Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(329)

Side by Side Diff: src/builtins/builtins-conversion.cc

Issue 2649093002: [builtins] Pass NotNullOrUndefined to ToPrimitive calls. (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/builtins/builtins-utils.h" 5 #include "src/builtins/builtins-utils.h"
6 #include "src/builtins/builtins.h" 6 #include "src/builtins/builtins.h"
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/code-stub-assembler.h" 8 #include "src/code-stub-assembler.h"
9 9
10 namespace v8 { 10 namespace v8 {
11 namespace internal { 11 namespace internal {
12 12
13 Handle<Code> Builtins::NonPrimitiveToPrimitive(ToPrimitiveHint hint) { 13 Handle<Code> Builtins::NonPrimitiveToPrimitive(ToPrimitiveHint hint) {
14 switch (hint) { 14 switch (hint) {
15 case ToPrimitiveHint::kDefault: 15 case ToPrimitiveHint::kDefault:
16 return NonPrimitiveToPrimitive_Default(); 16 return NonPrimitiveToPrimitive_Default();
17 case ToPrimitiveHint::kNumber: 17 case ToPrimitiveHint::kNumber:
18 return NonPrimitiveToPrimitive_Number(); 18 return NonPrimitiveToPrimitive_Number();
19 case ToPrimitiveHint::kString: 19 case ToPrimitiveHint::kString:
20 return NonPrimitiveToPrimitive_String(); 20 return NonPrimitiveToPrimitive_String();
21 } 21 }
22 UNREACHABLE(); 22 UNREACHABLE();
23 return Handle<Code>::null(); 23 return Handle<Code>::null();
24 } 24 }
25 25
26 namespace { 26 namespace {
27
27 // ES6 section 7.1.1 ToPrimitive ( input [ , PreferredType ] ) 28 // ES6 section 7.1.1 ToPrimitive ( input [ , PreferredType ] )
28 void Generate_NonPrimitiveToPrimitive(CodeStubAssembler* assembler, 29 void Generate_NonPrimitiveToPrimitive(CodeStubAssembler* assembler,
29 ToPrimitiveHint hint) { 30 ToPrimitiveHint hint) {
30 typedef CodeStubAssembler::Label Label; 31 typedef CodeStubAssembler::Label Label;
31 typedef compiler::Node Node; 32 typedef compiler::Node Node;
32 typedef TypeConversionDescriptor Descriptor; 33 typedef TypeConversionDescriptor Descriptor;
33 34
34 Node* input = assembler->Parameter(Descriptor::kArgument); 35 Node* input = assembler->Parameter(Descriptor::kArgument);
35 Node* context = assembler->Parameter(Descriptor::kContext); 36 Node* context = assembler->Parameter(Descriptor::kContext);
36 37
37 // Lookup the @@toPrimitive property on the {input}. 38 // Lookup the @@toPrimitive property on the {input}.
38 Callable callable = CodeFactory::GetProperty(assembler->isolate()); 39 Callable callable = CodeFactory::GetProperty(assembler->isolate());
39 Node* to_primitive_symbol = 40 Node* to_primitive_symbol =
40 assembler->HeapConstant(assembler->factory()->to_primitive_symbol()); 41 assembler->HeapConstant(assembler->factory()->to_primitive_symbol());
41 Node* exotic_to_prim = 42 Node* exotic_to_prim =
42 assembler->CallStub(callable, context, input, to_primitive_symbol); 43 assembler->CallStub(callable, context, input, to_primitive_symbol);
43 44
44 // Check if {exotic_to_prim} is neither null nor undefined. 45 // Check if {exotic_to_prim} is neither null nor undefined.
45 Label ordinary_to_primitive(assembler); 46 Label ordinary_to_primitive(assembler);
46 assembler->GotoIf( 47 assembler->GotoIf(
47 assembler->WordEqual(exotic_to_prim, assembler->NullConstant()), 48 assembler->WordEqual(exotic_to_prim, assembler->NullConstant()),
48 &ordinary_to_primitive); 49 &ordinary_to_primitive);
49 assembler->GotoIf( 50 assembler->GotoIf(
50 assembler->WordEqual(exotic_to_prim, assembler->UndefinedConstant()), 51 assembler->WordEqual(exotic_to_prim, assembler->UndefinedConstant()),
51 &ordinary_to_primitive); 52 &ordinary_to_primitive);
52 { 53 {
53 // Invoke the {exotic_to_prim} method on the {input} with a string 54 // Invoke the {exotic_to_prim} method on the {input} with a string
54 // representation of the {hint}. 55 // representation of the {hint}.
55 Callable callable = CodeFactory::Call(assembler->isolate()); 56 Callable callable = CodeFactory::Call(
57 assembler->isolate(), ConvertReceiverMode::kNotNullOrUndefined);
56 Node* hint_string = assembler->HeapConstant( 58 Node* hint_string = assembler->HeapConstant(
57 assembler->factory()->ToPrimitiveHintString(hint)); 59 assembler->factory()->ToPrimitiveHintString(hint));
58 Node* result = assembler->CallJS(callable, context, exotic_to_prim, input, 60 Node* result = assembler->CallJS(callable, context, exotic_to_prim, input,
59 hint_string); 61 hint_string);
60 62
61 // Verify that the {result} is actually a primitive. 63 // Verify that the {result} is actually a primitive.
62 Label if_resultisprimitive(assembler), 64 Label if_resultisprimitive(assembler),
63 if_resultisnotprimitive(assembler, Label::kDeferred); 65 if_resultisnotprimitive(assembler, Label::kDeferred);
64 assembler->GotoIf(assembler->TaggedIsSmi(result), &if_resultisprimitive); 66 assembler->GotoIf(assembler->TaggedIsSmi(result), &if_resultisprimitive);
65 Node* result_instance_type = assembler->LoadInstanceType(result); 67 Node* result_instance_type = assembler->LoadInstanceType(result);
(...skipping 20 matching lines...) Expand all
86 // Convert using the OrdinaryToPrimitive algorithm instead. 88 // Convert using the OrdinaryToPrimitive algorithm instead.
87 assembler->Bind(&ordinary_to_primitive); 89 assembler->Bind(&ordinary_to_primitive);
88 { 90 {
89 Callable callable = CodeFactory::OrdinaryToPrimitive( 91 Callable callable = CodeFactory::OrdinaryToPrimitive(
90 assembler->isolate(), (hint == ToPrimitiveHint::kString) 92 assembler->isolate(), (hint == ToPrimitiveHint::kString)
91 ? OrdinaryToPrimitiveHint::kString 93 ? OrdinaryToPrimitiveHint::kString
92 : OrdinaryToPrimitiveHint::kNumber); 94 : OrdinaryToPrimitiveHint::kNumber);
93 assembler->TailCallStub(callable, context, input); 95 assembler->TailCallStub(callable, context, input);
94 } 96 }
95 } 97 }
96 } // anonymous namespace 98
99 } // namespace
97 100
98 void Builtins::Generate_NonPrimitiveToPrimitive_Default( 101 void Builtins::Generate_NonPrimitiveToPrimitive_Default(
99 compiler::CodeAssemblerState* state) { 102 compiler::CodeAssemblerState* state) {
100 CodeStubAssembler assembler(state); 103 CodeStubAssembler assembler(state);
101 Generate_NonPrimitiveToPrimitive(&assembler, ToPrimitiveHint::kDefault); 104 Generate_NonPrimitiveToPrimitive(&assembler, ToPrimitiveHint::kDefault);
102 } 105 }
103 106
104 void Builtins::Generate_NonPrimitiveToPrimitive_Number( 107 void Builtins::Generate_NonPrimitiveToPrimitive_Number(
105 compiler::CodeAssemblerState* state) { 108 compiler::CodeAssemblerState* state) {
106 CodeStubAssembler assembler(state); 109 CodeStubAssembler assembler(state);
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 case OrdinaryToPrimitiveHint::kNumber: 217 case OrdinaryToPrimitiveHint::kNumber:
215 return OrdinaryToPrimitive_Number(); 218 return OrdinaryToPrimitive_Number();
216 case OrdinaryToPrimitiveHint::kString: 219 case OrdinaryToPrimitiveHint::kString:
217 return OrdinaryToPrimitive_String(); 220 return OrdinaryToPrimitive_String();
218 } 221 }
219 UNREACHABLE(); 222 UNREACHABLE();
220 return Handle<Code>::null(); 223 return Handle<Code>::null();
221 } 224 }
222 225
223 namespace { 226 namespace {
227
224 // 7.1.1.1 OrdinaryToPrimitive ( O, hint ) 228 // 7.1.1.1 OrdinaryToPrimitive ( O, hint )
225 void Generate_OrdinaryToPrimitive(CodeStubAssembler* assembler, 229 void Generate_OrdinaryToPrimitive(CodeStubAssembler* assembler,
226 OrdinaryToPrimitiveHint hint) { 230 OrdinaryToPrimitiveHint hint) {
227 typedef CodeStubAssembler::Label Label; 231 typedef CodeStubAssembler::Label Label;
228 typedef compiler::Node Node; 232 typedef compiler::Node Node;
229 typedef CodeStubAssembler::Variable Variable; 233 typedef CodeStubAssembler::Variable Variable;
230 typedef TypeConversionDescriptor Descriptor; 234 typedef TypeConversionDescriptor Descriptor;
231 235
232 Node* input = assembler->Parameter(Descriptor::kArgument); 236 Node* input = assembler->Parameter(Descriptor::kArgument);
233 Node* context = assembler->Parameter(Descriptor::kContext); 237 Node* context = assembler->Parameter(Descriptor::kContext);
(...skipping 22 matching lines...) Expand all
256 Label if_methodiscallable(assembler), 260 Label if_methodiscallable(assembler),
257 if_methodisnotcallable(assembler, Label::kDeferred); 261 if_methodisnotcallable(assembler, Label::kDeferred);
258 assembler->GotoIf(assembler->TaggedIsSmi(method), &if_methodisnotcallable); 262 assembler->GotoIf(assembler->TaggedIsSmi(method), &if_methodisnotcallable);
259 Node* method_map = assembler->LoadMap(method); 263 Node* method_map = assembler->LoadMap(method);
260 assembler->Branch(assembler->IsCallableMap(method_map), 264 assembler->Branch(assembler->IsCallableMap(method_map),
261 &if_methodiscallable, &if_methodisnotcallable); 265 &if_methodiscallable, &if_methodisnotcallable);
262 266
263 assembler->Bind(&if_methodiscallable); 267 assembler->Bind(&if_methodiscallable);
264 { 268 {
265 // Call the {method} on the {input}. 269 // Call the {method} on the {input}.
266 Callable callable = CodeFactory::Call(assembler->isolate()); 270 Callable callable = CodeFactory::Call(
271 assembler->isolate(), ConvertReceiverMode::kNotNullOrUndefined);
267 Node* result = assembler->CallJS(callable, context, method, input); 272 Node* result = assembler->CallJS(callable, context, method, input);
268 var_result.Bind(result); 273 var_result.Bind(result);
269 274
270 // Return the {result} if it is a primitive. 275 // Return the {result} if it is a primitive.
271 assembler->GotoIf(assembler->TaggedIsSmi(result), &return_result); 276 assembler->GotoIf(assembler->TaggedIsSmi(result), &return_result);
272 Node* result_instance_type = assembler->LoadInstanceType(result); 277 Node* result_instance_type = assembler->LoadInstanceType(result);
273 STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE); 278 STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE);
274 assembler->GotoIf(assembler->Int32LessThanOrEqual( 279 assembler->GotoIf(assembler->Int32LessThanOrEqual(
275 result_instance_type, 280 result_instance_type,
276 assembler->Int32Constant(LAST_PRIMITIVE_TYPE)), 281 assembler->Int32Constant(LAST_PRIMITIVE_TYPE)),
277 &return_result); 282 &return_result);
278 } 283 }
279 284
280 // Just continue with the next {name} if the {method} is not callable. 285 // Just continue with the next {name} if the {method} is not callable.
281 assembler->Goto(&if_methodisnotcallable); 286 assembler->Goto(&if_methodisnotcallable);
282 assembler->Bind(&if_methodisnotcallable); 287 assembler->Bind(&if_methodisnotcallable);
283 } 288 }
284 289
285 assembler->TailCallRuntime(Runtime::kThrowCannotConvertToPrimitive, context); 290 assembler->TailCallRuntime(Runtime::kThrowCannotConvertToPrimitive, context);
286 291
287 assembler->Bind(&return_result); 292 assembler->Bind(&return_result);
288 assembler->Return(var_result.value()); 293 assembler->Return(var_result.value());
289 } 294 }
290 } // anonymous namespace 295
296 } // namespace
291 297
292 void Builtins::Generate_OrdinaryToPrimitive_Number( 298 void Builtins::Generate_OrdinaryToPrimitive_Number(
293 compiler::CodeAssemblerState* state) { 299 compiler::CodeAssemblerState* state) {
294 CodeStubAssembler assembler(state); 300 CodeStubAssembler assembler(state);
295 Generate_OrdinaryToPrimitive(&assembler, OrdinaryToPrimitiveHint::kNumber); 301 Generate_OrdinaryToPrimitive(&assembler, OrdinaryToPrimitiveHint::kNumber);
296 } 302 }
297 303
298 void Builtins::Generate_OrdinaryToPrimitive_String( 304 void Builtins::Generate_OrdinaryToPrimitive_String(
299 compiler::CodeAssemblerState* state) { 305 compiler::CodeAssemblerState* state) {
300 CodeStubAssembler assembler(state); 306 CodeStubAssembler assembler(state);
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 CodeStubAssembler assembler(state); 498 CodeStubAssembler assembler(state);
493 499
494 Node* object = assembler.Parameter(Descriptor::kObject); 500 Node* object = assembler.Parameter(Descriptor::kObject);
495 Node* context = assembler.Parameter(Descriptor::kContext); 501 Node* context = assembler.Parameter(Descriptor::kContext);
496 502
497 assembler.Return(assembler.Typeof(object, context)); 503 assembler.Return(assembler.Typeof(object, context));
498 } 504 }
499 505
500 } // namespace internal 506 } // namespace internal
501 } // namespace v8 507 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698