From 2104e7fdcb9c16cabc58e93f0cd1d11e36bdca34 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 1 Dec 2012 14:05:07 +0100 Subject: [PATCH] Remove the DeclarativeEnvironment class again The class is a specification detail that we can implement in a more performant way. ExecutionContext now contains everything needed again. Change-Id: Ideb5f04eeeecaf2b8543676c626e3943e4d6d7a1 Reviewed-by: Simon Hausmann --- debugging.cpp | 8 +-- llvm_runtime.cpp | 2 +- main.cpp | 6 +-- moth/qv4vme_moth.cpp | 28 +++++------ qmljs_engine.cpp | 4 +- qmljs_engine.h | 4 +- qmljs_environment.cpp | 73 ++++++++++++--------------- qmljs_environment.h | 29 ++++------- qmljs_objects.cpp | 26 +++++----- qmljs_objects.h | 8 +-- qmljs_runtime.cpp | 18 +++---- qv4ecmaobjects.cpp | 134 +++++++++++++++++++++++++------------------------- qv4isel_masm.cpp | 6 +-- 13 files changed, 159 insertions(+), 187 deletions(-) diff --git a/debugging.cpp b/debugging.cpp index a54c1a0..207eab7 100644 --- a/debugging.cpp +++ b/debugging.cpp @@ -50,16 +50,16 @@ FunctionState::~FunctionState() VM::Value *FunctionState::argument(unsigned idx) { - if (idx < _context->lexicalEnvironment->argumentCount) - return _context->lexicalEnvironment->arguments + idx; + if (idx < _context->argumentCount) + return _context->arguments + idx; else return 0; } VM::Value *FunctionState::local(unsigned idx) { - if (idx < _context->lexicalEnvironment->variableCount()) - return _context->lexicalEnvironment->locals + idx; + if (idx < _context->variableCount()) + return _context->locals + idx; return 0; } diff --git a/llvm_runtime.cpp b/llvm_runtime.cpp index c5d1fd0..76abd79 100644 --- a/llvm_runtime.cpp +++ b/llvm_runtime.cpp @@ -55,7 +55,7 @@ Value __qmljs_llvm_return(ExecutionContext */*ctx*/, Value *result) Value *__qmljs_llvm_get_argument(ExecutionContext *ctx, int index) { - return &ctx->lexicalEnvironment->arguments[index]; + return &ctx->arguments[index]; } void __qmljs_llvm_init_undefined(Value *result) diff --git a/main.cpp b/main.cpp index 8418dc1..9090cd2 100644 --- a/main.cpp +++ b/main.cpp @@ -75,7 +75,7 @@ struct Print: FunctionObject virtual Value call(ExecutionContext *ctx) { - for (unsigned int i = 0; i < ctx->argumentCount(); ++i) { + for (unsigned int i = 0; i < ctx->argumentCount; ++i) { String *s = ctx->argument(i).toString(ctx); if (i) std::cout << ' '; @@ -96,7 +96,7 @@ struct TestHarnessError: FunctionObject { errorOccurred = true; - for (unsigned int i = 0; i < ctx->argumentCount(); ++i) { + for (unsigned int i = 0; i < ctx->argumentCount; ++i) { String *s = ctx->argument(i).toString(ctx); if (i) std::cerr << ' '; @@ -357,7 +357,7 @@ int main(int argc, char *argv[]) QQmlJS::IR::Function *f = QQmlJS::VM::EvalFunction::parseSource(ctx, fn, code, QQmlJS::Codegen::GlobalCode); if (!f) continue; - ctx->lexicalEnvironment->strictMode = f->isStrict; + ctx->strictMode = f->isStrict; if (debugger) debugger->aboutToCall(0, ctx); QQmlJS::VM::Value result = f->code(ctx, f->codeData); diff --git a/moth/qv4vme_moth.cpp b/moth/qv4vme_moth.cpp index ff42684..138d81a 100644 --- a/moth/qv4vme_moth.cpp +++ b/moth/qv4vme_moth.cpp @@ -53,8 +53,6 @@ using namespace QQmlJS::Moth; static inline VM::Value *tempValue(QQmlJS::VM::ExecutionContext *context, QVector &stack, int index) { - VM::DeclarativeEnvironment *varEnv = context->lexicalEnvironment; - #ifdef DO_TRACE_INSTR const char *kind; int pos; @@ -76,17 +74,17 @@ static inline VM::Value *tempValue(QQmlJS::VM::ExecutionContext *context, QVecto const int arg = -index - 1; Q_ASSERT(arg >= 0); - Q_ASSERT((unsigned) arg < varEnv->argumentCount); - Q_ASSERT(varEnv->arguments); + Q_ASSERT((unsigned) arg < context->argumentCount); + Q_ASSERT(context->arguments); - return varEnv->arguments + arg; - } else if (index < (int) varEnv->variableCount()) { + return context->arguments + arg; + } else if (index < (int) context->variableCount()) { Q_ASSERT(index >= 0); - Q_ASSERT(varEnv->locals); + Q_ASSERT(context->locals); - return varEnv->locals + index; + return context->locals + index; } else { - int off = index - varEnv->variableCount(); + int off = index - context->variableCount(); Q_ASSERT(off >= 0); Q_ASSERT(off < stack.size()); @@ -231,21 +229,21 @@ VM::Value VME::operator()(QQmlJS::VM::ExecutionContext *context, const uchar *co } } #endif // DO_TRACE_INSTR - quint32 argStart = instr.args - context->lexicalEnvironment->variableCount(); + quint32 argStart = instr.args - context->variableCount(); TRACE(Call, "value index = %d, argStart = %d, argc = %d, result temp index = %d", instr.destIndex, argStart, instr.argc, instr.targetTempIndex); VM::Value *args = stack.data() + argStart; TEMP(instr.targetTempIndex) = __qmljs_call_value(context, VM::Value::undefinedValue(), TEMP(instr.destIndex), args, instr.argc); MOTH_END_INSTR(CallValue) MOTH_BEGIN_INSTR(CallProperty) - quint32 argStart = instr.args - context->lexicalEnvironment->variableCount(); + quint32 argStart = instr.args - context->variableCount(); VM::Value *args = stack.data() + argStart; VM::Value base = TEMP(instr.baseTemp); TEMP(instr.targetTempIndex) = __qmljs_call_property(context, base, instr.name, args, instr.argc); MOTH_END_INSTR(CallProperty) MOTH_BEGIN_INSTR(CallBuiltin) - quint32 argStart = instr.args - context->lexicalEnvironment->variableCount(); + quint32 argStart = instr.args - context->variableCount(); VM::Value *args = stack.data() + argStart; void *buf; switch (instr.builtin) { @@ -325,20 +323,20 @@ VM::Value VME::operator()(QQmlJS::VM::ExecutionContext *context, const uchar *co MOTH_END_INSTR(CallBuiltinDeleteValue) MOTH_BEGIN_INSTR(CreateValue) - quint32 argStart = instr.args - context->lexicalEnvironment->variableCount(); + quint32 argStart = instr.args - context->variableCount(); VM::Value *args = stack.data() + argStart; TEMP(instr.targetTempIndex) = __qmljs_construct_value(context, TEMP(instr.func), args, instr.argc); MOTH_END_INSTR(CreateValue) MOTH_BEGIN_INSTR(CreateProperty) - quint32 argStart = instr.args - context->lexicalEnvironment->variableCount(); + quint32 argStart = instr.args - context->variableCount(); VM::Value *args = stack.data() + argStart; TEMP(instr.targetTempIndex) = __qmljs_construct_property(context, TEMP(instr.base), instr.name, args, instr.argc); MOTH_END_INSTR(CreateProperty) MOTH_BEGIN_INSTR(CreateActivationProperty) TRACE(inline, "property name = %s, argc = %d", instr.name->toQString().toUtf8().constData(), instr.argc); - quint32 argStart = instr.args - context->lexicalEnvironment->variableCount(); + quint32 argStart = instr.args - context->variableCount(); VM::Value *args = stack.data() + argStart; TEMP(instr.targetTempIndex) = __qmljs_construct_activation_property(context, instr.name, args, instr.argc); MOTH_END_INSTR(CreateActivationProperty) diff --git a/qmljs_engine.cpp b/qmljs_engine.cpp index 4ccbe4e..6c5edd1 100644 --- a/qmljs_engine.cpp +++ b/qmljs_engine.cpp @@ -158,7 +158,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) // VM::Object *glo = newObject(/*rootContext*/); globalObject = Value::fromObject(glo); - rootContext->lexicalEnvironment->activation = glo; + rootContext->activation = glo; glo->__put__(rootContext, identifier(QStringLiteral("Object")), objectCtor); glo->__put__(rootContext, identifier(QStringLiteral("String")), stringCtor); @@ -348,7 +348,7 @@ Object *ExecutionEngine::newMathObject(ExecutionContext *ctx) return object; } -Object *ExecutionEngine::newActivationObject(DeclarativeEnvironment *ctx) +Object *ExecutionEngine::newActivationObject(ExecutionContext *ctx) { return new ActivationObject(ctx); } diff --git a/qmljs_engine.h b/qmljs_engine.h index 9b91f01..a6f1808 100644 --- a/qmljs_engine.h +++ b/qmljs_engine.h @@ -138,7 +138,7 @@ struct ExecutionEngine struct ExceptionHandler { ExecutionContext *context; - DeclarativeEnvironment::With *with; + ExecutionContext::With *with; const uchar *code; // Interpreter state int targetTempIndex; // Interpreter state jmp_buf stackFrame; @@ -186,7 +186,7 @@ struct ExecutionEngine Object *newErrorObject(const Value &value); Object *newSyntaxErrorObject(ExecutionContext *ctx, DiagnosticMessage *message); Object *newMathObject(ExecutionContext *ctx); - Object *newActivationObject(DeclarativeEnvironment *ctx); + Object *newActivationObject(ExecutionContext *ctx); Object *newForEachIteratorObject(Object *o); }; diff --git a/qmljs_environment.cpp b/qmljs_environment.cpp index 76f1c8c..ebbe7d3 100644 --- a/qmljs_environment.cpp +++ b/qmljs_environment.cpp @@ -73,19 +73,7 @@ String *DiagnosticMessage::buildFullMessage(ExecutionContext *ctx) const return ctx->engine->newString(msg); } -void DeclarativeEnvironment::init(ExecutionEngine *e) -{ - engine = e; - function = 0; - arguments = 0; - argumentCount = 0; - locals = 0; - activation = 0; - withObject = 0; - strictMode = false; -} - -void DeclarativeEnvironment::init(FunctionObject *f, Value *args, uint argc) +void ExecutionContext::init(FunctionObject *f, Value *args, uint argc) { function = f; engine = f->scope->engine; @@ -112,7 +100,7 @@ void DeclarativeEnvironment::init(FunctionObject *f, Value *args, uint argc) withObject = 0; } -bool DeclarativeEnvironment::hasBinding(String *name) const +bool ExecutionContext::hasBinding(String *name) const { if (!function) return false; @@ -128,7 +116,7 @@ bool DeclarativeEnvironment::hasBinding(String *name) const return false; } -void DeclarativeEnvironment::createMutableBinding(ExecutionContext *ctx, String *name, bool deletable) +void ExecutionContext::createMutableBinding(ExecutionContext *ctx, String *name, bool deletable) { if (!activation) activation = engine->newActivationObject(this); @@ -144,7 +132,7 @@ void DeclarativeEnvironment::createMutableBinding(ExecutionContext *ctx, String activation->__defineOwnProperty__(ctx, name, &desc); } -void DeclarativeEnvironment::setMutableBinding(String *name, Value value, bool strict) +void ExecutionContext::setMutableBinding(String *name, Value value, bool strict) { Q_UNUSED(strict); assert(function); @@ -165,7 +153,7 @@ void DeclarativeEnvironment::setMutableBinding(String *name, Value value, bool s assert(false); } -Value DeclarativeEnvironment::getBindingValue(String *name, bool strict) const +Value ExecutionContext::getBindingValue(String *name, bool strict) const { Q_UNUSED(strict); assert(function); @@ -181,17 +169,17 @@ Value DeclarativeEnvironment::getBindingValue(String *name, bool strict) const assert(false); } -bool DeclarativeEnvironment::deleteBinding(ExecutionContext *ctx, String *name) +bool ExecutionContext::deleteBinding(ExecutionContext *ctx, String *name) { if (activation) activation->__delete__(ctx, name); - if (ctx->lexicalEnvironment->strictMode) + if (ctx->strictMode) __qmljs_throw_type_error(ctx); return false; } -void DeclarativeEnvironment::pushWithObject(Object *with) +void ExecutionContext::pushWithObject(Object *with) { With *w = new With; w->next = withObject; @@ -199,7 +187,7 @@ void DeclarativeEnvironment::pushWithObject(Object *with) withObject = w; } -void DeclarativeEnvironment::popWithObject() +void ExecutionContext::popWithObject() { assert(withObject); @@ -208,27 +196,27 @@ void DeclarativeEnvironment::popWithObject() delete w; } -DeclarativeEnvironment *DeclarativeEnvironment::outer() const +ExecutionContext *ExecutionContext::outer() const { return function ? function->scope : 0; } -String **DeclarativeEnvironment::formals() const +String **ExecutionContext::formals() const { return function ? function->formalParameterList : 0; } -unsigned int DeclarativeEnvironment::formalCount() const +unsigned int ExecutionContext::formalCount() const { return function ? function->formalParameterCount : 0; } -String **DeclarativeEnvironment::variables() const +String **ExecutionContext::variables() const { return function ? function->varList : 0; } -unsigned int DeclarativeEnvironment::variableCount() const +unsigned int ExecutionContext::variableCount() const { return function ? function->varCount : 0; } @@ -238,17 +226,24 @@ void ExecutionContext::init(ExecutionEngine *eng) { engine = eng; parent = 0; - lexicalEnvironment = new DeclarativeEnvironment; - lexicalEnvironment->init(eng); thisObject = Value::nullValue(); + + function = 0; + arguments = 0; + argumentCount = 0; + locals = 0; + strictMode = false; + activation = 0; + withObject = 0; + eng->exception = Value::undefinedValue(); } PropertyDescriptor *ExecutionContext::lookupPropertyDescriptor(String *name, PropertyDescriptor *tmp) { - for (DeclarativeEnvironment *ctx = lexicalEnvironment; ctx; ctx = ctx->outer()) { + for (ExecutionContext *ctx = this; ctx; ctx = ctx->outer()) { if (ctx->withObject) { - DeclarativeEnvironment::With *w = ctx->withObject; + With *w = ctx->withObject; while (w) { if (PropertyDescriptor *pd = w->object->__getPropertyDescriptor__(this, name, tmp)) return pd; @@ -265,9 +260,9 @@ PropertyDescriptor *ExecutionContext::lookupPropertyDescriptor(String *name, Pro bool ExecutionContext::deleteProperty(String *name) { - for (DeclarativeEnvironment *ctx = lexicalEnvironment; ctx; ctx = ctx->outer()) { + for (ExecutionContext *ctx = this; ctx; ctx = ctx->outer()) { if (ctx->withObject) { - DeclarativeEnvironment::With *w = ctx->withObject; + ExecutionContext::With *w = ctx->withObject; while (w) { if (w->object->__hasProperty__(this, name)) w->object->__delete__(this, name); @@ -285,7 +280,7 @@ bool ExecutionContext::deleteProperty(String *name) void ExecutionContext::inplaceBitOp(Value value, String *name, BinOp op) { - for (DeclarativeEnvironment *ctx = lexicalEnvironment; ctx; ctx = ctx->outer()) { + for (ExecutionContext *ctx = this; ctx; ctx = ctx->outer()) { if (ctx->activation) { if (ctx->activation->inplaceBinOp(value, name, op, this)) return; @@ -334,8 +329,7 @@ void ExecutionContext::initCallContext(ExecutionContext *parent, const Value tha engine = parent->engine; this->parent = parent; - lexicalEnvironment = new DeclarativeEnvironment; - lexicalEnvironment->init(f, args, argc); + init(f, args, argc); thisObject = that; @@ -346,14 +340,11 @@ void ExecutionContext::initCallContext(ExecutionContext *parent, const Value tha void ExecutionContext::leaveCallContext() { // ## Should rather be handled by a the activation object having a ref to the environment - if (lexicalEnvironment->activation) { - delete[] lexicalEnvironment->locals; - lexicalEnvironment->locals = 0; + if (activation) { + delete[] locals; + locals = 0; } - delete lexicalEnvironment; - lexicalEnvironment = 0; - if (engine->debugger) engine->debugger->justLeft(this); } diff --git a/qmljs_environment.h b/qmljs_environment.h index d780c56..a34774e 100644 --- a/qmljs_environment.h +++ b/qmljs_environment.h @@ -69,23 +69,25 @@ struct DiagnosticMessage String *buildFullMessage(ExecutionContext *ctx) const; }; -// This merges LexicalEnvironment and EnvironmentRecord from -// Sec. 10.2 into one class -struct DeclarativeEnvironment +struct ExecutionContext { ExecutionEngine *engine; + ExecutionContext *parent; + Value thisObject; + FunctionObject *function; Value *arguments; unsigned int argumentCount; Value *locals; + String **formals() const; unsigned int formalCount() const; String **variables() const; unsigned int variableCount() const; - bool strictMode; + ExecutionContext *outer() const; - DeclarativeEnvironment *outer() const; + bool strictMode; Object *activation; struct With { @@ -103,20 +105,8 @@ struct DeclarativeEnvironment Value getBindingValue(String *name, bool strict) const; bool deleteBinding(ExecutionContext *ctx, String *name); - // ### needs a bit of work in exception handlers void pushWithObject(Object *with); void popWithObject(); -}; - -struct ExecutionContext -{ - ExecutionEngine *engine; - ExecutionContext *parent; - // ### Should be a general environment - DeclarativeEnvironment *lexicalEnvironment; - Value thisObject; - - void init(ExecutionEngine *eng); void initCallContext(ExecutionContext *parent, const Value that, FunctionObject *f, Value *args, unsigned argc); void leaveCallContext(); @@ -136,11 +126,10 @@ struct ExecutionContext void inplaceBitOp(Value value, String *name, BinOp op); bool deleteProperty(String *name); - inline uint argumentCount() const { return lexicalEnvironment->argumentCount; } inline Value argument(unsigned int index = 0) { - if (index < lexicalEnvironment->argumentCount) - return lexicalEnvironment->arguments[index]; + if (index < argumentCount) + return arguments[index]; return Value::undefinedValue(); } }; diff --git a/qmljs_objects.cpp b/qmljs_objects.cpp index 09e937d..75fab4b 100644 --- a/qmljs_objects.cpp +++ b/qmljs_objects.cpp @@ -211,7 +211,7 @@ void Object::__put__(ExecutionContext *ctx, String *name, Value value) } reject: - if (ctx->lexicalEnvironment->strictMode) + if (ctx->strictMode) __qmljs_throw_type_error(ctx); } @@ -233,7 +233,7 @@ bool Object::__delete__(ExecutionContext *ctx, String *name) members->remove(entry); return true; } - if (ctx->lexicalEnvironment->strictMode) + if (ctx->strictMode) __qmljs_throw_type_error(ctx); return false; } @@ -317,7 +317,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, String *name, Property return true; reject: qDebug() << "___put__ rejected" << name->toQString(); - if (ctx->lexicalEnvironment->strictMode) + if (ctx->strictMode) __qmljs_throw_type_error(ctx); return false; } @@ -487,7 +487,7 @@ Value EvalFunction::call(ExecutionContext *context, Value /*thisObject*/, Value if (!f) return Value::undefinedValue(); - bool strict = f->isStrict || context->lexicalEnvironment->strictMode; + bool strict = f->isStrict || context->strictMode; ExecutionContext k, *ctx; if (!directCall) { @@ -497,12 +497,8 @@ Value EvalFunction::call(ExecutionContext *context, Value /*thisObject*/, Value ctx = &k; ctx->initCallContext(context, context->thisObject, this, args, argc); } else { - ctx = &k; - // a clone of the surrounding context - ctx->engine = context->engine; - ctx->parent = context; - ctx->thisObject = context->thisObject; - ctx->lexicalEnvironment = context->lexicalEnvironment; + // use the surrounding context + ctx = context; } Value result = f->code(ctx, f->codeData); @@ -583,11 +579,11 @@ QQmlJS::IR::Function *EvalFunction::parseSource(QQmlJS::VM::ExecutionContext *ct __qmljs_throw_type_error(ctx); } - if (!ctx->lexicalEnvironment->activation) - ctx->lexicalEnvironment->activation = new QQmlJS::VM::Object(); + if (!ctx->activation) + ctx->activation = new QQmlJS::VM::Object(); foreach (const QString *local, globalCode->locals) { - ctx->lexicalEnvironment->activation->__put__(ctx, *local, QQmlJS::VM::Value::undefinedValue()); + ctx->activation->__put__(ctx, *local, QQmlJS::VM::Value::undefinedValue()); } return globalCode; } @@ -712,7 +708,7 @@ PropertyDescriptor *ActivationObject::__getPropertyDescriptor__(ExecutionContext Value ArgumentsObject::__get__(ExecutionContext *ctx, String *name) { if (name->isEqualTo(ctx->engine->id_length)) - return Value::fromInt32(context->argumentCount()); + return Value::fromInt32(context->argumentCount); return Object::__get__(ctx, name); } @@ -720,7 +716,7 @@ PropertyDescriptor *ArgumentsObject::__getPropertyDescriptor__(ExecutionContext { if (context) { const quint32 i = Value::fromString(name).toUInt32(ctx); - if (i < context->argumentCount()) { + if (i < context->argumentCount) { *to_fill = PropertyDescriptor::fromValue(context->argument(i)); to_fill->writable = PropertyDescriptor::Unset; to_fill->enumberable = PropertyDescriptor::Unset; diff --git a/qmljs_objects.h b/qmljs_objects.h index a74f619..927b9f3 100644 --- a/qmljs_objects.h +++ b/qmljs_objects.h @@ -490,7 +490,7 @@ struct ArrayObject: Object { }; struct FunctionObject: Object { - DeclarativeEnvironment *scope; + ExecutionContext *scope; String *name; String **formalParameterList; unsigned int formalParameterCount; @@ -500,7 +500,7 @@ struct FunctionObject: Object { bool strictMode; FunctionObject(ExecutionContext *scope) - : scope(scope ? scope->lexicalEnvironment : 0) + : scope(scope) , name(0) , formalParameterList(0) , formalParameterCount(0) @@ -633,9 +633,9 @@ struct URIErrorObject: ErrorObject { }; struct ActivationObject: Object { - DeclarativeEnvironment *context; + ExecutionContext *context; Value arguments; - ActivationObject(DeclarativeEnvironment *context) + ActivationObject(ExecutionContext *context) : context(context), arguments(Value::undefinedValue()) {} virtual QString className() { return QStringLiteral("Activation"); } virtual ActivationObject *asActivationObject() { return this; } diff --git a/qmljs_runtime.cpp b/qmljs_runtime.cpp index 6779f86..5aacc79 100644 --- a/qmljs_runtime.cpp +++ b/qmljs_runtime.cpp @@ -721,7 +721,7 @@ Value __qmljs_call_property(ExecutionContext *context, Value base, String *name, Value thisObject; if (base.isUndefined()) { - baseObject = context->lexicalEnvironment->activation; + baseObject = context->activation; thisObject = Value::nullValue(); } else { if (!base.isObject()) @@ -788,10 +788,10 @@ void __qmljs_throw(Value value, ExecutionContext *context) context->leaveCallContext(); context = context->parent; } - DeclarativeEnvironment *env = context->lexicalEnvironment; - while (env->withObject != handler.with) { - DeclarativeEnvironment::With *w = env->withObject; - env->withObject = w->next; + + while (context->withObject != handler.with) { + ExecutionContext::With *w = context->withObject; + context->withObject = w->next; delete w; } @@ -806,7 +806,7 @@ void *__qmljs_create_exception_handler(ExecutionContext *context) context->engine->unwindStack.append(ExecutionEngine::ExceptionHandler()); ExecutionEngine::ExceptionHandler &handler = context->engine->unwindStack.last(); handler.context = context; - handler.with = context->lexicalEnvironment->withObject; + handler.with = context->withObject; return handler.stackFrame; } @@ -835,17 +835,17 @@ void __qmljs_builtin_throw(Value val, ExecutionContext *context) void __qmljs_builtin_push_with(Value o, ExecutionContext *ctx) { Object *obj = __qmljs_to_object(o, ctx).asObject(); - ctx->lexicalEnvironment->pushWithObject(obj); + ctx->pushWithObject(obj); } void __qmljs_builtin_pop_with(ExecutionContext *ctx) { - ctx->lexicalEnvironment->popWithObject(); + ctx->popWithObject(); } void __qmljs_builtin_declare_var(ExecutionContext *ctx, bool deletable, String *name) { - ctx->lexicalEnvironment->createMutableBinding(ctx, name, deletable); + ctx->createMutableBinding(ctx, name, deletable); } } // extern "C" diff --git a/qv4ecmaobjects.cpp b/qv4ecmaobjects.cpp index dfaf5f8..642eaa8 100644 --- a/qv4ecmaobjects.cpp +++ b/qv4ecmaobjects.cpp @@ -789,7 +789,7 @@ Value ObjectPrototype::method_propertyIsEnumerable(ExecutionContext *ctx) Value ObjectPrototype::method_defineGetter(ExecutionContext *ctx) { - if (ctx->argumentCount() < 2) + if (ctx->argumentCount < 2) __qmljs_throw_type_error(ctx); String *prop = ctx->argument(0).toString(ctx); @@ -809,7 +809,7 @@ Value ObjectPrototype::method_defineGetter(ExecutionContext *ctx) Value ObjectPrototype::method_defineSetter(ExecutionContext *ctx) { - if (ctx->argumentCount() < 2) + if (ctx->argumentCount < 2) __qmljs_throw_type_error(ctx); String *prop = ctx->argument(0).toString(ctx); @@ -838,7 +838,7 @@ StringCtor::StringCtor(ExecutionContext *scope) Value StringCtor::construct(ExecutionContext *ctx) { Value value; - if (ctx->argumentCount()) + if (ctx->argumentCount) value = Value::fromString(ctx->argument(0).toString(ctx)); else value = Value::fromString(ctx, QString()); @@ -913,7 +913,7 @@ Value StringPrototype::method_charAt(ExecutionContext *ctx) const QString str = getThisString(ctx); int pos = 0; - if (ctx->argumentCount() > 0) + if (ctx->argumentCount > 0) pos = (int) ctx->argument(0).toInteger(ctx); QString result; @@ -928,7 +928,7 @@ Value StringPrototype::method_charCodeAt(ExecutionContext *ctx) const QString str = getThisString(ctx); int pos = 0; - if (ctx->argumentCount() > 0) + if (ctx->argumentCount > 0) pos = (int) ctx->argument(0).toInteger(ctx); double result = qSNaN(); @@ -943,7 +943,7 @@ Value StringPrototype::method_concat(ExecutionContext *ctx) { QString value = getThisString(ctx); - for (unsigned i = 0; i < ctx->argumentCount(); ++i) { + for (unsigned i = 0; i < ctx->argumentCount; ++i) { Value v = __qmljs_to_string(ctx->argument(i), ctx); assert(v.isString()); value += v.stringValue()->toQString(); @@ -957,11 +957,11 @@ Value StringPrototype::method_indexOf(ExecutionContext *ctx) QString value = getThisString(ctx); QString searchString; - if (ctx->argumentCount()) + if (ctx->argumentCount) searchString = ctx->argument(0).toString(ctx)->toQString(); int pos = 0; - if (ctx->argumentCount() > 1) + if (ctx->argumentCount > 1) pos = (int) ctx->argument(1).toInteger(ctx); int index = -1; @@ -976,7 +976,7 @@ Value StringPrototype::method_lastIndexOf(ExecutionContext *ctx) const QString value = getThisString(ctx); QString searchString; - if (ctx->argumentCount()) { + if (ctx->argumentCount) { Value v = __qmljs_to_string(ctx->argument(0), ctx); searchString = v.stringValue()->toQString(); } @@ -1057,11 +1057,11 @@ Value StringPrototype::method_substr(ExecutionContext *ctx) const QString value = getThisString(ctx); double start = 0; - if (ctx->argumentCount() > 0) + if (ctx->argumentCount > 0) start = ctx->argument(0).toInteger(ctx); double length = +qInf(); - if (ctx->argumentCount() > 1) + if (ctx->argumentCount > 1) length = ctx->argument(1).toInteger(ctx); double count = value.length(); @@ -1083,10 +1083,10 @@ Value StringPrototype::method_substring(ExecutionContext *ctx) double start = 0; double end = length; - if (ctx->argumentCount() > 0) + if (ctx->argumentCount > 0) start = ctx->argument(0).toInteger(ctx); - if (ctx->argumentCount() > 1) + if (ctx->argumentCount > 1) end = ctx->argument(1).toInteger(ctx); if (std::isnan(start) || start < 0) @@ -1137,7 +1137,7 @@ Value StringPrototype::method_toLocaleUpperCase(ExecutionContext *ctx) Value StringPrototype::method_fromCharCode(ExecutionContext *ctx) { QString str; - for (unsigned i = 0; i < ctx->argumentCount(); ++i) { + for (unsigned i = 0; i < ctx->argumentCount; ++i) { QChar c(ctx->argument(i).toUInt16(ctx)); str += c; } @@ -1161,7 +1161,7 @@ Value NumberCtor::construct(ExecutionContext *ctx) Value NumberCtor::call(ExecutionContext *ctx) { - double value = ctx->argumentCount() ? ctx->argument(0).toNumber(ctx) : 0; + double value = ctx->argumentCount ? ctx->argument(0).toNumber(ctx) : 0; return Value::fromDouble(value); } @@ -1275,7 +1275,7 @@ Value NumberPrototype::method_toFixed(ExecutionContext *ctx) double fdigits = 0; - if (ctx->argumentCount() > 0) + if (ctx->argumentCount > 0) fdigits = ctx->argument(0).toInteger(ctx); if (std::isnan(fdigits)) @@ -1300,7 +1300,7 @@ Value NumberPrototype::method_toExponential(ExecutionContext *ctx) double fdigits = 0; - if (ctx->argumentCount() > 0) + if (ctx->argumentCount > 0) fdigits = ctx->argument(0).toInteger(ctx); QString z = QString::number(thisObject->value.asDouble(), 'e', int (fdigits)); @@ -1315,7 +1315,7 @@ Value NumberPrototype::method_toPrecision(ExecutionContext *ctx) double fdigits = 0; - if (ctx->argumentCount() > 0) + if (ctx->argumentCount > 0) fdigits = ctx->argument(0).toInteger(ctx); return Value::fromString(ctx, QString::number(thisObject->value.asDouble(), 'g', int (fdigits))); @@ -1338,7 +1338,7 @@ Value BooleanCtor::construct(ExecutionContext *ctx) Value BooleanCtor::call(ExecutionContext *ctx) { - bool value = ctx->argumentCount() ? ctx->argument(0).toBoolean(ctx) : 0; + bool value = ctx->argumentCount ? ctx->argument(0).toBoolean(ctx) : 0; return Value::fromBoolean(value); } @@ -1386,7 +1386,7 @@ Value ArrayCtor::construct(ExecutionContext *ctx) Value ArrayCtor::call(ExecutionContext *ctx) { Array value; - if (ctx->argumentCount() == 1 && ctx->argument(0).isNumber()) { + if (ctx->argumentCount == 1 && ctx->argument(0).isNumber()) { double size = ctx->argument(0).asDouble(); quint32 isize = Value::toUInt32(size); @@ -1397,7 +1397,7 @@ Value ArrayCtor::call(ExecutionContext *ctx) value.resize(isize); } else { - for (unsigned int i = 0; i < ctx->argumentCount(); ++i) { + for (unsigned int i = 0; i < ctx->argumentCount; ++i) { value.assign(i, ctx->argument(i)); } } @@ -1453,7 +1453,7 @@ Value ArrayPrototype::method_concat(ExecutionContext *ctx) result.assign(0, Value::fromString(ctx, v)); } - for (uint i = 0; i < ctx->argumentCount(); ++i) { + for (uint i = 0; i < ctx->argumentCount; ++i) { quint32 k = result.size(); Value arg = ctx->argument(i); @@ -1548,7 +1548,7 @@ Value ArrayPrototype::method_push(ExecutionContext *ctx) Value self = ctx->thisObject; if (ArrayObject *instance = self.asArrayObject()) { uint pos = instance->value.size(); - for (unsigned int i = 0; i < ctx->argumentCount(); ++i) { + for (unsigned int i = 0; i < ctx->argumentCount; ++i) { Value val = ctx->argument(i); instance->value.assign(pos++, val); } @@ -1557,7 +1557,7 @@ Value ArrayPrototype::method_push(ExecutionContext *ctx) Value r1 = self.property(ctx, ctx->engine->id_length); quint32 n = !r1.isUndefined() ? r1.toUInt32(ctx) : 0; - for (unsigned int index = 0; index < ctx->argumentCount(); ++index, ++n) { + for (unsigned int index = 0; index < ctx->argumentCount; ++index, ++n) { Value r3 = ctx->argument(index); String *name = Value::fromDouble(n).toString(ctx); self.objectValue()->__put__(ctx, name, r3); @@ -1631,7 +1631,7 @@ Value ArrayPrototype::method_sort(ExecutionContext *ctx) Value ArrayPrototype::method_splice(ExecutionContext *ctx) { - if (ctx->argumentCount() < 2) + if (ctx->argumentCount < 2) // ### check return Value::undefinedValue(); @@ -1643,7 +1643,7 @@ Value ArrayPrototype::method_splice(ExecutionContext *ctx) double deleteCount = ctx->argument(1).toInteger(ctx); Value a = Value::fromObject(ctx->engine->newArrayObject()); QVector items; - for (unsigned int i = 2; i < ctx->argumentCount(); ++i) + for (unsigned int i = 2; i < ctx->argumentCount; ++i) items << ctx->argument(i); ArrayObject *otherInstance = a.asArrayObject(); assert(otherInstance); @@ -1862,10 +1862,10 @@ Value FunctionCtor::construct(ExecutionContext *ctx) { QString args; QString body; - if (ctx->argumentCount() > 0) - body = ctx->argument(ctx->argumentCount() - 1).toString(ctx)->toQString(); + if (ctx->argumentCount > 0) + body = ctx->argument(ctx->argumentCount - 1).toString(ctx)->toQString(); - for (uint i = 0; i < ctx->argumentCount() - 1; ++i) { + for (uint i = 0; i < ctx->argumentCount - 1; ++i) { if (i) args += QLatin1String(", "); args += ctx->argument(i).toString(ctx)->toQString(); @@ -1958,10 +1958,10 @@ Value FunctionPrototype::method_apply(ExecutionContext *ctx) Value FunctionPrototype::method_call(ExecutionContext *ctx) { Value thisArg = ctx->argument(0); - QVector args(ctx->argumentCount() ? ctx->argumentCount() - 1 : 0); - if (ctx->argumentCount()) - qCopy(ctx->lexicalEnvironment->arguments + 1, - ctx->lexicalEnvironment->arguments + ctx->argumentCount(), args.begin()); + QVector args(ctx->argumentCount ? ctx->argumentCount - 1 : 0); + if (ctx->argumentCount) + qCopy(ctx->arguments + 1, + ctx->arguments + ctx->argumentCount, args.begin()); return __qmljs_call_value(ctx, thisArg, ctx->thisObject, args.data(), args.size()); } @@ -1987,10 +1987,10 @@ Value DateCtor::construct(ExecutionContext *ctx) { double t = 0; - if (ctx->argumentCount() == 0) + if (ctx->argumentCount == 0) t = currentTime(); - else if (ctx->argumentCount() == 1) { + else if (ctx->argumentCount == 1) { Value arg = ctx->argument(0); if (DateObject *d = arg.asDateObject()) arg = d->value; @@ -2003,14 +2003,14 @@ Value DateCtor::construct(ExecutionContext *ctx) t = TimeClip(arg.toNumber(ctx)); } - else { // ctx->argumentCount()() > 1 + else { // ctx->argumentCount > 1 double year = ctx->argument(0).toNumber(ctx); double month = ctx->argument(1).toNumber(ctx); - double day = ctx->argumentCount() >= 3 ? ctx->argument(2).toNumber(ctx) : 1; - double hours = ctx->argumentCount() >= 4 ? ctx->argument(3).toNumber(ctx) : 0; - double mins = ctx->argumentCount() >= 5 ? ctx->argument(4).toNumber(ctx) : 0; - double secs = ctx->argumentCount() >= 6 ? ctx->argument(5).toNumber(ctx) : 0; - double ms = ctx->argumentCount() >= 7 ? ctx->argument(6).toNumber(ctx) : 0; + double day = ctx->argumentCount >= 3 ? ctx->argument(2).toNumber(ctx) : 1; + double hours = ctx->argumentCount >= 4 ? ctx->argument(3).toNumber(ctx) : 0; + double mins = ctx->argumentCount >= 5 ? ctx->argument(4).toNumber(ctx) : 0; + double secs = ctx->argumentCount >= 6 ? ctx->argument(5).toNumber(ctx) : 0; + double ms = ctx->argumentCount >= 7 ? ctx->argument(6).toNumber(ctx) : 0; if (year >= 0 && year <= 99) year += 1900; t = MakeDate(MakeDay(year, month, day), MakeTime(hours, mins, secs, ms)); @@ -2118,7 +2118,7 @@ Value DatePrototype::method_parse(ExecutionContext *ctx) Value DatePrototype::method_UTC(ExecutionContext *ctx) { - const int numArgs = ctx->argumentCount(); + const int numArgs = ctx->argumentCount; if (numArgs >= 2) { double year = ctx->argument(0).toNumber(ctx); double month = ctx->argument(1).toNumber(ctx); @@ -2370,7 +2370,7 @@ Value DatePrototype::method_setSeconds(ExecutionContext *ctx) double t = LocalTime(self->value.asDouble()); double sec = ctx->argument(0).toNumber(ctx); - double ms = (ctx->argumentCount() < 2) ? msFromTime(t) : ctx->argument(1).toNumber(ctx); + double ms = (ctx->argumentCount < 2) ? msFromTime(t) : ctx->argument(1).toNumber(ctx); t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms)))); self->value.setDouble(t); return self->value; @@ -2384,7 +2384,7 @@ Value DatePrototype::method_setUTCSeconds(ExecutionContext *ctx) double t = self->value.asDouble(); double sec = ctx->argument(0).toNumber(ctx); - double ms = (ctx->argumentCount() < 2) ? msFromTime(t) : ctx->argument(1).toNumber(ctx); + double ms = (ctx->argumentCount < 2) ? msFromTime(t) : ctx->argument(1).toNumber(ctx); t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms)))); self->value.setDouble(t); return self->value; @@ -2398,8 +2398,8 @@ Value DatePrototype::method_setMinutes(ExecutionContext *ctx) double t = LocalTime(self->value.asDouble()); double min = ctx->argument(0).toNumber(ctx); - double sec = (ctx->argumentCount() < 2) ? SecFromTime(t) : ctx->argument(1).toNumber(ctx); - double ms = (ctx->argumentCount() < 3) ? msFromTime(t) : ctx->argument(2).toNumber(ctx); + double sec = (ctx->argumentCount < 2) ? SecFromTime(t) : ctx->argument(1).toNumber(ctx); + double ms = (ctx->argumentCount < 3) ? msFromTime(t) : ctx->argument(2).toNumber(ctx); t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms)))); self->value.setDouble(t); return self->value; @@ -2413,8 +2413,8 @@ Value DatePrototype::method_setUTCMinutes(ExecutionContext *ctx) double t = self->value.asDouble(); double min = ctx->argument(0).toNumber(ctx); - double sec = (ctx->argumentCount() < 2) ? SecFromTime(t) : ctx->argument(1).toNumber(ctx); - double ms = (ctx->argumentCount() < 3) ? msFromTime(t) : ctx->argument(2).toNumber(ctx); + double sec = (ctx->argumentCount < 2) ? SecFromTime(t) : ctx->argument(1).toNumber(ctx); + double ms = (ctx->argumentCount < 3) ? msFromTime(t) : ctx->argument(2).toNumber(ctx); t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms)))); self->value.setDouble(t); return self->value; @@ -2428,9 +2428,9 @@ Value DatePrototype::method_setHours(ExecutionContext *ctx) double t = LocalTime(self->value.asDouble()); double hour = ctx->argument(0).toNumber(ctx); - double min = (ctx->argumentCount() < 2) ? MinFromTime(t) : ctx->argument(1).toNumber(ctx); - double sec = (ctx->argumentCount() < 3) ? SecFromTime(t) : ctx->argument(2).toNumber(ctx); - double ms = (ctx->argumentCount() < 4) ? msFromTime(t) : ctx->argument(3).toNumber(ctx); + double min = (ctx->argumentCount < 2) ? MinFromTime(t) : ctx->argument(1).toNumber(ctx); + double sec = (ctx->argumentCount < 3) ? SecFromTime(t) : ctx->argument(2).toNumber(ctx); + double ms = (ctx->argumentCount < 4) ? msFromTime(t) : ctx->argument(3).toNumber(ctx); t = TimeClip(UTC(MakeDate(Day(t), MakeTime(hour, min, sec, ms)))); self->value.setDouble(t); return self->value; @@ -2444,9 +2444,9 @@ Value DatePrototype::method_setUTCHours(ExecutionContext *ctx) double t = self->value.asDouble(); double hour = ctx->argument(0).toNumber(ctx); - double min = (ctx->argumentCount() < 2) ? MinFromTime(t) : ctx->argument(1).toNumber(ctx); - double sec = (ctx->argumentCount() < 3) ? SecFromTime(t) : ctx->argument(2).toNumber(ctx); - double ms = (ctx->argumentCount() < 4) ? msFromTime(t) : ctx->argument(3).toNumber(ctx); + double min = (ctx->argumentCount < 2) ? MinFromTime(t) : ctx->argument(1).toNumber(ctx); + double sec = (ctx->argumentCount < 3) ? SecFromTime(t) : ctx->argument(2).toNumber(ctx); + double ms = (ctx->argumentCount < 4) ? msFromTime(t) : ctx->argument(3).toNumber(ctx); t = TimeClip(UTC(MakeDate(Day(t), MakeTime(hour, min, sec, ms)))); self->value.setDouble(t); return self->value; @@ -2486,7 +2486,7 @@ Value DatePrototype::method_setMonth(ExecutionContext *ctx) double t = LocalTime(self->value.asDouble()); double month = ctx->argument(0).toNumber(ctx); - double date = (ctx->argumentCount() < 2) ? DateFromTime(t) : ctx->argument(1).toNumber(ctx); + double date = (ctx->argumentCount < 2) ? DateFromTime(t) : ctx->argument(1).toNumber(ctx); t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t)))); self->value.setDouble(t); return self->value; @@ -2500,7 +2500,7 @@ Value DatePrototype::method_setUTCMonth(ExecutionContext *ctx) double t = self->value.asDouble(); double month = ctx->argument(0).toNumber(ctx); - double date = (ctx->argumentCount() < 2) ? DateFromTime(t) : ctx->argument(1).toNumber(ctx); + double date = (ctx->argumentCount < 2) ? DateFromTime(t) : ctx->argument(1).toNumber(ctx); t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t)))); self->value.setDouble(t); return self->value; @@ -2540,8 +2540,8 @@ Value DatePrototype::method_setUTCFullYear(ExecutionContext *ctx) double t = self->value.asDouble(); double year = ctx->argument(0).toNumber(ctx); - double month = (ctx->argumentCount() < 2) ? MonthFromTime(t) : ctx->argument(1).toNumber(ctx); - double date = (ctx->argumentCount() < 3) ? DateFromTime(t) : ctx->argument(2).toNumber(ctx); + double month = (ctx->argumentCount < 2) ? MonthFromTime(t) : ctx->argument(1).toNumber(ctx); + double date = (ctx->argumentCount < 3) ? DateFromTime(t) : ctx->argument(2).toNumber(ctx); t = TimeClip(UTC(MakeDate(MakeDay(year, month, date), TimeWithinDay(t)))); self->value.setDouble(t); return self->value; @@ -2555,8 +2555,8 @@ Value DatePrototype::method_setFullYear(ExecutionContext *ctx) double t = LocalTime(self->value.asDouble()); double year = ctx->argument(0).toNumber(ctx); - double month = (ctx->argumentCount() < 2) ? MonthFromTime(t) : ctx->argument(1).toNumber(ctx); - double date = (ctx->argumentCount() < 3) ? DateFromTime(t) : ctx->argument(2).toNumber(ctx); + double month = (ctx->argumentCount < 2) ? MonthFromTime(t) : ctx->argument(1).toNumber(ctx); + double date = (ctx->argumentCount < 3) ? DateFromTime(t) : ctx->argument(2).toNumber(ctx); t = TimeClip(UTC(MakeDate(MakeDay(year, month, date), TimeWithinDay(t)))); self->value.setDouble(t); return self->value; @@ -2582,13 +2582,13 @@ RegExpCtor::RegExpCtor(ExecutionContext *scope) Value RegExpCtor::construct(ExecutionContext *ctx) { -// if (ctx->argumentCount() > 2) { +// if (ctx->argumentCount > 2) { // ctx->throwTypeError(); // return; // } - Value r = ctx->argumentCount() > 0 ? ctx->argument(0) : Value::undefinedValue(); - Value f = ctx->argumentCount() > 1 ? ctx->argument(1) : Value::undefinedValue(); + Value r = ctx->argumentCount > 0 ? ctx->argument(0) : Value::undefinedValue(); + Value f = ctx->argumentCount > 1 ? ctx->argument(1) : Value::undefinedValue(); if (RegExpObject *re = r.asRegExpObject()) { if (!f.isUndefined()) ctx->throwTypeError(); @@ -2629,8 +2629,8 @@ Value RegExpCtor::construct(ExecutionContext *ctx) Value RegExpCtor::call(ExecutionContext *ctx) { - if (ctx->argumentCount() > 0 && ctx->argument(0).asRegExpObject()) { - if (ctx->argumentCount() == 1 || ctx->argument(1).isUndefined()) + if (ctx->argumentCount > 0 && ctx->argument(0).asRegExpObject()) { + if (ctx->argumentCount == 1 || ctx->argument(1).isUndefined()) return ctx->argument(0); } @@ -2951,7 +2951,7 @@ Value MathObject::method_log(ExecutionContext *ctx) Value MathObject::method_max(ExecutionContext *ctx) { double mx = -qInf(); - for (unsigned i = 0; i < ctx->argumentCount(); ++i) { + for (unsigned i = 0; i < ctx->argumentCount; ++i) { double x = ctx->argument(i).toNumber(ctx); if (x > mx || std::isnan(x)) mx = x; @@ -2962,7 +2962,7 @@ Value MathObject::method_max(ExecutionContext *ctx) Value MathObject::method_min(ExecutionContext *ctx) { double mx = qInf(); - for (unsigned i = 0; i < ctx->argumentCount(); ++i) { + for (unsigned i = 0; i < ctx->argumentCount; ++i) { double x = ctx->argument(i).toNumber(ctx); if ((x == 0 && mx == x && copySign(1.0, x) == -1.0) || (x < mx) || std::isnan(x)) { diff --git a/qv4isel_masm.cpp b/qv4isel_masm.cpp index 37ad3fe..236d6aa 100644 --- a/qv4isel_masm.cpp +++ b/qv4isel_masm.cpp @@ -191,12 +191,10 @@ InstructionSelection::Pointer InstructionSelection::loadTempAddress(RegisterID r int32_t offset = 0; if (t->index < 0) { const int arg = -t->index - 1; - loadPtr(Address(ContextRegister, offsetof(ExecutionContext, lexicalEnvironment)), reg); - loadPtr(Address(reg, offsetof(DeclarativeEnvironment, arguments)), reg); + loadPtr(Address(ContextRegister, offsetof(ExecutionContext, arguments)), reg); offset = arg * sizeof(Value); } else if (t->index < _function->locals.size()) { - loadPtr(Address(ContextRegister, offsetof(ExecutionContext, lexicalEnvironment)), reg); - loadPtr(Address(reg, offsetof(DeclarativeEnvironment, locals)), reg); + loadPtr(Address(ContextRegister, offsetof(ExecutionContext, locals)), reg); offset = t->index * sizeof(Value); } else { const int arg = _function->maxNumberOfArguments + t->index - _function->locals.size(); -- 2.7.4