| 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 |