diff options
author | Kent Hansen <kent.hansen@nokia.com> | 2010-02-11 10:55:52 (GMT) |
---|---|---|
committer | Kent Hansen <kent.hansen@nokia.com> | 2010-03-10 09:19:43 (GMT) |
commit | d73e11d56a094544f036fac3f6e4483d1104261e (patch) | |
tree | c292c8f53c660dae3f7681dc7acbbe788730a580 /src/script/api | |
parent | 20e2b87b5194abf7e9f08b7c42c030a57e2d6b28 (diff) | |
download | Qt-d73e11d56a094544f036fac3f6e4483d1104261e.zip Qt-d73e11d56a094544f036fac3f6e4483d1104261e.tar.gz Qt-d73e11d56a094544f036fac3f6e4483d1104261e.tar.bz2 |
Update src/3rdparty/javascriptcore and adapt src/script to the changes
- Update qscriptvalueiterator test to expect length property when
iterating arrays and strings.
- Use EvalExecutable::create() instead of EvalExecutable constructor.
The constructor is private.
- Reimplement getOwnPropertyDescriptor() in all custom script objects.
- Remove all reimplementations of getPropertyAttributes().
It doesn't exist in trunk anymore (getOwnPropertyDescriptor() is used
instead).
- Remove checkDontDelete argument from deleteProperty() reimplementations.
The purpose of this argument was to support deleting properties
with attribute Undeletable from C++. But it was quite an invasive
patch to JavaScriptCore, and it doesn't seem worth it. If this feature
is really crucial it should be re-done upstream.
One of the tests needed to be updated so it's not sensitive to the
C++ undeletability.
- Adapt getOwnPropertyNames() reimplementations to signature change.
- Add missing QScriptObject structure flags, otherwise we don't get all virtual calls.
- Remove our patch for reporting column numbers in the debugger callbacks.
It was just too intrusive. As with the checkDontDelete issue, this should
be redone upstream if it's really important. In 4.7, QScriptEngineAgent
will always report a column number of 1.
Other compilation fixes:
- InternalFunction::name() takes an ExecState* argument, not GlobalData*
- ScopeChain::globalObject is no longer a function but a member variable
- ScopeChainNode constructor takes a GlobalObject argument
- Heap::collect() is called collectAllGarbage()
- JSValue::strictEqual() takes an ExecState* argument
- Debugger::exception() takes a bool hasHandler argument
- Debugger no longer reports column number (we decided to drop that patch from JSC)
- UString doesn't have operator+=(char*)
- Update the autotests to reflect the columnNumber=1 change.
- Add helper class to avoid crashing inside JSC.
Ever since r52856 in WebKit trunk, this is needed. There are probably a lot of
other public API functions that need this guard as well, but I'll add them as they
are discovered.
- Update mkdist-javascriptcore tag, exclude a few more files.
- Set ENABLE_JSC_MULTIPLE_THREADS=0 define on Mac due to r52355 in trunk.
Reviewed-by: Simon Hausmann
Diffstat (limited to 'src/script/api')
-rw-r--r-- | src/script/api/qscriptcontextinfo.cpp | 2 | ||||
-rw-r--r-- | src/script/api/qscriptengine.cpp | 34 | ||||
-rw-r--r-- | src/script/api/qscriptengine_p.h | 18 | ||||
-rw-r--r-- | src/script/api/qscriptengineagent.cpp | 10 | ||||
-rw-r--r-- | src/script/api/qscriptengineagent_p.h | 7 | ||||
-rw-r--r-- | src/script/api/qscriptvalue.cpp | 11 | ||||
-rw-r--r-- | src/script/api/qscriptvalueiterator.cpp | 3 |
7 files changed, 56 insertions, 29 deletions
diff --git a/src/script/api/qscriptcontextinfo.cpp b/src/script/api/qscriptcontextinfo.cpp index cc5fcc1..ebb1770 100644 --- a/src/script/api/qscriptcontextinfo.cpp +++ b/src/script/api/qscriptcontextinfo.cpp @@ -181,7 +181,7 @@ QScriptContextInfoPrivate::QScriptContextInfoPrivate(const QScriptContext *conte // Get the others informations: JSC::JSObject *callee = frame->callee(); if (callee && callee->inherits(&JSC::InternalFunction::info)) - functionName = JSC::asInternalFunction(callee)->name(&frame->globalData()); + functionName = JSC::asInternalFunction(callee)->name(frame); if (callee && callee->inherits(&JSC::JSFunction::info)) { functionType = QScriptContextInfo::ScriptFunction; JSC::FunctionExecutable *body = JSC::asFunction(callee)->jsExecutable(); diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 024b4d0..6adb3de 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -898,6 +898,8 @@ QScriptEnginePrivate::QScriptEnginePrivate() QScriptEnginePrivate::~QScriptEnginePrivate() { + JSC::setCurrentIdentifierTable(globalData->identifierTable); + //disconnect all loadedScripts and generate all jsc::debugger::scriptUnload events QHash<intptr_t,QScript::UStringSourceProviderWithFeedback*>::const_iterator it; for (it = loadedScripts.constBegin(); it != loadedScripts.constEnd(); ++it) @@ -988,8 +990,7 @@ JSC::JSValue QScriptEnginePrivate::objectFromVariantMap(JSC::ExecState *exec, co QVariantMap QScriptEnginePrivate::variantMapFromObject(JSC::ExecState *exec, JSC::JSValue obj) { JSC::PropertyNameArray propertyNames(exec); - propertyNames.setShouldCache(false); - JSC::asObject(obj)->getOwnPropertyNames(exec, propertyNames, /*includeNonEnumerable=*/true); + JSC::asObject(obj)->getOwnPropertyNames(exec, propertyNames, JSC::IncludeDontEnumProperties); QVariantMap vmap; JSC::PropertyNameArray::const_iterator it = propertyNames.begin(); for( ; it != propertyNames.end(); ++it) @@ -1187,7 +1188,8 @@ bool QScriptEnginePrivate::isCollecting() const void QScriptEnginePrivate::collectGarbage() { JSC::JSLock lock(false); - globalData->heap.collect(); + QScript::APIShim shim(this); + globalData->heap.collectAllGarbage(); } QScript::TimeoutCheckerProxy *QScriptEnginePrivate::timeoutChecker() const @@ -1218,7 +1220,7 @@ JSC::JSValue QScriptEnginePrivate::evaluateHelper(JSC::ExecState *exec, intptr_t debugger->evaluateStart(sourceId); q->clearExceptions(); - JSC::DynamicGlobalObjectScope dynamicGlobalObjectScope(exec, exec->scopeChain()->globalObject()); + JSC::DynamicGlobalObjectScope dynamicGlobalObjectScope(exec, exec->scopeChain()->globalObject); if (compile) { JSC::JSObject* error = executable->compile(exec, exec->scopeChain()); @@ -1670,15 +1672,15 @@ void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue object // deleting getter/setter if ((flags & QScriptValue::PropertyGetter) && (flags & QScriptValue::PropertySetter)) { // deleting both: just delete the property - thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); + thisObject->deleteProperty(exec, id); } else if (flags & QScriptValue::PropertyGetter) { // preserve setter, if there is one - thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); + thisObject->deleteProperty(exec, id); if (setter && setter.isObject()) thisObject->defineSetter(exec, id, JSC::asObject(setter)); } else { // flags & QScriptValue::PropertySetter // preserve getter, if there is one - thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); + thisObject->deleteProperty(exec, id); if (getter && getter.isObject()) thisObject->defineGetter(exec, id, JSC::asObject(getter)); } @@ -1708,10 +1710,10 @@ void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue object } if (!value) { // ### check if it's a getter/setter property - thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); + thisObject->deleteProperty(exec, id); } else if (flags != QScriptValue::KeepExistingFlags) { if (thisObject->hasOwnProperty(exec, id)) - thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); // ### hmmm - can't we just update the attributes? + thisObject->deleteProperty(exec, id); // ### hmmm - can't we just update the attributes? unsigned attribs = 0; if (flags & QScriptValue::ReadOnly) attribs |= JSC::ReadOnly; @@ -1732,7 +1734,7 @@ void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue object JSC::JSValue value, const QScriptValue::PropertyFlags &flags) { if (!value) { - JSC::asObject(objectValue)->deleteProperty(exec, index, /*checkDontDelete=*/false); + JSC::asObject(objectValue)->deleteProperty(exec, index); } else { if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) { // fall back to string-based setProperty(), since there is no @@ -1766,7 +1768,7 @@ QScriptValue::PropertyFlags QScriptEnginePrivate::propertyFlags(JSC::ExecState * JSC::PropertyDescriptor descriptor; if (object->getOwnPropertyDescriptor(exec, id, descriptor)) attribs = descriptor.attributes(); - else if (!object->getPropertyAttributes(exec, id, attribs)) { + else { if ((mode & QScriptValue::ResolvePrototype) && object->prototype() && object->prototype().isObject()) { JSC::JSValue proto = object->prototype(); return propertyFlags(exec, proto, id, mode); @@ -2466,15 +2468,16 @@ QScriptSyntaxCheckResult QScriptEnginePrivate::checkSyntax(const QString &progra QScriptValue QScriptEngine::evaluate(const QString &program, const QString &fileName, int lineNumber) { Q_D(QScriptEngine); + QScript::APIShim shim(d); WTF::PassRefPtr<QScript::UStringSourceProviderWithFeedback> provider = QScript::UStringSourceProviderWithFeedback::create(program, fileName, lineNumber, d); intptr_t sourceId = provider->asID(); JSC::SourceCode source(provider, lineNumber); //after construction of SourceCode provider variable will be null. JSC::ExecState* exec = d->currentFrame; - JSC::EvalExecutable executable(exec, source); + WTF::RefPtr<JSC::EvalExecutable> executable = JSC::EvalExecutable::create(exec, source); bool compile = true; - return d->scriptValueFromJSCValue(d->evaluateHelper(exec, sourceId, &executable, compile)); + return d->scriptValueFromJSCValue(d->evaluateHelper(exec, sourceId, executable.get(), compile)); } /*! @@ -2491,6 +2494,7 @@ QScriptValue QScriptEngine::evaluate(const QScriptProgram &program) if (!program_d) return QScriptValue(); + QScript::APIShim shim(d); JSC::ExecState* exec = d->currentFrame; JSC::EvalExecutable *executable = program_d->executable(exec, d); bool compile = !program_d->isCompiled; @@ -2603,7 +2607,7 @@ JSC::CallFrame *QScriptEnginePrivate::pushContext(JSC::CallFrame *exec, JSC::JSV newCallFrame->init(0, /*vPC=*/0, exec->scopeChain(), exec, flags | ShouldRestoreCallFrame, argc, callee); } else { JSC::JSObject *jscObject = originalGlobalObject(); - JSC::ScopeChainNode *scn = new JSC::ScopeChainNode(0, jscObject, &exec->globalData(), jscObject); + JSC::ScopeChainNode *scn = new JSC::ScopeChainNode(0, jscObject, &exec->globalData(), exec->lexicalGlobalObject(), jscObject); newCallFrame->init(0, /*vPC=*/0, scn, exec, flags | ShouldRestoreCallFrame, argc, callee); } } else { @@ -2935,7 +2939,7 @@ JSC::JSValue QScriptEnginePrivate::create(JSC::ExecState *exec, int type, const } } if (result && result.isObject() && info && info->prototype - && JSC::JSValue::strictEqual(JSC::asObject(result)->prototype(), eng->originalGlobalObject()->objectPrototype())) { + && JSC::JSValue::strictEqual(exec, JSC::asObject(result)->prototype(), eng->originalGlobalObject()->objectPrototype())) { JSC::asObject(result)->setPrototype(info->prototype); } return result; diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index 5166d89..8265599 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -383,6 +383,23 @@ public: namespace QScript { +class APIShim +{ +public: + APIShim(QScriptEnginePrivate *engine) + : m_engine(engine), m_oldTable(JSC::setCurrentIdentifierTable(engine->globalData->identifierTable)) + { + } + ~APIShim() + { + JSC::setCurrentIdentifierTable(m_oldTable); + } + +private: + QScriptEnginePrivate *m_engine; + JSC::IdentifierTable *m_oldTable; +}; + /*Helper class. Main purpose is to give debugger feedback about unloading and loading scripts. It keeps pointer to JSGlobalObject assuming that it is always the same - there is no way to update this data. Class is internal and used as an implementation detail in and only in QScriptEngine::evaluate.*/ @@ -779,6 +796,7 @@ inline void QScriptEnginePrivate::unregisterScriptString(QScriptStringPrivate *v registeredScriptStrings = value->next; value->prev = 0; value->next = 0; + JSC::setCurrentIdentifierTable(globalData->identifierTable); } inline QScriptContext *QScriptEnginePrivate::contextForFrame(JSC::ExecState *frame) diff --git a/src/script/api/qscriptengineagent.cpp b/src/script/api/qscriptengineagent.cpp index 3bd97eb..28905e8 100644 --- a/src/script/api/qscriptengineagent.cpp +++ b/src/script/api/qscriptengineagent.cpp @@ -151,14 +151,15 @@ void QScriptEngineAgentPrivate::exceptionCatch(const JSC::DebuggerCallFrame& fra engine->clearCurrentException(); } -void QScriptEngineAgentPrivate::atStatement(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno, int column) +void QScriptEngineAgentPrivate::atStatement(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno/*, int column*/) { QScript::UStringSourceProviderWithFeedback *source = engine->loadedScripts.value(sourceID); if (!source) { // QTBUG-6108: We don't have the source for this script, so ignore. return; } - column = source->columnNumberFromOffset(column); +// column = source->columnNumberFromOffset(column); + int column = 1; JSC::CallFrame *oldFrame = engine->currentFrame; int oldAgentLineNumber = engine->agentLineNumber; engine->currentFrame = frame.callFrame(); @@ -182,7 +183,7 @@ void QScriptEngineAgentPrivate::evaluateStop(const JSC::JSValue& returnValue, in } void QScriptEngineAgentPrivate::didReachBreakpoint(const JSC::DebuggerCallFrame& frame, - intptr_t sourceID, int lineno, int column) + intptr_t sourceID, int lineno/*, int column*/) { if (q_ptr->supportsExtension(QScriptEngineAgent::DebuggerInvocationRequest)) { QScript::UStringSourceProviderWithFeedback *source = engine->loadedScripts.value(sourceID); @@ -190,7 +191,8 @@ void QScriptEngineAgentPrivate::didReachBreakpoint(const JSC::DebuggerCallFrame& // QTBUG-6108: We don't have the source for this script, so ignore. return; } - column = source->columnNumberFromOffset(column); +// column = source->columnNumberFromOffset(column); + int column = 1; JSC::CallFrame *oldFrame = engine->currentFrame; int oldAgentLineNumber = engine->agentLineNumber; engine->currentFrame = frame.callFrame(); diff --git a/src/script/api/qscriptengineagent_p.h b/src/script/api/qscriptengineagent_p.h index 8354143..fd10e68 100644 --- a/src/script/api/qscriptengineagent_p.h +++ b/src/script/api/qscriptengineagent_p.h @@ -75,17 +75,18 @@ public: }; //exceptions - virtual void exception(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno) + virtual void exception(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno, bool hasHandler) { Q_UNUSED(frame); Q_UNUSED(sourceID); Q_UNUSED(lineno); + Q_UNUSED(hasHandler); }; virtual void exceptionThrow(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, bool hasHandler); virtual void exceptionCatch(const JSC::DebuggerCallFrame& frame, intptr_t sourceID); //statements - virtual void atStatement(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno, int column); + virtual void atStatement(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno/*, int column*/); virtual void callEvent(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno) { Q_UNUSED(lineno); @@ -107,7 +108,7 @@ public: }; virtual void functionExit(const JSC::JSValue& returnValue, intptr_t sourceID); //others - virtual void didReachBreakpoint(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno, int column); + virtual void didReachBreakpoint(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno/*, int column*/); virtual void evaluateStart(intptr_t sourceID) { diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index 414a45c..458bab8 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -898,18 +898,21 @@ bool QScriptValue::strictlyEquals(const QScriptValue &other) const if (d->type == QScriptValuePrivate::JavaScriptCore) { QScriptEnginePrivate *eng_p = d->engine ? d->engine : other.d_ptr->engine; if (eng_p) - return JSC::JSValue::strictEqual(d->jscValue, eng_p->scriptValueToJSCValue(other)); + return JSC::JSValue::strictEqual(eng_p->currentFrame, d->jscValue, eng_p->scriptValueToJSCValue(other)); } else if (other.d_ptr->type == QScriptValuePrivate::JavaScriptCore) { QScriptEnginePrivate *eng_p = other.d_ptr->engine ? other.d_ptr->engine : d->engine; if (eng_p) - return JSC::JSValue::strictEqual(eng_p->scriptValueToJSCValue(*this), other.d_ptr->jscValue); + return JSC::JSValue::strictEqual(eng_p->currentFrame, eng_p->scriptValueToJSCValue(*this), other.d_ptr->jscValue); } return false; } switch (d->type) { - case QScriptValuePrivate::JavaScriptCore: - return JSC::JSValue::strictEqual(d->jscValue, other.d_ptr->jscValue); + case QScriptValuePrivate::JavaScriptCore: { + QScriptEnginePrivate *eng_p = d->engine ? d->engine : other.d_ptr->engine; + JSC::ExecState *exec = eng_p ? eng_p->currentFrame : 0; + return JSC::JSValue::strictEqual(exec, d->jscValue, other.d_ptr->jscValue); + } case QScriptValuePrivate::Number: return (d->numberValue == other.d_ptr->numberValue); case QScriptValuePrivate::String: diff --git a/src/script/api/qscriptvalueiterator.cpp b/src/script/api/qscriptvalueiterator.cpp index 24d9754..5737435 100644 --- a/src/script/api/qscriptvalueiterator.cpp +++ b/src/script/api/qscriptvalueiterator.cpp @@ -91,8 +91,7 @@ public: QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(object.engine()); JSC::ExecState *exec = eng_p->globalExec(); JSC::PropertyNameArray propertyNamesArray(exec); - propertyNamesArray.setShouldCache(false); - JSC::asObject(QScriptValuePrivate::get(object)->jscValue)->getOwnPropertyNames(exec, propertyNamesArray, /*includeNonEnumerable=*/true); + JSC::asObject(QScriptValuePrivate::get(object)->jscValue)->getOwnPropertyNames(exec, propertyNamesArray, JSC::IncludeDontEnumProperties); JSC::PropertyNameArray::const_iterator propertyNamesIt = propertyNamesArray.begin(); for(; propertyNamesIt != propertyNamesArray.end(); ++propertyNamesIt) { |