Move call/construct over into the new vtable.
authorLars Knoll <lars.knoll@digia.com>
Thu, 14 Feb 2013 13:07:57 +0000 (14:07 +0100)
committerSimon Hausmann <simon.hausmann@digia.com>
Thu, 14 Feb 2013 13:57:00 +0000 (14:57 +0100)
Change-Id: I4f58a1fac25440695bdc62a49adb51a887616a5c
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
27 files changed:
src/v4/qmljs_value.h
src/v4/qv4argumentsobject.cpp
src/v4/qv4argumentsobject.h
src/v4/qv4arrayobject.cpp
src/v4/qv4arrayobject.h
src/v4/qv4booleanobject.cpp
src/v4/qv4booleanobject.h
src/v4/qv4dateobject.cpp
src/v4/qv4dateobject.h
src/v4/qv4errorobject.cpp
src/v4/qv4errorobject.h
src/v4/qv4functionobject.cpp
src/v4/qv4functionobject.h
src/v4/qv4globalobject.cpp
src/v4/qv4globalobject.h
src/v4/qv4managed.cpp
src/v4/qv4managed.h
src/v4/qv4numberobject.cpp
src/v4/qv4numberobject.h
src/v4/qv4object.cpp
src/v4/qv4objectproto.cpp
src/v4/qv4objectproto.h
src/v4/qv4regexpobject.cpp
src/v4/qv4regexpobject.h
src/v4/qv4stringobject.cpp
src/v4/qv4stringobject.h
tools/v4/main.cpp

index 7c83af5..2675d55 100644 (file)
@@ -475,6 +475,13 @@ inline ErrorObject *Value::asErrorObject() const
     return isObject() ? managed()->asErrorObject() : 0;
 }
 
+// ###
+inline Value Managed::construct(ExecutionContext *context, Value *args, int argc) {
+    return vtbl->construct(this, context, args, argc);
+}
+inline Value Managed::call(ExecutionContext *context, const Value &thisObject, Value *args, int argc) {
+    return vtbl->call(this, context, thisObject, args, argc);
+}
 
 } // namespace VM
 } // namespace QQmlJS
index f805aa6..d1791e0 100644 (file)
@@ -50,12 +50,7 @@ static Value throwTypeError(ExecutionContext *ctx)
     return Value::undefinedValue();
 }
 
-const ManagedVTable ArgumentsObject::static_vtbl =
-{
-    ArgumentsObject::markObjects,
-    Managed::hasInstance,
-    ManagedVTable::EndOfVTable
-};
+DEFINE_MANAGED_VTABLE(ArgumentsObject);
 
 ArgumentsObject::ArgumentsObject(ExecutionContext *context, int formalParameterCount, int actualParameterCount)
     : Object(context->engine), context(context)
@@ -132,9 +127,11 @@ bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const
     return result;
 }
 
+DEFINE_MANAGED_VTABLE(ArgumentsGetterFunction);
 
-Value ArgumentsGetterFunction::call(ExecutionContext *ctx, Value thisObject, Value *, int)
+Value ArgumentsGetterFunction::call(Managed *getter, ExecutionContext *ctx, const Value &thisObject, Value *, int)
 {
+    ArgumentsGetterFunction *g = static_cast<ArgumentsGetterFunction *>(getter);
     Object *that = thisObject.asObject();
     if (!that)
         __qmljs_throw_type_error(ctx);
@@ -142,12 +139,15 @@ Value ArgumentsGetterFunction::call(ExecutionContext *ctx, Value thisObject, Val
     if (!o)
         __qmljs_throw_type_error(ctx);
 
-    assert(index < o->context->argumentCount);
-    return o->context->argument(index);
+    assert(g->index < o->context->argumentCount);
+    return o->context->argument(g->index);
 }
 
-Value ArgumentsSetterFunction::call(ExecutionContext *ctx, Value thisObject, Value *args, int argc)
+DEFINE_MANAGED_VTABLE(ArgumentsSetterFunction);
+
+Value ArgumentsSetterFunction::call(Managed *setter, ExecutionContext *ctx, const Value &thisObject, Value *args, int argc)
 {
+    ArgumentsSetterFunction *s = static_cast<ArgumentsSetterFunction *>(setter);
     Object *that = thisObject.asObject();
     if (!that)
         __qmljs_throw_type_error(ctx);
@@ -155,8 +155,8 @@ Value ArgumentsSetterFunction::call(ExecutionContext *ctx, Value thisObject, Val
     if (!o)
         __qmljs_throw_type_error(ctx);
 
-    assert(index < o->context->argumentCount);
-    o->context->arguments[index] = argc ? args[0] : Value::undefinedValue();
+    assert(s->index < o->context->argumentCount);
+    o->context->arguments[s->index] = argc ? args[0] : Value::undefinedValue();
     return Value::undefinedValue();
 }
 
index fe62bf7..acbcc75 100644 (file)
@@ -54,9 +54,12 @@ struct ArgumentsGetterFunction: FunctionObject
     uint index;
 
     ArgumentsGetterFunction(ExecutionContext *scope, uint index)
-        : FunctionObject(scope), index(index) {}
+        : FunctionObject(scope), index(index) { vtbl = &static_vtbl; }
 
-    virtual Value call(ExecutionContext *ctx, Value thisObject, Value *, int);
+    static Value call(Managed *that, ExecutionContext *, const Value &, Value *, int);
+
+protected:
+    static const ManagedVTable static_vtbl;
 };
 
 struct ArgumentsSetterFunction: FunctionObject
@@ -64,9 +67,12 @@ struct ArgumentsSetterFunction: FunctionObject
     uint index;
 
     ArgumentsSetterFunction(ExecutionContext *scope, uint index)
-        : FunctionObject(scope), index(index) {}
+        : FunctionObject(scope), index(index) { vtbl = &static_vtbl; }
 
-    virtual Value call(ExecutionContext *ctx, Value thisObject, Value *args, int argc);
+    static Value call(Managed *that, ExecutionContext *, const Value &, Value *, int);
+
+protected:
+    static const ManagedVTable static_vtbl;
 };
 
 
index 2999ce0..8117a65 100644 (file)
 
 using namespace QQmlJS::VM;
 
+DEFINE_MANAGED_VTABLE(ArrayCtor);
+
 ArrayCtor::ArrayCtor(ExecutionContext *scope)
     : FunctionObject(scope)
 {
+    vtbl = &static_vtbl;
 }
 
-Value ArrayCtor::construct(ExecutionContext *ctx, Value *argv, int argc)
+Value ArrayCtor::construct(Managed *, ExecutionContext *ctx, Value *argv, int argc)
 {
     ArrayObject *a = ctx->engine->newArrayObject(ctx);
     uint len;
@@ -74,9 +77,9 @@ Value ArrayCtor::construct(ExecutionContext *ctx, Value *argv, int argc)
     return Value::fromObject(a);
 }
 
-Value ArrayCtor::call(ExecutionContext *ctx, Value thisObject, Value *argv, int argc)
+Value ArrayCtor::call(Managed *that, ExecutionContext *ctx, const Value &thisObject, Value *argv, int argc)
 {
-    return construct(ctx, argv, argc);
+    return construct(that, ctx, argv, argc);
 }
 
 void ArrayPrototype::init(ExecutionContext *ctx, const Value &ctor)
index 48250dd..1e61600 100644 (file)
@@ -55,8 +55,11 @@ struct ArrayCtor: FunctionObject
 {
     ArrayCtor(ExecutionContext *scope);
 
-    virtual Value construct(ExecutionContext *ctx, Value *argv, int argc);
-    virtual Value call(ExecutionContext *ctx, Value thisObject, Value *argv, int argc);
+    static Value construct(Managed *, ExecutionContext *context, Value *args, int argc);
+    static Value call(Managed *that, ExecutionContext *, const Value &, Value *, int);
+
+protected:
+    static const ManagedVTable static_vtbl;
 };
 
 struct ArrayPrototype: ArrayObject
index 02fab7b..b2a72f1 100644 (file)
 
 using namespace QQmlJS::VM;
 
+DEFINE_MANAGED_VTABLE(BooleanCtor);
+
 BooleanCtor::BooleanCtor(ExecutionContext *scope)
     : FunctionObject(scope)
 {
+    vtbl = &static_vtbl;
 }
 
-Value BooleanCtor::construct(ExecutionContext *ctx, Value *args, int argc)
+Value BooleanCtor::construct(Managed *, ExecutionContext *ctx, Value *args, int argc)
 {
     bool n = argc ? args[0].toBoolean(ctx) : false;
     return Value::fromObject(ctx->engine->newBooleanObject(Value::fromBoolean(n)));
 }
 
-Value BooleanCtor::call(ExecutionContext *parentCtx, Value thisObject, Value *argv, int argc)
+Value BooleanCtor::call(Managed *, ExecutionContext *parentCtx, const Value &thisObject, Value *argv, int argc)
 {
     bool value = argc ? argv[0].toBoolean(parentCtx) : 0;
     return Value::fromBoolean(value);
index da9105e..68976f3 100644 (file)
@@ -54,8 +54,11 @@ struct BooleanCtor: FunctionObject
 {
     BooleanCtor(ExecutionContext *scope);
 
-    virtual Value construct(ExecutionContext *ctx, Value *args, int argc);
-    virtual Value call(ExecutionContext *parentCtx, Value thisObject, Value *argv, int argc);
+    static Value construct(Managed *, ExecutionContext *context, Value *args, int argc);
+    static Value call(Managed *that, ExecutionContext *, const Value &, Value *, int);
+
+protected:
+    static const ManagedVTable static_vtbl;
 };
 
 struct BooleanPrototype: BooleanObject
index de614cc..77ed279 100644 (file)
@@ -658,13 +658,15 @@ static double getLocalTZA()
 #endif
 }
 
+DEFINE_MANAGED_VTABLE(DateCtor);
 
 DateCtor::DateCtor(ExecutionContext *scope)
     : FunctionObject(scope)
 {
+    vtbl = &static_vtbl;
 }
 
-Value DateCtor::construct(ExecutionContext *ctx, Value *args, int argc)
+Value DateCtor::construct(Managed *, ExecutionContext *ctx, Value *args, int argc)
 {
     double t = 0;
 
@@ -702,7 +704,7 @@ Value DateCtor::construct(ExecutionContext *ctx, Value *args, int argc)
     return Value::fromObject(d);
 }
 
-Value DateCtor::call(ExecutionContext *ctx, Value, Value *, int)
+Value DateCtor::call(Managed *, ExecutionContext *ctx, const Value &, Value *, int)
 {
     double t = currentTime();
     return Value::fromString(ctx, ToString(t));
index b4916ec..946240e 100644 (file)
@@ -59,8 +59,11 @@ struct DateCtor: FunctionObject
 {
     DateCtor(ExecutionContext *scope);
 
-    virtual Value construct(ExecutionContext *ctx, Value *args, int argc);
-    virtual Value call(ExecutionContext *ctx, Value, Value *, int);
+    static Value construct(Managed *, ExecutionContext *context, Value *args, int argc);
+    static Value call(Managed *that, ExecutionContext *, const Value &, Value *, int);
+
+protected:
+    static const ManagedVTable static_vtbl;
 };
 
 struct DatePrototype: DateObject
index 8ad7d5e..418dbb7 100644 (file)
@@ -163,48 +163,56 @@ URIErrorObject::URIErrorObject(ExecutionContext *ctx, const Value &message)
     prototype = ctx->engine->uRIErrorPrototype;
 }
 
+DEFINE_MANAGED_VTABLE(ErrorCtor);
+DEFINE_MANAGED_VTABLE(EvalErrorCtor);
+DEFINE_MANAGED_VTABLE(RangeErrorCtor);
+DEFINE_MANAGED_VTABLE(ReferenceErrorCtor);
+DEFINE_MANAGED_VTABLE(SyntaxErrorCtor);
+DEFINE_MANAGED_VTABLE(TypeErrorCtor);
+DEFINE_MANAGED_VTABLE(URIErrorCtor);
 
 ErrorCtor::ErrorCtor(ExecutionContext *scope)
     : FunctionObject(scope)
 {
+    vtbl = &static_vtbl;
 }
 
-Value ErrorCtor::construct(ExecutionContext *ctx, Value *args, int argc)
+Value ErrorCtor::construct(Managed *, ExecutionContext *ctx, Value *args, int argc)
 {
     return Value::fromObject(ctx->engine->newErrorObject(argc ? args[0] : Value::undefinedValue()));
 }
 
-Value ErrorCtor::call(ExecutionContext *ctx, Value thisObject, Value *args, int argc)
+Value ErrorCtor::call(Managed *that, ExecutionContext *ctx, const Value &, Value *args, int argc)
 {
-    return construct(ctx, args, argc);
+    return that->construct(ctx, args, argc);
 }
 
-Value EvalErrorCtor::construct(ExecutionContext *ctx, Value *args, int argc)
+Value EvalErrorCtor::construct(Managed *, ExecutionContext *ctx, Value *args, int argc)
 {
     return Value::fromObject(new (ctx->engine->memoryManager) EvalErrorObject(ctx, argc ? args[0] : Value::undefinedValue()));
 }
 
-Value RangeErrorCtor::construct(ExecutionContext *ctx, Value *args, int argc)
+Value RangeErrorCtor::construct(Managed *, ExecutionContext *ctx, Value *args, int argc)
 {
     return Value::fromObject(new (ctx->engine->memoryManager) RangeErrorObject(ctx, argc ? args[0] : Value::undefinedValue()));
 }
 
-Value ReferenceErrorCtor::construct(ExecutionContext *ctx, Value *args, int argc)
+Value ReferenceErrorCtor::construct(Managed *, ExecutionContext *ctx, Value *args, int argc)
 {
     return Value::fromObject(new (ctx->engine->memoryManager) ReferenceErrorObject(ctx, argc ? args[0] : Value::undefinedValue()));
 }
 
-Value SyntaxErrorCtor::construct(ExecutionContext *ctx, Value *, int)
+Value SyntaxErrorCtor::construct(Managed *, ExecutionContext *ctx, Value *, int)
 {
     return Value::fromObject(new (ctx->engine->memoryManager) SyntaxErrorObject(ctx, 0));
 }
 
-Value TypeErrorCtor::construct(ExecutionContext *ctx, Value *args, int argc)
+Value TypeErrorCtor::construct(Managed *, ExecutionContext *ctx, Value *args, int argc)
 {
     return Value::fromObject(new (ctx->engine->memoryManager) TypeErrorObject(ctx, argc ? args[0] : Value::undefinedValue()));
 }
 
-Value URIErrorCtor::construct(ExecutionContext *ctx, Value *args, int argc)
+Value URIErrorCtor::construct(Managed *, ExecutionContext *ctx, Value *args, int argc)
 {
     return Value::fromObject(new (ctx->engine->memoryManager) URIErrorObject(ctx, argc ? args[0] : Value::undefinedValue()));
 }
index 734ee3f..2be3242 100644 (file)
@@ -106,50 +106,71 @@ struct ErrorCtor: FunctionObject
 {
     ErrorCtor(ExecutionContext *scope);
 
-    virtual Value construct(ExecutionContext *ctx, Value *args, int argc);
-    virtual Value call(ExecutionContext *ctx, Value thisObject, Value *args, int argc);
+    static Value construct(Managed *, ExecutionContext *context, Value *args, int argc);
+    static Value call(Managed *that, ExecutionContext *, const Value &, Value *, int);
+
+protected:
+    static const ManagedVTable static_vtbl;
 };
 
 struct EvalErrorCtor: ErrorCtor
 {
-    EvalErrorCtor(ExecutionContext *scope): ErrorCtor(scope) {}
+    EvalErrorCtor(ExecutionContext *scope): ErrorCtor(scope) { vtbl = &static_vtbl; }
 
-    virtual Value construct(ExecutionContext *ctx, Value *, int argc);
+    static Value construct(Managed *, ExecutionContext *context, Value *args, int argc);
+
+protected:
+    static const ManagedVTable static_vtbl;
 };
 
 struct RangeErrorCtor: ErrorCtor
 {
-    RangeErrorCtor(ExecutionContext *scope): ErrorCtor(scope) {}
+    RangeErrorCtor(ExecutionContext *scope): ErrorCtor(scope) { vtbl = &static_vtbl; }
 
-    virtual Value construct(ExecutionContext *ctx, Value *args, int argc);
+    static Value construct(Managed *, ExecutionContext *context, Value *args, int argc);
+
+protected:
+    static const ManagedVTable static_vtbl;
 };
 
 struct ReferenceErrorCtor: ErrorCtor
 {
-    ReferenceErrorCtor(ExecutionContext *scope): ErrorCtor(scope) {}
+    ReferenceErrorCtor(ExecutionContext *scope): ErrorCtor(scope) { vtbl = &static_vtbl; }
+
+    static Value construct(Managed *, ExecutionContext *context, Value *args, int argc);
 
-    virtual Value construct(ExecutionContext *ctx, Value *args, int argc);
+protected:
+    static const ManagedVTable static_vtbl;
 };
 
 struct SyntaxErrorCtor: ErrorCtor
 {
-    SyntaxErrorCtor(ExecutionContext *scope): ErrorCtor(scope) {}
+    SyntaxErrorCtor(ExecutionContext *scope): ErrorCtor(scope) { vtbl = &static_vtbl; }
+
+    static Value construct(Managed *, ExecutionContext *context, Value *args, int argc);
 
-    virtual Value construct(ExecutionContext *ctx, Value *, int);
+protected:
+    static const ManagedVTable static_vtbl;
 };
 
 struct TypeErrorCtor: ErrorCtor
 {
-    TypeErrorCtor(ExecutionContext *scope): ErrorCtor(scope) {}
+    TypeErrorCtor(ExecutionContext *scope): ErrorCtor(scope) { vtbl = &static_vtbl; }
+
+    static Value construct(Managed *, ExecutionContext *context, Value *args, int argc);
 
-    virtual Value construct(ExecutionContext *ctx, Value *args, int argc);
+protected:
+    static const ManagedVTable static_vtbl;
 };
 
 struct URIErrorCtor: ErrorCtor
 {
-    URIErrorCtor(ExecutionContext *scope): ErrorCtor(scope) {}
+    URIErrorCtor(ExecutionContext *scope): ErrorCtor(scope) { vtbl = &static_vtbl; }
+
+    static Value construct(Managed *, ExecutionContext *context, Value *args, int argc);
 
-    virtual Value construct(ExecutionContext *ctx, Value *args, int argc);
+protected:
+    static const ManagedVTable static_vtbl;
 };
 
 
@@ -165,37 +186,37 @@ struct ErrorPrototype: ErrorObject
 
 struct EvalErrorPrototype: EvalErrorObject
 {
-    EvalErrorPrototype(ExecutionContext *ctx): EvalErrorObject(ctx, Value::undefinedValue()) {}
+    EvalErrorPrototype(ExecutionContext *ctx): EvalErrorObject(ctx, Value::undefinedValue()) { vtbl = &static_vtbl; }
     void init(ExecutionContext *ctx, const Value &ctor) { ErrorPrototype::init(ctx, ctor, this); }
 };
 
 struct RangeErrorPrototype: RangeErrorObject
 {
-    RangeErrorPrototype(ExecutionContext *ctx): RangeErrorObject(ctx, Value::undefinedValue()) {}
+    RangeErrorPrototype(ExecutionContext *ctx): RangeErrorObject(ctx, Value::undefinedValue()) { vtbl = &static_vtbl; }
     void init(ExecutionContext *ctx, const Value &ctor) { ErrorPrototype::init(ctx, ctor, this); }
 };
 
 struct ReferenceErrorPrototype: ReferenceErrorObject
 {
-    ReferenceErrorPrototype(ExecutionContext *ctx): ReferenceErrorObject(ctx, Value::undefinedValue()) {}
+    ReferenceErrorPrototype(ExecutionContext *ctx): ReferenceErrorObject(ctx, Value::undefinedValue()) { vtbl = &static_vtbl; }
     void init(ExecutionContext *ctx, const Value &ctor) { ErrorPrototype::init(ctx, ctor, this); }
 };
 
 struct SyntaxErrorPrototype: SyntaxErrorObject
 {
-    SyntaxErrorPrototype(ExecutionContext *ctx): SyntaxErrorObject(ctx, 0) {}
+    SyntaxErrorPrototype(ExecutionContext *ctx): SyntaxErrorObject(ctx, 0) { vtbl = &static_vtbl; }
     void init(ExecutionContext *ctx, const Value &ctor) { ErrorPrototype::init(ctx, ctor, this); }
 };
 
 struct TypeErrorPrototype: TypeErrorObject
 {
-    TypeErrorPrototype(ExecutionContext *ctx): TypeErrorObject(ctx, Value::undefinedValue()) {}
+    TypeErrorPrototype(ExecutionContext *ctx): TypeErrorObject(ctx, Value::undefinedValue()) { vtbl = &static_vtbl; }
     void init(ExecutionContext *ctx, const Value &ctor) { ErrorPrototype::init(ctx, ctor, this); }
 };
 
 struct URIErrorPrototype: URIErrorObject
 {
-    URIErrorPrototype(ExecutionContext *ctx): URIErrorObject(ctx, Value::undefinedValue()) {}
+    URIErrorPrototype(ExecutionContext *ctx): URIErrorObject(ctx, Value::undefinedValue()) { vtbl = &static_vtbl; }
     void init(ExecutionContext *ctx, const Value &ctor) { ErrorPrototype::init(ctx, ctor, this); }
 };
 
index 991695c..caa6987 100644 (file)
@@ -64,6 +64,8 @@
 using namespace QQmlJS::VM;
 
 
+DEFINE_MANAGED_VTABLE(FunctionObject);
+
 Function::~Function()
 {
     delete[] codeData;
@@ -127,16 +129,18 @@ bool FunctionObject::hasInstance(Managed *that, ExecutionContext *ctx, const Val
     return false;
 }
 
-Value FunctionObject::construct(ExecutionContext *context, Value *, int)
+Value FunctionObject::construct(Managed *that, ExecutionContext *context, Value *, int)
 {
+    FunctionObject *f = static_cast<FunctionObject *>(that);
+
     Object *obj = context->engine->newObject();
-    Value proto = __get__(context, context->engine->id_prototype);
+    Value proto = f->__get__(context, context->engine->id_prototype);
     if (proto.isObject())
         obj->prototype = proto.objectValue();
     return Value::fromObject(obj);
 }
 
-Value FunctionObject::call(ExecutionContext *, Value, Value *, int)
+Value FunctionObject::call(Managed *, ExecutionContext *, const Value &, Value *, int)
 {
     return Value::undefinedValue();
 }
@@ -158,23 +162,19 @@ void FunctionObject::markObjects(Managed *that)
     Object::markObjects(that);
 }
 
-const ManagedVTable FunctionObject::static_vtbl =
-{
-    FunctionObject::markObjects,
-    FunctionObject::hasInstance,
-    ManagedVTable::EndOfVTable
-};
-
 
+DEFINE_MANAGED_VTABLE(FunctionCtor);
 
 FunctionCtor::FunctionCtor(ExecutionContext *scope)
     : FunctionObject(scope)
 {
+    vtbl = &static_vtbl;
 }
 
 // 15.3.2
-Value FunctionCtor::construct(ExecutionContext *ctx, Value *args, int argc)
+Value FunctionCtor::construct(Managed *that, ExecutionContext *ctx, Value *args, int argc)
 {
+    FunctionCtor *f = static_cast<FunctionCtor *>(that);
     MemoryManager::GCBlocker gcBlocker(ctx->engine->memoryManager);
 
     QString arguments;
@@ -207,7 +207,7 @@ Value FunctionCtor::construct(ExecutionContext *ctx, Value *args, int argc)
 
     IR::Module module;
 
-    Codegen cg(ctx, strictMode);
+    Codegen cg(ctx, f->strictMode);
     IR::Function *irf = cg(QString(), fe, &module);
 
     QScopedPointer<EvalInstructionSelection> isel(ctx->engine->iselFactory->create(ctx->engine, &module));
@@ -217,9 +217,9 @@ Value FunctionCtor::construct(ExecutionContext *ctx, Value *args, int argc)
 }
 
 // 15.3.1: This is equivalent to new Function(...)
-Value FunctionCtor::call(ExecutionContext *context, Value thisObject, Value *args, int argc)
+Value FunctionCtor::call(Managed *that, ExecutionContext *context, const Value &thisObject, Value *args, int argc)
 {
-    return construct(context, args, argc);
+    return construct(that, context, args, argc);
 }
 
 void FunctionPrototype::init(ExecutionContext *ctx, const Value &ctor)
@@ -309,9 +309,12 @@ static Value throwTypeError(ExecutionContext *ctx)
     return Value::undefinedValue();
 }
 
+DEFINE_MANAGED_VTABLE(ScriptFunction);
+
 ScriptFunction::ScriptFunction(ExecutionContext *scope, Function *function)
     : FunctionObject(scope)
 {
+    vtbl = &static_vtbl;
     this->function = function;
     assert(function);
     assert(function->code);
@@ -356,24 +359,25 @@ ScriptFunction::~ScriptFunction()
 {
 }
 
-Value ScriptFunction::construct(ExecutionContext *context, Value *args, int argc)
+Value ScriptFunction::construct(Managed *that, ExecutionContext *context, Value *args, int argc)
 {
-    assert(function->code);
+    ScriptFunction *f = static_cast<ScriptFunction *>(that);
+    assert(f->function->code);
     Object *obj = context->engine->newObject();
-    Value proto = __get__(context, context->engine->id_prototype);
+    Value proto = f->__get__(context, context->engine->id_prototype);
     if (proto.isObject())
         obj->prototype = proto.objectValue();
 
-    uint size = requiredMemoryForExecutionContect(this, argc);
-    ExecutionContext *ctx = static_cast<ExecutionContext *>(needsActivation ? malloc(size) : alloca(size));
+    uint size = requiredMemoryForExecutionContect(f, argc);
+    ExecutionContext *ctx = static_cast<ExecutionContext *>(f->needsActivation ? malloc(size) : alloca(size));
 
     ctx->thisObject = Value::fromObject(obj);
-    ctx->function = this;
+    ctx->function = f;
     ctx->arguments = args;
     ctx->argumentCount = argc;
 
     ctx->initCallContext(context);
-    Value result = function->code(ctx, function->codeData);
+    Value result = f->function->code(ctx, f->function->codeData);
     ctx->leaveCallContext();
 
     if (result.isObject())
@@ -381,104 +385,109 @@ Value ScriptFunction::construct(ExecutionContext *context, Value *args, int argc
     return Value::fromObject(obj);
 }
 
-Value ScriptFunction::call(ExecutionContext *context, Value thisObject, Value *args, int argc)
+Value ScriptFunction::call(Managed *that, ExecutionContext *context, const Value &thisObject, Value *args, int argc)
 {
-    assert(function->code);
-    uint size = requiredMemoryForExecutionContect(this, argc);
-    ExecutionContext *ctx = static_cast<ExecutionContext *>(needsActivation ? malloc(size) : alloca(size));
+    ScriptFunction *f = static_cast<ScriptFunction *>(that);
+    assert(f->function->code);
+    uint size = requiredMemoryForExecutionContect(f, argc);
+    ExecutionContext *ctx = static_cast<ExecutionContext *>(f->needsActivation ? malloc(size) : alloca(size));
 
-    if (!strictMode && !thisObject.isObject()) {
+    ctx->thisObject = thisObject;
+    if (!f->strictMode && !thisObject.isObject()) {
         // Built-in functions allow for the this object to be null or undefined. This overrides
         // the behaviour of changing thisObject to the global object if null/undefined and allows
         // the built-in functions for example to throw a type error if null is passed.
         if (thisObject.isUndefined() || thisObject.isNull()) {
-            if (!isBuiltinFunction)
-                thisObject = context->engine->globalObject;
+            if (!f->isBuiltinFunction)
+                ctx->thisObject = context->engine->globalObject;
         } else {
-            thisObject = thisObject.toObject(context);
+            ctx->thisObject = thisObject.toObject(context);
         }
     }
 
-    ctx->thisObject = thisObject;
-    ctx->function = this;
+    ctx->function = f;
     ctx->arguments = args;
     ctx->argumentCount = argc;
 
     ctx->initCallContext(context);
-    Value result = function->code(ctx, function->codeData);
+    Value result = f->function->code(ctx, f->function->codeData);
     ctx->leaveCallContext();
     return result;
 }
 
 
 
+DEFINE_MANAGED_VTABLE(BuiltinFunctionOld);
+
 BuiltinFunctionOld::BuiltinFunctionOld(ExecutionContext *scope, String *name, Value (*code)(ExecutionContext *))
     : FunctionObject(scope)
     , code(code)
 {
+    vtbl = &static_vtbl;
     this->name = name;
     isBuiltinFunction = true;
 }
 
-Value BuiltinFunctionOld::construct(ExecutionContext *ctx, Value *, int)
+Value BuiltinFunctionOld::construct(Managed *, ExecutionContext *ctx, Value *, int)
 {
     ctx->throwTypeError();
     return Value::undefinedValue();
 }
 
-Value BuiltinFunctionOld::call(ExecutionContext *context, Value thisObject, Value *args, int argc)
+Value BuiltinFunctionOld::call(Managed *that, ExecutionContext *context, const Value &thisObject, Value *args, int argc)
 {
-    uint size = requiredMemoryForExecutionContect(this, argc);
-    ExecutionContext *ctx = static_cast<ExecutionContext *>(needsActivation ? malloc(size) : alloca(size));
+    BuiltinFunctionOld *f = static_cast<BuiltinFunctionOld *>(that);
+    uint size = requiredMemoryForExecutionContect(f, argc);
+    ExecutionContext *ctx = static_cast<ExecutionContext *>(f->needsActivation ? malloc(size) : alloca(size));
 
-    if (!strictMode && !thisObject.isObject()) {
+    ctx->thisObject = thisObject;
+    if (!f->strictMode && !thisObject.isObject()) {
         // Built-in functions allow for the this object to be null or undefined. This overrides
         // the behaviour of changing thisObject to the global object if null/undefined and allows
         // the built-in functions for example to throw a type error if null is passed.
         if (thisObject.isUndefined() || thisObject.isNull()) {
-            if (!isBuiltinFunction)
-                thisObject = context->engine->globalObject;
+            if (!f->isBuiltinFunction)
+                ctx->thisObject = context->engine->globalObject;
         } else {
-            thisObject = thisObject.toObject(context);
+            ctx->thisObject = thisObject.toObject(context);
         }
     }
 
-    ctx->thisObject = thisObject;
-    ctx->function = this;
+    ctx->function = f;
     ctx->arguments = args;
     ctx->argumentCount = argc;
 
     ctx->initCallContext(context);
-    Value result = code(ctx);
+    Value result = f->code(ctx);
     ctx->leaveCallContext();
     return result;
 }
 
+
+DEFINE_MANAGED_VTABLE(BuiltinFunction);
+
 BuiltinFunction::BuiltinFunction(ExecutionContext *scope, String *name, Value (*code)(ExecutionContext *, Value, Value *, int))
     : FunctionObject(scope)
     , code(code)
 {
+    vtbl = &static_vtbl;
     this->name = name;
     isBuiltinFunction = true;
 }
 
-Value BuiltinFunction::call(ExecutionContext *context, Value thisObject, Value *args, int argc)
+Value BuiltinFunction::call(Managed *that, ExecutionContext *context, const Value &thisObject, Value *args, int argc)
 {
-    return code(context, thisObject, args, argc);
+    BuiltinFunction *f = static_cast<BuiltinFunction *>(that);
+    return f->code(context, thisObject, args, argc);
 }
 
-Value BuiltinFunction::construct(ExecutionContext *ctx, Value *, int)
+Value BuiltinFunction::construct(Managed *, ExecutionContext *ctx, Value *, int)
 {
     ctx->throwTypeError();
     return Value::undefinedValue();
 }
 
-const ManagedVTable BoundFunction::static_vtbl =
-{
-    BoundFunction::markObjects,
-    BoundFunction::hasInstance,
-    ManagedVTable::EndOfVTable
-};
+DEFINE_MANAGED_VTABLE(BoundFunction);
 
 BoundFunction::BoundFunction(ExecutionContext *scope, FunctionObject *target, Value boundThis, const QVector<Value> &boundArgs)
     : FunctionObject(scope)
@@ -501,22 +510,24 @@ BoundFunction::BoundFunction(ExecutionContext *scope, FunctionObject *target, Va
     *insertMember(scope->engine->id_caller) = pd;
 }
 
-Value BoundFunction::call(ExecutionContext *context, Value, Value *args, int argc)
+Value BoundFunction::call(Managed *that, ExecutionContext *context, const Value &, Value *args, int argc)
 {
-    Value *newArgs = static_cast<Value *>(alloca(sizeof(Value)*(boundArgs.size() + argc)));
-    memcpy(newArgs, boundArgs.constData(), boundArgs.size()*sizeof(Value));
-    memcpy(newArgs + boundArgs.size(), args, argc*sizeof(Value));
+    BoundFunction *f = static_cast<BoundFunction *>(that);
+    Value *newArgs = static_cast<Value *>(alloca(sizeof(Value)*(f->boundArgs.size() + argc)));
+    memcpy(newArgs, f->boundArgs.constData(), f->boundArgs.size()*sizeof(Value));
+    memcpy(newArgs + f->boundArgs.size(), args, argc*sizeof(Value));
 
-    return target->call(context, boundThis, newArgs, boundArgs.size() + argc);
+    return f->target->call(context, f->boundThis, newArgs, f->boundArgs.size() + argc);
 }
 
-Value BoundFunction::construct(ExecutionContext *context, Value *args, int argc)
+Value BoundFunction::construct(Managed *that, ExecutionContext *context, Value *args, int argc)
 {
-    Value *newArgs = static_cast<Value *>(alloca(sizeof(Value)*(boundArgs.size() + argc)));
-    memcpy(newArgs, boundArgs.constData(), boundArgs.size()*sizeof(Value));
-    memcpy(newArgs + boundArgs.size(), args, argc*sizeof(Value));
+    BoundFunction *f = static_cast<BoundFunction *>(that);
+    Value *newArgs = static_cast<Value *>(alloca(sizeof(Value)*(f->boundArgs.size() + argc)));
+    memcpy(newArgs, f->boundArgs.constData(), f->boundArgs.size()*sizeof(Value));
+    memcpy(newArgs + f->boundArgs.size(), args, argc*sizeof(Value));
 
-    return target->construct(context, newArgs, boundArgs.size() + argc);
+    return f->target->construct(context, newArgs, f->boundArgs.size() + argc);
 }
 
 bool BoundFunction::hasInstance(Managed *that, ExecutionContext *ctx, const Value &value)
index 9d55944..cf99b78 100644 (file)
@@ -156,8 +156,14 @@ struct Q_V4_EXPORT FunctionObject: Object {
 
     FunctionObject(ExecutionContext *scope);
 
-    virtual Value construct(ExecutionContext *context, Value *args, int argc);
-    virtual Value call(ExecutionContext *, Value, Value *, int);
+    static Value construct(Managed *that, ExecutionContext *context, Value *args, int argc);
+    static Value call(Managed *that, ExecutionContext *, const Value &, Value *, int);
+    inline Value construct(ExecutionContext *context, Value *args, int argc) {
+        return vtbl->construct(this, context, args, argc);
+    }
+    inline Value call(ExecutionContext *context, const Value &thisObject, Value *args, int argc) {
+        return vtbl->call(this, context, thisObject, args, argc);
+    }
 
 protected:
     static const ManagedVTable static_vtbl;
@@ -169,8 +175,11 @@ struct FunctionCtor: FunctionObject
 {
     FunctionCtor(ExecutionContext *scope);
 
-    virtual Value construct(ExecutionContext *ctx, Value *args, int argc);
-    virtual Value call(ExecutionContext *context, Value thisObject, Value *args, int argc);
+    static Value construct(Managed *that, ExecutionContext *context, Value *args, int argc);
+    static Value call(Managed *that, ExecutionContext *, const Value &, Value *, int);
+
+protected:
+    static const ManagedVTable static_vtbl;
 };
 
 struct FunctionPrototype: FunctionObject
@@ -188,24 +197,35 @@ struct BuiltinFunctionOld: FunctionObject {
     Value (*code)(ExecutionContext *);
 
     BuiltinFunctionOld(ExecutionContext *scope, String *name, Value (*code)(ExecutionContext *));
-    virtual Value call(ExecutionContext *context, Value thisObject, Value *args, int argc);
-    virtual Value construct(ExecutionContext *ctx, Value *, int);
+
+    static Value construct(Managed *, ExecutionContext *context, Value *args, int argc);
+    static Value call(Managed *that, ExecutionContext *, const Value &, Value *, int);
+
+protected:
+    static const ManagedVTable static_vtbl;
 };
 
 struct BuiltinFunction: FunctionObject {
     Value (*code)(ExecutionContext *parentContext, Value thisObject, Value *args, int argc);
 
     BuiltinFunction(ExecutionContext *scope, String *name, Value (*code)(ExecutionContext *, Value, Value *, int));
-    virtual Value call(ExecutionContext *context, Value thisObject, Value *args, int argc);
-    virtual Value construct(ExecutionContext *ctx, Value *, int);
+
+    static Value construct(Managed *, ExecutionContext *context, Value *args, int argc);
+    static Value call(Managed *that, ExecutionContext *, const Value &, Value *, int);
+
+protected:
+    static const ManagedVTable static_vtbl;
 };
 
 struct ScriptFunction: FunctionObject {
     ScriptFunction(ExecutionContext *scope, VM::Function *function);
-    virtual ~ScriptFunction();
+    ~ScriptFunction();
 
-    virtual Value call(ExecutionContext *context, Value thisObject, Value *args, int argc);
-    virtual Value construct(ExecutionContext *context, Value *args, int argc);
+    static Value construct(Managed *, ExecutionContext *context, Value *args, int argc);
+    static Value call(Managed *that, ExecutionContext *, const Value &, Value *, int);
+
+protected:
+    static const ManagedVTable static_vtbl;
 };
 
 struct BoundFunction: FunctionObject {
@@ -214,10 +234,10 @@ struct BoundFunction: FunctionObject {
     QVector<Value> boundArgs;
 
     BoundFunction(ExecutionContext *scope, FunctionObject *target, Value boundThis, const QVector<Value> &boundArgs);
-    virtual ~BoundFunction() {}
+    ~BoundFunction() {}
 
-    virtual Value call(ExecutionContext *context, Value thisObject, Value *args, int argc);
-    virtual Value construct(ExecutionContext *context, Value *args, int argc);
+    static Value construct(Managed *, ExecutionContext *context, Value *args, int argc);
+    static Value call(Managed *that, ExecutionContext *, const Value &, Value *, int);
 
     static const ManagedVTable static_vtbl;
     static void markObjects(Managed *that);
index 384bce5..2bba71e 100644 (file)
@@ -339,10 +339,12 @@ static QString decode(const QString &input, DecodeMode decodeMode, bool *ok)
     return QString();
 }
 
+DEFINE_MANAGED_VTABLE(EvalFunction);
 
 EvalFunction::EvalFunction(ExecutionContext *scope)
     : FunctionObject(scope)
 {
+    vtbl = &static_vtbl;
     name = scope->engine->id_eval;
     defineReadonlyProperty(scope->engine->id_length, Value::fromInt32(1));
 }
@@ -402,17 +404,17 @@ Value EvalFunction::evalCall(ExecutionContext *context, Value /*thisObject*/, Va
 }
 
 
-Value EvalFunction::call(ExecutionContext *context, Value thisObject, Value *args, int argc)
+Value EvalFunction::call(Managed *that, ExecutionContext *context, const Value &thisObject, Value *args, int argc)
 {
     // indirect call
-    return evalCall(context, thisObject, args, argc, false);
+    return static_cast<EvalFunction *>(that)->evalCall(context, thisObject, args, argc, false);
 }
 
-Value EvalFunction::construct(ExecutionContext *ctx, Value *, int)
-{
-    ctx->throwTypeError();
-    return Value::undefinedValue();
-}
+//Value EvalFunction::construct(ExecutionContext *ctx, Value *, int)
+//{
+//    ctx->throwTypeError();
+//    return Value::undefinedValue();
+//}
 
 QQmlJS::VM::Function *EvalFunction::parseSource(QQmlJS::VM::ExecutionContext *ctx,
                                                 const QString &fileName, const QString &source,
index e15b7b2..2aebad1 100644 (file)
@@ -59,10 +59,13 @@ struct Q_V4_EXPORT EvalFunction : FunctionObject
                                              QQmlJS::Codegen::Mode mode, bool strictMode,
                                              bool inheritContext);
 
-    virtual Value call(ExecutionContext *context, Value thisObject, Value *args, int argc);
     Value evalCall(ExecutionContext *context, Value thisObject, Value *args, int argc, bool directCall);
 
-    Value construct(ExecutionContext *ctx, Value *, int);
+    using Managed::construct;
+    static Value call(Managed *that, ExecutionContext *, const Value &, Value *, int);
+
+protected:
+    static const ManagedVTable static_vtbl;
 };
 
 struct GlobalFunctions
index fe71be4..ea4004e 100644 (file)
@@ -47,8 +47,11 @@ using namespace QQmlJS::VM;
 
 const ManagedVTable Managed::static_vtbl =
 {
+    "Managed",
     0 /*markObjects*/,
-    Managed::hasInstance,
+    hasInstance,
+    construct,
+    call,
     ManagedVTable::EndOfVTable
 };
 
@@ -151,3 +154,13 @@ bool Managed::hasInstance(Managed *, ExecutionContext *ctx, const Value &)
 {
     ctx->throwTypeError();
 }
+
+Value Managed::construct(Managed *, ExecutionContext *context, Value *, int)
+{
+    context->throwTypeError();
+}
+
+Value Managed::call(Managed *, ExecutionContext *context, const Value &, Value *, int)
+{
+    context->throwTypeError();
+}
index 979b308..54c8cf4 100644 (file)
@@ -50,7 +50,6 @@
 QT_BEGIN_NAMESPACE
 
 namespace QQmlJS {
-
 namespace VM {
 
 class MemoryManager;
@@ -80,11 +79,26 @@ struct ManagedVTable
     enum _EndOfVTable {
         EndOfVTable
     };
+    const char *className;
     void (*markObjects)(Managed *);
     bool (*hasInstance)(Managed *, ExecutionContext *ctx, const Value &value);
+    Value (*construct)(Managed *, ExecutionContext *context, Value *args, int argc);
+    Value (*call)(Managed *, ExecutionContext *context, const Value &thisObject, Value *args, int argc);
     _EndOfVTable endofVTable;
 };
 
+#define DEFINE_MANAGED_VTABLE(classname) \
+const ManagedVTable classname::static_vtbl =    \
+{                                               \
+    #classname,                                 \
+    markObjects,                                \
+    hasInstance,                                \
+    construct,                                  \
+    call,                                       \
+    ManagedVTable::EndOfVTable                  \
+}
+
+
 struct Q_V4_EXPORT Managed
 {
 private:
@@ -160,8 +174,12 @@ public:
     inline bool hasInstance(ExecutionContext *ctx, const Value &v) {
         return vtbl->hasInstance(this, ctx, v);
     }
+    inline Value construct(ExecutionContext *context, Value *args, int argc);
+    inline Value call(ExecutionContext *context, const Value &thisObject, Value *args, int argc);
 
     static bool hasInstance(Managed *that, ExecutionContext *ctx, const Value &value);
+    static Value construct(Managed *, ExecutionContext *context, Value *, int);
+    static Value call(Managed *, ExecutionContext *, const Value &, Value *, int);
 
 protected:
 
index 0601da6..4f42ef3 100644 (file)
 
 using namespace QQmlJS::VM;
 
+DEFINE_MANAGED_VTABLE(NumberCtor);
 
 NumberCtor::NumberCtor(ExecutionContext *scope)
     : FunctionObject(scope)
 {
+    vtbl = &static_vtbl;
 }
 
-Value NumberCtor::construct(ExecutionContext *ctx, Value *args, int argc)
+Value NumberCtor::construct(Managed *, ExecutionContext *ctx, Value *args, int argc)
 {
     double d = argc ? args[0].toNumber(ctx) : 0.;
     return Value::fromObject(ctx->engine->newNumberObject(Value::fromDouble(d)));
 }
 
-Value NumberCtor::call(ExecutionContext *parentCtx, Value thisObject, Value *argv, int argc)
+Value NumberCtor::call(Managed *m, ExecutionContext *parentCtx, const Value &thisObject, Value *argv, int argc)
 {
     double d = argc ? argv[0].toNumber(parentCtx) : 0.;
     return Value::fromDouble(d);
index e9125ab..4677a77 100644 (file)
@@ -54,8 +54,11 @@ struct NumberCtor: FunctionObject
 {
     NumberCtor(ExecutionContext *scope);
 
-    virtual Value construct(ExecutionContext *ctx, Value *args, int argc);
-    virtual Value call(ExecutionContext *parentCtx, Value thisObject, Value *argv, int argc);
+    static Value construct(Managed *that, ExecutionContext *context, Value *args, int argc);
+    static Value call(Managed *that, ExecutionContext *, const Value &, Value *, int);
+
+protected:
+    static const ManagedVTable static_vtbl;
 };
 
 struct NumberPrototype: NumberObject
index 46debdb..0d68f9e 100644 (file)
@@ -64,6 +64,7 @@
 
 using namespace QQmlJS::VM;
 
+DEFINE_MANAGED_VTABLE(Object);
 
 Object::Object(ExecutionEngine *engine)
     : prototype(0)
@@ -985,13 +986,6 @@ void Object::markArrayObjects() const
     }
 }
 
-const ManagedVTable Object::static_vtbl =
-{
-    Object::markObjects,
-    Managed::hasInstance,
-    ManagedVTable::EndOfVTable
-};
-
 void ArrayObject::init(ExecutionContext *context)
 {
     type = Type_ArrayObject;
@@ -1006,6 +1000,7 @@ void ArrayObject::init(ExecutionContext *context)
 }
 
 
+DEFINE_MANAGED_VTABLE(ForEachIteratorObject);
 
 void ForEachIteratorObject::markObjects(Managed *that)
 {
@@ -1014,10 +1009,3 @@ void ForEachIteratorObject::markObjects(Managed *that)
     if (o->it.object)
         o->it.object->mark();
 }
-
-const ManagedVTable ForEachIteratorObject::static_vtbl =
-{
-    ForEachIteratorObject::markObjects,
-    Managed::hasInstance,
-    ManagedVTable::EndOfVTable
-};
index de8b7ff..6e9f51e 100644 (file)
 using namespace QQmlJS::VM;
 
 
-//
-// Object
-//
+DEFINE_MANAGED_VTABLE(ObjectCtor);
+
 ObjectCtor::ObjectCtor(ExecutionContext *scope)
     : FunctionObject(scope)
 {
+    vtbl = &static_vtbl;
 }
 
-Value ObjectCtor::construct(ExecutionContext *ctx, Value *args, int argc)
+Value ObjectCtor::construct(Managed *that, ExecutionContext *ctx, Value *args, int argc)
 {
+    ObjectCtor *ctor = static_cast<ObjectCtor *>(that);
     if (!argc || args[0].isUndefined() || args[0].isNull()) {
         Object *obj = ctx->engine->newObject();
-        Value proto = __get__(ctx, ctx->engine->id_prototype);
+        Value proto = ctor->__get__(ctx, ctx->engine->id_prototype);
         if (proto.isObject())
             obj->prototype = proto.objectValue();
         return Value::fromObject(obj);
@@ -91,7 +92,7 @@ Value ObjectCtor::construct(ExecutionContext *ctx, Value *args, int argc)
     return __qmljs_to_object(args[0], ctx);
 }
 
-Value ObjectCtor::call(ExecutionContext *ctx, Value /*thisObject*/, Value *args, int argc)
+Value ObjectCtor::call(Managed *, ExecutionContext *ctx, const Value &/*thisObject*/, Value *args, int argc)
 {
     if (!argc || args[0].isUndefined() || args[0].isNull())
         return Value::fromObject(ctx->engine->newObject());
index 6341128..25387c0 100644 (file)
@@ -54,8 +54,11 @@ struct ObjectCtor: FunctionObject
 {
     ObjectCtor(ExecutionContext *scope);
 
-    virtual Value construct(ExecutionContext *ctx, Value *args, int argc);
-    virtual Value call(ExecutionContext *ctx, Value, Value *args, int argc);
+    static Value construct(Managed *that, ExecutionContext *context, Value *args, int argc);
+    static Value call(Managed *that, ExecutionContext *, const Value &, Value *, int);
+
+protected:
+    static const ManagedVTable static_vtbl;
 };
 
 struct ObjectPrototype: Object
index 19aee55..ccb4d3b 100644 (file)
@@ -91,14 +91,15 @@ PropertyDescriptor *RegExpObject::lastIndexProperty(ExecutionContext *ctx)
     return &memberData[0];
 }
 
-
+DEFINE_MANAGED_VTABLE(RegExpCtor);
 
 RegExpCtor::RegExpCtor(ExecutionContext *scope)
     : FunctionObject(scope)
 {
+    vtbl = &static_vtbl;
 }
 
-Value RegExpCtor::construct(ExecutionContext *ctx, Value *argv, int argc)
+Value RegExpCtor::construct(Managed *, ExecutionContext *ctx, Value *argv, int argc)
 {
     Value r = argc > 0 ? argv[0] : Value::undefinedValue();
     Value f = argc > 1 ? argv[1] : Value::undefinedValue();
@@ -142,14 +143,14 @@ Value RegExpCtor::construct(ExecutionContext *ctx, Value *argv, int argc)
     return Value::fromObject(o);
 }
 
-Value RegExpCtor::call(ExecutionContext *ctx, Value thisObject, Value *argv, int argc)
+Value RegExpCtor::call(Managed *that, ExecutionContext *ctx, const Value &thisObject, Value *argv, int argc)
 {
     if (argc > 0 && argv[0].asRegExpObject()) {
         if (argc == 1 || argv[1].isUndefined())
             return argv[0];
     }
 
-    return construct(ctx, argv, argc);
+    return construct(that, ctx, argv, argc);
 }
 
 void RegExpPrototype::init(ExecutionContext *ctx, const Value &ctor)
index d310374..65df03c 100644 (file)
@@ -76,8 +76,11 @@ struct RegExpCtor: FunctionObject
 {
     RegExpCtor(ExecutionContext *scope);
 
-    virtual Value construct(ExecutionContext *ctx, Value *argv, int argc);
-    virtual Value call(ExecutionContext *ctx, Value thisObject, Value *argv, int argc);
+    static Value construct(Managed *that, ExecutionContext *context, Value *args, int argc);
+    static Value call(Managed *that, ExecutionContext *, const Value &, Value *, int);
+
+protected:
+    static const ManagedVTable static_vtbl;
 };
 
 struct RegExpPrototype: RegExpObject
index e8ec9e6..9829054 100644 (file)
@@ -75,6 +75,8 @@
 
 using namespace QQmlJS::VM;
 
+DEFINE_MANAGED_VTABLE(StringObject);
+
 StringObject::StringObject(ExecutionContext *ctx, const Value &value)
     : Object(ctx->engine), value(value)
 {
@@ -108,18 +110,15 @@ void StringObject::markObjects(Managed *that)
     Object::markObjects(that);
 }
 
-const ManagedVTable StringObject::static_vtbl =
-{
-    StringObject::markObjects
-};
-
+DEFINE_MANAGED_VTABLE(StringCtor);
 
 StringCtor::StringCtor(ExecutionContext *scope)
     : FunctionObject(scope)
 {
+    vtbl = &static_vtbl;
 }
 
-Value StringCtor::construct(ExecutionContext *ctx, Value *argv, int argc)
+Value StringCtor::construct(Managed *, ExecutionContext *ctx, Value *argv, int argc)
 {
     Value value;
     if (argc)
@@ -129,7 +128,7 @@ Value StringCtor::construct(ExecutionContext *ctx, Value *argv, int argc)
     return Value::fromObject(ctx->engine->newStringObject(ctx, value));
 }
 
-Value StringCtor::call(ExecutionContext *parentCtx, Value thisObject, Value *argv, int argc)
+Value StringCtor::call(Managed *, ExecutionContext *parentCtx, const Value &thisObject, Value *argv, int argc)
 {
     Value value;
     if (argc)
index 5c295e2..0ee72a0 100644 (file)
@@ -66,8 +66,11 @@ struct StringCtor: FunctionObject
 {
     StringCtor(ExecutionContext *scope);
 
-    virtual Value construct(ExecutionContext *ctx, Value *argv, int argc);
-    virtual Value call(ExecutionContext *parentCtx, Value thisObject, Value *argv, int argc);
+    static Value construct(Managed *that, ExecutionContext *context, Value *args, int argc);
+    static Value call(Managed *that, ExecutionContext *, const Value &, Value *, int);
+
+protected:
+    static const ManagedVTable static_vtbl;
 };
 
 struct StringPrototype: StringObject
index 7a6e736..998a315 100644 (file)
@@ -74,10 +74,11 @@ using namespace QQmlJS::VM;
 struct Print: FunctionObject
 {
     Print(ExecutionContext *scope): FunctionObject(scope) {
+        vtbl = &static_vtbl;
         name = scope->engine->newString("print");
     }
 
-    virtual Value call(ExecutionContext *ctx, Value, Value *args, int argc)
+    static Value call(Managed *, ExecutionContext *ctx, const Value &, Value *args, int argc)
     {
         for (int i = 0; i < argc; ++i) {
             String *s = args[i].toString(ctx);
@@ -88,22 +89,31 @@ struct Print: FunctionObject
         std::cout << std::endl;
         return Value::undefinedValue();
     }
+
+    static const ManagedVTable static_vtbl;
 };
 
+DEFINE_MANAGED_VTABLE(Print);
+
 struct GC: public FunctionObject
 {
     GC(ExecutionContext* scope)
         : FunctionObject(scope)
     {
+        vtbl = &static_vtbl;
         name = scope->engine->newString("gc");
     }
-    virtual Value call(ExecutionContext *ctx, Value, Value *, int)
+    static Value call(Managed *, ExecutionContext *ctx, const Value &, Value *args, int argc)
     {
         ctx->engine->memoryManager->runGC();
         return Value::undefinedValue();
     }
+
+    static const ManagedVTable static_vtbl;
 };
 
+DEFINE_MANAGED_VTABLE(GC);
+
 } // builtins
 
 static void showException(QQmlJS::VM::ExecutionContext *ctx)