summaryrefslogtreecommitdiff
path: root/src/script/qscriptcontext_p.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/script/qscriptcontext_p.cpp')
-rw-r--r--src/script/qscriptcontext_p.cpp2598
1 files changed, 0 insertions, 2598 deletions
diff --git a/src/script/qscriptcontext_p.cpp b/src/script/qscriptcontext_p.cpp
deleted file mode 100644
index f19ba9c155..0000000000
--- a/src/script/qscriptcontext_p.cpp
+++ /dev/null
@@ -1,2598 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-** This file is part of the QtScript module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the either Technology Preview License Agreement or the
-** Beta Release License Agreement.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain
-** additional rights. These rights are described in the Nokia Qt LGPL
-** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
-** package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at qt-sales@nokia.com.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/QtDebug>
-
-#ifndef QT_NO_SCRIPT
-
-#include "qscriptcontext_p.h"
-#include "qscriptengine_p.h"
-#include "qscriptvalueimpl_p.h"
-#include "qscriptmember_p.h"
-#include "qscriptobject_p.h"
-#include "qscriptprettypretty_p.h"
-#include "qscriptast_p.h"
-#include "qscriptnodepool_p.h"
-#include "qscriptcompiler_p.h"
-#include "qscriptextenumeration_p.h"
-
-#include <math.h> // floor & friends...
-
-QT_BEGIN_NAMESPACE
-
-#define Q_SCRIPT_NO_PRINT_GENERATED_CODE
-
-#define Q_SCRIPT_NO_JOINED_FUNCTION
-
-#define CHECK_TEMPSTACK(needed) do { \
- if (stackPtr + needed >= eng->tempStackEnd) { \
- throwError(QLatin1String("out of memory")); \
- HandleException(); \
- } \
-} while (0)
-
-#ifndef Q_SCRIPT_NO_PRINT_GENERATED_CODE
-static QTextStream qout(stderr, QIODevice::WriteOnly);
-#endif
-
-static inline void qscript_uint_to_string_helper(uint i, QString &s)
-{
- switch (i) {
- case 0: case 1: case 2: case 3: case 4:
- case 5: case 6: case 7: case 8: case 9:
- s += QLatin1Char('0' + i);
- break;
-
- default:
- qscript_uint_to_string_helper(i / 10, s);
- s += QLatin1Char('0' + (i % 10));
- }
-}
-
-static inline void qscript_uint_to_string(qsreal i, QString &s)
-{
- if ((i < 0) || (i > 0xFFFFFFFF))
- return; // nothing to do
-
- qsreal x = ::fmod(i, 10);
-
- if (x != 0.0 && x != 1.0
- && x != 2.0 && x != 3.0
- && x != 4.0 && x != 5.0
- && x != 6.0 && x != 7.0
- && x != 8.0 && x != 9.0)
- return; // nothing to do
-
- qscript_uint_to_string_helper(uint(i), s);
-}
-
-static inline quint32 toArrayIndex(const QScriptValueImpl &v)
-{
- if (v.isNumber()) {
- quint32 ui = v.toUInt32();
- if (qsreal(ui) == v.m_number_value)
- return ui;
- } else if (v.isString()) {
- QByteArray bytes = v.m_string_value->s.toUtf8();
- char *eptr;
- quint32 pos = strtoul(bytes.constData(), &eptr, 10);
- if ((eptr == bytes.constData() + bytes.size())
- && (QByteArray::number(pos) == bytes)) {
- return pos;
- }
- }
- return 0xFFFFFFFF;
-}
-
-#define CREATE_MEMBER(__obj__, __name__, __member__, __flags__) do { \
- (__obj__).createMember(__name__, __member__, __flags__); \
- eng->adjustBytesAllocated(sizeof(QScript::Member) + sizeof(QScriptValueImpl)); \
-} while (0)
-
-#define BEGIN_PREFIX_OPERATOR \
- QScriptValue::ResolveFlags mode; \
- mode = QScriptValue::ResolveFlags(stackPtr[0].m_int_value) \
- | QScriptValue::ResolvePrototype; \
- --stackPtr; \
- QScriptValueImpl object = eng->toObject(stackPtr[-1]); \
- if (!object.isObject()) { \
- stackPtr -= 2; \
- throwTypeError(QLatin1String("not an object")); \
- HandleException(); \
- } \
- QScriptNameIdImpl *memberName = 0; \
- if (stackPtr[0].isString() && stackPtr[0].m_string_value->unique) \
- memberName = stackPtr[0].m_string_value; \
- else \
- memberName = eng->nameId(stackPtr[0].toString(), /*persistent=*/false); \
- QScript::Member member; \
- QScriptValueImpl base; \
- QScriptValueImpl value; \
- QScriptValueImpl getter; \
- QScriptValueImpl setter; \
- const bool isMemberAssignment = (object.m_object_value != m_scopeChain.m_object_value); \
- if (object.resolve(memberName, &member, &base, mode, QScript::ReadWrite)) { \
- base.get(member, &value); \
- if (hasUncaughtException()) { \
- stackPtr -= 2; \
- HandleException(); \
- } else if (member.isGetterOrSetter()) { \
- if (member.isGetter()) { \
- getter = value; \
- if (!member.isSetter() && !base.m_object_value->findSetter(&member)) { \
- stackPtr -= 2; \
- throwError(QLatin1String("No setter defined")); \
- HandleException(); \
- } \
- base.get(member, &setter); \
- } else { \
- setter = value; \
- QScript::Member tmp = member; \
- if (!base.m_object_value->findGetter(&member)) { \
- stackPtr -= 2; \
- throwError(QLatin1String("No getter defined")); \
- HandleException(); \
- } \
- base.get(member, &getter); \
- member = tmp; \
- } \
- value = getter.call(object); \
- if (hasUncaughtException()) { \
- stackPtr -= 2; \
- Done(); \
- } \
- } \
- } else if (!isMemberAssignment) { \
- stackPtr -= 2; \
- throwNotDefined(memberName); \
- HandleException(); \
- } else { \
- base = object; \
- CREATE_MEMBER(base, memberName, &member, /*flags=*/0); \
- value = undefined; \
- }
-
-#define END_PREFIX_OPERATOR \
- if (member.isSetter()) { \
- setter.call(object, QScriptValueImplList() << value); \
- if (hasUncaughtException()) { \
- stackPtr -= 2; \
- Done(); \
- } \
- } else { \
- if (member.isWritable()) { \
- if (isMemberAssignment && (base.m_object_value != object.m_object_value)) { \
- base = object; \
- CREATE_MEMBER(base, memberName, &member, /*flags=*/0); \
- } \
- base.put(member, value); \
- if (hasUncaughtException()) { \
- stackPtr -= 2; \
- HandleException(); \
- } \
- } \
- } \
- *--stackPtr = value; \
- ++iPtr;
-
-#define BEGIN_INPLACE_OPERATOR \
- if (! stackPtr[-1].isReference()) { \
- stackPtr -= 2; \
- throwSyntaxError(QLatin1String("invalid assignment lvalue")); \
- HandleException(); \
- } \
- QScriptValue::ResolveFlags mode; \
- mode = QScriptValue::ResolveFlags(stackPtr[-1].m_int_value) \
- | QScriptValue::ResolvePrototype; \
- QScriptValueImpl object = eng->toObject(stackPtr[-3]); \
- if (! object.isValid()) { \
- stackPtr -= 4; \
- throwTypeError(QLatin1String("not an object")); \
- HandleException(); \
- } \
- QScriptNameIdImpl *memberName = 0; \
- if (stackPtr[-2].isString() && stackPtr[-2].m_string_value->unique) \
- memberName = stackPtr[-2].m_string_value; \
- else \
- memberName = eng->nameId(stackPtr[-2].toString(), /*persistent=*/false); \
- QScriptValueImpl lhs; \
- QScriptValueImpl base; \
- QScript::Member member; \
- QScriptValueImpl getter; \
- QScriptValueImpl setter; \
- const bool isMemberAssignment = (object.m_object_value != m_scopeChain.m_object_value); \
- if (object.resolve(memberName, &member, &base, mode, QScript::ReadWrite)) { \
- base.get(member, &lhs); \
- if (hasUncaughtException()) { \
- stackPtr -= 4; \
- HandleException(); \
- } else if (member.isGetterOrSetter()) { \
- if (member.isGetter()) { \
- getter = lhs; \
- if (!member.isSetter() && !base.m_object_value->findSetter(&member)) { \
- stackPtr -= 4; \
- throwError(QLatin1String("No setter defined")); \
- HandleException(); \
- } \
- base.get(member, &setter); \
- } else { \
- setter = lhs; \
- QScript::Member tmp = member; \
- if (!base.m_object_value->findGetter(&member)) { \
- stackPtr -= 4; \
- throwError(QLatin1String("No getter defined")); \
- HandleException(); \
- } \
- base.get(member, &getter); \
- member = tmp; \
- } \
- lhs = getter.call(object); \
- if (hasUncaughtException()) { \
- stackPtr -= 4; \
- Done(); \
- } \
- } \
- } else if (!isMemberAssignment) { \
- stackPtr -= 4; \
- throwNotDefined(memberName); \
- HandleException(); \
- } else { \
- base = object; \
- CREATE_MEMBER(base, memberName, &member, /*flags=*/0); \
- lhs = undefined; \
- } \
- QScriptValueImpl rhs = stackPtr[0];
-
-#define END_INPLACE_OPERATOR \
- if (member.isSetter()) { \
- setter.call(object, QScriptValueImplList() << *stackPtr); \
- if (hasUncaughtException()) { \
- stackPtr -= 1; \
- Done(); \
- } \
- } else { \
- if (member.isWritable()) { \
- if (isMemberAssignment && (base.m_object_value != object.m_object_value)) { \
- base = object; \
- CREATE_MEMBER(base, memberName, &member, /*flags=*/0); \
- } \
- base.put(member, *stackPtr); \
- if (hasUncaughtException()) { \
- stackPtr -= 1; \
- HandleException(); \
- } \
- } \
- } \
- ++iPtr;
-
-namespace QScript {
-
-void ScriptFunction::execute(QScriptContextPrivate *context)
-{
- if (! m_compiledCode) {
- QScriptEnginePrivate *eng = context->engine();
- Compiler compiler(eng);
-
- CompilationUnit unit = compiler.compile(m_definition->body, formals);
- if (! unit.isValid()) {
- context->throwError(unit.errorMessage());
- return;
- }
-
- m_compiledCode = m_astPool->createCompiledCode(m_definition->body, unit);
- }
-
- context->execute(m_compiledCode);
-}
-
-QString ScriptFunction::toString(QScriptContextPrivate *) const
-{
- QString str;
- QTextStream out(&str, QIODevice::WriteOnly);
- PrettyPretty pp(out);
- pp(m_definition, /*indent=*/ 0);
- return str;
-}
-
-QString ScriptFunction::fileName() const
-{
- return m_astPool->fileName();
-}
-
-QString ScriptFunction::functionName() const
-{
- if (!m_definition->name)
- return QString();
- return m_definition->name->s;
-}
-
-int ScriptFunction::startLineNumber() const
-{
- return m_definition->startLine;
-}
-
-int ScriptFunction::endLineNumber() const
-{
- return m_definition->endLine;
-}
-
-} // namespace QScript
-
-/*!
- \internal
-
- Resolves and gets the value specified by \a stackPtr.
- stackPtr[0] contains the member specifier, stackPtr[-1] contains the object.
- If the member can be resolved, sets \a value to the value of that member,
- otherwise returns false.
-*/
-bool QScriptContextPrivate::resolveField(QScriptEnginePrivate *eng,
- QScriptValueImpl *stackPtr,
- QScriptValueImpl *value)
-{
- const QScriptValueImpl &m = stackPtr[0];
- QScriptValueImpl &object = stackPtr[-1];
-
- if (! object.isObject())
- object = eng->toObject(object);
-
- if (! object.isValid())
- return false;
-
- if (QScript::Ecma::Array::Instance *arrayInstance = eng->arrayConstructor->get(object)) {
- quint32 pos = toArrayIndex(m);
- if (pos != 0xFFFFFFFF) {
- *value = arrayInstance->value.at(pos);
-
- if (! value->isValid())
- *value = eng->undefinedValue();
-
- return true;
- }
- }
-
- QScriptNameIdImpl *nameId = m.isString() ? m.m_string_value : 0;
-
- if (! nameId || ! nameId->unique)
- nameId = eng->nameId(QScriptEnginePrivate::convertToNativeString(m), /*persistent=*/false); // ### slow!
-
- QScript::Member member;
- QScriptValueImpl base;
-
- if (! object.resolve(nameId, &member, &base, QScriptValue::ResolveFull, QScript::Read)) // ### ...
- return false;
-
- if (QScriptEnginePrivate::strictlyEquals(base, eng->m_globalObject))
- stackPtr[-1] = base;
- else if (object.classInfo() == eng->m_class_with)
- stackPtr[-1] = object.prototype();
-
- base.get(member, value);
-
- if (member.isGetterOrSetter()) {
- // call the getter function
- QScriptValueImpl getter;
- if (member.isGetter()) {
- getter = *value;
- } else {
- if (!base.m_object_value->findGetter(&member)) {
- *value = eng->undefinedValue();
- return true;
- }
- base.get(member, &getter);
- }
- *value = getter.call(object);
- }
-
- return true;
-}
-
-void QScriptContextPrivate::execute(QScript::Code *code)
-{
- int oldCurrentLine = currentLine;
- int oldCurrentColumn = currentColumn;
- QScript::Code *oldCode = m_code;
- m_code = code;
-
-#ifndef Q_SCRIPT_NO_PRINT_GENERATED_CODE
- qout << QLatin1String("function:") << endl;
- for (QScriptInstruction *current = code->firstInstruction; current != code->lastInstruction; ++current) {
- qout << int(current - code->firstInstruction) << QLatin1String(":\t");
- current->print(qout);
- qout << endl;
- }
- qout << endl;
-#endif
-
- QScriptEnginePrivate *eng = engine();
-
- bool wasEvaluating = eng->m_evaluating;
- if (!wasEvaluating) {
- eng->setupProcessEvents();
- eng->resetAbortFlag();
- }
- eng->m_evaluating = true;
-
- // set up the temp stack
- if (! tempStack)
- stackPtr = tempStack = eng->tempStackBegin;
-
- QScriptValueImpl undefined(eng->undefinedValue());
-
- catching = false;
- m_state = QScriptContext::NormalState;
- m_result = undefined;
- firstInstruction = code->firstInstruction;
- lastInstruction = code->lastInstruction;
- iPtr = code->firstInstruction;
-
- if (!m_scopeChain.isValid())
- m_scopeChain = m_activation;
-
-#ifndef Q_SCRIPT_NO_EVENT_NOTIFY
- eng->notifyFunctionEntry(this);
-#endif
-
-#ifndef Q_SCRIPT_DIRECT_CODE
-
-# define I(opc) case QScriptInstruction::OP_##opc
-# define Next() goto Lfetch
-# define Done() goto Ldone
-# define HandleException() goto Lhandle_exception
-# define Abort() goto Labort
-
-Lfetch:
-
-
-#else
-
-# define I(opc) qscript_execute_##opc
-# define Next() goto *iPtr->code
-# define Done() goto Ldone
-# define HandleException() goto Lhandle_exception
-# define Abort() goto Labort
-
- static void * const jump_table[] = {
-
-# define Q_SCRIPT_DEFINE_OPERATOR(op) &&I(op),
-# include "instruction.table"
-# undef Q_SCRIPT_DEFINE_OPERATOR
- }; // jump_table
-
-
- if (!code->optimized) {
- for (QScriptInstruction *current = code->firstInstruction; current != code->lastInstruction; ++current) {
- current->code = jump_table[current->op];
- }
-
- code->optimized = true;
- }
-
-#endif
-Ltop:
-
-#ifndef Q_SCRIPT_DIRECT_CODE
- switch (iPtr->op) {
-#else
- goto *iPtr->code;
-#endif
-
- I(Nop):
- {
- ++iPtr;
- } Next();
-
- I(LoadUndefined):
- {
- CHECK_TEMPSTACK(1);
- *(++stackPtr) = undefined;
- ++iPtr;
- } Next();
-
- I(LoadTrue):
- {
- CHECK_TEMPSTACK(1);
- *(++stackPtr) = QScriptValueImpl(true);
- ++iPtr;
- } Next();
-
- I(LoadFalse):
- {
- CHECK_TEMPSTACK(1);
- *(++stackPtr) = QScriptValueImpl(false);
- ++iPtr;
- } Next();
-
- I(LoadThis):
- {
- CHECK_TEMPSTACK(1);
- Q_ASSERT(m_thisObject.isObject());
- *++stackPtr = m_thisObject;
- ++iPtr;
- } Next();
-
- I(LoadActivation):
- {
- CHECK_TEMPSTACK(1);
- *++stackPtr = m_activation;
- ++iPtr;
- } Next();
-
- I(LoadNull):
- {
- CHECK_TEMPSTACK(1);
- *(++stackPtr) = eng->nullValue();
- ++iPtr;
- } Next();
-
- I(LoadNumber):
- {
- CHECK_TEMPSTACK(1);
- *++stackPtr = iPtr->operand[0];
- ++iPtr;
- } Next();
-
-
- I(LoadString):
- {
- CHECK_TEMPSTACK(1);
- *++stackPtr = iPtr->operand[0];
- ++iPtr;
- } Next();
-
- I(NewString):
- {
- CHECK_TEMPSTACK(1);
- eng->newNameId(++stackPtr, iPtr->operand[0].m_string_value);
- ++iPtr;
- } Next();
-
- I(Duplicate):
- {
- CHECK_TEMPSTACK(1);
- ++stackPtr;
- *stackPtr = stackPtr[-1];
- ++iPtr;
- } Next();
-
- I(Swap):
- {
- QScriptValueImpl tmp = stackPtr[0];
- *stackPtr = stackPtr[-1];
- stackPtr[-1] = tmp;
- ++iPtr;
- } Next();
-
-
- I(Receive):
- {
- int n = iPtr->operand[0].m_int_value;
-
- if (n >= argc) {
- throwError(QLatin1String("invalid argument"));
- HandleException();
- }
-
- CHECK_TEMPSTACK(1);
- *++stackPtr = argument(n);
- ++iPtr;
- } Next();
-
- I(Fetch):
- {
- CHECK_TEMPSTACK(1);
-
- QScriptNameIdImpl *memberName = iPtr->operand[0].m_string_value;
-
- QScriptValueImpl base;
- QScript::Member member;
-
- QScriptObject *instance = m_scopeChain.m_object_value;
- if (instance->findMember(memberName, &member)) {
- instance->get(member, ++stackPtr);
- base = m_scopeChain;
- } else {
- if (m_scopeChain.resolve_helper(memberName, &member, &base, QScriptValue::ResolveFull, QScript::Read)) {
- base.get(member, ++stackPtr);
- if (hasUncaughtException()) {
- stackPtr -= 1;
- HandleException();
- }
- } else {
- throwNotDefined(memberName);
- HandleException();
- }
- }
- if (member.isGetterOrSetter()) {
- // locate the getter function
- QScriptValueImpl getter;
- if (member.isGetter()) {
- getter = *stackPtr;
- } else {
- if (!base.m_object_value->findGetter(&member)) {
- stackPtr -= 1;
- throwError(QLatin1String("No getter defined"));
- HandleException();
- }
- base.get(member, &getter);
- }
- // decide the this-object. This is the object that actually
- // has the getter (in its prototype chain).
- QScriptValueImpl object = m_scopeChain;
- while (!object.resolve(memberName, &member, &base, QScriptValue::ResolvePrototype, QScript::Read))
- object = object.scope();
- if (object.classInfo() == eng->m_class_with)
- object = object.prototype();
-
- *stackPtr = getter.call(object);
- if (hasUncaughtException()) {
- stackPtr -= 1;
- Done();
- }
- }
- ++iPtr;
- } Next();
-
- I(Resolve):
- {
- Q_ASSERT(iPtr->operand[0].isString());
-
- CHECK_TEMPSTACK(2);
- *++stackPtr = m_scopeChain;
- *++stackPtr = iPtr->operand[0];
- eng->newReference(++stackPtr, QScriptValue::ResolveScope);
- ++iPtr;
- } Next();
-
- I(PutField):
- {
- Q_ASSERT(stackPtr[-1].isReference());
-
- const QScriptValueImpl &object = stackPtr[-3];
- QScriptNameIdImpl *memberName = stackPtr[-2].m_string_value;
- const QScriptValueImpl &value = stackPtr[0];
-
- QScript::Member member;
- QScriptValueImpl base;
-
- if (! object.resolve(memberName, &member, &base, QScriptValue::ResolveLocal, QScript::Write)) {
- base = object;
- CREATE_MEMBER(base, memberName, &member, /*flags=*/0);
- }
-
- base.put(member, value);
- stackPtr -= 4;
- if (hasUncaughtException())
- HandleException();
- ++iPtr;
- } Next();
-
- I(Call):
- {
- int argc = iPtr->operand[0].m_int_value;
- QScriptValueImpl *argp = stackPtr - argc;
-
- QScriptValueImpl base;
- QScriptValueImpl callee;
-
- bool isReference = argp[0].isReference();
-
- if (! isReference) { // we have a value
- base = eng->m_globalObject;
- callee = argp[0];
- } else if (resolveField(eng, &argp[-1], &callee)) {
- if (hasUncaughtException()) {
- stackPtr = argp - 3;
- HandleException();
- }
- base = argp[-2];
- } else {
- QScriptValueImpl member = argp[-1];
- stackPtr = argp - 1;
- Q_ASSERT(isReference);
- stackPtr -= 2;
-
- if (member.isString())
- throwNotDefined(member.toString());
- else
- throwNotDefined(QLatin1String("function"));
- HandleException();
- }
-
- Q_ASSERT(base.isValid());
- Q_ASSERT(callee.isValid());
-
- QScriptFunction *function = QScriptEnginePrivate::convertToNativeFunction(callee);
- if (! function) {
- QScriptValueImpl member = argp[-1];
- QString message;
- if (member.isString()) {
- message = QString::fromLatin1("%0 is not a function")
- .arg(member.toString());
- } else {
- message = QLatin1String("not a function");
- }
- throwTypeError(message);
- HandleException();
- }
-
- if (++eng->m_callDepth == eng->m_maxCallDepth) {
- throwError(QLatin1String("call stack overflow"));
- HandleException();
- }
-
- QScriptContextPrivate *nested_data = eng->pushContext();
- nested_data->m_thisObject = base;
- nested_data->m_callee = callee;
-
- // create the activation
- eng->newActivation(&nested_data->m_activation);
- QScriptObject *activation_data = nested_data->m_activation.m_object_value;
-
- int formalCount = function->formals.count();
- int mx = qMax(formalCount, argc);
- activation_data->m_members.resize(mx);
- activation_data->m_values.resize(mx);
- for (int i = 0; i < mx; ++i) {
- QScriptNameIdImpl *nameId = 0;
- if (i < formalCount)
- nameId = function->formals.at(i);
-
- activation_data->m_members[i].object(nameId, i,
- QScriptValue::Undeletable
- | QScriptValue::SkipInEnumeration);
- activation_data->m_values[i] = (i < argc) ? argp[i + 1] : undefined;
- }
-
- nested_data->argc = argc;
- if (callee.m_object_value->m_scope.isValid())
- activation_data->m_scope = callee.m_object_value->m_scope;
- else
- activation_data->m_scope = eng->m_globalObject;
- nested_data->tempStack = stackPtr;
- nested_data->args = &argp[1];
-
- function->execute(nested_data);
-
- --eng->m_callDepth;
-
- stackPtr = argp - 1;
- if (isReference)
- stackPtr -= 2;
-
- if (nested_data->m_state == QScriptContext::ExceptionState) {
- eng->popContext();
- if (eng->shouldAbort())
- Abort();
- else
- Done();
- }
-
- CHECK_TEMPSTACK(1);
- *++stackPtr = nested_data->m_result;
-
- eng->popContext();
-
- if (eng->shouldAbort())
- Abort();
-
- if (eng->m_processEventsInterval > 0)
- eng->processEvents();
-
- ++iPtr;
- } Next();
-
-
- I(NewArray):
- {
- CHECK_TEMPSTACK(1);
- eng->arrayConstructor->newArray(++stackPtr, QScript::Array(eng));
- ++iPtr;
- } Next();
-
- I(NewRegExp):
- {
- CHECK_TEMPSTACK(1);
-
- QString pattern = eng->toString(iPtr->operand[0].m_string_value);
-#ifndef QT_NO_REGEXP
- QString literal = pattern;
-#endif
- int flags = 0;
- if (iPtr->operand[1].isValid()) {
- flags = iPtr->operand[1].m_int_value;
-#ifndef QT_NO_REGEXP
- if (flags != 0) {
- literal += QLatin1Char('/');
- literal += QString::number(flags);
- }
-#endif
- }
-
-#ifndef QT_NO_REGEXP
- QRegExp rx;
- // lazy compilation of regexp literals
- QHash<QString, QRegExp>::const_iterator it;
- it = eng->m_regExpLiterals.constFind(literal);
- if (it == eng->m_regExpLiterals.constEnd()) {
- rx = QScript::Ecma::RegExp::toRegExp(pattern, flags);
- eng->m_regExpLiterals.insert(literal, rx);
- } else {
- rx = *it;
- }
- eng->regexpConstructor->newRegExp(++stackPtr, rx, flags);
-#else
- eng->regexpConstructor->newRegExp(++stackPtr, pattern, flags);
-#endif
- ++iPtr;
- } Next();
-
- I(NewObject):
- {
- CHECK_TEMPSTACK(1);
- eng->objectConstructor->newObject(++stackPtr);
- ++iPtr;
- } Next();
-
- I(New):
- {
- int argc = iPtr->operand[0].m_int_value;
- QScriptValueImpl *argp = stackPtr - argc;
-
- // QScriptValueImpl base;
- QScriptValueImpl callee;
-
- bool isReference = argp[0].isReference();
-
- if (! isReference) { // we have a value
- // base = eng->globalObject;
- callee = argp[0];
- } else if (resolveField(eng, &argp[-1], &callee)) {
- // base = argp[-2];
- if (hasUncaughtException()) {
- stackPtr = argp - 3;
- HandleException();
- }
- } else {
- QScriptValueImpl member = argp[-1];
- stackPtr = argp - 1;
- Q_ASSERT(isReference);
- stackPtr -= 2;
-
- if (member.isString())
- throwNotDefined(member.toString());
- else
- throwNotDefined(QLatin1String("constructor"));
- HandleException();
- }
-
- // Q_ASSERT(base.isValid());
- Q_ASSERT(callee.isValid());
-
- QScriptFunction *function = QScriptEnginePrivate::convertToNativeFunction(callee);
- if (! function) {
- QScriptValueImpl member = argp[-1];
- QString message;
- if (member.isString()) {
- message = QString::fromLatin1("%0 is not a constructor")
- .arg(member.toString());
- } else {
- message = QLatin1String("not a constructor");
- }
- throwTypeError(message);
- HandleException();
- }
-
- if (++eng->m_callDepth == eng->m_maxCallDepth) {
- throwError(QLatin1String("call stack overflow"));
- HandleException();
- }
-
- QScriptContextPrivate *nested_data = eng->pushContext();
- nested_data->m_callee = callee;
- nested_data->m_calledAsConstructor = true;
-
- // create the activation
- eng->newActivation(&nested_data->m_activation);
- QScriptObject *activation_data = nested_data->m_activation.m_object_value;
-
- int formalCount = function->formals.count();
- int mx = qMax(formalCount, argc);
- activation_data->m_members.resize(mx);
- activation_data->m_values.resize(mx);
- for (int i = 0; i < mx; ++i) {
- QScriptNameIdImpl *nameId = 0;
- if (i < formalCount)
- nameId = function->formals.at(i);
-
- activation_data->m_members[i].object(nameId, i,
- QScriptValue::Undeletable
- | QScriptValue::SkipInEnumeration);
- activation_data->m_values[i] = (i < argc) ? argp[i + 1] : undefined;
- }
-
- eng->objectConstructor->newObject(&nested_data->m_thisObject);
- nested_data->argc = argc;
- if (callee.m_object_value->m_scope.isValid())
- activation_data->m_scope = callee.m_object_value->m_scope;
- else
- activation_data->m_scope = eng->m_globalObject;
- nested_data->tempStack = stackPtr;
- nested_data->args = &argp[1];
- nested_data->m_result = undefined;
-
- QScriptObject *instance = nested_data->m_thisObject.m_object_value;
-
- // set [[prototype]]
- QScriptValueImpl dummy;
- QScript::Member proto;
- if (callee.resolve(eng->idTable()->id_prototype, &proto, &dummy, QScriptValue::ResolveLocal, QScript::Read))
- callee.get(proto, &instance->m_prototype);
- if (!instance->m_prototype.isObject())
- instance->m_prototype = eng->objectConstructor->publicPrototype;
-
- function->execute(nested_data);
-
- --eng->m_callDepth;
-
- stackPtr = argp - 1;
- if (isReference)
- stackPtr -= 2;
-
- if (! nested_data->m_result.isValid())
- nested_data->m_result = undefined;
- else if (! nested_data->m_result.isObject())
- nested_data->m_result = nested_data->m_thisObject;
-
- if (nested_data->m_state == QScriptContext::ExceptionState) {
- eng->popContext();
- if (eng->shouldAbort())
- Abort();
- else
- Done();
- }
-
- CHECK_TEMPSTACK(1);
-
- *++stackPtr = nested_data->m_result;
-
- eng->popContext();
-
- if (eng->shouldAbort())
- Abort();
-
- if (eng->m_processEventsInterval > 0)
- eng->processEvents();
-
- ++iPtr;
- } Next();
-
- I(FetchField):
- {
- QScriptValueImpl object = eng->toObject(stackPtr[-1]);
- if (! object.isValid()) {
- stackPtr -= 2;
- throwTypeError(QLatin1String("not an object"));
- HandleException();
- }
-
- QScriptValueImpl m = stackPtr[0];
-
- QScript::Ecma::Array::Instance *arrayInstance = 0;
- if (object.classInfo() == eng->arrayConstructor->classInfo())
- arrayInstance = static_cast<QScript::Ecma::Array::Instance *> (object.m_object_value->m_data);
-
- if (arrayInstance) {
- quint32 pos = toArrayIndex(m);
- if (pos != 0xFFFFFFFF) {
- QScriptValueImpl val = arrayInstance->value.at(pos);
- if (val.isValid()) {
- *--stackPtr = val;
- ++iPtr;
- Next();
- }
- }
- }
-
- QScriptNameIdImpl *nameId = m.isString() ? m.m_string_value : 0;
-
- if (! nameId || ! nameId->unique) {
- QString str;
-
- if (m.isNumber())
- qscript_uint_to_string(m.m_number_value, str);
-
- if (str.isEmpty())
- str = QScriptEnginePrivate::convertToNativeString(m);
-
- nameId = eng->nameId(str, /*persistent=*/false);
- }
-
- QScript::Member member;
- QScriptValueImpl base;
-
- if (object.resolve(nameId, &member, &base, QScriptValue::ResolvePrototype, QScript::Read)) {
- base.get(member, --stackPtr);
- if (hasUncaughtException()) {
- stackPtr -= 1;
- HandleException();
- } else if (member.isGetterOrSetter()) {
- // call the getter function
- QScriptValueImpl getter;
- if (member.isGetter()) {
- getter = *stackPtr;
- } else {
- if (!base.m_object_value->findGetter(&member)) {
- stackPtr -= 1;
- throwError(QLatin1String("No getter defined"));
- HandleException();
- }
- base.get(member, &getter);
- }
- *stackPtr = getter.call(object);
- if (hasUncaughtException()) {
- stackPtr -= 1;
- Done();
- }
- }
- } else {
- *(--stackPtr) = undefined;
- }
-
- ++iPtr;
- } Next();
-
- I(LazyArguments):
- {
- QScript::Member member;
- QScriptValueImpl base;
- QScriptNameIdImpl *arguments = eng->idTable()->id_arguments;
- if (!m_activation.resolve(arguments, &member, &base, QScriptValue::ResolveLocal, QScript::Read)) {
- CREATE_MEMBER(m_activation, arguments, &member, QScriptValue::Undeletable);
- if (!m_arguments.isValid()) {
- if (eng->strictlyEquals(m_activation, eng->globalObject()))
- m_arguments = undefined;
- else
- eng->newArguments(&m_arguments, m_activation, argc, m_callee);
- }
- m_activation.put(member, m_arguments);
- }
- ++iPtr;
- } Next();
-
- I(DeclareLocal):
- {
- QScriptValueImpl &act = m_activation;
-
- QScriptNameIdImpl *memberName = iPtr->operand[0].m_string_value;
- bool readOnly = iPtr->operand[1].m_int_value != 0;
- QScript::Member member;
- QScriptValueImpl object;
-
- if (! act.resolve(memberName, &member, &object, QScriptValue::ResolveLocal, QScript::ReadWrite)) {
- uint flags = QScriptValue::Undeletable;
- if (readOnly)
- flags |= QScript::Member::UninitializedConst | QScriptValue::ReadOnly;
- CREATE_MEMBER(act, memberName, &member, flags);
- act.put(member, undefined);
- }
- ++iPtr;
- } Next();
-
- I(Assign):
- {
- if (! stackPtr[-1].isReference()) {
- stackPtr -= 2;
- throwSyntaxError(QLatin1String("invalid assignment lvalue"));
- HandleException();
- }
-
- QScriptValue::ResolveFlags mode;
- mode = QScriptValue::ResolveFlags(stackPtr[-1].m_int_value)
- | QScriptValue::ResolvePrototype;
-
- QScriptValueImpl object = eng->toObject(stackPtr[-3]);
- if (! object.isValid()) {
- stackPtr -= 4;
- throwTypeError(QLatin1String("invalid assignment lvalue"));
- HandleException();
- }
-
- QScriptValueImpl m = stackPtr[-2];
- QScriptValueImpl value = stackPtr[0];
-
- quint32 pos = 0xFFFFFFFF;
-
- QScript::Ecma::Array::Instance *arrayInstance = eng->arrayConstructor->get(object);
- if (arrayInstance)
- pos = toArrayIndex(m);
-
- stackPtr -= 3;
-
- if (pos != 0xFFFFFFFF)
- arrayInstance->value.assign(pos, value);
-
- else {
- QScriptNameIdImpl *memberName;
-
- if (m.isString() && m.m_string_value->unique)
- memberName = m.m_string_value;
- else
- memberName = eng->nameId(QScriptEnginePrivate::convertToNativeString(m), /*persistent=*/false);
-
- QScriptValueImpl base;
- QScript::Member member;
-
- const bool isMemberAssignment = (object.m_object_value != m_scopeChain.m_object_value);
- if (! object.resolve(memberName, &member, &base, mode, QScript::Write)) {
- if (isMemberAssignment)
- base = object;
- else
- base = eng->m_globalObject;
-
- CREATE_MEMBER(base, memberName, &member, /*flags=*/0);
- }
-
- if (value.isString() && ! value.m_string_value->unique)
- eng->newNameId(&value, value.m_string_value->s);
-
- if (member.isGetterOrSetter()) {
- // find and call setter(value)
- QScriptValueImpl setter;
- if (!member.isSetter()) {
- if (!base.m_object_value->findSetter(&member)) {
- stackPtr -= 1;
- throwError(QLatin1String("no setter defined"));
- HandleException();
- }
- }
- base.get(member, &setter);
-
- if (!isMemberAssignment) {
- // decide the this-object. This is the object that actually
- // has the setter (in its prototype chain).
- while (!object.resolve(memberName, &member, &base, QScriptValue::ResolvePrototype, QScript::Write))
- object = object.scope();
- if (object.classInfo() == eng->m_class_with)
- object = object.prototype();
- }
-
- value = setter.call(object, QScriptValueImplList() << value);
- if (hasUncaughtException()) {
- stackPtr -= 1;
- Done();
- }
- } else {
- if (object.classInfo() == eng->m_class_with)
- object = object.prototype();
-
- if (member.isWritable()) {
- if (isMemberAssignment && (base.m_object_value != object.m_object_value)) {
- base = object;
- CREATE_MEMBER(base, memberName, &member, /*flags=*/0);
- }
- base.put(member, value);
- } else if (member.isUninitializedConst()) {
- base.put(member, value);
- if (member.isObjectProperty()) {
- base.m_object_value->m_members[member.id()]
- .unsetFlags(QScript::Member::UninitializedConst);
- }
- }
- if (hasUncaughtException()) {
- stackPtr -= 1;
- HandleException();
- }
- }
- }
-
- *stackPtr = value;
- ++iPtr;
- } Next();
-
- I(BitAnd):
- {
- qint32 v1 = QScriptEnginePrivate::convertToNativeInt32(stackPtr[-1]);
- qint32 v2 = QScriptEnginePrivate::convertToNativeInt32(stackPtr[0]);
- *(--stackPtr) = QScriptValueImpl(v1 & v2);
- ++iPtr;
- } Next();
-
- I(BitOr):
- {
- qint32 v1 = QScriptEnginePrivate::convertToNativeInt32(stackPtr[-1]);
- qint32 v2 = QScriptEnginePrivate::convertToNativeInt32(stackPtr[0]);
- *(--stackPtr) = QScriptValueImpl(v1 | v2);
- ++iPtr;
- } Next();
-
- I(BitXor):
- {
- qint32 v1 = QScriptEnginePrivate::convertToNativeInt32(stackPtr[-1]);
- qint32 v2 = QScriptEnginePrivate::convertToNativeInt32(stackPtr[0]);
- *(--stackPtr) = QScriptValueImpl(v1 ^ v2);
- ++iPtr;
- } Next();
-
- I(BitNot):
- {
- qint32 v1 = QScriptEnginePrivate::convertToNativeInt32(stackPtr[0]);
- *stackPtr = QScriptValueImpl(~v1);
- ++iPtr;
- } Next();
-
- I(Not):
- {
- bool v1 = QScriptEnginePrivate::convertToNativeBoolean(stackPtr[0]);
- *stackPtr = QScriptValueImpl(!v1);
- ++iPtr;
- } Next();
-
- I(LeftShift):
- {
- qint32 v1 = QScriptEnginePrivate::convertToNativeInt32(stackPtr[-1]);
- qint32 v2 = QScriptEnginePrivate::convertToNativeInt32(stackPtr[0]) & 0x1f;
- *(--stackPtr) = QScriptValueImpl(v1 << v2);
- ++iPtr;
- } Next();
-
- I(Mod):
- {
- qsreal v1 = QScriptEnginePrivate::convertToNativeDouble(stackPtr[-1]);
- qsreal v2 = QScriptEnginePrivate::convertToNativeDouble(stackPtr[0]);
-
- *(--stackPtr) = QScriptValueImpl(::fmod(v1, v2));
- ++iPtr;
- } Next();
-
- I(RightShift):
- {
- qint32 v1 = QScriptEnginePrivate::convertToNativeInt32(stackPtr[-1]);
- quint32 v2 = QScriptEnginePrivate::toUint32 (eng->convertToNativeDouble(stackPtr[0])) & 0x1f;
- *(--stackPtr) = QScriptValueImpl(v1 >> v2);
- ++iPtr;
- } Next();
-
- I(URightShift):
- {
- quint32 v1 = QScriptEnginePrivate::toUint32 (eng->convertToNativeDouble(stackPtr[-1]));
- qint32 v2 = QScriptEnginePrivate::convertToNativeInt32(stackPtr[0]) & 0x1f;
- *(--stackPtr) = QScriptValueImpl(v1 >> v2);
- ++iPtr;
- } Next();
-
- I(InstanceOf):
- {
- QScriptValueImpl object = stackPtr[-1];
- QScriptValueImpl ctor = stackPtr[0];
-
- if (!ctor.isObject() || !ctor.implementsHasInstance()) {
- stackPtr -= 2;
- throwTypeError(QLatin1String("invalid 'instanceof' operand"));
- HandleException();
- }
-
- bool result = ctor.hasInstance(object);
- if (eng->hasUncaughtException()) {
- stackPtr -= 2;
- HandleException();
- }
-
- *(--stackPtr) = QScriptValueImpl(result);
- ++iPtr;
- } Next();
-
- I(In):
- {
- QScriptValueImpl object = stackPtr[0];
- if (!object.isObject()) {
- stackPtr -= 2;
- throwTypeError(QLatin1String("invalid 'in' operand"));
- HandleException();
- }
- QString propertyName = QScriptEnginePrivate::convertToNativeString(stackPtr[-1]);
- bool result = object.property(propertyName, QScriptValue::ResolvePrototype).isValid(); // ### hasProperty()
- *(--stackPtr) = QScriptValueImpl(result);
- ++iPtr;
- } Next();
-
- I(Add):
- {
- QScriptValueImpl lhs = eng->toPrimitive(stackPtr[-1], QScriptValueImpl::NoTypeHint);
- QScriptValueImpl rhs = eng->toPrimitive(stackPtr[0], QScriptValueImpl::NoTypeHint);
-
- if (lhs.isString() || rhs.isString()) {
- QString tmp = QScriptEnginePrivate::convertToNativeString(lhs);
- tmp += QScriptEnginePrivate::convertToNativeString(rhs);
- eng->newString(--stackPtr, tmp);
- } else {
- qsreal tmp = QScriptEnginePrivate::convertToNativeDouble(lhs);
- tmp += QScriptEnginePrivate::convertToNativeDouble(rhs);
- *(--stackPtr) = QScriptValueImpl(tmp);
- }
-
- ++iPtr;
- } Next();
-
- I(Div):
- {
- qsreal v1 = QScriptEnginePrivate::convertToNativeDouble(stackPtr[-1]);
- qsreal v2 = QScriptEnginePrivate::convertToNativeDouble(stackPtr[0]);
- *(--stackPtr) = QScriptValueImpl(v1 / v2);
- ++iPtr;
- } Next();
-
- I(Equal):
- {
- QScriptValueImpl v1 = stackPtr[-1];
- QScriptValueImpl v2 = stackPtr[0];
- *(--stackPtr) = QScriptValueImpl(eq_cmp(v1, v2));
- ++iPtr;
- } Next();
-
- I(GreatOrEqual):
- {
- QScriptValueImpl v1 = stackPtr[0];
- QScriptValueImpl v2 = stackPtr[-1];
- *(--stackPtr) = QScriptValueImpl(le_cmp(v1, v2));
- ++iPtr;
- } Next();
-
- I(GreatThan):
- {
- QScriptValueImpl v1 = stackPtr[0];
- QScriptValueImpl v2 = stackPtr[-1];
- *(--stackPtr) = QScriptValueImpl(lt_cmp(v1, v2));
- ++iPtr;
- } Next();
-
- I(LessOrEqual):
- {
- QScriptValueImpl v1 = stackPtr[-1];
- QScriptValueImpl v2 = stackPtr[0];
- *(--stackPtr) = QScriptValueImpl(le_cmp(v1, v2));
- ++iPtr;
- } Next();
-
- I(LessThan):
- {
- QScriptValueImpl v1 = stackPtr[-1];
- QScriptValueImpl v2 = stackPtr[0];
- *(--stackPtr) = QScriptValueImpl(lt_cmp(v1, v2));
- ++iPtr;
- } Next();
-
- I(NotEqual):
- {
- QScriptValueImpl v1 = stackPtr[-1];
- QScriptValueImpl v2 = stackPtr[0];
- *(--stackPtr) = QScriptValueImpl(!eq_cmp(v1, v2));
- ++iPtr;
- } Next();
-
- I(Mul):
- {
- qsreal v1 = QScriptEnginePrivate::convertToNativeDouble(stackPtr[-1]);
- qsreal v2 = QScriptEnginePrivate::convertToNativeDouble(stackPtr[0]);
- *(--stackPtr) = QScriptValueImpl(v1 * v2);
- ++iPtr;
- } Next();
-
- I(StrictEqual):
- {
- QScriptValueImpl v1 = stackPtr[-1];
- QScriptValueImpl v2 = stackPtr[0];
- *(--stackPtr) = strict_eq_cmp(v1, v2);
- ++iPtr;
- } Next();
-
- I(StrictNotEqual):
- {
- QScriptValueImpl v1 = stackPtr[-1];
- QScriptValueImpl v2 = stackPtr[0];
- *(--stackPtr) = ! strict_eq_cmp(v1, v2);
- ++iPtr;
- } Next();
-
- I(Sub):
- {
- qsreal v1 = QScriptEnginePrivate::convertToNativeDouble(stackPtr[-1]);
- qsreal v2 = QScriptEnginePrivate::convertToNativeDouble(stackPtr[0]);
- *(--stackPtr) = QScriptValueImpl(v1 - v2);
- ++iPtr;
- } Next();
-
- I(UnaryMinus):
- {
- qsreal v1 = QScriptEnginePrivate::convertToNativeDouble(*stackPtr);
- *stackPtr = QScriptValueImpl(-v1);
- ++iPtr;
- } Next();
-
- I(UnaryPlus):
- {
- qsreal v1 = QScriptEnginePrivate::convertToNativeDouble(*stackPtr);
- *stackPtr = QScriptValueImpl(+v1);
- ++iPtr;
- } Next();
-
- I(Branch):
- {
- eng->maybeProcessEvents();
- if (hasUncaughtException())
- HandleException();
- if (eng->shouldAbort())
- Abort();
- iPtr += iPtr->operand[0].m_int_value;
- } Next();
-
- I(BranchFalse):
- {
- if (! QScriptEnginePrivate::convertToNativeBoolean(*stackPtr--))
- iPtr += iPtr->operand[0].m_int_value;
- else
- ++iPtr;
- } Next();
-
- I(BranchTrue):
- {
- if (eng->convertToNativeBoolean(*stackPtr--))
- iPtr += iPtr->operand[0].m_int_value;
- else
- ++iPtr;
- } Next();
-
- I(NewClosure):
- {
- CHECK_TEMPSTACK(1);
-
- QScript::AST::FunctionExpression *expr = static_cast<QScript::AST::FunctionExpression *> (iPtr->operand[0].m_ptr_value);
-
-#ifndef Q_SCRIPT_NO_JOINED_FUNCTION
- if (QScript::Code *code = eng->findCode(functionBody)) {
- QScriptValueImpl value = code->value;
-
- if (isValid(value)) {
- QScriptObject *instance = value.m_object_value;
- Q_ASSERT(instance != 0);
-
- if (instance->m_scope.m_object_value == m_scopeChain.m_object_value)
- {
- *++stackPtr = value;
- ++iPtr;
- Next();
- }
- }
- }
-#endif
-
- QScript::ScriptFunction *function = new QScript::ScriptFunction(expr, code->astPool);
-
- // update the formals
- for (QScript::AST::FormalParameterList *it = expr->formals; it != 0; it = it->next) {
- function->formals.append(it->name);
- }
- function->length = function->formals.count();
-
- eng->functionConstructor->newFunction(++stackPtr, function);
-
- QScriptObject *instance = stackPtr->m_object_value;
- // initialize [[scope]]
- instance->m_scope = m_scopeChain;
-
- // create and initialize `prototype'
- QScriptValueImpl proto;
- eng->objectConstructor->newObject(&proto);
-
- QScript::Member member;
- CREATE_MEMBER(proto, eng->idTable()->id_constructor, &member,
- QScriptValue::Undeletable
- | QScriptValue::SkipInEnumeration);
- proto.put(member, *stackPtr);
-
- stackPtr->createMember(eng->idTable()->id_prototype, &member,
- QScriptValue::Undeletable);
- stackPtr->put(member, proto);
-
- ++iPtr;
- } Next();
-
- I(Incr):
- {
- if (! stackPtr[0].isReference()) {
- stackPtr -= 1;
- throwSyntaxError(QLatin1String("invalid increment operand"));
- HandleException();
- }
-
- BEGIN_PREFIX_OPERATOR
-
- qsreal x = QScriptEnginePrivate::convertToNativeDouble(value);
- value = QScriptValueImpl(x + 1);
-
- END_PREFIX_OPERATOR
- } Next();
-
- I(Decr):
- {
- if (! stackPtr[0].isReference()) {
- stackPtr -= 1;
- throwSyntaxError(QLatin1String("invalid decrement operand"));
- HandleException();
- }
-
- BEGIN_PREFIX_OPERATOR
-
- qsreal x = QScriptEnginePrivate::convertToNativeDouble(value);
- value = QScriptValueImpl(x - 1);
-
- END_PREFIX_OPERATOR
- } Next();
-
- I(PostIncr):
- {
- if (! stackPtr[0].isReference()) {
- stackPtr -= 1;
- throwSyntaxError(QLatin1String("invalid increment operand"));
- HandleException();
- }
-
- QScriptValue::ResolveFlags mode;
- mode = QScriptValue::ResolveFlags(stackPtr[0].m_int_value)
- | QScriptValue::ResolvePrototype;
-
- --stackPtr;
-
- QScriptValueImpl object = eng->toObject(stackPtr[-1]);
- if (!object.isObject()) {
- stackPtr -= 2;
- throwTypeError(QLatin1String("not an object"));
- HandleException();
- }
-
- QScriptNameIdImpl *memberName = 0;
- if (stackPtr[0].isString() && stackPtr[0].m_string_value->unique)
- memberName = stackPtr[0].m_string_value;
- else
- memberName = eng->nameId(stackPtr[0].toString(), /*persistent=*/false);
-
- QScript::Member member;
- QScriptValueImpl base;
- QScriptValueImpl value;
- QScriptObject *instance = object.m_object_value;
- const bool isMemberAssignment = (instance != m_scopeChain.m_object_value);
- if (instance->findMember(memberName, &member)) {
- if (!member.isGetterOrSetter()) {
- QScriptValueImpl &r = instance->reference(member);
- if (r.isNumber()) {
- *(--stackPtr) = QScriptValueImpl(r.m_number_value);
- r.incr();
- ++iPtr;
- Next();
- }
- }
- base = object;
- } else if (!object.resolve_helper(memberName, &member, &base, mode, QScript::ReadWrite)) {
- if (!isMemberAssignment) {
- stackPtr -= 2;
- throwNotDefined(memberName);
- HandleException();
- }
- base = object;
- CREATE_MEMBER(base, memberName, &member, /*flags=*/0);
- base.put(member, undefined);
- }
-
- QScriptValueImpl getter;
- QScriptValueImpl setter;
- base.get(member, &value);
- if (hasUncaughtException()) {
- stackPtr -= 2;
- HandleException();
- } else if (member.isGetterOrSetter()) {
- if (member.isGetter()) {
- getter = value;
- if (!member.isSetter() && !base.m_object_value->findSetter(&member)) {
- stackPtr -= 2;
- throwError(QLatin1String("No setter defined"));
- HandleException();
- }
- base.get(member, &setter);
- } else {
- setter = value;
- QScript::Member tmp = member;
- if (!base.m_object_value->findGetter(&member)) {
- stackPtr -= 2;
- throwError(QLatin1String("No getter defined"));
- HandleException();
- }
- base.get(member, &getter);
- member = tmp;
- }
- value = getter.call(object);
- if (hasUncaughtException()) {
- stackPtr -= 2;
- Done();
- }
- }
-
- qsreal x = QScriptEnginePrivate::convertToNativeDouble(value);
-
- value = QScriptValueImpl(x + 1);
-
- if (member.isSetter()) {
- setter.call(object, QScriptValueImplList() << value);
- if (hasUncaughtException()) {
- stackPtr -= 2;
- Done();
- }
- } else {
- if (isMemberAssignment && (base.m_object_value != object.m_object_value)) {
- base = object;
- CREATE_MEMBER(base, memberName, &member, /*flags=*/0);
- }
- if (member.isWritable()) {
- base.put(member, value);
- if (hasUncaughtException()) {
- stackPtr -= 2;
- HandleException();
- }
- }
- }
-
- *(--stackPtr) = QScriptValueImpl(x);
-
- ++iPtr;
- } Next();
-
- I(PostDecr):
- {
- // ### most of the code is duplicated from PostIncr -- try to merge
- if (! stackPtr[0].isReference()) {
- stackPtr -= 1;
- throwSyntaxError(QLatin1String("invalid decrement operand"));
- HandleException();
- }
-
- QScriptValue::ResolveFlags mode = QScriptValue::ResolveFlags(stackPtr[0].m_int_value)
- | QScriptValue::ResolvePrototype;
-
- --stackPtr;
-
- QScriptValueImpl object = eng->toObject(stackPtr[-1]);
- if (!object.isObject()) {
- stackPtr -= 2;
- throwTypeError(QLatin1String("not an object"));
- HandleException();
- }
-
- QScriptNameIdImpl *memberName = 0;
- if (stackPtr[0].isString() && stackPtr[0].m_string_value->unique)
- memberName = stackPtr[0].m_string_value;
- else
- memberName = eng->nameId(stackPtr[0].toString(), /*persistent=*/false);
-
- QScript::Member member;
- QScriptValueImpl base;
- QScriptValueImpl value;
- QScriptObject *instance = object.m_object_value;
- const bool isMemberAssignment = (instance != m_scopeChain.m_object_value);
- if (instance->findMember(memberName, &member)) {
- if (!member.isGetterOrSetter()) {
- QScriptValueImpl &r = instance->reference(member);
- if (r.isNumber()) {
- *(--stackPtr) = QScriptValueImpl(r.m_number_value);
- r.decr();
- ++iPtr;
- Next();
- }
- }
- base = object;
- } else if (! object.resolve_helper(memberName, &member, &base, mode, QScript::ReadWrite)) {
- if (!isMemberAssignment) {
- stackPtr -= 2;
- throwNotDefined(memberName);
- HandleException();
- }
- base = object;
- CREATE_MEMBER(base, memberName, &member, /*flags=*/0);
- base.put(member, undefined);
- }
-
- QScriptValueImpl getter;
- QScriptValueImpl setter;
- base.get(member, &value);
- if (hasUncaughtException()) {
- stackPtr -= 2;
- HandleException();
- } else if (member.isGetterOrSetter()) {
- if (member.isGetter()) {
- getter = value;
- if (!member.isSetter() && !base.m_object_value->findSetter(&member)) {
- stackPtr -= 2;
- throwError(QLatin1String("No setter defined"));
- HandleException();
- }
- base.get(member, &setter);
- } else {
- setter = value;
- QScript::Member tmp = member;
- if (!base.m_object_value->findGetter(&member)) {
- stackPtr -= 2;
- throwError(QLatin1String("No getter defined"));
- HandleException();
- }
- base.get(member, &getter);
- member = tmp;
- }
- value = getter.call(object);
- if (hasUncaughtException()) {
- stackPtr -= 2;
- Done();
- }
- }
-
- qsreal x = QScriptEnginePrivate::convertToNativeDouble(value);
-
- value = QScriptValueImpl(x - 1);
-
- if (member.isSetter()) {
- setter.call(object, QScriptValueImplList() << value);
- if (hasUncaughtException()) {
- stackPtr -= 2;
- Done();
- }
- } else {
- if (isMemberAssignment && (base.m_object_value != object.m_object_value)) {
- base = object;
- CREATE_MEMBER(base, memberName, &member, /*flags=*/0);
- }
- if (member.isWritable()) {
- base.put(member, value);
- if (hasUncaughtException()) {
- stackPtr -= 2;
- HandleException();
- }
- }
- }
-
- *(--stackPtr) = QScriptValueImpl(x);
-
- ++iPtr;
- } Next();
-
- I(InplaceAdd):
- {
- BEGIN_INPLACE_OPERATOR
-
- lhs = eng->toPrimitive(lhs);
- rhs = eng->toPrimitive(rhs);
- if (lhs.isString() || rhs.isString()) {
- if (lhs.isString() && !lhs.m_string_value->unique) {
- lhs.m_string_value->s += QScriptEnginePrivate::convertToNativeString(rhs);
- stackPtr -= 3;
- *stackPtr = lhs;
- } else {
- QString tmp = QScriptEnginePrivate::convertToNativeString(lhs);
- tmp += QScriptEnginePrivate::convertToNativeString(rhs);
- stackPtr -= 3;
- eng->newString(stackPtr, tmp);
- }
- } else {
- qsreal tmp = QScriptEnginePrivate::convertToNativeDouble(lhs);
- tmp += QScriptEnginePrivate::convertToNativeDouble(rhs);
- stackPtr -= 3;
- *stackPtr = QScriptValueImpl(tmp);
- }
-
- END_INPLACE_OPERATOR
- } Next();
-
- I(InplaceSub):
- {
- BEGIN_INPLACE_OPERATOR
-
- qsreal v1 = QScriptEnginePrivate::convertToNativeDouble(lhs);
- qsreal v2 = QScriptEnginePrivate::convertToNativeDouble(rhs);
-
- stackPtr -= 3;
- *stackPtr = QScriptValueImpl(v1 - v2);
-
- END_INPLACE_OPERATOR
- } Next();
-
- I(InplaceAnd):
- {
- BEGIN_INPLACE_OPERATOR
-
- qint32 v1 = QScriptEnginePrivate::convertToNativeInt32(lhs);
- qint32 v2 = QScriptEnginePrivate::convertToNativeInt32(rhs);
-
- stackPtr -= 3;
- *stackPtr = QScriptValueImpl(v1 & v2);
-
- END_INPLACE_OPERATOR
- } Next();
-
- I(InplaceDiv):
- {
- BEGIN_INPLACE_OPERATOR
-
- qsreal v1 = QScriptEnginePrivate::convertToNativeDouble(lhs);
- qsreal v2 = QScriptEnginePrivate::convertToNativeDouble(rhs);
-
- stackPtr -= 3;
- *stackPtr = QScriptValueImpl(v1 / v2);
-
- END_INPLACE_OPERATOR
- } Next();
-
- I(InplaceLeftShift):
- {
- BEGIN_INPLACE_OPERATOR
-
- qint32 v1 = QScriptEnginePrivate::convertToNativeInt32(lhs);
- qint32 v2 = QScriptEnginePrivate::convertToNativeInt32(rhs);
-
- stackPtr -= 3;
- *stackPtr = QScriptValueImpl(v1 << v2);
-
- END_INPLACE_OPERATOR
- } Next();
-
- I(InplaceMod):
- {
- BEGIN_INPLACE_OPERATOR
-
- qsreal v1 = QScriptEnginePrivate::convertToNativeDouble(lhs);
- qsreal v2 = QScriptEnginePrivate::convertToNativeDouble(rhs);
-
- stackPtr -= 3;
- *stackPtr = QScriptValueImpl(::fmod (v1, v2));
-
- END_INPLACE_OPERATOR
- } Next();
-
- I(InplaceMul):
- {
- BEGIN_INPLACE_OPERATOR
-
- qsreal v1 = QScriptEnginePrivate::convertToNativeDouble(lhs);
- qsreal v2 = QScriptEnginePrivate::convertToNativeDouble(rhs);
-
- stackPtr -= 3;
- *stackPtr = QScriptValueImpl(v1 * v2);
-
- END_INPLACE_OPERATOR
- } Next();
-
- I(InplaceOr):
- {
- BEGIN_INPLACE_OPERATOR
-
- qint32 v1 = QScriptEnginePrivate::convertToNativeInt32(lhs);
- qint32 v2 = QScriptEnginePrivate::convertToNativeInt32(rhs);
-
- stackPtr -= 3;
- *stackPtr = QScriptValueImpl(v1 | v2);
-
- END_INPLACE_OPERATOR
- } Next();
-
- I(InplaceRightShift):
- {
- BEGIN_INPLACE_OPERATOR
-
- qint32 v1 = QScriptEnginePrivate::convertToNativeInt32(lhs);
- qint32 v2 = QScriptEnginePrivate::convertToNativeInt32(rhs);
-
- stackPtr -= 3;
- *stackPtr = QScriptValueImpl(v1 >> v2);
-
- END_INPLACE_OPERATOR
- } Next();
-
- I(InplaceURightShift):
- {
- BEGIN_INPLACE_OPERATOR
-
- quint32 v1 = QScriptEnginePrivate::toUint32 (eng->convertToNativeDouble(lhs));
- qint32 v2 = QScriptEnginePrivate::convertToNativeInt32(rhs);
-
- stackPtr -= 3;
- *stackPtr = QScriptValueImpl(v1 >> v2);
-
- END_INPLACE_OPERATOR
- } Next();
-
- I(InplaceXor):
- {
- BEGIN_INPLACE_OPERATOR
-
- qint32 v1 = QScriptEnginePrivate::convertToNativeInt32(lhs);
- qint32 v2 = QScriptEnginePrivate::convertToNativeInt32(rhs);
-
- stackPtr -= 3;
- *stackPtr = QScriptValueImpl(v1 ^ v2);
-
- END_INPLACE_OPERATOR
- } Next();
-
- I(MakeReference):
- {
- CHECK_TEMPSTACK(1);
- eng->newReference(++stackPtr, QScriptValue::ResolveLocal);
- ++iPtr;
- } Next();
-
- I(TypeOf):
- {
- QScriptValueImpl value;
-
- bool isReference = stackPtr[0].isReference();
-
- if (! isReference) { // we have a value
- value = stackPtr[0];
- } else if (resolveField(eng, &stackPtr[-1], &value)) {
- stackPtr -= 2;
- if (hasUncaughtException()) {
- stackPtr -= 1;
- HandleException();
- }
- } else {
- value = undefined;
- stackPtr -= 2;
- }
-
- QString typeName;
-
- switch (value.type()) {
- case QScript::InvalidType:
- typeName = QLatin1String("invalid");
- break;
-
- case QScript::UndefinedType:
- typeName = QLatin1String("undefined");
- break;
-
- case QScript::NullType:
- typeName = QLatin1String("object");
- break;
-
- case QScript::BooleanType:
- typeName = QLatin1String("boolean");
- break;
-
- case QScript::IntegerType:
- case QScript::NumberType:
- typeName = QLatin1String("number");
- break;
-
- case QScript::StringType:
- case QScript::LazyStringType:
- typeName = QLatin1String("string");
- break;
-
- case QScript::ReferenceType:
- typeName = QLatin1String("reference");
- break;
-
- case QScript::PointerType:
- typeName = QLatin1String("pointer");
- break;
-
- case QScript::ObjectType:
- if (value.isFunction())
- typeName = QLatin1String("function");
- else
- typeName = QLatin1String("object");
- break;
- }
-
- eng->newString(stackPtr, typeName);
- ++iPtr;
- } Next();
-
- I(Line):
- {
- eng->maybeGC();
- eng->maybeProcessEvents();
- if (hasUncaughtException())
- HandleException();
- if (eng->shouldAbort())
- Abort();
- currentLine = iPtr->operand[0].m_int_value;
- currentColumn = iPtr->operand[1].m_int_value;
-#ifndef Q_SCRIPT_NO_EVENT_NOTIFY
- if (eng->shouldNotify()) {
- eng->notifyPositionChange(this);
- if (hasUncaughtException())
- HandleException();
- if (eng->shouldAbort())
- Abort();
- }
-#endif
- ++iPtr;
- } Next();
-
- I(Delete):
- {
- bool result;
- if (! stackPtr[0].isReference())
- result = true;
-
- else {
- QScriptValueImpl object = stackPtr[-2];
- if (!object.isObject())
- object = eng->toObject(object);
-
- QScriptNameIdImpl *nameId = 0;
- if (stackPtr[-1].isString() && stackPtr[-1].m_string_value->unique) {
- nameId = stackPtr[-1].m_string_value;
- } else {
- nameId = eng->nameId(QScriptEnginePrivate::convertToNativeString(stackPtr[-1]),
- /*persistent=*/false);
- }
- if (object.classInfo() == eng->m_class_with)
- object = object.prototype();
- result = object.deleteProperty(nameId, QScriptValue::ResolveScope);
- stackPtr -= 2;
- }
-
- *stackPtr = QScriptValueImpl(result);
-
- ++iPtr;
- } Next();
-
-
- I(NewEnumeration): {
- QScriptValueImpl e;
- QScriptValueImpl object = eng->toObject(stackPtr[0]);
- eng->enumerationConstructor->newEnumeration(&e, object);
- *stackPtr = e;
- ++iPtr;
- } Next();
-
-
- I(ToFirstElement): {
- QScript::Ext::Enumeration::Instance *e = eng->enumerationConstructor->get(stackPtr[0]);
- Q_ASSERT(e != 0);
- e->toFront();
- --stackPtr;
- ++iPtr;
- } Next();
-
-
- I(HasNextElement): {
- QScript::Ext::Enumeration::Instance *e = eng->enumerationConstructor->get(stackPtr[0]);
- Q_ASSERT(e != 0);
- e->hasNext(this, stackPtr);
- ++iPtr;
- } Next();
-
-
- I(NextElement): {
- // the Enumeration should be located below the result of I(Resolve)
- if (! stackPtr[0].isReference()) {
- throwTypeError(QLatin1String("QScript.VM.NextElement"));
- HandleException();
- }
-
- QScript::Ext::Enumeration::Instance *e = eng->enumerationConstructor->get(stackPtr[-3]);
- if (! e) {
- throwTypeError(QLatin1String("QScript.VM.NextElement"));
- HandleException();
- }
- e->next(this, ++stackPtr);
- ++iPtr;
- } Next();
-
-
- I(Pop):
- {
- --stackPtr;
- ++iPtr;
- } Next();
-
- I(Sync):
- {
- m_result = *stackPtr;
- --stackPtr;
- ++iPtr;
- } Next();
-
- I(Throw):
- {
- Q_ASSERT(stackPtr->isValid());
- m_result = *stackPtr--;
- if (!m_result.isError() && !exceptionHandlerContext())
- eng->m_exceptionBacktrace = backtrace();
- m_state = QScriptContext::ExceptionState;
-#ifndef Q_SCRIPT_NO_EVENT_NOTIFY
- eng->notifyException(this);
-#endif
- } HandleException();
-
- I(Ret):
- {
- Q_ASSERT(stackPtr->isValid());
- m_result = *stackPtr--;
- ++iPtr;
- } Done();
-
- I(Halt):
- {
- ++iPtr;
- } Done();
-
- I(EnterWith):
- {
- QScriptValueImpl object = eng->toObject(*stackPtr--);
- if (! object.isValid()) {
- throwTypeError(QLatin1String("value has no properties"));
- HandleException();
- }
- QScriptValueImpl withObject;
- eng->newObject(&withObject, object, eng->m_class_with);
- withObject.m_object_value->m_scope = m_scopeChain;
- m_scopeChain = withObject;
- ++iPtr;
- } Next();
-
- I(LeaveWith):
- {
- QScriptValueImpl withObject = m_scopeChain;
- m_scopeChain = withObject.m_object_value->m_scope;
- ++iPtr;
- } Next();
-
- I(BeginCatch):
- {
- // result contains the thrown object
- QScriptValueImpl object;
- eng->newObject(&object, undefined); // ### prototype
- QScript::Member member;
- CREATE_MEMBER(object, iPtr->operand[0].m_string_value, &member, /*flags=*/0);
- object.put(member, m_result);
- // make catch-object head of scopechain
- object.m_object_value->m_scope = m_scopeChain;
- m_scopeChain = object;
-
- catching = true;
- ++iPtr;
- } Next();
-
- I(EndCatch):
- {
- // remove catch-object from scopechain
- QScriptValueImpl object = m_scopeChain;
- m_scopeChain = object.m_object_value->m_scope;
-
- catching = false;
- ++iPtr;
- } Next();
-
- I(Debugger):
- {
-#ifndef Q_SCRIPT_NO_EVENT_NOTIFY
- eng->notifyDebugger(this);
-#endif
- ++iPtr;
- } Next();
-
-#ifndef Q_SCRIPT_DIRECT_CODE
- I(Dummy):
- { ; }
-
- } // end switch
-#endif
-
-Lhandle_exception:
- errorLineNumber = currentLine;
-
-Ldone:
- Q_ASSERT(m_result.isValid());
-
- if (m_state == QScriptContext::ExceptionState) {
- if (catching) {
- // exception thrown in catch -- clean up scopechain
- QScriptValueImpl object = m_scopeChain;
- m_scopeChain = object.m_object_value->m_scope;
- catching = false;
- }
-
- // see if we have an exception handler in this context
- const QScriptInstruction *exPtr = findExceptionHandler(iPtr);
- if (exPtr) {
- if (m_scopeChain.classInfo() == eng->m_class_with) {
- // clean up effects of with-statements if necessary
- int withLevel = 0;
- for (++iPtr; iPtr != exPtr; ++iPtr) {
- if (iPtr->op == QScriptInstruction::OP_EnterWith) {
- ++withLevel;
- } else if (iPtr->op == QScriptInstruction::OP_LeaveWith) {
- --withLevel;
- if (withLevel < 0) {
- QScriptValueImpl withObject = m_scopeChain;
- m_scopeChain = withObject.m_object_value->m_scope;
- }
- }
- }
- } else {
- iPtr = exPtr;
- }
- // go to the handler
- recover();
-#ifndef Q_SCRIPT_NO_EVENT_NOTIFY
- eng->notifyExceptionCatch(this);
-#endif
- goto Ltop;
- } else {
- if (!parentContext()) {
- // pop all the top-level with-objects
- while ((m_scopeChain.classInfo() == eng->m_class_with)
- && !m_scopeChain.internalValue().isValid()) {
- QScriptValueImpl withObject = m_scopeChain;
- m_scopeChain = withObject.m_object_value->m_scope;
- }
- }
- }
- }
-
-Labort:
-#ifndef Q_SCRIPT_NO_EVENT_NOTIFY
- eng->notifyFunctionExit(this);
-#endif
-
- eng->maybeGC();
-
- currentLine = oldCurrentLine;
- currentColumn = oldCurrentColumn;
- m_code = oldCode;
-
- eng->m_evaluating = wasEvaluating;
-}
-
-QScriptValueImpl QScriptContextPrivate::throwError(QScriptContext::Error error, const QString &text)
-{
- QScriptEnginePrivate *eng_p = engine();
- QScript::Ecma::Error *ctor = eng_p->errorConstructor;
- m_result.invalidate();
- switch (error) {
- case QScriptContext::ReferenceError:
- ctor->newReferenceError(&m_result, text);
- break;
- case QScriptContext::SyntaxError:
- ctor->newSyntaxError(&m_result, text);
- break;
- case QScriptContext::TypeError:
- ctor->newTypeError(&m_result, text);
- break;
- case QScriptContext::RangeError:
- ctor->newRangeError(&m_result, text);
- break;
- case QScriptContext::URIError:
- ctor->newURIError(&m_result, text);
- break;
- case QScriptContext::UnknownError:
- default:
- ctor->newError(&m_result, text);
- }
- setDebugInformation(&m_result);
- m_state = QScriptContext::ExceptionState;
-#ifndef Q_SCRIPT_NO_EVENT_NOTIFY
- eng_p->notifyException(this);
-#endif
- return m_result;
-}
-
-#ifndef Q_SCRIPT_NO_EVENT_NOTIFY
-qint64 QScriptContextPrivate::scriptId() const
-{
- if (!m_code)
- return -1;
- return m_code->astPool->id();
-}
-#endif
-
-QString QScriptContextPrivate::fileName() const
-{
- if (!m_code)
- return QString();
- return m_code->astPool->fileName();
-}
-
-QString QScriptContextPrivate::functionName() const
-{
- if (!m_callee.isValid())
- return QString();
- QScriptFunction *fun = m_callee.toFunction();
- if (fun)
- return fun->functionName();
- return QString();
-}
-
-void QScriptContextPrivate::setDebugInformation(QScriptValueImpl *error) const
-{
- QScriptEnginePrivate *eng_p = engine();
- error->setProperty(QLatin1String("lineNumber"), QScriptValueImpl(currentLine));
- if (!fileName().isEmpty())
- error->setProperty(QLatin1String("fileName"), QScriptValueImpl(eng_p, fileName()));
-
- const QScriptContextPrivate *ctx = this;
- QScriptValueImpl stackArray = eng_p->newArray();
- int i = 0;
- while (ctx) {
- QScriptValueImpl obj = eng_p->newObject();
- obj.setProperty(QLatin1String("frame"), ctx->activationObject());
- obj.setProperty(QLatin1String("lineNumber"), QScriptValueImpl(ctx->currentLine));
- if (!ctx->fileName().isEmpty())
- obj.setProperty(QLatin1String("fileName"), QScriptValueImpl(eng_p, ctx->fileName()));
- if (!ctx->functionName().isEmpty())
- obj.setProperty(QLatin1String("functionName"), QScriptValueImpl(eng_p, ctx->functionName()));
- stackArray.setProperty(i, obj);
- ctx = ctx->parentContext();
- ++i;
- }
- error->setProperty(QLatin1String("stack"), stackArray);
-}
-
-QStringList QScriptContextPrivate::backtrace() const
-{
- QStringList result;
- const QScriptContextPrivate *ctx = this;
- while (ctx) {
- QString s;
- QString functionName = ctx->functionName();
- if (!functionName.isEmpty())
- s += functionName;
- else {
- if (ctx->parentContext()) {
- if (ctx->callee().isFunction()
- && ctx->callee().toFunction()->type() != QScriptFunction::Script) {
- s += QLatin1String("<native>");
- } else {
- s += QLatin1String("<anonymous>");
- }
- } else {
- s += QLatin1String("<global>");
- }
- }
- s += QLatin1Char('(');
- for (int i = 0; i < ctx->argc; ++i) {
- if (i > 0)
- s += QLatin1Char(',');
- QScriptValueImpl arg = ctx->args[i];
- if (arg.isObject())
- s += QLatin1String("[object Object]"); // don't do a function call
- else
- s += arg.toString();
- }
- s += QLatin1String(")@");
- s += ctx->fileName();
- s += QString::fromLatin1(":%0").arg(ctx->currentLine);
- result.append(s);
- ctx = ctx->parentContext();
- }
- return result;
-}
-
-QScriptValueImpl QScriptContextPrivate::throwError(const QString &text)
-{
- return throwError(QScriptContext::UnknownError, text);
-}
-
-QScriptValueImpl QScriptContextPrivate::throwNotImplemented(const QString &name)
-{
- return throwTypeError(QString::fromUtf8("%1 is not implemented").arg(name));
-}
-
-QScriptValueImpl QScriptContextPrivate::throwNotDefined(const QString &name)
-{
- return throwError(QScriptContext::ReferenceError,
- QString::fromUtf8("%1 is not defined").arg(name));
-}
-
-QScriptValueImpl QScriptContextPrivate::throwNotDefined(QScriptNameIdImpl *nameId)
-{
- return throwNotDefined(QScriptEnginePrivate::toString(nameId));
-}
-
-bool QScriptContextPrivate::eq_cmp_helper(QScriptValueImpl lhs, QScriptValueImpl rhs)
-{
- if (lhs.isNull() && rhs.isUndefined())
- return true;
-
- else if (lhs.isUndefined() && rhs.isNull())
- return true;
-
- else if (isNumerical(lhs) && rhs.isString())
- return QScriptEnginePrivate::convertToNativeDouble(lhs) == QScriptEnginePrivate::convertToNativeDouble(rhs);
-
- else if (lhs.isString() && isNumerical(rhs))
- return QScriptEnginePrivate::convertToNativeDouble(lhs) == QScriptEnginePrivate::convertToNativeDouble(rhs);
-
- else if (lhs.isBoolean())
- return eq_cmp(QScriptValueImpl(QScriptEnginePrivate::convertToNativeDouble(lhs)), rhs);
-
- else if (rhs.isBoolean())
- return eq_cmp(lhs, QScriptValueImpl(QScriptEnginePrivate::convertToNativeDouble(rhs)));
-
- else if (lhs.isObject() && ! rhs.isNull()) {
- lhs = lhs.engine()->toPrimitive(lhs);
-
- if (lhs.isValid() && ! lhs.isObject())
- return eq_cmp(lhs, rhs);
- }
-
- else if (rhs.isObject() && ! lhs.isNull()) {
- rhs = rhs.engine()->toPrimitive(rhs);
-
- if (rhs.isValid() && ! rhs.isObject())
- return eq_cmp(lhs, rhs);
- }
-
- return false;
-}
-
-#if defined(Q_CC_GNU) && __GNUC__ <= 3
-bool QScriptContextPrivate::lt_cmp(QScriptValueImpl lhs, QScriptValueImpl rhs)
-{
- if (lhs.type() == rhs.type()) {
- switch (lhs.type()) {
- case QScript::InvalidType:
- case QScript::UndefinedType:
- case QScript::NullType:
- return false;
-
- case QScript::NumberType:
- return lhs.m_number_value < rhs.m_number_value;
-
- case QScript::IntegerType:
- return lhs.m_int_value < rhs.m_int_value;
-
- case QScript::BooleanType:
- return lhs.m_bool_value < rhs.m_bool_value;
-
- default:
- break;
- } // switch
- }
-#else
-bool QScriptContextPrivate::lt_cmp_helper(QScriptValueImpl lhs, QScriptValueImpl rhs)
-{
-#endif
- if ((lhs.type() == rhs.type()) && (lhs.type() == QScript::StringType))
- return lhs.m_string_value->s < rhs.m_string_value->s;
-
- if (lhs.isObject())
- lhs = lhs.engine()->toPrimitive(lhs, QScriptValueImpl::NumberTypeHint);
-
- if (rhs.isObject())
- rhs = rhs.engine()->toPrimitive(rhs, QScriptValueImpl::NumberTypeHint);
-
- if (lhs.isString() && rhs.isString())
- return QScriptEnginePrivate::convertToNativeString(lhs) < QScriptEnginePrivate::convertToNativeString(rhs);
-
- qsreal n1 = QScriptEnginePrivate::convertToNativeDouble(lhs);
- qsreal n2 = QScriptEnginePrivate::convertToNativeDouble(rhs);
-#if defined Q_CC_MSVC && !defined Q_CC_MSVC_NET
- if (qIsNaN(n1) || qIsNaN(n2))
- return false;
-#endif
- return n1 < n2;
-}
-
-bool QScriptContextPrivate::le_cmp_helper(QScriptValueImpl lhs, QScriptValueImpl rhs)
-{
- if ((lhs.type() == rhs.type()) && (lhs.type() == QScript::StringType))
- return lhs.m_string_value->s <= rhs.m_string_value->s;
-
- if (lhs.isObject())
- lhs = lhs.engine()->toPrimitive(lhs, QScriptValueImpl::NumberTypeHint);
-
- if (rhs.isObject())
- rhs = rhs.engine()->toPrimitive(rhs, QScriptValueImpl::NumberTypeHint);
-
- if (lhs.isString() && rhs.isString())
- return QScriptEnginePrivate::convertToNativeString(lhs) <= QScriptEnginePrivate::convertToNativeString(rhs);
-
- qsreal n1 = QScriptEnginePrivate::convertToNativeDouble(lhs);
- qsreal n2 = QScriptEnginePrivate::convertToNativeDouble(rhs);
- return n1 <= n2;
-}
-
-const QScriptInstruction *QScriptContextPrivate::findExceptionHandler(
- const QScriptInstruction *ip) const
-{
- Q_ASSERT(m_code);
- int offset = ip - m_code->firstInstruction;
- for (int i = 0; i < m_code->exceptionHandlers.count(); ++i) {
- QScript::ExceptionHandlerDescriptor e = m_code->exceptionHandlers.at(i);
- if (offset >= e.startInstruction() && offset <= e.endInstruction()) {
- return m_code->firstInstruction + e.handlerInstruction();
- }
- }
- return 0;
-}
-
-const QScriptInstruction *QScriptContextPrivate::findExceptionHandlerRecursive(
- const QScriptInstruction *ip, QScriptContextPrivate **handlerContext) const
-{
- const QScriptContextPrivate *ctx = this;
- const QScriptInstruction *iip = ip;
- while (ctx) {
- if (ctx->m_code) {
- const QScriptInstruction *ep = ctx->findExceptionHandler(iip);
- if (ep) {
- Q_ASSERT(handlerContext);
- *handlerContext = const_cast<QScriptContextPrivate*>(ctx);
- return ep;
- }
- }
- ctx = ctx->parentContext();
- if (ctx)
- iip = ctx->iPtr;
- }
- return 0;
-}
-
-/*!
- Requires that iPtr in current context is in sync
-*/
-QScriptContextPrivate *QScriptContextPrivate::exceptionHandlerContext() const
-{
- QScriptContextPrivate *handlerContext;
- if (findExceptionHandlerRecursive(iPtr, &handlerContext))
- return handlerContext;
- return 0;
-}
-
-QScriptContext *QScriptContextPrivate::get(QScriptContextPrivate *d)
-{
- if (d)
- return d->q_func();
- return 0;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_SCRIPT