c->realArgumentCount = callData->argc;
c->strictMode = function->strictMode();
- c->outer = function->scope();
+ c->outer = function->scope()->d();
c->activation = 0;
// find the right context to create the binding on
ScopedObject activation(scope, d()->engine->globalObject);
- ExecutionContext *ctx = this;
+ Scoped<ExecutionContext> ctx(scope, this);
while (ctx) {
if (ctx->d()->type >= Heap::ExecutionContext::Type_CallContext) {
- CallContext *c = static_cast<CallContext *>(ctx);
+ CallContext *c = static_cast<CallContext *>(ctx.getPointer());
if (!c->d()->activation)
c->d()->activation = d()->engine->newObject()->getPointer()->d();
activation = c->d()->activation;
Heap::WithContext::WithContext(ExecutionEngine *engine, QV4::Object *with)
: Heap::ExecutionContext(engine, Heap::ExecutionContext::Type_WithContext)
{
- callData = parent->d()->callData;
+ callData = parent->callData;
outer = parent;
- lookups = parent->d()->lookups;
- compilationUnit = parent->d()->compilationUnit;
+ lookups = parent->lookups;
+ compilationUnit = parent->compilationUnit;
withObject = with->d();
}
Heap::CatchContext::CatchContext(ExecutionEngine *engine, QV4::String *exceptionVarName, const ValueRef exceptionValue)
: Heap::ExecutionContext(engine, Heap::ExecutionContext::Type_CatchContext)
{
- strictMode = parent->d()->strictMode;
- callData = parent->d()->callData;
+ strictMode = parent->strictMode;
+ callData = parent->callData;
outer = parent;
- lookups = parent->d()->lookups;
- compilationUnit = parent->d()->compilationUnit;
+ lookups = parent->lookups;
+ compilationUnit = parent->compilationUnit;
this->exceptionVarName = exceptionVarName;
this->exceptionValue = exceptionValue;
callData->thisObject = Primitive::undefinedValue();
strictMode = true;
- outer = function->scope();
+ outer = function->scope()->d();
activation = qml->d();
{
Scope scope(this);
bool hasWith = false;
- for (ExecutionContext *ctx = this; ctx; ctx = ctx->d()->outer) {
+ Scoped<ExecutionContext> ctx(scope, this);
+ for (; ctx; ctx = ctx->d()->outer) {
if (ctx->d()->type == Heap::ExecutionContext::Type_WithContext) {
hasWith = true;
- ScopedObject withObject(scope, static_cast<WithContext *>(ctx)->d()->withObject);
+ ScopedObject withObject(scope, static_cast<WithContext *>(ctx.getPointer())->d()->withObject);
if (withObject->hasProperty(name))
return withObject->deleteProperty(name);
} else if (ctx->d()->type == Heap::ExecutionContext::Type_CatchContext) {
- CatchContext *c = static_cast<CatchContext *>(ctx);
+ CatchContext *c = static_cast<CatchContext *>(ctx.getPointer());
if (c->d()->exceptionVarName->isEqualTo(name))
return false;
} else if (ctx->d()->type >= Heap::ExecutionContext::Type_CallContext) {
- CallContext *c = static_cast<CallContext *>(ctx);
+ CallContext *c = static_cast<CallContext *>(ctx.getPointer());
ScopedFunctionObject f(scope, c->d()->function);
if (f->needsActivation() || hasWith) {
uint index = f->function()->internalClass->find(name);
if (activation && activation->hasProperty(name))
return activation->deleteProperty(name);
} else if (ctx->d()->type == Heap::ExecutionContext::Type_GlobalContext) {
- ScopedObject global(scope, static_cast<GlobalContext *>(ctx)->d()->global);
+ ScopedObject global(scope, static_cast<GlobalContext *>(ctx.getPointer())->d()->global);
if (global->hasProperty(name))
return global->deleteProperty(name);
}
void ExecutionContext::setProperty(String *name, const ValueRef value)
{
Scope scope(this);
- for (ExecutionContext *ctx = this; ctx; ctx = ctx->d()->outer) {
+ Scoped<ExecutionContext> ctx(scope, this);
+ for (; ctx; ctx = ctx->d()->outer) {
if (ctx->d()->type == Heap::ExecutionContext::Type_WithContext) {
- ScopedObject w(scope, static_cast<WithContext *>(ctx)->d()->withObject);
+ ScopedObject w(scope, static_cast<WithContext *>(ctx.getPointer())->d()->withObject);
if (w->hasProperty(name)) {
w->put(name, value);
return;
}
- } else if (ctx->d()->type == Heap::ExecutionContext::Type_CatchContext && static_cast<CatchContext *>(ctx)->d()->exceptionVarName->isEqualTo(name)) {
- static_cast<CatchContext *>(ctx)->d()->exceptionValue = *value;
+ } else if (ctx->d()->type == Heap::ExecutionContext::Type_CatchContext && static_cast<CatchContext *>(ctx.getPointer())->d()->exceptionVarName->isEqualTo(name)) {
+ static_cast<CatchContext *>(ctx.getPointer())->d()->exceptionValue = *value;
return;
} else {
ScopedObject activation(scope, (Object *)0);
if (ctx->d()->type >= Heap::ExecutionContext::Type_CallContext) {
- CallContext *c = static_cast<CallContext *>(ctx);
+ CallContext *c = static_cast<CallContext *>(ctx.getPointer());
if (c->d()->function->function) {
uint index = c->d()->function->function->internalClass->find(name);
if (index < UINT_MAX) {
}
activation = c->d()->activation;
} else if (ctx->d()->type == Heap::ExecutionContext::Type_GlobalContext) {
- activation = static_cast<GlobalContext *>(ctx)->d()->global;
+ activation = static_cast<GlobalContext *>(ctx.getPointer())->d()->global;
}
if (activation) {
bool hasWith = false;
bool hasCatchScope = false;
- for (ExecutionContext *ctx = this; ctx; ctx = ctx->d()->outer) {
+ Scoped<ExecutionContext> ctx(scope, this);
+ for (; ctx; ctx = ctx->d()->outer) {
if (ctx->d()->type == Heap::ExecutionContext::Type_WithContext) {
- ScopedObject w(scope, static_cast<WithContext *>(ctx)->d()->withObject);
+ ScopedObject w(scope, static_cast<WithContext *>(ctx.getPointer())->d()->withObject);
hasWith = true;
bool hasProperty = false;
v = w->get(name, &hasProperty);
else if (ctx->d()->type == Heap::ExecutionContext::Type_CatchContext) {
hasCatchScope = true;
- CatchContext *c = static_cast<CatchContext *>(ctx);
+ CatchContext *c = static_cast<CatchContext *>(ctx.getPointer());
if (c->d()->exceptionVarName->isEqualTo(name))
return c->d()->exceptionValue.asReturnedValue();
}
else if (ctx->d()->type >= Heap::ExecutionContext::Type_CallContext) {
- QV4::CallContext *c = static_cast<CallContext *>(ctx);
+ QV4::CallContext *c = static_cast<CallContext *>(ctx.getPointer());
ScopedFunctionObject f(scope, c->d()->function);
if (f->function() && (f->needsActivation() || hasWith || hasCatchScope)) {
uint index = f->function()->internalClass->find(name);
}
else if (ctx->d()->type == Heap::ExecutionContext::Type_GlobalContext) {
- ScopedObject global(scope, static_cast<GlobalContext *>(ctx)->d()->global);
+ ScopedObject global(scope, static_cast<GlobalContext *>(ctx.getPointer())->d()->global);
bool hasProperty = false;
v = global->get(name, &hasProperty);
if (hasProperty)
bool hasWith = false;
bool hasCatchScope = false;
- for (ExecutionContext *ctx = this; ctx; ctx = ctx->d()->outer) {
+ Scoped<ExecutionContext> ctx(scope, this);
+ for (; ctx; ctx = ctx->d()->outer) {
if (ctx->d()->type == Heap::ExecutionContext::Type_WithContext) {
- ScopedObject w(scope, static_cast<WithContext *>(ctx)->d()->withObject);
+ ScopedObject w(scope, static_cast<WithContext *>(ctx.getPointer())->d()->withObject);
hasWith = true;
bool hasProperty = false;
v = w->get(name, &hasProperty);
else if (ctx->d()->type == Heap::ExecutionContext::Type_CatchContext) {
hasCatchScope = true;
- CatchContext *c = static_cast<CatchContext *>(ctx);
+ CatchContext *c = static_cast<CatchContext *>(ctx.getPointer());
if (c->d()->exceptionVarName->isEqualTo(name))
return c->d()->exceptionValue.asReturnedValue();
}
else if (ctx->d()->type >= Heap::ExecutionContext::Type_CallContext) {
- QV4::CallContext *c = static_cast<CallContext *>(ctx);
+ QV4::CallContext *c = static_cast<CallContext *>(ctx.getPointer());
ScopedFunctionObject f(scope, c->d()->function);
if (f->function() && (f->needsActivation() || hasWith || hasCatchScope)) {
uint index = f->function()->internalClass->find(name);
}
else if (ctx->d()->type == Heap::ExecutionContext::Type_GlobalContext) {
- ScopedObject global(scope, static_cast<GlobalContext *>(ctx)->d()->global);
+ ScopedObject global(scope, static_cast<GlobalContext *>(ctx.getPointer())->d()->global);
bool hasProperty = false;
v = global->get(name, &hasProperty);
if (hasProperty)
EvalCode *next;
};
- ExecutionContext(ExecutionEngine *engine, ContextType t)
- : Base(engine->executionContextClass)
- , type(t)
- , strictMode(false)
- , engine(engine)
- , parent(engine->currentContext())
- , outer(0)
- , lookups(0)
- , compilationUnit(0)
- , currentEvalCode(0)
- , lineNumber(-1)
- {
- // ### GC
- engine->current = reinterpret_cast<QV4::ExecutionContext *>(this);
- }
+ inline ExecutionContext(ExecutionEngine *engine, ContextType t);
ContextType type;
bool strictMode;
CallData *callData;
ExecutionEngine *engine;
- // ### GC
- QV4::ExecutionContext *parent;
- QV4::ExecutionContext *outer;
+ ExecutionContext *parent;
+ ExecutionContext *outer;
Lookup *lookups;
CompiledData::CompilationUnit *compilationUnit;
EvalCode *currentEvalCode;
d()->type = t;
d()->strictMode = false;
d()->engine = engine;
- d()->parent = engine->currentContext();
+ d()->parent = engine->currentContext()->d();
d()->outer = 0;
d()->lookups = 0;
d()->compilationUnit = 0;
static void markObjects(Heap::Base *m, ExecutionEngine *e);
};
+inline
+Heap::ExecutionContext::ExecutionContext(ExecutionEngine *engine, ContextType t)
+ : Heap::Base(engine->executionContextClass)
+ , type(t)
+ , strictMode(false)
+ , engine(engine)
+ , parent(engine->currentContext()->d())
+ , outer(0)
+ , lookups(0)
+ , compilationUnit(0)
+ , currentEvalCode(0)
+ , lineNumber(-1)
+{
+ // ### GC
+ engine->current = reinterpret_cast<QV4::ExecutionContext *>(this);
+}
+
+
struct CallContext : public ExecutionContext
{
V4_MANAGED(CallContext, ExecutionContext)
inline void ExecutionEngine::pushContext(CallContext *context)
{
- context->d()->parent = current;
+ Q_ASSERT(current && current->d() && context && context->d());
+ context->d()->parent = current->d();
current = context;
current->d()->currentEvalCode = 0;
}
inline ExecutionContext *ExecutionEngine::popContext()
{
Q_ASSERT(current->d()->parent);
- current = current->d()->parent;
+ // ### GC
+ current = reinterpret_cast<ExecutionContext *>(current->d()->parent);
+ Q_ASSERT(current && current->d());
return current;
}
static inline CallContext *findContext(ExecutionContext *ctxt, int frame)
{
- while (ctxt) {
- CallContext *cCtxt = ctxt->asCallContext();
+ if (!ctxt)
+ return 0;
+
+ Scope scope(ctxt);
+ Scoped<ExecutionContext> ctx(scope, ctxt);
+ while (ctx) {
+ CallContext *cCtxt = ctx->asCallContext();
if (cCtxt && cCtxt->d()->function) {
if (frame < 1)
return cCtxt;
--frame;
}
- ctxt = ctxt->d()->parent;
+ ctx = ctx->d()->parent;
}
return 0;
static inline CallContext *findScope(ExecutionContext *ctxt, int scope)
{
- for (; scope > 0 && ctxt; --scope)
- ctxt = ctxt->d()->outer;
+ if (!ctxt)
+ return 0;
+
+ Scope s(ctxt);
+ Scoped<ExecutionContext> ctx(s, ctxt);
+ for (; scope > 0 && ctx; --scope)
+ ctx = ctx->d()->outer;
- return ctxt ? ctxt->asCallContext() : 0;
+ return ctx ? ctx->asCallContext() : 0;
}
void Debugger::collectArgumentsInContext(Collector *collector, int frameNr, int scopeNr)
bool myRun()
{
- ExecutionContext *ctxt = findContext(engine->currentContext(), frameNr);
+ Scope scope(engine);
+ Scoped<ExecutionContext> ctxt(scope, findContext(engine->currentContext(), frameNr));
while (ctxt) {
if (CallContext *cCtxt = ctxt->asCallContext())
if (cCtxt->d()->activation)
if (!ctxt)
return false;
- Scope scope(engine);
ScopedObject o(scope, ctxt->asCallContext()->d()->activation);
collector->collect(o);
return true;
return types;
CallContext *ctxt = static_cast<CallContext *>(sctxt);
- for (ExecutionContext *it = ctxt; it; it = it->d()->outer)
+ Scope scope(m_engine);
+ Scoped<ExecutionContext> it(scope, ctxt);
+ for (; it; it = it->d()->outer)
types.append(it->d()->type);
return types;
QMutexLocker locker(&m_lock);
+ Scope scope(m_engine);
if (m_stepping != NotStepping && m_currentContext == m_engine->currentContext()) {
- m_currentContext = m_engine->currentContext()->d()->parent;
+ m_currentContext = Scoped<ExecutionContext>(scope, m_engine->currentContext()->d()->parent).getPointer();
m_stepping = StepOver;
m_returnedValue = retVal;
}
Returned<Object> *ExecutionEngine::qmlContextObject() const
{
- ExecutionContext *ctx = currentContext();
+ Heap::ExecutionContext *ctx = currentContext()->d();
- if (ctx->d()->type == Heap::ExecutionContext::Type_SimpleCallContext && !ctx->d()->outer)
- ctx = ctx->d()->parent;
+ if (ctx->type == Heap::ExecutionContext::Type_SimpleCallContext && !ctx->outer)
+ ctx = ctx->parent;
- if (!ctx->d()->outer)
+ if (!ctx->outer)
return 0;
- while (ctx->d()->outer && ctx->d()->outer->d()->type != Heap::ExecutionContext::Type_GlobalContext)
- ctx = ctx->d()->outer;
+ while (ctx->outer && ctx->outer->type != Heap::ExecutionContext::Type_GlobalContext)
+ ctx = ctx->outer;
Q_ASSERT(ctx);
- if (ctx->d()->type != Heap::ExecutionContext::Type_QmlContext)
+ if (ctx->type != Heap::ExecutionContext::Type_QmlContext)
return 0;
- Scope scope(ctx);
- ScopedObject activation(scope, static_cast<CallContext *>(ctx)->d()->activation);
+ Scope scope(currentContext());
+ ScopedObject activation(scope, static_cast<Heap::CallContext *>(ctx)->activation);
+ Q_ASSERT(activation);
return activation->asReturned<Object>();
}
ScopedString name(scope);
QVector<StackFrame> stack;
- QV4::ExecutionContext *c = currentContext();
+ Scoped<ExecutionContext> c(scope, currentContext());
while (c && frameLimit) {
CallContext *callCtx = c->asCallContext();
if (callCtx && callCtx->d()->function) {
return src;
QUrl base;
- QV4::ExecutionContext *c = currentContext();
+ Scope scope(this);
+ Scoped<ExecutionContext> c(scope, currentContext());
while (c) {
CallContext *callCtx = c->asCallContext();
if (callCtx && callCtx->d()->function) {
setter->mark(this);
}
- ExecutionContext *c = currentContext();
+ Heap::ExecutionContext *c = currentContext()->d();
while (c) {
- Q_ASSERT(c->inUse());
- if (!c->markBit()) {
- c->d()->markBit = 1;
- c->markObjects(c->d(), this);
+ Q_ASSERT(c->inUse);
+ if (!c->markBit) {
+ c->markBit = 1;
+ // ### GC
+ reinterpret_cast<ExecutionContext *>(c)->markObjects(c, this);
}
- c = c->d()->parent;
+ c = c->parent;
}
id_empty->mark(this);
ctx.function = f.getPointer()->d();
ctx.compilationUnit = f->function()->compilationUnit;
ctx.lookups = ctx.compilationUnit->runtimeLookups;
- ctx.outer = f->scope();
+ ctx.outer = f->scope()->d();
ctx.locals = v4->stackPush(f->varCount());
while (callData->argc < (int)f->formalParameterCount()) {
callData->args[callData->argc] = Encode::undefined();
ctx.function = f->d();
ctx.compilationUnit = f->function()->compilationUnit;
ctx.lookups = ctx.compilationUnit->runtimeLookups;
- ctx.outer = f->scope();
+ ctx.outer = f->scope()->d();
ctx.locals = v4->stackPush(f->varCount());
while (callData->argc < (int)f->formalParameterCount()) {
callData->args[callData->argc] = Encode::undefined();
++scope.size;
#endif
}
+ Scoped(const Scope &scope, typename T::Data *t)
+ {
+ ptr = scope.engine->jsStackTop++;
+ *ptr = Value::fromHeapObject(t);
+#ifndef QT_NO_DEBUG
+ ++scope.size;
+#endif
+ }
template<typename X>
Scoped(const Scope &scope, X *t, _Cast)
{
setPointer(value_cast<T>(v));
return *this;
}
+ Scoped<T> &operator=(typename T::Data *t) {
+ *ptr = Value::fromHeapObject(t);
+ return *this;
+ }
Scoped<T> &operator=(const Value &v) {
setPointer(value_cast<T>(v));
return *this;
static ReturnedValue signalParameterGetter(QV4::CallContext *ctx, uint parameterIndex)
{
- QV4::CallContext *signalEmittingContext = ctx->d()->parent->asCallContext();
- Q_ASSERT(signalEmittingContext);
+ QV4::Scope scope(ctx);
+ QV4::Scoped<CallContext> signalEmittingContext(scope, static_cast<Heap::CallContext *>(ctx->d()->parent));
+ Q_ASSERT(signalEmittingContext && signalEmittingContext->d()->type >= QV4::Heap::ExecutionContext::Type_SimpleCallContext);
return signalEmittingContext->argument(parameterIndex);
}
// setup lookup scopes
int scopeDepth = 0;
{
- QV4::ExecutionContext *scope = context;
+ QV4::Heap::ExecutionContext *scope = context->d();
while (scope) {
++scopeDepth;
- scope = scope->d()->outer;
+ scope = scope->outer;
}
}
scopes[0] = const_cast<QV4::Value *>(context->d()->compilationUnit->data->constants());
// stack gets setup in push instruction
scopes[1] = 0;
- QV4::ExecutionContext *scope = context;
+ QV4::Heap::ExecutionContext *scope = context->d();
int i = 0;
while (scope) {
- if (scope->d()->type >= QV4::Heap::ExecutionContext::Type_SimpleCallContext) {
- QV4::CallContext *cc = static_cast<QV4::CallContext *>(scope);
- scopes[2*i + 2] = cc->d()->callData->args;
- scopes[2*i + 3] = cc->d()->locals;
+ if (scope->type >= QV4::Heap::ExecutionContext::Type_SimpleCallContext) {
+ QV4::Heap::CallContext *cc = static_cast<QV4::Heap::CallContext *>(scope);
+ scopes[2*i + 2] = cc->callData->args;
+ scopes[2*i + 3] = cc->locals;
} else {
scopes[2*i + 2] = 0;
scopes[2*i + 3] = 0;
}
++i;
- scope = scope->d()->outer;
+ scope = scope->outer;
}
}
if ((ctx->d()->callData->argc > 2) && !ctx->d()->callData->args[2].isNumber())
V4THROW_ERROR("qsTr(): third argument (n) must be a number");
+ Scope scope(ctx);
QV8Engine *v8engine = ctx->d()->engine->v8Engine;
QString context;
if (QQmlContextData *ctxt = v8engine->callingContext()) {
int lastDot = path.lastIndexOf(QLatin1Char('.'));
int length = lastDot - (lastSlash + 1);
context = (lastSlash > -1) ? path.mid(lastSlash + 1, (length > -1) ? length : -1) : QString();
- } else if (QV4::ExecutionContext *parentCtx = ctx->d()->parent) {
+ } else if (ctx->d()->parent) {
+ Scoped<ExecutionContext> parentCtx(scope, ctx->d()->parent);
// The first non-empty source URL in the call stack determines the translation context.
while (parentCtx && context.isEmpty()) {
if (QV4::CompiledData::CompilationUnit *unit = parentCtx->d()->compilationUnit) {