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