OLD | NEW |
---|---|
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/ast.h" | 5 #include "src/ast.h" |
6 #include "src/messages.h" | 6 #include "src/messages.h" |
7 #include "src/parser.h" | 7 #include "src/parser.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 | 10 |
11 namespace internal { | 11 namespace internal { |
12 | 12 |
13 | 13 |
14 void Parser::PatternRewriter::DeclareAndInitializeVariables( | 14 void Parser::PatternRewriter::DeclareAndInitializeVariables( |
15 Block* block, const DeclarationDescriptor* declaration_descriptor, | 15 Block* block, const DeclarationDescriptor* declaration_descriptor, |
16 const DeclarationParsingResult::Declaration* declaration, | 16 const DeclarationParsingResult::Declaration* declaration, |
17 ZoneList<const AstRawString*>* names, bool* ok) { | 17 ZoneList<const AstRawString*>* names, bool* ok) { |
18 PatternRewriter rewriter; | 18 PatternRewriter rewriter; |
19 | 19 |
20 rewriter.parser_ = declaration_descriptor->parser; | |
21 rewriter.context_ = BINDING; | |
20 rewriter.pattern_ = declaration->pattern; | 22 rewriter.pattern_ = declaration->pattern; |
21 rewriter.initializer_position_ = declaration->initializer_position; | 23 rewriter.initializer_position_ = declaration->initializer_position; |
22 rewriter.block_ = block; | 24 rewriter.block_ = block; |
23 rewriter.descriptor_ = declaration_descriptor; | 25 rewriter.descriptor_ = declaration_descriptor; |
24 rewriter.names_ = names; | 26 rewriter.names_ = names; |
25 rewriter.ok_ = ok; | 27 rewriter.ok_ = ok; |
28 rewriter.rhs_ = nullptr; | |
26 | 29 |
27 rewriter.RecurseIntoSubpattern(rewriter.pattern_, declaration->initializer); | 30 rewriter.RecurseIntoSubpattern(rewriter.pattern_, declaration->initializer); |
28 } | 31 } |
29 | 32 |
30 | 33 |
34 Variable* Parser::PatternRewriter::RewriteDestructuringAssignment( | |
35 Parser* parser, Block* block, Expression* pattern, Expression* value, | |
36 Variable* result, bool* ok) { | |
37 PatternRewriter rewriter; | |
38 | |
39 rewriter.parser_ = parser; | |
40 rewriter.context_ = ASSIGNMENT; | |
41 rewriter.pattern_ = pattern; | |
42 rewriter.block_ = block; | |
43 rewriter.descriptor_ = nullptr; | |
44 rewriter.names_ = nullptr; | |
45 rewriter.ok_ = ok; | |
46 rewriter.rhs_ = result; | |
47 | |
48 rewriter.RecurseIntoSubpattern(rewriter.pattern_, value); | |
49 DCHECK_NOT_NULL(rewriter.rhs_); | |
50 return rewriter.rhs_; | |
51 } | |
52 | |
53 | |
31 void Parser::PatternRewriter::VisitVariableProxy(VariableProxy* pattern) { | 54 void Parser::PatternRewriter::VisitVariableProxy(VariableProxy* pattern) { |
32 Expression* value = current_value_; | 55 Expression* value = current_value_; |
56 | |
57 if (context() == ASSIGNMENT) { | |
58 // In an assignment context, simply perform the assignment | |
59 Assignment* assignment = factory()->NewAssignment( | |
60 Token::ASSIGN, pattern, value, pattern->position()); | |
61 block_->statements()->Add( | |
62 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), | |
63 zone()); | |
64 return; | |
65 } | |
66 | |
33 descriptor_->scope->RemoveUnresolved(pattern); | 67 descriptor_->scope->RemoveUnresolved(pattern); |
34 | 68 |
35 // Declare variable. | 69 // Declare variable. |
36 // Note that we *always* must treat the initial value via a separate init | 70 // Note that we *always* must treat the initial value via a separate init |
37 // assignment for variables and constants because the value must be assigned | 71 // assignment for variables and constants because the value must be assigned |
38 // when the variable is encountered in the source. But the variable/constant | 72 // when the variable is encountered in the source. But the variable/constant |
39 // is declared (and set to 'undefined') upon entering the function within | 73 // is declared (and set to 'undefined') upon entering the function within |
40 // which the variable or constant is declared. Only function variables have | 74 // which the variable or constant is declared. Only function variables have |
41 // an initial value in the declaration (because they are initialized upon | 75 // an initial value in the declaration (because they are initialized upon |
42 // entering the function). | 76 // entering the function). |
43 // | 77 // |
44 // If we have a legacy const declaration, in an inner scope, the proxy | 78 // If we have a legacy const declaration, in an inner scope, the proxy |
45 // is always bound to the declared variable (independent of possibly | 79 // is always bound to the declared variable (independent of possibly |
46 // surrounding 'with' statements). | 80 // surrounding 'with' statements). |
47 // For let/const declarations in harmony mode, we can also immediately | 81 // For let/const declarations in harmony mode, we can also immediately |
48 // pre-resolve the proxy because it resides in the same scope as the | 82 // pre-resolve the proxy because it resides in the same scope as the |
49 // declaration. | 83 // declaration. |
50 Parser* parser = descriptor_->parser; | 84 Parser* parser = parser_; |
51 const AstRawString* name = pattern->raw_name(); | 85 const AstRawString* name = pattern->raw_name(); |
52 VariableProxy* proxy = parser->NewUnresolved(name, descriptor_->mode); | 86 VariableProxy* proxy = parser->NewUnresolved(name, descriptor_->mode); |
53 Declaration* declaration = factory()->NewVariableDeclaration( | 87 Declaration* declaration = factory()->NewVariableDeclaration( |
54 proxy, descriptor_->mode, descriptor_->scope, | 88 proxy, descriptor_->mode, descriptor_->scope, |
55 descriptor_->declaration_pos); | 89 descriptor_->declaration_pos); |
56 Variable* var = parser->Declare(declaration, descriptor_->declaration_kind, | 90 Variable* var = parser->Declare(declaration, descriptor_->declaration_kind, |
57 descriptor_->mode != VAR, ok_, | 91 descriptor_->mode != VAR, ok_, |
58 descriptor_->hoist_scope); | 92 descriptor_->hoist_scope); |
59 if (!*ok_) return; | 93 if (!*ok_) return; |
60 DCHECK_NOT_NULL(var); | 94 DCHECK_NOT_NULL(var); |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
206 Assignment* assignment = factory()->NewAssignment( | 240 Assignment* assignment = factory()->NewAssignment( |
207 descriptor_->init_op, proxy, value, descriptor_->initialization_pos); | 241 descriptor_->init_op, proxy, value, descriptor_->initialization_pos); |
208 block_->statements()->Add( | 242 block_->statements()->Add( |
209 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), | 243 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), |
210 zone()); | 244 zone()); |
211 } | 245 } |
212 } | 246 } |
213 | 247 |
214 | 248 |
215 Variable* Parser::PatternRewriter::CreateTempVar(Expression* value) { | 249 Variable* Parser::PatternRewriter::CreateTempVar(Expression* value) { |
216 auto temp = descriptor_->parser->scope_->NewTemporary( | 250 if (value && value->IsDoExpression()) { |
217 ast_value_factory()->empty_string()); | 251 // Re-use completion values from |do-expressions| |
252 block_->statements()->Add( | |
caitp (gmail)
2015/10/19 12:10:50
I was hoping this would help reduce the number of
| |
253 factory()->NewExpressionStatement(value, RelocInfo::kNoPosition), | |
254 zone()); | |
255 return value->AsDoExpression()->result()->var(); | |
256 } | |
257 auto temp = parser_scope()->NewTemporary(ast_value_factory()->empty_string()); | |
218 if (value != nullptr) { | 258 if (value != nullptr) { |
219 auto assignment = factory()->NewAssignment( | 259 auto assignment = factory()->NewAssignment( |
220 Token::ASSIGN, factory()->NewVariableProxy(temp), value, | 260 Token::ASSIGN, factory()->NewVariableProxy(temp), value, |
221 RelocInfo::kNoPosition); | 261 RelocInfo::kNoPosition); |
222 | 262 |
223 block_->statements()->Add( | 263 block_->statements()->Add( |
224 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), | 264 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), |
225 zone()); | 265 zone()); |
226 } | 266 } |
227 return temp; | 267 return temp; |
228 } | 268 } |
229 | 269 |
230 | 270 |
231 void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* pattern) { | 271 void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* pattern) { |
232 auto temp = CreateTempVar(current_value_); | 272 auto temp = CreateTempVar(current_value_); |
273 if (rhs_ == nullptr) rhs_ = temp; | |
233 | 274 |
234 block_->statements()->Add(descriptor_->parser->BuildAssertIsCoercible(temp), | 275 block_->statements()->Add(parser_->BuildAssertIsCoercible(temp), zone()); |
235 zone()); | |
236 | 276 |
237 for (ObjectLiteralProperty* property : *pattern->properties()) { | 277 for (ObjectLiteralProperty* property : *pattern->properties()) { |
238 RecurseIntoSubpattern( | 278 RecurseIntoSubpattern( |
239 property->value(), | 279 property->value(), |
240 factory()->NewProperty(factory()->NewVariableProxy(temp), | 280 factory()->NewProperty(factory()->NewVariableProxy(temp), |
241 property->key(), RelocInfo::kNoPosition)); | 281 property->key(), RelocInfo::kNoPosition)); |
242 } | 282 } |
243 } | 283 } |
244 | 284 |
245 | 285 |
246 void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) { | 286 void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) { |
247 auto temp = CreateTempVar(current_value_); | 287 auto temp = CreateTempVar(current_value_); |
288 if (rhs_ == nullptr) rhs_ = temp; | |
248 | 289 |
249 block_->statements()->Add(descriptor_->parser->BuildAssertIsCoercible(temp), | 290 Block* outer_block = block_; |
250 zone()); | |
251 | 291 |
252 auto iterator = CreateTempVar(descriptor_->parser->GetIterator( | 292 if (context() == ASSIGNMENT) { |
253 factory()->NewVariableProxy(temp), factory())); | 293 block_ = factory()->NewBlock(nullptr, 4, false, node->position()); |
294 } | |
295 | |
296 block_->statements()->Add(parser_->BuildAssertIsCoercible(temp), zone()); | |
297 | |
298 auto iterator = CreateTempVar( | |
299 parser_->GetIterator(factory()->NewVariableProxy(temp), factory())); | |
254 auto done = CreateTempVar( | 300 auto done = CreateTempVar( |
255 factory()->NewBooleanLiteral(false, RelocInfo::kNoPosition)); | 301 factory()->NewBooleanLiteral(false, RelocInfo::kNoPosition)); |
256 auto result = CreateTempVar(); | 302 auto result = CreateTempVar(); |
257 auto v = CreateTempVar(); | 303 auto v = CreateTempVar(); |
258 | 304 |
259 Spread* spread = nullptr; | 305 Spread* spread = nullptr; |
260 for (Expression* value : *node->values()) { | 306 for (Expression* value : *node->values()) { |
261 if (value->IsSpread()) { | 307 if (value->IsSpread()) { |
262 spread = value->AsSpread(); | 308 spread = value->AsSpread(); |
263 break; | 309 break; |
264 } | 310 } |
265 | 311 |
266 // if (!done) { | 312 // if (!done) { |
267 // result = IteratorNext(iterator); | 313 // result = IteratorNext(iterator); |
268 // v = (done = result.done) ? undefined : result.value; | 314 // v = (done = result.done) ? undefined : result.value; |
269 // } | 315 // } |
270 auto next_block = | 316 auto next_block = |
271 factory()->NewBlock(nullptr, 2, true, RelocInfo::kNoPosition); | 317 factory()->NewBlock(nullptr, 2, true, RelocInfo::kNoPosition); |
272 next_block->statements()->Add( | 318 next_block->statements()->Add(factory()->NewExpressionStatement( |
273 factory()->NewExpressionStatement( | 319 parser_->BuildIteratorNextResult( |
274 descriptor_->parser->BuildIteratorNextResult( | 320 factory()->NewVariableProxy(iterator), |
275 factory()->NewVariableProxy(iterator), result, | 321 result, RelocInfo::kNoPosition), |
276 RelocInfo::kNoPosition), | 322 RelocInfo::kNoPosition), |
277 RelocInfo::kNoPosition), | 323 zone()); |
278 zone()); | |
279 | 324 |
280 auto assign_to_done = factory()->NewAssignment( | 325 auto assign_to_done = factory()->NewAssignment( |
281 Token::ASSIGN, factory()->NewVariableProxy(done), | 326 Token::ASSIGN, factory()->NewVariableProxy(done), |
282 factory()->NewProperty( | 327 factory()->NewProperty( |
283 factory()->NewVariableProxy(result), | 328 factory()->NewVariableProxy(result), |
284 factory()->NewStringLiteral(ast_value_factory()->done_string(), | 329 factory()->NewStringLiteral(ast_value_factory()->done_string(), |
285 RelocInfo::kNoPosition), | 330 RelocInfo::kNoPosition), |
286 RelocInfo::kNoPosition), | 331 RelocInfo::kNoPosition), |
287 RelocInfo::kNoPosition); | 332 RelocInfo::kNoPosition); |
288 auto next_value = factory()->NewConditional( | 333 auto next_value = factory()->NewConditional( |
(...skipping 26 matching lines...) Expand all Loading... | |
315 } | 360 } |
316 | 361 |
317 if (spread != nullptr) { | 362 if (spread != nullptr) { |
318 // array = []; | 363 // array = []; |
319 // if (!done) %concat_iterable_to_array(array, iterator); | 364 // if (!done) %concat_iterable_to_array(array, iterator); |
320 auto empty_exprs = new (zone()) ZoneList<Expression*>(0, zone()); | 365 auto empty_exprs = new (zone()) ZoneList<Expression*>(0, zone()); |
321 auto array = CreateTempVar(factory()->NewArrayLiteral( | 366 auto array = CreateTempVar(factory()->NewArrayLiteral( |
322 empty_exprs, | 367 empty_exprs, |
323 // Reuse pattern's literal index - it is unused since there is no | 368 // Reuse pattern's literal index - it is unused since there is no |
324 // actual literal allocated. | 369 // actual literal allocated. |
325 node->literal_index(), is_strong(descriptor_->parser->language_mode()), | 370 node->literal_index(), is_strong(parser_->language_mode()), |
326 RelocInfo::kNoPosition)); | 371 RelocInfo::kNoPosition)); |
327 | 372 |
328 auto arguments = new (zone()) ZoneList<Expression*>(2, zone()); | 373 auto arguments = new (zone()) ZoneList<Expression*>(2, zone()); |
329 arguments->Add(factory()->NewVariableProxy(array), zone()); | 374 arguments->Add(factory()->NewVariableProxy(array), zone()); |
330 arguments->Add(factory()->NewVariableProxy(iterator), zone()); | 375 arguments->Add(factory()->NewVariableProxy(iterator), zone()); |
331 auto spread_into_array_call = | 376 auto spread_into_array_call = |
332 factory()->NewCallRuntime(Context::CONCAT_ITERABLE_TO_ARRAY_INDEX, | 377 factory()->NewCallRuntime(Context::CONCAT_ITERABLE_TO_ARRAY_INDEX, |
333 arguments, RelocInfo::kNoPosition); | 378 arguments, RelocInfo::kNoPosition); |
334 | 379 |
335 auto if_statement = factory()->NewIfStatement( | 380 auto if_statement = factory()->NewIfStatement( |
336 factory()->NewUnaryOperation(Token::NOT, | 381 factory()->NewUnaryOperation(Token::NOT, |
337 factory()->NewVariableProxy(done), | 382 factory()->NewVariableProxy(done), |
338 RelocInfo::kNoPosition), | 383 RelocInfo::kNoPosition), |
339 factory()->NewExpressionStatement(spread_into_array_call, | 384 factory()->NewExpressionStatement(spread_into_array_call, |
340 RelocInfo::kNoPosition), | 385 RelocInfo::kNoPosition), |
341 factory()->NewEmptyStatement(RelocInfo::kNoPosition), | 386 factory()->NewEmptyStatement(RelocInfo::kNoPosition), |
342 RelocInfo::kNoPosition); | 387 RelocInfo::kNoPosition); |
343 block_->statements()->Add(if_statement, zone()); | 388 block_->statements()->Add(if_statement, zone()); |
344 | 389 |
345 RecurseIntoSubpattern(spread->expression(), | 390 RecurseIntoSubpattern(spread->expression(), |
346 factory()->NewVariableProxy(array)); | 391 factory()->NewVariableProxy(array)); |
347 } | 392 } |
393 | |
394 if (outer_block != block_) { | |
395 DoExpression* work = | |
396 factory()->NewDoExpression(block_, temp, node->position()); | |
397 block_ = outer_block; | |
398 block_->statements()->Add( | |
399 factory()->NewExpressionStatement(work, node->position()), zone()); | |
400 } | |
348 } | 401 } |
349 | 402 |
350 | 403 |
351 void Parser::PatternRewriter::VisitAssignment(Assignment* node) { | 404 void Parser::PatternRewriter::VisitAssignment(Assignment* node) { |
352 // let {<pattern> = <init>} = <value> | 405 // let {<pattern> = <init>} = <value> |
353 // becomes | 406 // becomes |
354 // temp = <value>; | 407 // temp = <value>; |
355 // <pattern> = temp === undefined ? <init> : temp; | 408 // <pattern> = temp === undefined ? <init> : temp; |
409 PatternContext old_context = context(); | |
410 if (old_context == INITIALIZER) { | |
411 set_context(ASSIGNMENT); | |
412 } else if (old_context == BINDING) { | |
413 set_context(INITIALIZER); | |
414 } | |
356 DCHECK(node->op() == Token::ASSIGN); | 415 DCHECK(node->op() == Token::ASSIGN); |
357 auto temp = CreateTempVar(current_value_); | 416 auto temp = CreateTempVar(current_value_); |
358 Expression* is_undefined = factory()->NewCompareOperation( | 417 Expression* is_undefined = factory()->NewCompareOperation( |
359 Token::EQ_STRICT, factory()->NewVariableProxy(temp), | 418 Token::EQ_STRICT, factory()->NewVariableProxy(temp), |
360 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), | 419 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), |
361 RelocInfo::kNoPosition); | 420 RelocInfo::kNoPosition); |
362 Expression* value = factory()->NewConditional( | 421 Expression* value = factory()->NewConditional( |
363 is_undefined, node->value(), factory()->NewVariableProxy(temp), | 422 is_undefined, node->value(), factory()->NewVariableProxy(temp), |
364 RelocInfo::kNoPosition); | 423 RelocInfo::kNoPosition); |
365 RecurseIntoSubpattern(node->target(), value); | 424 RecurseIntoSubpattern(node->target(), value); |
425 set_context(old_context); | |
366 } | 426 } |
367 | 427 |
368 | 428 |
429 // =============== ASSIGNMENT-ONLY ========================= | |
430 | |
431 void Parser::PatternRewriter::VisitProperty(v8::internal::Property* pattern) { | |
432 DCHECK(context() == ASSIGNMENT); | |
433 Expression* value = current_value_; | |
434 Assignment* assignment = factory()->NewAssignment(Token::ASSIGN, pattern, | |
435 value, pattern->position()); | |
436 block_->statements()->Add( | |
437 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), | |
438 zone()); | |
439 } | |
440 | |
441 | |
369 // =============== UNREACHABLE ============================= | 442 // =============== UNREACHABLE ============================= |
370 | 443 |
371 void Parser::PatternRewriter::Visit(AstNode* node) { UNREACHABLE(); } | 444 void Parser::PatternRewriter::Visit(AstNode* node) { UNREACHABLE(); } |
372 | 445 |
373 #define NOT_A_PATTERN(Node) \ | 446 #define NOT_A_PATTERN(Node) \ |
374 void Parser::PatternRewriter::Visit##Node(v8::internal::Node*) { \ | 447 void Parser::PatternRewriter::Visit##Node(v8::internal::Node*) { \ |
375 UNREACHABLE(); \ | 448 UNREACHABLE(); \ |
376 } | 449 } |
377 | 450 |
378 NOT_A_PATTERN(BinaryOperation) | 451 NOT_A_PATTERN(BinaryOperation) |
(...skipping 17 matching lines...) Expand all Loading... | |
396 NOT_A_PATTERN(ExpressionStatement) | 469 NOT_A_PATTERN(ExpressionStatement) |
397 NOT_A_PATTERN(ForInStatement) | 470 NOT_A_PATTERN(ForInStatement) |
398 NOT_A_PATTERN(ForOfStatement) | 471 NOT_A_PATTERN(ForOfStatement) |
399 NOT_A_PATTERN(ForStatement) | 472 NOT_A_PATTERN(ForStatement) |
400 NOT_A_PATTERN(FunctionDeclaration) | 473 NOT_A_PATTERN(FunctionDeclaration) |
401 NOT_A_PATTERN(FunctionLiteral) | 474 NOT_A_PATTERN(FunctionLiteral) |
402 NOT_A_PATTERN(IfStatement) | 475 NOT_A_PATTERN(IfStatement) |
403 NOT_A_PATTERN(ImportDeclaration) | 476 NOT_A_PATTERN(ImportDeclaration) |
404 NOT_A_PATTERN(Literal) | 477 NOT_A_PATTERN(Literal) |
405 NOT_A_PATTERN(NativeFunctionLiteral) | 478 NOT_A_PATTERN(NativeFunctionLiteral) |
406 NOT_A_PATTERN(Property) | |
407 NOT_A_PATTERN(RegExpLiteral) | 479 NOT_A_PATTERN(RegExpLiteral) |
408 NOT_A_PATTERN(ReturnStatement) | 480 NOT_A_PATTERN(ReturnStatement) |
409 NOT_A_PATTERN(SloppyBlockFunctionStatement) | 481 NOT_A_PATTERN(SloppyBlockFunctionStatement) |
410 NOT_A_PATTERN(Spread) | 482 NOT_A_PATTERN(Spread) |
411 NOT_A_PATTERN(SuperPropertyReference) | 483 NOT_A_PATTERN(SuperPropertyReference) |
412 NOT_A_PATTERN(SuperCallReference) | 484 NOT_A_PATTERN(SuperCallReference) |
413 NOT_A_PATTERN(SwitchStatement) | 485 NOT_A_PATTERN(SwitchStatement) |
414 NOT_A_PATTERN(ThisFunction) | 486 NOT_A_PATTERN(ThisFunction) |
415 NOT_A_PATTERN(Throw) | 487 NOT_A_PATTERN(Throw) |
416 NOT_A_PATTERN(TryCatchStatement) | 488 NOT_A_PATTERN(TryCatchStatement) |
417 NOT_A_PATTERN(TryFinallyStatement) | 489 NOT_A_PATTERN(TryFinallyStatement) |
418 NOT_A_PATTERN(UnaryOperation) | 490 NOT_A_PATTERN(UnaryOperation) |
419 NOT_A_PATTERN(VariableDeclaration) | 491 NOT_A_PATTERN(VariableDeclaration) |
420 NOT_A_PATTERN(WhileStatement) | 492 NOT_A_PATTERN(WhileStatement) |
421 NOT_A_PATTERN(WithStatement) | 493 NOT_A_PATTERN(WithStatement) |
422 NOT_A_PATTERN(Yield) | 494 NOT_A_PATTERN(Yield) |
423 | 495 |
424 #undef NOT_A_PATTERN | 496 #undef NOT_A_PATTERN |
425 } // namespace internal | 497 } // namespace internal |
426 } // namespace v8 | 498 } // namespace v8 |
OLD | NEW |