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: https://svn.webkit.org/repository/webkit/trunk@154797
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+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
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.
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);
}
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
// onreadystatechange() frame on the return path.
lastReadyStateObserved = 0;
-hasCompensatedAlready = false;
+isCompensating = false;
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);
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)
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);
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;
}
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)
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;
}
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;
}
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;
}
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;
}
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;
}
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);
}
}
result = hasInstance(execRef, thisRef, valueRef, &exception);
}
if (exception)
- throwError(exec, toJS(exec, exception));
+ exec->vm().throwException(exec, toJS(exec, exception));
return result;
}
}
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);
}
}
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)
}
}
- 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>
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)
}
}
- 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
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;
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;
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
}
// 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);
}
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));
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*>(
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;
}
NativeCallFrameTracer tracer(vm, exec);
if (!base->isObject()) {
- vm->exception = createInvalidParameterError(exec, "in", base);
+ vm->throwException(exec, createInvalidParameterError(exec, "in", base));
return jsUndefined();
}
NativeCallFrameTracer tracer(vm, exec);
if (!base->isObject()) {
- vm->exception = createInvalidParameterError(exec, "in", base);
+ vm->throwException(exec, createInvalidParameterError(exec, "in", base));
return jsUndefined();
}
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();
}
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();
}
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);
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());
}
}
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));
}
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());
}
// NB: This needs to be exceedingly careful with top call frame tracking, since it
// may be called from OSR exit, while the state of the call stack is bizarre.
Arguments* result = Arguments::create(vm, exec);
- ASSERT(!vm.exception);
+ ASSERT(!vm.exception());
return result;
}
// NB: This needs to be exceedingly careful with top call frame tracking, since it
// may be called from OSR exit, while the state of the call stack is bizarre.
Arguments* result = Arguments::create(vm, exec, inlineCallFrame);
- ASSERT(!vm.exception);
+ ASSERT(!vm.exception());
return result;
}
LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("Exception check continuation"));
m_out.branch(
- m_out.notZero64(m_out.load64(m_out.absolute(&vm().exception))),
+ m_out.notZero64(m_out.load64(m_out.absolute(&vm().exception()))),
didHaveException, continuation);
LBasicBlock lastNext = m_out.appendTo(didHaveException, continuation);
visitor.donateAndDrain();
}
}
- if (m_vm->exception) {
+ if (m_vm->exception()) {
GCPHASE(MarkingException);
MARK_LOG_ROOT(visitor, "Exceptions");
- heapRootVisitor.visit(&m_vm->exception);
+ heapRootVisitor.visit(m_vm->addressOfException());
visitor.donateAndDrain();
}
// pointer, so these are inefficient, and should be used sparingly in new code.
// But they're used in many places in legacy code, so they're not going away any time soon.
- void clearException() { vm().exception = JSValue(); }
+ void clearException() { vm().clearException(); }
void clearSupplementaryExceptionInfo()
{
vm().clearExceptionStack();
}
- JSValue exception() const { return vm().exception; }
- bool hadException() const { return vm().exception; }
+ JSValue exception() const { return vm().exception(); }
+ bool hadException() const { return vm().exception(); }
const CommonIdentifiers& propertyNames() const { return *vm().propertyNames; }
const MarkedArgumentBuffer& emptyList() const { return *vm().emptyList; }
}
// If the literal parser bailed, it should not have thrown exceptions.
- ASSERT(!callFrame->vm().exception);
+ ASSERT(!callFrame->vm().exception());
eval = callerCodeBlock->evalCodeCache().getSlow(callFrame, callerCodeBlock->ownerExecutable(), callerCodeBlock->isStrictMode(), programSource, callerScopeChain);
if (!eval)
unsigned argumentCountIncludingThis = callFrame->argumentCountIncludingThis();
CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + argumentCountIncludingThis + JSStack::CallFrameHeaderSize);
if (argumentCountIncludingThis > Arguments::MaxArguments + 1 || !stack->grow(newCallFrame->registers())) {
- callFrame->vm().exception = createStackOverflowError(callFrame);
+ callFrame->vm().throwException(callFrame, createStackOverflowError(callFrame));
return 0;
}
if (arguments.isUndefinedOrNull()) {
CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + 1 + JSStack::CallFrameHeaderSize);
if (!stack->grow(newCallFrame->registers())) {
- callFrame->vm().exception = createStackOverflowError(callFrame);
+ callFrame->vm().throwException(callFrame, createStackOverflowError(callFrame));
return 0;
}
newCallFrame->setArgumentCountIncludingThis(1);
}
if (!arguments.isObject()) {
- callFrame->vm().exception = createInvalidParameterError(callFrame, "Function.prototype.apply", arguments);
+ callFrame->vm().throwException(callFrame, createInvalidParameterError(callFrame, "Function.prototype.apply", arguments));
return 0;
}
unsigned argCount = argsObject->length(callFrame);
CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + CallFrame::offsetFor(argCount + 1));
if (argCount > Arguments::MaxArguments || !stack->grow(newCallFrame->registers())) {
- callFrame->vm().exception = createStackOverflowError(callFrame);
+ callFrame->vm().throwException(callFrame, createStackOverflowError(callFrame));
return 0;
}
newCallFrame->setArgumentCountIncludingThis(argCount + 1);
unsigned argCount = array->length();
CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + CallFrame::offsetFor(argCount + 1));
if (argCount > Arguments::MaxArguments || !stack->grow(newCallFrame->registers())) {
- callFrame->vm().exception = createStackOverflowError(callFrame);
+ callFrame->vm().throwException(callFrame, createStackOverflowError(callFrame));
return 0;
}
newCallFrame->setArgumentCountIncludingThis(argCount + 1);
unsigned argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + CallFrame::offsetFor(argCount + 1));
if (argCount > Arguments::MaxArguments || !stack->grow(newCallFrame->registers())) {
- callFrame->vm().exception = createStackOverflowError(callFrame);
+ callFrame->vm().throwException(callFrame, createStackOverflowError(callFrame));
return 0;
}
newCallFrame->setArgumentCountIncludingThis(argCount + 1);
newCallFrame->setThisValue(thisValue);
for (size_t i = 0; i < argCount; ++i) {
newCallFrame->setArgument(i, asObject(arguments)->get(callFrame, i));
- if (UNLIKELY(callFrame->vm().exception))
+ if (UNLIKELY(callFrame->vm().exception()))
return 0;
}
return newCallFrame;
return !callerFrame->hasHostCallFrameFlag();
}
-static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception, unsigned bytecodeOffset)
-{
- exception->clearAppendSourceToMessage();
-
- if (!callFrame->codeBlock()->hasExpressionInfo())
- return;
-
- int startOffset = 0;
- int endOffset = 0;
- int divotPoint = 0;
- unsigned line = 0;
- unsigned column = 0;
-
- CodeBlock* codeBlock = callFrame->codeBlock();
- codeBlock->expressionRangeForBytecodeOffset(bytecodeOffset, divotPoint, startOffset, endOffset, line, column);
-
- int expressionStart = divotPoint - startOffset;
- int expressionStop = divotPoint + endOffset;
-
- const String& sourceString = codeBlock->source()->source();
- if (!expressionStop || expressionStart > static_cast<int>(sourceString.length()))
- return;
-
- VM* vm = &callFrame->vm();
- JSValue jsMessage = exception->getDirect(*vm, vm->propertyNames->message);
- if (!jsMessage || !jsMessage.isString())
- return;
-
- String message = asString(jsMessage)->value(callFrame);
-
- if (expressionStart < expressionStop)
- message = makeString(message, " (evaluating '", codeBlock->source()->getRange(expressionStart, expressionStop), "')");
- else {
- // No range information, so give a few characters of context
- const StringImpl* data = sourceString.impl();
- int dataLength = sourceString.length();
- int start = expressionStart;
- int stop = expressionStart;
- // Get up to 20 characters of context to the left and right of the divot, clamping to the line.
- // then strip whitespace.
- while (start > 0 && (expressionStart - start < 20) && (*data)[start - 1] != '\n')
- start--;
- while (start < (expressionStart - 1) && isStrWhiteSpace((*data)[start]))
- start++;
- while (stop < dataLength && (stop - expressionStart < 20) && (*data)[stop] != '\n')
- stop++;
- while (stop > expressionStart && isStrWhiteSpace((*data)[stop - 1]))
- stop--;
- message = makeString(message, " (near '...", codeBlock->source()->getRange(start, stop), "...')");
- }
-
- exception->putDirect(*vm, vm->propertyNames->message, jsString(vm, message));
-}
-
static ALWAYS_INLINE const String getSourceURLFromCallFrame(CallFrame* callFrame)
{
ASSERT(!callFrame->hasHostCallFrameFlag());
}
return jsString(&exec->vm(), builder.toString());
}
-
-void Interpreter::addStackTraceIfNecessary(CallFrame* callFrame, JSValue error)
-{
- VM* vm = &callFrame->vm();
- ASSERT(callFrame == vm->topCallFrame || callFrame == callFrame->lexicalGlobalObject()->globalExec() || callFrame == callFrame->dynamicGlobalObject()->globalExec());
-
- Vector<StackFrame> stackTrace;
- vm->interpreter->getStackTrace(stackTrace);
- vm->exceptionStack() = RefCountedArray<StackFrame>(stackTrace);
- if (stackTrace.isEmpty() || !error.isObject())
- return;
-
- if (asObject(error)->hasProperty(callFrame, vm->propertyNames->stack))
- return;
-
- asObject(error)->putDirect(*vm, vm->propertyNames->stack, vm->interpreter->stackTraceAsString(vm->topCallFrame, stackTrace), None);
-
-}
-NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSValue& exceptionValue, unsigned bytecodeOffset)
+NEVER_INLINE HandlerInfo* Interpreter::unwind(CallFrame*& callFrame, JSValue& exceptionValue, unsigned bytecodeOffset)
{
CodeBlock* codeBlock = callFrame->codeBlock();
bool isTermination = false;
if (exceptionValue.isEmpty() || (exceptionValue.isCell() && !exceptionValue.asCell()))
exceptionValue = jsNull();
- // Set up the exception object
if (exceptionValue.isObject()) {
- JSObject* exception = asObject(exceptionValue);
-
- if (exception->isErrorInstance() && static_cast<ErrorInstance*>(exception)->appendSourceToMessage())
- appendSourceToError(callFrame, static_cast<ErrorInstance*>(exception), bytecodeOffset);
-
- if (!hasErrorInfo(callFrame, exception)) {
- // FIXME: should only really be adding these properties to VM generated exceptions,
- // but the inspector currently requires these for all thrown objects.
- addErrorInfo(callFrame, exception, codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), codeBlock->ownerExecutable()->source());
- }
-
- isTermination = isTerminatedExecutionException(exception);
- } else {
- if (!callFrame->vm().exceptionStack().size()) {
- Vector<StackFrame> stack;
- callFrame->vm().interpreter->getStackTrace(stack);
- callFrame->vm().exceptionStack() = RefCountedArray<StackFrame>(stack);
- }
+ isTermination = isTerminatedExecutionException(asObject(exceptionValue));
}
+ ASSERT(callFrame->vm().exceptionStack().size());
+ ASSERT(!exceptionValue.isObject() || asObject(exceptionValue)->hasProperty(callFrame, callFrame->vm().propertyNames->stack));
+
if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) {
+ // We need to clear the exception and the exception stack here in order to see if a new exception happens.
+ // Afterwards, the values are put back to continue processing this error.
+ ClearExceptionScope scope(&callFrame->vm());
+
DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue);
bool hasHandler = codeBlock->handlerForBytecodeOffset(bytecodeOffset);
debugger->exception(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), 0, hasHandler);
JSScope* scope = callFrame->scope();
VM& vm = *scope->vm();
- ASSERT(!vm.exception);
+ ASSERT(!vm.exception());
ASSERT(!vm.isCollectorBusy());
if (vm.isCollectorBusy())
return jsNull();
PropertySlot slot(globalObject);
if (!globalObject->getPropertySlot(callFrame, JSONPPath[i].m_pathEntryName, slot)) {
if (entry)
- return throwError(callFrame, createUndefinedVariableError(globalObject->globalExec(), JSONPPath[i].m_pathEntryName));
+ return callFrame->vm().throwException(callFrame, createUndefinedVariableError(globalObject->globalExec(), JSONPPath[i].m_pathEntryName));
goto failedJSONP;
}
baseObject = slot.getValue(callFrame, JSONPPath[i].m_pathEntryName);
CallData callData;
CallType callType = getCallData(function, callData);
if (callType == CallTypeNone)
- return throwError(callFrame, createNotAFunctionError(callFrame, function));
+ return callFrame->vm().throwException(callFrame, createNotAFunctionError(callFrame, function));
MarkedArgumentBuffer jsonArg;
jsonArg.append(JSONPValue);
JSValue thisValue = JSONPPath.size() == 1 ? jsUndefined(): baseObject;
// Compile source to bytecode if necessary:
if (JSObject* error = program->initializeGlobalProperties(vm, callFrame, scope))
- return checkedReturn(throwError(callFrame, error));
+ return checkedReturn(callFrame->vm().throwException(callFrame, error));
if (JSObject* error = program->compile(callFrame, scope))
- return checkedReturn(throwError(callFrame, error));
+ return checkedReturn(callFrame->vm().throwException(callFrame, error));
ProgramCodeBlock* codeBlock = &program->generatedBytecode();
// Compile the callee:
JSObject* compileError = callData.js.functionExecutable->compileForCall(callFrame, scope);
if (UNLIKELY(!!compileError)) {
- return checkedReturn(throwError(callFrame, compileError));
+ return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
}
newCodeBlock = &callData.js.functionExecutable->generatedBytecodeForCall();
ASSERT(!!newCodeBlock);
// Compile the callee:
JSObject* compileError = constructData.js.functionExecutable->compileForConstruct(callFrame, scope);
if (UNLIKELY(!!compileError)) {
- return checkedReturn(throwError(callFrame, compileError));
+ return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
}
newCodeBlock = &constructData.js.functionExecutable->generatedBytecodeForConstruct();
ASSERT(!!newCodeBlock);
CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionExecutable, CallFrame* callFrame, JSFunction* function, int argumentCountIncludingThis, JSScope* scope)
{
VM& vm = *scope->vm();
- ASSERT(!vm.exception);
+ ASSERT(!vm.exception());
if (vm.isCollectorBusy())
return CallFrameClosure();
// Compile the callee:
JSObject* error = functionExecutable->compileForCall(callFrame, scope);
if (error) {
- throwError(callFrame, error);
+ callFrame->vm().throwException(callFrame, error);
return CallFrameClosure();
}
CodeBlock* newCodeBlock = &functionExecutable->generatedBytecodeForCall();
SamplingScope samplingScope(this);
ASSERT(scope->vm() == &callFrame->vm());
- ASSERT(!vm.exception);
+ ASSERT(!vm.exception());
ASSERT(!vm.isCollectorBusy());
if (vm.isCollectorBusy())
return jsNull();
JSObject* compileError = eval->compile(callFrame, scope);
if (UNLIKELY(!!compileError))
- return checkedReturn(throwError(callFrame, compileError));
+ return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
EvalCodeBlock* codeBlock = &eval->generatedBytecode();
if (numVariables || numFunctions) {
#include "JSStack.h"
#include "LLIntData.h"
#include "Opcode.h"
+#include "SourceProvider.h"
#include <wtf/HashMap.h>
#include <wtf/text/StringBuilder.h>
void expressionInfo(int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column);
};
+ class ClearExceptionScope {
+ public:
+ ClearExceptionScope(VM* vm): m_vm(vm)
+ {
+ vm->getExceptionInfo(oldException, oldExceptionStack);
+ vm->clearException();
+ }
+ ~ClearExceptionScope()
+ {
+ m_vm->setExceptionInfo(oldException, oldExceptionStack);
+ }
+ private:
+ JSC::JSValue oldException;
+ RefCountedArray<JSC::StackFrame> oldExceptionStack;
+ VM* m_vm;
+ };
+
class TopCallFrameSetter {
public:
TopCallFrameSetter(VM& currentVM, CallFrame* callFrame)
friend class CachedCall;
friend class LLIntOffsetsExtractor;
friend class JIT;
+ friend class VM;
public:
class ErrorHandlingMode {
bool isInErrorHandlingMode() { return m_errorHandlingModeReentry; }
- NEVER_INLINE HandlerInfo* throwException(CallFrame*&, JSValue&, unsigned bytecodeOffset);
+ NEVER_INLINE HandlerInfo* unwind(CallFrame*&, JSValue&, unsigned bytecodeOffset);
NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine, int column);
- static void addStackTraceIfNecessary(CallFrame*, JSValue error);
JSString* stackTraceAsString(ExecState*, Vector<StackFrame>);
static EncodedJSValue JSC_HOST_CALL constructWithErrorConstructor(ExecState*);
JSValue JITCode::execute(JSStack* stack, CallFrame* callFrame, VM* vm)
{
JSValue result = JSValue::decode(ctiTrampoline(executableAddress(), stack, callFrame, 0, 0, vm));
- return vm->exception ? jsNull() : result;
+ return vm->exception() ? jsNull() : result;
}
#endif
ExceptionHandler genericThrow(VM* vm, ExecState* callFrame, JSValue exceptionValue, unsigned vPCIndex)
{
RELEASE_ASSERT(exceptionValue);
-
- vm->exception = JSValue();
- HandlerInfo* handler = vm->interpreter->throwException(callFrame, exceptionValue, vPCIndex); // This may update callFrame & exceptionValue!
- vm->exception = exceptionValue;
+ HandlerInfo* handler = vm->interpreter->unwind(callFrame, exceptionValue, vPCIndex); // This may update callFrame.
void* catchRoutine;
Instruction* catchPCForInterpreter = 0;
killLastResultRegister(); // FIXME: Implicitly treat op_catch as a labeled statement, and remove this line of code.
move(regT0, callFrameRegister);
peek(regT3, OBJECT_OFFSETOF(struct JITStackFrame, vm) / sizeof(void*));
- load64(Address(regT3, OBJECT_OFFSETOF(VM, exception)), regT0);
- store64(TrustedImm64(JSValue::encode(JSValue())), Address(regT3, OBJECT_OFFSETOF(VM, exception)));
+ load64(Address(regT3, VM::exceptionOffset()), regT0);
+ store64(TrustedImm64(JSValue::encode(JSValue())), Address(regT3, VM::exceptionOffset()));
emitPutVirtualRegister(currentInstruction[1].u.operand);
}
#endif // CPU(X86)
// Check for an exception
- Jump sawException = branch32(NotEqual, AbsoluteAddress(reinterpret_cast<char*>(&vm->exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag));
+ Jump sawException = branch32(NotEqual, AbsoluteAddress(reinterpret_cast<char*>(vm->addressOfException()) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag));
// Return.
ret();
// Now store the exception returned by cti_op_throw.
loadPtr(Address(stackPointerRegister, OBJECT_OFFSETOF(struct JITStackFrame, vm)), regT3);
- load32(Address(regT3, OBJECT_OFFSETOF(VM, exception) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0);
- load32(Address(regT3, OBJECT_OFFSETOF(VM, exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1);
- store32(TrustedImm32(JSValue().payload()), Address(regT3, OBJECT_OFFSETOF(VM, exception) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
- store32(TrustedImm32(JSValue().tag()), Address(regT3, OBJECT_OFFSETOF(VM, exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
+ load32(Address(regT3, VM::exceptionOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0);
+ load32(Address(regT3, VM::exceptionOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1);
+ store32(TrustedImm32(JSValue().payload()), Address(regT3, VM::exceptionOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
+ store32(TrustedImm32(JSValue().tag()), Address(regT3, VM::exceptionOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
unsigned exception = currentInstruction[1].u.operand;
emitStore(exception, regT1, regT0);
#include "DFGWorklist.h"
#include "Debugger.h"
#include "DeferGC.h"
+#include "ErrorInstance.h"
#include "ExceptionHelpers.h"
#include "GetterSetter.h"
#include "Heap.h"
// handling code out of line as possible.
static NEVER_INLINE void returnToThrowTrampoline(VM* vm, ReturnAddressPtr exceptionLocation, ReturnAddressPtr& returnAddressSlot)
{
- RELEASE_ASSERT(vm->exception);
+ RELEASE_ASSERT(vm->exception());
vm->exceptionLocation = exceptionLocation;
returnAddressSlot = ReturnAddressPtr(FunctionPtr(ctiVMThrowTrampoline));
}
#define CHECK_FOR_EXCEPTION() \
do { \
- if (UNLIKELY(stackFrame.vm->exception)) \
+ if (UNLIKELY(stackFrame.vm->exception())) \
VM_THROW_EXCEPTION(); \
} while (0)
#define CHECK_FOR_EXCEPTION_AT_END() \
do { \
- if (UNLIKELY(stackFrame.vm->exception)) \
+ if (UNLIKELY(stackFrame.vm->exception())) \
VM_THROW_EXCEPTION_AT_END(); \
} while (0)
#define CHECK_FOR_EXCEPTION_VOID() \
do { \
- if (UNLIKELY(stackFrame.vm->exception)) { \
+ if (UNLIKELY(stackFrame.vm->exception())) { \
VM_THROW_EXCEPTION_AT_END(); \
return; \
} \
JSValue m_callee;
};
-class ErrorWithExceptionFunctor : public ErrorFunctor {
- public:
- ErrorWithExceptionFunctor(JSValue exception)
- : m_exception(exception)
- {
- }
- JSValue operator()(ExecState*)
- {
- return m_exception;
- }
-
-private:
- JSValue m_exception;
-};
-
// Helper function for JIT stubs that may throw an exception in the middle of
// processing a function call. This function rolls back the stack to
// our caller, so exception processing can proceed from a valid state.
-template<typename T> static T throwExceptionFromOpCall(JITStackFrame& jitStackFrame, CallFrame* newCallFrame, ReturnAddressPtr& returnAddressSlot, ErrorFunctor& createError )
+template<typename T> static T throwExceptionFromOpCall(JITStackFrame& jitStackFrame, CallFrame* newCallFrame, ReturnAddressPtr& returnAddressSlot, ErrorFunctor* createError = 0)
{
CallFrame* callFrame = newCallFrame->callerFrame()->removeHostCallFrameFlag();
jitStackFrame.callFrame = callFrame;
callFrame->vm().topCallFrame = callFrame;
- callFrame->vm().exception = createError(callFrame);
- ASSERT(callFrame->vm().exception);
+ if (createError)
+ callFrame->vm().throwException(callFrame, (*createError)(callFrame));
+ ASSERT(callFrame->vm().exception());
returnToThrowTrampoline(&callFrame->vm(), ReturnAddressPtr(newCallFrame->returnPC()), returnAddressSlot);
return T();
}
-template<typename T> static T throwExceptionFromOpCall(JITStackFrame& jitStackFrame, CallFrame* newCallFrame, ReturnAddressPtr& returnAddressSlot)
-{
- CallFrame* callFrame = newCallFrame->callerFrame();
- ASSERT(callFrame->vm().exception);
- ErrorWithExceptionFunctor functor = ErrorWithExceptionFunctor(callFrame->vm().exception);
- return throwExceptionFromOpCall<T>(jitStackFrame, newCallFrame, returnAddressSlot, functor);
-}
-
// If the CPU specific header does not provide an implementation, use the default one here.
#ifndef DEFINE_STUB_FUNCTION
#define DEFINE_STUB_FUNCTION(rtype, op) rtype JIT_STUB cti_##op(STUB_ARGS_DECLARATION)
CallFrame* callFrame = stackFrame.callFrame;
VM* vm = stackFrame.vm;
if (UNLIKELY(vm->watchdog.didFire(callFrame))) {
- vm->exception = createTerminatedExecutionException(vm);
+ vm->throwException(callFrame, createTerminatedExecutionException(vm));
VM_THROW_EXCEPTION_AT_END();
return;
}
if (UNLIKELY(!stackFrame.stack->grow(&callFrame->registers()[callFrame->codeBlock()->m_numCalleeRegisters]))) {
ErrorWithExecFunctor functor = ErrorWithExecFunctor(createStackOverflowError);
- return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, functor);
+ return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, &functor);
}
return callFrame;
}
}
- stackFrame.vm->exception = createInvalidParameterError(callFrame, "instanceof", baseVal);
+ stackFrame.vm->throwException(callFrame, createInvalidParameterError(callFrame, "instanceof", baseVal));
VM_THROW_EXCEPTION_AT_END();
return JSValue::encode(JSValue());
}
bool couldDelete = baseObj->methodTable()->deleteProperty(baseObj, callFrame, stackFrame.args[1].identifier());
JSValue result = jsBoolean(couldDelete);
if (!couldDelete && callFrame->codeBlock()->isStrictMode())
- stackFrame.vm->exception = createTypeError(stackFrame.callFrame, "Unable to delete property.");
+ stackFrame.vm->throwException(stackFrame.callFrame, createTypeError(stackFrame.callFrame, "Unable to delete property."));
CHECK_FOR_EXCEPTION_AT_END();
return JSValue::encode(result);
JSObject* error = executable->compileFor(callFrame, callDataScopeChain, kind);
if (!error)
return function;
- callFrame->vm().exception = error;
+ callFrame->vm().throwException(callFrame, error);
return 0;
}
int missingArgCount = CommonSlowPaths::arityCheckFor(callFrame, stackFrame.stack, CodeForCall);
if (missingArgCount < 0) {
ErrorWithExecFunctor functor = ErrorWithExecFunctor(createStackOverflowError);
- return throwExceptionFromOpCall<int>(stackFrame, callFrame, STUB_RETURN_ADDRESS, functor);
+ return throwExceptionFromOpCall<int>(stackFrame, callFrame, STUB_RETURN_ADDRESS, &functor);
}
return missingArgCount;
}
int missingArgCount = CommonSlowPaths::arityCheckFor(callFrame, stackFrame.stack, CodeForConstruct);
if (missingArgCount < 0) {
ErrorWithExecFunctor functor = ErrorWithExecFunctor(createStackOverflowError);
- return throwExceptionFromOpCall<int>(stackFrame, callFrame, STUB_RETURN_ADDRESS, functor);
+ return throwExceptionFromOpCall<int>(stackFrame, callFrame, STUB_RETURN_ADDRESS, &functor);
}
return missingArgCount;
}
else {
FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
if (JSObject* error = functionExecutable->compileFor(callFrame, callee->scope(), kind)) {
- callFrame->vm().exception = error;
+ callFrame->vm().throwException(callFrame, error);
return 0;
}
codeBlock = &functionExecutable->generatedBytecodeFor(kind);
JSScope* scopeChain = callee->scope();
JSObject* error = functionExecutable->compileFor(callFrame, scopeChain, CodeForCall);
if (error) {
- callFrame->vm().exception = error;
+ callFrame->vm().throwException(callFrame, error);
return 0;
}
if (callType != CallTypeHost) {
ASSERT(callType == CallTypeNone);
ErrorWithExecAndCalleeFunctor functor = ErrorWithExecAndCalleeFunctor(createNotAFunctionError, callee);
- return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS, functor);
+ return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS, &functor);
}
EncodedJSValue returnValue;
returnValue = callData.native.function(callFrame);
}
- if (stackFrame.vm->exception)
+ if (stackFrame.vm->exception())
return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
return returnValue;
if (constructType != ConstructTypeHost) {
ASSERT(constructType == ConstructTypeNone);
ErrorWithExecAndCalleeFunctor functor = ErrorWithExecAndCalleeFunctor(createNotAConstructorError, callee);
- return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS, functor);
+ return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS, &functor);
}
EncodedJSValue returnValue;
returnValue = constructData.native.function(callFrame);
}
- if (stackFrame.vm->exception)
+ if (stackFrame.vm->exception())
return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
return returnValue;
baseValue.put(callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot);
} else {
Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
- if (!callFrame->vm().exception) { // Don't put to an object if toString threw an exception.
+ if (!callFrame->vm().exception()) { // Don't put to an object if toString threw an exception.
PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
baseValue.put(callFrame, property, value, slot);
}
RegExp* regExp = stackFrame.args[0].regExp();
if (!regExp->isValid()) {
- stackFrame.vm->exception = createSyntaxError(callFrame, "Invalid flags supplied to RegExp constructor.");
+ stackFrame.vm->throwException(callFrame, createSyntaxError(callFrame, "Invalid flags supplied to RegExp constructor."));
VM_THROW_EXCEPTION();
}
return JSValue::encode(JSValue());
JSValue result = eval(callFrame);
- if (stackFrame.vm->exception)
+ if (stackFrame.vm->exception())
return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
return JSValue::encode(result);
DEFINE_STUB_FUNCTION(void*, op_throw)
{
STUB_INIT_STACK_FRAME(stackFrame);
+ stackFrame.vm->throwException(stackFrame.callFrame, stackFrame.args[0].jsValue());
ExceptionHandler handler = jitThrow(stackFrame.vm, stackFrame.callFrame, stackFrame.args[0].jsValue(), STUB_RETURN_ADDRESS);
STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
return handler.callFrame;
CallFrame* callFrame = stackFrame.callFrame;
String message = errorDescriptionForValue(callFrame, stackFrame.args[0].jsValue())->value(callFrame);
if (stackFrame.args[1].asInt32)
- stackFrame.vm->exception = createReferenceError(callFrame, message);
+ stackFrame.vm->throwException(callFrame, createReferenceError(callFrame, message));
else
- stackFrame.vm->exception = createTypeError(callFrame, message);
+ stackFrame.vm->throwException(callFrame, createTypeError(callFrame, message));
VM_THROW_EXCEPTION_AT_END();
}
{
STUB_INIT_STACK_FRAME(stackFrame);
VM* vm = stackFrame.vm;
- ExceptionHandler handler = jitThrow(vm, stackFrame.callFrame, vm->exception, vm->exceptionLocation);
+ ExceptionHandler handler = jitThrow(vm, stackFrame.callFrame, vm->exception(), vm->exceptionLocation);
STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
return handler.callFrame;
}
VM* vm = callFrame->codeBlock()->vm();
vm->topCallFrame = callFrame;
- return encode(jitThrowNew(vm, callFrame, vm->exception));
+ return encode(jitThrowNew(vm, callFrame, vm->exception()));
}
#else
ExceptionHandler JIT_STUB cti_vm_handle_exception(CallFrame* callFrame)
VM* vm = callFrame->codeBlock()->vm();
vm->topCallFrame = callFrame;
- return jitThrowNew(vm, callFrame, vm->exception);
+ return jitThrowNew(vm, callFrame, vm->exception());
}
#endif
PropertySlot slot(scope);
if (!scope->getPropertySlot(exec, ident, slot)) {
if (modeAndType.mode() == ThrowIfNotFound) {
- throwError(exec, createUndefinedVariableError(exec, ident));
+ exec->vm().throwException(exec, createUndefinedVariableError(exec, ident));
VM_THROW_EXCEPTION();
}
return JSValue::encode(jsUndefined());
ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
if (modeAndType.mode() == ThrowIfNotFound && !scope->hasProperty(exec, ident)) {
- throwError(exec, createUndefinedVariableError(exec, ident));
+ exec->vm().throwException(exec, createUndefinedVariableError(exec, ident));
VM_THROW_EXCEPTION_AT_END();
return;
}
PutPropertySlot slot(codeBlock->isStrictMode());
scope->methodTable()->put(scope, exec, ident, value, slot);
- if (exec->vm().exception) {
+ if (exec->vm().exception()) {
VM_THROW_EXCEPTION_AT_END();
return;
}
#endif
#if USE(JSVALUE32_64)
- JIT::Jump noException = m_jit->branch32(JIT::Equal, JIT::AbsoluteAddress(reinterpret_cast<char*>(&m_jit->m_codeBlock->vm()->exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), JIT::TrustedImm32(JSValue::EmptyValueTag));
+ JIT::Jump noException = m_jit->branch32(JIT::Equal, JIT::AbsoluteAddress(reinterpret_cast<char*>(m_jit->m_codeBlock->vm()->addressOfException()) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), JIT::TrustedImm32(JSValue::EmptyValueTag));
#else
- JIT::Jump noException = m_jit->branchTest64(JIT::Zero, JIT::AbsoluteAddress(&m_jit->m_codeBlock->vm()->exception));
+ JIT::Jump noException = m_jit->branchTest64(JIT::Zero, JIT::AbsoluteAddress(m_jit->m_codeBlock->vm()->addressOfException()));
#endif
m_jit->reloadCallFrameFromTopCallFrame();
m_jit->move(JIT::TrustedImmPtr(FunctionPtr(ctiVMHandleException).value()), JIT::regT1);
// Check for an exception
#if USE(JSVALUE64)
- jit.load64(&(vm->exception), JSInterfaceJIT::regT2);
+ jit.load64(vm->addressOfException(), JSInterfaceJIT::regT2);
JSInterfaceJIT::Jump exceptionHandler = jit.branchTest64(JSInterfaceJIT::NonZero, JSInterfaceJIT::regT2);
#else
JSInterfaceJIT::Jump exceptionHandler = jit.branch32(
JSInterfaceJIT::NotEqual,
- JSInterfaceJIT::AbsoluteAddress(reinterpret_cast<char*>(&vm->exception) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
+ JSInterfaceJIT::AbsoluteAddress(reinterpret_cast<char*>(vm->addressOfException()) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
JSInterfaceJIT::TrustedImm32(JSValue::EmptyValueTag));
#endif
String fileName = exec->argument(0).toString(exec)->value(exec);
Vector<char> script;
if (!fillBufferWithContentsOfFile(fileName, script))
- return JSValue::encode(throwError(exec, createError(exec, "Could not open file.")));
+ return JSValue::encode(exec->vm().throwException(exec, createError(exec, "Could not open file.")));
GlobalObject* globalObject = GlobalObject::create(exec->vm(), GlobalObject::createStructure(exec->vm(), jsNull()), Vector<String>());
stopWatch.stop();
if (!!exception) {
- throwError(globalObject->globalExec(), exception);
+ exec->vm().throwException(globalObject->globalExec(), exception);
return JSValue::encode(jsUndefined());
}
String fileName = exec->argument(0).toString(exec)->value(exec);
Vector<char> script;
if (!fillBufferWithContentsOfFile(fileName, script))
- return JSValue::encode(throwError(exec, createError(exec, "Could not open file.")));
+ return JSValue::encode(exec->vm().throwException(exec, createError(exec, "Could not open file.")));
JSGlobalObject* globalObject = exec->lexicalGlobalObject();
JSValue evaluationException;
JSValue result = evaluate(globalObject->globalExec(), jscSource(script.data(), fileName), JSValue(), &evaluationException);
if (evaluationException)
- throwError(exec, evaluationException);
+ exec->vm().throwException(exec, evaluationException);
return JSValue::encode(result);
}
String fileName = exec->argument(0).toString(exec)->value(exec);
Vector<char> script;
if (!fillBufferWithContentsOfFile(fileName, script))
- return JSValue::encode(throwError(exec, createError(exec, "Could not open file.")));
+ return JSValue::encode(exec->vm().throwException(exec, createError(exec, "Could not open file.")));
JSGlobalObject* globalObject = exec->lexicalGlobalObject();
stopWatch.stop();
if (!validSyntax)
- throwError(exec, syntaxException);
+ exec->vm().throwException(exec, syntaxException);
return JSValue::encode(jsNumber(stopWatch.getElapsedMS()));
}
{
VM* vm = &exec->vm();
NativeCallFrameTracer tracer(vm, exec);
- genericThrow(vm, exec, vm->exception, pc - exec->codeBlock()->instructions().begin());
+ genericThrow(vm, exec, vm->exception(), pc - exec->codeBlock()->instructions().begin());
}
Instruction* returnToThrow(ExecState* exec, Instruction* pc)
{
#if LLINT_SLOW_PATH_TRACING
VM* vm = &exec->vm();
- dataLog("Throwing exception ", vm->exception, " (returnToThrow).\n");
+ dataLog("Throwing exception ", vm->exception(), " (returnToThrow).\n");
#endif
doThrow(exec, pc);
return LLInt::exceptionInstructions();
{
#if LLINT_SLOW_PATH_TRACING
VM* vm = &exec->vm();
- dataLog("Throwing exception ", vm->exception, " (callToThrow).\n");
+ dataLog("Throwing exception ", vm->exception(), " (callToThrow).\n");
#endif
doThrow(exec, pc);
return LLInt::getCodePtr(llint_throw_during_call_trampoline);
#define LLINT_END_IMPL() LLINT_RETURN_TWO(pc, exec)
#define LLINT_THROW(exceptionToThrow) do { \
- vm.exception = (exceptionToThrow); \
+ vm.throwException(exec, exceptionToThrow); \
pc = returnToThrow(exec, pc); \
LLINT_END_IMPL(); \
} while (false)
#define LLINT_CHECK_EXCEPTION() do { \
- if (UNLIKELY(vm.exception)) { \
+ if (UNLIKELY(vm.exception())) { \
pc = returnToThrow(exec, pc); \
LLINT_END_IMPL(); \
} \
#define LLINT_CALL_THROW(exec, pc, exceptionToThrow) do { \
ExecState* __ct_exec = (exec); \
Instruction* __ct_pc = (pc); \
- vm.exception = (exceptionToThrow); \
+ vm.throwException(__ct_exec, exceptionToThrow); \
LLINT_CALL_END_IMPL(__ct_exec, callToThrow(__ct_exec, __ct_pc)); \
} while (false)
#define LLINT_CALL_CHECK_EXCEPTION(exec, pc) do { \
ExecState* __cce_exec = (exec); \
Instruction* __cce_pc = (pc); \
- if (UNLIKELY(vm.exception)) \
+ if (UNLIKELY(vm.exception())) \
LLINT_CALL_END_IMPL(__cce_exec, callToThrow(__cce_exec, __cce_pc)); \
} while (false)
if (UNLIKELY(!vm.interpreter->stack().grow(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters]))) {
ReturnAddressPtr returnPC = exec->returnPC();
exec = exec->callerFrame();
- vm.exception = createStackOverflowError(exec);
+ vm.throwException(exec, createStackOverflowError(exec));
CommonSlowPaths::interpreterThrowInCaller(exec, returnPC);
pc = returnToThrowForThrownException(exec);
}
LLINT_SLOW_PATH_DECL(throw_from_native_call)
{
LLINT_BEGIN();
- ASSERT(vm.exception);
+ ASSERT(vm.exception());
LLINT_END();
}
PropertySlot slot(scope);
if (!scope->getPropertySlot(exec, ident, slot)) {
if (modeAndType.mode() == ThrowIfNotFound)
- LLINT_RETURN(throwError(exec, createUndefinedVariableError(exec, ident)));
+ LLINT_RETURN(exec->vm().throwException(exec, createUndefinedVariableError(exec, ident)));
LLINT_RETURN(jsUndefined());
}
OFFLINE_ASM_GLUE_LABEL(ctiOpThrowNotCaught)
{
- return vm->exception;
+ return vm->exception();
}
#if !ENABLE(COMPUTED_GOTO_OPCODES)
move t0, cfr
loadp JITStackFrame::vm[sp], t3
loadi VM::targetInterpreterPCForThrow[t3], PC
- loadi VM::exception + PayloadOffset[t3], t0
- loadi VM::exception + TagOffset[t3], t1
- storei 0, VM::exception + PayloadOffset[t3]
- storei EmptyValueTag, VM::exception + TagOffset[t3]
+ loadi VM::m_exception + PayloadOffset[t3], t0
+ loadi VM::m_exception + TagOffset[t3], t1
+ storei 0, VM::m_exception + PayloadOffset[t3]
+ storei EmptyValueTag, VM::m_exception + TagOffset[t3]
loadi 4[PC], t2
storei t0, PayloadOffset[cfr, t2, 8]
storei t1, TagOffset[cfr, t2, 8]
else
error
end
- bineq VM::exception + TagOffset[t3], EmptyValueTag, .exception
+ bineq VM::m_exception + TagOffset[t3], EmptyValueTag, .exception
ret
.exception:
preserveReturnAddressAfterCall(t1) # This is really only needed on X86
loadp VM::targetInterpreterPCForThrow[t3], PC
subp PB, PC
rshiftp 3, PC
- loadq VM::exception[t3], t0
- storeq 0, VM::exception[t3]
+ loadq VM::m_exception[t3], t0
+ storeq 0, VM::m_exception[t3]
loadisFromInstruction(1, t2)
storeq t0, [cfr, t2, 8]
traceExecution()
error
end
- btqnz VM::exception[t3], .exception
+ btqnz VM::m_exception[t3], .exception
ret
.exception:
preserveReturnAddressAfterCall(t1)
uint32_t n = length.toUInt32(exec);
if (n != length.toNumber(exec))
- return throwError(exec, createRangeError(exec, ASCIILiteral("Array size is not a small enough positive integer.")));
+ return exec->vm().throwException(exec, createRangeError(exec, ASCIILiteral("Array size is not a small enough positive integer.")));
return constructEmptyArray(exec, profile, globalObject, n);
}
#define END_IMPL() RETURN_TWO(pc, exec)
#define THROW(exceptionToThrow) do { \
- vm.exception = (exceptionToThrow); \
- RETURN_TO_THROW(exec, pc); \
+ vm.throwException(exec, exceptionToThrow); \
+ RETURN_TO_THROW(exec, pc); \
END_IMPL(); \
} while (false)
#define CHECK_EXCEPTION() do { \
- if (UNLIKELY(vm.exception)) { \
+ if (UNLIKELY(vm.exception())) { \
RETURN_TO_THROW(exec, pc); \
END_IMPL(); \
} \
#define CALL_THROW(exec, pc, exceptionToThrow) do { \
ExecState* ctExec = (exec); \
Instruction* ctPC = (pc); \
- vm.exception = (exceptionToThrow); \
+ vm.throwException(exec, exceptionToThrow); \
CALL_END_IMPL(ctExec, LLInt::callToThrow(ctExec, ctPC)); \
} while (false)
#define CALL_CHECK_EXCEPTION(exec, pc) do { \
ExecState* cceExec = (exec); \
Instruction* ccePC = (pc); \
- if (UNLIKELY(vm.exception)) \
+ if (UNLIKELY(vm.exception())) \
CALL_END_IMPL(cceExec, LLInt::callToThrow(cceExec, ccePC)); \
} while (false)
if (SlotsToAdd < 0) {
ReturnAddressPtr returnPC = exec->returnPC();
exec = exec->callerFrame();
- vm.exception = createStackOverflowError(exec);
+ vm.throwException(exec, createStackOverflowError(exec));
CommonSlowPaths::interpreterThrowInCaller(exec, returnPC);
RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec);
}
if (SlotsToAdd < 0) {
ReturnAddressPtr returnPC = exec->returnPC();
exec = exec->callerFrame();
- vm.exception = createStackOverflowError(exec);
+ vm.throwException(exec, createStackOverflowError(exec));
CommonSlowPaths::interpreterThrowInCaller(exec, returnPC);
RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec);
}
inline bool opIn(ExecState* exec, JSValue propName, JSValue baseVal)
{
if (!baseVal.isObject()) {
- exec->vm().exception = createInvalidParameterError(exec, "in", baseVal);
+ exec->vm().throwException(exec, createInvalidParameterError(exec, "in", baseVal));
return false;
}
return baseObj->hasProperty(exec, jsCast<NameInstance*>(propName.asCell())->privateName());
Identifier property(exec, propName.toString(exec)->value(exec));
- if (exec->vm().exception)
+ if (exec->vm().exception())
return false;
return baseObj->hasProperty(exec, property);
}
VM* vm = &exec->vm();
NativeCallFrameTracer tracer(vm, exec);
#if LLINT_SLOW_PATH_TRACING
- dataLog("Throwing exception ", vm->exception, ".\n");
+ dataLog("Throwing exception ", vm->exception(), ".\n");
#endif
genericThrow(
- vm, exec, vm->exception,
+ vm, exec, vm->exception(),
exec->codeBlock()->bytecodeOffset(exec, pc));
}
ProgramExecutable* program = ProgramExecutable::create(exec, source);
if (!program) {
if (returnedException)
- *returnedException = exec->vm().exception;
+ *returnedException = exec->vm().exception();
- exec->vm().exception = JSValue();
+ exec->vm().clearException();
return jsUndefined();
}
error->putDirect(*vm, Identifier(vm, linePropertyName), jsNumber(line), ReadOnly | DontDelete);
if (!sourceURL.isNull())
error->putDirect(*vm, Identifier(vm, sourceURLPropertyName), jsString(vm, sourceURL), ReadOnly | DontDelete);
-
- vm->interpreter->addStackTraceIfNecessary(callFrame, error);
-
return error;
}
|| error->hasProperty(exec, Identifier(exec, sourceURLPropertyName));
}
-JSValue throwError(ExecState* exec, JSValue error)
-{
- Interpreter::addStackTraceIfNecessary(exec, error);
- exec->vm().exception = error;
- return error;
-}
-
-JSObject* throwError(ExecState* exec, JSObject* error)
-{
- Interpreter::addStackTraceIfNecessary(exec, error);
- exec->vm().exception = error;
- return error;
-}
-
JSObject* throwTypeError(ExecState* exec)
{
- return throwError(exec, createTypeError(exec, ASCIILiteral("Type error")));
+ return exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Type error")));
}
JSObject* throwSyntaxError(ExecState* exec)
{
- return throwError(exec, createSyntaxError(exec, ASCIILiteral("Syntax error")));
+ return exec->vm().throwException(exec, createSyntaxError(exec, ASCIILiteral("Syntax error")));
}
const ClassInfo StrictModeTypeErrorFunction::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(StrictModeTypeErrorFunction) };
JSObject* addErrorInfo(ExecState*, JSObject* error, int line, const SourceCode&);
// Methods to throw Errors.
- JS_EXPORT_PRIVATE JSValue throwError(ExecState*, JSValue);
- JS_EXPORT_PRIVATE JSObject* throwError(ExecState*, JSObject*);
// Convenience wrappers, create an throw an exception with a default message.
JS_EXPORT_PRIVATE JSObject* throwTypeError(ExecState*);
JS_EXPORT_PRIVATE JSObject* throwSyntaxError(ExecState*);
// Convenience wrappers, wrap result as an EncodedJSValue.
- inline EncodedJSValue throwVMError(ExecState* exec, JSValue error) { return JSValue::encode(throwError(exec, error)); }
+ inline EncodedJSValue throwVMError(ExecState* exec, JSValue error) { return JSValue::encode(exec->vm().throwException(exec, error)); }
inline EncodedJSValue throwVMTypeError(ExecState* exec) { return JSValue::encode(throwTypeError(exec)); }
class StrictModeTypeErrorFunction : public InternalFunction {
JSObject* throwOutOfMemoryError(ExecState* exec)
{
- return throwError(exec, createOutOfMemoryError(exec->lexicalGlobalObject()));
+ return exec->vm().throwException(exec, createOutOfMemoryError(exec->lexicalGlobalObject()));
}
JSObject* throwStackOverflowError(ExecState* exec)
{
Interpreter::ErrorHandlingMode mode(exec);
- return throwError(exec, createStackOverflowError(exec));
+ return exec->vm().throwException(exec, createStackOverflowError(exec));
}
JSObject* throwTerminatedExecutionException(ExecState* exec)
{
Interpreter::ErrorHandlingMode mode(exec);
- return throwError(exec, createTerminatedExecutionException(&exec->vm()));
+ return exec->vm().throwException(exec, createTerminatedExecutionException(&exec->vm()));
}
} // namespace JSC
{
JSGlobalObject* globalObject = exec->lexicalGlobalObject();
if (!globalObject->evalEnabled()) {
- throwError(exec, createEvalError(exec, globalObject->evalDisabledErrorMessage()));
+ exec->vm().throwException(exec, createEvalError(exec, globalObject->evalDisabledErrorMessage()));
return 0;
}
recordParse(m_unlinkedExecutable->features(), m_unlinkedExecutable->hasCapturedVariables(), lineNo(), lastLine(), startColumn());
if (!unlinkedCodeBlock) {
- exception = error.toErrorObject(globalObject, m_source);
+ exception = vm->throwException(globalObject->globalExec(), error.toErrorObject(globalObject, m_source));
return 0;
}
JSObject* constructFunction(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args, const Identifier& functionName, const String& sourceURL, const TextPosition& position)
{
if (!globalObject->evalEnabled())
- return throwError(exec, createEvalError(exec, globalObject->evalDisabledErrorMessage()));
+ return exec->vm().throwException(exec, createEvalError(exec, globalObject->evalDisabledErrorMessage()));
return constructFunctionSkippingEvalEnabledCheck(exec, globalObject, args, functionName, sourceURL, position);
}
FunctionExecutable* function = FunctionExecutable::fromGlobalCode(functionName, exec, exec->dynamicGlobalObject()->debugger(), source, &exception);
if (!function) {
ASSERT(exception);
- return throwError(exec, exception);
+ return exec->vm().throwException(exec, exception);
}
return JSFunction::create(exec, function, globalObject);
unsigned newLen = descriptor.value().toUInt32(exec);
// d. If newLen is not equal to ToNumber( Desc.[[Value]]), throw a RangeError exception.
if (newLen != descriptor.value().toNumber(exec)) {
- throwError(exec, createRangeError(exec, "Invalid array length"));
+ exec->vm().throwException(exec, createRangeError(exec, "Invalid array length"));
return false;
}
if (propertyName == exec->propertyNames().length) {
unsigned newLength = value.toUInt32(exec);
if (value.toNumber(exec) != static_cast<double>(newLength)) {
- throwError(exec, createRangeError(exec, ASCIILiteral("Invalid array length")));
+ exec->vm().throwException(exec, createRangeError(exec, ASCIILiteral("Invalid array length")));
return;
}
thisObject->setLength(exec, newLength, slot.isStrictMode());
if (length > MAX_ARRAY_INDEX) {
methodTable()->putByIndex(this, exec, length, value, true);
if (!exec->hadException())
- throwError(exec, createRangeError(exec, "Invalid array length"));
+ exec->vm().throwException(exec, createRangeError(exec, "Invalid array length"));
return;
}
if (length > MAX_ARRAY_INDEX) {
methodTable()->putByIndex(this, exec, length, value, true);
if (!exec->hadException())
- throwError(exec, createRangeError(exec, "Invalid array length"));
+ exec->vm().throwException(exec, createRangeError(exec, "Invalid array length"));
return;
}
if (length > MAX_ARRAY_INDEX) {
methodTable()->putByIndex(this, exec, length, value, true);
if (!exec->hadException())
- throwError(exec, createRangeError(exec, "Invalid array length"));
+ exec->vm().throwException(exec, createRangeError(exec, "Invalid array length"));
return;
}
methodTable()->putByIndex(this, exec, storage->length(), value, true);
// Per ES5.1 15.4.4.7 step 6 & 15.4.5.1 step 3.d.
if (!exec->hadException())
- throwError(exec, createRangeError(exec, "Invalid array length"));
+ exec->vm().throwException(exec, createRangeError(exec, "Invalid array length"));
return;
}
return constructBooleanFromImmediateBoolean(exec, globalObject, asValue());
ASSERT(isUndefinedOrNull());
- throwError(exec, createNotAnObjectError(exec, *this));
+ exec->vm().throwException(exec, createNotAnObjectError(exec, *this));
return JSNotAnObject::create(exec);
}
return exec->lexicalGlobalObject()->booleanPrototype();
ASSERT(isUndefinedOrNull());
- throwError(exec, createNotAnObjectError(exec, *this));
+ exec->vm().throwException(exec, createNotAnObjectError(exec, *this));
return JSNotAnObject::create(exec);
}
if (offset != invalidOffset) {
if (attributes & ReadOnly) {
if (slot.isStrictMode())
- throwError(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError));
+ exec->vm().throwException(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError));
return;
}
if (descriptor.configurablePresent() && descriptor.configurable()) {
if (throwException)
- throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to configurable attribute of unconfigurable property.")));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to configurable attribute of unconfigurable property.")));
return false;
}
if (descriptor.enumerablePresent() && descriptor.enumerable()) {
if (throwException)
- throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change enumerable attribute of unconfigurable property.")));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change enumerable attribute of unconfigurable property.")));
return false;
}
if (descriptor.isAccessorDescriptor()) {
if (throwException)
- throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change access mechanism for an unconfigurable property.")));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change access mechanism for an unconfigurable property.")));
return false;
}
if (descriptor.writablePresent() && descriptor.writable()) {
if (throwException)
- throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change writable attribute of unconfigurable property.")));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change writable attribute of unconfigurable property.")));
return false;
}
if (!valueCheck) {
if (throwException)
- throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change value of a readonly property.")));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change value of a readonly property.")));
return false;
}
return true;
{
ConstructionContext context(exec->vm(), structure, length, sizeof(typename Adaptor::Type));
if (!context) {
- throwError(exec, createOutOfMemoryError(structure->globalObject()));
+ exec->vm().throwException(exec, createOutOfMemoryError(structure->globalObject()));
return 0;
}
JSGenericTypedArrayView* result =
exec->vm(), structure, length, sizeof(typename Adaptor::Type),
ConstructionContext::DontInitialize);
if (!context) {
- throwError(exec, createOutOfMemoryError(structure->globalObject()));
+ exec->vm().throwException(exec, createOutOfMemoryError(structure->globalObject()));
return 0;
}
JSGenericTypedArrayView* result =
{
RefPtr<ArrayBuffer> buffer = passedBuffer;
if (!ArrayBufferView::verifySubRange<typename Adaptor::Type>(buffer, byteOffset, length)) {
- throwError(
+ exec->vm().throwException(
exec, createRangeError(exec, "Byte offset and length out of range of buffer"));
return 0;
}
if (canAccessRangeQuickly(offset, length))
return true;
- throwError(exec, createRangeError(exec, "Range consisting of offset and length are out of bounds"));
+ exec->vm().throwException(exec, createRangeError(exec, "Range consisting of offset and length are out of bounds"));
return false;
}
return false;
if (other->length() != length) {
- throwError(exec, createRangeError(exec, "Length of incoming array changed unexpectedly."));
+ exec->vm().throwException(exec, createRangeError(exec, "Length of incoming array changed unexpectedly."));
return false;
}
{
CString cstr = exec->argument(0).toString(exec)->value(exec).utf8(StrictConversion);
if (!cstr.data())
- return throwError(exec, createURIError(exec, ASCIILiteral("String contained an illegal UTF-16 sequence.")));
+ return exec->vm().throwException(exec, createURIError(exec, ASCIILiteral("String contained an illegal UTF-16 sequence.")));
JSStringBuilder builder;
const char* p = cstr.data();
}
if (charLen == 0) {
if (strict)
- return throwError(exec, createURIError(exec, ASCIILiteral("URI error")));
+ return exec->vm().throwException(exec, createURIError(exec, ASCIILiteral("URI error")));
// The only case where we don't use "strict" mode is the "unescape" function.
// For that, it's good to support the wonky "%u" syntax for compatibility with WinIE.
if (k <= length - 6 && p[1] == 'u'
return throwVMError(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError));
if (!thisObject->setPrototypeWithCycleCheck(exec, value))
- throwError(exec, createError(exec, "cyclic __proto__ value"));
+ exec->vm().throwException(exec, createError(exec, "cyclic __proto__ value"));
return JSValue::encode(jsUndefined());
}
bool isWritable = true;
symbolTableGet(thisObject, propertyName, slot, isWritable);
if (!isWritable) {
- throwError(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError));
+ exec->vm().throwException(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError));
return;
}
}
// Handle cycle detection, and put the holder on the stack.
for (unsigned i = 0; i < m_holderStack.size(); i++) {
if (m_holderStack[i].object() == object) {
- throwError(m_exec, createTypeError(m_exec, ASCIILiteral("JSON.stringify cannot serialize cyclic structures.")));
+ m_exec->vm().throwException(m_exec, createTypeError(m_exec, ASCIILiteral("JSON.stringify cannot serialize cyclic structures.")));
return StringifyFailed;
}
}
ASSERT(inValue.isObject());
ASSERT(isJSArray(asObject(inValue)) || asObject(inValue)->inherits(JSArray::info()));
if (objectStack.size() + arrayStack.size() > maximumFilterRecursion)
- return throwError(m_exec, createStackOverflowError(m_exec));
+ return m_exec->vm().throwException(m_exec, createStackOverflowError(m_exec));
JSArray* array = asArray(inValue);
arrayStack.push(array);
ASSERT(inValue.isObject());
ASSERT(!isJSArray(asObject(inValue)) && !asObject(inValue)->inherits(JSArray::info()));
if (objectStack.size() + arrayStack.size() > maximumFilterRecursion)
- return throwError(m_exec, createStackOverflowError(m_exec));
+ return m_exec->vm().throwException(m_exec, createStackOverflowError(m_exec));
JSObject* object = asObject(inValue);
objectStack.push(object);
if (attributes & ReadOnly) {
ASSERT(thisObject->structure()->prototypeChainMayInterceptStoreTo(exec->vm(), propertyName) || obj == thisObject);
if (slot.isStrictMode())
- throwError(exec, createTypeError(exec, ASCIILiteral(StrictModeReadonlyPropertyWriteError)));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral(StrictModeReadonlyPropertyWriteError)));
return;
}
ASSERT(!exec->hadException());
- return throwError(exec, createTypeError(exec, ASCIILiteral("No default value")));
+ return exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("No default value")));
}
const HashEntry* JSObject::findPropertyHashEntry(ExecState* exec, PropertyName propertyName) const
return defaultHasInstance(exec, value, get(exec, exec->propertyNames().prototype));
if (info.implementsHasInstance())
return methodTable()->customHasInstance(this, exec, value);
- throwError(exec, createInvalidParameterError(exec, "instanceof" , this));
+ exec->vm().throwException(exec, createInvalidParameterError(exec, "instanceof" , this));
return false;
}
return false;
if (!proto.isObject()) {
- throwError(exec, createTypeError(exec, ASCIILiteral("instanceof called on an object with an invalid prototype property.")));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("instanceof called on an object with an invalid prototype property.")));
return false;
}
// unless extensions are prevented!
if (!isExtensible()) {
if (throwException)
- throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to define property on object that is not extensible.")));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to define property on object that is not extensible.")));
return false;
}
PropertyDescriptor oldDescriptor;
if (!current.configurable()) {
if (descriptor.configurable()) {
if (throwException)
- throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to configurable attribute of unconfigurable property.")));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to configurable attribute of unconfigurable property.")));
return false;
}
if (descriptor.enumerablePresent() && descriptor.enumerable() != current.enumerable()) {
if (throwException)
- throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change enumerable attribute of unconfigurable property.")));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change enumerable attribute of unconfigurable property.")));
return false;
}
}
if (descriptor.isDataDescriptor() != current.isDataDescriptor()) {
if (!current.configurable()) {
if (throwException)
- throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change access mechanism for an unconfigurable property.")));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change access mechanism for an unconfigurable property.")));
return false;
}
methodTable()->deleteProperty(this, exec, propertyName);
if (!current.configurable()) {
if (!current.writable() && descriptor.writable()) {
if (throwException)
- throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change writable attribute of unconfigurable property.")));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change writable attribute of unconfigurable property.")));
return false;
}
if (!current.writable()) {
if (descriptor.value() && !sameValue(exec, current.value(), descriptor.value())) {
if (throwException)
- throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change value of a readonly property.")));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change value of a readonly property.")));
return false;
}
}
if (!current.configurable()) {
if (descriptor.setterPresent() && !(current.setterPresent() && JSValue::strictEqual(exec, current.setter(), descriptor.setter()))) {
if (throwException)
- throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change the setter of an unconfigurable property.")));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change the setter of an unconfigurable property.")));
return false;
}
if (descriptor.getterPresent() && !(current.getterPresent() && JSValue::strictEqual(exec, current.getter(), descriptor.getter()))) {
if (throwException)
- throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change the getter of an unconfigurable property.")));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change the getter of an unconfigurable property.")));
return false;
}
}
JSObject* throwTypeError(ExecState* exec, const String& message)
{
- return throwError(exec, createTypeError(exec, message));
+ return exec->vm().throwException(exec, createTypeError(exec, message));
}
} // namespace JSC
static bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor& desc)
{
if (!in.isObject()) {
- throwError(exec, createTypeError(exec, ASCIILiteral("Property description must be an object.")));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Property description must be an object.")));
return false;
}
JSObject* description = asObject(in);
if (!get.isUndefined()) {
CallData callData;
if (getCallData(get, callData) == CallTypeNone) {
- throwError(exec, createTypeError(exec, ASCIILiteral("Getter must be a function.")));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Getter must be a function.")));
return false;
}
}
if (!set.isUndefined()) {
CallData callData;
if (getCallData(set, callData) == CallTypeNone) {
- throwError(exec, createTypeError(exec, ASCIILiteral("Setter must be a function.")));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Setter must be a function.")));
return false;
}
}
return true;
if (desc.value()) {
- throwError(exec, createTypeError(exec, ASCIILiteral("Invalid property. 'value' present on property with getter or setter.")));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Invalid property. 'value' present on property with getter or setter.")));
return false;
}
if (desc.writablePresent()) {
- throwError(exec, createTypeError(exec, ASCIILiteral("Invalid property. 'writable' present on property with getter or setter.")));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Invalid property. 'writable' present on property with getter or setter.")));
return false;
}
return true;
if (arg0.inherits(RegExpObject::info())) {
if (!arg1.isUndefined())
- return throwError(exec, createTypeError(exec, ASCIILiteral("Cannot supply flags when constructing one RegExp from another.")));
+ return exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Cannot supply flags when constructing one RegExp from another.")));
// If called as a function, this just returns the first argument (see 15.10.3.1).
if (callAsConstructor) {
RegExp* regExp = static_cast<RegExpObject*>(asObject(arg0))->regExp();
if (exec->hadException())
return 0;
if (flags == InvalidFlags)
- return throwError(exec, createSyntaxError(exec, ASCIILiteral("Invalid flags supplied to RegExp constructor.")));
+ return exec->vm().throwException(exec, createSyntaxError(exec, ASCIILiteral("Invalid flags supplied to RegExp constructor.")));
}
RegExp* regExp = RegExp::create(exec->vm(), pattern, flags);
if (!regExp->isValid())
- return throwError(exec, createSyntaxError(exec, regExp->errorMessage()));
+ return exec->vm().throwException(exec, createSyntaxError(exec, regExp->errorMessage()));
return RegExpObject::create(exec, exec->lexicalGlobalObject(), globalObject->regExpStructure(), regExp);
}
if (propertyName == exec->propertyNames().length) {
if (!object->isExtensible()) {
if (throwException)
- throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to define property on object that is not extensible.")));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to define property on object that is not extensible.")));
return false;
}
if (descriptor.configurablePresent() && descriptor.configurable()) {
if (throwException)
- throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to configurable attribute of unconfigurable property.")));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to configurable attribute of unconfigurable property.")));
return false;
}
if (descriptor.enumerablePresent() && descriptor.enumerable()) {
if (throwException)
- throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change enumerable attribute of unconfigurable property.")));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change enumerable attribute of unconfigurable property.")));
return false;
}
if (descriptor.isAccessorDescriptor()) {
if (throwException)
- throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change access mechanism for an unconfigurable property.")));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change access mechanism for an unconfigurable property.")));
return false;
}
if (descriptor.writablePresent() && descriptor.writable()) {
if (throwException)
- throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change writable attribute of unconfigurable property.")));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change writable attribute of unconfigurable property.")));
return false;
}
if (!descriptor.value())
if (propertyName == exec->propertyNames().length && sameValue(exec, descriptor.value(), jsNumber(thisObject->internalValue()->length())))
return true;
if (throwException)
- throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change value of a readonly property.")));
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change value of a readonly property.")));
return false;
}
JSValue StringRecursionChecker::throwStackOverflowError()
{
- return throwError(m_exec, createStackOverflowError(m_exec));
+ return m_exec->vm().throwException(m_exec, createStackOverflowError(m_exec));
}
JSValue StringRecursionChecker::emptyString()
#include "VM.h"
#include "ArgList.h"
+#include "CallFrameInlines.h"
+#include "CodeBlock.h"
#include "CodeCache.h"
#include "CommonIdentifiers.h"
#include "DFGLongLivedState.h"
#include "DFGWorklist.h"
#include "DebuggerActivation.h"
+#include "ErrorInstance.h"
#include "FunctionConstructor.h"
#include "GCActivityCallback.h"
#include "GetterSetter.h"
#include "Heap.h"
#include "HostCallReturnValue.h"
+#include "Identifier.h"
#include "IncrementalSweeper.h"
#include "Interpreter.h"
#include "JSActivation.h"
#include "JSAPIValueWrapper.h"
#include "JSArray.h"
#include "JSFunction.h"
+#include "JSGlobalObjectFunctions.h"
#include "JSLock.h"
#include "JSNameScope.h"
#include "JSNotAnObject.h"
heap.collectAllGarbage();
}
-void VM::clearExceptionStack()
+static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception, unsigned bytecodeOffset)
{
- m_exceptionStack = RefCountedArray<StackFrame>();
+ exception->clearAppendSourceToMessage();
+
+ if (!callFrame->codeBlock()->hasExpressionInfo())
+ return;
+
+ int startOffset = 0;
+ int endOffset = 0;
+ int divotPoint = 0;
+ unsigned line = 0;
+ unsigned column = 0;
+
+ CodeBlock* codeBlock = callFrame->codeBlock();
+ codeBlock->expressionRangeForBytecodeOffset(bytecodeOffset, divotPoint, startOffset, endOffset, line, column);
+
+ int expressionStart = divotPoint - startOffset;
+ int expressionStop = divotPoint + endOffset;
+
+ const String& sourceString = codeBlock->source()->source();
+ if (!expressionStop || expressionStart > static_cast<int>(sourceString.length()))
+ return;
+
+ VM* vm = &callFrame->vm();
+ JSValue jsMessage = exception->getDirect(*vm, vm->propertyNames->message);
+ if (!jsMessage || !jsMessage.isString())
+ return;
+
+ String message = asString(jsMessage)->value(callFrame);
+
+ if (expressionStart < expressionStop)
+ message = makeString(message, " (evaluating '", codeBlock->source()->getRange(expressionStart, expressionStop), "')");
+ else {
+ // No range information, so give a few characters of context.
+ const StringImpl* data = sourceString.impl();
+ int dataLength = sourceString.length();
+ int start = expressionStart;
+ int stop = expressionStart;
+ // Get up to 20 characters of context to the left and right of the divot, clamping to the line.
+ // Then strip whitespace.
+ while (start > 0 && (expressionStart - start < 20) && (*data)[start - 1] != '\n')
+ start--;
+ while (start < (expressionStart - 1) && isStrWhiteSpace((*data)[start]))
+ start++;
+ while (stop < dataLength && (stop - expressionStart < 20) && (*data)[stop] != '\n')
+ stop++;
+ while (stop > expressionStart && isStrWhiteSpace((*data)[stop - 1]))
+ stop--;
+ message = makeString(message, " (near '...", codeBlock->source()->getRange(start, stop), "...')");
+ }
+
+ exception->putDirect(*vm, vm->propertyNames->message, jsString(vm, message));
+}
+
+JSValue VM::throwException(ExecState* exec, JSValue error)
+{
+ ASSERT(exec == topCallFrame || exec == exec->lexicalGlobalObject()->globalExec() || exec == exec->dynamicGlobalObject()->globalExec());
+
+ Vector<StackFrame> stackTrace;
+ interpreter->getStackTrace(stackTrace);
+ m_exceptionStack = RefCountedArray<StackFrame>(stackTrace);
+ m_exception = error;
+
+ if (stackTrace.isEmpty() || !error.isObject())
+ return error;
+ JSObject* exception = asObject(error);
+
+ StackFrame stackFrame;
+ for (unsigned i = 0 ; i < stackTrace.size(); ++i) {
+ stackFrame = stackTrace.at(i);
+ if (stackFrame.bytecodeOffset)
+ break;
+ }
+ unsigned bytecodeOffset = stackFrame.bytecodeOffset;
+ if (!hasErrorInfo(exec, exception)) {
+ // FIXME: We should only really be adding these properties to VM generated exceptions,
+ // but the inspector currently requires these for all thrown objects.
+ unsigned line;
+ unsigned column;
+ stackFrame.computeLineAndColumn(line, column);
+ exception->putDirect(*this, Identifier(this, "line"), jsNumber(line), ReadOnly | DontDelete);
+ exception->putDirect(*this, Identifier(this, "column"), jsNumber(column), ReadOnly | DontDelete);
+ if (!stackFrame.sourceURL.isEmpty())
+ exception->putDirect(*this, Identifier(this, "sourceURL"), jsString(this, stackFrame.sourceURL), ReadOnly | DontDelete);
+ }
+ if (exception->isErrorInstance() && static_cast<ErrorInstance*>(exception)->appendSourceToMessage()) {
+ unsigned stackIndex = 0;
+ CallFrame* callFrame;
+ for (callFrame = exec; callFrame && !callFrame->codeBlock(); callFrame = callFrame->callerFrame()->removeHostCallFrameFlag())
+ stackIndex++;
+ stackFrame = stackTrace.at(stackIndex);
+ bytecodeOffset = stackFrame.bytecodeOffset;
+ appendSourceToError(callFrame, static_cast<ErrorInstance*>(exception), bytecodeOffset);
+ }
+
+ if (exception->hasProperty(exec, this->propertyNames->stack))
+ return error;
+
+ exception->putDirect(*this, propertyNames->stack, interpreter->stackTraceAsString(topCallFrame, stackTrace), DontEnum);
+ return error;
}
+JSObject* VM::throwException(ExecState* exec, JSObject* error)
+{
+ return asObject(throwException(exec, JSValue(error)));
+}
+void VM::getExceptionInfo(JSValue& exception, RefCountedArray<StackFrame>& exceptionStack)
+{
+ exception = m_exception;
+ exceptionStack = m_exceptionStack;
+}
+void VM::setExceptionInfo(JSValue& exception, RefCountedArray<StackFrame>& exceptionStack)
+{
+ m_exception = exception;
+ m_exceptionStack = exceptionStack;
+}
+
+void VM::clearException()
+{
+ m_exception = JSValue();
+}
+void VM:: clearExceptionStack()
+{
+ m_exceptionStack = RefCountedArray<StackFrame>();
+}
+
void releaseExecutableMemory(VM& vm)
{
vm.releaseExecutableMemory();
#endif
NativeExecutable* getHostFunction(NativeFunction, NativeFunction constructor);
- JSValue exception;
+ static ptrdiff_t exceptionOffset()
+ {
+ return OBJECT_OFFSETOF(VM, m_exception);
+ }
+
+ JS_EXPORT_PRIVATE void clearException();
JS_EXPORT_PRIVATE void clearExceptionStack();
- RefCountedArray<StackFrame>& exceptionStack() { return m_exceptionStack; }
-
+ void getExceptionInfo(JSValue& exception, RefCountedArray<StackFrame>& exceptionStack);
+ void setExceptionInfo(JSValue& exception, RefCountedArray<StackFrame>& exceptionStack);
+ JSValue exception() const { return m_exception; }
+ JSValue* addressOfException() { return &m_exception; }
+ const RefCountedArray<StackFrame>& exceptionStack() const { return m_exceptionStack; }
+
+ JS_EXPORT_PRIVATE JSValue throwException(ExecState*, JSValue);
+ JS_EXPORT_PRIVATE JSObject* throwException(ExecState*, JSObject*);
+
const ClassInfo* const jsArrayClassInfo;
const ClassInfo* const jsFinalObjectClassInfo;
private:
friend class LLIntOffsetsExtractor;
+ friend class ClearExceptionScope;
VM(VMType, HeapType);
static VM*& sharedInstanceInternal();
#if ENABLE(GC_VALIDATION)
const ClassInfo* m_initializingObjectClass;
#endif
+ JSValue m_exception;
bool m_inDefineOwnProperty;
OwnPtr<CodeCache> m_codeCache;
RefCountedArray<StackFrame> m_exceptionStack;
+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.
+
+ 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):
+
2013-08-28 Alexey Proskuryakov <ap@apple.com>
Remove an unused data member from Page.
AudioBufferSourceNode* imp = static_cast<AudioBufferSourceNode*>(impl());
AudioBuffer* buffer = toAudioBuffer(value);
if (!buffer) {
- throwError(exec, createTypeError(exec, "Value is not of type AudioBuffer"));
+ exec->vm().throwException(exec, createTypeError(exec, "Value is not of type AudioBuffer"));
return;
}
if (!imp->setBuffer(buffer))
- throwError(exec, createTypeError(exec, "AudioBuffer unsupported number of channels"));
+ exec->vm().throwException(exec, createTypeError(exec, "AudioBuffer unsupported number of channels"));
}
} // namespace WebCore
if (value.isNumber()) {
uint32_t type = value.toUInt32(exec);
if (!imp->setType(type))
- throwError(exec, createTypeError(exec, "Illegal BiquadFilterNode type"));
+ exec->vm().throwException(exec, createTypeError(exec, "Illegal BiquadFilterNode type"));
return;
}
#endif
}
}
- throwError(exec, createTypeError(exec, "Illegal BiquadFilterNode type"));
+ exec->vm().throwException(exec, createTypeError(exec, "Illegal BiquadFilterNode type"));
}
} // namespace WebCore
JSValue JSCrypto::getRandomValues(ExecState* exec)
{
if (exec->argumentCount() < 1)
- return throwError(exec, createNotEnoughArgumentsError(exec));
+ return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
JSValue buffer = exec->argument(0);
RefPtr<ArrayBufferView> arrayBufferView = toArrayBufferView(buffer);
JSObject* exceptionObject = exception.toObject(exec);
JSValue lineValue = exceptionObject->getDirect(exec->vm(), Identifier(exec, "line"));
lineNumber = lineValue && lineValue.isNumber() ? int(lineValue.toNumber(exec)) : 0;
+ JSValue columnValue = exceptionObject->getDirect(exec->vm(), Identifier(exec, "column"));
+ columnNumber = columnValue && columnValue.isNumber() ? int(columnValue.toNumber(exec)) : 0;
JSValue sourceURLValue = exceptionObject->getDirect(exec->vm(), Identifier(exec, "sourceURL"));
exceptionSourceURL = sourceURLValue && sourceURLValue.isString() ? sourceURLValue.toString(exec)->value(exec) : ASCIILiteral("undefined");
}
}
ASSERT(errorObject);
- throwError(exec, errorObject);
+ exec->vm().throwException(exec, errorObject);
}
#undef TRY_TO_CREATE_EXCEPTION
JSValue JSIDBDatabase::createObjectStore(ExecState* exec)
{
if (exec->argumentCount() < 1)
- return throwError(exec, createNotEnoughArgumentsError(exec));
+ return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
String name = exec->argument(0).toString(exec)->value(exec);
if (exec->hadException())
{
ScriptExecutionContext* context = jsCast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())->scriptExecutionContext();
if (!context)
- return throwError(exec, createReferenceError(exec, "IDBObjectStore script execution context is unavailable"));
+ return exec->vm().throwException(exec, createReferenceError(exec, "IDBObjectStore script execution context is unavailable"));
if (exec->argumentCount() < 2)
- return throwError(exec, createNotEnoughArgumentsError(exec));
+ return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
String name = exec->argument(0).toString(exec)->value(exec);
if (exec->hadException())
JSValue JSInjectedScriptHost::setFunctionVariableValue(JSC::ExecState* exec)
{
// FIXME: implement this. https://bugs.webkit.org/show_bug.cgi?id=107830
- throwError(exec, createTypeError(exec, "Variable value mutation is not supported"));
+ exec->vm().throwException(exec, createTypeError(exec, "Variable value mutation is not supported"));
return jsUndefined();
}
JSValue result = impl()->evaluate(exec->argument(0).toString(exec)->value(exec), exception);
if (exception)
- throwError(exec, exception);
+ exec->vm().throwException(exec, exception);
return result;
}
JSValue JSJavaScriptCallFrame::setVariableValue(JSC::ExecState* exec)
{
// FIXME: implement this. https://bugs.webkit.org/show_bug.cgi?id=107830
- throwError(exec, createTypeError(exec, "Variable value mutation is not supported"));
+ exec->vm().throwException(exec, createTypeError(exec, "Variable value mutation is not supported"));
return jsUndefined();
}
filter = filter.get(exec, Identifier(exec, "acceptNode"));
callType = getCallData(filter, callData);
if (callType == CallTypeNone) {
- throwError(exec, createTypeError(exec, "NodeFilter object does not have an acceptNode function"));
+ exec->vm().throwException(exec, createTypeError(exec, "NodeFilter object does not have an acceptNode function"));
return NodeFilter::FILTER_REJECT;
}
}
if (value.isNumber()) {
uint32_t type = value.toUInt32(exec);
if (!imp->setType(type))
- throwError(exec, createTypeError(exec, "Illegal OscillatorNode type"));
+ exec->vm().throwException(exec, createTypeError(exec, "Illegal OscillatorNode type"));
return;
}
#endif
}
}
- throwError(exec, createTypeError(exec, "Illegal OscillatorNode type"));
+ exec->vm().throwException(exec, createTypeError(exec, "Illegal OscillatorNode type"));
}
} // namespace WebCore
if (value.isNumber()) {
uint32_t model = value.toUInt32(exec);
if (!imp->setPanningModel(model))
- throwError(exec, createTypeError(exec, "Illegal panningModel"));
+ exec->vm().throwException(exec, createTypeError(exec, "Illegal panningModel"));
return;
}
#endif
}
}
- throwError(exec, createTypeError(exec, "Illegal panningModel"));
+ exec->vm().throwException(exec, createTypeError(exec, "Illegal panningModel"));
}
void JSPannerNode::setDistanceModel(ExecState* exec, JSValue value)
if (value.isNumber()) {
uint32_t model = value.toUInt32(exec);
if (!imp->setDistanceModel(model))
- throwError(exec, createTypeError(exec, "Illegal distanceModel"));
+ exec->vm().throwException(exec, createTypeError(exec, "Illegal distanceModel"));
return;
}
#endif
}
}
- throwError(exec, createTypeError(exec, "Illegal distanceModel"));
+ exec->vm().throwException(exec, createTypeError(exec, "Illegal distanceModel"));
}
} // namespace WebCore
SVGLength& podImp = impl()->propertyReference();
if (exec->argumentCount() < 1)
- return throwError(exec, createNotEnoughArgumentsError(exec));
+ return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
unsigned short unitType = exec->argument(0).toUInt32(exec);
if (exec->hadException())
static JSValue getObjectParameter(JSWebGLRenderingContext* obj, ExecState* exec, ObjectType objectType)
{
if (exec->argumentCount() != 2)
- return throwError(exec, createNotEnoughArgumentsError(exec));
+ return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
ExceptionCode ec = 0;
WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(obj->impl());
JSValue JSWebGLRenderingContext::getAttachedShaders(ExecState* exec)
{
if (exec->argumentCount() < 1)
- return throwError(exec, createNotEnoughArgumentsError(exec));
+ return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
ExceptionCode ec = 0;
WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(JSWebGLProgram::info()))
JSValue JSWebGLRenderingContext::getExtension(ExecState* exec)
{
if (exec->argumentCount() < 1)
- return throwError(exec, createNotEnoughArgumentsError(exec));
+ return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
const String name = exec->argument(0).toString(exec)->value(exec);
JSValue JSWebGLRenderingContext::getFramebufferAttachmentParameter(ExecState* exec)
{
if (exec->argumentCount() != 3)
- return throwError(exec, createNotEnoughArgumentsError(exec));
+ return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
ExceptionCode ec = 0;
WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
JSValue JSWebGLRenderingContext::getParameter(ExecState* exec)
{
if (exec->argumentCount() != 1)
- return throwError(exec, createNotEnoughArgumentsError(exec));
+ return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
ExceptionCode ec = 0;
WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
JSValue JSWebGLRenderingContext::getProgramParameter(ExecState* exec)
{
if (exec->argumentCount() != 2)
- return throwError(exec, createNotEnoughArgumentsError(exec));
+ return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
ExceptionCode ec = 0;
WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
JSValue JSWebGLRenderingContext::getShaderParameter(ExecState* exec)
{
if (exec->argumentCount() != 2)
- return throwError(exec, createNotEnoughArgumentsError(exec));
+ return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
ExceptionCode ec = 0;
WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
JSValue JSWebGLRenderingContext::getUniform(ExecState* exec)
{
if (exec->argumentCount() != 2)
- return throwError(exec, createNotEnoughArgumentsError(exec));
+ return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
ExceptionCode ec = 0;
WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
static JSC::JSValue dataFunctionf(DataFunctionToCall f, JSC::ExecState* exec, WebGLRenderingContext* context)
{
if (exec->argumentCount() != 2)
- return throwError(exec, createNotEnoughArgumentsError(exec));
+ return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
WebGLUniformLocation* location = 0;
long index = -1;
static JSC::JSValue dataFunctioni(DataFunctionToCall f, JSC::ExecState* exec, WebGLRenderingContext* context)
{
if (exec->argumentCount() != 2)
- return throwError(exec, createNotEnoughArgumentsError(exec));
+ return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(JSWebGLUniformLocation::info()))
return throwTypeError(exec);
static JSC::JSValue dataFunctionMatrix(DataFunctionMatrixToCall f, JSC::ExecState* exec, WebGLRenderingContext* context)
{
if (exec->argumentCount() != 3)
- return throwError(exec, createNotEnoughArgumentsError(exec));
+ return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(JSWebGLUniformLocation::info()))
return throwTypeError(exec);
JSValue JSXMLHttpRequest::open(ExecState* exec)
{
if (exec->argumentCount() < 2)
- return throwError(exec, createNotEnoughArgumentsError(exec));
+ return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
const KURL& url = impl()->scriptExecutionContext()->completeURL(exec->argument(1).toString(exec)->value(exec));
String method = exec->argument(0).toString(exec)->value(exec);
if (exception.isObject() && firstCallFrame.sourceURL().isEmpty()) {
JSValue lineValue = exceptionObject->getDirect(exec->vm(), Identifier(exec, "line"));
int lineNumber = lineValue && lineValue.isNumber() ? int(lineValue.toNumber(exec)) : 0;
+ JSValue columnValue = exceptionObject->getDirect(exec->vm(), Identifier(exec, "column"));
+ int columnNumber = columnValue && columnValue.isNumber() ? int(columnValue.toNumber(exec)) : 0;
JSValue sourceURLValue = exceptionObject->getDirect(exec->vm(), Identifier(exec, "sourceURL"));
String exceptionSourceURL = sourceURLValue && sourceURLValue.isString() ? sourceURLValue.toString(exec)->value(exec) : ASCIILiteral("undefined");
- frames[0] = ScriptCallFrame(firstCallFrame.functionName(), exceptionSourceURL, lineNumber, 0);
+ frames[0] = ScriptCallFrame(firstCallFrame.functionName(), exceptionSourceURL, lineNumber, columnNumber);
}
}
void throwStackOverflow()
{
- throwError(m_exec, createStackOverflowError(m_exec));
+ m_exec->vm().throwException(m_exec, createStackOverflowError(m_exec));
}
NO_RETURN_DUE_TO_ASSERT
void throwValidationError()
{
- throwError(m_exec, createTypeError(m_exec, "Unable to deserialize data."));
+ m_exec->vm().throwException(m_exec, createTypeError(m_exec, "Unable to deserialize data."));
}
bool isValid() const { return m_version <= CurrentVersion; }
switch (code) {
case StackOverflowError:
- throwError(exec, createStackOverflowError(exec));
+ exec->vm().throwException(exec, createStackOverflowError(exec));
break;
case ValidationError:
- throwError(exec, createTypeError(exec, "Unable to deserialize data."));
+ exec->vm().throwException(exec, createTypeError(exec, "Unable to deserialize data."));
break;
case DataCloneError:
setDOMException(exec, DATA_CLONE_ERR);
int columnNumber = 0;
String sourceURL = sourceCode.url().string();
if (m_workerGlobalScope->sanitizeScriptError(errorMessage, lineNumber, columnNumber, sourceURL, sourceCode.cachedScript()))
- *exception = ScriptValue(*m_vm, throwError(exec, createError(exec, errorMessage.impl())));
+ *exception = ScriptValue(*m_vm, exec->vm().throwException(exec, createError(exec, errorMessage.impl())));
else
*exception = ScriptValue(*m_vm, evaluationException);
}
void WorkerScriptController::setException(const ScriptValue& exception)
{
- throwError(m_workerGlobalScopeWrapper->globalExec(), exception.jsValue());
+ m_workerGlobalScopeWrapper->globalExec()->vm().throwException(m_workerGlobalScopeWrapper->globalExec(), exception.jsValue());
}
void WorkerScriptController::scheduleExecutionTermination()
{
JSLockHolder lock(exec);
- throwError(exec, createError(exec, globalExceptionString()));
+ exec->vm().throwException(exec, createError(exec, globalExceptionString()));
}
globalExceptionString() = String();
JSValue CInstance::invokeMethod(ExecState* exec, RuntimeMethod* runtimeMethod)
{
if (!asObject(runtimeMethod)->inherits(CRuntimeMethod::info()))
- return throwError(exec, createTypeError(exec, "Attempt to invoke non-plug-in method on plug-in object."));
+ return exec->vm().throwException(exec, createTypeError(exec, "Attempt to invoke non-plug-in method on plug-in object."));
CMethod* method = static_cast<CMethod*>(runtimeMethod->method());
ASSERT(method);
}
if (!retval)
- throwError(exec, createError(exec, ASCIILiteral("Error calling method on NPObject.")));
+ exec->vm().throwException(exec, createError(exec, ASCIILiteral("Error calling method on NPObject.")));
for (i = 0; i < count; i++)
_NPN_ReleaseVariantValue(&cArgs[i]);
}
if (!retval)
- throwError(exec, createError(exec, ASCIILiteral("Error calling method on NPObject.")));
+ exec->vm().throwException(exec, createError(exec, ASCIILiteral("Error calling method on NPObject.")));
for (i = 0; i < count; i++)
_NPN_ReleaseVariantValue(&cArgs[i]);
}
if (!retval)
- throwError(exec, createError(exec, ASCIILiteral("Error calling method on NPObject.")));
+ exec->vm().throwException(exec, createError(exec, ASCIILiteral("Error calling method on NPObject.")));
for (i = 0; i < count; i++)
_NPN_ReleaseVariantValue(&cArgs[i]);
}
if (!retval)
- throwError(exec, createError(exec, ASCIILiteral("Error calling method on NPObject.")));
+ exec->vm().throwException(exec, createError(exec, ASCIILiteral("Error calling method on NPObject.")));
resultValue = convertNPVariantToValue(exec, &resultVariant, m_rootObject.get());
_NPN_ReleaseVariantValue(&resultVariant);
JSValue ObjcInstance::invokeMethod(ExecState* exec, RuntimeMethod* runtimeMethod)
{
if (!asObject(runtimeMethod)->inherits(ObjCRuntimeMethod::info()))
- return throwError(exec, createTypeError(exec, "Attempt to invoke non-plug-in method on plug-in object."));
+ return exec->vm().throwException(exec, createTypeError(exec, "Attempt to invoke non-plug-in method on plug-in object."));
ObjcMethod *method = static_cast<ObjcMethod*>(runtimeMethod->method());
ASSERT(method);
void ObjcArray::setValueAt(ExecState* exec, unsigned int index, JSValue aValue) const
{
if (![_array.get() respondsToSelector:@selector(insertObject:atIndex:)]) {
- throwError(exec, createTypeError(exec, "Array is not mutable."));
+ exec->vm().throwException(exec, createTypeError(exec, "Array is not mutable."));
return;
}
if (index > [_array.get() count]) {
- throwError(exec, createRangeError(exec, "Index exceeds array size."));
+ exec->vm().throwException(exec, createRangeError(exec, "Index exceeds array size."));
return;
}
@try {
[_array.get() insertObject:oValue.objectValue atIndex:index];
} @catch(NSException* localException) {
- throwError(exec, createError(exec, "Objective-C exception."));
+ exec->vm().throwException(exec, createError(exec, "Objective-C exception."));
}
}
JSValue ObjcArray::valueAt(ExecState* exec, unsigned int index) const
{
if (index > [_array.get() count])
- return throwError(exec, createRangeError(exec, "Index exceeds array size."));
+ return exec->vm().throwException(exec, createRangeError(exec, "Index exceeds array size."));
@try {
id obj = [_array.get() objectAtIndex:index];
if (obj)
return convertObjcValueToValue (exec, &obj, ObjcObjectType, m_rootObject.get());
} @catch(NSException* localException) {
- return throwError(exec, createError(exec, "Objective-C exception."));
+ return exec->vm().throwException(exec, createError(exec, "Objective-C exception."));
}
return jsUndefined();
}
JSObject *throwError(ExecState *exec, NSString *message)
{
ASSERT(message);
- JSObject *error = JSC::throwError(exec, JSC::createError(exec, String(message)));
+ JSObject *error = exec->vm().throwException(exec, JSC::createError(exec, String(message)));
return error;
}
if (QtRuntimeMethod* method = qtinst->m_methods.value(name)) {
JSValue obj = toJS(method->jsObjectRef(context, &exception));
if (exception)
- return throwError(exec, toJS(exec, exception));
+ return exec->vm().throwException(exec, toJS(exec, exception));
return obj;
}
qtinst->m_methods.insert(name, method);
JSValue obj = toJS(method->jsObjectRef(context, &exception));
if (exception)
- return throwError(exec, toJS(exec, exception));
+ return exec->vm().throwException(exec, toJS(exec, exception));
return obj;
}
JSValueRef exception = 0;
JSValueRef jsValue = convertQVariantToValue(toRef(exec), inst->rootObject(), val, &exception);
if (exception)
- return throwError(exec, toJS(exec, exception));
+ return exec->vm().throwException(exec, toJS(exec, exception));
return toJS(exec, jsValue);
}
QString msg = QString(QLatin1String("cannot access member `%1' of deleted QObject")).arg(QLatin1String(name()));
- return throwError(exec, createError(exec, msg.toLatin1().constData()));
+ return exec->vm().throwException(exec, createError(exec, msg.toLatin1().constData()));
}
void QtField::setValueToInstance(ExecState* exec, const Instance* inst, JSValue aValue) const
JSValueRef exception = 0;
QVariant val = convertValueToQVariant(toRef(exec), toRef(exec, aValue), argtype, 0, &exception);
if (exception) {
- throwError(exec, toJS(exec, exception));
+ exec->vm().throwException(exec, toJS(exec, exception));
return;
}
if (m_type == MetaProperty) {
#endif
} else {
QString msg = QString(QLatin1String("cannot access member `%1' of deleted QObject")).arg(QLatin1String(name()));
- throwError(exec, createError(exec, msg.toLatin1().constData()));
+ exec->vm().throwException(exec, createError(exec, msg.toLatin1().constData()));
}
}
{
RuntimeArray* thisObject = jsCast<RuntimeArray*>(cell);
if (propertyName == exec->propertyNames().length) {
- throwError(exec, createRangeError(exec, "Range error"));
+ exec->vm().throwException(exec, createRangeError(exec, "Range error"));
return;
}
{
RuntimeArray* thisObject = jsCast<RuntimeArray*>(cell);
if (index >= thisObject->getLength()) {
- throwError(exec, createRangeError(exec, "Range error"));
+ exec->vm().throwException(exec, createRangeError(exec, "Range error"));
return;
}
JSObject* RuntimeObject::throwInvalidAccessError(ExecState* exec)
{
- return throwError(exec, createReferenceError(exec, "Trying to access object from destroyed plug-in."));
+ return exec->vm().throwException(exec, createReferenceError(exec, "Trying to access object from destroyed plug-in."));
}
}
+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.
+
+ 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):
+
2013-08-27 Anders Carlsson <andersca@apple.com>
Fix build.
{
JSLockHolder lock(exec);
- throwError(exec, createError(exec, globalExceptionString()));
+ exec->vm().throwException(exec, createError(exec, globalExceptionString()));
}
globalExceptionString() = String();
JSValue ProxyInstance::invokeMethod(ExecState* exec, JSC::RuntimeMethod* runtimeMethod)
{
if (!asObject(runtimeMethod)->inherits(ProxyRuntimeMethod::info()))
- return throwError(exec, createTypeError(exec, "Attempt to invoke non-plug-in method on plug-in object."));
+ return exec->vm().throwException(exec, createTypeError(exec, "Attempt to invoke non-plug-in method on plug-in object."));
ProxyMethod* method = static_cast<ProxyMethod*>(runtimeMethod->method());
ASSERT(method);
+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.
+
+ 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):
+
2013-08-28 Anders Carlsson <andersca@apple.com>
Allow the Flash plug-in to open its preference pane
releaseNPVariantValue(&arguments[i]);
if (!returnValue)
- throwError(exec, createError(exec, "Error calling method on NPObject."));
+ exec->vm().throwException(exec, createError(exec, "Error calling method on NPObject."));
JSValue propertyValue = m_objectMap->convertNPVariantToJSValue(exec, globalObject(), result);
releaseNPVariantValue(&result);
releaseNPVariantValue(&arguments[i]);
if (!returnValue)
- throwError(exec, createError(exec, "Error calling method on NPObject."));
+ exec->vm().throwException(exec, createError(exec, "Error calling method on NPObject."));
JSValue propertyValue = m_objectMap->convertNPVariantToJSValue(exec, globalObject(), result);
releaseNPVariantValue(&result);
}
if (!returnValue)
- throwError(exec, createError(exec, "Error calling method on NPObject."));
+ exec->vm().throwException(exec, createError(exec, "Error calling method on NPObject."));
JSValue value = m_objectMap->convertNPVariantToJSValue(exec, globalObject(), result);
releaseNPVariantValue(&result);
JSObject* JSNPObject::throwInvalidAccessError(ExecState* exec)
{
- return throwError(exec, createReferenceError(exec, "Trying to access object from destroyed plug-in."));
+ return exec->vm().throwException(exec, createReferenceError(exec, "Trying to access object from destroyed plug-in."));
}
} // namespace WebKit
{
JSLockHolder lock(exec);
- throwError(exec, createError(exec, globalExceptionString()));
+ exec->vm().throwException(exec, createError(exec, globalExceptionString()));
}
globalExceptionString() = String();