aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2013-04-14 23:38:46 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2013-04-15 10:51:13 +0200
commit800bc0ed8d22bae49e7e3c5efce59aa33e5d6998 (patch)
treeadb84633fda303042cfb137b3387f1c175816cd0 /src
parent58ad517474606057a7777073dffded982ae9c85d (diff)
Specialized lookups for accessor properties
Change-Id: Ic4afb5b2b73b3311077d3d64ddc03fa6da842e82 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/v4/qv4lookup.cpp134
-rw-r--r--src/v4/qv4lookup.h8
2 files changed, 140 insertions, 2 deletions
diff --git a/src/v4/qv4lookup.cpp b/src/v4/qv4lookup.cpp
index 76e1c415ca..38a11a99de 100644
--- a/src/v4/qv4lookup.cpp
+++ b/src/v4/qv4lookup.cpp
@@ -39,6 +39,7 @@
**
****************************************************************************/
#include "qv4lookup.h"
+#include "qv4functionobject.h"
QT_BEGIN_NAMESPACE
@@ -62,6 +63,14 @@ void Lookup::lookupPropertyGeneric(QQmlJS::VM::Lookup *l, ExecutionContext *ctx,
*result = p->value;
return;
} else {
+ if (l->level == 0)
+ l->lookupProperty = lookupPropertyAccessor0;
+ else if (l->level == 1)
+ l->lookupProperty = lookupPropertyAccessor1;
+ else if (l->level == 2)
+ l->lookupProperty = lookupPropertyAccessor2;
+ if (result)
+ *result = p->value;
Value res = o->getValue(ctx, p, attrs);
if (result)
*result = res;
@@ -119,7 +128,7 @@ void Lookup::lookupProperty2(Lookup *l, ExecutionContext *ctx, Value *result, co
o = o->prototype;
if (l->classList[2] == o->internalClass) {
if (result)
- *result = o->prototype->memberData[l->index].value;
+ *result = o->memberData[l->index].value;
return;
}
}
@@ -129,6 +138,71 @@ void Lookup::lookupProperty2(Lookup *l, ExecutionContext *ctx, Value *result, co
lookupPropertyGeneric(l, ctx, result, object);
}
+void Lookup::lookupPropertyAccessor0(Lookup *l, ExecutionContext *ctx, Value *result, const Value &object)
+{
+ if (Object *o = object.asObject()) {
+ if (l->classList[0] == o->internalClass) {
+ Value res;
+ FunctionObject *getter = o->memberData[l->index].getter();
+ if (!getter)
+ res = Value::undefinedValue();
+ else
+ res = getter->call(ctx, object, 0, 0);
+ if (result)
+ *result = res;
+ return;
+ }
+ }
+ l->lookupProperty = lookupPropertyGeneric;
+ lookupPropertyGeneric(l, ctx, result, object);
+}
+
+void Lookup::lookupPropertyAccessor1(Lookup *l, ExecutionContext *ctx, Value *result, const Value &object)
+{
+ if (Object *o = object.asObject()) {
+ if (l->classList[0] == o->internalClass &&
+ l->classList[1] == o->prototype->internalClass) {
+ Value res;
+ FunctionObject *getter = o->prototype->memberData[l->index].getter();
+ if (!getter)
+ res = Value::undefinedValue();
+ else
+ res = getter->call(ctx, object, 0, 0);
+ if (result)
+ *result = res;
+ return;
+ }
+ }
+ l->lookupProperty = lookupPropertyGeneric;
+ lookupPropertyGeneric(l, ctx, result, object);
+}
+
+void Lookup::lookupPropertyAccessor2(Lookup *l, ExecutionContext *ctx, Value *result, const Value &object)
+{
+ if (Object *o = object.asObject()) {
+ if (l->classList[0] == o->internalClass) {
+ o = o->prototype;
+ if (l->classList[1] == o->internalClass) {
+ o = o->prototype;
+ if (l->classList[2] == o->internalClass) {
+ Value res;
+ FunctionObject *getter = o->memberData[l->index].getter();
+ if (!getter)
+ res = Value::undefinedValue();
+ else
+ res = getter->call(ctx, object, 0, 0);
+ if (result)
+ *result = res;
+ return;
+ }
+ }
+ }
+ }
+ l->lookupProperty = lookupPropertyGeneric;
+ lookupPropertyGeneric(l, ctx, result, object);
+}
+
+
void Lookup::lookupGlobalGeneric(Lookup *l, ExecutionContext *ctx, Value *result)
{
Object *o = ctx->engine->globalObject;
@@ -145,6 +219,12 @@ void Lookup::lookupGlobalGeneric(Lookup *l, ExecutionContext *ctx, Value *result
*result = p->value;
return;
} else {
+ if (l->level == 0)
+ l->lookupGlobal = lookupGlobalAccessor0;
+ else if (l->level == 1)
+ l->lookupGlobal = lookupGlobalAccessor1;
+ else if (l->level == 2)
+ l->lookupGlobal = lookupGlobalAccessor2;
Value res = o->getValue(ctx, p, attrs);
if (result)
*result = res;
@@ -194,6 +274,58 @@ void Lookup::lookupGlobal2(Lookup *l, ExecutionContext *ctx, Value *result)
lookupGlobalGeneric(l, ctx, result);
}
+void Lookup::lookupGlobalAccessor0(Lookup *l, ExecutionContext *ctx, Value *result)
+{
+ Object *o = ctx->engine->globalObject;
+ if (l->classList[0] == o->internalClass) {
+ FunctionObject *getter = o->memberData[l->index].getter();
+ if (!getter)
+ *result = Value::undefinedValue();
+ else
+ *result = getter->call(ctx, Value::undefinedValue(), 0, 0);
+ return;
+ }
+ l->lookupGlobal = lookupGlobalGeneric;
+ lookupGlobalGeneric(l, ctx, result);
+}
+
+void Lookup::lookupGlobalAccessor1(Lookup *l, ExecutionContext *ctx, Value *result)
+{
+ Object *o = ctx->engine->globalObject;
+ if (l->classList[0] == o->internalClass &&
+ l->classList[1] == o->prototype->internalClass) {
+ FunctionObject *getter = o->prototype->memberData[l->index].getter();
+ if (!getter)
+ *result = Value::undefinedValue();
+ else
+ *result = getter->call(ctx, Value::undefinedValue(), 0, 0);
+ return;
+ }
+ l->lookupGlobal = lookupGlobalGeneric;
+ lookupGlobalGeneric(l, ctx, result);
+}
+
+void Lookup::lookupGlobalAccessor2(Lookup *l, ExecutionContext *ctx, Value *result)
+{
+ Object *o = ctx->engine->globalObject;
+ if (l->classList[0] == o->internalClass) {
+ o = o->prototype;
+ if (l->classList[1] == o->internalClass) {
+ o = o->prototype;
+ if (l->classList[2] == o->internalClass) {
+ FunctionObject *getter = o->memberData[l->index].getter();
+ if (!getter)
+ *result = Value::undefinedValue();
+ else
+ *result = getter->call(ctx, Value::undefinedValue(), 0, 0);
+ return;
+ }
+ }
+ }
+ l->lookupGlobal = lookupGlobalGeneric;
+ lookupGlobalGeneric(l, ctx, result);
+}
+
}
}
diff --git a/src/v4/qv4lookup.h b/src/v4/qv4lookup.h
index c287c97124..38546cd65b 100644
--- a/src/v4/qv4lookup.h
+++ b/src/v4/qv4lookup.h
@@ -54,7 +54,7 @@ namespace QQmlJS {
namespace VM {
struct Lookup {
- enum { Size = 4 };
+ enum { Size = 3 };
union {
void (*lookupProperty)(Lookup *l, ExecutionContext *ctx, Value *result, const Value &object);
void (*lookupGlobal)(Lookup *l, ExecutionContext *ctx, Value *result);
@@ -68,11 +68,17 @@ struct Lookup {
static void lookupProperty0(Lookup *l, ExecutionContext *ctx, Value *result, const Value &object);
static void lookupProperty1(Lookup *l, ExecutionContext *ctx, Value *result, const Value &object);
static void lookupProperty2(Lookup *l, ExecutionContext *ctx, Value *result, const Value &object);
+ static void lookupPropertyAccessor0(Lookup *l, ExecutionContext *ctx, Value *result, const Value &object);
+ static void lookupPropertyAccessor1(Lookup *l, ExecutionContext *ctx, Value *result, const Value &object);
+ static void lookupPropertyAccessor2(Lookup *l, ExecutionContext *ctx, Value *result, const Value &object);
static void lookupGlobalGeneric(Lookup *l, ExecutionContext *ctx, Value *result);
static void lookupGlobal0(Lookup *l, ExecutionContext *ctx, Value *result);
static void lookupGlobal1(Lookup *l, ExecutionContext *ctx, Value *result);
static void lookupGlobal2(Lookup *l, ExecutionContext *ctx, Value *result);
+ static void lookupGlobalAccessor0(Lookup *l, ExecutionContext *ctx, Value *result);
+ static void lookupGlobalAccessor1(Lookup *l, ExecutionContext *ctx, Value *result);
+ static void lookupGlobalAccessor2(Lookup *l, ExecutionContext *ctx, Value *result);
Property *lookup(Object *obj, PropertyAttributes *attrs) {
int i = 0;