diff --git a/llvm_runtime.cpp b/llvm_runtime.cpp index aa5d70ccbb..b911ad4880 100644 --- a/llvm_runtime.cpp +++ b/llvm_runtime.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qmljs_runtime.h" +#include "qmljs_environment.h" #include #include diff --git a/qmljs_engine.cpp b/qmljs_engine.cpp new file mode 100644 index 0000000000..9229dbd9a2 --- /dev/null +++ b/qmljs_engine.cpp @@ -0,0 +1,339 @@ +/**************************************************************************** +** +** 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 +#include +#include + +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 diff --git a/qmljs_engine.h b/qmljs_engine.h new file mode 100644 index 0000000000..ed4b0d4a16 --- /dev/null +++ b/qmljs_engine.h @@ -0,0 +1,182 @@ +/**************************************************************************** +** +** 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 +#include + +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 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 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 diff --git a/qmljs_environment.cpp b/qmljs_environment.cpp new file mode 100644 index 0000000000..550d619fe1 --- /dev/null +++ b/qmljs_environment.cpp @@ -0,0 +1,181 @@ +/**************************************************************************** +** +** 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 +#include +#include + +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 diff --git a/qmljs_environment.h b/qmljs_environment.h new file mode 100644 index 0000000000..74568cdf25 --- /dev/null +++ b/qmljs_environment.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** 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 + +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 diff --git a/qmljs_objects.cpp b/qmljs_objects.cpp index d352774cdf..7552a83a03 100644 --- a/qmljs_objects.cpp +++ b/qmljs_objects.cpp @@ -686,292 +686,3 @@ PropertyDescriptor *ArgumentsObject::__getPropertyDescriptor__(ExecutionContext 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); -} diff --git a/qmljs_objects.h b/qmljs_objects.h index 963b7638c6..ce26089e8f 100644 --- a/qmljs_objects.h +++ b/qmljs_objects.h @@ -42,6 +42,8 @@ #define QMLJS_OBJECTS_H #include "qmljs_runtime.h" +#include "qmljs_engine.h" +#include "qmljs_environment.h" #include "qv4array_p.h" #include "qv4codegen_p.h" @@ -50,7 +52,6 @@ #include #include #include -#include namespace QQmlJS { @@ -600,102 +601,6 @@ struct ArgumentsObject: Object { 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 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 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 diff --git a/qmljs_runtime.cpp b/qmljs_runtime.cpp index ec97864192..d660aaf87b 100644 --- a/qmljs_runtime.cpp +++ b/qmljs_runtime.cpp @@ -230,138 +230,6 @@ Value Value::property(ExecutionContext *ctx, String *name) const 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) diff --git a/qmljs_runtime.h b/qmljs_runtime.h index 98c628cf9c..56cc95334d 100644 --- a/qmljs_runtime.h +++ b/qmljs_runtime.h @@ -570,47 +570,6 @@ inline bool Value::sameValue(Value other) { #include -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" { diff --git a/v4.pro b/v4.pro index c2790f044f..159e4d8967 100644 --- a/v4.pro +++ b/v4.pro @@ -13,6 +13,8 @@ LIBS += -rdynamic SOURCES += main.cpp \ qv4codegen.cpp \ qv4ir.cpp \ + qmljs_engine.cpp \ + qmljs_environment.cpp \ qmljs_runtime.cpp \ qmljs_objects.cpp \ qv4syntaxchecker.cpp \ @@ -24,6 +26,8 @@ SOURCES += main.cpp \ HEADERS += \ qv4codegen_p.h \ qv4ir_p.h \ + qmljs_engine.h \ + qmljs_environment.h \ qmljs_runtime.h \ qmljs_objects.h \ qmljs_math.h \