| 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
|
|
|