aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--qmljs_objects.cpp9
-rw-r--r--qmljs_objects.h6
-rw-r--r--qv4ecmaobjects.cpp42
-rw-r--r--qv4ecmaobjects_p.h3
-rw-r--r--tests/accessors.js8
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);