Fix Object.prototype.toString.call(proxy)
BUG= Review URL: https://codereview.chromium.org/1517673002 Cr-Commit-Position: refs/heads/master@{#32806}
This commit is contained in:
parent
cf46317483
commit
a1e9ccf90f
@ -1449,7 +1449,7 @@ void MacroAssembler::IsInstanceJSObjectType(Register map,
|
||||
Ldrb(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset));
|
||||
// If cmp result is lt, the following ccmp will clear all flags.
|
||||
// Z == 0, N == V implies gt condition.
|
||||
Cmp(scratch, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
|
||||
Cmp(scratch, FIRST_JS_RECEIVER_TYPE);
|
||||
Ccmp(scratch, LAST_NONCALLABLE_SPEC_OBJECT_TYPE, NoFlag, ge);
|
||||
|
||||
// If we didn't get a valid label object just fall through and leave the
|
||||
|
@ -2255,6 +2255,7 @@ void Genesis::InstallJSProxyMaps() {
|
||||
Handle<Map> proxy_callable_map = Map::Copy(proxy_map, "callable Proxy");
|
||||
proxy_callable_map->set_is_callable();
|
||||
native_context()->set_proxy_callable_map(*proxy_callable_map);
|
||||
proxy_callable_map->SetConstructor(native_context()->function_function());
|
||||
|
||||
Handle<Map> proxy_constructor_map =
|
||||
Map::Copy(proxy_callable_map, "constructor Proxy");
|
||||
@ -2276,8 +2277,8 @@ void Genesis::InitializeGlobal_harmony_proxies() {
|
||||
Handle<String> name = factory->Proxy_string();
|
||||
Handle<Code> code(isolate->builtins()->ProxyConstructor());
|
||||
|
||||
Handle<JSFunction> proxy_function =
|
||||
factory->NewFunction(isolate->proxy_function_map(), name, code);
|
||||
Handle<JSFunction> proxy_function = factory->NewFunction(
|
||||
isolate->proxy_function_map(), factory->Object_string(), code);
|
||||
|
||||
JSFunction::SetInitialMap(proxy_function,
|
||||
Handle<Map>(native_context()->proxy_map(), isolate),
|
||||
@ -2289,7 +2290,7 @@ void Genesis::InitializeGlobal_harmony_proxies() {
|
||||
proxy_function->shared()->set_length(2);
|
||||
|
||||
native_context()->set_proxy_function(*proxy_function);
|
||||
InstallFunction(global, name, proxy_function, name);
|
||||
InstallFunction(global, name, proxy_function, factory->Object_string());
|
||||
}
|
||||
|
||||
|
||||
|
@ -2542,14 +2542,11 @@ void LCodeGen::EmitClassOfTest(Label* is_true,
|
||||
// Assuming the following assertions, we can use the same compares to test
|
||||
// for both being a function type and being in the object type range.
|
||||
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
|
||||
STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
FIRST_JS_RECEIVER_TYPE + 1);
|
||||
STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
LAST_JS_RECEIVER_TYPE - 1);
|
||||
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
|
||||
__ CompareObjectType(input, temp, temp2, FIRST_JS_RECEIVER_TYPE);
|
||||
__ b(lt, is_false);
|
||||
__ b(eq, is_true);
|
||||
__ cmp(temp2, Operand(LAST_JS_RECEIVER_TYPE));
|
||||
__ b(eq, is_true);
|
||||
} else {
|
||||
@ -2557,9 +2554,9 @@ void LCodeGen::EmitClassOfTest(Label* is_true,
|
||||
// actual type and do a signed compare with the width of the type range.
|
||||
__ ldr(temp, FieldMemOperand(input, HeapObject::kMapOffset));
|
||||
__ ldrb(temp2, FieldMemOperand(temp, Map::kInstanceTypeOffset));
|
||||
__ sub(temp2, temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
|
||||
__ cmp(temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE -
|
||||
FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
|
||||
__ sub(temp2, temp2, Operand(FIRST_JS_RECEIVER_TYPE));
|
||||
__ cmp(temp2,
|
||||
Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE - FIRST_JS_RECEIVER_TYPE));
|
||||
__ b(gt, is_false);
|
||||
}
|
||||
|
||||
|
@ -2263,8 +2263,6 @@ void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
|
||||
// Assuming the following assertions, we can use the same compares to test
|
||||
// for both being a function type and being in the object type range.
|
||||
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
|
||||
STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
FIRST_JS_RECEIVER_TYPE + 1);
|
||||
STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
LAST_JS_RECEIVER_TYPE - 1);
|
||||
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
|
||||
@ -2272,7 +2270,6 @@ void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
|
||||
// We expect CompareObjectType to load the object instance type in scratch1.
|
||||
__ CompareObjectType(input, map, scratch1, FIRST_JS_RECEIVER_TYPE);
|
||||
__ B(lt, false_label);
|
||||
__ B(eq, true_label);
|
||||
__ Cmp(scratch1, LAST_JS_RECEIVER_TYPE);
|
||||
__ B(eq, true_label);
|
||||
} else {
|
||||
|
@ -2445,14 +2445,11 @@ void LCodeGen::EmitClassOfTest(Label* is_true,
|
||||
// Assuming the following assertions, we can use the same compares to test
|
||||
// for both being a function type and being in the object type range.
|
||||
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
|
||||
STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
FIRST_JS_RECEIVER_TYPE + 1);
|
||||
STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
LAST_JS_RECEIVER_TYPE - 1);
|
||||
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
|
||||
__ CmpObjectType(input, FIRST_JS_RECEIVER_TYPE, temp);
|
||||
__ j(below, is_false);
|
||||
__ j(equal, is_true);
|
||||
__ CmpInstanceType(temp, LAST_JS_RECEIVER_TYPE);
|
||||
__ j(equal, is_true);
|
||||
} else {
|
||||
@ -2460,9 +2457,9 @@ void LCodeGen::EmitClassOfTest(Label* is_true,
|
||||
// actual type and do a signed compare with the width of the type range.
|
||||
__ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
|
||||
__ movzx_b(temp2, FieldOperand(temp, Map::kInstanceTypeOffset));
|
||||
__ sub(Operand(temp2), Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
|
||||
__ sub(Operand(temp2), Immediate(FIRST_JS_RECEIVER_TYPE));
|
||||
__ cmp(Operand(temp2), Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE -
|
||||
FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
|
||||
FIRST_JS_RECEIVER_TYPE));
|
||||
__ j(above, is_false);
|
||||
}
|
||||
|
||||
|
@ -2453,23 +2453,20 @@ void LCodeGen::EmitClassOfTest(Label* is_true,
|
||||
// Assuming the following assertions, we can use the same compares to test
|
||||
// for both being a function type and being in the object type range.
|
||||
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
|
||||
STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
FIRST_JS_RECEIVER_TYPE + 1);
|
||||
STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
LAST_JS_RECEIVER_TYPE - 1);
|
||||
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
|
||||
|
||||
__ GetObjectType(input, temp, temp2);
|
||||
__ Branch(is_false, lt, temp2, Operand(FIRST_JS_RECEIVER_TYPE));
|
||||
__ Branch(is_true, eq, temp2, Operand(FIRST_JS_RECEIVER_TYPE));
|
||||
__ Branch(is_true, eq, temp2, Operand(LAST_JS_RECEIVER_TYPE));
|
||||
} else {
|
||||
// Faster code path to avoid two compares: subtract lower bound from the
|
||||
// actual type and do a signed compare with the width of the type range.
|
||||
__ GetObjectType(input, temp, temp2);
|
||||
__ Subu(temp2, temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
|
||||
__ Subu(temp2, temp2, Operand(FIRST_JS_RECEIVER_TYPE));
|
||||
__ Branch(is_false, gt, temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE -
|
||||
FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
|
||||
FIRST_JS_RECEIVER_TYPE));
|
||||
}
|
||||
|
||||
// Now we are in the FIRST-LAST_NONCALLABLE_SPEC_OBJECT_TYPE range.
|
||||
|
@ -2574,23 +2574,20 @@ void LCodeGen::EmitClassOfTest(Label* is_true,
|
||||
// Assuming the following assertions, we can use the same compares to test
|
||||
// for both being a function type and being in the object type range.
|
||||
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
|
||||
STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
FIRST_JS_RECEIVER_TYPE + 1);
|
||||
STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
LAST_JS_RECEIVER_TYPE - 1);
|
||||
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
|
||||
|
||||
__ GetObjectType(input, temp, temp2);
|
||||
__ Branch(is_false, lt, temp2, Operand(FIRST_JS_RECEIVER_TYPE));
|
||||
__ Branch(is_true, eq, temp2, Operand(FIRST_JS_RECEIVER_TYPE));
|
||||
__ Branch(is_true, eq, temp2, Operand(LAST_JS_RECEIVER_TYPE));
|
||||
} else {
|
||||
// Faster code path to avoid two compares: subtract lower bound from the
|
||||
// actual type and do a signed compare with the width of the type range.
|
||||
__ GetObjectType(input, temp, temp2);
|
||||
__ Dsubu(temp2, temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
|
||||
__ Dsubu(temp2, temp2, Operand(FIRST_JS_RECEIVER_TYPE));
|
||||
__ Branch(is_false, gt, temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE -
|
||||
FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
|
||||
FIRST_JS_RECEIVER_TYPE));
|
||||
}
|
||||
|
||||
// Now we are in the FIRST-LAST_NONCALLABLE_SPEC_OBJECT_TYPE range.
|
||||
|
@ -2614,14 +2614,11 @@ void LCodeGen::EmitClassOfTest(Label* is_true, Label* is_false,
|
||||
// Assuming the following assertions, we can use the same compares to test
|
||||
// for both being a function type and being in the object type range.
|
||||
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
|
||||
STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
FIRST_JS_RECEIVER_TYPE + 1);
|
||||
STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
LAST_JS_RECEIVER_TYPE - 1);
|
||||
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
|
||||
__ CompareObjectType(input, temp, temp2, FIRST_JS_RECEIVER_TYPE);
|
||||
__ blt(is_false);
|
||||
__ beq(is_true);
|
||||
__ cmpi(temp2, Operand(LAST_JS_RECEIVER_TYPE));
|
||||
__ beq(is_true);
|
||||
} else {
|
||||
@ -2629,9 +2626,9 @@ void LCodeGen::EmitClassOfTest(Label* is_true, Label* is_false,
|
||||
// actual type and do a signed compare with the width of the type range.
|
||||
__ LoadP(temp, FieldMemOperand(input, HeapObject::kMapOffset));
|
||||
__ lbz(temp2, FieldMemOperand(temp, Map::kInstanceTypeOffset));
|
||||
__ subi(temp2, temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
|
||||
__ subi(temp2, temp2, Operand(FIRST_JS_RECEIVER_TYPE));
|
||||
__ cmpi(temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE -
|
||||
FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
|
||||
FIRST_JS_RECEIVER_TYPE));
|
||||
__ bgt(is_false);
|
||||
}
|
||||
|
||||
|
@ -2502,14 +2502,11 @@ void LCodeGen::EmitClassOfTest(Label* is_true,
|
||||
// Assuming the following assertions, we can use the same compares to test
|
||||
// for both being a function type and being in the object type range.
|
||||
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
|
||||
STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
FIRST_JS_RECEIVER_TYPE + 1);
|
||||
STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
LAST_JS_RECEIVER_TYPE - 1);
|
||||
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
|
||||
__ CmpObjectType(input, FIRST_JS_RECEIVER_TYPE, temp);
|
||||
__ j(below, is_false);
|
||||
__ j(equal, is_true);
|
||||
__ CmpInstanceType(temp, LAST_JS_RECEIVER_TYPE);
|
||||
__ j(equal, is_true);
|
||||
} else {
|
||||
@ -2517,9 +2514,9 @@ void LCodeGen::EmitClassOfTest(Label* is_true,
|
||||
// actual type and do a signed compare with the width of the type range.
|
||||
__ movp(temp, FieldOperand(input, HeapObject::kMapOffset));
|
||||
__ movzxbl(temp2, FieldOperand(temp, Map::kInstanceTypeOffset));
|
||||
__ subp(temp2, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
|
||||
__ subp(temp2, Immediate(FIRST_JS_RECEIVER_TYPE));
|
||||
__ cmpp(temp2, Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE -
|
||||
FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
|
||||
FIRST_JS_RECEIVER_TYPE));
|
||||
__ j(above, is_false);
|
||||
}
|
||||
|
||||
|
@ -2728,14 +2728,11 @@ void LCodeGen::EmitClassOfTest(Label* is_true,
|
||||
// Assuming the following assertions, we can use the same compares to test
|
||||
// for both being a function type and being in the object type range.
|
||||
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
|
||||
STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
FIRST_JS_RECEIVER_TYPE + 1);
|
||||
STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
LAST_JS_RECEIVER_TYPE - 1);
|
||||
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
|
||||
__ CmpObjectType(input, FIRST_JS_RECEIVER_TYPE, temp);
|
||||
__ j(below, is_false);
|
||||
__ j(equal, is_true);
|
||||
__ CmpInstanceType(temp, LAST_JS_RECEIVER_TYPE);
|
||||
__ j(equal, is_true);
|
||||
} else {
|
||||
@ -2743,9 +2740,9 @@ void LCodeGen::EmitClassOfTest(Label* is_true,
|
||||
// actual type and do a signed compare with the width of the type range.
|
||||
__ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
|
||||
__ movzx_b(temp2, FieldOperand(temp, Map::kInstanceTypeOffset));
|
||||
__ sub(Operand(temp2), Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
|
||||
__ sub(Operand(temp2), Immediate(FIRST_JS_RECEIVER_TYPE));
|
||||
__ cmp(Operand(temp2), Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE -
|
||||
FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
|
||||
FIRST_JS_RECEIVER_TYPE));
|
||||
__ j(above, is_false);
|
||||
}
|
||||
|
||||
|
@ -3326,9 +3326,6 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
|
||||
__ CompareObjectType(r0, r0, r1, FIRST_JS_RECEIVER_TYPE);
|
||||
// Map is now in r0.
|
||||
__ b(lt, &null);
|
||||
STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
FIRST_JS_RECEIVER_TYPE + 1);
|
||||
__ b(eq, &function);
|
||||
|
||||
__ cmp(r1, Operand(LAST_JS_RECEIVER_TYPE));
|
||||
STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
|
@ -3039,9 +3039,6 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
|
||||
// x10: object's map.
|
||||
// x11: object's type.
|
||||
__ B(lt, &null);
|
||||
STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
FIRST_JS_RECEIVER_TYPE + 1);
|
||||
__ B(eq, &function);
|
||||
|
||||
__ Cmp(x11, LAST_JS_RECEIVER_TYPE);
|
||||
STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
|
@ -3209,9 +3209,6 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
|
||||
__ CmpObjectType(eax, FIRST_JS_RECEIVER_TYPE, eax);
|
||||
// Map is now in eax.
|
||||
__ j(below, &null);
|
||||
STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
FIRST_JS_RECEIVER_TYPE + 1);
|
||||
__ j(equal, &function);
|
||||
|
||||
__ CmpInstanceType(eax, LAST_JS_RECEIVER_TYPE);
|
||||
STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
|
@ -3320,10 +3320,6 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
|
||||
__ GetObjectType(v0, v0, a1); // Map is now in v0.
|
||||
__ Branch(&null, lt, a1, Operand(FIRST_JS_RECEIVER_TYPE));
|
||||
|
||||
STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
FIRST_JS_RECEIVER_TYPE + 1);
|
||||
__ Branch(&function, eq, a1, Operand(FIRST_JS_RECEIVER_TYPE));
|
||||
|
||||
STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
LAST_JS_RECEIVER_TYPE - 1);
|
||||
__ Branch(&function, eq, a1, Operand(LAST_JS_RECEIVER_TYPE));
|
||||
|
@ -3326,10 +3326,6 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
|
||||
__ GetObjectType(v0, v0, a1); // Map is now in v0.
|
||||
__ Branch(&null, lt, a1, Operand(FIRST_JS_RECEIVER_TYPE));
|
||||
|
||||
STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
FIRST_JS_RECEIVER_TYPE + 1);
|
||||
__ Branch(&function, eq, a1, Operand(FIRST_JS_RECEIVER_TYPE));
|
||||
|
||||
STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
LAST_JS_RECEIVER_TYPE - 1);
|
||||
__ Branch(&function, eq, a1, Operand(LAST_JS_RECEIVER_TYPE));
|
||||
|
@ -3325,9 +3325,6 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
|
||||
__ CompareObjectType(r3, r3, r4, FIRST_JS_RECEIVER_TYPE);
|
||||
// Map is now in r3.
|
||||
__ blt(&null);
|
||||
STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
FIRST_JS_RECEIVER_TYPE + 1);
|
||||
__ beq(&function);
|
||||
|
||||
__ cmpi(r4, Operand(LAST_JS_RECEIVER_TYPE));
|
||||
STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == LAST_JS_RECEIVER_TYPE - 1);
|
||||
|
@ -3196,9 +3196,6 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
|
||||
__ CmpObjectType(rax, FIRST_JS_RECEIVER_TYPE, rax);
|
||||
// Map is now in rax.
|
||||
__ j(below, &null);
|
||||
STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
FIRST_JS_RECEIVER_TYPE + 1);
|
||||
__ j(equal, &function);
|
||||
|
||||
__ CmpInstanceType(rax, LAST_JS_RECEIVER_TYPE);
|
||||
STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
|
@ -3202,9 +3202,6 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
|
||||
__ CmpObjectType(eax, FIRST_JS_RECEIVER_TYPE, eax);
|
||||
// Map is now in eax.
|
||||
__ j(below, &null);
|
||||
STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
FIRST_JS_RECEIVER_TYPE + 1);
|
||||
__ j(equal, &function);
|
||||
|
||||
__ CmpInstanceType(eax, LAST_JS_RECEIVER_TYPE);
|
||||
STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE ==
|
||||
|
27
test/mjsunit/es6/classof-proxy.js
Normal file
27
test/mjsunit/es6/classof-proxy.js
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright 2015 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 --harmony-proxies
|
||||
|
||||
function test_function(o) {
|
||||
if (%_ClassOf(o) === "Function") {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var non_callable = new Proxy({}, {});
|
||||
var callable = new Proxy(function(){}.__proto__, {});
|
||||
var constructable = new Proxy(function(){}, {});
|
||||
|
||||
assertFalse(test_function(non_callable));
|
||||
assertTrue(test_function(callable));
|
||||
assertTrue(test_function(constructable));
|
||||
|
||||
%OptimizeFunctionOnNextCall(test_function);
|
||||
|
||||
assertFalse(test_function(non_callable));
|
||||
assertTrue(test_function(callable));
|
||||
assertTrue(test_function(constructable));
|
Loading…
Reference in New Issue
Block a user