Skip to content

Commit

Permalink
deps: cherry-pick 2aa070be from V8 upstream
Browse files Browse the repository at this point in the history
Original commit message:

    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=

    Committed: https://crrev.com/2aa070be4fd2960df98905b254f12ed801ef26cd

    Cr-Commit-Position: refs/heads/master@{#34863}

This fixes the behavior of instanceof when the second parameter is not a
constructor.

Fixes: nodejs/node#7592
PR-URL: nodejs/node#7638
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
  • Loading branch information
fhinkel authored and evanlucas committed Jul 21, 2016
1 parent 71f84b5 commit e239045
Show file tree
Hide file tree
Showing 7 changed files with 30 additions and 5 deletions.
6 changes: 5 additions & 1 deletion deps/v8/src/arm/code-stubs-arm.cc
Expand Up @@ -1358,8 +1358,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);

Expand Down
5 changes: 4 additions & 1 deletion deps/v8/src/arm64/code-stubs-arm64.cc
Expand Up @@ -1544,8 +1544,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}.
Expand Down
5 changes: 5 additions & 0 deletions deps/v8/src/ia32/code-stubs-ia32.cc
Expand Up @@ -2110,6 +2110,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));
Expand Down
6 changes: 5 additions & 1 deletion deps/v8/src/mips/code-stubs-mips.cc
Expand Up @@ -1492,8 +1492,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));

Expand Down
6 changes: 5 additions & 1 deletion deps/v8/src/mips64/code-stubs-mips64.cc
Expand Up @@ -1488,8 +1488,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));

Expand Down
5 changes: 5 additions & 0 deletions deps/v8/src/x64/code-stubs-x64.cc
Expand Up @@ -2069,6 +2069,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));
Expand Down
2 changes: 1 addition & 1 deletion deps/v8/test/mjsunit/regress/regress-crbug-573858.js
Expand Up @@ -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);
Expand Down

0 comments on commit e239045

Please sign in to comment.