diff options
-rw-r--r-- | qmljs_objects.cpp | 9 | ||||
-rw-r--r-- | qmljs_objects.h | 6 | ||||
-rw-r--r-- | qv4ecmaobjects.cpp | 42 | ||||
-rw-r--r-- | qv4ecmaobjects_p.h | 3 | ||||
-rw-r--r-- | tests/accessors.js | 8 |
5 files changed, 62 insertions, 6 deletions
diff --git a/qmljs_objects.cpp b/qmljs_objects.cpp index b0b1d71fbd..d55006024b 100644 --- a/qmljs_objects.cpp +++ b/qmljs_objects.cpp @@ -144,7 +144,7 @@ bool Object::__canPut__(ExecutionContext *ctx, String *name) { if (PropertyDescriptor *p = __getOwnProperty__(ctx, name)) { if (p->isAccessor()) - return p->get != 0; + return p->set != 0; return p->isWritable(); } @@ -154,7 +154,7 @@ bool Object::__canPut__(ExecutionContext *ctx, String *name) PropertyDescriptor tmp; if (PropertyDescriptor *p = prototype->__getPropertyDescriptor__(ctx, name, &tmp)) { if (p->isAccessor()) - return p->get != 0; + return p->set != 0; if (!extensible) return false; return p->isWritable(); @@ -189,7 +189,7 @@ void Object::__put__(ExecutionContext *ctx, String *name, Value value) // clause 4 PropertyDescriptor tmp; - if (prototype) + if (!pd && prototype) pd = prototype->__getPropertyDescriptor__(ctx, name, &tmp); // Clause 5 @@ -305,7 +305,8 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, String *name, Property } else { // clause 10 assert(current->isAccessor() && desc->isAccessor()); if (!current->isConfigurable()) { - if (current->get != desc->get || current->set != desc->set) + if ((desc->get && current->get != desc->get) || + (desc->set && current->set != desc->set)) goto reject; } } diff --git a/qmljs_objects.h b/qmljs_objects.h index 84dc513843..103a9de8fc 100644 --- a/qmljs_objects.h +++ b/qmljs_objects.h @@ -217,8 +217,10 @@ struct PropertyDescriptor { if (other.writable != Undefined) writable = other.writable; if (type == Accessor) { - get = other.get; - set = other.set; + if (other.get) + get = other.get; + if (other.set) + set = other.set; } else { value = other.value; } diff --git a/qv4ecmaobjects.cpp b/qv4ecmaobjects.cpp index 8af8f457e7..8c374e1c30 100644 --- a/qv4ecmaobjects.cpp +++ b/qv4ecmaobjects.cpp @@ -570,6 +570,8 @@ void ObjectPrototype::init(ExecutionContext *ctx, const Value &ctor) __put__(ctx, QStringLiteral("hasOwnProperty"), method_hasOwnProperty, 0); __put__(ctx, QStringLiteral("isPrototypeOf"), method_isPrototypeOf, 0); __put__(ctx, QStringLiteral("propertyIsEnumerable"), method_propertyIsEnumerable, 0); + __put__(ctx, QStringLiteral("__defineGetter__"), method_defineGetter, 0); + __put__(ctx, QStringLiteral("__defineSetter__"), method_defineSetter, 0); } Value ObjectPrototype::method_getPrototypeOf(ExecutionContext *ctx) @@ -707,6 +709,46 @@ Value ObjectPrototype::method_propertyIsEnumerable(ExecutionContext *ctx) return Value::undefinedValue(); } +Value ObjectPrototype::method_defineGetter(ExecutionContext *ctx) +{ + if (ctx->argumentCount() < 2) + __qmljs_throw_type_error(ctx); + String *prop = ctx->argument(0).toString(ctx); + + FunctionObject *f = ctx->argument(1).asFunctionObject(); + if (!f) + __qmljs_throw_type_error(ctx); + + Object *o = ctx->thisObject.toObject(ctx).objectValue(); + + PropertyDescriptor pd = PropertyDescriptor::fromAccessor(f, 0); + pd.writable = PropertyDescriptor::Set; + pd.configurable = PropertyDescriptor::Set; + pd.enumberable = PropertyDescriptor::Set; + o->__defineOwnProperty__(ctx, prop, &pd); + return Value::undefinedValue(); +} + +Value ObjectPrototype::method_defineSetter(ExecutionContext *ctx) +{ + if (ctx->argumentCount() < 2) + __qmljs_throw_type_error(ctx); + String *prop = ctx->argument(0).toString(ctx); + + FunctionObject *f = ctx->argument(1).asFunctionObject(); + if (!f) + __qmljs_throw_type_error(ctx); + + Object *o = ctx->thisObject.toObject(ctx).objectValue(); + + PropertyDescriptor pd = PropertyDescriptor::fromAccessor(0, f); + pd.writable = PropertyDescriptor::Set; + pd.configurable = PropertyDescriptor::Set; + pd.enumberable = PropertyDescriptor::Set; + o->__defineOwnProperty__(ctx, prop, &pd); + return Value::undefinedValue(); +} + // // String // diff --git a/qv4ecmaobjects_p.h b/qv4ecmaobjects_p.h index 7afbe43ac5..02d7d8cf19 100644 --- a/qv4ecmaobjects_p.h +++ b/qv4ecmaobjects_p.h @@ -80,6 +80,9 @@ struct ObjectPrototype: Object static Value method_hasOwnProperty(ExecutionContext *ctx); static Value method_isPrototypeOf(ExecutionContext *ctx); static Value method_propertyIsEnumerable(ExecutionContext *ctx); + + static Value method_defineGetter(ExecutionContext *ctx); + static Value method_defineSetter(ExecutionContext *ctx); }; struct StringCtor: FunctionObject diff --git a/tests/accessors.js b/tests/accessors.js new file mode 100644 index 0000000000..3874e4d329 --- /dev/null +++ b/tests/accessors.js @@ -0,0 +1,8 @@ +"use strict"; +var foo = { y: 1 } +foo.__defineSetter__("x", function(x) { this.y = x;} ) +foo.__defineGetter__("x", function() { return this.y;} ) +print(foo.y); +foo.x = "ok"; +print(foo.x); +print(foo.y); |