ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
: memoryManager(new QQmlJS::VM::MemoryManager)
, executableAllocator(new QQmlJS::VM::ExecutableAllocator)
- , contextStack(0)
- , contextStackPosition(0)
- , contextStackSize(0)
, debugger(0)
, globalObject(Value::nullValue())
, globalCode(0)
{
delete regExpCache;
delete globalObject.asObject();
- delete [] contextStack;
UnwindHelper::deregisterFunctions(functions);
qDeleteAll(functions);
delete memoryManager;
void ExecutionEngine::initRootContext()
{
- ensureContextStackSize();
rootContext = static_cast<GlobalContext *>(memoryManager->allocContext(sizeof(GlobalContext)));
current = rootContext;
- contextStack[0] = rootContext;
+ current->parent = 0;
rootContext->init(this);
}
-void ExecutionEngine::ensureContextStackSize()
-{
- if (contextStackPosition < contextStackSize - 1)
- return;
-
- const int stackSize = qMax(32, 2*contextStackSize);
- ExecutionContext **newStack = new ExecutionContext *[stackSize];
- if (contextStack)
- memcpy(newStack, contextStack, contextStackSize*sizeof(ExecutionContext *));
- memset(newStack + contextStackSize, 0, (stackSize - contextStackSize)*sizeof(ExecutionContext *));
- delete [] contextStack;
- contextStackSize = stackSize;
- contextStack = newStack;
-}
-
WithContext *ExecutionEngine::newWithContext(Object *with)
{
- ensureContextStackSize();
- assert(contextStack[contextStackPosition + 1] == 0);
-
ExecutionContext *p = current;
WithContext *w = static_cast<WithContext *>(memoryManager->allocContext(sizeof(WithContext)));
+ w->parent = current;
current = w;
- contextStack[++contextStackPosition] = current;
w->init(p, with);
return w;
CatchContext *ExecutionEngine::newCatchContext(String *exceptionVarName, const Value &exceptionValue)
{
- ensureContextStackSize();
- assert(contextStack[contextStackPosition + 1] == 0);
-
ExecutionContext *p = current;
CatchContext *c = static_cast<CatchContext *>(memoryManager->allocContext(sizeof(CatchContext)));
+ c->parent = current;
current = c;
- contextStack[++contextStackPosition] = current;
c->init(p, exceptionVarName, exceptionValue);
return c;
CallContext *ExecutionEngine::newCallContext(FunctionObject *f, const Value &thisObject, Value *args, int argc)
{
- ensureContextStackSize();
- assert(contextStack[contextStackPosition + 1] == 0);
-
CallContext *c = static_cast<CallContext *>(memoryManager->allocContext(requiredMemoryForExecutionContect(f, argc)));
+ c->parent = current;
current = c;
- contextStack[++contextStackPosition] = current;
c->function = f;
c->thisObject = thisObject;
CallContext *ExecutionEngine::newCallContext(void *stackSpace, FunctionObject *f, const Value &thisObject, Value *args, int argc)
{
- ensureContextStackSize();
- assert(contextStack[contextStackPosition + 1] == 0);
-
CallContext *c;
uint memory = requiredMemoryForExecutionContect(f, argc);
if (f->needsActivation || memory > stackContextSize) {
c->next = (CallContext *)0x1;
#endif
}
+ c->parent = current;
current = c;
- contextStack[++contextStackPosition] = current;
-
c->function = f;
c->thisObject = thisObject;
c->arguments = args;
ExecutionContext *ExecutionEngine::pushGlobalContext()
{
- ensureContextStackSize();
- assert(contextStack[contextStackPosition + 1] == 0);
-
- current = rootContext;
-
- contextStack[++contextStackPosition] = current;
- return current;
-}
-
-ExecutionContext *ExecutionEngine::popContext()
-{
- assert(current == contextStack[contextStackPosition]);
+ GlobalContext *g = static_cast<GlobalContext *>(memoryManager->allocContext(sizeof(GlobalContext)));
+ *g = *rootContext;
+ g->parent = current;
+ current = g;
- if (debugger)
- debugger->justLeft(current);
-
- CallContext *c = current->asCallContext();
- if (c && !c->needsOwnArguments()) {
- c->arguments = 0;
- c->argumentCount = 0;
- }
-
- contextStack[contextStackPosition] = 0;
- current = contextStack[--contextStackPosition];
return current;
}
pd.set->mark();
}
- for (int i = 0; i <= contextStackPosition; ++i)
- contextStack[i]->mark();
+ ExecutionContext *c = current;
+ while (c) {
+ c->mark();
+ c = c->parent;
+ }
for (int i = 0; i < functions.size(); ++i)
functions.at(i)->mark();
ExecutableAllocator *executableAllocator;
QScopedPointer<EvalISelFactory> iselFactory;
- ExecutionContext **contextStack;
- int contextStackPosition;
- int contextStackSize;
-
ExecutionContext *current;
GlobalContext *rootContext;
Value run(VM::Function *function, ExecutionContext *ctx = 0);
void initRootContext();
- void ensureContextStackSize();
};
inline void ExecutionEngine::pushContext(SimpleCallContext *context)
{
- ensureContextStackSize();
- assert(contextStack[contextStackPosition + 1] == 0);
-
+ context->parent = current;
current = context;
+}
- contextStack[++contextStackPosition] = current;
+inline ExecutionContext *ExecutionEngine::popContext()
+{
+ CallContext *c = current->asCallContext();
+ if (c && !c->needsOwnArguments()) {
+ c->arguments = 0;
+ c->argumentCount = 0;
+ }
+
+ current = current->parent;
+ return current;
}
+
} // namespace VM
} // namespace QQmlJS
{
StackTrace *trace = new StackTrace;
VM::ExecutionEngine *engine = currentEngine();
- VM::ExecutionContext **root = engine->contextStack;
- VM::ExecutionContext **current = root + engine->contextStackPosition;
- while (current >= root && frame_limit) {
- if (CallContext *c = (*current)->asCallContext()) {
+ VM::ExecutionContext *current = engine->current;
+ while (current && frame_limit) {
+ if (CallContext *c = current->asCallContext()) {
StackFrame *frame = new StackFrame(Value::fromVmValue(VM::Value::fromString(engine->id_null)),
Value::fromVmValue(VM::Value::fromString(c->function->name)),
0, 0);
trace->frames.append(frame);
--frame_limit;
}
- --current;
+ current = current->parent;
}
return Local<StackTrace>::New(Handle<StackTrace>(trace));