body = new (zone()) ZoneList<Statement*>(1, zone());
if (call_super) {
- Expression* prop = SuperReference(function_scope, factory(), pos);
ZoneList<Expression*>* args =
new (zone()) ZoneList<Expression*>(0, zone());
- Call* call = factory()->NewCall(prop, args, pos);
+ CallRuntime* call = factory()->NewCallRuntime(
+ ast_value_factory()->empty_string(),
+ Runtime::FunctionForId(Runtime::kDefaultConstructorSuperCall), args,
+ pos);
body->Add(factory()->NewExpressionStatement(call, pos), zone());
}
return StoreKeyedToSuper(isolate, home_object, receiver, key, value, SLOPPY);
}
+
+
+RUNTIME_FUNCTION(Runtime_DefaultConstructorSuperCall) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 0);
+
+ // Compute the frame holding the arguments.
+ JavaScriptFrameIterator it(isolate);
+ it.AdvanceToArgumentsFrame();
+ JavaScriptFrame* frame = it.frame();
+
+ Handle<JSFunction> function(frame->function(), isolate);
+ Handle<Object> receiver(frame->receiver(), isolate);
+
+ Handle<Object> proto_function;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, proto_function,
+ Runtime::GetPrototype(isolate, function));
+
+ // Get the actual number of provided arguments.
+ const int argc = frame->ComputeParametersCount();
+
+ // Loose upper bound to allow fuzzing. We'll most likely run out of
+ // stack space before hitting this limit.
+ static int kMaxArgc = 1000000;
+ RUNTIME_ASSERT(argc >= 0 && argc <= kMaxArgc);
+
+ // If there are too many arguments, allocate argv via malloc.
+ const int argv_small_size = 10;
+ Handle<Object> argv_small_buffer[argv_small_size];
+ SmartArrayPointer<Handle<Object> > argv_large_buffer;
+ Handle<Object>* argv = argv_small_buffer;
+ if (argc > argv_small_size) {
+ argv = new Handle<Object>[argc];
+ if (argv == NULL) return isolate->StackOverflow();
+ argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
+ }
+
+ for (int i = 0; i < argc; ++i) {
+ argv[i] = handle(frame->GetParameter(i), isolate);
+ }
+
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ Execution::Call(isolate, proto_function, receiver, argc, argv, false));
+ return *result;
+}
}
} // namespace v8::internal
}
-RUNTIME_FUNCTION(Runtime_GetPrototype) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 1);
- CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
+MaybeHandle<Object> Runtime::GetPrototype(Isolate* isolate,
+ Handle<Object> obj) {
// We don't expect access checks to be needed on JSProxy objects.
DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
isolate->ReportFailedAccessCheck(
Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
v8::ACCESS_GET);
- RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
- return isolate->heap()->undefined_value();
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ return isolate->factory()->undefined_value();
}
iter.AdvanceIgnoringProxies();
if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
- return *PrototypeIterator::GetCurrent(iter);
+ return PrototypeIterator::GetCurrent(iter);
}
} while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN));
- return *PrototypeIterator::GetCurrent(iter);
+ return PrototypeIterator::GetCurrent(iter);
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetPrototype) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
+ Runtime::GetPrototype(isolate, obj));
+ return *result;
}
F(StoreToSuper_Strict, 4, 1) \
F(StoreToSuper_Sloppy, 4, 1) \
F(StoreKeyedToSuper_Strict, 4, 1) \
- F(StoreKeyedToSuper_Sloppy, 4, 1)
+ F(StoreKeyedToSuper_Sloppy, 4, 1) \
+ F(DefaultConstructorSuperCall, 0, 1)
#define RUNTIME_FUNCTION_LIST_ALWAYS_2(F) \
MUST_USE_RESULT static MaybeHandle<Object> GetObjectProperty(
Isolate* isolate, Handle<Object> object, Handle<Object> key);
+ MUST_USE_RESULT static MaybeHandle<Object> GetPrototype(
+ Isolate* isolate, Handle<Object> object);
+
MUST_USE_RESULT static MaybeHandle<Name> ToName(Isolate* isolate,
Handle<Object> key);
})();
+(function TestDefaultConstructorArguments() {
+ var args, self;
+ class Base {
+ constructor() {
+ self = this;
+ args = arguments;
+ }
+ }
+ class Derived extends Base {}
+
+ new Derived;
+ assertEquals(0, args.length);
+
+ new Derived(0, 1, 2);
+ assertEquals(3, args.length);
+ assertTrue(self instanceof Derived);
+
+ var arr = new Array(100);
+ var obj = {};
+ Derived.apply(obj, arr);
+ assertEquals(100, args.length);
+ assertEquals(obj, self);
+})();
+
+
+(function TestDefaultConstructorArguments2() {
+ var args;
+ class Base {
+ constructor(x, y) {
+ args = arguments;
+ }
+ }
+ class Derived extends Base {}
+
+ new Derived;
+ assertEquals(0, args.length);
+
+ new Derived(1);
+ assertEquals(1, args.length);
+ assertEquals(1, args[0]);
+
+ new Derived(1, 2, 3);
+ assertEquals(3, args.length);
+ assertEquals(1, args[0]);
+ assertEquals(2, args[1]);
+ assertEquals(3, args[2]);
+})();
+
+
/* TODO(arv): Implement
(function TestNameBindingInConstructor() {
class C {