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
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)
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);
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);
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();
}
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
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;
};
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;
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)
{
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
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);
{
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
#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;
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));
{
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
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()));
}
{
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;
};
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); }
};
using namespace QQmlJS::VM;
+DEFINE_MANAGED_VTABLE(FunctionObject);
+
Function::~Function()
{
delete[] codeData;
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();
}
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;
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));
}
// 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)
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);
{
}
-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())
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)
*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)
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;
{
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
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 {
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);
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));
}
}
-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,
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
const ManagedVTable Managed::static_vtbl =
{
+ "Managed",
0 /*markObjects*/,
- Managed::hasInstance,
+ hasInstance,
+ construct,
+ call,
ManagedVTable::EndOfVTable
};
{
ctx->throwTypeError();
}
+
+Value Managed::construct(Managed *, ExecutionContext *context, Value *, int)
+{
+ context->throwTypeError();
+}
+
+Value Managed::call(Managed *, ExecutionContext *context, const Value &, Value *, int)
+{
+ context->throwTypeError();
+}
QT_BEGIN_NAMESPACE
namespace QQmlJS {
-
namespace VM {
class MemoryManager;
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:
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:
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);
{
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
using namespace QQmlJS::VM;
+DEFINE_MANAGED_VTABLE(Object);
Object::Object(ExecutionEngine *engine)
: prototype(0)
}
}
-const ManagedVTable Object::static_vtbl =
-{
- Object::markObjects,
- Managed::hasInstance,
- ManagedVTable::EndOfVTable
-};
-
void ArrayObject::init(ExecutionContext *context)
{
type = Type_ArrayObject;
}
+DEFINE_MANAGED_VTABLE(ForEachIteratorObject);
void ForEachIteratorObject::markObjects(Managed *that)
{
if (o->it.object)
o->it.object->mark();
}
-
-const ManagedVTable ForEachIteratorObject::static_vtbl =
-{
- ForEachIteratorObject::markObjects,
- Managed::hasInstance,
- ManagedVTable::EndOfVTable
-};
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);
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());
{
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
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();
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)
{
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
using namespace QQmlJS::VM;
+DEFINE_MANAGED_VTABLE(StringObject);
+
StringObject::StringObject(ExecutionContext *ctx, const Value &value)
: Object(ctx->engine), value(value)
{
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)
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)
{
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
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);
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)