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);
|
||||
__ 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));
|
||||
__ tst(scratch, Operand(1 << Map::kIsConstructor));
|
||||
__ b(eq, &slow_case);
|
||||
|
||||
// Ensure that {function} has an instance prototype.
|
||||
__ tst(scratch, Operand(1 << Map::kHasNonInstancePrototype));
|
||||
__ b(ne, &slow_case);
|
||||
|
||||
|
@ -1557,8 +1557,11 @@ void InstanceOfStub::Generate(MacroAssembler* masm) {
|
||||
__ JumpIfNotObjectType(function, function_map, scratch, JS_FUNCTION_TYPE,
|
||||
&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));
|
||||
__ Tbz(scratch, Map::kIsConstructor, &slow_case);
|
||||
|
||||
// Ensure that {function} has an instance prototype.
|
||||
__ Tbnz(scratch, Map::kHasNonInstancePrototype, &slow_case);
|
||||
|
||||
// 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);
|
||||
__ 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.
|
||||
__ test_b(FieldOperand(function_map, Map::kBitFieldOffset),
|
||||
static_cast<uint8_t>(1 << Map::kHasNonInstancePrototype));
|
||||
|
@ -1503,8 +1503,12 @@ void InstanceOfStub::Generate(MacroAssembler* masm) {
|
||||
__ GetObjectType(function, function_map, scratch);
|
||||
__ 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));
|
||||
__ 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));
|
||||
__ Branch(&slow_case, ne, at, Operand(zero_reg));
|
||||
|
||||
|
@ -1499,8 +1499,12 @@ void InstanceOfStub::Generate(MacroAssembler* masm) {
|
||||
__ GetObjectType(function, function_map, scratch);
|
||||
__ 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));
|
||||
__ 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));
|
||||
__ Branch(&slow_case, ne, at, Operand(zero_reg));
|
||||
|
||||
|
@ -2092,6 +2092,11 @@ void InstanceOfStub::Generate(MacroAssembler* masm) {
|
||||
__ CmpObjectType(function, JS_FUNCTION_TYPE, function_map);
|
||||
__ 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.
|
||||
__ testb(FieldOperand(function_map, Map::kBitFieldOffset),
|
||||
Immediate(1 << Map::kHasNonInstancePrototype));
|
||||
|
@ -9,7 +9,7 @@ var throw_type_error = Object.getOwnPropertyDescriptor(
|
||||
|
||||
function create_initial_map() { this instanceof throw_type_error }
|
||||
%OptimizeFunctionOnNextCall(create_initial_map);
|
||||
create_initial_map();
|
||||
assertThrows(create_initial_map);
|
||||
|
||||
function test() { new throw_type_error }
|
||||
%OptimizeFunctionOnNextCall(test);
|
||||
|
Loading…
Reference in New Issue
Block a user