****************************************************************************/
#include "qmljs_runtime.h"
+#include "qmljs_environment.h"
#include <stdio.h>
#include <setjmp.h>
--- /dev/null
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the V4VM module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <qmljs_engine.h>
+#include <qmljs_objects.h>
+#include <qv4ecmaobjects_p.h>
+
+namespace QQmlJS {
+namespace VM {
+
+ExecutionEngine::ExecutionEngine()
+{
+ rootContext = newContext();
+ rootContext->init(this);
+
+ id_length = identifier(QStringLiteral("length"));
+ id_prototype = identifier(QStringLiteral("prototype"));
+ id_constructor = identifier(QStringLiteral("constructor"));
+ id_arguments = identifier(QStringLiteral("arguments"));
+ id___proto__ = identifier(QStringLiteral("__proto__"));
+
+ objectPrototype = new ObjectPrototype();
+ stringPrototype = new StringPrototype(rootContext);
+ numberPrototype = new NumberPrototype();
+ booleanPrototype = new BooleanPrototype();
+ arrayPrototype = new ArrayPrototype();
+ datePrototype = new DatePrototype();
+ functionPrototype = new FunctionPrototype(rootContext);
+ regExpPrototype = new RegExpPrototype();
+ errorPrototype = new ErrorPrototype();
+ evalErrorPrototype = new EvalErrorPrototype(rootContext);
+ rangeErrorPrototype = new RangeErrorPrototype(rootContext);
+ referenceErrorPrototype = new ReferenceErrorPrototype(rootContext);
+ syntaxErrorPrototype = new SyntaxErrorPrototype(rootContext);
+ typeErrorPrototype = new TypeErrorPrototype(rootContext);
+ uRIErrorPrototype = new URIErrorPrototype(rootContext);
+
+ stringPrototype->prototype = objectPrototype;
+ numberPrototype->prototype = objectPrototype;
+ booleanPrototype->prototype = objectPrototype;
+ arrayPrototype->prototype = objectPrototype;
+ datePrototype->prototype = objectPrototype;
+ functionPrototype->prototype = objectPrototype;
+ regExpPrototype->prototype = objectPrototype;
+ errorPrototype->prototype = objectPrototype;
+ evalErrorPrototype->prototype = errorPrototype;
+ rangeErrorPrototype->prototype = errorPrototype;
+ referenceErrorPrototype->prototype = errorPrototype;
+ syntaxErrorPrototype->prototype = errorPrototype;
+ typeErrorPrototype->prototype = errorPrototype;
+ uRIErrorPrototype->prototype = errorPrototype;
+
+ objectCtor = Value::fromObject(new ObjectCtor(rootContext));
+ stringCtor = Value::fromObject(new StringCtor(rootContext));
+ numberCtor = Value::fromObject(new NumberCtor(rootContext));
+ booleanCtor = Value::fromObject(new BooleanCtor(rootContext));
+ arrayCtor = Value::fromObject(new ArrayCtor(rootContext));
+ functionCtor = Value::fromObject(new FunctionCtor(rootContext));
+ dateCtor = Value::fromObject(new DateCtor(rootContext));
+ regExpCtor = Value::fromObject(new RegExpCtor(rootContext));
+ errorCtor = Value::fromObject(new ErrorCtor(rootContext));
+ evalErrorCtor = Value::fromObject(new EvalErrorCtor(rootContext));
+ rangeErrorCtor = Value::fromObject(new RangeErrorCtor(rootContext));
+ referenceErrorCtor = Value::fromObject(new ReferenceErrorCtor(rootContext));
+ syntaxErrorCtor = Value::fromObject(new SyntaxErrorCtor(rootContext));
+ typeErrorCtor = Value::fromObject(new TypeErrorCtor(rootContext));
+ uRIErrorCtor = Value::fromObject(new URIErrorCtor(rootContext));
+
+ stringCtor.objectValue()->prototype = functionPrototype;
+ numberCtor.objectValue()->prototype = functionPrototype;
+ booleanCtor.objectValue()->prototype = functionPrototype;
+ arrayCtor.objectValue()->prototype = functionPrototype;
+ functionCtor.objectValue()->prototype = functionPrototype;
+ dateCtor.objectValue()->prototype = functionPrototype;
+ regExpCtor.objectValue()->prototype = functionPrototype;
+ errorCtor.objectValue()->prototype = functionPrototype;
+ evalErrorCtor.objectValue()->prototype = errorPrototype;
+ rangeErrorCtor.objectValue()->prototype = errorPrototype;
+ referenceErrorCtor.objectValue()->prototype = errorPrototype;
+ syntaxErrorCtor.objectValue()->prototype = errorPrototype;
+ typeErrorCtor.objectValue()->prototype = errorPrototype;
+ uRIErrorCtor.objectValue()->prototype = errorPrototype;
+
+ objectPrototype->init(rootContext, objectCtor);
+ stringPrototype->init(rootContext, stringCtor);
+ numberPrototype->init(rootContext, numberCtor);
+ booleanPrototype->init(rootContext, booleanCtor);
+ arrayPrototype->init(rootContext, arrayCtor);
+ datePrototype->init(rootContext, dateCtor);
+ functionPrototype->init(rootContext, functionCtor);
+ regExpPrototype->init(rootContext, regExpCtor);
+ errorPrototype->init(rootContext, errorCtor);
+ evalErrorPrototype->init(rootContext, evalErrorCtor);
+ rangeErrorPrototype->init(rootContext, rangeErrorCtor);
+ referenceErrorPrototype->init(rootContext, referenceErrorCtor);
+ syntaxErrorPrototype->init(rootContext, syntaxErrorCtor);
+ typeErrorPrototype->init(rootContext, typeErrorCtor);
+ uRIErrorPrototype->init(rootContext, uRIErrorCtor);
+
+ //
+ // set up the global object
+ //
+ VM::Object *glo = newObject(/*rootContext*/);
+ globalObject = Value::fromObject(glo);
+ rootContext->activation = glo;
+
+ glo->__put__(rootContext, identifier(QStringLiteral("Object")), objectCtor);
+ glo->__put__(rootContext, identifier(QStringLiteral("String")), stringCtor);
+ glo->__put__(rootContext, identifier(QStringLiteral("Number")), numberCtor);
+ glo->__put__(rootContext, identifier(QStringLiteral("Boolean")), booleanCtor);
+ glo->__put__(rootContext, identifier(QStringLiteral("Array")), arrayCtor);
+ glo->__put__(rootContext, identifier(QStringLiteral("Function")), functionCtor);
+ glo->__put__(rootContext, identifier(QStringLiteral("Date")), dateCtor);
+ glo->__put__(rootContext, identifier(QStringLiteral("RegExp")), regExpCtor);
+ glo->__put__(rootContext, identifier(QStringLiteral("Error")), errorCtor);
+ glo->__put__(rootContext, identifier(QStringLiteral("EvalError")), evalErrorCtor);
+ glo->__put__(rootContext, identifier(QStringLiteral("RangeError")), rangeErrorCtor);
+ glo->__put__(rootContext, identifier(QStringLiteral("ReferenceError")), referenceErrorCtor);
+ glo->__put__(rootContext, identifier(QStringLiteral("SyntaxError")), syntaxErrorCtor);
+ glo->__put__(rootContext, identifier(QStringLiteral("TypeError")), typeErrorCtor);
+ glo->__put__(rootContext, identifier(QStringLiteral("URIError")), uRIErrorCtor);
+ glo->__put__(rootContext, identifier(QStringLiteral("Math")), Value::fromObject(newMathObject(rootContext)));
+ glo->__put__(rootContext, identifier(QStringLiteral("undefined")), Value::undefinedValue());
+ glo->__put__(rootContext, identifier(QStringLiteral("NaN")), Value::fromDouble(nan("")));
+ glo->__put__(rootContext, identifier(QStringLiteral("Infinity")), Value::fromDouble(INFINITY));
+ glo->__put__(rootContext, identifier(QStringLiteral("eval")), Value::fromObject(new EvalFunction(rootContext)));
+
+
+}
+
+ExecutionContext *ExecutionEngine::newContext()
+{
+ return new ExecutionContext();
+}
+
+String *ExecutionEngine::identifier(const QString &s)
+{
+ String *&id = identifiers[s];
+ if (! id)
+ id = newString(s);
+ return id;
+}
+
+FunctionObject *ExecutionEngine::newNativeFunction(ExecutionContext *scope, void (*code)(ExecutionContext *))
+{
+ NativeFunction *f = new NativeFunction(scope, code);
+ f->prototype = scope->engine->functionPrototype;
+ return f;
+}
+
+FunctionObject *ExecutionEngine::newScriptFunction(ExecutionContext *scope, IR::Function *function)
+{
+ ScriptFunction *f = new ScriptFunction(scope, function);
+ Object *proto = scope->engine->newObject();
+ proto->__put__(scope, scope->engine->id_constructor, Value::fromObject(f));
+ f->__put__(scope, scope->engine->id_prototype, Value::fromObject(proto));
+ f->prototype = scope->engine->functionPrototype;
+ return f;
+}
+
+Object *ExecutionEngine::newObject()
+{
+ Object *object = new Object();
+ object->prototype = objectPrototype;
+ return object;
+}
+
+FunctionObject *ExecutionEngine::newObjectCtor(ExecutionContext *ctx)
+{
+ return new ObjectCtor(ctx);
+}
+
+String *ExecutionEngine::newString(const QString &s)
+{
+ return new String(s);
+}
+
+Object *ExecutionEngine::newStringObject(const Value &value)
+{
+ StringObject *object = new StringObject(value);
+ object->prototype = stringPrototype;
+ return object;
+}
+
+FunctionObject *ExecutionEngine::newStringCtor(ExecutionContext *ctx)
+{
+ return new StringCtor(ctx);
+}
+
+Object *ExecutionEngine::newNumberObject(const Value &value)
+{
+ NumberObject *object = new NumberObject(value);
+ object->prototype = numberPrototype;
+ return object;
+}
+
+FunctionObject *ExecutionEngine::newNumberCtor(ExecutionContext *ctx)
+{
+ return new NumberCtor(ctx);
+}
+
+Object *ExecutionEngine::newBooleanObject(const Value &value)
+{
+ Object *object = new BooleanObject(value);
+ object->prototype = booleanPrototype;
+ return object;
+}
+
+FunctionObject *ExecutionEngine::newBooleanCtor(ExecutionContext *ctx)
+{
+ return new BooleanCtor(ctx);
+}
+
+Object *ExecutionEngine::newFunctionObject(ExecutionContext *ctx)
+{
+ Object *object = new FunctionObject(ctx);
+ object->prototype = functionPrototype;
+ return object;
+}
+
+FunctionObject *ExecutionEngine::newFunctionCtor(ExecutionContext *ctx)
+{
+ return new FunctionCtor(ctx);
+}
+
+Object *ExecutionEngine::newArrayObject()
+{
+ ArrayObject *object = new ArrayObject();
+ object->prototype = arrayPrototype;
+ return object;
+}
+
+Object *ExecutionEngine::newArrayObject(const Array &value)
+{
+ ArrayObject *object = new ArrayObject(value);
+ object->prototype = arrayPrototype;
+ return object;
+}
+
+FunctionObject *ExecutionEngine::newArrayCtor(ExecutionContext *ctx)
+{
+ return new ArrayCtor(ctx);
+}
+
+Object *ExecutionEngine::newDateObject(const Value &value)
+{
+ Object *object = new DateObject(value);
+ object->prototype = datePrototype;
+ return object;
+}
+
+FunctionObject *ExecutionEngine::newDateCtor(ExecutionContext *ctx)
+{
+ return new DateCtor(ctx);
+}
+
+Object *ExecutionEngine::newRegExpObject(const QString &pattern, int flags)
+{
+ bool global = (flags & IR::RegExp::RegExp_Global);
+ QRegularExpression::PatternOptions options = 0;
+ if (flags & IR::RegExp::RegExp_IgnoreCase)
+ options |= QRegularExpression::CaseInsensitiveOption;
+ if (flags & IR::RegExp::RegExp_Multiline)
+ options |= QRegularExpression::MultilineOption;
+
+ Object *object = new RegExpObject(QRegularExpression(pattern, options), global);
+ object->prototype = regExpPrototype;
+ return object;
+}
+
+FunctionObject *ExecutionEngine::newRegExpCtor(ExecutionContext *ctx)
+{
+ return new RegExpCtor(ctx);
+}
+
+Object *ExecutionEngine::newErrorObject(const Value &value)
+{
+ ErrorObject *object = new ErrorObject(value);
+ object->prototype = errorPrototype;
+ return object;
+}
+
+Object *ExecutionEngine::newMathObject(ExecutionContext *ctx)
+{
+ MathObject *object = new MathObject(ctx);
+ object->prototype = objectPrototype;
+ return object;
+}
+
+Object *ExecutionEngine::newActivationObject(ExecutionContext *ctx)
+{
+ return new ActivationObject(ctx);
+}
+
+Object *ExecutionEngine::newForEachIteratorObject(Object *o)
+{
+ return new ForEachIteratorObject(o);
+}
+
+
+} // namespace VM
+} // namespace QQmlJS
--- /dev/null
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the V4VM module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QMLJS_ENGINE_H
+#define QMLJS_ENGINE_H
+
+#include <qmljs_objects.h>
+#include <setjmp.h>
+
+namespace QQmlJS {
+namespace VM {
+
+struct Value;
+struct Array;
+struct Object;
+struct BooleanObject;
+struct NumberObject;
+struct StringObject;
+struct ArrayObject;
+struct DateObject;
+struct FunctionObject;
+struct RegExpObject;
+struct ErrorObject;
+struct ActivationObject;
+struct ArgumentsObject;
+struct ExecutionContext;
+struct ExecutionEngine;
+
+struct ObjectPrototype;
+struct StringPrototype;
+struct NumberPrototype;
+struct BooleanPrototype;
+struct ArrayPrototype;
+struct FunctionPrototype;
+struct DatePrototype;
+struct RegExpPrototype;
+struct ErrorPrototype;
+struct EvalErrorPrototype;
+struct RangeErrorPrototype;
+struct ReferenceErrorPrototype;
+struct SyntaxErrorPrototype;
+struct TypeErrorPrototype;
+struct URIErrorPrototype;
+
+struct ExecutionEngine
+{
+ ExecutionContext *rootContext;
+ Value globalObject;
+
+ Value objectCtor;
+ Value stringCtor;
+ Value numberCtor;
+ Value booleanCtor;
+ Value arrayCtor;
+ Value functionCtor;
+ Value dateCtor;
+ Value regExpCtor;
+ Value errorCtor;
+ Value evalErrorCtor;
+ Value rangeErrorCtor;
+ Value referenceErrorCtor;
+ Value syntaxErrorCtor;
+ Value typeErrorCtor;
+ Value uRIErrorCtor;
+
+ ObjectPrototype *objectPrototype;
+ StringPrototype *stringPrototype;
+ NumberPrototype *numberPrototype;
+ BooleanPrototype *booleanPrototype;
+ ArrayPrototype *arrayPrototype;
+ FunctionPrototype *functionPrototype;
+ DatePrototype *datePrototype;
+ RegExpPrototype *regExpPrototype;
+ ErrorPrototype *errorPrototype;
+ EvalErrorPrototype *evalErrorPrototype;
+ RangeErrorPrototype *rangeErrorPrototype;
+ ReferenceErrorPrototype *referenceErrorPrototype;
+ SyntaxErrorPrototype *syntaxErrorPrototype;
+ TypeErrorPrototype *typeErrorPrototype;
+ URIErrorPrototype *uRIErrorPrototype;
+
+ QHash<QString, String *> identifiers;
+
+ String *id_length;
+ String *id_prototype;
+ String *id_constructor;
+ String *id_arguments;
+ String *id___proto__;
+
+ struct ExceptionHandler {
+ ExecutionContext *context;
+ const uchar *code; // Interpreter state
+ int targetTempIndex; // Interpreter state
+ jmp_buf stackFrame;
+ };
+
+ QVector<ExceptionHandler> unwindStack;
+
+ ExecutionEngine();
+
+ ExecutionContext *newContext();
+
+ String *identifier(const QString &s);
+
+ FunctionObject *newNativeFunction(ExecutionContext *scope, void (*code)(ExecutionContext *));
+ FunctionObject *newScriptFunction(ExecutionContext *scope, IR::Function *function);
+
+ Object *newObject();
+ FunctionObject *newObjectCtor(ExecutionContext *ctx);
+
+ String *newString(const QString &s);
+ Object *newStringObject(const Value &value);
+ FunctionObject *newStringCtor(ExecutionContext *ctx);
+
+ Object *newNumberObject(const Value &value);
+ FunctionObject *newNumberCtor(ExecutionContext *ctx);
+
+ Object *newBooleanObject(const Value &value);
+ FunctionObject *newBooleanCtor(ExecutionContext *ctx);
+
+ Object *newFunctionObject(ExecutionContext *ctx);
+ FunctionObject *newFunctionCtor(ExecutionContext *ctx);
+
+ Object *newArrayObject();
+ Object *newArrayObject(const Array &value);
+ FunctionObject *newArrayCtor(ExecutionContext *ctx);
+
+ Object *newDateObject(const Value &value);
+ FunctionObject *newDateCtor(ExecutionContext *ctx);
+
+ Object *newRegExpObject(const QString &pattern, int flags);
+ FunctionObject *newRegExpCtor(ExecutionContext *ctx);
+
+ Object *newErrorObject(const Value &value);
+ Object *newMathObject(ExecutionContext *ctx);
+ Object *newActivationObject(ExecutionContext *ctx);
+
+ Object *newForEachIteratorObject(Object *o);
+};
+
+
+} // namespace VM
+} // namespace QQmlJS
+
+#endif
--- /dev/null
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the V4VM module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <qmljs_environment.h>
+#include <qmljs_objects.h>
+#include <qv4ecmaobjects_p.h>
+
+namespace QQmlJS {
+namespace VM {
+
+void ExecutionContext::init(ExecutionEngine *eng)
+{
+ engine = eng;
+ parent = 0;
+ arguments = 0;
+ argumentCount = 0;
+ locals = 0;
+ activation = 0;
+ thisObject = Value::nullValue();
+ result = Value::undefinedValue();
+ formals = 0;
+ formalCount = 0;
+ vars = 0;
+ varCount = 0;
+}
+
+PropertyDescriptor *ExecutionContext::lookupPropertyDescriptor(String *name, PropertyDescriptor *tmp)
+{
+ for (ExecutionContext *ctx = this; ctx; ctx = ctx->parent) {
+ if (ctx->activation) {
+ if (PropertyDescriptor *pd = ctx->activation->__getPropertyDescriptor__(this, name, tmp))
+ return pd;
+ }
+ }
+ return 0;
+}
+
+void ExecutionContext::inplaceBitOp(Value value, String *name, BinOp op)
+{
+ for (ExecutionContext *ctx = this; ctx; ctx = ctx->parent) {
+ if (ctx->activation) {
+ if (ctx->activation->inplaceBinOp(value, name, op, this))
+ return;
+ }
+ }
+ throwReferenceError(Value::fromString(name));
+}
+
+void ExecutionContext::throwError(Value value)
+{
+ result = value;
+ __qmljs_builtin_throw(value, this);
+}
+
+void ExecutionContext::throwError(const QString &message)
+{
+ Value v = Value::fromString(this, message);
+ throwError(Value::fromObject(engine->newErrorObject(v)));
+}
+
+void ExecutionContext::throwTypeError()
+{
+ Value v = Value::fromString(this, QStringLiteral("Type error"));
+ throwError(Value::fromObject(engine->newErrorObject(v)));
+}
+
+void ExecutionContext::throwUnimplemented(const QString &message)
+{
+ Value v = Value::fromString(this, QStringLiteral("Unimplemented ") + message);
+ throwError(Value::fromObject(engine->newErrorObject(v)));
+}
+
+void ExecutionContext::throwReferenceError(Value value)
+{
+ String *s = value.toString(this);
+ QString msg = s->toQString() + QStringLiteral(" is not defined");
+ throwError(Value::fromObject(engine->newErrorObject(Value::fromString(this, msg))));
+}
+
+void ExecutionContext::initCallContext(ExecutionContext *parent, const Value that, FunctionObject *f, Value *args, unsigned argc)
+{
+ engine = parent->engine;
+ this->parent = f->scope;
+ assert(this->parent == f->scope);
+ result = Value::undefinedValue();
+
+ if (f->needsActivation)
+ activation = engine->newActivationObject(this);
+ else
+ activation = 0;
+
+ thisObject = that;
+
+ formals = f->formalParameterList;
+ formalCount = f->formalParameterCount;
+ arguments = args;
+ argumentCount = argc;
+ if (f->needsActivation || argc < formalCount){
+ arguments = new Value[qMax(argc, formalCount)];
+ if (argc)
+ std::copy(args, args + argc, arguments);
+ if (argc < formalCount)
+ std::fill(arguments + argc, arguments + formalCount, Value::undefinedValue());
+ }
+ vars = f->varList;
+ varCount = f->varCount;
+ locals = varCount ? new Value[varCount] : 0;
+ if (varCount)
+ std::fill(locals, locals + varCount, Value::undefinedValue());
+}
+
+void ExecutionContext::leaveCallContext()
+{
+ if (activation) {
+ delete[] locals;
+ locals = 0;
+ }
+}
+
+void ExecutionContext::initConstructorContext(ExecutionContext *parent, Value that, FunctionObject *f, Value *args, unsigned argc)
+{
+ initCallContext(parent, that, f, args, argc);
+}
+
+void ExecutionContext::leaveConstructorContext(FunctionObject *f)
+{
+ wireUpPrototype(f);
+ leaveCallContext();
+}
+
+void ExecutionContext::wireUpPrototype(FunctionObject *f)
+{
+ assert(thisObject.isObject());
+ result = thisObject;
+
+ Value proto = f->__get__(this, engine->id_prototype);
+ thisObject.objectValue()->prototype = proto.objectValue();
+ if (! thisObject.isObject())
+ thisObject.objectValue()->prototype = engine->objectPrototype;
+
+}
+
+} // namespace VM
+} // namespace QQmlJS
--- /dev/null
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the V4VM module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QMLJS_ENVIRONMENT_H
+#define QMLJS_ENVIRONMENT_H
+
+#include <qmljs_runtime.h>
+
+namespace QQmlJS {
+namespace VM {
+
+struct Value;
+struct Object;
+struct ExecutionEngine;
+struct ExecutionContext;
+
+struct ExecutionContext {
+ ExecutionEngine *engine;
+ ExecutionContext *parent;
+ Object *activation;
+ Value thisObject;
+ Value *arguments;
+ unsigned int argumentCount;
+ Value *locals;
+ Value result;
+ String **formals;
+ unsigned int formalCount;
+ String **vars;
+ unsigned int varCount;
+
+ PropertyDescriptor *lookupPropertyDescriptor(String *name, PropertyDescriptor *tmp);
+ void inplaceBitOp(Value value, String *name, BinOp op);
+
+ inline Value argument(unsigned int index = 0)
+ {
+ if (index < argumentCount)
+ return arguments[index];
+ return Value::undefinedValue();
+ }
+
+ void init(ExecutionEngine *eng);
+
+ void initCallContext(ExecutionContext *parent, const Value that, FunctionObject *f, Value *args, unsigned argc);
+ void leaveCallContext();
+
+ void initConstructorContext(ExecutionContext *parent, Value that, FunctionObject *f, Value *args, unsigned argc);
+ void leaveConstructorContext(FunctionObject *f);
+ void wireUpPrototype(FunctionObject *f);
+
+ void throwError(Value value);
+ void throwError(const QString &message);
+ void throwTypeError();
+ void throwReferenceError(Value value);
+ void throwUnimplemented(const QString &message);
+};
+
+
+} // namespace VM
+} // namespace QQmlJS
+
+#endif
return Object::__getPropertyDescriptor__(ctx, name, to_fill);
}
-
-ExecutionEngine::ExecutionEngine()
-{
- rootContext = newContext();
- rootContext->init(this);
-
- id_length = identifier(QStringLiteral("length"));
- id_prototype = identifier(QStringLiteral("prototype"));
- id_constructor = identifier(QStringLiteral("constructor"));
- id_arguments = identifier(QStringLiteral("arguments"));
- id___proto__ = identifier(QStringLiteral("__proto__"));
-
- objectPrototype = new ObjectPrototype();
- stringPrototype = new StringPrototype(rootContext);
- numberPrototype = new NumberPrototype();
- booleanPrototype = new BooleanPrototype();
- arrayPrototype = new ArrayPrototype();
- datePrototype = new DatePrototype();
- functionPrototype = new FunctionPrototype(rootContext);
- regExpPrototype = new RegExpPrototype();
- errorPrototype = new ErrorPrototype();
- evalErrorPrototype = new EvalErrorPrototype(rootContext);
- rangeErrorPrototype = new RangeErrorPrototype(rootContext);
- referenceErrorPrototype = new ReferenceErrorPrototype(rootContext);
- syntaxErrorPrototype = new SyntaxErrorPrototype(rootContext);
- typeErrorPrototype = new TypeErrorPrototype(rootContext);
- uRIErrorPrototype = new URIErrorPrototype(rootContext);
-
- stringPrototype->prototype = objectPrototype;
- numberPrototype->prototype = objectPrototype;
- booleanPrototype->prototype = objectPrototype;
- arrayPrototype->prototype = objectPrototype;
- datePrototype->prototype = objectPrototype;
- functionPrototype->prototype = objectPrototype;
- regExpPrototype->prototype = objectPrototype;
- errorPrototype->prototype = objectPrototype;
- evalErrorPrototype->prototype = errorPrototype;
- rangeErrorPrototype->prototype = errorPrototype;
- referenceErrorPrototype->prototype = errorPrototype;
- syntaxErrorPrototype->prototype = errorPrototype;
- typeErrorPrototype->prototype = errorPrototype;
- uRIErrorPrototype->prototype = errorPrototype;
-
- objectCtor = Value::fromObject(new ObjectCtor(rootContext));
- stringCtor = Value::fromObject(new StringCtor(rootContext));
- numberCtor = Value::fromObject(new NumberCtor(rootContext));
- booleanCtor = Value::fromObject(new BooleanCtor(rootContext));
- arrayCtor = Value::fromObject(new ArrayCtor(rootContext));
- functionCtor = Value::fromObject(new FunctionCtor(rootContext));
- dateCtor = Value::fromObject(new DateCtor(rootContext));
- regExpCtor = Value::fromObject(new RegExpCtor(rootContext));
- errorCtor = Value::fromObject(new ErrorCtor(rootContext));
- evalErrorCtor = Value::fromObject(new EvalErrorCtor(rootContext));
- rangeErrorCtor = Value::fromObject(new RangeErrorCtor(rootContext));
- referenceErrorCtor = Value::fromObject(new ReferenceErrorCtor(rootContext));
- syntaxErrorCtor = Value::fromObject(new SyntaxErrorCtor(rootContext));
- typeErrorCtor = Value::fromObject(new TypeErrorCtor(rootContext));
- uRIErrorCtor = Value::fromObject(new URIErrorCtor(rootContext));
-
- stringCtor.objectValue()->prototype = functionPrototype;
- numberCtor.objectValue()->prototype = functionPrototype;
- booleanCtor.objectValue()->prototype = functionPrototype;
- arrayCtor.objectValue()->prototype = functionPrototype;
- functionCtor.objectValue()->prototype = functionPrototype;
- dateCtor.objectValue()->prototype = functionPrototype;
- regExpCtor.objectValue()->prototype = functionPrototype;
- errorCtor.objectValue()->prototype = functionPrototype;
- evalErrorCtor.objectValue()->prototype = errorPrototype;
- rangeErrorCtor.objectValue()->prototype = errorPrototype;
- referenceErrorCtor.objectValue()->prototype = errorPrototype;
- syntaxErrorCtor.objectValue()->prototype = errorPrototype;
- typeErrorCtor.objectValue()->prototype = errorPrototype;
- uRIErrorCtor.objectValue()->prototype = errorPrototype;
-
- objectPrototype->init(rootContext, objectCtor);
- stringPrototype->init(rootContext, stringCtor);
- numberPrototype->init(rootContext, numberCtor);
- booleanPrototype->init(rootContext, booleanCtor);
- arrayPrototype->init(rootContext, arrayCtor);
- datePrototype->init(rootContext, dateCtor);
- functionPrototype->init(rootContext, functionCtor);
- regExpPrototype->init(rootContext, regExpCtor);
- errorPrototype->init(rootContext, errorCtor);
- evalErrorPrototype->init(rootContext, evalErrorCtor);
- rangeErrorPrototype->init(rootContext, rangeErrorCtor);
- referenceErrorPrototype->init(rootContext, referenceErrorCtor);
- syntaxErrorPrototype->init(rootContext, syntaxErrorCtor);
- typeErrorPrototype->init(rootContext, typeErrorCtor);
- uRIErrorPrototype->init(rootContext, uRIErrorCtor);
-
- //
- // set up the global object
- //
- VM::Object *glo = newObject(/*rootContext*/);
- globalObject = Value::fromObject(glo);
- rootContext->activation = glo;
-
- glo->__put__(rootContext, identifier(QStringLiteral("Object")), objectCtor);
- glo->__put__(rootContext, identifier(QStringLiteral("String")), stringCtor);
- glo->__put__(rootContext, identifier(QStringLiteral("Number")), numberCtor);
- glo->__put__(rootContext, identifier(QStringLiteral("Boolean")), booleanCtor);
- glo->__put__(rootContext, identifier(QStringLiteral("Array")), arrayCtor);
- glo->__put__(rootContext, identifier(QStringLiteral("Function")), functionCtor);
- glo->__put__(rootContext, identifier(QStringLiteral("Date")), dateCtor);
- glo->__put__(rootContext, identifier(QStringLiteral("RegExp")), regExpCtor);
- glo->__put__(rootContext, identifier(QStringLiteral("Error")), errorCtor);
- glo->__put__(rootContext, identifier(QStringLiteral("EvalError")), evalErrorCtor);
- glo->__put__(rootContext, identifier(QStringLiteral("RangeError")), rangeErrorCtor);
- glo->__put__(rootContext, identifier(QStringLiteral("ReferenceError")), referenceErrorCtor);
- glo->__put__(rootContext, identifier(QStringLiteral("SyntaxError")), syntaxErrorCtor);
- glo->__put__(rootContext, identifier(QStringLiteral("TypeError")), typeErrorCtor);
- glo->__put__(rootContext, identifier(QStringLiteral("URIError")), uRIErrorCtor);
- glo->__put__(rootContext, identifier(QStringLiteral("Math")), Value::fromObject(newMathObject(rootContext)));
- glo->__put__(rootContext, identifier(QStringLiteral("undefined")), Value::undefinedValue());
- glo->__put__(rootContext, identifier(QStringLiteral("NaN")), Value::fromDouble(nan("")));
- glo->__put__(rootContext, identifier(QStringLiteral("Infinity")), Value::fromDouble(INFINITY));
- glo->__put__(rootContext, identifier(QStringLiteral("eval")), Value::fromObject(new EvalFunction(rootContext)));
-
-
-}
-
-ExecutionContext *ExecutionEngine::newContext()
-{
- return new ExecutionContext();
-}
-
-String *ExecutionEngine::identifier(const QString &s)
-{
- String *&id = identifiers[s];
- if (! id)
- id = newString(s);
- return id;
-}
-
-FunctionObject *ExecutionEngine::newNativeFunction(ExecutionContext *scope, void (*code)(ExecutionContext *))
-{
- NativeFunction *f = new NativeFunction(scope, code);
- f->prototype = scope->engine->functionPrototype;
- return f;
-}
-
-FunctionObject *ExecutionEngine::newScriptFunction(ExecutionContext *scope, IR::Function *function)
-{
- ScriptFunction *f = new ScriptFunction(scope, function);
- Object *proto = scope->engine->newObject();
- proto->__put__(scope, scope->engine->id_constructor, Value::fromObject(f));
- f->__put__(scope, scope->engine->id_prototype, Value::fromObject(proto));
- f->prototype = scope->engine->functionPrototype;
- return f;
-}
-
-Object *ExecutionEngine::newObject()
-{
- Object *object = new Object();
- object->prototype = objectPrototype;
- return object;
-}
-
-FunctionObject *ExecutionEngine::newObjectCtor(ExecutionContext *ctx)
-{
- return new ObjectCtor(ctx);
-}
-
-String *ExecutionEngine::newString(const QString &s)
-{
- return new String(s);
-}
-
-Object *ExecutionEngine::newStringObject(const Value &value)
-{
- StringObject *object = new StringObject(value);
- object->prototype = stringPrototype;
- return object;
-}
-
-FunctionObject *ExecutionEngine::newStringCtor(ExecutionContext *ctx)
-{
- return new StringCtor(ctx);
-}
-
-Object *ExecutionEngine::newNumberObject(const Value &value)
-{
- NumberObject *object = new NumberObject(value);
- object->prototype = numberPrototype;
- return object;
-}
-
-FunctionObject *ExecutionEngine::newNumberCtor(ExecutionContext *ctx)
-{
- return new NumberCtor(ctx);
-}
-
-Object *ExecutionEngine::newBooleanObject(const Value &value)
-{
- Object *object = new BooleanObject(value);
- object->prototype = booleanPrototype;
- return object;
-}
-
-FunctionObject *ExecutionEngine::newBooleanCtor(ExecutionContext *ctx)
-{
- return new BooleanCtor(ctx);
-}
-
-Object *ExecutionEngine::newFunctionObject(ExecutionContext *ctx)
-{
- Object *object = new FunctionObject(ctx);
- object->prototype = functionPrototype;
- return object;
-}
-
-FunctionObject *ExecutionEngine::newFunctionCtor(ExecutionContext *ctx)
-{
- return new FunctionCtor(ctx);
-}
-
-Object *ExecutionEngine::newArrayObject()
-{
- ArrayObject *object = new ArrayObject();
- object->prototype = arrayPrototype;
- return object;
-}
-
-Object *ExecutionEngine::newArrayObject(const Array &value)
-{
- ArrayObject *object = new ArrayObject(value);
- object->prototype = arrayPrototype;
- return object;
-}
-
-FunctionObject *ExecutionEngine::newArrayCtor(ExecutionContext *ctx)
-{
- return new ArrayCtor(ctx);
-}
-
-Object *ExecutionEngine::newDateObject(const Value &value)
-{
- Object *object = new DateObject(value);
- object->prototype = datePrototype;
- return object;
-}
-
-FunctionObject *ExecutionEngine::newDateCtor(ExecutionContext *ctx)
-{
- return new DateCtor(ctx);
-}
-
-Object *ExecutionEngine::newRegExpObject(const QString &pattern, int flags)
-{
- bool global = (flags & IR::RegExp::RegExp_Global);
- QRegularExpression::PatternOptions options = 0;
- if (flags & IR::RegExp::RegExp_IgnoreCase)
- options |= QRegularExpression::CaseInsensitiveOption;
- if (flags & IR::RegExp::RegExp_Multiline)
- options |= QRegularExpression::MultilineOption;
-
- Object *object = new RegExpObject(QRegularExpression(pattern, options), global);
- object->prototype = regExpPrototype;
- return object;
-}
-
-FunctionObject *ExecutionEngine::newRegExpCtor(ExecutionContext *ctx)
-{
- return new RegExpCtor(ctx);
-}
-
-Object *ExecutionEngine::newErrorObject(const Value &value)
-{
- ErrorObject *object = new ErrorObject(value);
- object->prototype = errorPrototype;
- return object;
-}
-
-Object *ExecutionEngine::newMathObject(ExecutionContext *ctx)
-{
- MathObject *object = new MathObject(ctx);
- object->prototype = objectPrototype;
- return object;
-}
-
-Object *ExecutionEngine::newActivationObject(ExecutionContext *ctx)
-{
- return new ActivationObject(ctx);
-}
-
-Object *ExecutionEngine::newForEachIteratorObject(Object *o)
-{
- return new ForEachIteratorObject(o);
-}
#define QMLJS_OBJECTS_H
#include "qmljs_runtime.h"
+#include "qmljs_engine.h"
+#include "qmljs_environment.h"
#include "qv4array_p.h"
#include "qv4codegen_p.h"
#include <QtCore/QRegularExpression>
#include <cstdio>
#include <cassert>
-#include <setjmp.h>
namespace QQmlJS {
virtual PropertyDescriptor *__getPropertyDescriptor__(ExecutionContext *ctx, String *name, PropertyDescriptor *to_fill);
};
-struct ExecutionEngine
-{
- ExecutionContext *rootContext;
- Value globalObject;
-
- Value objectCtor;
- Value stringCtor;
- Value numberCtor;
- Value booleanCtor;
- Value arrayCtor;
- Value functionCtor;
- Value dateCtor;
- Value regExpCtor;
- Value errorCtor;
- Value evalErrorCtor;
- Value rangeErrorCtor;
- Value referenceErrorCtor;
- Value syntaxErrorCtor;
- Value typeErrorCtor;
- Value uRIErrorCtor;
-
- ObjectPrototype *objectPrototype;
- StringPrototype *stringPrototype;
- NumberPrototype *numberPrototype;
- BooleanPrototype *booleanPrototype;
- ArrayPrototype *arrayPrototype;
- FunctionPrototype *functionPrototype;
- DatePrototype *datePrototype;
- RegExpPrototype *regExpPrototype;
- ErrorPrototype *errorPrototype;
- EvalErrorPrototype *evalErrorPrototype;
- RangeErrorPrototype *rangeErrorPrototype;
- ReferenceErrorPrototype *referenceErrorPrototype;
- SyntaxErrorPrototype *syntaxErrorPrototype;
- TypeErrorPrototype *typeErrorPrototype;
- URIErrorPrototype *uRIErrorPrototype;
-
- QHash<QString, String *> identifiers;
-
- String *id_length;
- String *id_prototype;
- String *id_constructor;
- String *id_arguments;
- String *id___proto__;
-
- struct ExceptionHandler {
- ExecutionContext *context;
- const uchar *code; // Interpreter state
- int targetTempIndex; // Interpreter state
- jmp_buf stackFrame;
- };
-
- QVector<ExceptionHandler> unwindStack;
-
- ExecutionEngine();
-
- ExecutionContext *newContext();
-
- String *identifier(const QString &s);
-
- FunctionObject *newNativeFunction(ExecutionContext *scope, void (*code)(ExecutionContext *));
- FunctionObject *newScriptFunction(ExecutionContext *scope, IR::Function *function);
-
- Object *newObject();
- FunctionObject *newObjectCtor(ExecutionContext *ctx);
-
- String *newString(const QString &s);
- Object *newStringObject(const Value &value);
- FunctionObject *newStringCtor(ExecutionContext *ctx);
-
- Object *newNumberObject(const Value &value);
- FunctionObject *newNumberCtor(ExecutionContext *ctx);
-
- Object *newBooleanObject(const Value &value);
- FunctionObject *newBooleanCtor(ExecutionContext *ctx);
-
- Object *newFunctionObject(ExecutionContext *ctx);
- FunctionObject *newFunctionCtor(ExecutionContext *ctx);
-
- Object *newArrayObject();
- Object *newArrayObject(const Array &value);
- FunctionObject *newArrayCtor(ExecutionContext *ctx);
-
- Object *newDateObject(const Value &value);
- FunctionObject *newDateCtor(ExecutionContext *ctx);
-
- Object *newRegExpObject(const QString &pattern, int flags);
- FunctionObject *newRegExpCtor(ExecutionContext *ctx);
-
- Object *newErrorObject(const Value &value);
- Object *newMathObject(ExecutionContext *ctx);
- Object *newActivationObject(ExecutionContext *ctx);
-
- Object *newForEachIteratorObject(Object *o);
-};
-
} // namespace VM
} // namespace QQmlJS
return isObject() ? objectValue()->__get__(ctx, name) : undefinedValue();
}
-void ExecutionContext::init(ExecutionEngine *eng)
-{
- engine = eng;
- parent = 0;
- arguments = 0;
- argumentCount = 0;
- locals = 0;
- activation = 0;
- thisObject = Value::nullValue();
- result = Value::undefinedValue();
- formals = 0;
- formalCount = 0;
- vars = 0;
- varCount = 0;
-}
-
-PropertyDescriptor *ExecutionContext::lookupPropertyDescriptor(String *name, PropertyDescriptor *tmp)
-{
- for (ExecutionContext *ctx = this; ctx; ctx = ctx->parent) {
- if (ctx->activation) {
- if (PropertyDescriptor *pd = ctx->activation->__getPropertyDescriptor__(this, name, tmp))
- return pd;
- }
- }
- return 0;
-}
-
-void ExecutionContext::inplaceBitOp(Value value, String *name, BinOp op)
-{
- for (ExecutionContext *ctx = this; ctx; ctx = ctx->parent) {
- if (ctx->activation) {
- if (ctx->activation->inplaceBinOp(value, name, op, this))
- return;
- }
- }
- throwReferenceError(Value::fromString(name));
-}
-
-void ExecutionContext::throwError(Value value)
-{
- result = value;
- __qmljs_builtin_throw(value, this);
-}
-
-void ExecutionContext::throwError(const QString &message)
-{
- Value v = Value::fromString(this, message);
- throwError(Value::fromObject(engine->newErrorObject(v)));
-}
-
-void ExecutionContext::throwTypeError()
-{
- Value v = Value::fromString(this, QStringLiteral("Type error"));
- throwError(Value::fromObject(engine->newErrorObject(v)));
-}
-
-void ExecutionContext::throwUnimplemented(const QString &message)
-{
- Value v = Value::fromString(this, QStringLiteral("Unimplemented ") + message);
- throwError(Value::fromObject(engine->newErrorObject(v)));
-}
-
-void ExecutionContext::throwReferenceError(Value value)
-{
- String *s = value.toString(this);
- QString msg = s->toQString() + QStringLiteral(" is not defined");
- throwError(Value::fromObject(engine->newErrorObject(Value::fromString(this, msg))));
-}
-
-void ExecutionContext::initCallContext(ExecutionContext *parent, const Value that, FunctionObject *f, Value *args, unsigned argc)
-{
- engine = parent->engine;
- this->parent = f->scope;
- assert(this->parent == f->scope);
- result = Value::undefinedValue();
-
- if (f->needsActivation)
- activation = engine->newActivationObject(this);
- else
- activation = 0;
-
- thisObject = that;
-
- formals = f->formalParameterList;
- formalCount = f->formalParameterCount;
- arguments = args;
- argumentCount = argc;
- if (f->needsActivation || argc < formalCount){
- arguments = new Value[qMax(argc, formalCount)];
- if (argc)
- std::copy(args, args + argc, arguments);
- if (argc < formalCount)
- std::fill(arguments + argc, arguments + formalCount, Value::undefinedValue());
- }
- vars = f->varList;
- varCount = f->varCount;
- locals = varCount ? new Value[varCount] : 0;
- if (varCount)
- std::fill(locals, locals + varCount, Value::undefinedValue());
-}
-
-void ExecutionContext::leaveCallContext()
-{
- if (activation) {
- delete[] locals;
- locals = 0;
- }
-}
-
-void ExecutionContext::initConstructorContext(ExecutionContext *parent, Value that, FunctionObject *f, Value *args, unsigned argc)
-{
- initCallContext(parent, that, f, args, argc);
-}
-
-void ExecutionContext::leaveConstructorContext(FunctionObject *f)
-{
- wireUpPrototype(f);
- leaveCallContext();
-}
-
-void ExecutionContext::wireUpPrototype(FunctionObject *f)
-{
- assert(thisObject.isObject());
- result = thisObject;
-
- Value proto = f->__get__(this, engine->id_prototype);
- thisObject.objectValue()->prototype = proto.objectValue();
- if (! thisObject.isObject())
- thisObject.objectValue()->prototype = engine->objectPrototype;
-
-}
-
extern "C" {
Value __qmljs_init_closure(IR::Function *clos, ExecutionContext *ctx)
#include <qmljs_math.h>
-struct ExecutionContext {
- ExecutionEngine *engine;
- ExecutionContext *parent;
- Object *activation;
- Value thisObject;
- Value *arguments;
- unsigned int argumentCount;
- Value *locals;
- Value result;
- String **formals;
- unsigned int formalCount;
- String **vars;
- unsigned int varCount;
-
- PropertyDescriptor *lookupPropertyDescriptor(String *name, PropertyDescriptor *tmp);
- void inplaceBitOp(Value value, String *name, BinOp op);
-
- inline Value argument(unsigned int index = 0)
- {
- if (index < argumentCount)
- return arguments[index];
- return Value::undefinedValue();
- }
-
- void init(ExecutionEngine *eng);
-
- void initCallContext(ExecutionContext *parent, const Value that, FunctionObject *f, Value *args, unsigned argc);
- void leaveCallContext();
-
- void initConstructorContext(ExecutionContext *parent, Value that, FunctionObject *f, Value *args, unsigned argc);
- void leaveConstructorContext(FunctionObject *f);
- void wireUpPrototype(FunctionObject *f);
-
- void throwError(Value value);
- void throwError(const QString &message);
- void throwTypeError();
- void throwReferenceError(Value value);
- void throwUnimplemented(const QString &message);
-};
-
-
extern "C" {
SOURCES += main.cpp \
qv4codegen.cpp \
qv4ir.cpp \
+ qmljs_engine.cpp \
+ qmljs_environment.cpp \
qmljs_runtime.cpp \
qmljs_objects.cpp \
qv4syntaxchecker.cpp \
HEADERS += \
qv4codegen_p.h \
qv4ir_p.h \
+ qmljs_engine.h \
+ qmljs_environment.h \
qmljs_runtime.h \
qmljs_objects.h \
qmljs_math.h \