Commit 8e35d8eb authored by neis's avatar neis Committed by Commit bot

[es6] Partially implement Reflect.defineProperty.

Proxies are not properly supported yet.

R=rossberg,jkummerow@chromium.org
BUG=v8:3931
LOG=n

Review URL: https://codereview.chromium.org/1421033002

Cr-Commit-Position: refs/heads/master@{#31661}
parent 0bdaa4d8
......@@ -2191,6 +2191,8 @@ void Genesis::InitializeGlobal_harmony_reflect() {
factory()->NewJSObject(isolate()->object_function(), TENURED);
JSObject::AddProperty(global, reflect_string, reflect, DONT_ENUM);
SimpleInstallFunction(reflect, "defineProperty",
Builtins::kReflectDefineProperty, 3, true);
SimpleInstallFunction(reflect, "deleteProperty",
Builtins::kReflectDeleteProperty, 2, true);
SimpleInstallFunction(reflect, "get",
......
......@@ -17,6 +17,7 @@
#include "src/isolate-inl.h"
#include "src/messages.h"
#include "src/profiler/cpu-profiler.h"
#include "src/property-descriptor.h"
#include "src/prototype.h"
#include "src/vm-state-inl.h"
......@@ -1444,6 +1445,39 @@ BUILTIN(ArrayConcat) {
}
// ES6 section 26.1.3 Reflect.defineProperty
BUILTIN(ReflectDefineProperty) {
HandleScope scope(isolate);
DCHECK_EQ(4, args.length());
Handle<Object> target = args.at<Object>(1);
Handle<Object> key = args.at<Object>(2);
Handle<Object> attributes = args.at<Object>(3);
if (!target->IsJSReceiver()) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
isolate->factory()->NewStringFromAsciiChecked(
"Reflect.defineProperty")));
}
Handle<Name> name;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
Object::ToName(isolate, key));
PropertyDescriptor desc;
if (!PropertyDescriptor::ToPropertyDescriptor(isolate, attributes, &desc)) {
return isolate->heap()->exception();
}
bool result =
JSReceiver::DefineOwnProperty(isolate, Handle<JSReceiver>::cast(target),
name, &desc, Object::DONT_THROW);
if (isolate->has_pending_exception()) return isolate->heap()->exception();
// TODO(neis): Make DefineOwnProperty return Maybe<bool>.
return *isolate->factory()->ToBoolean(result);
}
// ES6 section 26.1.4 Reflect.deleteProperty
BUILTIN(ReflectDeleteProperty) {
HandleScope scope(isolate);
......
......@@ -59,6 +59,7 @@ enum BuiltinExtraArguments {
\
V(DateToPrimitive, NO_EXTRA_ARGUMENTS) \
\
V(ReflectDefineProperty, NO_EXTRA_ARGUMENTS) \
V(ReflectDeleteProperty, NO_EXTRA_ARGUMENTS) \
V(ReflectGet, NO_EXTRA_ARGUMENTS) \
V(ReflectGetPrototypeOf, NO_EXTRA_ARGUMENTS) \
......
......@@ -6061,7 +6061,7 @@ Object* JSReceiver::DefineProperties(Isolate* isolate, Handle<Object> object,
// static
bool JSReceiver::DefineOwnProperty(Isolate* isolate, Handle<JSObject> object,
bool JSReceiver::DefineOwnProperty(Isolate* isolate, Handle<JSReceiver> object,
Handle<Object> key, PropertyDescriptor* desc,
ShouldThrow should_throw) {
if (object->IsJSArray()) {
......@@ -6070,12 +6070,14 @@ bool JSReceiver::DefineOwnProperty(Isolate* isolate, Handle<JSObject> object,
}
// TODO(jkummerow): Support Modules (ES6 9.4.6.6)
// TODO(jkummerow): Support Proxies (ES6 9.5.6)
if (!object->IsJSObject()) return true;
// OrdinaryDefineOwnProperty, by virtue of calling
// DefineOwnPropertyIgnoreAttributes, can handle arguments (ES6 9.4.4.2)
// and IntegerIndexedExotics (ES6 9.4.5.3), with one exception:
// TODO(jkummerow): Setting an indexed accessor on a typed array should throw.
return OrdinaryDefineOwnProperty(isolate, object, key, desc, should_throw);
return OrdinaryDefineOwnProperty(isolate, Handle<JSObject>::cast(object), key,
desc, should_throw);
}
......
......@@ -1879,7 +1879,7 @@ class JSReceiver: public HeapObject {
Handle<Object> properties);
// "virtual" dispatcher to the correct [[DefineOwnProperty]] implementation.
static bool DefineOwnProperty(Isolate* isolate, Handle<JSObject> object,
static bool DefineOwnProperty(Isolate* isolate, Handle<JSReceiver> object,
Handle<Object> key, PropertyDescriptor* desc,
ShouldThrow should_throw);
......
This diff is collapsed.
......@@ -176,6 +176,41 @@ function prepare(tgt) {
////////////////////////////////////////////////////////////////////////////////
// Reflect.defineProperty
(function testReflectDefinePropertyArity() {
assertEquals(3, Reflect.defineProperty.length);
})();
(function testReflectDefinePropertyOnNonObject() {
assertThrows(function() { Reflect.defineProperty(); }, TypeError);
assertThrows(function() { Reflect.defineProperty(42, "bla"); }, TypeError);
assertThrows(function() { Reflect.defineProperty(null, "bla"); }, TypeError);
assertThrows(function() { Reflect.defineProperty({}, "bla"); }, TypeError);
assertThrows(function() { Reflect.defineProperty({}, "bla", 42); },
TypeError);
assertThrows(function() { Reflect.defineProperty({}, "bla", null); },
TypeError);
})();
(function testReflectDefinePropertyKeyConversion() {
var tgt = {};
var a = { [Symbol.toPrimitive]: function() { return "bla" } };
var b = { [Symbol.toPrimitive]: function() { throw "gaga" } };
assertTrue(Reflect.defineProperty(tgt, a, {value: 42}));
assertEquals(tgt.bla, 42);
assertThrows(function() { Reflect.defineProperty(tgt, b); }, "gaga");
})();
// See reflect-define-property.js for further tests.
////////////////////////////////////////////////////////////////////////////////
// Reflect.deleteProperty
......@@ -261,12 +296,12 @@ function prepare(tgt) {
(function testReflectSetPrototypeOfOnNonObject() {
assertThrows(function() { Reflect.setPrototypeOf(undefined, {}); },
TypeError);
TypeError);
assertThrows(function() { Reflect.setPrototypeOf(42, {}); }, TypeError);
assertThrows(function() { Reflect.setPrototypeOf(null, {}); }, TypeError);
assertThrows(function() { Reflect.setPrototypeOf({}, undefined); },
TypeError);
TypeError);
assertThrows(function() { Reflect.setPrototypeOf({}, 42); }, TypeError);
assertTrue(Reflect.setPrototypeOf({}, null));
})();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment