bool ExecutionContext::deleteProperty(String *name) { Scope scope(this); bool hasWith = false; for (ExecutionContext *ctx = this; ctx; ctx = ctx->d()->outer) { if (ctx->d()->type == Type_WithContext) { hasWith = true; WithContext *w = static_cast<WithContext *>(ctx); if (w->d()->withObject->hasProperty(name)) return w->d()->withObject->deleteProperty(name); } else if (ctx->d()->type == Type_CatchContext) { CatchContext *c = static_cast<CatchContext *>(ctx); if (c->d()->exceptionVarName->isEqualTo(name)) return false; } else if (ctx->d()->type >= Type_CallContext) { CallContext *c = static_cast<CallContext *>(ctx); FunctionObject *f = c->d()->function; if (f->needsActivation() || hasWith) { uint index = f->function()->internalClass->find(name); if (index < UINT_MAX) // ### throw in strict mode? return false; } if (c->d()->activation && c->d()->activation->hasProperty(name)) return c->d()->activation->deleteProperty(name); } else if (ctx->d()->type == Type_GlobalContext) { GlobalContext *g = static_cast<GlobalContext *>(ctx); if (g->d()->global->hasProperty(name)) return g->d()->global->deleteProperty(name); } } if (d()->strictMode) throwSyntaxError(QStringLiteral("Can't delete property %1").arg(name->toQString())); return true; }
ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Object *&base) { Scope scope(this); ScopedValue v(scope); base = (Object *)0; name->makeIdentifier(); if (name->equals(d()->engine->id_this.getPointer())) return d()->callData->thisObject.asReturnedValue(); bool hasWith = false; bool hasCatchScope = false; for (ExecutionContext *ctx = this; ctx; ctx = ctx->d()->outer) { if (ctx->d()->type == Type_WithContext) { Object *w = static_cast<WithContext *>(ctx)->d()->withObject; hasWith = true; bool hasProperty = false; v = w->get(name, &hasProperty); if (hasProperty) { base = w; return v.asReturnedValue(); } continue; } else if (ctx->d()->type == Type_CatchContext) { hasCatchScope = true; CatchContext *c = static_cast<CatchContext *>(ctx); if (c->d()->exceptionVarName->isEqualTo(name)) return c->d()->exceptionValue.asReturnedValue(); } else if (ctx->d()->type >= Type_CallContext) { QV4::CallContext *c = static_cast<CallContext *>(ctx); FunctionObject *f = c->d()->function; if (f->function() && (f->needsActivation() || hasWith || hasCatchScope)) { uint index = f->function()->internalClass->find(name); if (index < UINT_MAX) { if (index < c->d()->function->formalParameterCount()) return c->d()->callData->args[c->d()->function->formalParameterCount() - index - 1].asReturnedValue(); return c->d()->locals[index - c->d()->function->formalParameterCount()].asReturnedValue(); } } if (c->d()->activation) { bool hasProperty = false; v = c->d()->activation->get(name, &hasProperty); if (hasProperty) { if (ctx->d()->type == Type_QmlContext) base = c->d()->activation; return v.asReturnedValue(); } } if (f->function() && f->function()->isNamedExpression() && name->equals(f->function()->name())) return c->d()->function->asReturnedValue(); } else if (ctx->d()->type == Type_GlobalContext) { GlobalContext *g = static_cast<GlobalContext *>(ctx); bool hasProperty = false; v = g->d()->global->get(name, &hasProperty); if (hasProperty) return v.asReturnedValue(); } } ScopedValue n(scope, name); return throwReferenceError(n); }