52
52
using namespace QV4;
54
const ManagedVTable ExecutionContext::static_vtbl =
60
0 /*collectDeletables*/,
54
76
CallContext *ExecutionContext::newCallContext(FunctionObject *function, CallData *callData)
56
CallContext *c = static_cast<CallContext *>(engine->memoryManager->allocContext(requiredMemoryForExecutionContect(function, callData->argc)));
60
c->initBaseContext(Type_CallContext, engine, this);
78
CallContext *c = static_cast<CallContext *>(engine->memoryManager->allocManaged(requiredMemoryForExecutionContect(function, callData->argc)));
79
new (c) CallContext(engine, Type_CallContext);
62
81
c->function = function;
63
82
c->realArgumentCount = callData->argc;
65
84
c->strictMode = function->strictMode;
67
85
c->outer = function->scope;
69
assert(c->outer->next != (ExecutionContext *)0x1);
93
108
WithContext *ExecutionContext::newWithContext(ObjectRef with)
95
WithContext *w = static_cast<WithContext *>(engine->memoryManager->allocContext(sizeof(WithContext)));
97
w->initWithContext(this, with);
110
WithContext *w = new (engine->memoryManager) WithContext(engine, with);
101
114
CatchContext *ExecutionContext::newCatchContext(const StringRef exceptionVarName, const ValueRef exceptionValue)
103
CatchContext *c = static_cast<CatchContext *>(engine->memoryManager->allocContext(sizeof(CatchContext)));
105
c->initCatchContext(this, exceptionVarName, exceptionValue);
116
CatchContext *c = new (engine->memoryManager) CatchContext(engine, exceptionVarName, exceptionValue);
109
120
CallContext *ExecutionContext::newQmlContext(FunctionObject *f, ObjectRef qml)
111
CallContext *c = static_cast<CallContext *>(engine->memoryManager->allocContext(requiredMemoryForExecutionContect(f, 0)));
114
c->initQmlContext(this, qml, f);
122
CallContext *c = static_cast<CallContext *>(engine->memoryManager->allocManaged(requiredMemoryForExecutionContect(f, 0)));
123
new (c) CallContext(engine, qml, f);
180
void GlobalContext::initGlobalContext(ExecutionEngine *eng)
188
GlobalContext::GlobalContext(ExecutionEngine *eng)
189
: ExecutionContext(eng, Type_GlobalContext)
182
initBaseContext(Type_GlobalContext, eng, /*parentContext*/0);
183
callData = reinterpret_cast<CallData *>(this + 1);
184
callData->tag = QV4::Value::_Integer_Type;
186
callData->thisObject = eng->globalObject;
191
global = eng->globalObject;
190
void WithContext::initWithContext(ExecutionContext *p, ObjectRef with)
194
WithContext::WithContext(ExecutionEngine *engine, ObjectRef with)
195
: ExecutionContext(engine, Type_WithContext)
192
initBaseContext(Type_WithContext, p->engine, p);
193
callData = p->callData;
195
lookups = p->lookups;
196
compilationUnit = p->compilationUnit;
197
callData = parent->callData;
199
lookups = parent->lookups;
200
compilationUnit = parent->compilationUnit;
198
202
withObject = with.getPointer();
201
void CatchContext::initCatchContext(ExecutionContext *p, const StringRef exceptionVarName, const ValueRef exceptionValue)
205
CatchContext::CatchContext(ExecutionEngine *engine, const StringRef exceptionVarName, const ValueRef exceptionValue)
206
: ExecutionContext(engine, Type_CatchContext)
203
initBaseContext(Type_CatchContext, p->engine, p);
204
strictMode = p->strictMode;
205
callData = p->callData;
207
lookups = p->lookups;
208
compilationUnit = p->compilationUnit;
208
strictMode = parent->strictMode;
209
callData = parent->callData;
211
lookups = parent->lookups;
212
compilationUnit = parent->compilationUnit;
210
214
this->exceptionVarName = exceptionVarName;
211
215
this->exceptionValue = exceptionValue;
214
void CallContext::initQmlContext(ExecutionContext *parentContext, ObjectRef qml, FunctionObject *function)
218
CallContext::CallContext(ExecutionEngine *engine, ObjectRef qml, FunctionObject *function)
219
: ExecutionContext(engine, Type_QmlContext)
216
initBaseContext(Type_QmlContext, parentContext->engine, parentContext);
218
221
this->function = function;
219
this->callData = reinterpret_cast<CallData *>(this + 1);
220
this->callData->tag = QV4::Value::_Integer_Type;
221
this->callData->argc = 0;
222
this->callData->thisObject = Primitive::undefinedValue();
222
callData = reinterpret_cast<CallData *>(this + 1);
223
callData->tag = QV4::Value::_Integer_Type;
225
callData->thisObject = Primitive::undefinedValue();
224
227
strictMode = true;
226
this->outer = function->scope;
228
assert(outer->next != (ExecutionContext *)0x1);
228
outer = function->scope;
231
230
activation = qml.getPointer();
259
258
CallContext *c = static_cast<CallContext *>(ctx);
260
259
FunctionObject *f = c->function;
261
260
if (f->needsActivation || hasWith) {
262
for (unsigned int i = 0; i < f->varCount; ++i)
263
if (f->varList[i]->isEqualTo(name))
265
for (int i = (int)f->formalParameterCount - 1; i >= 0; --i)
266
if (f->formalParameterList[i]->isEqualTo(name))
261
uint index = f->function->internalClass->find(name);
262
if (index < UINT_MAX)
263
// ### throw in strict mode?
269
266
if (c->activation && c->activation->__hasProperty__(name))
270
267
return c->activation->deleteProperty(name);
285
282
return function->needsActivation || callData->argc < static_cast<int>(function->formalParameterCount);
288
void ExecutionContext::mark()
285
void ExecutionContext::markObjects(Managed *m, ExecutionEngine *engine)
287
ExecutionContext *ctx = static_cast<ExecutionContext *>(m);
290
ctx->outer->mark(engine);
297
292
// ### shouldn't need these 3 lines
298
callData->thisObject.mark(engine);
299
for (int arg = 0; arg < callData->argc; ++arg)
300
callData->args[arg].mark(engine);
293
ctx->callData->thisObject.mark(engine);
294
for (int arg = 0; arg < ctx->callData->argc; ++arg)
295
ctx->callData->args[arg].mark(engine);
302
if (type >= Type_CallContext) {
303
QV4::CallContext *c = static_cast<CallContext *>(this);
297
if (ctx->type >= Type_CallContext) {
298
QV4::CallContext *c = static_cast<CallContext *>(ctx);
304
299
for (unsigned local = 0, lastLocal = c->variableCount(); local < lastLocal; ++local)
305
300
c->locals[local].mark(engine);
306
301
if (c->activation)
307
302
c->activation->mark(engine);
308
303
c->function->mark(engine);
309
} else if (type == Type_WithContext) {
310
WithContext *w = static_cast<WithContext *>(this);
304
} else if (ctx->type == Type_WithContext) {
305
WithContext *w = static_cast<WithContext *>(ctx);
311
306
w->withObject->mark(engine);
312
} else if (type == Type_CatchContext) {
313
CatchContext *c = static_cast<CatchContext *>(this);
307
} else if (ctx->type == Type_CatchContext) {
308
CatchContext *c = static_cast<CatchContext *>(ctx);
314
309
c->exceptionVarName->mark(engine);
315
310
c->exceptionValue.mark(engine);
316
} else if (type == Type_GlobalContext) {
317
GlobalContext *g = static_cast<GlobalContext *>(this);
311
} else if (ctx->type == Type_GlobalContext) {
312
GlobalContext *g = static_cast<GlobalContext *>(ctx);
318
313
g->global->mark(engine);
336
331
ScopedObject activation(scope, (Object *)0);
337
332
if (ctx->type >= Type_CallContext) {
338
333
CallContext *c = static_cast<CallContext *>(ctx);
339
for (unsigned int i = 0; i < c->function->varCount; ++i)
340
if (c->function->varList[i]->isEqualTo(name)) {
341
c->locals[i] = *value;
344
for (int i = (int)c->function->formalParameterCount - 1; i >= 0; --i)
345
if (c->function->formalParameterList[i]->isEqualTo(name)) {
346
c->callData->args[i] = *value;
334
if (c->function->function) {
335
uint index = c->function->function->internalClass->find(name);
336
if (index < UINT_MAX) {
337
if (index < c->function->formalParameterCount) {
338
c->callData->args[c->function->formalParameterCount - index - 1] = *value;
340
index -= c->function->formalParameterCount;
341
c->locals[index] = *value;
349
346
activation = c->activation;
350
347
} else if (ctx->type == Type_GlobalContext) {
351
348
activation = static_cast<GlobalContext *>(ctx)->global;
354
if (activation && (ctx->type == Type_QmlContext || activation->__hasProperty__(name))) {
355
activation->put(name, value);
352
if (ctx->type == Type_QmlContext) {
353
activation->put(name, value);
356
PropertyAttributes attrs;
357
Property *p = activation->__getOwnProperty__(name, &attrs);
359
activation->putValue(p, attrs, value);
398
404
else if (ctx->type >= Type_CallContext) {
399
405
QV4::CallContext *c = static_cast<CallContext *>(ctx);
400
406
ScopedFunctionObject f(scope, c->function);
401
if (f->needsActivation || hasWith || hasCatchScope) {
402
for (unsigned int i = 0; i < f->varCount; ++i)
403
if (f->varList[i]->isEqualTo(name))
404
return c->locals[i].asReturnedValue();
405
for (int i = (int)f->formalParameterCount - 1; i >= 0; --i)
406
if (f->formalParameterList[i]->isEqualTo(name))
407
return c->callData->args[i].asReturnedValue();
407
if (f->function && (f->needsActivation || hasWith || hasCatchScope)) {
408
uint index = f->function->internalClass->find(name);
409
if (index < UINT_MAX) {
410
if (index < c->function->formalParameterCount)
411
return c->callData->args[c->function->formalParameterCount - index - 1].asReturnedValue();
412
return c->locals[index - c->function->formalParameterCount].asReturnedValue();
409
415
if (c->activation) {
410
416
bool hasProperty = false;
464
470
else if (ctx->type >= Type_CallContext) {
465
471
QV4::CallContext *c = static_cast<CallContext *>(ctx);
466
472
FunctionObject *f = c->function;
467
if (f->needsActivation || hasWith || hasCatchScope) {
468
for (unsigned int i = 0; i < f->varCount; ++i)
469
if (f->varList[i]->isEqualTo(name))
470
return c->locals[i].asReturnedValue();
471
for (int i = (int)f->formalParameterCount - 1; i >= 0; --i)
472
if (f->formalParameterList[i]->isEqualTo(name))
473
return c->callData->args[i].asReturnedValue();
473
if (f->function && (f->needsActivation || hasWith || hasCatchScope)) {
474
uint index = f->function->internalClass->find(name);
475
if (index < UINT_MAX) {
476
if (index < c->function->formalParameterCount)
477
return c->callData->args[c->function->formalParameterCount - index - 1].asReturnedValue();
478
return c->locals[index - c->function->formalParameterCount].asReturnedValue();
475
481
if (c->activation) {
476
482
bool hasProperty = false;