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 |