Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/parsing/parser.h" | 5 #include "src/parsing/parser.h" |
| 6 | 6 |
| 7 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
| 9 #include "src/ast/ast-expression-rewriter.h" | 9 #include "src/ast/ast-expression-rewriter.h" |
| 10 #include "src/ast/ast-expression-visitor.h" | 10 #include "src/ast/ast-expression-visitor.h" |
| (...skipping 3239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3250 throw_arguments->Add(result_proxy_again, zone()); | 3250 throw_arguments->Add(result_proxy_again, zone()); |
| 3251 Expression* throw_call = factory()->NewCallRuntime( | 3251 Expression* throw_call = factory()->NewCallRuntime( |
| 3252 Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos); | 3252 Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos); |
| 3253 | 3253 |
| 3254 return factory()->NewBinaryOperation( | 3254 return factory()->NewBinaryOperation( |
| 3255 Token::AND, | 3255 Token::AND, |
| 3256 factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos), | 3256 factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos), |
| 3257 throw_call, pos); | 3257 throw_call, pos); |
| 3258 } | 3258 } |
| 3259 | 3259 |
| 3260 | |
| 3261 void Parser::InitializeForEachStatement(ForEachStatement* stmt, | 3260 void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
| 3262 Expression* each, Expression* subject, | 3261 Expression* each, Expression* subject, |
| 3263 Statement* body, | 3262 Statement* body) { |
| 3264 bool is_destructuring) { | |
| 3265 DCHECK(!is_destructuring || allow_harmony_destructuring_assignment()); | |
| 3266 ForOfStatement* for_of = stmt->AsForOfStatement(); | 3263 ForOfStatement* for_of = stmt->AsForOfStatement(); |
| 3267 | |
| 3268 if (for_of != NULL) { | 3264 if (for_of != NULL) { |
| 3269 Variable* iterator = scope_->NewTemporary( | 3265 InitializeForOfStatement(for_of, each, subject, body, true); |
| 3270 ast_value_factory()->dot_iterator_string()); | |
| 3271 Variable* result = scope_->NewTemporary( | |
| 3272 ast_value_factory()->dot_result_string()); | |
| 3273 | |
| 3274 Expression* assign_iterator; | |
| 3275 Expression* next_result; | |
| 3276 Expression* result_done; | |
| 3277 Expression* assign_each; | |
| 3278 | |
| 3279 // iterator = subject[Symbol.iterator]() | |
| 3280 // Hackily disambiguate o from o.next and o [Symbol.iterator](). | |
| 3281 // TODO(verwaest): Come up with a better solution. | |
| 3282 assign_iterator = factory()->NewAssignment( | |
| 3283 Token::ASSIGN, factory()->NewVariableProxy(iterator), | |
| 3284 GetIterator(subject, factory(), subject->position() - 2), | |
| 3285 subject->position()); | |
| 3286 | |
| 3287 // !%_IsJSReceiver(result = iterator.next()) && | |
| 3288 // %ThrowIteratorResultNotAnObject(result) | |
| 3289 { | |
| 3290 // result = iterator.next() | |
| 3291 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | |
| 3292 // Hackily disambiguate o from o.next and o [Symbol.iterator](). | |
| 3293 // TODO(verwaest): Come up with a better solution. | |
| 3294 next_result = BuildIteratorNextResult(iterator_proxy, result, | |
| 3295 subject->position() - 1); | |
| 3296 } | |
| 3297 | |
| 3298 // result.done | |
| 3299 { | |
| 3300 Expression* done_literal = factory()->NewStringLiteral( | |
| 3301 ast_value_factory()->done_string(), RelocInfo::kNoPosition); | |
| 3302 Expression* result_proxy = factory()->NewVariableProxy(result); | |
| 3303 result_done = factory()->NewProperty( | |
| 3304 result_proxy, done_literal, RelocInfo::kNoPosition); | |
| 3305 } | |
| 3306 | |
| 3307 // each = result.value | |
| 3308 { | |
| 3309 Expression* value_literal = factory()->NewStringLiteral( | |
| 3310 ast_value_factory()->value_string(), RelocInfo::kNoPosition); | |
| 3311 Expression* result_proxy = factory()->NewVariableProxy(result); | |
| 3312 Expression* result_value = factory()->NewProperty( | |
| 3313 result_proxy, value_literal, RelocInfo::kNoPosition); | |
| 3314 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value, | |
| 3315 RelocInfo::kNoPosition); | |
| 3316 if (is_destructuring) { | |
| 3317 assign_each = PatternRewriter::RewriteDestructuringAssignment( | |
| 3318 this, assign_each->AsAssignment(), scope_); | |
| 3319 } | |
| 3320 } | |
| 3321 | |
| 3322 for_of->Initialize(each, subject, body, | |
| 3323 iterator, | |
| 3324 assign_iterator, | |
| 3325 next_result, | |
| 3326 result_done, | |
| 3327 assign_each); | |
| 3328 } else { | 3266 } else { |
| 3329 if (is_destructuring) { | 3267 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { |
| 3268 DCHECK(allow_harmony_destructuring_assignment()); | |
| 3330 Variable* temp = | 3269 Variable* temp = |
| 3331 scope_->NewTemporary(ast_value_factory()->empty_string()); | 3270 scope_->NewTemporary(ast_value_factory()->empty_string()); |
| 3332 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | 3271 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
| 3333 Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment( | 3272 Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment( |
| 3334 this, factory()->NewAssignment(Token::ASSIGN, each, temp_proxy, | 3273 this, factory()->NewAssignment(Token::ASSIGN, each, temp_proxy, |
| 3335 RelocInfo::kNoPosition), | 3274 RelocInfo::kNoPosition), |
| 3336 scope_); | 3275 scope_); |
| 3337 auto block = | 3276 auto block = |
| 3338 factory()->NewBlock(nullptr, 2, false, RelocInfo::kNoPosition); | 3277 factory()->NewBlock(nullptr, 2, false, RelocInfo::kNoPosition); |
| 3339 block->statements()->Add(factory()->NewExpressionStatement( | 3278 block->statements()->Add(factory()->NewExpressionStatement( |
| 3340 assign_each, RelocInfo::kNoPosition), | 3279 assign_each, RelocInfo::kNoPosition), |
| 3341 zone()); | 3280 zone()); |
| 3342 block->statements()->Add(body, zone()); | 3281 block->statements()->Add(body, zone()); |
| 3343 body = block; | 3282 body = block; |
| 3344 each = factory()->NewVariableProxy(temp); | 3283 each = factory()->NewVariableProxy(temp); |
| 3345 } | 3284 } |
| 3346 stmt->Initialize(each, subject, body); | 3285 stmt->Initialize(each, subject, body); |
| 3347 } | 3286 } |
| 3348 } | 3287 } |
| 3349 | 3288 |
| 3289 void Parser::InitializeForOfStatement(ForOfStatement* for_of, Expression* each, | |
| 3290 Expression* subject, Statement* body, | |
| 3291 bool use_position_hack) { | |
|
nickie
2016/03/04 14:15:13
As a fix, I suggest that you replace "bool use_pos
| |
| 3292 Variable* iterator = | |
| 3293 scope_->NewTemporary(ast_value_factory()->dot_iterator_string()); | |
| 3294 Variable* result = | |
| 3295 scope_->NewTemporary(ast_value_factory()->dot_result_string()); | |
| 3296 | |
| 3297 Expression* assign_iterator; | |
| 3298 Expression* next_result; | |
| 3299 Expression* result_done; | |
| 3300 Expression* assign_each; | |
| 3301 | |
| 3302 // Hackily disambiguate o from o.next and o [Symbol.iterator](). | |
| 3303 // TODO(verwaest): Come up with a better solution. | |
| 3304 int get_iterator_pos = subject->position() - (use_position_hack * 2); | |
| 3305 int next_result_pos = subject->position() - (use_position_hack * 1); | |
|
nickie
2016/03/04 14:15:13
These two would become:
int get_iterator_pos =
| |
| 3306 | |
| 3307 // iterator = subject[Symbol.iterator]() | |
| 3308 assign_iterator = factory()->NewAssignment( | |
| 3309 Token::ASSIGN, factory()->NewVariableProxy(iterator), | |
| 3310 GetIterator(subject, factory(), get_iterator_pos), subject->position()); | |
| 3311 | |
| 3312 // !%_IsJSReceiver(result = iterator.next()) && | |
| 3313 // %ThrowIteratorResultNotAnObject(result) | |
| 3314 { | |
| 3315 // result = iterator.next() | |
| 3316 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | |
| 3317 next_result = | |
| 3318 BuildIteratorNextResult(iterator_proxy, result, next_result_pos); | |
| 3319 } | |
| 3320 | |
| 3321 // result.done | |
| 3322 { | |
| 3323 Expression* done_literal = factory()->NewStringLiteral( | |
| 3324 ast_value_factory()->done_string(), RelocInfo::kNoPosition); | |
| 3325 Expression* result_proxy = factory()->NewVariableProxy(result); | |
| 3326 result_done = factory()->NewProperty(result_proxy, done_literal, | |
| 3327 RelocInfo::kNoPosition); | |
| 3328 } | |
| 3329 | |
| 3330 // each = result.value | |
| 3331 { | |
| 3332 Expression* value_literal = factory()->NewStringLiteral( | |
| 3333 ast_value_factory()->value_string(), RelocInfo::kNoPosition); | |
| 3334 Expression* result_proxy = factory()->NewVariableProxy(result); | |
| 3335 Expression* result_value = factory()->NewProperty( | |
| 3336 result_proxy, value_literal, RelocInfo::kNoPosition); | |
| 3337 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value, | |
| 3338 RelocInfo::kNoPosition); | |
| 3339 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { | |
| 3340 DCHECK(allow_harmony_destructuring_assignment()); | |
| 3341 assign_each = PatternRewriter::RewriteDestructuringAssignment( | |
| 3342 this, assign_each->AsAssignment(), scope_); | |
| 3343 } | |
| 3344 } | |
| 3345 | |
| 3346 for_of->Initialize(each, subject, body, iterator, assign_iterator, | |
| 3347 next_result, result_done, assign_each); | |
| 3348 } | |
| 3349 | |
| 3350 Statement* Parser::DesugarLexicalBindingsInForStatement( | 3350 Statement* Parser::DesugarLexicalBindingsInForStatement( |
| 3351 Scope* inner_scope, VariableMode mode, ZoneList<const AstRawString*>* names, | 3351 Scope* inner_scope, VariableMode mode, ZoneList<const AstRawString*>* names, |
| 3352 ForStatement* loop, Statement* init, Expression* cond, Statement* next, | 3352 ForStatement* loop, Statement* init, Expression* cond, Statement* next, |
| 3353 Statement* body, bool* ok) { | 3353 Statement* body, bool* ok) { |
| 3354 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are | 3354 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are |
| 3355 // copied into a new environment. Moreover, the "next" statement must be | 3355 // copied into a new environment. Moreover, the "next" statement must be |
| 3356 // evaluated not in the environment of the just completed iteration but in | 3356 // evaluated not in the environment of the just completed iteration but in |
| 3357 // that of the upcoming one. We achieve this with the following desugaring. | 3357 // that of the upcoming one. We achieve this with the following desugaring. |
| 3358 // Extra care is needed to preserve the completion value of the original loop. | 3358 // Extra care is needed to preserve the completion value of the original loop. |
| 3359 // | 3359 // |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3722 each_initialization_block, &descriptor, &decl, | 3722 each_initialization_block, &descriptor, &decl, |
| 3723 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings | 3723 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings |
| 3724 : nullptr, | 3724 : nullptr, |
| 3725 CHECK_OK); | 3725 CHECK_OK); |
| 3726 } | 3726 } |
| 3727 | 3727 |
| 3728 body_block->statements()->Add(each_initialization_block, zone()); | 3728 body_block->statements()->Add(each_initialization_block, zone()); |
| 3729 body_block->statements()->Add(body, zone()); | 3729 body_block->statements()->Add(body, zone()); |
| 3730 VariableProxy* temp_proxy = | 3730 VariableProxy* temp_proxy = |
| 3731 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); | 3731 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); |
| 3732 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block, | 3732 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block); |
| 3733 false); | |
| 3734 } | 3733 } |
| 3735 body_scope->set_end_position(scanner()->location().end_pos); | 3734 body_scope->set_end_position(scanner()->location().end_pos); |
| 3736 body_scope = body_scope->FinalizeBlockScope(); | 3735 body_scope = body_scope->FinalizeBlockScope(); |
| 3737 body_block->set_scope(body_scope); | 3736 body_block->set_scope(body_scope); |
| 3738 | 3737 |
| 3739 // Create a TDZ for any lexically-bound names. | 3738 // Create a TDZ for any lexically-bound names. |
| 3740 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) { | 3739 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) { |
| 3741 DCHECK_NULL(init_block); | 3740 DCHECK_NULL(init_block); |
| 3742 | 3741 |
| 3743 init_block = | 3742 init_block = |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3831 // lexical binding is introduced which overlaps with the for-in/of, | 3830 // lexical binding is introduced which overlaps with the for-in/of, |
| 3832 // expressions in head of the loop should actually have variables | 3831 // expressions in head of the loop should actually have variables |
| 3833 // resolved in the outer scope. | 3832 // resolved in the outer scope. |
| 3834 Scope* body_scope = NewScope(for_scope, BLOCK_SCOPE); | 3833 Scope* body_scope = NewScope(for_scope, BLOCK_SCOPE); |
| 3835 { | 3834 { |
| 3836 BlockState block_state(&scope_, body_scope); | 3835 BlockState block_state(&scope_, body_scope); |
| 3837 Block* block = | 3836 Block* block = |
| 3838 factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); | 3837 factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); |
| 3839 Statement* body = ParseSubStatement(NULL, CHECK_OK); | 3838 Statement* body = ParseSubStatement(NULL, CHECK_OK); |
| 3840 block->statements()->Add(body, zone()); | 3839 block->statements()->Add(body, zone()); |
| 3841 InitializeForEachStatement(loop, expression, enumerable, block, | 3840 InitializeForEachStatement(loop, expression, enumerable, block); |
| 3842 is_destructuring); | |
| 3843 body_scope->set_end_position(scanner()->location().end_pos); | 3841 body_scope->set_end_position(scanner()->location().end_pos); |
| 3844 body_scope = body_scope->FinalizeBlockScope(); | 3842 body_scope = body_scope->FinalizeBlockScope(); |
| 3845 block->set_scope(body_scope); | 3843 block->set_scope(body_scope); |
| 3846 } | 3844 } |
| 3847 | 3845 |
| 3848 Statement* final_loop = loop->IsForOfStatement() | 3846 Statement* final_loop = loop->IsForOfStatement() |
| 3849 ? FinalizeForOfStatement( | 3847 ? FinalizeForOfStatement( |
| 3850 loop->AsForOfStatement(), RelocInfo::kNoPosition) | 3848 loop->AsForOfStatement(), RelocInfo::kNoPosition) |
| 3851 : loop; | 3849 : loop; |
| 3852 | 3850 |
| (...skipping 1807 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5660 factory()->NewCallRuntime(Runtime::kAppendElement, | 5658 factory()->NewCallRuntime(Runtime::kAppendElement, |
| 5661 append_element_args, | 5659 append_element_args, |
| 5662 RelocInfo::kNoPosition), | 5660 RelocInfo::kNoPosition), |
| 5663 RelocInfo::kNoPosition), | 5661 RelocInfo::kNoPosition), |
| 5664 zone()); | 5662 zone()); |
| 5665 } else { | 5663 } else { |
| 5666 // If it's a spread, we're adding a for/of loop iterating through it. | 5664 // If it's a spread, we're adding a for/of loop iterating through it. |
| 5667 Variable* each = | 5665 Variable* each = |
| 5668 scope_->NewTemporary(ast_value_factory()->dot_for_string()); | 5666 scope_->NewTemporary(ast_value_factory()->dot_for_string()); |
| 5669 Expression* subject = spread->expression(); | 5667 Expression* subject = spread->expression(); |
| 5670 Variable* iterator = | |
| 5671 scope_->NewTemporary(ast_value_factory()->dot_iterator_string()); | |
| 5672 Variable* element = | |
| 5673 scope_->NewTemporary(ast_value_factory()->dot_result_string()); | |
| 5674 // iterator = subject[Symbol.iterator]() | |
| 5675 Expression* assign_iterator = factory()->NewAssignment( | |
| 5676 Token::ASSIGN, factory()->NewVariableProxy(iterator), | |
| 5677 GetIterator(subject, factory(), spread->expression_position()), | |
|
nickie
2016/03/04 14:15:13
There was another tricky point but it was a bit hi
| |
| 5678 subject->position()); | |
| 5679 // !%_IsJSReceiver(element = iterator.next()) && | |
| 5680 // %ThrowIteratorResultNotAnObject(element) | |
| 5681 Expression* next_element; | |
| 5682 { | |
| 5683 // element = iterator.next() | |
| 5684 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | |
| 5685 next_element = BuildIteratorNextResult(iterator_proxy, element, | |
| 5686 spread->expression_position()); | |
|
nickie
2016/03/04 14:15:13
Here too...
| |
| 5687 } | |
| 5688 // element.done | |
| 5689 Expression* element_done; | |
| 5690 { | |
| 5691 Expression* done_literal = factory()->NewStringLiteral( | |
| 5692 ast_value_factory()->done_string(), RelocInfo::kNoPosition); | |
| 5693 Expression* element_proxy = factory()->NewVariableProxy(element); | |
| 5694 element_done = factory()->NewProperty(element_proxy, done_literal, | |
| 5695 RelocInfo::kNoPosition); | |
| 5696 } | |
| 5697 // each = element.value | |
| 5698 Expression* assign_each; | |
| 5699 { | |
| 5700 Expression* value_literal = factory()->NewStringLiteral( | |
| 5701 ast_value_factory()->value_string(), RelocInfo::kNoPosition); | |
| 5702 Expression* element_proxy = factory()->NewVariableProxy(element); | |
| 5703 Expression* element_value = factory()->NewProperty( | |
| 5704 element_proxy, value_literal, RelocInfo::kNoPosition); | |
| 5705 assign_each = factory()->NewAssignment( | |
| 5706 Token::ASSIGN, factory()->NewVariableProxy(each), element_value, | |
| 5707 RelocInfo::kNoPosition); | |
| 5708 } | |
| 5709 // %AppendElement($R, each) | 5668 // %AppendElement($R, each) |
| 5710 Statement* append_body; | 5669 Statement* append_body; |
| 5711 { | 5670 { |
| 5712 ZoneList<Expression*>* append_element_args = | 5671 ZoneList<Expression*>* append_element_args = |
| 5713 NewExpressionList(2, zone()); | 5672 NewExpressionList(2, zone()); |
| 5714 append_element_args->Add(factory()->NewVariableProxy(result), zone()); | 5673 append_element_args->Add(factory()->NewVariableProxy(result), zone()); |
| 5715 append_element_args->Add(factory()->NewVariableProxy(each), zone()); | 5674 append_element_args->Add(factory()->NewVariableProxy(each), zone()); |
| 5716 append_body = factory()->NewExpressionStatement( | 5675 append_body = factory()->NewExpressionStatement( |
| 5717 factory()->NewCallRuntime(Runtime::kAppendElement, | 5676 factory()->NewCallRuntime(Runtime::kAppendElement, |
| 5718 append_element_args, | 5677 append_element_args, |
| 5719 RelocInfo::kNoPosition), | 5678 RelocInfo::kNoPosition), |
| 5720 RelocInfo::kNoPosition); | 5679 RelocInfo::kNoPosition); |
| 5721 } | 5680 } |
| 5722 // for (each of spread) %AppendElement($R, each) | 5681 // for (each of spread) %AppendElement($R, each) |
| 5723 ForEachStatement* loop = factory()->NewForEachStatement( | 5682 ForEachStatement* loop = factory()->NewForEachStatement( |
| 5724 ForEachStatement::ITERATE, nullptr, RelocInfo::kNoPosition); | 5683 ForEachStatement::ITERATE, nullptr, RelocInfo::kNoPosition); |
| 5725 ForOfStatement* for_of = loop->AsForOfStatement(); | 5684 InitializeForOfStatement(loop->AsForOfStatement(), |
| 5726 for_of->Initialize(factory()->NewVariableProxy(each), subject, | 5685 factory()->NewVariableProxy(each), subject, |
| 5727 append_body, iterator, assign_iterator, next_element, | 5686 append_body); |
| 5728 element_done, assign_each); | 5687 do_block->statements()->Add(loop, zone()); |
| 5729 do_block->statements()->Add(for_of, zone()); | |
| 5730 } | 5688 } |
| 5731 } | 5689 } |
| 5732 // Now, rewind the original array literal to truncate everything from the | 5690 // Now, rewind the original array literal to truncate everything from the |
| 5733 // first spread (included) until the end. This fixes $R's initialization. | 5691 // first spread (included) until the end. This fixes $R's initialization. |
| 5734 lit->RewindSpreads(); | 5692 lit->RewindSpreads(); |
| 5735 return factory()->NewDoExpression(do_block, result, lit->position()); | 5693 return factory()->NewDoExpression(do_block, result, lit->position()); |
| 5736 } | 5694 } |
| 5737 | 5695 |
| 5738 | 5696 |
| 5739 void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) { | 5697 void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) { |
| (...skipping 1200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6940 Expression* do_each = | 6898 Expression* do_each = |
| 6941 factory->NewDoExpression(new_assign_each, var_each, nopos); | 6899 factory->NewDoExpression(new_assign_each, var_each, nopos); |
| 6942 loop->set_assign_each(do_each); | 6900 loop->set_assign_each(do_each); |
| 6943 | 6901 |
| 6944 return final_loop; | 6902 return final_loop; |
| 6945 } | 6903 } |
| 6946 | 6904 |
| 6947 | 6905 |
| 6948 } // namespace internal | 6906 } // namespace internal |
| 6949 } // namespace v8 | 6907 } // namespace v8 |
| OLD | NEW |