diff options
author | Lars Knoll <lars.knoll@digia.com> | 2012-11-24 22:07:02 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2012-11-25 10:20:25 +0100 |
commit | 87b31798170233b92f13ba4d39e0278fdf61e10e (patch) | |
tree | 8d2a106262de90fad6556985bb519f817641ccbd /qmljs_environment.cpp | |
parent | 2bd3fa3fc27379a78e8cca0e66eda800729ed8c9 (diff) |
Support for the with statement
Add the with object (list) to the environment, and check properties
there if it's available.
Generate IR statements implementing with() support.
Add two new builtin methods to enter and leave a with scope.
Implement support for the builtin's in masm.
Make sure exception handling works across with scopes.
Change-Id: I8257a16cfccc91a1acedfd740ade711b016b33fd
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'qmljs_environment.cpp')
-rw-r--r-- | qmljs_environment.cpp | 68 |
1 files changed, 52 insertions, 16 deletions
diff --git a/qmljs_environment.cpp b/qmljs_environment.cpp index 121670c999..5504763b31 100644 --- a/qmljs_environment.cpp +++ b/qmljs_environment.cpp @@ -52,11 +52,12 @@ DeclarativeEnvironment::DeclarativeEnvironment(ExecutionEngine *e) arguments = 0; argumentCount = 0; locals = 0; - activation = 0; formals = 0; formalCount = 0; vars = 0; varCount = 0; + activation = 0; + withObject = 0; } DeclarativeEnvironment::DeclarativeEnvironment(FunctionObject *f, Value *args, uint argc) @@ -64,11 +65,6 @@ DeclarativeEnvironment::DeclarativeEnvironment(FunctionObject *f, Value *args, u outer = f->scope; engine = outer->engine; - if (f->needsActivation) - activation = engine->newActivationObject(this); - else - activation = 0; - formals = f->formalParameterList; formalCount = f->formalParameterCount; arguments = args; @@ -85,6 +81,13 @@ DeclarativeEnvironment::DeclarativeEnvironment(FunctionObject *f, Value *args, u locals = varCount ? new Value[varCount] : 0; if (varCount) std::fill(locals, locals + varCount, Value::undefinedValue()); + + if (f->needsActivation) + activation = engine->newActivationObject(this); + else + activation = 0; + + withObject = 0; } bool DeclarativeEnvironment::hasBinding(String *name) const @@ -97,7 +100,9 @@ bool DeclarativeEnvironment::hasBinding(String *name) const if (__qmljs_string_equal(formals[i], name)) return true; } - return deletableLocals.contains(name->toQString()); + if (!deletableLocals) + return false; + return deletableLocals->contains(name->toQString()); } void DeclarativeEnvironment::createMutableBinding(String *name, bool deletable) @@ -106,7 +111,9 @@ void DeclarativeEnvironment::createMutableBinding(String *name, bool deletable) assert(deletable); assert(!hasBinding(name)); - deletableLocals.insert(name->toQString(), Value::undefinedValue()); + if (!deletableLocals) + deletableLocals = new QHash<QString, Value>(); + deletableLocals->insert(name->toQString(), Value::undefinedValue()); } void DeclarativeEnvironment::setMutableBinding(String *name, Value value, bool strict) @@ -126,8 +133,9 @@ void DeclarativeEnvironment::setMutableBinding(String *name, Value value, bool s return; } } - QHash<QString, Value>::iterator it = deletableLocals.find(name->toQString()); - if (it != deletableLocals.end()) { + assert(deletableLocals); + QHash<QString, Value>::iterator it = deletableLocals->find(name->toQString()); + if (it != deletableLocals->end()) { *it = value; return; } @@ -146,8 +154,9 @@ Value DeclarativeEnvironment::getBindingValue(String *name, bool strict) const if (__qmljs_string_equal(formals[i], name)) return arguments[i]; } - QHash<QString, Value>::const_iterator it = deletableLocals.find(name->toQString()); - if (it != deletableLocals.end()) + assert(deletableLocals); + QHash<QString, Value>::const_iterator it = deletableLocals->find(name->toQString()); + if (it != deletableLocals->end()) return *it; assert(false); @@ -155,14 +164,33 @@ Value DeclarativeEnvironment::getBindingValue(String *name, bool strict) const bool DeclarativeEnvironment::deleteBinding(String *name) { - QHash<QString, Value>::iterator it = deletableLocals.find(name->toQString()); - if (it != deletableLocals.end()) { - deletableLocals.erase(it); - return true; + if (deletableLocals) { + QHash<QString, Value>::iterator it = deletableLocals->find(name->toQString()); + if (it != deletableLocals->end()) { + deletableLocals->erase(it); + return true; + } } return !hasBinding(name); } +void DeclarativeEnvironment::pushWithObject(Object *with) +{ + With *w = new With; + w->next = withObject; + w->object = with; + withObject = w; +} + +void DeclarativeEnvironment::popWithObject() +{ + assert(withObject); + + With *w = withObject; + withObject = w->next; + delete w; +} + void ExecutionContext::init(ExecutionEngine *eng) { @@ -177,6 +205,14 @@ void ExecutionContext::init(ExecutionEngine *eng) PropertyDescriptor *ExecutionContext::lookupPropertyDescriptor(String *name, PropertyDescriptor *tmp) { for (DeclarativeEnvironment *ctx = lexicalEnvironment; ctx; ctx = ctx->outer) { + if (ctx->withObject) { + DeclarativeEnvironment::With *w = ctx->withObject; + while (w) { + if (PropertyDescriptor *pd = w->object->__getPropertyDescriptor__(this, name, tmp)) + return pd; + w = w->next; + } + } if (ctx->activation) { if (PropertyDescriptor *pd = ctx->activation->__getPropertyDescriptor__(this, name, tmp)) return pd; |