Chromium Code Reviews| Index: src/code-stub-assembler.cc |
| diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc |
| index c93af865c3418a16a36f2b24ee5f8d55fb7114ae..a2e571629ee09cb36f0ec5198b3dffb3bc4ed60e 100644 |
| --- a/src/code-stub-assembler.cc |
| +++ b/src/code-stub-assembler.cc |
| @@ -2880,6 +2880,13 @@ Node* CodeStubAssembler::IsCallableMap(Node* map) { |
| Int32Constant(0)); |
| } |
| +Node* CodeStubAssembler::IsConstructorMap(Node* map) { |
| + CSA_ASSERT(this, IsMap(map)); |
| + return Word32NotEqual( |
| + Word32And(LoadMapBitField(map), Int32Constant(1 << Map::kIsConstructor)), |
| + Int32Constant(0)); |
| +} |
| + |
| Node* CodeStubAssembler::IsSpecialReceiverInstanceType(Node* instance_type) { |
| STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); |
| return Int32LessThanOrEqual(instance_type, |
| @@ -5294,13 +5301,7 @@ Node* CodeStubAssembler::OrdinaryHasInstance(Node* context, Node* callable, |
| // Goto runtime if {callable} is not a constructor or has |
| // a non-instance "prototype". |
| - Node* callable_bitfield = LoadMapBitField(callable_map); |
| - GotoUnless( |
| - Word32Equal(Word32And(callable_bitfield, |
| - Int32Constant((1 << Map::kHasNonInstancePrototype) | |
| - (1 << Map::kIsConstructor))), |
| - Int32Constant(1 << Map::kIsConstructor)), |
| - &return_runtime); |
| + GotoUnless(IsConstructorMap(callable_map), &return_runtime); |
|
Benedikt Meurer
2016/12/08 18:42:24
This is not correct, as the original code also tes
Henrique Ferreiro
2016/12/09 13:24:28
Sorry, I should have double-checked. Anyway, is it
Benedikt Meurer
2016/12/09 18:30:28
Better do a separate CL for those. Unrelated chang
|
| // Get the "prototype" (or initial map) of the {callable}. |
| Node* callable_prototype = |
| @@ -7818,6 +7819,43 @@ Node* CodeStubAssembler::Typeof(Node* value, Node* context) { |
| return result_var.value(); |
| } |
| +Node* CodeStubAssembler::GetSuperConstructor(Node* active_function, |
| + Node* context) { |
| + Label is_not_object(this, Label::kDeferred), |
| + is_not_constructor(this, Label::kDeferred), out(this); |
| + Variable result(this, MachineRepresentation::kTagged); |
| + |
| + Node* map = LoadMap(active_function); |
| + Node* prototype = LoadMapPrototype(map); |
| + GotoIf(TaggedIsSmi(active_function), &is_not_object); |
| + |
| + Node* prototype_map = LoadMap(prototype); |
| + GotoUnless(IsConstructorMap(prototype_map), &is_not_constructor); |
| + |
| + result.Bind(prototype); |
| + Goto(&out); |
| + |
| + Bind(&is_not_object); |
| + { |
| + CallRuntime(Runtime::kThrowTypeError, context, |
| + SmiConstant(MessageTemplate::kMethodCalledOnWrongObject), |
| + HeapConstant(factory()->NewStringFromStaticChars("super"))); |
| + result.Bind(UndefinedConstant()); // Never reached. |
| + Goto(&out); |
| + } |
| + |
| + Bind(&is_not_constructor); |
| + { |
| + CallRuntime(Runtime::kThrowNotSuperConstructor, context, prototype, |
| + active_function); |
| + result.Bind(UndefinedConstant()); // Never reached. |
| + Goto(&out); |
| + } |
| + |
| + Bind(&out); |
| + return result.value(); |
| +} |
| + |
| Node* CodeStubAssembler::InstanceOf(Node* object, Node* callable, |
| Node* context) { |
| Label return_runtime(this, Label::kDeferred), end(this); |