Commit bf782ec5 authored by petermarshall's avatar petermarshall Committed by Commit bot

[Builtins] Smi-check the spread and go to runtime in CheckSpreadAndPushToStack.

We did not smi-check the spread argument here, meaning we tried to take the map
of a smi, resulting in segfaults which clusterfuzz found.

Also added tests that exercise this path.

BUG=685086

Review-Url: https://codereview.chromium.org/2655013002
Cr-Commit-Position: refs/heads/master@{#42657}
parent 6053f4a3
......@@ -2632,10 +2632,11 @@ static void CheckSpreadAndPushToStack(MacroAssembler* masm) {
Register spread_len = r5;
Label runtime_call, push_args;
__ ldr(spread, MemOperand(sp, 0));
__ JumpIfSmi(spread, &runtime_call);
__ ldr(spread_map, FieldMemOperand(spread, HeapObject::kMapOffset));
Label runtime_call, push_args;
// Check that the spread is an array.
__ CompareInstanceType(spread_map, scratch, JS_ARRAY_TYPE);
__ b(ne, &runtime_call);
......
......@@ -2711,10 +2711,11 @@ static void CheckSpreadAndPushToStack(MacroAssembler* masm) {
Register spread_len = x5;
Label runtime_call, push_args;
__ Peek(spread, 0);
__ JumpIfSmi(spread, &runtime_call);
__ Ldr(spread_map, FieldMemOperand(spread, HeapObject::kMapOffset));
Label runtime_call, push_args;
// Check that the spread is an array.
__ CompareInstanceType(spread_map, scratch, JS_ARRAY_TYPE);
__ B(ne, &runtime_call);
......
......@@ -2690,10 +2690,11 @@ static void CheckSpreadAndPushToStack(MacroAssembler* masm) {
Register spread_len = edx;
Label runtime_call, push_args;
__ mov(spread, Operand(esp, kPointerSize));
__ JumpIfSmi(spread, &runtime_call);
__ mov(spread_map, FieldOperand(spread, HeapObject::kMapOffset));
Label runtime_call, push_args;
// Check that the spread is an array.
__ CmpInstanceType(spread_map, JS_ARRAY_TYPE);
__ j(not_equal, &runtime_call);
......
......@@ -2643,11 +2643,12 @@ static void CheckSpreadAndPushToStack(MacroAssembler* masm) {
Register native_context = t4;
Label runtime_call, push_args;
__ lw(spread, MemOperand(sp, 0));
__ JumpIfSmi(spread, &runtime_call);
__ lw(spread_map, FieldMemOperand(spread, HeapObject::kMapOffset));
__ lw(native_context, NativeContextMemOperand());
Label runtime_call, push_args;
// Check that the spread is an array.
__ lbu(scratch, FieldMemOperand(spread_map, Map::kInstanceTypeOffset));
__ Branch(&runtime_call, ne, scratch, Operand(JS_ARRAY_TYPE));
......
......@@ -2669,11 +2669,12 @@ static void CheckSpreadAndPushToStack(MacroAssembler* masm) {
Register native_context = a5;
Label runtime_call, push_args;
__ ld(spread, MemOperand(sp, 0));
__ JumpIfSmi(spread, &runtime_call);
__ ld(spread_map, FieldMemOperand(spread, HeapObject::kMapOffset));
__ ld(native_context, NativeContextMemOperand());
Label runtime_call, push_args;
// Check that the spread is an array.
__ lbu(scratch, FieldMemOperand(spread_map, Map::kInstanceTypeOffset));
__ Branch(&runtime_call, ne, scratch, Operand(JS_ARRAY_TYPE));
......
......@@ -2764,14 +2764,15 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode,
}
static void CheckSpreadAndPushToStack(MacroAssembler* masm) {
Label runtime_call, push_args;
// Load the spread argument into rbx.
__ movp(rbx, Operand(rsp, kPointerSize));
__ JumpIfSmi(rbx, &runtime_call);
// Load the map of the spread into r15.
__ movp(r15, FieldOperand(rbx, HeapObject::kMapOffset));
// Load native context into r14.
__ movp(r14, NativeContextOperand());
Label runtime_call, push_args;
// Check that the spread is an array.
__ CmpInstanceType(r15, JS_ARRAY_TYPE);
__ j(not_equal, &runtime_call);
......
......@@ -2722,10 +2722,11 @@ static void CheckSpreadAndPushToStack(MacroAssembler* masm) {
Register spread_len = edx;
Label runtime_call, push_args;
__ mov(spread, Operand(esp, kPointerSize));
__ JumpIfSmi(spread, &runtime_call);
__ mov(spread_map, FieldOperand(spread, HeapObject::kMapOffset));
Label runtime_call, push_args;
// Check that the spread is an array.
__ CmpInstanceType(spread_map, JS_ARRAY_TYPE);
__ j(not_equal, &runtime_call);
......
......@@ -49,6 +49,9 @@
return sum;
}
assertThrows(function() {
sum(...0);
}, TypeError);
assertEquals(void 0, sum(...""));
assertEquals(void 0, sum(...[]));
assertEquals(void 0, sum(...new Set));
......@@ -201,6 +204,9 @@
return sum;
}
assertThrows(function() {
sum(...0);
}, TypeError);
assertEquals(void 0, sum(...""));
assertEquals(void 0, sum(...[]));
assertEquals(void 0, sum(...new Set));
......
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
try {
Math.max(...0);
} catch (e) {
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment