diff options
author | Olivier Goffart <ogoffart@trolltech.com> | 2009-08-03 14:06:30 (GMT) |
---|---|---|
committer | Olivier Goffart <ogoffart@trolltech.com> | 2009-08-03 14:06:30 (GMT) |
commit | 42aa031a16522bdcabe166881205bfa4607da693 (patch) | |
tree | 1c3ab542c188b4e52128aea7c1fb0dafdf1a98f0 /src/script/api/qscriptcontext.cpp | |
parent | 31263060c53597bfc7677ccc526cc8a19f62b387 (diff) | |
download | Qt-42aa031a16522bdcabe166881205bfa4607da693.zip Qt-42aa031a16522bdcabe166881205bfa4607da693.tar.gz Qt-42aa031a16522bdcabe166881205bfa4607da693.tar.bz2 |
QScriptContext::calledAsConstructor also works with non-native function
Use the opcode to see if it was called with op_construct
This could also work with native function, but not when they are called
with QScriptValue::call() or QScriptValue::construct()
Diffstat (limited to 'src/script/api/qscriptcontext.cpp')
-rw-r--r-- | src/script/api/qscriptcontext.cpp | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/src/script/api/qscriptcontext.cpp b/src/script/api/qscriptcontext.cpp index d68b913..99b8989 100644 --- a/src/script/api/qscriptcontext.cpp +++ b/src/script/api/qscriptcontext.cpp @@ -330,20 +330,36 @@ QScriptValue QScriptContext::argumentsObject() const */ bool QScriptContext::isCalledAsConstructor() const { - const JSC::CallFrame *frame = reinterpret_cast<const JSC::CallFrame *>(this); - //look up for the QScriptActivationObject and its calledAsConstructor flag. + JSC::CallFrame *frame = reinterpret_cast<JSC::CallFrame *>(const_cast<QScriptContext *>(this)); + + //For native functions, look up for the QScriptActivationObject and its calledAsConstructor flag. JSC::ScopeChainNode *node = frame->scopeChain(); JSC::ScopeChainIterator it(node); for (it = node->begin(); it != node->end(); ++it) { - if (!(*it)->isVariableObject()) { + if ((*it)->isVariableObject()) { if ((*it)->inherits(&QScript::QScriptActivationObject::info)) { return static_cast<QScript::QScriptActivationObject *>(*it)->d_ptr()->calledAsConstructor; } //not a native function - //### we have no way to know if is is or not a constructor - return false; + break; } } + + //Not a native function, try to look up in the bytecode if we where called from op_construct + JSC::Instruction* returnPC = frame->returnPC(); + + if (!returnPC) + return false; + + JSC::CallFrame *callerFrame = reinterpret_cast<JSC::CallFrame *>(parentContext()); + if (!callerFrame) + return false; + + if (returnPC[-JSC::op_construct_length].u.opcode == frame->interpreter()->getOpcode(JSC::op_construct)) { + //We are maybe called from the op_construct opcode which has 6 opperands. + //But we need to check we are not called from op_call with 4 opperands (by checking the argc operand) + return returnPC[-4].u.operand == frame->argumentCount(); + } return false; } |