diff --git a/include/v8-version.h b/include/v8-version.h index 76c90bd3e15..00eb7fc52ea 100644 --- a/include/v8-version.h +++ b/include/v8-version.h @@ -11,7 +11,7 @@ #define V8_MAJOR_VERSION 4 #define V8_MINOR_VERSION 2 #define V8_BUILD_NUMBER 77 -#define V8_PATCH_LEVEL 3 +#define V8_PATCH_LEVEL 4 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/src/arm/builtins-arm.cc b/src/arm/builtins-arm.cc index ba92ff8e34f..d13d4ffa25f 100644 --- a/src/arm/builtins-arm.cc +++ b/src/arm/builtins-arm.cc @@ -129,6 +129,7 @@ void Builtins::Generate_ArrayCode(MacroAssembler* masm) { __ Assert(eq, kUnexpectedInitialMapForArrayFunction); } + __ mov(r3, r1); // Run the native code for the Array function called as a normal function. // tail call a stub __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index ad04cb5454a..56a93274abe 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -2663,6 +2663,7 @@ void CallIC_ArrayStub::Generate(MacroAssembler* masm) { __ b(ne, &miss); __ mov(r2, r4); + __ mov(r3, r1); ArrayConstructorStub stub(masm->isolate(), arg_count()); __ TailCallStub(&stub); @@ -4573,6 +4574,7 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) { // -- r0 : argc (only if argument_count() == ANY) // -- r1 : constructor // -- r2 : AllocationSite or undefined + // -- r3 : original constructor // -- sp[0] : return address // -- sp[4] : last argument // ----------------------------------- @@ -4593,6 +4595,10 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) { __ AssertUndefinedOrAllocationSite(r2, r4); } + Label subclassing; + __ cmp(r3, r1); + __ b(ne, &subclassing); + Label no_info; // Get the elements kind and case on that. __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); @@ -4606,6 +4612,9 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) { __ bind(&no_info); GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); + + __ bind(&subclassing); + __ TailCallRuntime(Runtime::kThrowArrayNotSubclassableError, 0, 1); } diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc index 15958ccf545..7311d7e8c92 100644 --- a/src/arm/full-codegen-arm.cc +++ b/src/arm/full-codegen-arm.cc @@ -4230,6 +4230,7 @@ void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) { __ bind(&args_set_up); __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); + __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); CallConstructStub stub(isolate(), SUPER_CONSTRUCTOR_CALL); __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); diff --git a/src/arm64/builtins-arm64.cc b/src/arm64/builtins-arm64.cc index 8adec6a51e0..89e304051ab 100644 --- a/src/arm64/builtins-arm64.cc +++ b/src/arm64/builtins-arm64.cc @@ -126,6 +126,7 @@ void Builtins::Generate_ArrayCode(MacroAssembler* masm) { // Run the native code for the Array function called as a normal function. __ LoadRoot(x2, Heap::kUndefinedValueRootIndex); + __ Mov(x3, x1); ArrayConstructorStub stub(masm->isolate()); __ TailCallStub(&stub); } diff --git a/src/arm64/code-stubs-arm64.cc b/src/arm64/code-stubs-arm64.cc index 3179972d4bd..b8f63b40801 100644 --- a/src/arm64/code-stubs-arm64.cc +++ b/src/arm64/code-stubs-arm64.cc @@ -3071,6 +3071,9 @@ void CallIC_ArrayStub::Generate(MacroAssembler* masm) { Register allocation_site = feedback_vector; __ Mov(allocation_site, scratch); + + Register original_constructor = x3; + __ Mov(original_constructor, function); ArrayConstructorStub stub(masm->isolate(), arg_count()); __ TailCallStub(&stub); @@ -5006,11 +5009,13 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) { // -- x0 : argc (only if argument_count() == ANY) // -- x1 : constructor // -- x2 : AllocationSite or undefined + // -- x3 : original constructor // -- sp[0] : return address // -- sp[4] : last argument // ----------------------------------- Register constructor = x1; Register allocation_site = x2; + Register original_constructor = x3; if (FLAG_debug_code) { // The array construct code is only set for the global and natives @@ -5032,6 +5037,10 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) { __ AssertUndefinedOrAllocationSite(allocation_site, x10); } + Label subclassing; + __ Cmp(original_constructor, constructor); + __ B(ne, &subclassing); + Register kind = x3; Label no_info; // Get the elements kind and case on that. @@ -5045,6 +5054,9 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) { __ Bind(&no_info); GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); + + __ Bind(&subclassing); + __ TailCallRuntime(Runtime::kThrowArrayNotSubclassableError, 0, 1); } diff --git a/src/arm64/full-codegen-arm64.cc b/src/arm64/full-codegen-arm64.cc index 265f75f97c4..88b31a4da54 100644 --- a/src/arm64/full-codegen-arm64.cc +++ b/src/arm64/full-codegen-arm64.cc @@ -3937,6 +3937,7 @@ void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) { __ bind(&args_set_up); __ Peek(x1, Operand(x0, LSL, kPointerSizeLog2)); + __ LoadRoot(x2, Heap::kUndefinedValueRootIndex); CallConstructStub stub(isolate(), SUPER_CONSTRUCTOR_CALL); __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc index 537ffcd129c..9aa4e073f7f 100644 --- a/src/ia32/builtins-ia32.cc +++ b/src/ia32/builtins-ia32.cc @@ -1192,6 +1192,7 @@ void Builtins::Generate_ArrayCode(MacroAssembler* masm) { // Get the Array function. __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, edi); + __ mov(edx, edi); if (FLAG_debug_code) { // Initial map for the builtin Array function should be a map. diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc index b5cf5cec5c1..fff1e2fda32 100644 --- a/src/ia32/code-stubs-ia32.cc +++ b/src/ia32/code-stubs-ia32.cc @@ -2252,6 +2252,7 @@ void CallIC_ArrayStub::Generate(MacroAssembler* masm) { __ j(not_equal, &miss); __ mov(ebx, ecx); + __ mov(edx, edi); ArrayConstructorStub stub(masm->isolate(), arg_count()); __ TailCallStub(&stub); @@ -4630,6 +4631,7 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) { // -- eax : argc (only if argument_count() == ANY) // -- ebx : AllocationSite or undefined // -- edi : constructor + // -- edx : Original constructor // -- esp[0] : return address // -- esp[4] : last argument // ----------------------------------- @@ -4649,12 +4651,20 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) { __ AssertUndefinedOrAllocationSite(ebx); } + Label subclassing; + + __ cmp(edx, edi); + __ j(not_equal, &subclassing); + Label no_info; // If the feedback vector is the undefined value call an array constructor // that doesn't use AllocationSites. __ cmp(ebx, isolate()->factory()->undefined_value()); __ j(equal, &no_info); + __ cmp(edx, edi); + __ j(not_equal, &subclassing); + // Only look at the lower 16 bits of the transition info. __ mov(edx, FieldOperand(ebx, AllocationSite::kTransitionInfoOffset)); __ SmiUntag(edx); @@ -4664,6 +4674,9 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) { __ bind(&no_info); GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); + + __ bind(&subclassing); + __ TailCallRuntime(Runtime::kThrowArrayNotSubclassableError, 0, 1); } diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc index b76592238d7..cf181597aaa 100644 --- a/src/ia32/full-codegen-ia32.cc +++ b/src/ia32/full-codegen-ia32.cc @@ -4124,7 +4124,7 @@ void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) { __ bind(&args_set_up); __ mov(edi, Operand(esp, eax, times_pointer_size, 0)); - + __ mov(ebx, Immediate(isolate()->factory()->undefined_value())); CallConstructStub stub(isolate(), SUPER_CONSTRUCTOR_CALL); __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); diff --git a/src/messages.js b/src/messages.js index 049f7f602bd..b49556c6a1b 100644 --- a/src/messages.js +++ b/src/messages.js @@ -185,7 +185,8 @@ var kMessages = { super_constructor_call: ["A 'super' constructor call may only appear as the first statement of a function, and its arguments may not access 'this'. Other forms are not yet supported."], duplicate_proto: ["Duplicate __proto__ fields are not allowed in object literals"], param_after_rest: ["Rest parameter must be last formal parameter"], - constructor_noncallable: ["Class constructors cannot be invoked without 'new'"] + constructor_noncallable: ["Class constructors cannot be invoked without 'new'"], + array_not_subclassable: ["Subclassing Arrays is not currently supported."] }; diff --git a/src/mips/builtins-mips.cc b/src/mips/builtins-mips.cc index f4a34591961..42a0bbe58bc 100644 --- a/src/mips/builtins-mips.cc +++ b/src/mips/builtins-mips.cc @@ -138,6 +138,7 @@ void Builtins::Generate_ArrayCode(MacroAssembler* masm) { // Run the native code for the Array function called as a normal function. // Tail call a stub. + __ mov(a3, a1); __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); ArrayConstructorStub stub(masm->isolate()); __ TailCallStub(&stub); diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc index 74705f97efd..79546999837 100644 --- a/src/mips/code-stubs-mips.cc +++ b/src/mips/code-stubs-mips.cc @@ -2808,6 +2808,7 @@ void CallIC_ArrayStub::Generate(MacroAssembler* masm) { __ Branch(&miss, ne, t1, Operand(at)); __ mov(a2, t0); + __ mov(a3, a1); ArrayConstructorStub stub(masm->isolate(), arg_count()); __ TailCallStub(&stub); @@ -4799,6 +4800,7 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) { // -- a0 : argc (only if argument_count() == ANY) // -- a1 : constructor // -- a2 : AllocationSite or undefined + // -- a3 : Original constructor // -- sp[0] : return address // -- sp[4] : last argument // ----------------------------------- @@ -4821,6 +4823,9 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) { __ AssertUndefinedOrAllocationSite(a2, t0); } + Label subclassing; + __ Branch(&subclassing, ne, a1, Operand(a3)); + Label no_info; // Get the elements kind and case on that. __ LoadRoot(at, Heap::kUndefinedValueRootIndex); @@ -4834,6 +4839,9 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) { __ bind(&no_info); GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); + + __ bind(&subclassing); + __ TailCallRuntime(Runtime::kThrowArrayNotSubclassableError, 0, 1); } diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc index c5749fcf3a6..1f12011803d 100644 --- a/src/mips/full-codegen-mips.cc +++ b/src/mips/full-codegen-mips.cc @@ -4232,6 +4232,7 @@ void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) { __ sll(at, a0, kPointerSizeLog2); __ Addu(at, at, Operand(sp)); __ lw(a1, MemOperand(at, 0)); + __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); CallConstructStub stub(isolate(), SUPER_CONSTRUCTOR_CALL); __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); diff --git a/src/mips64/builtins-mips64.cc b/src/mips64/builtins-mips64.cc index 2d676a1fa96..89fda10b059 100644 --- a/src/mips64/builtins-mips64.cc +++ b/src/mips64/builtins-mips64.cc @@ -137,6 +137,7 @@ void Builtins::Generate_ArrayCode(MacroAssembler* masm) { // Run the native code for the Array function called as a normal function. // Tail call a stub. + __ mov(a3, a1); __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); ArrayConstructorStub stub(masm->isolate()); __ TailCallStub(&stub); diff --git a/src/mips64/code-stubs-mips64.cc b/src/mips64/code-stubs-mips64.cc index 5c1b8976998..cb889ca454b 100644 --- a/src/mips64/code-stubs-mips64.cc +++ b/src/mips64/code-stubs-mips64.cc @@ -2886,6 +2886,7 @@ void CallIC_ArrayStub::Generate(MacroAssembler* masm) { __ Branch(&miss, ne, a5, Operand(at)); __ mov(a2, a4); + __ mov(a3, a1); ArrayConstructorStub stub(masm->isolate(), arg_count()); __ TailCallStub(&stub); @@ -4842,6 +4843,7 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) { // -- a0 : argc (only if argument_count() == ANY) // -- a1 : constructor // -- a2 : AllocationSite or undefined + // -- a3 : original constructor // -- sp[0] : return address // -- sp[4] : last argument // ----------------------------------- @@ -4864,6 +4866,9 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) { __ AssertUndefinedOrAllocationSite(a2, a4); } + Label subclassing; + __ Branch(&subclassing, ne, a1, Operand(a3)); + Label no_info; // Get the elements kind and case on that. __ LoadRoot(at, Heap::kUndefinedValueRootIndex); @@ -4877,6 +4882,9 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) { __ bind(&no_info); GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); + + __ bind(&subclassing); + __ TailCallRuntime(Runtime::kThrowArrayNotSubclassableError, 0, 1); } diff --git a/src/mips64/full-codegen-mips64.cc b/src/mips64/full-codegen-mips64.cc index 5fe0c5a6ee9..c400a8ba334 100644 --- a/src/mips64/full-codegen-mips64.cc +++ b/src/mips64/full-codegen-mips64.cc @@ -4234,6 +4234,7 @@ void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) { __ dsll(at, a0, kPointerSizeLog2); __ Daddu(at, at, Operand(sp)); __ ld(a1, MemOperand(at, 0)); + __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); CallConstructStub stub(isolate(), SUPER_CONSTRUCTOR_CALL); __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); diff --git a/src/runtime/runtime-classes.cc b/src/runtime/runtime-classes.cc index 1be0341eae2..e88a76ac9e7 100644 --- a/src/runtime/runtime-classes.cc +++ b/src/runtime/runtime-classes.cc @@ -47,6 +47,15 @@ RUNTIME_FUNCTION(Runtime_ThrowConstructorNonCallableError) { } +RUNTIME_FUNCTION(Runtime_ThrowArrayNotSubclassableError) { + HandleScope scope(isolate); + DCHECK(args.length() == 0); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, + NewTypeError("array_not_subclassable", HandleVector(NULL, 0))); +} + + RUNTIME_FUNCTION(Runtime_ToMethod) { HandleScope scope(isolate); DCHECK(args.length() == 2); diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index 1ea85c83ab9..04107ee5423 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -191,6 +191,7 @@ namespace internal { F(LoadFromSuper, 3, 1) \ F(LoadKeyedFromSuper, 3, 1) \ F(ThrowConstructorNonCallableError, 0, 1) \ + F(ThrowArrayNotSubclassableError, 0, 1) \ F(ThrowNonMethodError, 0, 1) \ F(ThrowUnsupportedSuperError, 0, 1) \ F(HandleStepInForDerivedConstructors, 1, 1) \ diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc index 60a291acf5a..f43084b13f6 100644 --- a/src/x64/builtins-x64.cc +++ b/src/x64/builtins-x64.cc @@ -1272,6 +1272,7 @@ void Builtins::Generate_ArrayCode(MacroAssembler* masm) { __ Check(equal, kUnexpectedInitialMapForArrayFunction); } + __ movp(rdx, rdi); // Run the native code for the Array function called as a normal function. // tail call a stub __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index 23c43e359ba..9ef0c0330cb 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -2122,6 +2122,7 @@ void CallIC_ArrayStub::Generate(MacroAssembler* masm) { __ j(not_equal, &miss); __ movp(rbx, rcx); + __ movp(rdx, rdi); ArrayConstructorStub stub(masm->isolate(), arg_count()); __ TailCallStub(&stub); @@ -4573,6 +4574,7 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) { // -- rax : argc // -- rbx : AllocationSite or undefined // -- rdi : constructor + // -- rdx : original constructor // -- rsp[0] : return address // -- rsp[8] : last argument // ----------------------------------- @@ -4593,6 +4595,10 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) { __ AssertUndefinedOrAllocationSite(rbx); } + Label subclassing; + __ cmpp(rdi, rdx); + __ j(not_equal, &subclassing); + Label no_info; // If the feedback vector is the undefined value call an array constructor // that doesn't use AllocationSites. @@ -4608,6 +4614,9 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) { __ bind(&no_info); GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); + + __ bind(&subclassing); + __ TailCallRuntime(Runtime::kThrowArrayNotSubclassableError, 0, 1); } diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc index faf9e74dcf3..a64f504282b 100644 --- a/src/x64/full-codegen-x64.cc +++ b/src/x64/full-codegen-x64.cc @@ -4119,6 +4119,7 @@ void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) { __ bind(&args_set_up); __ movp(rdi, Operand(rsp, rax, times_pointer_size, 0)); + __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); CallConstructStub stub(isolate(), SUPER_CONSTRUCTOR_CALL); __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);