OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 #define __ ACCESS_MASM(masm_) | 96 #define __ ACCESS_MASM(masm_) |
97 | 97 |
98 | 98 |
99 void CodeGenerator::DeclareGlobals(Handle<FixedArray> a) { | 99 void CodeGenerator::DeclareGlobals(Handle<FixedArray> a) { |
100 UNIMPLEMENTED(); | 100 UNIMPLEMENTED(); |
101 } | 101 } |
102 | 102 |
103 void CodeGenerator::TestCodeGenerator() { | 103 void CodeGenerator::TestCodeGenerator() { |
104 // Compile a function from a string, and run it. | 104 // Compile a function from a string, and run it. |
105 Handle<JSFunction> test_function = Compiler::Compile( | 105 Handle<JSFunction> test_function = Compiler::Compile( |
106 Factory::NewStringFromAscii(CStrVector("39; 42;")), | 106 Factory::NewStringFromAscii(CStrVector( |
| 107 "39;" |
| 108 "(function(){return 43})();" |
| 109 "42;" |
| 110 // "function foo(x, y){return x;};" |
| 111 "43;" |
| 112 // "foo(2,3);" |
| 113 "44;" |
| 114 "(function(){return (function(){return 47})()})();")), |
107 Factory::NewStringFromAscii(CStrVector("CodeGeneratorTestScript")), | 115 Factory::NewStringFromAscii(CStrVector("CodeGeneratorTestScript")), |
108 0, | 116 0, |
109 0, | 117 0, |
110 NULL, | 118 NULL, |
111 NULL); | 119 NULL); |
112 | 120 |
113 Code* code_object = test_function->code(); // Local for debugging ease. | 121 Code* code_object = test_function->code(); // Local for debugging ease. |
114 USE(code_object); | 122 USE(code_object); |
115 | 123 |
116 // Create a dummy function and context. | 124 // Create a dummy function and context. |
117 Handle<JSFunction> bridge = | 125 Handle<JSFunction> bridge = |
118 Factory::NewFunction(Factory::empty_symbol(), Factory::undefined_value()); | 126 Factory::NewFunction(Factory::empty_symbol(), Factory::undefined_value()); |
119 Handle<Context> context = | 127 Handle<Context> context = |
120 Factory::NewFunctionContext(Context::MIN_CONTEXT_SLOTS, bridge); | 128 Factory::NewFunctionContext(Context::MIN_CONTEXT_SLOTS, bridge); |
121 | 129 |
122 test_function = Factory::NewFunctionFromBoilerplate( | 130 test_function = Factory::NewFunctionFromBoilerplate( |
123 test_function, | 131 test_function, |
124 context); | 132 context); |
125 | 133 |
126 bool pending_exceptions; | 134 bool pending_exceptions; |
127 Handle<Object> result = | 135 Handle<Object> result = |
128 Execution::Call(test_function, | 136 Execution::Call(test_function, |
129 Handle<Object>::cast(test_function), | 137 Handle<Object>::cast(test_function), |
130 0, | 138 0, |
131 NULL, | 139 NULL, |
132 &pending_exceptions); | 140 &pending_exceptions); |
133 // Function compiles and runs, but returns a JSFunction object. | 141 // Function compiles and runs, but returns a JSFunction object. |
134 CHECK(result->IsSmi()); | 142 CHECK(result->IsSmi()); |
135 CHECK_EQ(42, Smi::cast(*result)->value()); | 143 CHECK_EQ(47, Smi::cast(*result)->value()); |
136 } | 144 } |
137 | 145 |
138 | 146 |
139 void CodeGenerator::GenCode(FunctionLiteral* function) { | 147 void CodeGenerator::GenCode(FunctionLiteral* function) { |
140 // Record the position for debugging purposes. | 148 // Record the position for debugging purposes. |
141 CodeForFunctionPosition(function); | 149 CodeForFunctionPosition(function); |
142 ZoneList<Statement*>* body = function->body(); | 150 ZoneList<Statement*>* body = function->body(); |
143 | 151 |
144 // Initialize state. | 152 // Initialize state. |
145 ASSERT(scope_ == NULL); | 153 ASSERT(scope_ == NULL); |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 } | 371 } |
364 | 372 |
365 void CodeGenerator::VisitTryFinally(TryFinally* a) { | 373 void CodeGenerator::VisitTryFinally(TryFinally* a) { |
366 UNIMPLEMENTED(); | 374 UNIMPLEMENTED(); |
367 } | 375 } |
368 | 376 |
369 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* a) { | 377 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* a) { |
370 UNIMPLEMENTED(); | 378 UNIMPLEMENTED(); |
371 } | 379 } |
372 | 380 |
373 void CodeGenerator::VisitFunctionLiteral(FunctionLiteral* a) { | 381 |
374 UNIMPLEMENTED(); | 382 void CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) { |
| 383 // Call the runtime to instantiate the function boilerplate object. |
| 384 // The inevitable call will sync frame elements to memory anyway, so |
| 385 // we do it eagerly to allow us to push the arguments directly into |
| 386 // place. |
| 387 ASSERT(boilerplate->IsBoilerplate()); |
| 388 frame_->SyncRange(0, frame_->element_count() - 1); |
| 389 |
| 390 // Push the boilerplate on the stack. |
| 391 __ movq(kScratchRegister, boilerplate, RelocInfo::EMBEDDED_OBJECT); |
| 392 frame_->EmitPush(kScratchRegister); |
| 393 |
| 394 // Create a new closure. |
| 395 frame_->EmitPush(rsi); |
| 396 Result result = frame_->CallRuntime(Runtime::kNewClosure, 2); |
| 397 frame_->Push(&result); |
375 } | 398 } |
376 | 399 |
| 400 |
| 401 void CodeGenerator::VisitFunctionLiteral(FunctionLiteral* node) { |
| 402 Comment cmnt(masm_, "[ FunctionLiteral"); |
| 403 |
| 404 // Build the function boilerplate and instantiate it. |
| 405 Handle<JSFunction> boilerplate = BuildBoilerplate(node); |
| 406 // Check for stack-overflow exception. |
| 407 if (HasStackOverflow()) return; |
| 408 InstantiateBoilerplate(boilerplate); |
| 409 } |
| 410 |
| 411 |
377 void CodeGenerator::VisitFunctionBoilerplateLiteral( | 412 void CodeGenerator::VisitFunctionBoilerplateLiteral( |
378 FunctionBoilerplateLiteral* a) { | 413 FunctionBoilerplateLiteral* node) { |
379 UNIMPLEMENTED(); | 414 Comment cmnt(masm_, "[ FunctionBoilerplateLiteral"); |
| 415 InstantiateBoilerplate(node->boilerplate()); |
380 } | 416 } |
381 | 417 |
| 418 |
382 void CodeGenerator::VisitConditional(Conditional* a) { | 419 void CodeGenerator::VisitConditional(Conditional* a) { |
383 UNIMPLEMENTED(); | 420 UNIMPLEMENTED(); |
384 } | 421 } |
385 | 422 |
386 void CodeGenerator::VisitSlot(Slot* node) { | 423 void CodeGenerator::VisitSlot(Slot* node) { |
387 Comment cmnt(masm_, "[ Slot"); | 424 Comment cmnt(masm_, "[ Slot"); |
388 LoadFromSlot(node, typeof_state()); | 425 LoadFromSlot(node, typeof_state()); |
389 } | 426 } |
390 | 427 |
391 | 428 |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 | 551 |
515 | 552 |
516 void CodeGenerator::VisitThrow(Throw* a) { | 553 void CodeGenerator::VisitThrow(Throw* a) { |
517 // UNIMPLEMENTED(); | 554 // UNIMPLEMENTED(); |
518 } | 555 } |
519 | 556 |
520 void CodeGenerator::VisitProperty(Property* a) { | 557 void CodeGenerator::VisitProperty(Property* a) { |
521 UNIMPLEMENTED(); | 558 UNIMPLEMENTED(); |
522 } | 559 } |
523 | 560 |
524 void CodeGenerator::VisitCall(Call* a) { | 561 |
525 UNIMPLEMENTED(); | 562 void CodeGenerator::VisitCall(Call* node) { |
| 563 Comment cmnt(masm_, "[ Call"); |
| 564 |
| 565 ZoneList<Expression*>* args = node->arguments(); |
| 566 |
| 567 CodeForStatementPosition(node); |
| 568 |
| 569 // Check if the function is a variable or a property. |
| 570 Expression* function = node->expression(); |
| 571 Variable* var = function->AsVariableProxy()->AsVariable(); |
| 572 Property* property = function->AsProperty(); |
| 573 |
| 574 // ------------------------------------------------------------------------ |
| 575 // Fast-case: Use inline caching. |
| 576 // --- |
| 577 // According to ECMA-262, section 11.2.3, page 44, the function to call |
| 578 // must be resolved after the arguments have been evaluated. The IC code |
| 579 // automatically handles this by loading the arguments before the function |
| 580 // is resolved in cache misses (this also holds for megamorphic calls). |
| 581 // ------------------------------------------------------------------------ |
| 582 |
| 583 if (var != NULL && !var->is_this() && var->is_global()) { |
| 584 // ---------------------------------- |
| 585 // JavaScript example: 'foo(1, 2, 3)' // foo is global |
| 586 // ---------------------------------- |
| 587 |
| 588 // Push the name of the function and the receiver onto the stack. |
| 589 frame_->Push(var->name()); |
| 590 |
| 591 // Pass the global object as the receiver and let the IC stub |
| 592 // patch the stack to use the global proxy as 'this' in the |
| 593 // invoked function. |
| 594 LoadGlobal(); |
| 595 |
| 596 // Load the arguments. |
| 597 int arg_count = args->length(); |
| 598 for (int i = 0; i < arg_count; i++) { |
| 599 Load(args->at(i)); |
| 600 } |
| 601 |
| 602 // Call the IC initialization code. |
| 603 CodeForSourcePosition(node->position()); |
| 604 Result result = frame_->CallCallIC(RelocInfo::CODE_TARGET_CONTEXT, |
| 605 arg_count, |
| 606 loop_nesting()); |
| 607 frame_->RestoreContextRegister(); |
| 608 // Replace the function on the stack with the result. |
| 609 frame_->SetElementAt(0, &result); |
| 610 } else if (var != NULL && var->slot() != NULL && |
| 611 var->slot()->type() == Slot::LOOKUP) { |
| 612 // TODO(X64): Enable calls of non-global functions. |
| 613 UNIMPLEMENTED(); |
| 614 /* |
| 615 // ---------------------------------- |
| 616 // JavaScript example: 'with (obj) foo(1, 2, 3)' // foo is in obj |
| 617 // ---------------------------------- |
| 618 |
| 619 // Load the function from the context. Sync the frame so we can |
| 620 // push the arguments directly into place. |
| 621 frame_->SyncRange(0, frame_->element_count() - 1); |
| 622 frame_->EmitPush(esi); |
| 623 frame_->EmitPush(Immediate(var->name())); |
| 624 frame_->CallRuntime(Runtime::kLoadContextSlot, 2); |
| 625 // The runtime call returns a pair of values in eax and edx. The |
| 626 // looked-up function is in eax and the receiver is in edx. These |
| 627 // register references are not ref counted here. We spill them |
| 628 // eagerly since they are arguments to an inevitable call (and are |
| 629 // not sharable by the arguments). |
| 630 ASSERT(!allocator()->is_used(eax)); |
| 631 frame_->EmitPush(eax); |
| 632 |
| 633 // Load the receiver. |
| 634 ASSERT(!allocator()->is_used(edx)); |
| 635 frame_->EmitPush(edx); |
| 636 |
| 637 // Call the function. |
| 638 CallWithArguments(args, node->position()); |
| 639 */ |
| 640 } else if (property != NULL) { |
| 641 UNIMPLEMENTED(); |
| 642 /* |
| 643 // Check if the key is a literal string. |
| 644 Literal* literal = property->key()->AsLiteral(); |
| 645 |
| 646 if (literal != NULL && literal->handle()->IsSymbol()) { |
| 647 // ------------------------------------------------------------------ |
| 648 // JavaScript example: 'object.foo(1, 2, 3)' or 'map["key"](1, 2, 3)' |
| 649 // ------------------------------------------------------------------ |
| 650 |
| 651 // Push the name of the function and the receiver onto the stack. |
| 652 frame_->Push(literal->handle()); |
| 653 Load(property->obj()); |
| 654 |
| 655 // Load the arguments. |
| 656 int arg_count = args->length(); |
| 657 for (int i = 0; i < arg_count; i++) { |
| 658 Load(args->at(i)); |
| 659 } |
| 660 |
| 661 // Call the IC initialization code. |
| 662 CodeForSourcePosition(node->position()); |
| 663 Result result = |
| 664 frame_->CallCallIC(RelocInfo::CODE_TARGET, arg_count, loop_nesting()); |
| 665 frame_->RestoreContextRegister(); |
| 666 // Replace the function on the stack with the result. |
| 667 frame_->SetElementAt(0, &result); |
| 668 |
| 669 } else { |
| 670 // ------------------------------------------- |
| 671 // JavaScript example: 'array[index](1, 2, 3)' |
| 672 // ------------------------------------------- |
| 673 |
| 674 // Load the function to call from the property through a reference. |
| 675 Reference ref(this, property); |
| 676 ref.GetValue(NOT_INSIDE_TYPEOF); |
| 677 |
| 678 // Pass receiver to called function. |
| 679 if (property->is_synthetic()) { |
| 680 // Use global object as receiver. |
| 681 LoadGlobalReceiver(); |
| 682 } else { |
| 683 // The reference's size is non-negative. |
| 684 frame_->PushElementAt(ref.size()); |
| 685 } |
| 686 |
| 687 // Call the function. |
| 688 CallWithArguments(args, node->position()); |
| 689 } |
| 690 */ |
| 691 } else { |
| 692 // ---------------------------------- |
| 693 // JavaScript example: 'foo(1, 2, 3)' // foo is not global |
| 694 // ---------------------------------- |
| 695 |
| 696 // Load the function. |
| 697 Load(function); |
| 698 |
| 699 // Pass the global proxy as the receiver. |
| 700 LoadGlobalReceiver(); |
| 701 |
| 702 // Call the function. |
| 703 CallWithArguments(args, node->position()); |
| 704 } |
526 } | 705 } |
527 | 706 |
| 707 |
528 void CodeGenerator::VisitCallEval(CallEval* a) { | 708 void CodeGenerator::VisitCallEval(CallEval* a) { |
529 UNIMPLEMENTED(); | 709 UNIMPLEMENTED(); |
530 } | 710 } |
531 | 711 |
532 void CodeGenerator::VisitCallNew(CallNew* a) { | 712 void CodeGenerator::VisitCallNew(CallNew* a) { |
533 UNIMPLEMENTED(); | 713 UNIMPLEMENTED(); |
534 } | 714 } |
535 | 715 |
536 void CodeGenerator::VisitCallRuntime(CallRuntime* a) { | 716 void CodeGenerator::VisitCallRuntime(CallRuntime* a) { |
537 UNIMPLEMENTED(); | 717 UNIMPLEMENTED(); |
538 } | 718 } |
539 | 719 |
| 720 |
540 void CodeGenerator::VisitUnaryOperation(UnaryOperation* a) { | 721 void CodeGenerator::VisitUnaryOperation(UnaryOperation* a) { |
541 UNIMPLEMENTED(); | 722 UNIMPLEMENTED(); |
542 } | 723 } |
543 | 724 |
544 void CodeGenerator::VisitCountOperation(CountOperation* a) { | 725 void CodeGenerator::VisitCountOperation(CountOperation* a) { |
545 UNIMPLEMENTED(); | 726 UNIMPLEMENTED(); |
546 } | 727 } |
547 | 728 |
548 void CodeGenerator::VisitBinaryOperation(BinaryOperation* a) { | 729 void CodeGenerator::VisitBinaryOperation(BinaryOperation* a) { |
549 UNIMPLEMENTED(); | 730 UNIMPLEMENTED(); |
(...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1209 void CodeGenerator::LoadGlobal() { | 1390 void CodeGenerator::LoadGlobal() { |
1210 if (in_spilled_code()) { | 1391 if (in_spilled_code()) { |
1211 frame_->EmitPush(GlobalObject()); | 1392 frame_->EmitPush(GlobalObject()); |
1212 } else { | 1393 } else { |
1213 Result temp = allocator_->Allocate(); | 1394 Result temp = allocator_->Allocate(); |
1214 __ movq(temp.reg(), GlobalObject()); | 1395 __ movq(temp.reg(), GlobalObject()); |
1215 frame_->Push(&temp); | 1396 frame_->Push(&temp); |
1216 } | 1397 } |
1217 } | 1398 } |
1218 | 1399 |
| 1400 |
| 1401 void CodeGenerator::LoadGlobalReceiver() { |
| 1402 Result temp = allocator_->Allocate(); |
| 1403 Register reg = temp.reg(); |
| 1404 __ movq(reg, GlobalObject()); |
| 1405 __ movq(reg, FieldOperand(reg, GlobalObject::kGlobalReceiverOffset)); |
| 1406 frame_->Push(&temp); |
| 1407 } |
| 1408 |
| 1409 |
1219 #undef __ | 1410 #undef __ |
1220 | 1411 |
1221 // End of CodeGenerator implementation. | 1412 // End of CodeGenerator implementation. |
1222 | 1413 |
1223 // ----------------------------------------------------------------------------- | 1414 // ----------------------------------------------------------------------------- |
1224 // Implementation of stubs. | 1415 // Implementation of stubs. |
1225 | 1416 |
1226 // Stub classes have public member named masm, not masm_. | 1417 // Stub classes have public member named masm, not masm_. |
1227 #define __ ACCESS_MASM(masm) | 1418 #define __ ACCESS_MASM(masm) |
1228 | 1419 |
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1581 void Print() { PrintF("CallFunctionStub (args %d)\n", argc_); } | 1772 void Print() { PrintF("CallFunctionStub (args %d)\n", argc_); } |
1582 #endif | 1773 #endif |
1583 | 1774 |
1584 Major MajorKey() { return CallFunction; } | 1775 Major MajorKey() { return CallFunction; } |
1585 int MinorKey() { return argc_; } | 1776 int MinorKey() { return argc_; } |
1586 InLoopFlag InLoop() { return in_loop_; } | 1777 InLoopFlag InLoop() { return in_loop_; } |
1587 }; | 1778 }; |
1588 | 1779 |
1589 | 1780 |
1590 void CallFunctionStub::Generate(MacroAssembler* masm) { | 1781 void CallFunctionStub::Generate(MacroAssembler* masm) { |
| 1782 Label slow; |
| 1783 |
| 1784 // Get the function to call from the stack. |
| 1785 // +2 ~ receiver, return address |
| 1786 __ movq(rdi, Operand(rsp, (argc_ + 2) * kPointerSize)); |
| 1787 |
| 1788 // Check that the function really is a JavaScript function. |
| 1789 __ testq(rdi, Immediate(kSmiTagMask)); |
| 1790 __ j(zero, &slow); |
| 1791 // Goto slow case if we do not have a function. |
| 1792 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); |
| 1793 __ j(not_equal, &slow); |
| 1794 |
| 1795 // Fast-case: Just invoke the function. |
| 1796 ParameterCount actual(argc_); |
| 1797 __ InvokeFunction(rdi, actual, JUMP_FUNCTION); |
| 1798 |
| 1799 // Slow-case: Non-function called. |
| 1800 __ bind(&slow); |
| 1801 __ Set(rax, argc_); |
| 1802 __ Set(rbx, 0); |
| 1803 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION); |
| 1804 Handle<Code> adaptor(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)); |
| 1805 __ Jump(adaptor, RelocInfo::CODE_TARGET); |
| 1806 } |
| 1807 |
| 1808 |
| 1809 // Call the function just below TOS on the stack with the given |
| 1810 // arguments. The receiver is the TOS. |
| 1811 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args, |
| 1812 int position) { |
| 1813 // Push the arguments ("left-to-right") on the stack. |
| 1814 int arg_count = args->length(); |
| 1815 for (int i = 0; i < arg_count; i++) { |
| 1816 Load(args->at(i)); |
| 1817 } |
| 1818 |
| 1819 // Record the position for debugging purposes. |
| 1820 CodeForSourcePosition(position); |
| 1821 |
| 1822 // Use the shared code stub to call the function. |
| 1823 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP; |
| 1824 CallFunctionStub call_function(arg_count, in_loop); |
| 1825 Result answer = frame_->CallStub(&call_function, arg_count + 1); |
| 1826 // Restore context and replace function on the stack with the |
| 1827 // result of the stub invocation. |
| 1828 frame_->RestoreContextRegister(); |
| 1829 frame_->SetElementAt(0, &answer); |
1591 } | 1830 } |
1592 | 1831 |
1593 | 1832 |
1594 void InstanceofStub::Generate(MacroAssembler* masm) { | 1833 void InstanceofStub::Generate(MacroAssembler* masm) { |
1595 } | 1834 } |
1596 | 1835 |
1597 | 1836 |
1598 | |
1599 void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) { | 1837 void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) { |
1600 // The displacement is used for skipping the return address and the | 1838 // The displacement is used for skipping the return address and the |
1601 // frame pointer on the stack. It is the offset of the last | 1839 // frame pointer on the stack. It is the offset of the last |
1602 // parameter (if any) relative to the frame pointer. | 1840 // parameter (if any) relative to the frame pointer. |
1603 static const int kDisplacement = 2 * kPointerSize; | 1841 static const int kDisplacement = 2 * kPointerSize; |
1604 | 1842 |
1605 // Check if the calling frame is an arguments adaptor frame. | 1843 // Check if the calling frame is an arguments adaptor frame. |
1606 Label runtime; | 1844 Label runtime; |
1607 __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | 1845 __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |
1608 __ movq(rcx, Operand(rdx, StandardFrameConstants::kContextOffset)); | 1846 __ movq(rcx, Operand(rdx, StandardFrameConstants::kContextOffset)); |
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2044 __ addq(rsp, Immediate(2 * kPointerSize)); // remove markers | 2282 __ addq(rsp, Immediate(2 * kPointerSize)); // remove markers |
2045 | 2283 |
2046 // Restore frame pointer and return. | 2284 // Restore frame pointer and return. |
2047 __ pop(rbp); | 2285 __ pop(rbp); |
2048 __ ret(0); | 2286 __ ret(0); |
2049 } | 2287 } |
2050 | 2288 |
2051 #undef __ | 2289 #undef __ |
2052 | 2290 |
2053 } } // namespace v8::internal | 2291 } } // namespace v8::internal |
OLD | NEW |