Index: src/runtime/runtime-classes.cc |
diff --git a/src/runtime/runtime-classes.cc b/src/runtime/runtime-classes.cc |
index 20e98efc64eb0ac6cfbc469455adc4599f29421c..b8cfa9b8dd46f102d6d84830311158542f4907a5 100644 |
--- a/src/runtime/runtime-classes.cc |
+++ b/src/runtime/runtime-classes.cc |
@@ -151,5 +151,84 @@ RUNTIME_FUNCTION(Runtime_StoreToSuper_Sloppy) { |
return StoreToSuper(isolate, home_object, receiver, name, value, SLOPPY); |
} |
+ |
+ |
+RUNTIME_FUNCTION(Runtime_DefineClass) { |
+ HandleScope scope(isolate); |
+ DCHECK(args.length() == 3); |
+ CONVERT_ARG_HANDLE_CHECKED(Object, name, 0); |
+ CONVERT_ARG_HANDLE_CHECKED(Object, super_class, 1); |
+ CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 2); |
+ |
+ Handle<Object> prototype_parent; |
+ Handle<Object> constructor_parent; |
+ |
+ if (super_class->IsTheHole()) { |
+ prototype_parent = isolate->initial_object_prototype(); |
+ } else { |
+ if (super_class->IsNull()) { |
+ prototype_parent = isolate->factory()->null_value(); |
+ } else if (super_class->IsSpecFunction()) { |
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
+ isolate, prototype_parent, |
+ Runtime::GetObjectProperty(isolate, super_class, |
+ isolate->factory()->prototype_string())); |
+ if (!prototype_parent->IsNull() && !prototype_parent->IsSpecObject()) { |
+ Handle<Object> args[1] = {prototype_parent}; |
+ THROW_NEW_ERROR_RETURN_FAILURE( |
+ isolate, NewTypeError("prototype_parent_not_an_object", |
+ HandleVector(args, 1))); |
+ } |
+ constructor_parent = super_class; |
+ } else { |
+ // TODO(arv): Should be IsConstructor. |
+ Handle<Object> args[1] = {super_class}; |
+ THROW_NEW_ERROR_RETURN_FAILURE( |
+ isolate, |
+ NewTypeError("extends_value_not_a_function", HandleVector(args, 1))); |
+ } |
+ } |
+ |
+ Handle<Map> map = |
+ isolate->factory()->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); |
+ map->set_prototype(*prototype_parent); |
+ Handle<JSObject> prototype = isolate->factory()->NewJSObjectFromMap(map); |
+ |
+ Handle<String> name_string = name->IsString() |
+ ? Handle<String>::cast(name) |
+ : isolate->factory()->empty_string(); |
+ |
+ Handle<JSFunction> ctor; |
+ if (constructor->IsSpecFunction()) { |
+ ctor = Handle<JSFunction>::cast(constructor); |
+ JSFunction::SetPrototype(ctor, prototype); |
+ PropertyAttributes attribs = |
+ static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); |
+ RETURN_FAILURE_ON_EXCEPTION( |
+ isolate, |
+ JSObject::SetOwnPropertyIgnoreAttributes( |
+ ctor, isolate->factory()->prototype_string(), prototype, attribs)); |
+ } else { |
+ // TODO(arv): This should not use an empty function but a function that |
+ // calls super. |
+ Handle<Code> code(isolate->builtins()->builtin(Builtins::kEmptyFunction)); |
+ ctor = isolate->factory()->NewFunction(name_string, code, prototype, true); |
+ } |
+ |
+ Handle<Symbol> home_object_symbol(isolate->heap()->home_object_symbol()); |
+ RETURN_FAILURE_ON_EXCEPTION( |
+ isolate, JSObject::SetOwnPropertyIgnoreAttributes( |
+ ctor, home_object_symbol, prototype, DONT_ENUM)); |
+ |
+ if (!constructor_parent.is_null()) { |
+ RETURN_FAILURE_ON_EXCEPTION( |
+ isolate, JSObject::SetPrototype(ctor, constructor_parent, false)); |
+ } |
+ |
+ JSObject::AddProperty(prototype, isolate->factory()->constructor_string(), |
+ ctor, DONT_ENUM); |
+ |
+ return *ctor; |
+} |
} |
} // namespace v8::internal |