InstanceOfStub incorrectly interprets the hole as a prototype.
Repair this to match what the runtime correctly does, by first checking if the function is a constructor before we access the prototype. R=verwaest@chromium.org BUG= Review URL: https://codereview.chromium.org/1810953002 Cr-Commit-Position: refs/heads/master@{#34863}
This commit is contained in:
parent
165b68e227
commit
2aa070be4f
@ -1371,8 +1371,12 @@ void InstanceOfStub::Generate(MacroAssembler* masm) {
|
|||||||
__ CompareObjectType(function, function_map, scratch, JS_FUNCTION_TYPE);
|
__ CompareObjectType(function, function_map, scratch, JS_FUNCTION_TYPE);
|
||||||
__ b(ne, &slow_case);
|
__ b(ne, &slow_case);
|
||||||
|
|
||||||
// Ensure that {function} has an instance prototype.
|
// Go to the runtime if the function is not a constructor.
|
||||||
__ ldrb(scratch, FieldMemOperand(function_map, Map::kBitFieldOffset));
|
__ ldrb(scratch, FieldMemOperand(function_map, Map::kBitFieldOffset));
|
||||||
|
__ tst(scratch, Operand(1 << Map::kIsConstructor));
|
||||||
|
__ b(eq, &slow_case);
|
||||||
|
|
||||||
|
// Ensure that {function} has an instance prototype.
|
||||||
__ tst(scratch, Operand(1 << Map::kHasNonInstancePrototype));
|
__ tst(scratch, Operand(1 << Map::kHasNonInstancePrototype));
|
||||||
__ b(ne, &slow_case);
|
__ b(ne, &slow_case);
|
||||||
|
|
||||||
|
@ -1557,8 +1557,11 @@ void InstanceOfStub::Generate(MacroAssembler* masm) {
|
|||||||
__ JumpIfNotObjectType(function, function_map, scratch, JS_FUNCTION_TYPE,
|
__ JumpIfNotObjectType(function, function_map, scratch, JS_FUNCTION_TYPE,
|
||||||
&slow_case);
|
&slow_case);
|
||||||
|
|
||||||
// Ensure that {function} has an instance prototype.
|
// Go to the runtime if the function is not a constructor.
|
||||||
__ Ldrb(scratch, FieldMemOperand(function_map, Map::kBitFieldOffset));
|
__ Ldrb(scratch, FieldMemOperand(function_map, Map::kBitFieldOffset));
|
||||||
|
__ Tbz(scratch, Map::kIsConstructor, &slow_case);
|
||||||
|
|
||||||
|
// Ensure that {function} has an instance prototype.
|
||||||
__ Tbnz(scratch, Map::kHasNonInstancePrototype, &slow_case);
|
__ Tbnz(scratch, Map::kHasNonInstancePrototype, &slow_case);
|
||||||
|
|
||||||
// Get the "prototype" (or initial map) of the {function}.
|
// Get the "prototype" (or initial map) of the {function}.
|
||||||
|
@ -2137,6 +2137,11 @@ void InstanceOfStub::Generate(MacroAssembler* masm) {
|
|||||||
__ CmpObjectType(function, JS_FUNCTION_TYPE, function_map);
|
__ CmpObjectType(function, JS_FUNCTION_TYPE, function_map);
|
||||||
__ j(not_equal, &slow_case);
|
__ j(not_equal, &slow_case);
|
||||||
|
|
||||||
|
// Go to the runtime if the function is not a constructor.
|
||||||
|
__ test_b(FieldOperand(function_map, Map::kBitFieldOffset),
|
||||||
|
static_cast<uint8_t>(1 << Map::kIsConstructor));
|
||||||
|
__ j(zero, &slow_case);
|
||||||
|
|
||||||
// Ensure that {function} has an instance prototype.
|
// Ensure that {function} has an instance prototype.
|
||||||
__ test_b(FieldOperand(function_map, Map::kBitFieldOffset),
|
__ test_b(FieldOperand(function_map, Map::kBitFieldOffset),
|
||||||
static_cast<uint8_t>(1 << Map::kHasNonInstancePrototype));
|
static_cast<uint8_t>(1 << Map::kHasNonInstancePrototype));
|
||||||
|
@ -1503,8 +1503,12 @@ void InstanceOfStub::Generate(MacroAssembler* masm) {
|
|||||||
__ GetObjectType(function, function_map, scratch);
|
__ GetObjectType(function, function_map, scratch);
|
||||||
__ Branch(&slow_case, ne, scratch, Operand(JS_FUNCTION_TYPE));
|
__ Branch(&slow_case, ne, scratch, Operand(JS_FUNCTION_TYPE));
|
||||||
|
|
||||||
// Ensure that {function} has an instance prototype.
|
// Go to the runtime if the function is not a constructor.
|
||||||
__ lbu(scratch, FieldMemOperand(function_map, Map::kBitFieldOffset));
|
__ lbu(scratch, FieldMemOperand(function_map, Map::kBitFieldOffset));
|
||||||
|
__ And(at, scratch, Operand(1 << Map::kIsConstructor));
|
||||||
|
__ Branch(&slow_case, eq, at, Operand(zero_reg));
|
||||||
|
|
||||||
|
// Ensure that {function} has an instance prototype.
|
||||||
__ And(at, scratch, Operand(1 << Map::kHasNonInstancePrototype));
|
__ And(at, scratch, Operand(1 << Map::kHasNonInstancePrototype));
|
||||||
__ Branch(&slow_case, ne, at, Operand(zero_reg));
|
__ Branch(&slow_case, ne, at, Operand(zero_reg));
|
||||||
|
|
||||||
|
@ -1499,8 +1499,12 @@ void InstanceOfStub::Generate(MacroAssembler* masm) {
|
|||||||
__ GetObjectType(function, function_map, scratch);
|
__ GetObjectType(function, function_map, scratch);
|
||||||
__ Branch(&slow_case, ne, scratch, Operand(JS_FUNCTION_TYPE));
|
__ Branch(&slow_case, ne, scratch, Operand(JS_FUNCTION_TYPE));
|
||||||
|
|
||||||
// Ensure that {function} has an instance prototype.
|
// Go to the runtime if the function is not a constructor.
|
||||||
__ lbu(scratch, FieldMemOperand(function_map, Map::kBitFieldOffset));
|
__ lbu(scratch, FieldMemOperand(function_map, Map::kBitFieldOffset));
|
||||||
|
__ And(at, scratch, Operand(1 << Map::kIsConstructor));
|
||||||
|
__ Branch(&slow_case, eq, at, Operand(zero_reg));
|
||||||
|
|
||||||
|
// Ensure that {function} has an instance prototype.
|
||||||
__ And(at, scratch, Operand(1 << Map::kHasNonInstancePrototype));
|
__ And(at, scratch, Operand(1 << Map::kHasNonInstancePrototype));
|
||||||
__ Branch(&slow_case, ne, at, Operand(zero_reg));
|
__ Branch(&slow_case, ne, at, Operand(zero_reg));
|
||||||
|
|
||||||
|
@ -2092,6 +2092,11 @@ void InstanceOfStub::Generate(MacroAssembler* masm) {
|
|||||||
__ CmpObjectType(function, JS_FUNCTION_TYPE, function_map);
|
__ CmpObjectType(function, JS_FUNCTION_TYPE, function_map);
|
||||||
__ j(not_equal, &slow_case);
|
__ j(not_equal, &slow_case);
|
||||||
|
|
||||||
|
// Go to the runtime if the function is not a constructor.
|
||||||
|
__ testb(FieldOperand(function_map, Map::kBitFieldOffset),
|
||||||
|
Immediate(1 << Map::kIsConstructor));
|
||||||
|
__ j(zero, &slow_case);
|
||||||
|
|
||||||
// Ensure that {function} has an instance prototype.
|
// Ensure that {function} has an instance prototype.
|
||||||
__ testb(FieldOperand(function_map, Map::kBitFieldOffset),
|
__ testb(FieldOperand(function_map, Map::kBitFieldOffset),
|
||||||
Immediate(1 << Map::kHasNonInstancePrototype));
|
Immediate(1 << Map::kHasNonInstancePrototype));
|
||||||
|
@ -9,7 +9,7 @@ var throw_type_error = Object.getOwnPropertyDescriptor(
|
|||||||
|
|
||||||
function create_initial_map() { this instanceof throw_type_error }
|
function create_initial_map() { this instanceof throw_type_error }
|
||||||
%OptimizeFunctionOnNextCall(create_initial_map);
|
%OptimizeFunctionOnNextCall(create_initial_map);
|
||||||
create_initial_map();
|
assertThrows(create_initial_map);
|
||||||
|
|
||||||
function test() { new throw_type_error }
|
function test() { new throw_type_error }
|
||||||
%OptimizeFunctionOnNextCall(test);
|
%OptimizeFunctionOnNextCall(test);
|
||||||
|
Loading…
Reference in New Issue
Block a user