Source/JavaScriptCore: https://bugs.webkit.org/show_bug.cgi?id=119548

Refactoring Exception throws.

Patch by Chris Curtis <chris_curtis@apple.com> on 2013-08-28
Reviewed by Geoffrey Garen.

Gardening of exception throws. The act of throwing an exception was being handled in
different ways depending on whether the code was running in the LLint, Baseline JIT,
or the DFG Jit. This made development in the vm exception and error objects difficult.

 * runtime/VM.cpp:
(JSC::appendSourceToError):
This function moved from the interpreter into the VM. It views the developers code
(if there is a codeBlock) to extract what was trying to be evaluated when the error
occurred.

(JSC::VM::throwException):
This function takes in the error object and sets the following:
    1: The VM's exception stack
    2: The VM's exception
    3: Appends extra information on the error message(via appendSourceToError)
    4: The error object's line number
    5: The error object's column number
    6: The error object's sourceURL
    7: The error object's stack trace (unless it already exists because the developer
        created the error object).

(JSC::VM::getExceptionInfo):
(JSC::VM::setExceptionInfo):
(JSC::VM::clearException):
(JSC::clearExceptionStack):
* runtime/VM.h:
(JSC::VM::exceptionOffset):
(JSC::VM::exception):
(JSC::VM::addressOfException):
(JSC::VM::exceptionStack):
VM exception and exceptionStack are now private data members.

* interpreter/Interpreter.h:
(JSC::ClearExceptionScope::ClearExceptionScope):
Created this structure to temporarily clear the exception within the VM. This
needed to see if addition errors occur when setting the debugger as we are
unwinding the stack.

 * interpreter/Interpreter.cpp:
(JSC::Interpreter::unwind):
Removed the code that would try to add error information if it did not exist.
All of this functionality has moved into the VM and all error information is set
at the time the error occurs.

The rest of these functions reference the new calling convention to throw an error.

* API/APICallbackFunction.h:
(JSC::APICallbackFunction::call):
* API/JSCallbackConstructor.cpp:
(JSC::constructJSCallback):
* API/JSCallbackObjectFunctions.h:
(JSC::::getOwnPropertySlot):
(JSC::::defaultValue):
(JSC::::put):
(JSC::::putByIndex):
(JSC::::deleteProperty):
(JSC::::construct):
(JSC::::customHasInstance):
(JSC::::call):
(JSC::::getStaticValue):
(JSC::::staticFunctionGetter):
(JSC::::callbackGetter):
* debugger/Debugger.cpp:
(JSC::evaluateInGlobalCallFrame):
* debugger/DebuggerCallFrame.cpp:
(JSC::DebuggerCallFrame::evaluate):
* dfg/DFGAssemblyHelpers.h:
(JSC::DFG::AssemblyHelpers::emitExceptionCheck):
* dfg/DFGOperations.cpp:
(JSC::DFG::operationPutByValInternal):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::callCheck):
* heap/Heap.cpp:
(JSC::Heap::markRoots):
* interpreter/CallFrame.h:
(JSC::ExecState::clearException):
(JSC::ExecState::exception):
(JSC::ExecState::hadException):
* interpreter/Interpreter.cpp:
(JSC::eval):
(JSC::loadVarargs):
(JSC::stackTraceAsString):
(JSC::Interpreter::execute):
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):
(JSC::Interpreter::prepareForRepeatCall):
* interpreter/Interpreter.h:
(JSC::ClearExceptionScope::ClearExceptionScope):
* jit/JITCode.cpp:
(JSC::JITCode::execute):
* jit/JITExceptions.cpp:
(JSC::genericThrow):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_catch):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::privateCompileCTINativeCall):
(JSC::JIT::emit_op_catch):
* jit/JITStubs.cpp:
(JSC::returnToThrowTrampoline):
(JSC::throwExceptionFromOpCall):
(JSC::DEFINE_STUB_FUNCTION):
(JSC::jitCompileFor):
(JSC::lazyLinkFor):
(JSC::putByVal):
(JSC::cti_vm_handle_exception):
* jit/SlowPathCall.h:
(JSC::JITSlowPathCall::call):
* jit/ThunkGenerators.cpp:
(JSC::nativeForGenerator):
* jsc.cpp:
(functionRun):
(functionLoad):
(functionCheckSyntax):
* llint/LLIntExceptions.cpp:
(JSC::LLInt::doThrow):
(JSC::LLInt::returnToThrow):
(JSC::LLInt::callToThrow):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LowLevelInterpreter.cpp:
(JSC::CLoop::execute):
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/ArrayConstructor.cpp:
(JSC::constructArrayWithSizeQuirk):
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:
(JSC::CommonSlowPaths::opIn):
* runtime/CommonSlowPathsExceptions.cpp:
(JSC::CommonSlowPaths::interpreterThrowInCaller):
* runtime/Completion.cpp:
(JSC::evaluate):
* runtime/Error.cpp:
(JSC::addErrorInfo):
(JSC::throwTypeError):
(JSC::throwSyntaxError):
* runtime/Error.h:
(JSC::throwVMError):
* runtime/ExceptionHelpers.cpp:
(JSC::throwOutOfMemoryError):
(JSC::throwStackOverflowError):
(JSC::throwTerminatedExecutionException):
* runtime/Executable.cpp:
(JSC::EvalExecutable::create):
(JSC::FunctionExecutable::produceCodeBlockFor):
* runtime/FunctionConstructor.cpp:
(JSC::constructFunction):
(JSC::constructFunctionSkippingEvalEnabledCheck):
* runtime/JSArray.cpp:
(JSC::JSArray::defineOwnProperty):
(JSC::JSArray::put):
(JSC::JSArray::push):
* runtime/JSCJSValue.cpp:
(JSC::JSValue::toObjectSlowCase):
(JSC::JSValue::synthesizePrototype):
(JSC::JSValue::putToPrimitive):
* runtime/JSFunction.cpp:
(JSC::JSFunction::defineOwnProperty):
* runtime/JSGenericTypedArrayViewInlines.h:
(JSC::::create):
(JSC::::createUninitialized):
(JSC::::validateRange):
(JSC::::setWithSpecificType):
* runtime/JSGlobalObjectFunctions.cpp:
(JSC::encode):
(JSC::decode):
(JSC::globalFuncProtoSetter):
* runtime/JSNameScope.cpp:
(JSC::JSNameScope::put):
* runtime/JSONObject.cpp:
(JSC::Stringifier::appendStringifiedValue):
(JSC::Walker::walk):
* runtime/JSObject.cpp:
(JSC::JSObject::put):
(JSC::JSObject::defaultValue):
(JSC::JSObject::hasInstance):
(JSC::JSObject::defaultHasInstance):
(JSC::JSObject::defineOwnNonIndexProperty):
(JSC::throwTypeError):
* runtime/ObjectConstructor.cpp:
(JSC::toPropertyDescriptor):
* runtime/RegExpConstructor.cpp:
(JSC::constructRegExp):
* runtime/StringObject.cpp:
(JSC::StringObject::defineOwnProperty):
* runtime/StringRecursionChecker.cpp:
(JSC::StringRecursionChecker::throwStackOverflowError):

Source/WebCore: https://bugs.webkit.org/show_bug.cgi?id=119548
Refactoring Exception throws.

Patch by Chris Curtis <chris_curtis@apple.com> on 2013-08-28
Reviewed by Geoffrey Garen.

Gets column information from the error object for reporting exceptions.
* bindings/js/JSDOMBinding.cpp:
(WebCore::reportException):
* bindings/js/ScriptCallStackFactory.cpp:
(WebCore::createScriptCallStackFromException):

Moved setting an exception into the vm, These functions changed to use the new functionality.

* bindings/js/JSAudioBufferSourceNodeCustom.cpp:
(WebCore::JSAudioBufferSourceNode::setBuffer):
* bindings/js/JSBiquadFilterNodeCustom.cpp:
(WebCore::JSBiquadFilterNode::setType):
* bindings/js/JSCryptoCustom.cpp:
(WebCore::JSCrypto::getRandomValues):
* bindings/js/JSDOMBinding.cpp:
(WebCore::setDOMException):
* bindings/js/JSInjectedScriptHostCustom.cpp:
(WebCore::JSInjectedScriptHost::setFunctionVariableValue):
* bindings/js/JSJavaScriptCallFrameCustom.cpp:
(WebCore::JSJavaScriptCallFrame::evaluate):
(WebCore::JSJavaScriptCallFrame::setVariableValue):
* bindings/js/JSNodeFilterCondition.cpp:
(WebCore::JSNodeFilterCondition::acceptNode):
* bindings/js/JSOscillatorNodeCustom.cpp:
(WebCore::JSOscillatorNode::setType):
* bindings/js/JSPannerNodeCustom.cpp:
(WebCore::JSPannerNode::setPanningModel):
(WebCore::JSPannerNode::setDistanceModel):
* bindings/js/JSSVGLengthCustom.cpp:
(WebCore::JSSVGLength::convertToSpecifiedUnits):
* bindings/js/JSWebGLRenderingContextCustom.cpp:
(WebCore::getObjectParameter):
(WebCore::JSWebGLRenderingContext::getAttachedShaders):
(WebCore::JSWebGLRenderingContext::getExtension):
(WebCore::JSWebGLRenderingContext::getFramebufferAttachmentParameter):
(WebCore::JSWebGLRenderingContext::getParameter):
(WebCore::JSWebGLRenderingContext::getProgramParameter):
(WebCore::JSWebGLRenderingContext::getShaderParameter):
(WebCore::JSWebGLRenderingContext::getUniform):
(WebCore::dataFunctionf):
(WebCore::dataFunctioni):
(WebCore::dataFunctionMatrix):
* bindings/js/JSXMLHttpRequestCustom.cpp:
(WebCore::JSXMLHttpRequest::open):
* bindings/js/SerializedScriptValue.cpp:
(WebCore::CloneBase::throwStackOverflow):
(WebCore::CloneDeserializer::throwValidationError):
(WebCore::SerializedScriptValue::maybeThrowExceptionIfSerializationFailed):
* bindings/js/WorkerScriptController.cpp:
(WebCore::WorkerScriptController::evaluate):
(WebCore::WorkerScriptController::setException):
* bridge/c/c_instance.cpp:
(JSC::Bindings::CInstance::moveGlobalExceptionToExecState):
(JSC::Bindings::CInstance::invokeMethod):
(JSC::Bindings::CInstance::invokeDefaultMethod):
(JSC::Bindings::CInstance::invokeConstruct):
(JSC::Bindings::CInstance::toJSPrimitive):
* bridge/objc/objc_instance.mm:
(ObjcInstance::invokeMethod):
* bridge/objc/objc_runtime.mm:
(JSC::Bindings::ObjcArray::setValueAt):
(JSC::Bindings::ObjcArray::valueAt):
* bridge/objc/objc_utility.mm:
(JSC::Bindings::throwError):
* bridge/qt/qt_instance.cpp:
(JSC::Bindings::QtField::valueFromInstance):
(JSC::Bindings::QtField::setValueToInstance):
* bridge/runtime_array.cpp:
(JSC::RuntimeArray::put):
(JSC::RuntimeArray::putByIndex):
* bridge/runtime_object.cpp:
(JSC::Bindings::RuntimeObject::throwInvalidAccessError):

Source/WebKit/mac: https://bugs.webkit.org/show_bug.cgi?id=119548
Refactoring Exception throws.

Patch by Chris Curtis <chris_curtis@apple.com> on 2013-08-28
Reviewed by Geoffrey Garen.

Moved setting an exception into the vm, These functions changed to use the new functionality.

* Plugins/Hosted/NetscapePluginInstanceProxy.mm:
(WebKit::NetscapePluginInstanceProxy::moveGlobalExceptionToExecState):
* Plugins/Hosted/ProxyInstance.mm:
(WebKit::ProxyInstance::invokeMethod):

Source/WebKit2: https://bugs.webkit.org/show_bug.cgi?id=119548
Refactoring Exception throws.

Patch by Chris Curtis <chris_curtis@apple.com> on 2013-08-28
Reviewed by Geoffrey Garen.

Moved setting an exception into the vm, These functions changed to use the new functionality.

* WebProcess/Plugins/Netscape/JSNPObject.cpp:
(WebKit::JSNPObject::callMethod):
(WebKit::JSNPObject::callObject):
(WebKit::JSNPObject::callConstructor):
(WebKit::JSNPObject::throwInvalidAccessError):
* WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp:
(WebKit::NPRuntimeObjectMap::moveGlobalExceptionToExecState):

LayoutTests: https://bugs.webkit.org/show_bug.cgi?id=119548
Refactoring Exception throws.

Patch by Chris Curtis <chris_curtis@apple.com> on 2013-08-28
Reviewed by Geoffrey Garen.

Column/line information was added into these results.
* fast/events/window-onerror4-expected.txt:
* fast/js/global-recursion-on-full-stack-expected.txt:

fixed a variable name in a case when shouldThrowType failed.
* fast/js/mozilla/resources/js-test-pre.js:
(shouldThrowType):

Sorted the properties to allow the results always show in the same order.
* fast/js/script-tests/exception-properties.js:
* fast/js/exception-properties-expected.txt:

This test needed to be modified to have the line numbers match on the output across
wk and wk2. This test is inherently flaky because is relies on size of the available
native stack. To account for the flakiness an additional call was made to force the
results to match.
This patch now records and outputs the line number where the errors were occurring.
This was causing the test results to no longer match because of the line numbers.
By changing how to account for the flakiness, the results match again.
* fast/xmlhttprequest/xmlhttprequest-recursive-sync-event-expected.txt:
* fast/xmlhttprequest/xmlhttprequest-recursive-sync-event.html:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@154797 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 8c23e6ea
2013-08-28 Chris Curtis <chris_curtis@apple.com>
https://bugs.webkit.org/show_bug.cgi?id=119548
Refactoring Exception throws.
Reviewed by Geoffrey Garen.
Column/line information was added into these results.
* fast/events/window-onerror4-expected.txt:
* fast/js/global-recursion-on-full-stack-expected.txt:
fixed a variable name in a case when shouldThrowType failed.
* fast/js/mozilla/resources/js-test-pre.js:
(shouldThrowType):
Sorted the properties to allow the results always show in the same order.
* fast/js/script-tests/exception-properties.js:
* fast/js/exception-properties-expected.txt:
This test needed to be modified to have the line numbers match on the output across
wk and wk2. This test is inherently flaky because is relies on size of the available
native stack. To account for the flakiness an additional call was made to force the
results to match.
This patch now records and outputs the line number where the errors were occurring.
This was causing the test results to no longer match because of the line numbers.
By changing how to account for the flakiness, the results match again.
* fast/xmlhttprequest/xmlhttprequest-recursive-sync-event-expected.txt:
* fast/xmlhttprequest/xmlhttprequest-recursive-sync-event.html:
2013-08-28 Dean Jackson <dino@apple.com>
[WebGL] CoreGraphics can provide greyscale image data
You should see a log record if window.onerror is working properly for this test.Bug 8519.
Error caught successfully: ReferenceError: Left side of assignment is not a reference. File: undefined Line: 1 Column: 0
Error caught successfully: ReferenceError: Left side of assignment is not a reference. File: undefined Line: 1 Column: 3
......@@ -4,7 +4,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
PASS enumerableProperties(error) is []
PASS enumerableProperties(nativeError) is ["stack", "line", "sourceURL"]
PASS enumerableProperties(nativeError).sort() is ["column", "line", "sourceURL"]
PASS Object.getPrototypeOf(nativeError).name is "RangeError"
PASS Object.getPrototypeOf(nativeError).message is ""
PASS successfullyParsed is true
......
CONSOLE MESSAGE: RangeError: Maximum call stack size exceeded.
CONSOLE MESSAGE: line 14: RangeError: Maximum call stack size exceeded.
This tests global code recursion when the JS stack is full.
PASS: Entering global code with a full JS stack did not crash, and did not allow continued recursion.
......@@ -272,7 +272,7 @@ function shouldThrowType(_a, _e)
if (exception instanceof _e)
testPassed(_a + " threw exception of type " + _e.name + ".");
else
testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Threw exception " + exception + ".");
testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _e) + ". Threw exception " + exception + ".");
} else
testFailed(_a + " should throw an instance of " + _e.name);
}
......
......@@ -16,7 +16,7 @@ try {
var error = new Error("message");
shouldBe('enumerableProperties(error)', '[]');
shouldBe('enumerableProperties(nativeError)', '["stack", "line", "sourceURL"]');
shouldBe('enumerableProperties(nativeError).sort()', '["column", "line", "sourceURL"]');
shouldBe('Object.getPrototypeOf(nativeError).name', '"RangeError"');
shouldBe('Object.getPrototypeOf(nativeError).message', '""');
......
CONSOLE MESSAGE: RangeError: Maximum call stack size exceeded.
CONSOLE MESSAGE: RangeError: Maximum call stack size exceeded.
CONSOLE MESSAGE: line 95: RangeError: Maximum call stack size exceeded.
CONSOLE MESSAGE: line 95: RangeError: Maximum call stack size exceeded.
This tests that having infinite recursion in XMLHttpRequest event handler does not crash.
PASS
......@@ -80,7 +80,7 @@ function log(s)
// onreadystatechange() frame on the return path.
lastReadyStateObserved = 0;
hasCompensatedAlready = false;
isCompensating = false;
function test()
{
......@@ -91,15 +91,13 @@ function test()
xhr.onreadystatechange = function() {
lastReadyStateObserved = xhr.readyState;
if (xhr.readyState == 4) {
xhr.open("GET", "recurse.html", false);
xhr.send(null);
// Compensate for test flakiness if needed:
if (!hasCompensatedAlready && lastReadyStateObserved == 1) {
xhr.open("GET", "recurse.html", false);
xhr.send(null);
hasCompensatedAlready = true;
}
do {
xhr.open("GET", "recurse.html", false), xhr.send(null);
if (isCompensating)
break;
if (lastReadyStateObserved == 1)
isCompensating = true;
} while (isCompensating && lastReadyStateObserved == 1);
}
};
xhr.open("GET", "recurse.html", false);
......
......@@ -59,7 +59,7 @@ EncodedJSValue JSC_HOST_CALL APICallbackFunction::call(ExecState* exec)
result = jsCast<T*>(toJS(functionRef))->m_callback(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception);
}
if (exception)
throwError(exec, toJS(exec, exception));
exec->vm().throwException(exec, toJS(exec, exception));
// result must be a valid JSValue.
if (!result)
......
......@@ -86,7 +86,7 @@ static EncodedJSValue JSC_HOST_CALL constructJSCallback(ExecState* exec)
result = callback(ctx, constructorRef, argumentCount, arguments.data(), &exception);
}
if (exception)
throwError(exec, toJS(exec, exception));
exec->vm().throwException(exec, toJS(exec, exception));
// result must be a valid JSValue.
if (!result)
return throwVMTypeError(exec);
......
......@@ -150,7 +150,7 @@ bool JSCallbackObject<Parent>::getOwnPropertySlot(JSObject* object, ExecState* e
value = getProperty(ctx, thisRef, propertyNameRef.get(), &exception);
}
if (exception) {
throwError(exec, toJS(exec, exception));
exec->vm().throwException(exec, toJS(exec, exception));
slot.setValue(thisObject, ReadOnly | DontEnum, jsUndefined());
return true;
}
......@@ -201,7 +201,7 @@ JSValue JSCallbackObject<Parent>::defaultValue(const JSObject* object, ExecState
JSValueRef exception = 0;
JSValueRef result = convertToType(ctx, thisRef, jsHint, &exception);
if (exception) {
throwError(exec, toJS(exec, exception));
exec->vm().throwException(exec, toJS(exec, exception));
return jsUndefined();
}
if (result)
......@@ -233,7 +233,7 @@ void JSCallbackObject<Parent>::put(JSCell* cell, ExecState* exec, PropertyName p
result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception);
}
if (exception)
throwError(exec, toJS(exec, exception));
exec->vm().throwException(exec, toJS(exec, exception));
if (result || exception)
return;
}
......@@ -250,7 +250,7 @@ void JSCallbackObject<Parent>::put(JSCell* cell, ExecState* exec, PropertyName p
result = setProperty(ctx, thisRef, entry->propertyNameRef.get(), valueRef, &exception);
}
if (exception)
throwError(exec, toJS(exec, exception));
exec->vm().throwException(exec, toJS(exec, exception));
if (result || exception)
return;
}
......@@ -292,7 +292,7 @@ void JSCallbackObject<Parent>::putByIndex(JSCell* cell, ExecState* exec, unsigne
result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception);
}
if (exception)
throwError(exec, toJS(exec, exception));
exec->vm().throwException(exec, toJS(exec, exception));
if (result || exception)
return;
}
......@@ -309,7 +309,7 @@ void JSCallbackObject<Parent>::putByIndex(JSCell* cell, ExecState* exec, unsigne
result = setProperty(ctx, thisRef, entry->propertyNameRef.get(), valueRef, &exception);
}
if (exception)
throwError(exec, toJS(exec, exception));
exec->vm().throwException(exec, toJS(exec, exception));
if (result || exception)
return;
}
......@@ -348,7 +348,7 @@ bool JSCallbackObject<Parent>::deleteProperty(JSCell* cell, ExecState* exec, Pro
result = deleteProperty(ctx, thisRef, propertyNameRef.get(), &exception);
}
if (exception)
throwError(exec, toJS(exec, exception));
exec->vm().throwException(exec, toJS(exec, exception));
if (result || exception)
return true;
}
......@@ -415,7 +415,7 @@ EncodedJSValue JSCallbackObject<Parent>::construct(ExecState* exec)
result = toJS(callAsConstructor(execRef, constructorRef, argumentCount, arguments.data(), &exception));
}
if (exception)
throwError(exec, toJS(exec, exception));
exec->vm().throwException(exec, toJS(exec, exception));
return JSValue::encode(result);
}
}
......@@ -441,7 +441,7 @@ bool JSCallbackObject<Parent>::customHasInstance(JSObject* object, ExecState* ex
result = hasInstance(execRef, thisRef, valueRef, &exception);
}
if (exception)
throwError(exec, toJS(exec, exception));
exec->vm().throwException(exec, toJS(exec, exception));
return result;
}
}
......@@ -482,7 +482,7 @@ EncodedJSValue JSCallbackObject<Parent>::call(ExecState* exec)
result = toJS(exec, callAsFunction(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception));
}
if (exception)
throwError(exec, toJS(exec, exception));
exec->vm().throwException(exec, toJS(exec, exception));
return JSValue::encode(result);
}
}
......@@ -569,7 +569,7 @@ JSValue JSCallbackObject<Parent>::getStaticValue(ExecState* exec, PropertyName p
value = getProperty(toRef(exec), thisRef, entry->propertyNameRef.get(), &exception);
}
if (exception) {
throwError(exec, toJS(exec, exception));
exec->vm().throwException(exec, toJS(exec, exception));
return jsUndefined();
}
if (value)
......@@ -608,7 +608,7 @@ JSValue JSCallbackObject<Parent>::staticFunctionGetter(ExecState* exec, JSValue
}
}
return throwError(exec, createReferenceError(exec, ASCIILiteral("Static function property defined with NULL callAsFunction callback.")));
return exec->vm().throwException(exec, createReferenceError(exec, ASCIILiteral("Static function property defined with NULL callAsFunction callback.")));
}
template <class Parent>
......@@ -631,7 +631,7 @@ JSValue JSCallbackObject<Parent>::callbackGetter(ExecState* exec, JSValue slotPa
value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), &exception);
}
if (exception) {
throwError(exec, toJS(exec, exception));
exec->vm().throwException(exec, toJS(exec, exception));
return jsUndefined();
}
if (value)
......@@ -640,7 +640,7 @@ JSValue JSCallbackObject<Parent>::callbackGetter(ExecState* exec, JSValue slotPa
}
}
return throwError(exec, createReferenceError(exec, ASCIILiteral("hasProperty callback returned true for a property that doesn't exist.")));
return exec->vm().throwException(exec, createReferenceError(exec, ASCIILiteral("hasProperty callback returned true for a property that doesn't exist.")));
}
} // namespace JSC
2013-08-28 Chris Curtis <chris_curtis@apple.com>
https://bugs.webkit.org/show_bug.cgi?id=119548
Refactoring Exception throws.
Reviewed by Geoffrey Garen.
Gardening of exception throws. The act of throwing an exception was being handled in
different ways depending on whether the code was running in the LLint, Baseline JIT,
or the DFG Jit. This made development in the vm exception and error objects difficult.
* runtime/VM.cpp:
(JSC::appendSourceToError):
This function moved from the interpreter into the VM. It views the developers code
(if there is a codeBlock) to extract what was trying to be evaluated when the error
occurred.
(JSC::VM::throwException):
This function takes in the error object and sets the following:
1: The VM's exception stack
2: The VM's exception
3: Appends extra information on the error message(via appendSourceToError)
4: The error object's line number
5: The error object's column number
6: The error object's sourceURL
7: The error object's stack trace (unless it already exists because the developer
created the error object).
(JSC::VM::getExceptionInfo):
(JSC::VM::setExceptionInfo):
(JSC::VM::clearException):
(JSC::clearExceptionStack):
* runtime/VM.h:
(JSC::VM::exceptionOffset):
(JSC::VM::exception):
(JSC::VM::addressOfException):
(JSC::VM::exceptionStack):
VM exception and exceptionStack are now private data members.
* interpreter/Interpreter.h:
(JSC::ClearExceptionScope::ClearExceptionScope):
Created this structure to temporarily clear the exception within the VM. This
needed to see if addition errors occur when setting the debugger as we are
unwinding the stack.
* interpreter/Interpreter.cpp:
(JSC::Interpreter::unwind):
Removed the code that would try to add error information if it did not exist.
All of this functionality has moved into the VM and all error information is set
at the time the error occurs.
The rest of these functions reference the new calling convention to throw an error.
* API/APICallbackFunction.h:
(JSC::APICallbackFunction::call):
* API/JSCallbackConstructor.cpp:
(JSC::constructJSCallback):
* API/JSCallbackObjectFunctions.h:
(JSC::::getOwnPropertySlot):
(JSC::::defaultValue):
(JSC::::put):
(JSC::::putByIndex):
(JSC::::deleteProperty):
(JSC::::construct):
(JSC::::customHasInstance):
(JSC::::call):
(JSC::::getStaticValue):
(JSC::::staticFunctionGetter):
(JSC::::callbackGetter):
* debugger/Debugger.cpp:
(JSC::evaluateInGlobalCallFrame):
* debugger/DebuggerCallFrame.cpp:
(JSC::DebuggerCallFrame::evaluate):
* dfg/DFGAssemblyHelpers.h:
(JSC::DFG::AssemblyHelpers::emitExceptionCheck):
* dfg/DFGOperations.cpp:
(JSC::DFG::operationPutByValInternal):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::callCheck):
* heap/Heap.cpp:
(JSC::Heap::markRoots):
* interpreter/CallFrame.h:
(JSC::ExecState::clearException):
(JSC::ExecState::exception):
(JSC::ExecState::hadException):
* interpreter/Interpreter.cpp:
(JSC::eval):
(JSC::loadVarargs):
(JSC::stackTraceAsString):
(JSC::Interpreter::execute):
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):
(JSC::Interpreter::prepareForRepeatCall):
* interpreter/Interpreter.h:
(JSC::ClearExceptionScope::ClearExceptionScope):
* jit/JITCode.cpp:
(JSC::JITCode::execute):
* jit/JITExceptions.cpp:
(JSC::genericThrow):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_catch):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::privateCompileCTINativeCall):
(JSC::JIT::emit_op_catch):
* jit/JITStubs.cpp:
(JSC::returnToThrowTrampoline):
(JSC::throwExceptionFromOpCall):
(JSC::DEFINE_STUB_FUNCTION):
(JSC::jitCompileFor):
(JSC::lazyLinkFor):
(JSC::putByVal):
(JSC::cti_vm_handle_exception):
* jit/SlowPathCall.h:
(JSC::JITSlowPathCall::call):
* jit/ThunkGenerators.cpp:
(JSC::nativeForGenerator):
* jsc.cpp:
(functionRun):
(functionLoad):
(functionCheckSyntax):
* llint/LLIntExceptions.cpp:
(JSC::LLInt::doThrow):
(JSC::LLInt::returnToThrow):
(JSC::LLInt::callToThrow):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LowLevelInterpreter.cpp:
(JSC::CLoop::execute):
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/ArrayConstructor.cpp:
(JSC::constructArrayWithSizeQuirk):
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:
(JSC::CommonSlowPaths::opIn):
* runtime/CommonSlowPathsExceptions.cpp:
(JSC::CommonSlowPaths::interpreterThrowInCaller):
* runtime/Completion.cpp:
(JSC::evaluate):
* runtime/Error.cpp:
(JSC::addErrorInfo):
(JSC::throwTypeError):
(JSC::throwSyntaxError):
* runtime/Error.h:
(JSC::throwVMError):
* runtime/ExceptionHelpers.cpp:
(JSC::throwOutOfMemoryError):
(JSC::throwStackOverflowError):
(JSC::throwTerminatedExecutionException):
* runtime/Executable.cpp:
(JSC::EvalExecutable::create):
(JSC::FunctionExecutable::produceCodeBlockFor):
* runtime/FunctionConstructor.cpp:
(JSC::constructFunction):
(JSC::constructFunctionSkippingEvalEnabledCheck):
* runtime/JSArray.cpp:
(JSC::JSArray::defineOwnProperty):
(JSC::JSArray::put):
(JSC::JSArray::push):
* runtime/JSCJSValue.cpp:
(JSC::JSValue::toObjectSlowCase):
(JSC::JSValue::synthesizePrototype):
(JSC::JSValue::putToPrimitive):
* runtime/JSFunction.cpp:
(JSC::JSFunction::defineOwnProperty):
* runtime/JSGenericTypedArrayViewInlines.h:
(JSC::::create):
(JSC::::createUninitialized):
(JSC::::validateRange):
(JSC::::setWithSpecificType):
* runtime/JSGlobalObjectFunctions.cpp:
(JSC::encode):
(JSC::decode):
(JSC::globalFuncProtoSetter):
* runtime/JSNameScope.cpp:
(JSC::JSNameScope::put):
* runtime/JSONObject.cpp:
(JSC::Stringifier::appendStringifiedValue):
(JSC::Walker::walk):
* runtime/JSObject.cpp:
(JSC::JSObject::put):
(JSC::JSObject::defaultValue):
(JSC::JSObject::hasInstance):
(JSC::JSObject::defaultHasInstance):
(JSC::JSObject::defineOwnNonIndexProperty):
(JSC::throwTypeError):
* runtime/ObjectConstructor.cpp:
(JSC::toPropertyDescriptor):
* runtime/RegExpConstructor.cpp:
(JSC::constructRegExp):
* runtime/StringObject.cpp:
(JSC::StringObject::defineOwnProperty):
* runtime/StringRecursionChecker.cpp:
(JSC::StringRecursionChecker::throwStackOverflowError):
2013-08-28 Zan Dobersek <zdobersek@igalia.com>
[GTK] Add support for building JSC with FTL JIT enabled
......
......@@ -132,15 +132,15 @@ JSValue evaluateInGlobalCallFrame(const String& script, JSValue& exception, JSGl
EvalExecutable* eval = EvalExecutable::create(globalCallFrame, makeSource(script), false);
if (!eval) {
exception = vm.exception;
vm.exception = JSValue();
exception = vm.exception();
vm.clearException();
return exception;
}
JSValue result = vm.interpreter->execute(eval, globalCallFrame, globalObject, globalCallFrame->scope());
if (vm.exception) {
exception = vm.exception;
vm.exception = JSValue();
if (vm.exception()) {
exception = vm.exception();
vm.clearException();
}
ASSERT(result);
return result;
......
......@@ -92,15 +92,15 @@ JSValue DebuggerCallFrame::evaluate(const String& script, JSValue& exception) co
VM& vm = m_callFrame->vm();
EvalExecutable* eval = EvalExecutable::create(m_callFrame, makeSource(script), m_callFrame->codeBlock()->isStrictMode());
if (vm.exception) {
exception = vm.exception;
vm.exception = JSValue();
if (vm.exception()) {
exception = vm.exception();
vm.clearException();
}
JSValue result = vm.interpreter->execute(eval, m_callFrame, thisObject(), m_callFrame->scope());
if (vm.exception) {
exception = vm.exception;
vm.exception = JSValue();
if (vm.exception()) {
exception = vm.exception();
vm.clearException();
}
ASSERT(result);
return result;
......
......@@ -310,9 +310,9 @@ public:
Jump emitExceptionCheck(ExceptionCheckKind kind = NormalExceptionCheck)
{
#if USE(JSVALUE64)
return branchTest64(kind == NormalExceptionCheck ? NonZero : Zero, AbsoluteAddress(&vm()->exception));
return branchTest64(kind == NormalExceptionCheck ? NonZero : Zero, AbsoluteAddress(vm()->addressOfException()));
#elif USE(JSVALUE32_64)
return branch32(kind == NormalExceptionCheck ? NotEqual : Equal, AbsoluteAddress(reinterpret_cast<char*>(&vm()->exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag));
return branch32(kind == NormalExceptionCheck ? NotEqual : Equal, AbsoluteAddress(reinterpret_cast<char*>(vm()->addressOfException()) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag));
#endif
}
......
......@@ -382,7 +382,7 @@ ALWAYS_INLINE static void DFG_OPERATION operationPutByValInternal(ExecState* exe
// Don't put to an object if toString throws an exception.
Identifier ident(exec, property.toString(exec)->value(exec));
if (!vm->exception) {
if (!vm->exception()) {
PutPropertySlot slot(strict);
baseValue.put(exec, ident, value, slot);
}
......@@ -394,7 +394,7 @@ char* newTypedArrayWithSize(ExecState* exec, Structure* structure, int32_t size)
VM& vm = exec->vm();
NativeCallFrameTracer tracer(&vm, exec);
if (size < 0) {
throwError(exec, createRangeError(exec, "Requested length is negative"));
vm.throwException(exec, createRangeError(exec, "Requested length is negative"));
return 0;
}
return bitwise_cast<char*>(ViewClass::create(exec, structure, size));
......@@ -413,7 +413,7 @@ char* newTypedArrayWithOneArgument(
RefPtr<ArrayBuffer> buffer = jsBuffer->impl();
if (buffer->byteLength() % ViewClass::elementSize) {
throwError(exec, createRangeError(exec, "ArrayBuffer length minus the byteOffset is not a multiple of the element size"));
vm.throwException(exec, createRangeError(exec, "ArrayBuffer length minus the byteOffset is not a multiple of the element size"));
return 0;
}
return bitwise_cast<char*>(
......@@ -440,18 +440,18 @@ char* newTypedArrayWithOneArgument(
if (value.isInt32())
length = value.asInt32();
else if (!value.isNumber()) {
throwError(exec, createTypeError(exec, "Invalid array length argument"));
vm.throwException(exec, createTypeError(exec, "Invalid array length argument"));
return 0;
} else {
length = static_cast<int>(value.asNumber());
if (length != value.asNumber()) {
throwError(exec, createTypeError(exec, "Invalid array length argument (fractional lengths not allowed)"));
vm.throwException(exec, createTypeError(exec, "Invalid array length argument (fractional lengths not allowed)"));
return 0;
}
}
if (length < 0) {
throwError(exec, createRangeError(exec, "Requested length is negative"));
vm.throwException(exec, createRangeError(exec, "Requested length is negative"));
return 0;
}
......@@ -676,7 +676,7 @@ EncodedJSValue DFG_OPERATION operationInOptimizeWithReturnAddress(ExecState* exe
NativeCallFrameTracer tracer(vm, exec);
if (!base->isObject()) {
vm->exception = createInvalidParameterError(exec, "in", base);
vm->throwException(exec, createInvalidParameterError(exec, "in", base));
return jsUndefined();
}
......@@ -703,7 +703,7 @@ EncodedJSValue DFG_OPERATION operationIn(ExecState* exec, JSCell* base, StringIm
NativeCallFrameTracer tracer(vm, exec);
if (!base->isObject()) {
vm->exception = createInvalidParameterError(exec, "in", base);
vm->throwException(exec, createInvalidParameterError(exec, "in", base));
return jsUndefined();
}
......@@ -1227,14 +1227,14 @@ static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializ
NativeCallFrameTracer tracer(vm, execCallee);
execCallee->setCallee(asObject(callee));
vm->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
if (vm->exception)
if (vm->exception())
return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
return reinterpret_cast<void*>(getHostCallReturnValue);
}
ASSERT(callType == CallTypeNone);
exec->vm().exception = createNotAFunctionError(exec, callee);
exec->vm().throwException(exec, createNotAFunctionError(exec, callee));
return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
}
......@@ -1249,14 +1249,14 @@ static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializ
NativeCallFrameTracer tracer(vm, execCallee);
execCallee->setCallee(asObject(callee));
vm->hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
if (vm->exception)
if (vm->exception())
return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
return reinterpret_cast<void*>(getHostCallReturnValue);
}
ASSERT(constructType == ConstructTypeNone);
exec->vm().exception = createNotAConstructorError(exec, callee);
exec->vm().throwException(exec, createNotAConstructorError(exec, callee));
return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
}
......@@ -1283,7 +1283,7 @@ inline char* linkFor(ExecState* execCallee, CodeSpecializationKind kind)
FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind);
if (error) {
vm->exception = createStackOverflowError(exec);
vm->throwException(exec, createStackOverflowError(exec));
return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
}
codeBlock = &functionExecutable->generatedBytecodeFor(kind);
......@@ -1328,7 +1328,7 @@ inline char* virtualForWithFunction(ExecState* execCallee, CodeSpecializationKin
FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
JSObject* error = functionExecutable->compileFor(execCallee, function->scope(), kind);
if (error) {
exec->vm().exception = error;
exec->vm().throwException(execCallee, error);
return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
}
}
......@@ -1425,7 +1425,7 @@ char* DFG_OPERATION operationNewArrayWithSize(ExecState* exec, Structure* arrayS
NativeCallFrameTracer tracer(vm, exec);
if (UNLIKELY(size < 0))
return bitwise_cast<char*>(throwError(exec, createRangeError(exec, ASCIILiteral("Array size is not a small enough positive integer."))));
return bitwise_cast<char*>(exec->vm().throwException(exec, createRangeError(exec, ASCIILiteral("Array size is not a small enough positive integer."))));
return bitwise_cast<char*>(JSArray::create(*vm, arrayStructure, size));
}
......@@ -1551,7 +1551,7 @@ EncodedJSValue DFG_OPERATION operationNewRegexp(ExecState* exec, void* regexpPtr
NativeCallFrameTracer tracer(&vm, exec);
RegExp* regexp = static_cast<RegExp*>(regexpPtr);
if (!regexp->isValid()) {
throwError(exec, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor."));
exec->vm().throwException(exec, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor."));
return JSValue::encode(jsUndefined());
}