From: Lars Knoll Date: Thu, 14 Feb 2013 13:07:57 +0000 (+0100) Subject: Move call/construct over into the new vtable. X-Git-Tag: upstream/5.2.1~669^2~659^2~248 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1056456cb580d6eed1c6344c4114695ef315d7fd;p=platform%2Fupstream%2Fqtdeclarative.git Move call/construct over into the new vtable. Change-Id: I4f58a1fac25440695bdc62a49adb51a887616a5c Reviewed-by: Simon Hausmann --- diff --git a/src/v4/qmljs_value.h b/src/v4/qmljs_value.h index 7c83af5..2675d55 100644 --- a/src/v4/qmljs_value.h +++ b/src/v4/qmljs_value.h @@ -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 diff --git a/src/v4/qv4argumentsobject.cpp b/src/v4/qv4argumentsobject.cpp index f805aa6..d1791e0 100644 --- a/src/v4/qv4argumentsobject.cpp +++ b/src/v4/qv4argumentsobject.cpp @@ -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(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(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(); } diff --git a/src/v4/qv4argumentsobject.h b/src/v4/qv4argumentsobject.h index fe62bf7..acbcc75 100644 --- a/src/v4/qv4argumentsobject.h +++ b/src/v4/qv4argumentsobject.h @@ -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; }; diff --git a/src/v4/qv4arrayobject.cpp b/src/v4/qv4arrayobject.cpp index 2999ce0..8117a65 100644 --- a/src/v4/qv4arrayobject.cpp +++ b/src/v4/qv4arrayobject.cpp @@ -44,12 +44,15 @@ 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) diff --git a/src/v4/qv4arrayobject.h b/src/v4/qv4arrayobject.h index 48250dd..1e61600 100644 --- a/src/v4/qv4arrayobject.h +++ b/src/v4/qv4arrayobject.h @@ -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 diff --git a/src/v4/qv4booleanobject.cpp b/src/v4/qv4booleanobject.cpp index 02fab7b..b2a72f1 100644 --- a/src/v4/qv4booleanobject.cpp +++ b/src/v4/qv4booleanobject.cpp @@ -43,18 +43,21 @@ 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); diff --git a/src/v4/qv4booleanobject.h b/src/v4/qv4booleanobject.h index da9105e..68976f3 100644 --- a/src/v4/qv4booleanobject.h +++ b/src/v4/qv4booleanobject.h @@ -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 diff --git a/src/v4/qv4dateobject.cpp b/src/v4/qv4dateobject.cpp index de614cc..77ed279 100644 --- a/src/v4/qv4dateobject.cpp +++ b/src/v4/qv4dateobject.cpp @@ -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)); diff --git a/src/v4/qv4dateobject.h b/src/v4/qv4dateobject.h index b4916ec..946240e 100644 --- a/src/v4/qv4dateobject.h +++ b/src/v4/qv4dateobject.h @@ -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 diff --git a/src/v4/qv4errorobject.cpp b/src/v4/qv4errorobject.cpp index 8ad7d5e..418dbb7 100644 --- a/src/v4/qv4errorobject.cpp +++ b/src/v4/qv4errorobject.cpp @@ -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())); } diff --git a/src/v4/qv4errorobject.h b/src/v4/qv4errorobject.h index 734ee3f..2be3242 100644 --- a/src/v4/qv4errorobject.h +++ b/src/v4/qv4errorobject.h @@ -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); } }; diff --git a/src/v4/qv4functionobject.cpp b/src/v4/qv4functionobject.cpp index 991695c..caa6987 100644 --- a/src/v4/qv4functionobject.cpp +++ b/src/v4/qv4functionobject.cpp @@ -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(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(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 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(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(needsActivation ? malloc(size) : alloca(size)); + uint size = requiredMemoryForExecutionContect(f, argc); + ExecutionContext *ctx = static_cast(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(needsActivation ? malloc(size) : alloca(size)); + ScriptFunction *f = static_cast(that); + assert(f->function->code); + uint size = requiredMemoryForExecutionContect(f, argc); + ExecutionContext *ctx = static_cast(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(needsActivation ? malloc(size) : alloca(size)); + BuiltinFunctionOld *f = static_cast(that); + uint size = requiredMemoryForExecutionContect(f, argc); + ExecutionContext *ctx = static_cast(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(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 &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(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(that); + Value *newArgs = static_cast(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(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(that); + Value *newArgs = static_cast(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) diff --git a/src/v4/qv4functionobject.h b/src/v4/qv4functionobject.h index 9d55944..cf99b78 100644 --- a/src/v4/qv4functionobject.h +++ b/src/v4/qv4functionobject.h @@ -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 boundArgs; BoundFunction(ExecutionContext *scope, FunctionObject *target, Value boundThis, const QVector &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); diff --git a/src/v4/qv4globalobject.cpp b/src/v4/qv4globalobject.cpp index 384bce5..2bba71e 100644 --- a/src/v4/qv4globalobject.cpp +++ b/src/v4/qv4globalobject.cpp @@ -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(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, diff --git a/src/v4/qv4globalobject.h b/src/v4/qv4globalobject.h index e15b7b2..2aebad1 100644 --- a/src/v4/qv4globalobject.h +++ b/src/v4/qv4globalobject.h @@ -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 diff --git a/src/v4/qv4managed.cpp b/src/v4/qv4managed.cpp index fe71be4..ea4004e 100644 --- a/src/v4/qv4managed.cpp +++ b/src/v4/qv4managed.cpp @@ -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(); +} diff --git a/src/v4/qv4managed.h b/src/v4/qv4managed.h index 979b308..54c8cf4 100644 --- a/src/v4/qv4managed.h +++ b/src/v4/qv4managed.h @@ -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: diff --git a/src/v4/qv4numberobject.cpp b/src/v4/qv4numberobject.cpp index 0601da6..4f42ef3 100644 --- a/src/v4/qv4numberobject.cpp +++ b/src/v4/qv4numberobject.cpp @@ -48,19 +48,21 @@ 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); diff --git a/src/v4/qv4numberobject.h b/src/v4/qv4numberobject.h index e9125ab..4677a77 100644 --- a/src/v4/qv4numberobject.h +++ b/src/v4/qv4numberobject.h @@ -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 diff --git a/src/v4/qv4object.cpp b/src/v4/qv4object.cpp index 46debdb..0d68f9e 100644 --- a/src/v4/qv4object.cpp +++ b/src/v4/qv4object.cpp @@ -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 -}; diff --git a/src/v4/qv4objectproto.cpp b/src/v4/qv4objectproto.cpp index de8b7ff..6e9f51e 100644 --- a/src/v4/qv4objectproto.cpp +++ b/src/v4/qv4objectproto.cpp @@ -71,19 +71,20 @@ 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(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()); diff --git a/src/v4/qv4objectproto.h b/src/v4/qv4objectproto.h index 6341128..25387c0 100644 --- a/src/v4/qv4objectproto.h +++ b/src/v4/qv4objectproto.h @@ -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 diff --git a/src/v4/qv4regexpobject.cpp b/src/v4/qv4regexpobject.cpp index 19aee55..ccb4d3b 100644 --- a/src/v4/qv4regexpobject.cpp +++ b/src/v4/qv4regexpobject.cpp @@ -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) diff --git a/src/v4/qv4regexpobject.h b/src/v4/qv4regexpobject.h index d310374..65df03c 100644 --- a/src/v4/qv4regexpobject.h +++ b/src/v4/qv4regexpobject.h @@ -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 diff --git a/src/v4/qv4stringobject.cpp b/src/v4/qv4stringobject.cpp index e8ec9e6..9829054 100644 --- a/src/v4/qv4stringobject.cpp +++ b/src/v4/qv4stringobject.cpp @@ -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) diff --git a/src/v4/qv4stringobject.h b/src/v4/qv4stringobject.h index 5c295e2..0ee72a0 100644 --- a/src/v4/qv4stringobject.h +++ b/src/v4/qv4stringobject.h @@ -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 diff --git a/tools/v4/main.cpp b/tools/v4/main.cpp index 7a6e736..998a315 100644 --- a/tools/v4/main.cpp +++ b/tools/v4/main.cpp @@ -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)