Skip to content
This repository has been archived by the owner on Apr 3, 2020. It is now read-only.

Commit

Permalink
Fix %FunctionGetName and %_ClassOf for bound functions.
Browse files Browse the repository at this point in the history
[email protected]
BUG=v8:5010

Review-Url: https://codereview.chromium.org/1980463002
Cr-Commit-Position: refs/heads/master@{#36276}
  • Loading branch information
hashseed authored and Commit bot committed May 17, 2016
1 parent 551e0aa commit 8e303dd
Show file tree
Hide file tree
Showing 15 changed files with 64 additions and 34 deletions.
7 changes: 4 additions & 3 deletions src/crankshaft/arm/lithium-codegen-arm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2436,11 +2436,12 @@ void LCodeGen::EmitClassOfTest(Label* is_true,

__ JumpIfSmi(input, is_false);

__ CompareObjectType(input, temp, temp2, JS_FUNCTION_TYPE);
__ CompareObjectType(input, temp, temp2, FIRST_FUNCTION_TYPE);
STATIC_ASSERT(LAST_FUNCTION_TYPE == LAST_TYPE);
if (String::Equals(isolate()->factory()->Function_string(), class_name)) {
__ b(eq, is_true);
__ b(hs, is_true);
} else {
__ b(eq, is_false);
__ b(hs, is_false);
}

// Check if the constructor in the map is a function.
Expand Down
7 changes: 4 additions & 3 deletions src/crankshaft/arm64/lithium-codegen-arm64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2250,11 +2250,12 @@ void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
__ JumpIfSmi(input, false_label);

Register map = scratch2;
__ CompareObjectType(input, map, scratch1, JS_FUNCTION_TYPE);
__ CompareObjectType(input, map, scratch1, FIRST_FUNCTION_TYPE);
STATIC_ASSERT(LAST_FUNCTION_TYPE == LAST_TYPE);
if (String::Equals(isolate()->factory()->Function_string(), class_name)) {
__ B(eq, true_label);
__ B(hs, true_label);
} else {
__ B(eq, false_label);
__ B(hs, false_label);
}

// Check if the constructor in the map is a function.
Expand Down
7 changes: 4 additions & 3 deletions src/crankshaft/ia32/lithium-codegen-ia32.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2232,11 +2232,12 @@ void LCodeGen::EmitClassOfTest(Label* is_true,
DCHECK(!temp.is(temp2));
__ JumpIfSmi(input, is_false);

__ CmpObjectType(input, JS_FUNCTION_TYPE, temp);
__ CmpObjectType(input, FIRST_FUNCTION_TYPE, temp);
STATIC_ASSERT(LAST_FUNCTION_TYPE == LAST_TYPE);
if (String::Equals(isolate()->factory()->Function_string(), class_name)) {
__ j(equal, is_true);
__ j(above_equal, is_true);
} else {
__ j(equal, is_false);
__ j(above_equal, is_false);
}

// Now we are in the FIRST-LAST_NONCALLABLE_SPEC_OBJECT_TYPE range.
Expand Down
5 changes: 3 additions & 2 deletions src/crankshaft/mips/lithium-codegen-mips.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2324,10 +2324,11 @@ void LCodeGen::EmitClassOfTest(Label* is_true,

__ JumpIfSmi(input, is_false);
__ GetObjectType(input, temp, temp2);
STATIC_ASSERT(LAST_FUNCTION_TYPE == LAST_TYPE);
if (String::Equals(isolate()->factory()->Function_string(), class_name)) {
__ Branch(is_true, eq, temp2, Operand(JS_FUNCTION_TYPE));
__ Branch(is_true, hs, temp2, Operand(FIRST_FUNCTION_TYPE));
} else {
__ Branch(is_false, eq, temp2, Operand(JS_FUNCTION_TYPE));
__ Branch(is_false, hs, temp2, Operand(FIRST_FUNCTION_TYPE));
}

// Check if the constructor in the map is a function.
Expand Down
5 changes: 3 additions & 2 deletions src/crankshaft/mips64/lithium-codegen-mips64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2443,10 +2443,11 @@ void LCodeGen::EmitClassOfTest(Label* is_true,
__ JumpIfSmi(input, is_false);

__ GetObjectType(input, temp, temp2);
STATIC_ASSERT(LAST_FUNCTION_TYPE == LAST_TYPE);
if (String::Equals(isolate()->factory()->Function_string(), class_name)) {
__ Branch(is_true, eq, temp2, Operand(JS_FUNCTION_TYPE));
__ Branch(is_true, hs, temp2, Operand(FIRST_FUNCTION_TYPE));
} else {
__ Branch(is_false, eq, temp2, Operand(JS_FUNCTION_TYPE));
__ Branch(is_false, hs, temp2, Operand(FIRST_FUNCTION_TYPE));
}

// Now we are in the FIRST-LAST_NONCALLABLE_SPEC_OBJECT_TYPE range.
Expand Down
7 changes: 4 additions & 3 deletions src/crankshaft/x64/lithium-codegen-x64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2381,11 +2381,12 @@ void LCodeGen::EmitClassOfTest(Label* is_true,

__ JumpIfSmi(input, is_false);

__ CmpObjectType(input, JS_FUNCTION_TYPE, temp);
__ CmpObjectType(input, FIRST_FUNCTION_TYPE, temp);
STATIC_ASSERT(LAST_FUNCTION_TYPE == LAST_TYPE);
if (String::Equals(isolate()->factory()->Function_string(), class_name)) {
__ j(equal, is_true);
__ j(above_equal, is_true);
} else {
__ j(equal, is_false);
__ j(above_equal, is_false);
}

// Check if the constructor in the map is a function.
Expand Down
7 changes: 4 additions & 3 deletions src/full-codegen/arm/full-codegen-arm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2834,9 +2834,10 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
// Map is now in r0.
__ b(lt, &null);

// Return 'Function' for JSFunction objects.
__ cmp(r1, Operand(JS_FUNCTION_TYPE));
__ b(eq, &function);
// Return 'Function' for JSFunction and JSBoundFunction objects.
__ cmp(r1, Operand(FIRST_FUNCTION_TYPE));
STATIC_ASSERT(LAST_FUNCTION_TYPE == LAST_TYPE);
__ b(hs, &function);

// Check if the constructor in the map is a JS function.
Register instance_type = r2;
Expand Down
5 changes: 3 additions & 2 deletions src/full-codegen/arm64/full-codegen-arm64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2741,8 +2741,9 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
__ B(lt, &null);

// Return 'Function' for JSFunction objects.
__ Cmp(x11, JS_FUNCTION_TYPE);
__ B(eq, &function);
__ Cmp(x11, FIRST_FUNCTION_TYPE);
STATIC_ASSERT(LAST_FUNCTION_TYPE == LAST_TYPE);
__ B(hs, &function);

// Check if the constructor in the map is a JS function.
Register instance_type = x14;
Expand Down
7 changes: 4 additions & 3 deletions src/full-codegen/ia32/full-codegen-ia32.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2723,9 +2723,10 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
__ CmpObjectType(eax, FIRST_JS_RECEIVER_TYPE, eax);
__ j(below, &null, Label::kNear);

// Return 'Function' for JSFunction objects.
__ CmpInstanceType(eax, JS_FUNCTION_TYPE);
__ j(equal, &function, Label::kNear);
// Return 'Function' for JSFunction and JSBoundFunction objects.
__ CmpInstanceType(eax, FIRST_FUNCTION_TYPE);
STATIC_ASSERT(LAST_FUNCTION_TYPE == LAST_TYPE);
__ j(above_equal, &function, Label::kNear);

// Check if the constructor in the map is a JS function.
__ GetMapConstructor(eax, eax, ebx);
Expand Down
5 changes: 3 additions & 2 deletions src/full-codegen/mips/full-codegen-mips.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2839,8 +2839,9 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
__ GetObjectType(v0, v0, a1); // Map is now in v0.
__ Branch(&null, lt, a1, Operand(FIRST_JS_RECEIVER_TYPE));

// Return 'Function' for JSFunction objects.
__ Branch(&function, eq, a1, Operand(JS_FUNCTION_TYPE));
// Return 'Function' for JSFunction and JSBoundFunction objects.
STATIC_ASSERT(LAST_FUNCTION_TYPE == LAST_TYPE);
__ Branch(&function, hs, a1, Operand(FIRST_FUNCTION_TYPE));

// Check if the constructor in the map is a JS function.
Register instance_type = a2;
Expand Down
5 changes: 3 additions & 2 deletions src/full-codegen/mips64/full-codegen-mips64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2838,8 +2838,9 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
__ GetObjectType(v0, v0, a1); // Map is now in v0.
__ Branch(&null, lt, a1, Operand(FIRST_JS_RECEIVER_TYPE));

// Return 'Function' for JSFunction objects.
__ Branch(&function, eq, a1, Operand(JS_FUNCTION_TYPE));
// Return 'Function' for JSFunction and JSBoundFunction objects.
STATIC_ASSERT(LAST_FUNCTION_TYPE == LAST_TYPE);
__ Branch(&function, hs, a1, Operand(FIRST_FUNCTION_TYPE));

// Check if the constructor in the map is a JS function.
Register instance_type = a2;
Expand Down
7 changes: 4 additions & 3 deletions src/full-codegen/x64/full-codegen-x64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2712,9 +2712,10 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
__ CmpObjectType(rax, FIRST_JS_RECEIVER_TYPE, rax);
__ j(below, &null, Label::kNear);

// Return 'Function' for JSFunction objects.
__ CmpInstanceType(rax, JS_FUNCTION_TYPE);
__ j(equal, &function, Label::kNear);
// Return 'Function' for JSFunction and JSBoundFunction objects.
__ CmpInstanceType(rax, FIRST_FUNCTION_TYPE);
STATIC_ASSERT(LAST_FUNCTION_TYPE == LAST_TYPE);
__ j(above_equal, &function, Label::kNear);

// Check if the constructor in the map is a JS function.
__ GetMapConstructor(rax, rax, rbx);
Expand Down
14 changes: 11 additions & 3 deletions src/runtime/runtime-function.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,19 @@ namespace v8 {
namespace internal {

RUNTIME_FUNCTION(Runtime_FunctionGetName) {
SealHandleScope shs(isolate);
HandleScope scope(isolate);
DCHECK(args.length() == 1);

CONVERT_ARG_CHECKED(JSFunction, f, 0);
return f->shared()->name();
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
Handle<Object> result;
if (function->IsJSBoundFunction()) {
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result, JSBoundFunction::GetName(
isolate, Handle<JSBoundFunction>::cast(function)));
} else {
result = JSFunction::GetName(isolate, Handle<JSFunction>::cast(function));
}
return *result;
}


Expand Down
1 change: 1 addition & 0 deletions test/mjsunit/mirror-function.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,4 @@ function testFunctionMirror(f) {
testFunctionMirror(function(){});
testFunctionMirror(function a(){return 1;});
testFunctionMirror(Math.sin);
testFunctionMirror((function(){}).bind({}), "Object");
9 changes: 9 additions & 0 deletions test/mjsunit/regress/regress-5010.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright 2016 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.

// Flags: --allow-natives-syntax

var bound = (function(){}).bind({});
assertEquals("Function", %_ClassOf(bound));
assertEquals("Function", %ClassOf(bound));

0 comments on commit 8e303dd

Please sign in to comment.