From 58d6fc71544343ffd9bbefcfb49eca16e0ae660a Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 5 Apr 2013 14:16:56 +0200 Subject: Move locals from ExecutionContext to CallContext Change-Id: I3f6751fc7e0450a74339f1131b10b56a2ebe6a50 Reviewed-by: Simon Hausmann --- src/v4/debugging.cpp | 5 ++-- src/v4/moth/qv4vme_moth.cpp | 12 ++++++---- src/v4/qv4context.cpp | 57 +++++++++++++++++++++++++-------------------- src/v4/qv4context.h | 12 +++++++++- src/v4/qv4isel_masm.cpp | 2 +- 5 files changed, 54 insertions(+), 34 deletions(-) diff --git a/src/v4/debugging.cpp b/src/v4/debugging.cpp index 180958ff..57607531 100644 --- a/src/v4/debugging.cpp +++ b/src/v4/debugging.cpp @@ -72,8 +72,9 @@ VM::Value *FunctionState::argument(unsigned idx) VM::Value *FunctionState::local(unsigned idx) { - if (idx < _context->variableCount()) - return _context->locals + idx; + VM::CallContext *c = _context->asCallContext(); + if (c && idx < c->variableCount()) + return c->locals + idx; return 0; } diff --git a/src/v4/moth/qv4vme_moth.cpp b/src/v4/moth/qv4vme_moth.cpp index d5cbcd8c..f4ac8f78 100644 --- a/src/v4/moth/qv4vme_moth.cpp +++ b/src/v4/moth/qv4vme_moth.cpp @@ -151,10 +151,11 @@ static inline VM::Value *getValueRef(QQmlJS::VM::ExecutionContext *context, } else if (param.isLocal()) { VMSTATS(paramIsLocal); const unsigned index = param.index; + VM::CallContext *c = static_cast(context); Q_ASSERT(index >= 0); Q_ASSERT(index < context->variableCount()); - Q_ASSERT(context->locals); - return context->locals + index; + Q_ASSERT(c->locals); + return c->locals + index; } else if (param.isTemp()) { VMSTATS(paramIsTemp); Q_ASSERT(param.index < stackSize); @@ -166,10 +167,11 @@ static inline VM::Value *getValueRef(QQmlJS::VM::ExecutionContext *context, while (scope--) c = c->outer; const unsigned index = param.index; + VM::CallContext *cc = static_cast(c); Q_ASSERT(index >= 0); - Q_ASSERT(index < c->variableCount()); - Q_ASSERT(c->locals); - return c->locals + index; + Q_ASSERT(index < cc->variableCount()); + Q_ASSERT(cc->locals); + return cc->locals + index; } else { Q_UNIMPLEMENTED(); return 0; diff --git a/src/v4/qv4context.cpp b/src/v4/qv4context.cpp index 202acc81..274b2eb6 100644 --- a/src/v4/qv4context.cpp +++ b/src/v4/qv4context.cpp @@ -99,15 +99,16 @@ bool ExecutionContext::setMutableBinding(ExecutionContext *scope, String *name, { // ### throw if scope->strict is true, and it would change an immutable binding if (type == Type_CallContext) { + CallContext *c = static_cast(this); assert(function); - for (unsigned int i = 0; i < function->varCount; ++i) - if (function->varList[i]->isEqualTo(name)) { - locals[i] = value; + for (unsigned int i = 0; i < c->function->varCount; ++i) + if (c->function->varList[i]->isEqualTo(name)) { + c->locals[i] = value; return true; } - for (int i = (int)function->formalParameterCount - 1; i >= 0; --i) - if (function->formalParameterList[i]->isEqualTo(name)) { - arguments[i] = value; + for (int i = (int)c->function->formalParameterCount - 1; i >= 0; --i) + if (c->function->formalParameterList[i]->isEqualTo(name)) { + c->arguments[i] = value; return true; } } @@ -127,12 +128,13 @@ Value ExecutionContext::getBindingValue(ExecutionContext *scope, String *name, b if (type == Type_CallContext) { assert(function); + const CallContext *c = static_cast(this); for (unsigned int i = 0; i < function->varCount; ++i) - if (function->varList[i]->isEqualTo(name)) - return locals[i]; - for (int i = (int)function->formalParameterCount - 1; i >= 0; --i) - if (function->formalParameterList[i]->isEqualTo(name)) - return arguments[i]; + if (c->function->varList[i]->isEqualTo(name)) + return c->locals[i]; + for (int i = (int)c->function->formalParameterCount - 1; i >= 0; --i) + if (c->function->formalParameterList[i]->isEqualTo(name)) + return c->arguments[i]; } if (activation) { @@ -190,7 +192,6 @@ void GlobalContext::init(ExecutionEngine *eng) argumentCount = 0; activation = 0; function = 0; - locals = 0; } void WithContext::init(ExecutionContext *p, Object *with) @@ -210,7 +211,6 @@ void WithContext::init(ExecutionContext *p, Object *with) argumentCount = 0; activation = 0; function = 0; - locals = 0; } void CatchContext::init(ExecutionContext *p, String *exceptionVarName, const Value &exceptionValue) @@ -231,7 +231,6 @@ void CatchContext::init(ExecutionContext *p, String *exceptionVarName, const Val argumentCount = 0; activation = 0; function = 0; - locals = 0; } void CallContext::initCallContext(ExecutionEngine *engine) @@ -334,8 +333,13 @@ void ExecutionContext::mark() function->mark(); for (unsigned arg = 0, lastArg = argumentCount; arg < lastArg; ++arg) arguments[arg].mark(); - for (unsigned local = 0, lastLocal = variableCount(); local < lastLocal; ++local) - locals[local].mark(); + + if (type == Type_CallContext) { + VM::CallContext *c = static_cast(this); + for (unsigned local = 0, lastLocal = c->variableCount(); local < lastLocal; ++local) + c->locals[local].mark(); + } + if (activation) activation->mark(); if (type == Type_WithContext) { @@ -401,14 +405,15 @@ Value ExecutionContext::getProperty(String *name) } if (ctx->type == Type_CallContext) { - FunctionObject *f = ctx->function; + VM::CallContext *c = static_cast(ctx); + FunctionObject *f = c->function; if (f->needsActivation || hasWith || hasCatchScope) { for (unsigned int i = 0; i < f->varCount; ++i) if (f->varList[i]->isEqualTo(name)) - return ctx->locals[i]; + return c->locals[i]; for (int i = (int)f->formalParameterCount - 1; i >= 0; --i) if (f->formalParameterList[i]->isEqualTo(name)) - return ctx->arguments[i]; + return c->arguments[i]; } } if (ctx->activation) { @@ -457,14 +462,15 @@ Value ExecutionContext::getPropertyNoThrow(String *name) } if (ctx->type == Type_CallContext) { - FunctionObject *f = ctx->function; + VM::CallContext *c = static_cast(ctx); + FunctionObject *f = c->function; if (f->needsActivation || hasWith || hasCatchScope) { for (unsigned int i = 0; i < f->varCount; ++i) if (f->varList[i]->isEqualTo(name)) - return ctx->locals[i]; + return c->locals[i]; for (int i = (int)f->formalParameterCount - 1; i >= 0; --i) if (f->formalParameterList[i]->isEqualTo(name)) - return ctx->arguments[i]; + return c->arguments[i]; } } if (ctx->activation) { @@ -514,14 +520,15 @@ Value ExecutionContext::getPropertyAndBase(String *name, Object **base) } if (ctx->type == Type_CallContext) { - FunctionObject *f = ctx->function; + VM::CallContext *c = static_cast(ctx); + FunctionObject *f = c->function; if (f->needsActivation || hasWith || hasCatchScope) { for (unsigned int i = 0; i < f->varCount; ++i) if (f->varList[i]->isEqualTo(name)) - return ctx->locals[i]; + return c->locals[i]; for (int i = (int)f->formalParameterCount - 1; i >= 0; --i) if (f->formalParameterList[i]->isEqualTo(name)) - return ctx->arguments[i]; + return c->arguments[i]; } } if (ctx->activation) { diff --git a/src/v4/qv4context.h b/src/v4/qv4context.h index b97d8be9..a1da174c 100644 --- a/src/v4/qv4context.h +++ b/src/v4/qv4context.h @@ -73,6 +73,8 @@ struct Q_V4_EXPORT DiagnosticMessage String *buildFullMessage(ExecutionContext *ctx) const; }; +struct CallContext; + struct ExecutionContext { enum Type { @@ -100,7 +102,6 @@ struct ExecutionContext unsigned int argumentCount; Object *activation; FunctionObject *function; - Value *locals; String * const *formals() const; unsigned int formalCount() const; @@ -135,11 +136,15 @@ struct ExecutionContext bool needsOwnArguments() const; void mark(); + + inline CallContext *asCallContext(); }; struct CallContext : public ExecutionContext { void initCallContext(QQmlJS::VM::ExecutionEngine *engine); + + Value *locals; }; struct GlobalContext : public ExecutionContext @@ -172,6 +177,11 @@ inline Value ExecutionContext::argument(unsigned int index) return Value::undefinedValue(); } +inline CallContext *ExecutionContext::asCallContext() +{ + return type == Type_CallContext ? static_cast(this) : 0; +} + /* Function *f, int argc */ #define requiredMemoryForExecutionContect(f, argc) \ sizeof(CallContext) + sizeof(Value) * (f->varCount + qMax((uint)argc, f->formalParameterCount)) diff --git a/src/v4/qv4isel_masm.cpp b/src/v4/qv4isel_masm.cpp index 30f5b3f6..2cb10315 100644 --- a/src/v4/qv4isel_masm.cpp +++ b/src/v4/qv4isel_masm.cpp @@ -160,7 +160,7 @@ Assembler::Pointer Assembler::loadTempAddress(RegisterID reg, V4IR::Temp *t) loadPtr(Address(context, offsetof(ExecutionContext, arguments)), reg); offset = arg * sizeof(Value); } else if (t->index < f->locals.size()) { - loadPtr(Address(context, offsetof(ExecutionContext, locals)), reg); + loadPtr(Address(context, offsetof(CallContext, locals)), reg); offset = t->index * sizeof(Value); } else { assert(t->scope == 0); -- cgit v1.2.3