Index: src/runtime/runtime-classes.cc |
diff --git a/src/runtime/runtime-classes.cc b/src/runtime/runtime-classes.cc |
index 5448159513bda41508a1c8cd1f72e859be74197a..3708e2cf3e9fd1e4e5cb80c238dd7f38a608dda7 100644 |
--- a/src/runtime/runtime-classes.cc |
+++ b/src/runtime/runtime-classes.cc |
@@ -84,6 +84,9 @@ RUNTIME_FUNCTION(Runtime_HomeObjectSymbol) { |
static MaybeHandle<Object> DefineClass(Isolate* isolate, |
Handle<Object> super_class, |
Handle<JSFunction> constructor, |
+ Handle<JSArray> property_names, |
+ Handle<JSArray> property_funcs, |
+ Handle<JSArray> property_infos, |
int start_position, int end_position) { |
Handle<Object> prototype_parent; |
Handle<Object> constructor_parent; |
@@ -170,20 +173,114 @@ static MaybeHandle<Object> DefineClass(Isolate* isolate, |
handle(Smi::FromInt(end_position), isolate), STRICT), |
Object); |
+ Object* array_length_obj = property_names->length(); |
+ CHECK(array_length_obj->IsSmi()); |
+ int array_len = Smi::cast(array_length_obj)->value(); |
+ |
+ DCHECK_EQ(array_length_obj, property_funcs->length()); |
+ DCHECK_EQ(array_length_obj, property_infos->length()); |
+ |
+ if (array_len == 0) return constructor; |
+ |
+ DCHECK(property_names->GetElementsKind() == FAST_ELEMENTS); |
+ DCHECK(property_funcs->GetElementsKind() == FAST_ELEMENTS); |
+ DCHECK(property_infos->GetElementsKind() == FAST_SMI_ELEMENTS); |
+ |
+ Handle<FixedArray> property_names_elements( |
+ FixedArray::cast(property_names->elements())); |
+ Handle<FixedArray> property_funcs_elements( |
+ FixedArray::cast(property_funcs->elements())); |
+ Handle<FixedArray> property_infos_elements( |
+ FixedArray::cast(property_infos->elements())); |
+ |
+ for (int i = 0; i < array_len; ++i) { |
+ Handle<Object> name_obj(property_names_elements->get(i), isolate); |
+ DCHECK(name_obj->IsName()); |
+ Handle<Name> name = Handle<Name>::cast(name_obj); |
+ |
+ Handle<Object> func_obj(property_funcs_elements->get(i), isolate); |
+ DCHECK(func_obj->IsJSFunction()); |
+ Handle<JSFunction> func = Handle<JSFunction>::cast(func_obj); |
+ |
+ Handle<Object> info_obj(property_infos_elements->get(i), isolate); |
+ DCHECK(info_obj->IsSmi()); |
+ int info = Smi::cast(*info_obj)->value(); |
+ |
+ bool is_static = info & kIsStaticMask; |
+ |
+ if (is_static) { |
+ if (Name::Equals(name, isolate->factory()->prototype_string())) { |
+ THROW_NEW_ERROR( |
+ isolate, NewTypeError(MessageTemplate::kStaticPrototype), Object); |
+ } |
+ } |
+ |
+ Handle<JSObject> receiver = |
+ is_static ? static_cast<Handle<JSObject>>(constructor) : prototype; |
+ |
+ if (func->shared()->needs_home_object()) { |
+ RETURN_ON_EXCEPTION(isolate, |
+ JSObject::SetOwnPropertyIgnoreAttributes( |
+ func, home_object_symbol, receiver, DONT_ENUM), |
+ Object); |
+ } |
+ |
+ if (info & kIsAccessorMask) { |
+ if (info & kIsSetterMask) { |
+ // Setter |
+ if (String::cast(func->shared()->name())->length() == 0) { |
+ JSFunction::SetName(func, name, isolate->factory()->set_string()); |
+ } |
+ |
+ RETURN_ON_EXCEPTION( |
+ isolate, JSObject::DefineAccessor(receiver, name, |
+ isolate->factory()->null_value(), |
+ func, DONT_ENUM), |
+ Object); |
+ } else { |
+ // Getter |
+ if (String::cast(func->shared()->name())->length() == 0) { |
+ JSFunction::SetName(func, name, isolate->factory()->get_string()); |
+ } |
+ |
+ RETURN_ON_EXCEPTION( |
+ isolate, JSObject::DefineAccessor(receiver, name, func, |
+ isolate->factory()->null_value(), |
+ DONT_ENUM), |
+ Object); |
+ } |
+ } else { |
+ // Method |
+ if (String::cast(func->shared()->name())->length() == 0) { |
+ JSFunction::SetName(func, name, isolate->factory()->empty_string()); |
+ } |
+ |
+ LookupIterator it = LookupIterator::PropertyOrElement( |
+ isolate, receiver, name, receiver, LookupIterator::OWN); |
+ CHECK(JSObject::DefineOwnPropertyIgnoreAttributes(&it, func, DONT_ENUM, |
+ Object::DONT_THROW) |
+ .IsJust()); |
+ } |
+ } |
+ |
return constructor; |
} |
RUNTIME_FUNCTION(Runtime_DefineClass) { |
HandleScope scope(isolate); |
- DCHECK(args.length() == 4); |
+ DCHECK(args.length() == 7); |
CONVERT_ARG_HANDLE_CHECKED(Object, super_class, 0); |
CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 1); |
- CONVERT_SMI_ARG_CHECKED(start_position, 2); |
- CONVERT_SMI_ARG_CHECKED(end_position, 3); |
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, property_names, 2); |
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, property_funcs, 3); |
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, property_infos, 4); |
+ CONVERT_SMI_ARG_CHECKED(start_position, 5); |
+ CONVERT_SMI_ARG_CHECKED(end_position, 6); |
RETURN_RESULT_OR_FAILURE( |
- isolate, DefineClass(isolate, super_class, constructor, start_position, |
+ isolate, DefineClass(isolate, super_class, constructor, property_names, |
+ property_funcs, property_infos, start_position, |
end_position)); |
} |