foreach (IR::Function *function, module.functions) {
if (function->name && ! function->name->isEmpty()) {
globalObject->put(vm->identifier(*function->name),
- VM::Value::object(ctx, new VM::ScriptFunction(ctx, function)));
+ VM::Value::object(ctx, ctx->engine->newScriptFunction(ctx, function)));
}
}
codeByName.value(QLatin1String("%entry"))->code(ctx);
using namespace QQmlJS::VM;
+String *String::get(Context *ctx, const QString &s)
+{
+ return ctx->engine->newString(s);
+}
+
Object::~Object()
{
delete members;
void Object::setProperty(Context *ctx, const QString &name, void (*code)(Context *), int count)
{
Q_UNUSED(count);
- setProperty(ctx, name, Value::object(ctx, new NativeFunction(ctx, code)));
+ setProperty(ctx, name, Value::object(ctx, ctx->engine->newNativeFunction(ctx, code)));
}
bool Object::get(String *name, Value *result)
void FunctionObject::construct(Context *ctx)
{
- __qmljs_init_object(ctx, &ctx->thisObject, new Object());
+ __qmljs_init_object(ctx, &ctx->thisObject, ctx->engine->newObject());
call(ctx);
}
void ScriptFunction::construct(VM::Context *ctx)
{
- __qmljs_init_object(ctx, &ctx->thisObject, new Object());
+ __qmljs_init_object(ctx, &ctx->thisObject, ctx->engine->newObject());
function->code(ctx);
}
ExecutionEngine::ExecutionEngine()
{
- rootContext = new VM::Context;
+ rootContext = newContext();
rootContext->init(this);
//
// set up the global object
//
- VM::Object *glo = new VM::ArgumentsObject(rootContext);
+ VM::Object *glo = newArgumentsObject(rootContext);
__qmljs_init_object(rootContext, &globalObject, glo);
__qmljs_init_object(rootContext, &rootContext->activation, glo);
glo->put(VM::String::get(rootContext, QLatin1String("Object")), objectCtor);
glo->put(VM::String::get(rootContext, QLatin1String("String")), stringCtor);
glo->put(VM::String::get(rootContext, QLatin1String("Number")), numberCtor);
- glo->put(VM::String::get(rootContext, QLatin1String("Math")), Value::object(rootContext, new MathObject(rootContext)));
+ glo->put(VM::String::get(rootContext, QLatin1String("Math")), Value::object(rootContext, newMathObject(rootContext)));
+}
+
+Context *ExecutionEngine::newContext()
+{
+ return new Context();
}
String *ExecutionEngine::identifier(const QString &s)
{
String *&id = identifiers[s];
if (! id)
- id = new String(s);
+ id = newString(s);
return id;
}
+
+FunctionObject *ExecutionEngine::newNativeFunction(Context *scope, void (*code)(Context *))
+{
+ return new NativeFunction(scope, code);
+}
+
+FunctionObject *ExecutionEngine::newScriptFunction(Context *scope, IR::Function *function)
+{
+ return new ScriptFunction(scope, function);
+}
+
+Object *ExecutionEngine::newObject()
+{
+ return new Object();
+}
+
+FunctionObject *ExecutionEngine::newObjectCtor(Context *ctx)
+{
+ return new ObjectCtor(ctx);
+}
+
+Object *ExecutionEngine::newObjectPrototype(Context *ctx, FunctionObject *proto)
+{
+ return new ObjectPrototype(ctx, proto);
+}
+
+String *ExecutionEngine::newString(const QString &s)
+{
+ return new String(s);
+}
+
+Object *ExecutionEngine::newStringObject(const Value &value)
+{
+ return new StringObject(value);
+}
+
+FunctionObject *ExecutionEngine::newStringCtor(Context *ctx)
+{
+ return new StringCtor(ctx);
+}
+
+Object *ExecutionEngine::newStringPrototype(Context *ctx, FunctionObject *proto)
+{
+ return new StringPrototype(ctx, proto);
+}
+
+Object *ExecutionEngine::newNumberObject(const Value &value)
+{
+ return new NumberObject(value);
+}
+
+FunctionObject *ExecutionEngine::newNumberCtor(Context *ctx)
+{
+ return new NumberCtor(ctx);
+}
+
+Object *ExecutionEngine::newNumberPrototype(Context *ctx, FunctionObject *proto)
+{
+ return new NumberPrototype(ctx, proto);
+}
+
+Object *ExecutionEngine::newBooleanObject(const Value &value)
+{
+ return new BooleanObject(value);
+}
+
+Object *ExecutionEngine::newErrorObject(const Value &value)
+{
+ return new ErrorObject(value);
+}
+
+Object *ExecutionEngine::newMathObject(Context *ctx)
+{
+ return new MathObject(ctx);
+}
+
+Object *ExecutionEngine::newArgumentsObject(Context *ctx)
+{
+ return new ArgumentsObject(ctx);
+}
return _hashValue;
}
- static String *get(Context *ctx, const QString &s) {
- Q_UNUSED(ctx);
- return new String(s);
- }
+ static String *get(Context *ctx, const QString &s);
private:
QString _text;
};
struct ErrorObject: Object {
- String *message;
- ErrorObject(String *message): message(message) {}
+ Value message;
+ ErrorObject(const Value &message): message(message) {}
};
struct ArgumentsObject: Object {
ExecutionEngine();
+ Context *newContext();
+
String *identifier(const QString &s);
+
+ FunctionObject *newNativeFunction(Context *scope, void (*code)(Context *));
+ FunctionObject *newScriptFunction(Context *scope, IR::Function *function);
+
+ Object *newObject();
+ FunctionObject *newObjectCtor(Context *ctx);
+ Object *newObjectPrototype(Context *ctx, FunctionObject *proto);
+
+ String *newString(const QString &s);
+ Object *newStringObject(const Value &value);
+ FunctionObject *newStringCtor(Context *ctx);
+ Object *newStringPrototype(Context *ctx, FunctionObject *proto);
+
+ Object *newNumberObject(const Value &value);
+ FunctionObject *newNumberCtor(Context *ctx);
+ Object *newNumberPrototype(Context *ctx, FunctionObject *proto);
+
+ Object *newBooleanObject(const Value &value);
+ Object *newErrorObject(const Value &value);
+ Object *newMathObject(Context *ctx);
+ Object *newArgumentsObject(Context *ctx);
};
} // namespace VM
void __qmljs_init_closure(Context *ctx, Value *result, IR::Function *clos)
{
- __qmljs_init_object(ctx, result, new ScriptFunction(ctx, clos));
+ __qmljs_init_object(ctx, result, ctx->engine->newScriptFunction(ctx, clos));
}
void __qmljs_string_literal_undefined(Context *ctx, Value *result)
void __qmljs_throw_type_error(Context *ctx, Value *result)
{
- __qmljs_init_object(ctx, result, new ErrorObject(String::get(ctx, QLatin1String("type error"))));
+ __qmljs_init_object(ctx, result, ctx->engine->newErrorObject(Value::string(ctx, QLatin1String("type error"))));
}
void __qmljs_new_boolean_object(Context *ctx, Value *result, bool boolean)
{
Value value;
__qmljs_init_boolean(ctx, &value, boolean);
- __qmljs_init_object(ctx, result, new BooleanObject(value));
+ __qmljs_init_object(ctx, result, ctx->engine->newBooleanObject(value));
}
void __qmljs_new_number_object(Context *ctx, Value *result, double number)
{
Value value;
__qmljs_init_number(ctx, &value, number);
- __qmljs_init_object(ctx, result, new NumberObject(value));
+ __qmljs_init_object(ctx, result, ctx->engine->newNumberObject(value));
result->objectValue->prototype = ctx->engine->numberPrototype.objectValue;
}
{
Value value;
__qmljs_init_string(ctx, &value, string);
- __qmljs_init_object(ctx, result, new StringObject(value));
+ __qmljs_init_object(ctx, result, ctx->engine->newStringObject(value));
result->objectValue->prototype = ctx->engine->stringPrototype.objectValue;
}
if (func.type == OBJECT_TYPE) {
if (FunctionObject *f = func.objectValue->asFunctionObject()) {
Context k;
- Context *ctx = f->needsActivation ? new Context : &k;
+ Context *ctx = f->needsActivation ? context->engine->newContext() : &k;
ctx->init(context->engine);
ctx->parent = f->scope;
if (f->needsActivation)
- __qmljs_init_object(ctx, &ctx->activation, new ArgumentsObject(ctx));
+ __qmljs_init_object(ctx, &ctx->activation, ctx->engine->newArgumentsObject(ctx));
else
__qmljs_init_null(ctx, &ctx->activation);
ctx->thisObject = thisObject;
if (func->type == OBJECT_TYPE) {
if (FunctionObject *f = func->objectValue->asFunctionObject()) {
Context k;
- Context *ctx = f->needsActivation ? new Context : &k;
+ Context *ctx = f->needsActivation ? context->engine->newContext() : &k;
ctx->init(context->engine);
ctx->parent = f->scope;
if (f->needsActivation)
- __qmljs_init_object(ctx, &ctx->activation, new ArgumentsObject(ctx));
+ __qmljs_init_object(ctx, &ctx->activation, ctx->engine->newArgumentsObject(ctx));
else
__qmljs_init_null(ctx, &ctx->activation);
__qmljs_init_null(ctx, &ctx->thisObject);
if (func->type == OBJECT_TYPE) {
if (FunctionObject *f = func->objectValue->asFunctionObject()) {
Context k;
- Context *ctx = f->needsActivation ? new Context : &k;
+ Context *ctx = f->needsActivation ? context->engine->newContext() : &k;
ctx->init(context->engine);
ctx->parent = f->scope;
if (f->needsActivation)
- __qmljs_init_object(ctx, &ctx->activation, new ArgumentsObject(ctx));
+ __qmljs_init_object(ctx, &ctx->activation, ctx->engine->newArgumentsObject(ctx));
else
__qmljs_init_null(ctx, &ctx->activation);
__qmljs_init_null(ctx, &ctx->thisObject);
if (func.type == OBJECT_TYPE) {
if (FunctionObject *f = func.objectValue->asFunctionObject()) {
Context k;
- Context *ctx = f->needsActivation ? new Context : &k;
+ Context *ctx = f->needsActivation ? context->engine->newContext() : &k;
ctx->init(context->engine);
ctx->parent = f->scope;
if (f->needsActivation)
- __qmljs_init_object(ctx, &ctx->activation, new ArgumentsObject(ctx));
+ __qmljs_init_object(ctx, &ctx->activation, ctx->engine->newArgumentsObject(ctx));
else
__qmljs_init_null(ctx, &ctx->activation);
ctx->thisObject = thisObject;
Value ObjectCtor::create(ExecutionEngine *engine)
{
Context *ctx = engine->rootContext;
- ObjectCtor *ctor = new ObjectCtor(ctx);
- ctor->setProperty(ctx, QLatin1String("prototype"), Value::object(ctx, new ObjectPrototype(ctx, ctor)));
+ FunctionObject *ctor = ctx->engine->newObjectCtor(ctx);
+ ctor->setProperty(ctx, QLatin1String("prototype"), Value::object(ctx, ctx->engine->newObjectPrototype(ctx, ctor)));
return Value::object(ctx, ctor);
}
void ObjectCtor::construct(Context *ctx)
{
- __qmljs_init_object(ctx, &ctx->thisObject, new Object());
+ __qmljs_init_object(ctx, &ctx->thisObject, ctx->engine->newObject());
}
void ObjectCtor::call(Context *)
Value StringCtor::create(ExecutionEngine *engine)
{
Context *ctx = engine->rootContext;
- StringCtor *ctor = new StringCtor(ctx);
- ctor->setProperty(ctx, QLatin1String("prototype"), Value::object(ctx, new StringPrototype(ctx, ctor)));
+ FunctionObject *ctor = ctx->engine->newStringCtor(ctx);
+ ctor->setProperty(ctx, QLatin1String("prototype"), Value::object(ctx, ctx->engine->newStringPrototype(ctx, ctor)));
return Value::object(ctx, ctor);
}
value = Value::string(ctx, ctx->argument(0).toString(ctx));
else
value = Value::string(ctx, QString());
- __qmljs_init_object(ctx, &ctx->thisObject, new StringObject(value));
+ __qmljs_init_object(ctx, &ctx->thisObject, ctx->engine->newStringObject(value));
}
void StringCtor::call(Context *ctx)
Value NumberCtor::create(ExecutionEngine *engine)
{
Context *ctx = engine->rootContext;
- NumberCtor *ctor = new NumberCtor(ctx);
- ctor->setProperty(ctx, QLatin1String("prototype"), Value::object(ctx, new NumberPrototype(ctx, ctor)));
+ FunctionObject *ctor = ctx->engine->newNumberCtor(ctx);
+ ctor->setProperty(ctx, QLatin1String("prototype"), Value::object(ctx, ctx->engine->newNumberPrototype(ctx, ctor)));
return Value::object(ctx, ctor);
}
void NumberCtor::construct(Context *ctx)
{
const double n = ctx->argument(0).toNumber(ctx);
- __qmljs_init_object(ctx, &ctx->thisObject, new NumberObject(Value::number(ctx, n)));
+ __qmljs_init_object(ctx, &ctx->thisObject, ctx->engine->newNumberObject(Value::number(ctx, n)));
}
void NumberCtor::call(Context *ctx)
} else if (IR::String *str = s->source->asString()) {
amd64_mov_reg_reg(_codePtr, AMD64_RDI, AMD64_R14, 8);
amd64_mov_reg_imm(_codePtr, AMD64_RSI, propertyName);
- amd64_mov_reg_imm(_codePtr, AMD64_RDX, new String(*str->value));
+ amd64_mov_reg_imm(_codePtr, AMD64_RDX, _engine->newString(*str->value));
amd64_call_code(_codePtr, __qmljs_set_activation_property_string);
return;
} else if (IR::Temp *t = s->source->asTemp()) {
} else if (IR::String *str = s->source->asString()) {
amd64_mov_reg_reg(_codePtr, AMD64_RDI, AMD64_R14, 8);
loadTempAddress(AMD64_RSI, t);
- amd64_mov_reg_imm(_codePtr, AMD64_RDX, new String(*str->value));
+ amd64_mov_reg_imm(_codePtr, AMD64_RDX, _engine->newString(*str->value));
amd64_call_code(_codePtr, __qmljs_init_string);
return;
} else if (IR::Closure *clos = s->source->asClosure()) {