{
using namespace QQmlJS;
- GC_INIT();
-
QCoreApplication app(argc, argv);
QStringList args = app.arguments();
args.removeFirst();
#include "qmljs_objects.h"
#include <cassert>
+Object::~Object()
+{
+ delete members;
+}
+
bool Object::get(String *name, Value *result)
{
if (Property *prop = getProperty(name)) {
void Object::put(String *name, const Value &value, bool flag)
{
+ Q_UNUSED(flag);
+
if (! members)
- members = new (GC) Table();
+ members = new Table();
members->insert(name, value);
}
bool Object::canPut(String *name)
{
- if (Property *prop = getOwnProperty(name))
+ if (Property *prop = getOwnProperty(name)) {
+ Q_UNUSED(prop);
return true;
- if (! prototype)
+ } else if (! prototype) {
return extensible;
- if (Property *inherited = prototype->getProperty(name)) {
+ } else if (Property *inherited = prototype->getProperty(name)) {
return inherited->isWritable();
} else {
return extensible;
bool Object::deleteProperty(String *name, bool flag)
{
+ Q_UNUSED(flag);
+
if (members)
return members->remove(name);
Value FunctionObject::call(const Value &thisObject, const Value args[], unsigned argc)
{
- (void) thisObject;
+ Q_UNUSED(thisObject);
+ Q_UNUSED(args);
+ Q_UNUSED(argc);
Value v;
__qmljs_init_undefined(0, &v);
Value FunctionObject::construct(const Value args[], unsigned argc)
{
Value thisObject;
- __qmljs_init_object(0, &thisObject, new (GC) Object);
+ __qmljs_init_object(0, &thisObject, new Object);
call(thisObject, args, argc);
return thisObject;
}
#include "qmljs_runtime.h"
-#include <gc/gc_cpp.h>
#include <QtCore/QString>
#include <QtCore/QHash>
+#include <cassert>
struct Value;
struct Object;
struct FunctionObject;
struct ErrorObject;
-struct String: gc_cleanup {
+struct String {
String(const QString &text)
: _text(text), _hashValue(0) {}
}
static String *get(Context *ctx, const QString &s) {
- return new (GC) String(s);
+ Q_UNUSED(ctx);
+ return new String(s);
}
private:
mutable unsigned _hashValue;
};
-struct Property: gc {
+struct Property {
String *name;
Value value;
PropertyAttributes flags;
Property *next;
+ int index;
Property(String *name, const Value &value, PropertyAttributes flags = NoAttributes)
- : name(name), value(value), flags(flags), next(0) {}
+ : name(name), value(value), flags(flags), next(0), index(-1) {}
inline bool isWritable() const { return flags & WritableAttribute; }
inline bool isEnumerable() const { return flags & EnumerableAttribute; }
inline bool isConfigurable() const { return flags & ConfigurableAttribute; }
inline bool hasName(String *n) const {
- if (name == n || (name->hashValue() == n->hashValue() && name->text() == n->text()))
+ if (name == n) {
return true;
+ } else if (name->hashValue() == n->hashValue() && name->text() == n->text()) {
+ return true;
+ }
return false;
}
}
};
-class Table: public gc
+class Table
{
- Property **_properties;
- Property **_buckets;
- int _propertyCount;
- int _bucketCount;
- int _allocated;
+ Q_DISABLE_COPY(Table)
public:
Table()
, _bucketCount(11)
, _allocated(0) {}
- bool empty() const { return _propertyCount == -1; }
- unsigned size() const { return _propertyCount + 1; }
+ ~Table()
+ {
+ qDeleteAll(_properties, _properties + _propertyCount + 1);
+ delete[] _properties;
+ delete[] _buckets;
+ }
+
+ inline bool isEmpty() const { return _propertyCount == -1; }
typedef Property **iterator;
- iterator begin() const { return _properties; }
- iterator end() const { return _properties + (_propertyCount + 1); }
+ inline iterator begin() const { return _properties; }
+ inline iterator end() const { return _properties + (_propertyCount + 1); }
bool remove(String *name)
{
- if (_properties) {
- const unsigned hash = name->hashValue() % _bucketCount;
-
- if (Property *prop = _buckets[hash]) {
- if (prop->hasName(name)) {
- _buckets[hash] = prop->next;
- return true;
- }
-
- do {
- Property *next = prop->next;
-
- if (next && next->hasName(name)) {
- prop->next = next->next;
- return true;
- }
- prop = next;
- } while (prop);
- }
- }
-
+ Q_UNUSED(name);
+ assert(!"TODO");
return false;
}
Property *find(String *name) const
{
- if (! _properties)
- return 0;
-
- for (Property *prop = _buckets[name->hashValue() % _bucketCount]; prop; prop = prop->next) {
- if (prop->hasName(name))
- return prop;
+ if (_properties) {
+ for (Property *prop = _buckets[name->hashValue() % _bucketCount]; prop; prop = prop->next) {
+ if (prop->hasName(name))
+ return prop;
+ }
}
return 0;
else
_allocated *= 2;
- Property **properties = new (GC) Property*[_allocated];
+ Property **properties = new Property*[_allocated];
std::copy(_properties, _properties + _propertyCount, properties);
+ delete[] _properties;
_properties = properties;
}
- Property *prop = new (GC) Property(name, value);
+ Property *prop = new Property(name, value);
+ prop->index = _propertyCount;
_properties[_propertyCount] = prop;
if (! _buckets || 3 * _propertyCount >= 2 * _bucketCount) {
if (_bucketCount)
_bucketCount *= 2; // ### next prime
- _buckets = new (GC) Property *[_bucketCount];
+ if (_buckets)
+ delete[] _buckets;
+
+ _buckets = new Property *[_bucketCount];
std::fill(_buckets, _buckets + _bucketCount, (Property *) 0);
for (int i = 0; i <= _propertyCount; ++i) {
Property *prop = _properties[i];
- Property *&bucket = _buckets[prop->name->hashValue() % _bucketCount];
+ Property *&bucket = _buckets[prop->hashValue() % _bucketCount];
prop->next = bucket;
bucket = prop;
}
}
+
+private:
+ Property **_properties;
+ Property **_buckets;
+ int _propertyCount;
+ int _bucketCount;
+ int _allocated;
};
-struct Object: gc_cleanup {
+struct Object {
Object *prototype;
String *klass;
Table *members;
, members(0)
, extensible(true) {}
- virtual ~Object() {}
+ virtual ~Object();
virtual FunctionObject *asFunctionObject() { return 0; }
struct BooleanObject: Object {
Value value;
BooleanObject(const Value &value): value(value) {}
- virtual void defaultValue(Value *result, int typehint) { *result = value; }
+ virtual void defaultValue(Value *result, int /*typehint*/) { *result = value; }
};
struct NumberObject: Object {
Value value;
NumberObject(const Value &value): value(value) {}
- virtual void defaultValue(Value *result, int typehint) { *result = value; }
+ virtual void defaultValue(Value *result, int /*typehint*/) { *result = value; }
};
struct StringObject: Object {
Value value;
StringObject(const Value &value): value(value) {}
- virtual void defaultValue(Value *result, int typehint) { *result = value; }
+ virtual void defaultValue(Value *result, int /*typehint*/) { *result = value; }
};
struct ArrayObject: Object {
struct ArgumentsObject: Object {
};
-struct Context: gc {
+struct Context {
Value activation;
Value thisObject;
Object *scope;
void __qmljs_delete(Context *ctx, Value *result, const Value *value)
{
+ Q_UNIMPLEMENTED();
(void) ctx;
(void) result;
(void) value;
+ assert(!"TODO");
}
void __qmljs_instanceof(Context *ctx, Value *result, const Value *left, const Value *right)
void __qmljs_object_default_value(Context *ctx, Value *result, Object *object, int typeHint)
{
+ Q_UNUSED(ctx);
object->defaultValue(result, typeHint);
}
void __qmljs_throw_type_error(Context *ctx, Value *result)
{
- __qmljs_init_object(ctx, result, new (GC) ErrorObject(String::get(ctx, QLatin1String("type error"))));
+ __qmljs_init_object(ctx, result, new ErrorObject(String::get(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 (GC) BooleanObject(value));
+ __qmljs_init_object(ctx, result, new BooleanObject(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 (GC) NumberObject(value));
+ __qmljs_init_object(ctx, result, new NumberObject(value));
}
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 (GC) StringObject(value));
+ __qmljs_init_object(ctx, result, new StringObject(value));
}
void __qmljs_set_property(Context *ctx, Value *object, String *name, Value *value)
{
+ Q_UNUSED(ctx);
object->objectValue->put(name, *value, /*flags*/ 0);
}
void __qmljs_get_property(Context *ctx, Value *result, Value *object, String *name)
{
+ Q_UNUSED(ctx);
Q_ASSERT(object->type == OBJECT_TYPE);
object->objectValue->get(name, result);
}
void __qmljs_copy_property(Context *ctx, Value *target, String *name, Value *source, String *other)
{
+ Q_UNUSED(ctx);
Value v;
source->objectValue->get(other, &v);
target->objectValue->put(name, v);
void (*f)(Context *) = (void (*)(Context *)) code;
- Context *ctx = new (GC) Context;
- ctx->activation = Value::object(ctx, new (GC) ArgumentsObject);
+ Context *ctx = new Context;
+ ctx->activation = Value::object(ctx, new ArgumentsObject);
f(ctx);
Value d;
ctx->activation.objectValue->get(identifier("d"), &d);
{
String *&id = _identifiers[s];
if (! id)
- id = new (GC) String(s);
+ id = new String(s);
return id;
}
amd64_lea_membase(_codePtr, reg, AMD64_RSP, sizeof(Value) * (t->index - 1));
}
-void InstructionSelection::visitExp(IR::Exp *s)
+void InstructionSelection::visitExp(IR::Exp *)
{
- // if (IR::Call *c = s->expr->asCall()) {
- // return;
- // }
+ Q_UNIMPLEMENTED();
assert(!"TODO");
}
void InstructionSelection::visitEnter(IR::Enter *)
{
+ Q_UNIMPLEMENTED();
assert(!"TODO");
}
void InstructionSelection::visitLeave(IR::Leave *)
{
+ Q_UNIMPLEMENTED();
assert(!"TODO");
}
break;
default:
+ Q_UNIMPLEMENTED();
assert(!"TODO");
}
return;
} 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 (GC) String(*str->value));
+ amd64_mov_reg_imm(_codePtr, AMD64_RDX, new String(*str->value));
amd64_call_code(_codePtr, __qmljs_set_activation_property_string);
return;
} else if (IR::Temp *t = s->source->asTemp()) {
break;
default:
+ Q_UNIMPLEMENTED();
assert(!"TODO");
}
return;
} 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 (GC) String(*str->value));
+ amd64_mov_reg_imm(_codePtr, AMD64_RDX, new String(*str->value));
amd64_call_code(_codePtr, __qmljs_init_string);
return;
} else if (IR::Unop *u = s->source->asUnop()) {
} else {
// inplace assignment, e.g. x += 1, ++x, ...
}
+ Q_UNIMPLEMENTED();
assert(!"TODO");
}
}
return;
}
+ Q_UNIMPLEMENTED();
assert(!"TODO");
}
void InstructionSelection::visitRet(IR::Ret *s)
{
- qWarning() << "TODO: RET";
- //assert(!"TODO");
+ Q_UNIMPLEMENTED();
+ Q_UNUSED(s);
}
DEFINES += __default_codegen__
-LIBS += -lgc
-
udis86:LIBS += -ludis86
else:DEFINES += NO_UDIS86