| 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.h" | 5 #include "src/builtins/builtins.h" |
| 6 #include "src/builtins/builtins-utils.h" | 6 #include "src/builtins/builtins-utils.h" |
| 7 | 7 |
| 8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
| 9 #include "src/property-descriptor.h" | 9 #include "src/property-descriptor.h" |
| 10 | 10 |
| 11 namespace v8 { | 11 namespace v8 { |
| 12 namespace internal { | 12 namespace internal { |
| 13 | 13 |
| 14 // ----------------------------------------------------------------------------- | 14 // ----------------------------------------------------------------------------- |
| 15 // ES6 section 19.1 Object Objects | 15 // ES6 section 19.1 Object Objects |
| 16 | 16 |
| 17 void Builtins::Generate_ObjectHasOwnProperty(CodeStubAssembler* assembler) { | 17 void Builtins::Generate_ObjectHasOwnProperty( |
| 18 compiler::CodeAssemblerState* state) { |
| 18 typedef compiler::Node Node; | 19 typedef compiler::Node Node; |
| 19 typedef CodeStubAssembler::Label Label; | 20 typedef CodeStubAssembler::Label Label; |
| 20 typedef CodeStubAssembler::Variable Variable; | 21 typedef CodeStubAssembler::Variable Variable; |
| 22 CodeStubAssembler assembler(state); |
| 21 | 23 |
| 22 Node* object = assembler->Parameter(0); | 24 Node* object = assembler.Parameter(0); |
| 23 Node* key = assembler->Parameter(1); | 25 Node* key = assembler.Parameter(1); |
| 24 Node* context = assembler->Parameter(4); | 26 Node* context = assembler.Parameter(4); |
| 25 | 27 |
| 26 Label call_runtime(assembler), return_true(assembler), | 28 Label call_runtime(&assembler), return_true(&assembler), |
| 27 return_false(assembler); | 29 return_false(&assembler); |
| 28 | 30 |
| 29 // Smi receivers do not have own properties. | 31 // Smi receivers do not have own properties. |
| 30 Label if_objectisnotsmi(assembler); | 32 Label if_objectisnotsmi(&assembler); |
| 31 assembler->Branch(assembler->TaggedIsSmi(object), &return_false, | 33 assembler.Branch(assembler.TaggedIsSmi(object), &return_false, |
| 32 &if_objectisnotsmi); | 34 &if_objectisnotsmi); |
| 33 assembler->Bind(&if_objectisnotsmi); | 35 assembler.Bind(&if_objectisnotsmi); |
| 34 | 36 |
| 35 Node* map = assembler->LoadMap(object); | 37 Node* map = assembler.LoadMap(object); |
| 36 Node* instance_type = assembler->LoadMapInstanceType(map); | 38 Node* instance_type = assembler.LoadMapInstanceType(map); |
| 37 | 39 |
| 38 Variable var_index(assembler, MachineType::PointerRepresentation()); | 40 Variable var_index(&assembler, MachineType::PointerRepresentation()); |
| 39 | 41 |
| 40 Label keyisindex(assembler), if_iskeyunique(assembler); | 42 Label keyisindex(&assembler), if_iskeyunique(&assembler); |
| 41 assembler->TryToName(key, &keyisindex, &var_index, &if_iskeyunique, | 43 assembler.TryToName(key, &keyisindex, &var_index, &if_iskeyunique, |
| 42 &call_runtime); | 44 &call_runtime); |
| 43 | 45 |
| 44 assembler->Bind(&if_iskeyunique); | 46 assembler.Bind(&if_iskeyunique); |
| 45 assembler->TryHasOwnProperty(object, map, instance_type, key, &return_true, | 47 assembler.TryHasOwnProperty(object, map, instance_type, key, &return_true, |
| 46 &return_false, &call_runtime); | 48 &return_false, &call_runtime); |
| 47 | 49 |
| 48 assembler->Bind(&keyisindex); | 50 assembler.Bind(&keyisindex); |
| 49 assembler->TryLookupElement(object, map, instance_type, var_index.value(), | 51 assembler.TryLookupElement(object, map, instance_type, var_index.value(), |
| 50 &return_true, &return_false, &call_runtime); | 52 &return_true, &return_false, &call_runtime); |
| 51 | 53 |
| 52 assembler->Bind(&return_true); | 54 assembler.Bind(&return_true); |
| 53 assembler->Return(assembler->BooleanConstant(true)); | 55 assembler.Return(assembler.BooleanConstant(true)); |
| 54 | 56 |
| 55 assembler->Bind(&return_false); | 57 assembler.Bind(&return_false); |
| 56 assembler->Return(assembler->BooleanConstant(false)); | 58 assembler.Return(assembler.BooleanConstant(false)); |
| 57 | 59 |
| 58 assembler->Bind(&call_runtime); | 60 assembler.Bind(&call_runtime); |
| 59 assembler->Return(assembler->CallRuntime(Runtime::kObjectHasOwnProperty, | 61 assembler.Return(assembler.CallRuntime(Runtime::kObjectHasOwnProperty, |
| 60 context, object, key)); | 62 context, object, key)); |
| 61 } | 63 } |
| 62 | 64 |
| 63 namespace { | 65 namespace { |
| 64 | 66 |
| 65 MUST_USE_RESULT Maybe<bool> FastAssign(Handle<JSReceiver> to, | 67 MUST_USE_RESULT Maybe<bool> FastAssign(Handle<JSReceiver> to, |
| 66 Handle<Object> next_source) { | 68 Handle<Object> next_source) { |
| 67 // Non-empty strings are the only non-JSReceivers that need to be handled | 69 // Non-empty strings are the only non-JSReceivers that need to be handled |
| 68 // explicitly by Object.assign. | 70 // explicitly by Object.assign. |
| 69 if (!next_source->IsJSReceiver()) { | 71 if (!next_source->IsJSReceiver()) { |
| 70 return Just(!next_source->IsString() || | 72 return Just(!next_source->IsString() || |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 | 268 |
| 267 assembler->GotoIf( | 269 assembler->GotoIf( |
| 268 assembler->Word32Equal(instance_type, | 270 assembler->Word32Equal(instance_type, |
| 269 assembler->Int32Constant(HEAP_NUMBER_TYPE)), | 271 assembler->Int32Constant(HEAP_NUMBER_TYPE)), |
| 270 return_number); | 272 return_number); |
| 271 } | 273 } |
| 272 | 274 |
| 273 } // namespace | 275 } // namespace |
| 274 | 276 |
| 275 // ES6 section 19.1.3.6 Object.prototype.toString | 277 // ES6 section 19.1.3.6 Object.prototype.toString |
| 276 void Builtins::Generate_ObjectProtoToString(CodeStubAssembler* assembler) { | 278 void Builtins::Generate_ObjectProtoToString( |
| 279 compiler::CodeAssemblerState* state) { |
| 277 typedef compiler::Node Node; | 280 typedef compiler::Node Node; |
| 278 typedef CodeStubAssembler::Label Label; | 281 typedef CodeStubAssembler::Label Label; |
| 279 typedef CodeStubAssembler::Variable Variable; | 282 typedef CodeStubAssembler::Variable Variable; |
| 283 CodeStubAssembler assembler(state); |
| 280 | 284 |
| 281 Label return_undefined(assembler, Label::kDeferred), | 285 Label return_undefined(&assembler, Label::kDeferred), |
| 282 return_null(assembler, Label::kDeferred), | 286 return_null(&assembler, Label::kDeferred), |
| 283 return_arguments(assembler, Label::kDeferred), return_array(assembler), | 287 return_arguments(&assembler, Label::kDeferred), return_array(&assembler), |
| 284 return_api(assembler, Label::kDeferred), return_object(assembler), | 288 return_api(&assembler, Label::kDeferred), return_object(&assembler), |
| 285 return_regexp(assembler), return_function(assembler), | 289 return_regexp(&assembler), return_function(&assembler), |
| 286 return_error(assembler), return_date(assembler), return_string(assembler), | 290 return_error(&assembler), return_date(&assembler), |
| 287 return_boolean(assembler), return_jsvalue(assembler), | 291 return_string(&assembler), return_boolean(&assembler), |
| 288 return_jsproxy(assembler, Label::kDeferred), return_number(assembler); | 292 return_jsvalue(&assembler), return_jsproxy(&assembler, Label::kDeferred), |
| 293 return_number(&assembler); |
| 289 | 294 |
| 290 Label if_isproxy(assembler, Label::kDeferred); | 295 Label if_isproxy(&assembler, Label::kDeferred); |
| 291 | 296 |
| 292 Label checkstringtag(assembler); | 297 Label checkstringtag(&assembler); |
| 293 Label if_tostringtag(assembler), if_notostringtag(assembler); | 298 Label if_tostringtag(&assembler), if_notostringtag(&assembler); |
| 294 | 299 |
| 295 Node* receiver = assembler->Parameter(0); | 300 Node* receiver = assembler.Parameter(0); |
| 296 Node* context = assembler->Parameter(3); | 301 Node* context = assembler.Parameter(3); |
| 297 | 302 |
| 298 assembler->GotoIf( | 303 assembler.GotoIf( |
| 299 assembler->Word32Equal(receiver, assembler->UndefinedConstant()), | 304 assembler.Word32Equal(receiver, assembler.UndefinedConstant()), |
| 300 &return_undefined); | 305 &return_undefined); |
| 301 | 306 |
| 302 assembler->GotoIf(assembler->Word32Equal(receiver, assembler->NullConstant()), | 307 assembler.GotoIf(assembler.Word32Equal(receiver, assembler.NullConstant()), |
| 303 &return_null); | 308 &return_null); |
| 304 | 309 |
| 305 assembler->GotoIf(assembler->TaggedIsSmi(receiver), &return_number); | 310 assembler.GotoIf(assembler.TaggedIsSmi(receiver), &return_number); |
| 306 | 311 |
| 307 Node* receiver_instance_type = assembler->LoadInstanceType(receiver); | 312 Node* receiver_instance_type = assembler.LoadInstanceType(receiver); |
| 308 ReturnIfPrimitive(assembler, receiver_instance_type, &return_string, | 313 ReturnIfPrimitive(&assembler, receiver_instance_type, &return_string, |
| 309 &return_boolean, &return_number); | 314 &return_boolean, &return_number); |
| 310 | 315 |
| 311 // for proxies, check IsArray before getting @@toStringTag | 316 // for proxies, check IsArray before getting @@toStringTag |
| 312 Variable var_proxy_is_array(assembler, MachineRepresentation::kTagged); | 317 Variable var_proxy_is_array(&assembler, MachineRepresentation::kTagged); |
| 313 var_proxy_is_array.Bind(assembler->BooleanConstant(false)); | 318 var_proxy_is_array.Bind(assembler.BooleanConstant(false)); |
| 314 | 319 |
| 315 assembler->Branch( | 320 assembler.Branch( |
| 316 assembler->Word32Equal(receiver_instance_type, | 321 assembler.Word32Equal(receiver_instance_type, |
| 317 assembler->Int32Constant(JS_PROXY_TYPE)), | 322 assembler.Int32Constant(JS_PROXY_TYPE)), |
| 318 &if_isproxy, &checkstringtag); | 323 &if_isproxy, &checkstringtag); |
| 319 | 324 |
| 320 assembler->Bind(&if_isproxy); | 325 assembler.Bind(&if_isproxy); |
| 321 { | 326 { |
| 322 // This can throw | 327 // This can throw |
| 323 var_proxy_is_array.Bind( | 328 var_proxy_is_array.Bind( |
| 324 assembler->CallRuntime(Runtime::kArrayIsArray, context, receiver)); | 329 assembler.CallRuntime(Runtime::kArrayIsArray, context, receiver)); |
| 325 assembler->Goto(&checkstringtag); | 330 assembler.Goto(&checkstringtag); |
| 326 } | 331 } |
| 327 | 332 |
| 328 assembler->Bind(&checkstringtag); | 333 assembler.Bind(&checkstringtag); |
| 329 { | 334 { |
| 330 Node* to_string_tag_symbol = assembler->HeapConstant( | 335 Node* to_string_tag_symbol = assembler.HeapConstant( |
| 331 assembler->isolate()->factory()->to_string_tag_symbol()); | 336 assembler.isolate()->factory()->to_string_tag_symbol()); |
| 332 | 337 |
| 333 GetPropertyStub stub(assembler->isolate()); | 338 GetPropertyStub stub(assembler.isolate()); |
| 334 Callable get_property = | 339 Callable get_property = |
| 335 Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); | 340 Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); |
| 336 Node* to_string_tag_value = assembler->CallStub( | 341 Node* to_string_tag_value = assembler.CallStub( |
| 337 get_property, context, receiver, to_string_tag_symbol); | 342 get_property, context, receiver, to_string_tag_symbol); |
| 338 | 343 |
| 339 IsString(assembler, to_string_tag_value, &if_tostringtag, | 344 IsString(&assembler, to_string_tag_value, &if_tostringtag, |
| 340 &if_notostringtag); | 345 &if_notostringtag); |
| 341 | 346 |
| 342 assembler->Bind(&if_tostringtag); | 347 assembler.Bind(&if_tostringtag); |
| 343 ReturnToStringFormat(assembler, context, to_string_tag_value); | 348 ReturnToStringFormat(&assembler, context, to_string_tag_value); |
| 344 } | 349 } |
| 345 assembler->Bind(&if_notostringtag); | 350 assembler.Bind(&if_notostringtag); |
| 346 { | 351 { |
| 347 size_t const kNumCases = 11; | 352 size_t const kNumCases = 11; |
| 348 Label* case_labels[kNumCases]; | 353 Label* case_labels[kNumCases]; |
| 349 int32_t case_values[kNumCases]; | 354 int32_t case_values[kNumCases]; |
| 350 case_labels[0] = &return_api; | 355 case_labels[0] = &return_api; |
| 351 case_values[0] = JS_API_OBJECT_TYPE; | 356 case_values[0] = JS_API_OBJECT_TYPE; |
| 352 case_labels[1] = &return_api; | 357 case_labels[1] = &return_api; |
| 353 case_values[1] = JS_SPECIAL_API_OBJECT_TYPE; | 358 case_values[1] = JS_SPECIAL_API_OBJECT_TYPE; |
| 354 case_labels[2] = &return_arguments; | 359 case_labels[2] = &return_arguments; |
| 355 case_values[2] = JS_ARGUMENTS_TYPE; | 360 case_values[2] = JS_ARGUMENTS_TYPE; |
| 356 case_labels[3] = &return_array; | 361 case_labels[3] = &return_array; |
| 357 case_values[3] = JS_ARRAY_TYPE; | 362 case_values[3] = JS_ARRAY_TYPE; |
| 358 case_labels[4] = &return_function; | 363 case_labels[4] = &return_function; |
| 359 case_values[4] = JS_BOUND_FUNCTION_TYPE; | 364 case_values[4] = JS_BOUND_FUNCTION_TYPE; |
| 360 case_labels[5] = &return_function; | 365 case_labels[5] = &return_function; |
| 361 case_values[5] = JS_FUNCTION_TYPE; | 366 case_values[5] = JS_FUNCTION_TYPE; |
| 362 case_labels[6] = &return_error; | 367 case_labels[6] = &return_error; |
| 363 case_values[6] = JS_ERROR_TYPE; | 368 case_values[6] = JS_ERROR_TYPE; |
| 364 case_labels[7] = &return_date; | 369 case_labels[7] = &return_date; |
| 365 case_values[7] = JS_DATE_TYPE; | 370 case_values[7] = JS_DATE_TYPE; |
| 366 case_labels[8] = &return_regexp; | 371 case_labels[8] = &return_regexp; |
| 367 case_values[8] = JS_REGEXP_TYPE; | 372 case_values[8] = JS_REGEXP_TYPE; |
| 368 case_labels[9] = &return_jsvalue; | 373 case_labels[9] = &return_jsvalue; |
| 369 case_values[9] = JS_VALUE_TYPE; | 374 case_values[9] = JS_VALUE_TYPE; |
| 370 case_labels[10] = &return_jsproxy; | 375 case_labels[10] = &return_jsproxy; |
| 371 case_values[10] = JS_PROXY_TYPE; | 376 case_values[10] = JS_PROXY_TYPE; |
| 372 | 377 |
| 373 assembler->Switch(receiver_instance_type, &return_object, case_values, | 378 assembler.Switch(receiver_instance_type, &return_object, case_values, |
| 374 case_labels, arraysize(case_values)); | 379 case_labels, arraysize(case_values)); |
| 375 | 380 |
| 376 assembler->Bind(&return_undefined); | 381 assembler.Bind(&return_undefined); |
| 377 assembler->Return(assembler->HeapConstant( | 382 assembler.Return(assembler.HeapConstant( |
| 378 assembler->isolate()->factory()->undefined_to_string())); | 383 assembler.isolate()->factory()->undefined_to_string())); |
| 379 | 384 |
| 380 assembler->Bind(&return_null); | 385 assembler.Bind(&return_null); |
| 381 assembler->Return(assembler->HeapConstant( | 386 assembler.Return(assembler.HeapConstant( |
| 382 assembler->isolate()->factory()->null_to_string())); | 387 assembler.isolate()->factory()->null_to_string())); |
| 383 | 388 |
| 384 assembler->Bind(&return_number); | 389 assembler.Bind(&return_number); |
| 385 assembler->Return(assembler->HeapConstant( | 390 assembler.Return(assembler.HeapConstant( |
| 386 assembler->isolate()->factory()->number_to_string())); | 391 assembler.isolate()->factory()->number_to_string())); |
| 387 | 392 |
| 388 assembler->Bind(&return_string); | 393 assembler.Bind(&return_string); |
| 389 assembler->Return(assembler->HeapConstant( | 394 assembler.Return(assembler.HeapConstant( |
| 390 assembler->isolate()->factory()->string_to_string())); | 395 assembler.isolate()->factory()->string_to_string())); |
| 391 | 396 |
| 392 assembler->Bind(&return_boolean); | 397 assembler.Bind(&return_boolean); |
| 393 assembler->Return(assembler->HeapConstant( | 398 assembler.Return(assembler.HeapConstant( |
| 394 assembler->isolate()->factory()->boolean_to_string())); | 399 assembler.isolate()->factory()->boolean_to_string())); |
| 395 | 400 |
| 396 assembler->Bind(&return_arguments); | 401 assembler.Bind(&return_arguments); |
| 397 assembler->Return(assembler->HeapConstant( | 402 assembler.Return(assembler.HeapConstant( |
| 398 assembler->isolate()->factory()->arguments_to_string())); | 403 assembler.isolate()->factory()->arguments_to_string())); |
| 399 | 404 |
| 400 assembler->Bind(&return_array); | 405 assembler.Bind(&return_array); |
| 401 assembler->Return(assembler->HeapConstant( | 406 assembler.Return(assembler.HeapConstant( |
| 402 assembler->isolate()->factory()->array_to_string())); | 407 assembler.isolate()->factory()->array_to_string())); |
| 403 | 408 |
| 404 assembler->Bind(&return_function); | 409 assembler.Bind(&return_function); |
| 405 assembler->Return(assembler->HeapConstant( | 410 assembler.Return(assembler.HeapConstant( |
| 406 assembler->isolate()->factory()->function_to_string())); | 411 assembler.isolate()->factory()->function_to_string())); |
| 407 | 412 |
| 408 assembler->Bind(&return_error); | 413 assembler.Bind(&return_error); |
| 409 assembler->Return(assembler->HeapConstant( | 414 assembler.Return(assembler.HeapConstant( |
| 410 assembler->isolate()->factory()->error_to_string())); | 415 assembler.isolate()->factory()->error_to_string())); |
| 411 | 416 |
| 412 assembler->Bind(&return_date); | 417 assembler.Bind(&return_date); |
| 413 assembler->Return(assembler->HeapConstant( | 418 assembler.Return(assembler.HeapConstant( |
| 414 assembler->isolate()->factory()->date_to_string())); | 419 assembler.isolate()->factory()->date_to_string())); |
| 415 | 420 |
| 416 assembler->Bind(&return_regexp); | 421 assembler.Bind(&return_regexp); |
| 417 assembler->Return(assembler->HeapConstant( | 422 assembler.Return(assembler.HeapConstant( |
| 418 assembler->isolate()->factory()->regexp_to_string())); | 423 assembler.isolate()->factory()->regexp_to_string())); |
| 419 | 424 |
| 420 assembler->Bind(&return_api); | 425 assembler.Bind(&return_api); |
| 421 { | 426 { |
| 422 Node* class_name = | 427 Node* class_name = |
| 423 assembler->CallRuntime(Runtime::kClassOf, context, receiver); | 428 assembler.CallRuntime(Runtime::kClassOf, context, receiver); |
| 424 ReturnToStringFormat(assembler, context, class_name); | 429 ReturnToStringFormat(&assembler, context, class_name); |
| 425 } | 430 } |
| 426 | 431 |
| 427 assembler->Bind(&return_jsvalue); | 432 assembler.Bind(&return_jsvalue); |
| 428 { | 433 { |
| 429 Node* value = assembler->LoadJSValueValue(receiver); | 434 Node* value = assembler.LoadJSValueValue(receiver); |
| 430 assembler->GotoIf(assembler->TaggedIsSmi(value), &return_number); | 435 assembler.GotoIf(assembler.TaggedIsSmi(value), &return_number); |
| 431 | 436 |
| 432 ReturnIfPrimitive(assembler, assembler->LoadInstanceType(value), | 437 ReturnIfPrimitive(&assembler, assembler.LoadInstanceType(value), |
| 433 &return_string, &return_boolean, &return_number); | 438 &return_string, &return_boolean, &return_number); |
| 434 assembler->Goto(&return_object); | 439 assembler.Goto(&return_object); |
| 435 } | 440 } |
| 436 | 441 |
| 437 assembler->Bind(&return_jsproxy); | 442 assembler.Bind(&return_jsproxy); |
| 438 { | 443 { |
| 439 assembler->GotoIf(assembler->WordEqual(var_proxy_is_array.value(), | 444 assembler.GotoIf(assembler.WordEqual(var_proxy_is_array.value(), |
| 440 assembler->BooleanConstant(true)), | 445 assembler.BooleanConstant(true)), |
| 441 &return_array); | 446 &return_array); |
| 442 | 447 |
| 443 Node* map = assembler->LoadMap(receiver); | 448 Node* map = assembler.LoadMap(receiver); |
| 444 | 449 |
| 445 // Return object if the proxy {receiver} is not callable. | 450 // Return object if the proxy {receiver} is not callable. |
| 446 assembler->Branch(assembler->IsCallableMap(map), &return_function, | 451 assembler.Branch(assembler.IsCallableMap(map), &return_function, |
| 447 &return_object); | 452 &return_object); |
| 448 } | 453 } |
| 449 | 454 |
| 450 // Default | 455 // Default |
| 451 assembler->Bind(&return_object); | 456 assembler.Bind(&return_object); |
| 452 assembler->Return(assembler->HeapConstant( | 457 assembler.Return(assembler.HeapConstant( |
| 453 assembler->isolate()->factory()->object_to_string())); | 458 assembler.isolate()->factory()->object_to_string())); |
| 454 } | 459 } |
| 455 } | 460 } |
| 456 | 461 |
| 457 void Builtins::Generate_ObjectCreate(CodeStubAssembler* a) { | 462 void Builtins::Generate_ObjectCreate(compiler::CodeAssemblerState* state) { |
| 458 typedef compiler::Node Node; | 463 typedef compiler::Node Node; |
| 459 typedef CodeStubAssembler::Label Label; | 464 typedef CodeStubAssembler::Label Label; |
| 460 typedef CodeStubAssembler::Variable Variable; | 465 typedef CodeStubAssembler::Variable Variable; |
| 466 CodeStubAssembler a(state); |
| 461 | 467 |
| 462 Node* prototype = a->Parameter(1); | 468 Node* prototype = a.Parameter(1); |
| 463 Node* properties = a->Parameter(2); | 469 Node* properties = a.Parameter(2); |
| 464 Node* context = a->Parameter(3 + 2); | 470 Node* context = a.Parameter(3 + 2); |
| 465 | 471 |
| 466 Label call_runtime(a, Label::kDeferred), prototype_valid(a), no_properties(a); | 472 Label call_runtime(&a, Label::kDeferred), prototype_valid(&a), |
| 473 no_properties(&a); |
| 467 { | 474 { |
| 468 a->Comment("Argument 1 check: prototype"); | 475 a.Comment("Argument 1 check: prototype"); |
| 469 a->GotoIf(a->WordEqual(prototype, a->NullConstant()), &prototype_valid); | 476 a.GotoIf(a.WordEqual(prototype, a.NullConstant()), &prototype_valid); |
| 470 a->BranchIfJSReceiver(prototype, &prototype_valid, &call_runtime); | 477 a.BranchIfJSReceiver(prototype, &prototype_valid, &call_runtime); |
| 471 } | 478 } |
| 472 | 479 |
| 473 a->Bind(&prototype_valid); | 480 a.Bind(&prototype_valid); |
| 474 { | 481 { |
| 475 a->Comment("Argument 2 check: properties"); | 482 a.Comment("Argument 2 check: properties"); |
| 476 // Check that we have a simple object | 483 // Check that we have a simple object |
| 477 a->GotoIf(a->TaggedIsSmi(properties), &call_runtime); | 484 a.GotoIf(a.TaggedIsSmi(properties), &call_runtime); |
| 478 // Undefined implies no properties. | 485 // Undefined implies no properties. |
| 479 a->GotoIf(a->WordEqual(properties, a->UndefinedConstant()), &no_properties); | 486 a.GotoIf(a.WordEqual(properties, a.UndefinedConstant()), &no_properties); |
| 480 Node* properties_map = a->LoadMap(properties); | 487 Node* properties_map = a.LoadMap(properties); |
| 481 a->GotoIf(a->IsSpecialReceiverMap(properties_map), &call_runtime); | 488 a.GotoIf(a.IsSpecialReceiverMap(properties_map), &call_runtime); |
| 482 // Stay on the fast path only if there are no elements. | 489 // Stay on the fast path only if there are no elements. |
| 483 a->GotoUnless(a->WordEqual(a->LoadElements(properties), | 490 a.GotoUnless(a.WordEqual(a.LoadElements(properties), |
| 484 a->LoadRoot(Heap::kEmptyFixedArrayRootIndex)), | 491 a.LoadRoot(Heap::kEmptyFixedArrayRootIndex)), |
| 485 &call_runtime); | 492 &call_runtime); |
| 486 // Handle dictionary objects or fast objects with properties in runtime. | 493 // Handle dictionary objects or fast objects with properties in runtime. |
| 487 Node* bit_field3 = a->LoadMapBitField3(properties_map); | 494 Node* bit_field3 = a.LoadMapBitField3(properties_map); |
| 488 a->GotoIf(a->IsSetWord32<Map::DictionaryMap>(bit_field3), &call_runtime); | 495 a.GotoIf(a.IsSetWord32<Map::DictionaryMap>(bit_field3), &call_runtime); |
| 489 a->Branch(a->IsSetWord32<Map::NumberOfOwnDescriptorsBits>(bit_field3), | 496 a.Branch(a.IsSetWord32<Map::NumberOfOwnDescriptorsBits>(bit_field3), |
| 490 &call_runtime, &no_properties); | 497 &call_runtime, &no_properties); |
| 491 } | 498 } |
| 492 | 499 |
| 493 // Create a new object with the given prototype. | 500 // Create a new object with the given prototype. |
| 494 a->Bind(&no_properties); | 501 a.Bind(&no_properties); |
| 495 { | 502 { |
| 496 Variable map(a, MachineRepresentation::kTagged); | 503 Variable map(&a, MachineRepresentation::kTagged); |
| 497 Variable properties(a, MachineRepresentation::kTagged); | 504 Variable properties(&a, MachineRepresentation::kTagged); |
| 498 Label non_null_proto(a), instantiate_map(a), good(a); | 505 Label non_null_proto(&a), instantiate_map(&a), good(&a); |
| 499 | 506 |
| 500 a->Branch(a->WordEqual(prototype, a->NullConstant()), &good, | 507 a.Branch(a.WordEqual(prototype, a.NullConstant()), &good, &non_null_proto); |
| 501 &non_null_proto); | |
| 502 | 508 |
| 503 a->Bind(&good); | 509 a.Bind(&good); |
| 504 { | 510 { |
| 505 map.Bind(a->LoadContextElement( | 511 map.Bind(a.LoadContextElement( |
| 506 context, Context::SLOW_OBJECT_WITH_NULL_PROTOTYPE_MAP)); | 512 context, Context::SLOW_OBJECT_WITH_NULL_PROTOTYPE_MAP)); |
| 507 properties.Bind( | 513 properties.Bind( |
| 508 a->AllocateNameDictionary(NameDictionary::kInitialCapacity)); | 514 a.AllocateNameDictionary(NameDictionary::kInitialCapacity)); |
| 509 a->Goto(&instantiate_map); | 515 a.Goto(&instantiate_map); |
| 510 } | 516 } |
| 511 | 517 |
| 512 a->Bind(&non_null_proto); | 518 a.Bind(&non_null_proto); |
| 513 { | 519 { |
| 514 properties.Bind(a->EmptyFixedArrayConstant()); | 520 properties.Bind(a.EmptyFixedArrayConstant()); |
| 515 Node* object_function = | 521 Node* object_function = |
| 516 a->LoadContextElement(context, Context::OBJECT_FUNCTION_INDEX); | 522 a.LoadContextElement(context, Context::OBJECT_FUNCTION_INDEX); |
| 517 Node* object_function_map = a->LoadObjectField( | 523 Node* object_function_map = a.LoadObjectField( |
| 518 object_function, JSFunction::kPrototypeOrInitialMapOffset); | 524 object_function, JSFunction::kPrototypeOrInitialMapOffset); |
| 519 map.Bind(object_function_map); | 525 map.Bind(object_function_map); |
| 520 a->GotoIf(a->WordEqual(prototype, a->LoadMapPrototype(map.value())), | 526 a.GotoIf(a.WordEqual(prototype, a.LoadMapPrototype(map.value())), |
| 521 &instantiate_map); | 527 &instantiate_map); |
| 522 // Try loading the prototype info. | 528 // Try loading the prototype info. |
| 523 Node* prototype_info = | 529 Node* prototype_info = |
| 524 a->LoadMapPrototypeInfo(a->LoadMap(prototype), &call_runtime); | 530 a.LoadMapPrototypeInfo(a.LoadMap(prototype), &call_runtime); |
| 525 a->Comment("Load ObjectCreateMap from PrototypeInfo"); | 531 a.Comment("Load ObjectCreateMap from PrototypeInfo"); |
| 526 Node* weak_cell = | 532 Node* weak_cell = |
| 527 a->LoadObjectField(prototype_info, PrototypeInfo::kObjectCreateMap); | 533 a.LoadObjectField(prototype_info, PrototypeInfo::kObjectCreateMap); |
| 528 a->GotoIf(a->WordEqual(weak_cell, a->UndefinedConstant()), &call_runtime); | 534 a.GotoIf(a.WordEqual(weak_cell, a.UndefinedConstant()), &call_runtime); |
| 529 map.Bind(a->LoadWeakCellValue(weak_cell, &call_runtime)); | 535 map.Bind(a.LoadWeakCellValue(weak_cell, &call_runtime)); |
| 530 a->Goto(&instantiate_map); | 536 a.Goto(&instantiate_map); |
| 531 } | 537 } |
| 532 | 538 |
| 533 a->Bind(&instantiate_map); | 539 a.Bind(&instantiate_map); |
| 534 { | 540 { |
| 535 Node* instance = | 541 Node* instance = |
| 536 a->AllocateJSObjectFromMap(map.value(), properties.value()); | 542 a.AllocateJSObjectFromMap(map.value(), properties.value()); |
| 537 a->Return(instance); | 543 a.Return(instance); |
| 538 } | 544 } |
| 539 } | 545 } |
| 540 | 546 |
| 541 a->Bind(&call_runtime); | 547 a.Bind(&call_runtime); |
| 542 { | 548 { |
| 543 a->Return( | 549 a.Return( |
| 544 a->CallRuntime(Runtime::kObjectCreate, context, prototype, properties)); | 550 a.CallRuntime(Runtime::kObjectCreate, context, prototype, properties)); |
| 545 } | 551 } |
| 546 } | 552 } |
| 547 | 553 |
| 548 // ES6 section 19.1.2.3 Object.defineProperties | 554 // ES6 section 19.1.2.3 Object.defineProperties |
| 549 BUILTIN(ObjectDefineProperties) { | 555 BUILTIN(ObjectDefineProperties) { |
| 550 HandleScope scope(isolate); | 556 HandleScope scope(isolate); |
| 551 DCHECK_EQ(3, args.length()); | 557 DCHECK_EQ(3, args.length()); |
| 552 Handle<Object> target = args.at<Object>(1); | 558 Handle<Object> target = args.at<Object>(1); |
| 553 Handle<Object> properties = args.at<Object>(2); | 559 Handle<Object> properties = args.at<Object>(2); |
| 554 | 560 |
| (...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1011 HandleScope scope(isolate); | 1017 HandleScope scope(isolate); |
| 1012 Handle<Object> object = args.atOrUndefined(isolate, 1); | 1018 Handle<Object> object = args.atOrUndefined(isolate, 1); |
| 1013 if (object->IsJSReceiver()) { | 1019 if (object->IsJSReceiver()) { |
| 1014 MAYBE_RETURN(JSReceiver::SetIntegrityLevel(Handle<JSReceiver>::cast(object), | 1020 MAYBE_RETURN(JSReceiver::SetIntegrityLevel(Handle<JSReceiver>::cast(object), |
| 1015 SEALED, Object::THROW_ON_ERROR), | 1021 SEALED, Object::THROW_ON_ERROR), |
| 1016 isolate->heap()->exception()); | 1022 isolate->heap()->exception()); |
| 1017 } | 1023 } |
| 1018 return *object; | 1024 return *object; |
| 1019 } | 1025 } |
| 1020 | 1026 |
| 1021 void Builtins::Generate_HasProperty(CodeStubAssembler* assembler) { | 1027 void Builtins::Generate_HasProperty(compiler::CodeAssemblerState* state) { |
| 1022 typedef HasPropertyDescriptor Descriptor; | 1028 typedef HasPropertyDescriptor Descriptor; |
| 1023 typedef compiler::Node Node; | 1029 typedef compiler::Node Node; |
| 1030 CodeStubAssembler assembler(state); |
| 1024 | 1031 |
| 1025 Node* key = assembler->Parameter(Descriptor::kKey); | 1032 Node* key = assembler.Parameter(Descriptor::kKey); |
| 1026 Node* object = assembler->Parameter(Descriptor::kObject); | 1033 Node* object = assembler.Parameter(Descriptor::kObject); |
| 1027 Node* context = assembler->Parameter(Descriptor::kContext); | 1034 Node* context = assembler.Parameter(Descriptor::kContext); |
| 1028 | 1035 |
| 1029 assembler->Return( | 1036 assembler.Return( |
| 1030 assembler->HasProperty(object, key, context, Runtime::kHasProperty)); | 1037 assembler.HasProperty(object, key, context, Runtime::kHasProperty)); |
| 1031 } | 1038 } |
| 1032 | 1039 |
| 1033 void Builtins::Generate_ForInFilter(CodeStubAssembler* assembler) { | 1040 void Builtins::Generate_ForInFilter(compiler::CodeAssemblerState* state) { |
| 1034 typedef compiler::Node Node; | 1041 typedef compiler::Node Node; |
| 1035 typedef ForInFilterDescriptor Descriptor; | 1042 typedef ForInFilterDescriptor Descriptor; |
| 1043 CodeStubAssembler assembler(state); |
| 1036 | 1044 |
| 1037 Node* key = assembler->Parameter(Descriptor::kKey); | 1045 Node* key = assembler.Parameter(Descriptor::kKey); |
| 1038 Node* object = assembler->Parameter(Descriptor::kObject); | 1046 Node* object = assembler.Parameter(Descriptor::kObject); |
| 1039 Node* context = assembler->Parameter(Descriptor::kContext); | 1047 Node* context = assembler.Parameter(Descriptor::kContext); |
| 1040 | 1048 |
| 1041 assembler->Return(assembler->ForInFilter(key, object, context)); | 1049 assembler.Return(assembler.ForInFilter(key, object, context)); |
| 1042 } | 1050 } |
| 1043 | 1051 |
| 1044 void Builtins::Generate_InstanceOf(CodeStubAssembler* assembler) { | 1052 void Builtins::Generate_InstanceOf(compiler::CodeAssemblerState* state) { |
| 1045 typedef compiler::Node Node; | 1053 typedef compiler::Node Node; |
| 1046 typedef CompareDescriptor Descriptor; | 1054 typedef CompareDescriptor Descriptor; |
| 1047 Node* object = assembler->Parameter(Descriptor::kLeft); | 1055 CodeStubAssembler assembler(state); |
| 1048 Node* callable = assembler->Parameter(Descriptor::kRight); | |
| 1049 Node* context = assembler->Parameter(Descriptor::kContext); | |
| 1050 | 1056 |
| 1051 assembler->Return(assembler->InstanceOf(object, callable, context)); | 1057 Node* object = assembler.Parameter(Descriptor::kLeft); |
| 1058 Node* callable = assembler.Parameter(Descriptor::kRight); |
| 1059 Node* context = assembler.Parameter(Descriptor::kContext); |
| 1060 |
| 1061 assembler.Return(assembler.InstanceOf(object, callable, context)); |
| 1052 } | 1062 } |
| 1053 | 1063 |
| 1054 } // namespace internal | 1064 } // namespace internal |
| 1055 } // namespace v8 | 1065 } // namespace v8 |
| OLD | NEW |