} else if (param.isLocal()) {
VMSTATS(paramIsLocal);
const unsigned index = param.index;
+ VM::CallContext *c = static_cast<VM::CallContext *>(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);
while (scope--)
c = c->outer;
const unsigned index = param.index;
+ VM::CallContext *cc = static_cast<VM::CallContext *>(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;
{
// ### throw if scope->strict is true, and it would change an immutable binding
if (type == Type_CallContext) {
+ CallContext *c = static_cast<CallContext *>(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;
}
}
if (type == Type_CallContext) {
assert(function);
+ const CallContext *c = static_cast<const CallContext *>(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) {
argumentCount = 0;
activation = 0;
function = 0;
- locals = 0;
}
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)
argumentCount = 0;
activation = 0;
function = 0;
- locals = 0;
}
void CallContext::initCallContext(ExecutionEngine *engine)
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<CallContext *>(this);
+ for (unsigned local = 0, lastLocal = c->variableCount(); local < lastLocal; ++local)
+ c->locals[local].mark();
+ }
+
if (activation)
activation->mark();
if (type == Type_WithContext) {
}
if (ctx->type == Type_CallContext) {
- FunctionObject *f = ctx->function;
+ VM::CallContext *c = static_cast<CallContext *>(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) {
}
if (ctx->type == Type_CallContext) {
- FunctionObject *f = ctx->function;
+ VM::CallContext *c = static_cast<CallContext *>(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) {
}
if (ctx->type == Type_CallContext) {
- FunctionObject *f = ctx->function;
+ VM::CallContext *c = static_cast<CallContext *>(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) {
String *buildFullMessage(ExecutionContext *ctx) const;
};
+struct CallContext;
+
struct ExecutionContext
{
enum Type {
unsigned int argumentCount;
Object *activation;
FunctionObject *function;
- Value *locals;
String * const *formals() const;
unsigned int formalCount() const;
bool needsOwnArguments() const;
void mark();
+
+ inline CallContext *asCallContext();
};
struct CallContext : public ExecutionContext
{
void initCallContext(QQmlJS::VM::ExecutionEngine *engine);
+
+ Value *locals;
};
struct GlobalContext : public ExecutionContext
return Value::undefinedValue();
}
+inline CallContext *ExecutionContext::asCallContext()
+{
+ return type == Type_CallContext ? static_cast<CallContext *>(this) : 0;
+}
+
/* Function *f, int argc */
#define requiredMemoryForExecutionContect(f, argc) \
sizeof(CallContext) + sizeof(Value) * (f->varCount + qMax((uint)argc, f->formalParameterCount))