Add methods to allocate JS entities.
authorRoberto Raggi <roberto.raggi@nokia.com>
Tue, 15 May 2012 08:35:19 +0000 (10:35 +0200)
committerRoberto Raggi <roberto.raggi@nokia.com>
Tue, 15 May 2012 08:35:19 +0000 (10:35 +0200)
main.cpp
qmljs_objects.cpp
qmljs_objects.h
qmljs_runtime.cpp
qv4ecmaobjects.cpp
qv4isel.cpp

index 459c560..e2feac9 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -94,7 +94,7 @@ void evaluate(QQmlJS::VM::ExecutionEngine *vm, QQmlJS::Engine *engine, const QSt
         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);
index aed6c37..fd9647e 100644 (file)
@@ -7,6 +7,11 @@
 
 using namespace QQmlJS::VM;
 
+String *String::get(Context *ctx, const QString &s)
+{
+    return ctx->engine->newString(s);
+}
+
 Object::~Object()
 {
     delete members;
@@ -20,7 +25,7 @@ void Object::setProperty(Context *ctx, const QString &name, const Value &value)
 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)
@@ -124,7 +129,7 @@ void FunctionObject::call(Context *ctx)
 
 void FunctionObject::construct(Context *ctx)
 {
-    __qmljs_init_object(ctx, &ctx->thisObject, new Object());
+    __qmljs_init_object(ctx, &ctx->thisObject, ctx->engine->newObject());
     call(ctx);
 }
 
@@ -154,7 +159,7 @@ void ScriptFunction::call(VM::Context *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);
 }
 
@@ -177,13 +182,13 @@ Value *ArgumentsObject::getProperty(String *name, PropertyAttributes *attributes
 
 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);
 
@@ -200,13 +205,98 @@ ExecutionEngine::ExecutionEngine()
     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);
+}
index 6c64491..26987a2 100644 (file)
@@ -41,10 +41,7 @@ struct String {
         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;
@@ -277,8 +274,8 @@ struct ScriptFunction: FunctionObject {
 };
 
 struct ErrorObject: Object {
-    String *message;
-    ErrorObject(String *message): message(message) {}
+    Value message;
+    ErrorObject(const Value &message): message(message) {}
 };
 
 struct ArgumentsObject: Object {
@@ -354,7 +351,30 @@ struct ExecutionEngine
 
     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
index a93cab9..4f7418f 100644 (file)
@@ -74,7 +74,7 @@ extern "C" {
 
 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)
@@ -203,21 +203,21 @@ void __qmljs_object_default_value(Context *ctx, Value *result, Object *object, i
 
 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;
 }
 
@@ -225,7 +225,7 @@ void __qmljs_new_string_object(Context *ctx, Value *result, String *string)
 {
     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;
 }
 
@@ -453,11 +453,11 @@ void __qmljs_call_property(Context *context, Value *result, const Value *base, S
     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;
@@ -487,11 +487,11 @@ void __qmljs_call_value(Context *context, Value *result, const Value *func, Valu
     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);
@@ -529,11 +529,11 @@ void __qmljs_construct_value(Context *context, Value *result, const Value *func,
     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);
@@ -577,11 +577,11 @@ void __qmljs_construct_property(Context *context, Value *result, const Value *ba
     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;
index 1e00940..33e444a 100644 (file)
@@ -14,8 +14,8 @@ static const double qt_PI = 2.0 * ::asin(1.0);
 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);
 }
 
@@ -26,7 +26,7 @@ ObjectCtor::ObjectCtor(Context *scope)
 
 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 *)
@@ -45,8 +45,8 @@ ObjectPrototype::ObjectPrototype(Context *ctx, FunctionObject *ctor)
 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);
 }
 
@@ -62,7 +62,7 @@ void StringCtor::construct(Context *ctx)
         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)
@@ -358,8 +358,8 @@ void StringPrototype::method_fromCharCode(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);
 }
 
@@ -371,7 +371,7 @@ NumberCtor::NumberCtor(Context *scope)
 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)
index 6e60cc9..573c3d5 100644 (file)
@@ -400,7 +400,7 @@ void InstructionSelection::visitMove(IR::Move *s)
             } 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()) {
@@ -474,7 +474,7 @@ void InstructionSelection::visitMove(IR::Move *s)
             } 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()) {