Chromium Code Reviews| Index: src/runtime/runtime-classes.cc |
| diff --git a/src/runtime/runtime-classes.cc b/src/runtime/runtime-classes.cc |
| index 5448159513bda41508a1c8cd1f72e859be74197a..dfbc50d6aaab6eb26006b6e6b2a03b1db5baeea5 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,104 @@ 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()); |
| + |
| + for (int i = 0; i < array_len; ++i) { |
| + Handle<Object> name_obj = |
| + JSReceiver::GetElement(isolate, property_names, i).ToHandleChecked(); |
|
adamk
2016/07/13 20:57:32
These are probably one of the reasons this is slow
|
| + DCHECK(name_obj->IsName()); |
| + Handle<Name> name = Handle<Name>::cast(name_obj); |
| + |
| + Handle<Object> func_obj = |
| + JSReceiver::GetElement(isolate, property_funcs, i).ToHandleChecked(); |
| + DCHECK(func_obj->IsJSFunction()); |
| + Handle<JSFunction> func = Handle<JSFunction>::cast(func_obj); |
| + |
| + Handle<Object> info_obj = |
| + JSReceiver::GetElement(isolate, property_infos, i).ToHandleChecked(); |
| + 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)); |
| } |