OLD | NEW |
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 #include "src/property-descriptor.h" | 9 #include "src/property-descriptor.h" |
10 | 10 |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 assembler->factory()->NewStringFromStaticChars("]")); | 251 assembler->factory()->NewStringFromStaticChars("]")); |
252 | 252 |
253 Callable callable = CodeFactory::StringAdd( | 253 Callable callable = CodeFactory::StringAdd( |
254 assembler->isolate(), STRING_ADD_CHECK_NONE, NOT_TENURED); | 254 assembler->isolate(), STRING_ADD_CHECK_NONE, NOT_TENURED); |
255 | 255 |
256 assembler->Return(assembler->CallStub( | 256 assembler->Return(assembler->CallStub( |
257 callable, context, assembler->CallStub(callable, context, lhs, string), | 257 callable, context, assembler->CallStub(callable, context, lhs, string), |
258 rhs)); | 258 rhs)); |
259 } | 259 } |
260 | 260 |
261 void ReturnIfPrimitive(CodeStubAssembler* assembler, | |
262 compiler::Node* instance_type, | |
263 CodeStubAssembler::Label* return_string, | |
264 CodeStubAssembler::Label* return_boolean, | |
265 CodeStubAssembler::Label* return_number) { | |
266 assembler->GotoIf(assembler->IsStringInstanceType(instance_type), | |
267 return_string); | |
268 | |
269 assembler->GotoIf(assembler->Word32Equal( | |
270 instance_type, assembler->Int32Constant(ODDBALL_TYPE)), | |
271 return_boolean); | |
272 | |
273 assembler->GotoIf( | |
274 assembler->Word32Equal(instance_type, | |
275 assembler->Int32Constant(HEAP_NUMBER_TYPE)), | |
276 return_number); | |
277 } | |
278 | |
279 } // namespace | 261 } // namespace |
280 | 262 |
281 // ES6 section 19.1.3.6 Object.prototype.toString | 263 // ES6 section 19.1.3.6 Object.prototype.toString |
282 void Builtins::Generate_ObjectProtoToString( | 264 void Builtins::Generate_ObjectProtoToString( |
283 compiler::CodeAssemblerState* state) { | 265 compiler::CodeAssemblerState* state) { |
284 typedef compiler::Node Node; | 266 typedef compiler::Node Node; |
285 typedef CodeStubAssembler::Label Label; | 267 typedef CodeStubAssembler::Label Label; |
286 typedef CodeStubAssembler::Variable Variable; | 268 typedef CodeStubAssembler::Variable Variable; |
287 CodeStubAssembler assembler(state); | 269 CodeStubAssembler assembler(state); |
288 | 270 |
289 Label return_undefined(&assembler, Label::kDeferred), | 271 Label return_undefined(&assembler, Label::kDeferred), |
290 return_null(&assembler, Label::kDeferred), | 272 return_null(&assembler, Label::kDeferred), |
291 return_arguments(&assembler, Label::kDeferred), return_array(&assembler), | 273 return_arguments(&assembler, Label::kDeferred), return_array(&assembler), |
292 return_api(&assembler, Label::kDeferred), return_object(&assembler), | 274 return_api(&assembler, Label::kDeferred), return_object(&assembler), |
293 return_regexp(&assembler), return_function(&assembler), | 275 return_regexp(&assembler), return_function(&assembler), |
294 return_error(&assembler), return_date(&assembler), | 276 return_error(&assembler), return_date(&assembler), |
295 return_string(&assembler), return_boolean(&assembler), | 277 return_jsvalue(&assembler), return_jsproxy(&assembler, Label::kDeferred); |
296 return_jsvalue(&assembler), return_jsproxy(&assembler, Label::kDeferred), | |
297 return_number(&assembler); | |
298 | 278 |
299 Label if_isproxy(&assembler, Label::kDeferred); | 279 Label if_isproxy(&assembler, Label::kDeferred); |
300 | 280 |
301 Label checkstringtag(&assembler); | 281 Label checkstringtag(&assembler); |
302 Label if_tostringtag(&assembler), if_notostringtag(&assembler); | 282 Label if_tostringtag(&assembler), if_notostringtag(&assembler); |
303 | 283 |
304 Node* receiver = assembler.Parameter(0); | 284 Node* receiver = assembler.Parameter(0); |
305 Node* context = assembler.Parameter(3); | 285 Node* context = assembler.Parameter(3); |
306 | 286 |
307 assembler.GotoIf(assembler.WordEqual(receiver, assembler.UndefinedConstant()), | 287 assembler.GotoIf(assembler.WordEqual(receiver, assembler.UndefinedConstant()), |
308 &return_undefined); | 288 &return_undefined); |
309 | 289 |
310 assembler.GotoIf(assembler.WordEqual(receiver, assembler.NullConstant()), | 290 assembler.GotoIf(assembler.WordEqual(receiver, assembler.NullConstant()), |
311 &return_null); | 291 &return_null); |
312 | 292 |
313 assembler.GotoIf(assembler.TaggedIsSmi(receiver), &return_number); | 293 Callable to_object = CodeFactory::ToObject(assembler.isolate()); |
| 294 receiver = assembler.CallStub(to_object, context, receiver); |
314 | 295 |
315 Node* receiver_instance_type = assembler.LoadInstanceType(receiver); | 296 Node* receiver_instance_type = assembler.LoadInstanceType(receiver); |
316 ReturnIfPrimitive(&assembler, receiver_instance_type, &return_string, | |
317 &return_boolean, &return_number); | |
318 | 297 |
319 // for proxies, check IsArray before getting @@toStringTag | 298 // for proxies, check IsArray before getting @@toStringTag |
320 Variable var_proxy_is_array(&assembler, MachineRepresentation::kTagged); | 299 Variable var_proxy_is_array(&assembler, MachineRepresentation::kTagged); |
321 var_proxy_is_array.Bind(assembler.BooleanConstant(false)); | 300 var_proxy_is_array.Bind(assembler.BooleanConstant(false)); |
322 | 301 |
323 assembler.Branch( | 302 assembler.Branch( |
324 assembler.Word32Equal(receiver_instance_type, | 303 assembler.Word32Equal(receiver_instance_type, |
325 assembler.Int32Constant(JS_PROXY_TYPE)), | 304 assembler.Int32Constant(JS_PROXY_TYPE)), |
326 &if_isproxy, &checkstringtag); | 305 &if_isproxy, &checkstringtag); |
327 | 306 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 case_labels, arraysize(case_values)); | 361 case_labels, arraysize(case_values)); |
383 | 362 |
384 assembler.Bind(&return_undefined); | 363 assembler.Bind(&return_undefined); |
385 assembler.Return(assembler.HeapConstant( | 364 assembler.Return(assembler.HeapConstant( |
386 assembler.isolate()->factory()->undefined_to_string())); | 365 assembler.isolate()->factory()->undefined_to_string())); |
387 | 366 |
388 assembler.Bind(&return_null); | 367 assembler.Bind(&return_null); |
389 assembler.Return(assembler.HeapConstant( | 368 assembler.Return(assembler.HeapConstant( |
390 assembler.isolate()->factory()->null_to_string())); | 369 assembler.isolate()->factory()->null_to_string())); |
391 | 370 |
392 assembler.Bind(&return_number); | |
393 assembler.Return(assembler.HeapConstant( | |
394 assembler.isolate()->factory()->number_to_string())); | |
395 | |
396 assembler.Bind(&return_string); | |
397 assembler.Return(assembler.HeapConstant( | |
398 assembler.isolate()->factory()->string_to_string())); | |
399 | |
400 assembler.Bind(&return_boolean); | |
401 assembler.Return(assembler.HeapConstant( | |
402 assembler.isolate()->factory()->boolean_to_string())); | |
403 | |
404 assembler.Bind(&return_arguments); | 371 assembler.Bind(&return_arguments); |
405 assembler.Return(assembler.HeapConstant( | 372 assembler.Return(assembler.HeapConstant( |
406 assembler.isolate()->factory()->arguments_to_string())); | 373 assembler.isolate()->factory()->arguments_to_string())); |
407 | 374 |
408 assembler.Bind(&return_array); | 375 assembler.Bind(&return_array); |
409 assembler.Return(assembler.HeapConstant( | 376 assembler.Return(assembler.HeapConstant( |
410 assembler.isolate()->factory()->array_to_string())); | 377 assembler.isolate()->factory()->array_to_string())); |
411 | 378 |
412 assembler.Bind(&return_function); | 379 assembler.Bind(&return_function); |
413 assembler.Return(assembler.HeapConstant( | 380 assembler.Return(assembler.HeapConstant( |
(...skipping 13 matching lines...) Expand all Loading... |
427 | 394 |
428 assembler.Bind(&return_api); | 395 assembler.Bind(&return_api); |
429 { | 396 { |
430 Node* class_name = | 397 Node* class_name = |
431 assembler.CallRuntime(Runtime::kClassOf, context, receiver); | 398 assembler.CallRuntime(Runtime::kClassOf, context, receiver); |
432 ReturnToStringFormat(&assembler, context, class_name); | 399 ReturnToStringFormat(&assembler, context, class_name); |
433 } | 400 } |
434 | 401 |
435 assembler.Bind(&return_jsvalue); | 402 assembler.Bind(&return_jsvalue); |
436 { | 403 { |
| 404 Label return_boolean(&assembler), return_number(&assembler), |
| 405 return_string(&assembler); |
| 406 |
437 Node* value = assembler.LoadJSValueValue(receiver); | 407 Node* value = assembler.LoadJSValueValue(receiver); |
438 assembler.GotoIf(assembler.TaggedIsSmi(value), &return_number); | 408 assembler.GotoIf(assembler.TaggedIsSmi(value), &return_number); |
| 409 Node* instance_type = assembler.LoadInstanceType(value); |
439 | 410 |
440 ReturnIfPrimitive(&assembler, assembler.LoadInstanceType(value), | 411 assembler.GotoIf(assembler.IsStringInstanceType(instance_type), |
441 &return_string, &return_boolean, &return_number); | 412 &return_string); |
| 413 assembler.GotoIf( |
| 414 assembler.Word32Equal(instance_type, |
| 415 assembler.Int32Constant(HEAP_NUMBER_TYPE)), |
| 416 &return_number); |
| 417 assembler.GotoIf( |
| 418 assembler.Word32Equal(instance_type, |
| 419 assembler.Int32Constant(ODDBALL_TYPE)), |
| 420 &return_boolean); |
| 421 |
| 422 CSA_ASSERT(&assembler, |
| 423 assembler.Word32Equal(instance_type, |
| 424 assembler.Int32Constant(SYMBOL_TYPE))); |
442 assembler.Goto(&return_object); | 425 assembler.Goto(&return_object); |
| 426 |
| 427 assembler.Bind(&return_string); |
| 428 assembler.Return(assembler.HeapConstant( |
| 429 assembler.isolate()->factory()->string_to_string())); |
| 430 |
| 431 assembler.Bind(&return_number); |
| 432 assembler.Return(assembler.HeapConstant( |
| 433 assembler.isolate()->factory()->number_to_string())); |
| 434 |
| 435 assembler.Bind(&return_boolean); |
| 436 assembler.Return(assembler.HeapConstant( |
| 437 assembler.isolate()->factory()->boolean_to_string())); |
443 } | 438 } |
444 | 439 |
445 assembler.Bind(&return_jsproxy); | 440 assembler.Bind(&return_jsproxy); |
446 { | 441 { |
447 assembler.GotoIf(assembler.WordEqual(var_proxy_is_array.value(), | 442 assembler.GotoIf(assembler.WordEqual(var_proxy_is_array.value(), |
448 assembler.BooleanConstant(true)), | 443 assembler.BooleanConstant(true)), |
449 &return_array); | 444 &return_array); |
450 | 445 |
451 Node* map = assembler.LoadMap(receiver); | 446 Node* map = assembler.LoadMap(receiver); |
452 | 447 |
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1105 CodeStubAssembler assembler(state); | 1100 CodeStubAssembler assembler(state); |
1106 | 1101 |
1107 Node* object = assembler.Parameter(Descriptor::kObject); | 1102 Node* object = assembler.Parameter(Descriptor::kObject); |
1108 Node* context = assembler.Parameter(Descriptor::kContext); | 1103 Node* context = assembler.Parameter(Descriptor::kContext); |
1109 | 1104 |
1110 assembler.Return(assembler.GetSuperConstructor(object, context)); | 1105 assembler.Return(assembler.GetSuperConstructor(object, context)); |
1111 } | 1106 } |
1112 | 1107 |
1113 } // namespace internal | 1108 } // namespace internal |
1114 } // namespace v8 | 1109 } // namespace v8 |
OLD | NEW |