summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKent Hansen <khansen@trolltech.com>2009-07-09 08:20:20 (GMT)
committerKent Hansen <khansen@trolltech.com>2009-07-09 08:20:20 (GMT)
commit103439f4c8a70740d6475af1b1b58deede12d2c3 (patch)
treeedcae1809b2eae72b35cbeee7b13389977059844
parent4c0e6b163df9e12c7295d989e4240769e2e23058 (diff)
downloadQt-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.cpp23
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/PropertySlot.cpp19
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());