diff options
author | Kent Hansen <khansen@trolltech.com> | 2009-07-09 08:20:20 (GMT) |
---|---|---|
committer | Kent Hansen <khansen@trolltech.com> | 2009-07-09 08:20:20 (GMT) |
commit | 103439f4c8a70740d6475af1b1b58deede12d2c3 (patch) | |
tree | edcae1809b2eae72b35cbeee7b13389977059844 | |
parent | 4c0e6b163df9e12c7295d989e4240769e2e23058 (diff) | |
download | Qt-103439f4c8a70740d6475af1b1b58deede12d2c3.zip Qt-103439f4c8a70740d6475af1b1b58deede12d2c3.tar.gz Qt-103439f4c8a70740d6475af1b1b58deede12d2c3.tar.bz2 |
create a new frame when executing native getter/setter functions
Frames are created when calling JS functions, so they should be
when calling native functions as well. This makes QScriptContext
behave correctly in these cases (see getSetProperty autotest).
-rw-r--r-- | src/3rdparty/webkit/JavaScriptCore/runtime/CallData.cpp | 23 | ||||
-rw-r--r-- | src/3rdparty/webkit/JavaScriptCore/runtime/PropertySlot.cpp | 19 |
2 files changed, 38 insertions, 4 deletions
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/CallData.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/CallData.cpp index 62e42fe..0579b27 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/CallData.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/CallData.cpp @@ -25,6 +25,8 @@ #include "config.h" #include "CallData.h" +#include "ExceptionHelpers.h" +#include "Interpreter.h" #include "JSFunction.h" @@ -32,8 +34,25 @@ namespace JSC { JSValue call(ExecState* exec, JSValue functionObject, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args) { - if (callType == CallTypeHost) - return callData.native.function(exec, asObject(functionObject), thisValue, args); + if (callType == CallTypeHost) { + ScopeChainNode* scopeChain = exec->scopeChain(); + Interpreter *interp = exec->interpreter(); + Register *oldEnd = interp->registerFile().end(); + int argc = 1 + args.size(); // implicit "this" parameter + if (!interp->registerFile().grow(oldEnd + argc + RegisterFile::CallFrameHeaderSize)) + return createStackOverflowError(exec); + CallFrame* newCallFrame = CallFrame::create(oldEnd); + newCallFrame[0] = thisValue; + size_t dst = 0; + ArgList::const_iterator it; + for (it = args.begin(); it != args.end(); ++it) + newCallFrame[++dst] = *it; + newCallFrame += argc + JSC::RegisterFile::CallFrameHeaderSize; + newCallFrame->init(0, /*vPC=*/0, scopeChain, exec, 0, argc, asObject(functionObject)); + JSValue result = callData.native.function(newCallFrame, asObject(functionObject), thisValue, args); + interp->registerFile().shrink(oldEnd); + return result; + } ASSERT(callType == CallTypeJS); // FIXME: Can this be done more efficiently using the callData? return asFunction(functionObject)->call(exec, thisValue, args); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertySlot.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertySlot.cpp index 36fa5d8..e0a1b5d 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertySlot.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertySlot.cpp @@ -19,6 +19,8 @@ */ #include "config.h" +#include "ExceptionHelpers.h" +#include "Interpreter.h" #include "PropertySlot.h" #include "JSFunction.h" @@ -35,8 +37,21 @@ JSValue PropertySlot::functionGetter(ExecState* exec, const Identifier&, const P CallData callData; CallType callType = slot.m_data.getterFunc->getCallData(callData); - if (callType == CallTypeHost) - return callData.native.function(exec, slot.m_data.getterFunc, slot.slotBase(), exec->emptyList()); + if (callType == CallTypeHost) { + ScopeChainNode* scopeChain = exec->scopeChain(); + Interpreter *interp = exec->interpreter(); + Register *oldEnd = interp->registerFile().end(); + int argc = 1; // implicit "this" parameter + if (!interp->registerFile().grow(oldEnd + argc + RegisterFile::CallFrameHeaderSize)) + return createStackOverflowError(exec); + JSC::CallFrame* newCallFrame = JSC::CallFrame::create(oldEnd); + newCallFrame[0] = slot.slotBase(); // this + newCallFrame += argc + JSC::RegisterFile::CallFrameHeaderSize; + newCallFrame->init(0, /*vPC=*/0, scopeChain, exec, 0, argc, slot.m_data.getterFunc); + JSValue result = callData.native.function(newCallFrame, slot.m_data.getterFunc, slot.slotBase(), exec->emptyList()); + interp->registerFile().shrink(oldEnd); + return result; + } ASSERT(callType == CallTypeJS); // FIXME: Can this be done more efficiently using the callData? return static_cast<JSFunction*>(slot.m_data.getterFunc)->call(exec, slot.slotBase(), exec->emptyList()); |