Commit 2aa070be authored by mvstanton's avatar mvstanton Committed by Commit bot

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}
parent 165b68e2
......@@ -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);
......
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