}
__ push(scratch);
VisitForStackValue(key);
+ VisitForStackValue(value);
switch (property->kind()) {
case ObjectLiteral::Property::CONSTANT:
case ObjectLiteral::Property::MATERIALIZED_LITERAL:
case ObjectLiteral::Property::COMPUTED:
case ObjectLiteral::Property::PROTOTYPE:
- VisitForStackValue(value);
- __ mov(scratch, Operand(Smi::FromInt(NONE)));
- __ push(scratch);
- __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4);
+ __ CallRuntime(Runtime::kDefineClassMethod, 3);
break;
case ObjectLiteral::Property::GETTER:
- VisitForStackValue(value);
- __ LoadRoot(scratch, Heap::kNullValueRootIndex);
- __ push(scratch);
- __ mov(scratch, Operand(Smi::FromInt(NONE)));
- __ push(scratch);
- __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
+ __ CallRuntime(Runtime::kDefineClassGetter, 3);
break;
case ObjectLiteral::Property::SETTER:
- __ LoadRoot(scratch, Heap::kNullValueRootIndex);
- __ push(scratch);
- VisitForStackValue(value);
- __ mov(scratch, Operand(Smi::FromInt(NONE)));
- __ push(scratch);
- __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
+ __ CallRuntime(Runtime::kDefineClassSetter, 3);
break;
default:
}
__ Push(scratch);
VisitForStackValue(key);
+ VisitForStackValue(value);
switch (property->kind()) {
case ObjectLiteral::Property::CONSTANT:
case ObjectLiteral::Property::MATERIALIZED_LITERAL:
case ObjectLiteral::Property::COMPUTED:
case ObjectLiteral::Property::PROTOTYPE:
- VisitForStackValue(value);
- __ Mov(scratch, Smi::FromInt(NONE));
- __ Push(scratch);
- __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4);
+ __ CallRuntime(Runtime::kDefineClassMethod, 3);
break;
case ObjectLiteral::Property::GETTER:
- VisitForStackValue(value);
- __ LoadRoot(scratch, Heap::kNullValueRootIndex);
- __ push(scratch);
- __ Mov(scratch, Smi::FromInt(NONE));
- __ Push(scratch);
- __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
+ __ CallRuntime(Runtime::kDefineClassGetter, 3);
break;
case ObjectLiteral::Property::SETTER:
- __ LoadRoot(scratch, Heap::kNullValueRootIndex);
- __ push(scratch);
- VisitForStackValue(value);
- __ Mov(scratch, Smi::FromInt(NONE));
- __ Push(scratch);
- __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
+ __ CallRuntime(Runtime::kDefineClassSetter, 3);
break;
default:
__ push(Operand(esp, 0)); // prototype
}
VisitForStackValue(key);
+ VisitForStackValue(value);
switch (property->kind()) {
case ObjectLiteral::Property::CONSTANT:
case ObjectLiteral::Property::MATERIALIZED_LITERAL:
case ObjectLiteral::Property::COMPUTED:
case ObjectLiteral::Property::PROTOTYPE:
- VisitForStackValue(value);
- __ push(Immediate(Smi::FromInt(NONE)));
- __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4);
+ __ CallRuntime(Runtime::kDefineClassMethod, 3);
break;
case ObjectLiteral::Property::GETTER:
- VisitForStackValue(value);
- __ push(Immediate(isolate()->factory()->null_value()));
- __ push(Immediate(Smi::FromInt(NONE)));
- __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
+ __ CallRuntime(Runtime::kDefineClassGetter, 3);
break;
case ObjectLiteral::Property::SETTER:
- __ push(Immediate(isolate()->factory()->null_value()));
- VisitForStackValue(value);
- __ push(Immediate(Smi::FromInt(NONE)));
- __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
+ __ CallRuntime(Runtime::kDefineClassSetter, 3);
break;
default:
}
+RUNTIME_FUNCTION(Runtime_DefineClassMethod) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 3);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 2);
+
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate, JSObject::SetOwnPropertyIgnoreAttributes(
+ function, isolate->factory()->home_object_symbol(), object,
+ DONT_ENUM));
+
+ uint32_t index;
+ if (key->ToArrayIndex(&index)) {
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate, JSObject::SetOwnElement(object, index, function, STRICT));
+ }
+
+ Handle<Name> name;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
+ Runtime::ToName(isolate, key));
+ if (name->AsArrayIndex(&index)) {
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate, JSObject::SetOwnElement(object, index, function, STRICT));
+ } else {
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate,
+ JSObject::SetOwnPropertyIgnoreAttributes(object, name, function, NONE));
+ }
+ return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_DefineClassGetter) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 3);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, getter, 2);
+
+ Handle<Name> name;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
+ Runtime::ToName(isolate, key));
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate,
+ JSObject::SetOwnPropertyIgnoreAttributes(
+ getter, isolate->factory()->home_object_symbol(), object, DONT_ENUM));
+
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate,
+ JSObject::DefineAccessor(object, name, getter,
+ isolate->factory()->null_value(), NONE));
+ return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_DefineClassSetter) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 3);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, setter, 2);
+
+ Handle<Name> name;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
+ Runtime::ToName(isolate, key));
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate,
+ JSObject::SetOwnPropertyIgnoreAttributes(
+ setter, isolate->factory()->home_object_symbol(), object, DONT_ENUM));
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate,
+ JSObject::DefineAccessor(object, name, isolate->factory()->null_value(),
+ setter, NONE));
+ return isolate->heap()->undefined_value();
+}
+
+
RUNTIME_FUNCTION(Runtime_ClassGetSourceCode) {
HandleScope shs(isolate);
DCHECK(args.length() == 1);
F(ToMethod, 2, 1) \
F(HomeObjectSymbol, 0, 1) \
F(DefineClass, 6, 1) \
+ F(DefineClassMethod, 3, 1) \
+ F(DefineClassGetter, 3, 1) \
+ F(DefineClassSetter, 3, 1) \
F(ClassGetSourceCode, 1, 1) \
F(ThrowNonMethodError, 0, 1) \
F(ThrowUnsupportedSuperError, 0, 1) \
__ Push(Operand(rsp, 0)); // prototype
}
VisitForStackValue(key);
+ VisitForStackValue(value);
switch (property->kind()) {
case ObjectLiteral::Property::CONSTANT:
case ObjectLiteral::Property::MATERIALIZED_LITERAL:
case ObjectLiteral::Property::COMPUTED:
case ObjectLiteral::Property::PROTOTYPE:
- VisitForStackValue(value);
- __ Push(Smi::FromInt(NONE));
- __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4);
+ __ CallRuntime(Runtime::kDefineClassMethod, 3);
break;
case ObjectLiteral::Property::GETTER:
- VisitForStackValue(value);
- __ Push(isolate()->factory()->null_value());
- __ Push(Smi::FromInt(NONE));
- __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
+ __ CallRuntime(Runtime::kDefineClassGetter, 3);
break;
case ObjectLiteral::Property::SETTER:
- __ Push(isolate()->factory()->null_value());
- VisitForStackValue(value);
- __ Push(Smi::FromInt(NONE));
- __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
+ __ CallRuntime(Runtime::kDefineClassSetter, 3);
break;
default:
})();
+(function TestSuperInMethods() {
+ class B {
+ method() {
+ return 1;
+ }
+ get x() {
+ return 2;
+ }
+ }
+ class C extends B {
+ method() {
+ assertEquals(2, super.x);
+ return super.method();
+ }
+ }
+ assertEquals(1, new C().method());
+})();
+
+
+(function TestSuperInGetter() {
+ class B {
+ method() {
+ return 1;
+ }
+ get x() {
+ return 2;
+ }
+ }
+ class C extends B {
+ get y() {
+ assertEquals(2, super.x);
+ return super.method();
+ }
+ }
+ assertEquals(1, new C().y);
+})();
+
+
+(function TestSuperInSetter() {
+ class B {
+ method() {
+ return 1;
+ }
+ get x() {
+ return 2;
+ }
+ }
+ class C extends B {
+ set y(v) {
+ assertEquals(3, v);
+ assertEquals(2, super.x);
+ assertEquals(1, super.method());
+ }
+ }
+ assertEquals(3, new C().y = 3);
+})();
+
+
+(function TestSuperInStaticMethods() {
+ class B {
+ static method() {
+ return 1;
+ }
+ static get x() {
+ return 2;
+ }
+ }
+ class C extends B {
+ static method() {
+ assertEquals(2, super.x);
+ return super.method();
+ }
+ }
+ assertEquals(1, C.method());
+})();
+
+
+(function TestSuperInStaticGetter() {
+ class B {
+ static method() {
+ return 1;
+ }
+ static get x() {
+ return 2;
+ }
+ }
+ class C extends B {
+ static get x() {
+ assertEquals(2, super.x);
+ return super.method();
+ }
+ }
+ assertEquals(1, C.x);
+})();
+
+
+(function TestSuperInStaticSetter() {
+ class B {
+ static method() {
+ return 1;
+ }
+ static get x() {
+ return 2;
+ }
+ }
+ class C extends B {
+ static set x(v) {
+ assertEquals(3, v);
+ assertEquals(2, super.x);
+ assertEquals(1, super.method());
+ }
+ }
+ assertEquals(3, C.x = 3);
+})();
+
+
+(function TestNumericPropertyNames() {
+ class B {
+ 1() { return 1; }
+ get 2() { return 2; }
+ set 3(_) {}
+
+ static 4() { return 4; }
+ static get 5() { return 5; }
+ static set 6(_) {}
+ }
+
+ assertMethodDescriptor(B.prototype, '1');
+ assertGetterDescriptor(B.prototype, '2');
+ assertSetterDescriptor(B.prototype, '3');
+
+ assertMethodDescriptor(B, '4');
+ assertGetterDescriptor(B, '5');
+ assertSetterDescriptor(B, '6');
+
+ class C extends B {
+ 1() { return super[1](); }
+ get 2() { return super[2]; }
+
+ static 4() { return super[4](); }
+ static get 5() { return super[5]; }
+ }
+
+ assertEquals(1, new C()[1]());
+ assertEquals(2, new C()[2]);
+ assertEquals(4, C[4]());
+ assertEquals(5, C[5]);
+})();
+
+
/* TODO(arv): Implement
(function TestNameBindingInConstructor() {
class C {