Fix implicit this object for value based calls inside with() blocks
authorLars Knoll <lars.knoll@digia.com>
Mon, 21 Jan 2013 15:01:28 +0000 (16:01 +0100)
committerSimon Hausmann <simon.hausmann@digia.com>
Mon, 21 Jan 2013 15:07:06 +0000 (16:07 +0100)
Change-Id: Id1d18623ff84e41f2a3c08df8a13648ae49fc4ae
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
qmljs_environment.cpp
qmljs_environment.h
qmljs_runtime.cpp
tests/TestExpectations

index 9dc1761..bdfd685 100644 (file)
@@ -349,6 +349,47 @@ Value ExecutionContext::getPropertyNoThrow(String *name)
     return Value::undefinedValue();
 }
 
+Value ExecutionContext::getPropertyAndBase(String *name, Object **base)
+{
+    *base = 0;
+
+    if (name == engine->id_this)
+        return thisObject;
+
+    for (ExecutionContext *ctx = this; ctx; ctx = ctx->outer()) {
+        if (With *w = ctx->withObject) {
+            while (w) {
+                bool hasProperty = false;
+                Value v = w->object->__get__(ctx, name, &hasProperty);
+                if (hasProperty) {
+                    *base = w->object;
+                    return v;
+                }
+                w = w->next;
+            }
+        }
+
+        if (FunctionObject *f = ctx->function) {
+            if (f->needsActivation || ctx->withObject) {
+                for (unsigned int i = 0; i < f->varCount; ++i)
+                    if (f->varList[i]->isEqualTo(name))
+                        return ctx->locals[i];
+                for (int i = (int)f->formalParameterCount - 1; i >= 0; --i)
+                    if (f->formalParameterList[i]->isEqualTo(name))
+                        return ctx->arguments[i];
+            }
+        }
+        if (ctx->activation) {
+            bool hasProperty = false;
+            Value v = ctx->activation->__get__(ctx, name, &hasProperty);
+            if (hasProperty)
+                return v;
+        }
+    }
+    throwReferenceError(Value::fromString(name));
+    return Value::undefinedValue();
+}
+
 
 
 void ExecutionContext::inplaceBitOp(Value value, String *name, BinOp op)
index e4bb0b9..f043b06 100644 (file)
@@ -124,6 +124,7 @@ struct ExecutionContext
     void setProperty(String *name, Value value);
     Value getProperty(String *name);
     Value getPropertyNoThrow(String *name);
+    Value getPropertyAndBase(String *name, Object **base);
     void inplaceBitOp(Value value, String *name, BinOp op);
     bool deleteProperty(String *name);
 
index 40fc075..9ba9b89 100644 (file)
@@ -730,15 +730,17 @@ uint __qmljs_equal(Value x, Value y, ExecutionContext *ctx)
     return false;
 }
 
-// TODO: remove this function. Backends should just generate a __qmljs_get_activation_property followed by a __qmljs_call_value
 Value __qmljs_call_activation_property(ExecutionContext *context, String *name, Value *args, int argc)
 {
-    Value func = context->getProperty(name);
+    Object *base;
+    Value func = context->getPropertyAndBase(name, &base);
     Object *o = func.asObject();
     if (!o)
         context->throwTypeError();
 
-    return o->call(context, Value::undefinedValue(), args, argc);
+    Value thisObject = base ? Value::fromObject(base) : Value::undefinedValue();
+
+    return o->call(context, thisObject, args, argc);
 }
 
 Value __qmljs_call_property(ExecutionContext *context, Value that, String *name, Value *args, int argc)
index e85eecf..e7e8a56 100644 (file)
@@ -294,7 +294,6 @@ S15.1.2.2_A9.2 failing
 S15.1.2.2_A9.3 failing
 S15.1.2.2_A9.4 failing
 S15.1.2.2_A9.7 failing
-S15.10.6.2_A1_T2 failing
 S15.11.4.2_A1 failing
 S15.11.4.2_A2 failing
 15.12.1.1-g6-3 failing
@@ -618,11 +617,7 @@ S15.4.4.6_A4_T2 failing
 S15.4.4.7_A3 failing
 S15.4.4.7_A4_T2 failing
 S15.4.4.7_A4_T3 failing
-S15.5.4.10_A1_T10 failing
-S15.5.4.11_A1_T10 failing
 S15.5.4.11_A5_T1 failing
-S15.5.4.12_A1_T10 failing
-S15.5.4.13_A1_T10 failing
 S15.4.4.8_A1_T1 failing
 S15.4.4.8_A1_T2 failing
 S15.4.4.8_A2_T1 failing
@@ -743,18 +738,12 @@ S15.5.4.14_A4_T6 failing
 S15.5.4.14_A4_T7 failing
 S15.5.4.14_A4_T8 failing
 S15.5.4.14_A4_T9 failing
-S15.5.4.15_A1_T10 failing
 S15.5.4.15_A1_T2 failing
 S15.5.4.15_A1_T7 failing
 S15.5.4.15_A1_T8 failing
 S15.5.4.15_A1_T9 failing
 15.5.4.20-4-1 failing
-S15.5.4.5_A1_T10 failing
-S15.5.4.6_A1_T10 failing
-S15.5.4.7_A1_T10 failing
 S15.5.4.7_A1_T11 failing
-S15.5.4.4_A1_T10 failing
-S15.5.4.8_A1_T10 failing
 S15.5.4.8_A1_T12 failing
 S15.5.4.8_A1_T4 failing
 S15.7.4_A3.3 failing
@@ -943,4 +932,4 @@ S15.4.4.4_A1_T2 failing
 
 15.4.4.21-8-b-iii-1-6 failing
 15.12.3_4-1-1
-15.12.3_4-1-3
+15.12.3_4-1-3
\ No newline at end of file