void ExecutionContext::setProperty(const StringRef name, const ValueRef value) { Scope scope(this); for (ExecutionContext *ctx = this; ctx; ctx = ctx->outer) { if (ctx->type == Type_WithContext) { ScopedObject w(scope, static_cast<WithContext *>(ctx)->withObject); if (w->__hasProperty__(name)) { w->put(name, value); return; } } else if (ctx->type == Type_CatchContext && static_cast<CatchContext *>(ctx)->exceptionVarName->isEqualTo(name)) { static_cast<CatchContext *>(ctx)->exceptionValue = *value; return; } else { ScopedObject activation(scope, (Object *)0); if (ctx->type >= Type_CallContext) { CallContext *c = static_cast<CallContext *>(ctx); if (c->function->function) { uint index = c->function->function->internalClass->find(name); if (index < UINT_MAX) { if (index < c->function->formalParameterCount) { c->callData->args[c->function->formalParameterCount - index - 1] = *value; } else { index -= c->function->formalParameterCount; c->locals[index] = *value; } return; } } activation = c->activation; } else if (ctx->type == Type_GlobalContext) { activation = static_cast<GlobalContext *>(ctx)->global; } if (activation) { if (ctx->type == Type_QmlContext) { activation->put(name, value); return; } else { PropertyAttributes attrs; Property *p = activation->__getOwnProperty__(name, &attrs); if (p) { activation->putValue(p, attrs, value); return; } } } } } if (strictMode || name->equals(engine->id_this)) { ScopedValue n(scope, name.asReturnedValue()); throwReferenceError(n); return; } engine->globalObject->put(name, value); }
void FunctionObject::init(const StringRef n, bool createProto) { name = n; Scope s(internalClass->engine); ScopedValue protectThis(s, this); type = Type_FunctionObject; needsActivation = true; strictMode = false; if (createProto) { Scoped<Object> proto(s, scope->engine->newObject(scope->engine->protoClass)); proto->memberData[Index_ProtoConstructor].value = this->asReturnedValue(); memberData[Index_Prototype].value = proto.asReturnedValue(); } ScopedValue v(s, n.asReturnedValue()); defineReadonlyProperty(scope->engine->id_name, v); }
ReturnedValue ExecutionContext::getPropertyAndBase(const StringRef name, ObjectRef base) { Scope scope(this); ScopedValue v(scope); base = (Object *)0; name->makeIdentifier(); if (name->equals(engine->id_this)) return callData->thisObject.asReturnedValue(); bool hasWith = false; bool hasCatchScope = false; for (ExecutionContext *ctx = this; ctx; ctx = ctx->outer) { if (ctx->type == Type_WithContext) { Object *w = static_cast<WithContext *>(ctx)->withObject; hasWith = true; bool hasProperty = false; v = w->get(name, &hasProperty); if (hasProperty) { base = w; return v.asReturnedValue(); } continue; } else if (ctx->type == Type_CatchContext) { hasCatchScope = true; CatchContext *c = static_cast<CatchContext *>(ctx); if (c->exceptionVarName->isEqualTo(name)) return c->exceptionValue.asReturnedValue(); } else if (ctx->type >= Type_CallContext) { QV4::CallContext *c = static_cast<CallContext *>(ctx); FunctionObject *f = c->function; if (f->function && (f->needsActivation || hasWith || hasCatchScope)) { uint index = f->function->internalClass->find(name); if (index < UINT_MAX) { if (index < c->function->formalParameterCount) return c->callData->args[c->function->formalParameterCount - index - 1].asReturnedValue(); return c->locals[index - c->function->formalParameterCount].asReturnedValue(); } } if (c->activation) { bool hasProperty = false; v = c->activation->get(name, &hasProperty); if (hasProperty) { if (ctx->type == Type_QmlContext) base = c->activation; return v.asReturnedValue(); } } if (f->function && f->function->isNamedExpression() && name->equals(f->function->name)) return c->function->asReturnedValue(); } else if (ctx->type == Type_GlobalContext) { GlobalContext *g = static_cast<GlobalContext *>(ctx); bool hasProperty = false; v = g->global->get(name, &hasProperty); if (hasProperty) return v.asReturnedValue(); } } ScopedValue n(scope, name.asReturnedValue()); return throwReferenceError(n); }