Example #1
0
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);
}
Example #2
0
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);
}
Example #3
0
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);
}