| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/interpreter/bytecode-array-builder.h" | 7 #include "src/interpreter/bytecode-array-builder.h" |
| 8 #include "src/interpreter/bytecode-array-iterator.h" | 8 #include "src/interpreter/bytecode-array-iterator.h" |
| 9 #include "test/unittests/test-utils.h" | 9 #include "test/unittests/test-utils.h" |
| 10 | 10 |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 builder.CastAccumulatorToNumber() | 143 builder.CastAccumulatorToNumber() |
| 144 .CastAccumulatorToBoolean() | 144 .CastAccumulatorToBoolean() |
| 145 .CastAccumulatorToJSObject() | 145 .CastAccumulatorToJSObject() |
| 146 .CastAccumulatorToName(); | 146 .CastAccumulatorToName(); |
| 147 | 147 |
| 148 // Emit control flow. Return must be the last instruction. | 148 // Emit control flow. Return must be the last instruction. |
| 149 BytecodeLabel start; | 149 BytecodeLabel start; |
| 150 builder.Bind(&start); | 150 builder.Bind(&start); |
| 151 // Short jumps with Imm8 operands | 151 // Short jumps with Imm8 operands |
| 152 builder.Jump(&start) | 152 builder.Jump(&start) |
| 153 .JumpIfTrue(&start) | |
| 154 .JumpIfFalse(&start) | |
| 155 .JumpIfToBooleanTrue(&start) | |
| 156 .JumpIfToBooleanFalse(&start) | |
| 157 .JumpIfNull(&start) | 153 .JumpIfNull(&start) |
| 158 .JumpIfUndefined(&start); | 154 .JumpIfUndefined(&start); |
| 159 | 155 // Perform an operation that returns boolean value to |
| 156 // generate JumpIfTrue/False |
| 157 builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK) |
| 158 .JumpIfTrue(&start) |
| 159 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK) |
| 160 .JumpIfFalse(&start); |
| 161 // Perform an operation that returns a non-boolean operation to |
| 162 // generate JumpIfToBooleanTrue/False. |
| 163 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) |
| 164 .JumpIfTrue(&start) |
| 165 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) |
| 166 .JumpIfFalse(&start); |
| 160 // Insert dummy ops to force longer jumps | 167 // Insert dummy ops to force longer jumps |
| 161 for (int i = 0; i < 128; i++) { | 168 for (int i = 0; i < 128; i++) { |
| 162 builder.LoadTrue(); | 169 builder.LoadTrue(); |
| 163 } | 170 } |
| 164 // Longer jumps requiring Constant operand | 171 // Longer jumps requiring Constant operand |
| 165 builder.Jump(&start) | 172 builder.Jump(&start) |
| 166 .JumpIfTrue(&start) | |
| 167 .JumpIfFalse(&start) | |
| 168 .JumpIfToBooleanTrue(&start) | |
| 169 .JumpIfToBooleanFalse(&start) | |
| 170 .JumpIfNull(&start) | 173 .JumpIfNull(&start) |
| 171 .JumpIfUndefined(&start); | 174 .JumpIfUndefined(&start); |
| 175 // Perform an operation that returns boolean value to |
| 176 // generate JumpIfTrue/False |
| 177 builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK) |
| 178 .JumpIfTrue(&start) |
| 179 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK) |
| 180 .JumpIfFalse(&start); |
| 181 // Perform an operation that returns a non-boolean operation to |
| 182 // generate JumpIfToBooleanTrue/False. |
| 183 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) |
| 184 .JumpIfTrue(&start) |
| 185 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) |
| 186 .JumpIfFalse(&start); |
| 172 | 187 |
| 173 builder.EnterBlock() | 188 builder.EnterBlock() |
| 174 .Throw() | 189 .Throw() |
| 175 .LeaveBlock(); | 190 .LeaveBlock(); |
| 176 | 191 |
| 177 builder.ForInPrepare(reg).ForInDone(reg).ForInNext(reg, reg); | 192 builder.ForInPrepare(reg).ForInDone(reg).ForInNext(reg, reg); |
| 178 | 193 |
| 179 // Wide constant pool loads | 194 // Wide constant pool loads |
| 180 for (int i = 0; i < 256; i++) { | 195 for (int i = 0; i < 256; i++) { |
| 181 // Emit junk in constant pool to force wide constant pool index. | 196 // Emit junk in constant pool to force wide constant pool index. |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 // Should only have one entry for each identical constant. | 353 // Should only have one entry for each identical constant. |
| 339 CHECK_EQ(array->constant_pool()->length(), 3); | 354 CHECK_EQ(array->constant_pool()->length(), 3); |
| 340 } | 355 } |
| 341 | 356 |
| 342 | 357 |
| 343 TEST_F(BytecodeArrayBuilderTest, ForwardJumps) { | 358 TEST_F(BytecodeArrayBuilderTest, ForwardJumps) { |
| 344 static const int kFarJumpDistance = 256; | 359 static const int kFarJumpDistance = 256; |
| 345 | 360 |
| 346 BytecodeArrayBuilder builder(isolate(), zone()); | 361 BytecodeArrayBuilder builder(isolate(), zone()); |
| 347 builder.set_parameter_count(0); | 362 builder.set_parameter_count(0); |
| 348 builder.set_locals_count(0); | 363 builder.set_locals_count(1); |
| 349 builder.set_context_count(0); | 364 builder.set_context_count(0); |
| 350 | 365 |
| 351 BytecodeLabel far0, far1, far2; | 366 Register reg(0); |
| 352 BytecodeLabel near0, near1, near2; | 367 BytecodeLabel far0, far1, far2, far3, far4; |
| 368 BytecodeLabel near0, near1, near2, near3, near4; |
| 353 | 369 |
| 354 builder.Jump(&near0) | 370 builder.Jump(&near0) |
| 371 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK) |
| 355 .JumpIfTrue(&near1) | 372 .JumpIfTrue(&near1) |
| 373 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK) |
| 356 .JumpIfFalse(&near2) | 374 .JumpIfFalse(&near2) |
| 375 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) |
| 376 .JumpIfTrue(&near3) |
| 377 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) |
| 378 .JumpIfFalse(&near4) |
| 357 .Bind(&near0) | 379 .Bind(&near0) |
| 358 .Bind(&near1) | 380 .Bind(&near1) |
| 359 .Bind(&near2) | 381 .Bind(&near2) |
| 382 .Bind(&near3) |
| 383 .Bind(&near4) |
| 360 .Jump(&far0) | 384 .Jump(&far0) |
| 385 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK) |
| 361 .JumpIfTrue(&far1) | 386 .JumpIfTrue(&far1) |
| 362 .JumpIfFalse(&far2); | 387 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK) |
| 363 for (int i = 0; i < kFarJumpDistance - 6; i++) { | 388 .JumpIfFalse(&far2) |
| 389 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) |
| 390 .JumpIfTrue(&far3) |
| 391 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) |
| 392 .JumpIfFalse(&far4); |
| 393 for (int i = 0; i < kFarJumpDistance - 18; i++) { |
| 364 builder.LoadUndefined(); | 394 builder.LoadUndefined(); |
| 365 } | 395 } |
| 366 builder.Bind(&far0).Bind(&far1).Bind(&far2); | 396 builder.Bind(&far0).Bind(&far1).Bind(&far2).Bind(&far3).Bind(&far4); |
| 367 builder.Return(); | 397 builder.Return(); |
| 368 | 398 |
| 369 Handle<BytecodeArray> array = builder.ToBytecodeArray(); | 399 Handle<BytecodeArray> array = builder.ToBytecodeArray(); |
| 370 DCHECK_EQ(array->length(), 12 + kFarJumpDistance - 6 + 1); | 400 DCHECK_EQ(array->length(), 36 + kFarJumpDistance - 18 + 1); |
| 371 | 401 |
| 372 BytecodeArrayIterator iterator(array); | 402 BytecodeArrayIterator iterator(array); |
| 373 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); | 403 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); |
| 404 CHECK_EQ(iterator.GetImmediateOperand(0), 18); |
| 405 iterator.Advance(); |
| 406 |
| 407 // Ignore compare operation. |
| 408 iterator.Advance(); |
| 409 |
| 410 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue); |
| 411 CHECK_EQ(iterator.GetImmediateOperand(0), 14); |
| 412 iterator.Advance(); |
| 413 |
| 414 // Ignore compare operation. |
| 415 iterator.Advance(); |
| 416 |
| 417 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse); |
| 418 CHECK_EQ(iterator.GetImmediateOperand(0), 10); |
| 419 iterator.Advance(); |
| 420 |
| 421 // Ignore add operation. |
| 422 iterator.Advance(); |
| 423 |
| 424 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); |
| 374 CHECK_EQ(iterator.GetImmediateOperand(0), 6); | 425 CHECK_EQ(iterator.GetImmediateOperand(0), 6); |
| 375 iterator.Advance(); | 426 iterator.Advance(); |
| 376 | 427 |
| 377 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue); | 428 // Ignore add operation. |
| 378 CHECK_EQ(iterator.GetImmediateOperand(0), 4); | |
| 379 iterator.Advance(); | 429 iterator.Advance(); |
| 380 | 430 |
| 381 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse); | 431 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse); |
| 382 CHECK_EQ(iterator.GetImmediateOperand(0), 2); | 432 CHECK_EQ(iterator.GetImmediateOperand(0), 2); |
| 383 iterator.Advance(); | 433 iterator.Advance(); |
| 384 | 434 |
| 435 |
| 385 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant); | 436 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant); |
| 386 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), | 437 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), |
| 387 Smi::FromInt(kFarJumpDistance)); | 438 Smi::FromInt(kFarJumpDistance)); |
| 388 CHECK_EQ( | 439 iterator.Advance(); |
| 389 array->get(iterator.current_offset() + | 440 |
| 390 Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()), | 441 // Ignore compare operation. |
| 391 Bytecodes::ToByte(Bytecode::kReturn)); | |
| 392 iterator.Advance(); | 442 iterator.Advance(); |
| 393 | 443 |
| 394 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrueConstant); | 444 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrueConstant); |
| 395 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), | 445 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), |
| 396 Smi::FromInt(kFarJumpDistance - 2)); | 446 Smi::FromInt(kFarJumpDistance - 4)); |
| 397 CHECK_EQ( | 447 iterator.Advance(); |
| 398 array->get(iterator.current_offset() + | 448 |
| 399 Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()), | 449 // Ignore compare operation. |
| 400 Bytecodes::ToByte(Bytecode::kReturn)); | |
| 401 iterator.Advance(); | 450 iterator.Advance(); |
| 402 | 451 |
| 403 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalseConstant); | 452 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalseConstant); |
| 404 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), | 453 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), |
| 405 Smi::FromInt(kFarJumpDistance - 4)); | 454 Smi::FromInt(kFarJumpDistance - 8)); |
| 406 CHECK_EQ( | 455 iterator.Advance(); |
| 407 array->get(iterator.current_offset() + | 456 |
| 408 Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()), | 457 // Ignore add operation. |
| 409 Bytecodes::ToByte(Bytecode::kReturn)); | 458 iterator.Advance(); |
| 459 |
| 460 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrueConstant); |
| 461 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), |
| 462 Smi::FromInt(kFarJumpDistance - 12)); |
| 463 iterator.Advance(); |
| 464 |
| 465 // Ignore add operation. |
| 466 iterator.Advance(); |
| 467 |
| 468 CHECK_EQ(iterator.current_bytecode(), |
| 469 Bytecode::kJumpIfToBooleanFalseConstant); |
| 470 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), |
| 471 Smi::FromInt(kFarJumpDistance - 16)); |
| 410 iterator.Advance(); | 472 iterator.Advance(); |
| 411 } | 473 } |
| 412 | 474 |
| 413 | 475 |
| 414 TEST_F(BytecodeArrayBuilderTest, BackwardJumps) { | 476 TEST_F(BytecodeArrayBuilderTest, BackwardJumps) { |
| 415 BytecodeArrayBuilder builder(isolate(), zone()); | 477 BytecodeArrayBuilder builder(isolate(), zone()); |
| 416 builder.set_parameter_count(0); | 478 builder.set_parameter_count(0); |
| 417 builder.set_locals_count(0); | 479 builder.set_locals_count(1); |
| 418 builder.set_context_count(0); | 480 builder.set_context_count(0); |
| 481 Register reg(0); |
| 419 | 482 |
| 420 BytecodeLabel label0, label1, label2; | 483 BytecodeLabel label0, label1, label2, label3, label4; |
| 421 builder.Bind(&label0) | 484 builder.Bind(&label0) |
| 422 .Jump(&label0) | 485 .Jump(&label0) |
| 486 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK) |
| 423 .Bind(&label1) | 487 .Bind(&label1) |
| 424 .JumpIfTrue(&label1) | 488 .JumpIfTrue(&label1) |
| 489 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK) |
| 425 .Bind(&label2) | 490 .Bind(&label2) |
| 491 .JumpIfFalse(&label2) |
| 492 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) |
| 493 .Bind(&label3) |
| 494 .JumpIfTrue(&label3) |
| 495 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) |
| 496 .Bind(&label4) |
| 497 .JumpIfFalse(&label4); |
| 498 for (int i = 0; i < 64; i++) { |
| 499 builder.Jump(&label4); |
| 500 } |
| 501 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) |
| 502 .JumpIfFalse(&label4); |
| 503 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) |
| 504 .JumpIfTrue(&label3); |
| 505 builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK) |
| 426 .JumpIfFalse(&label2); | 506 .JumpIfFalse(&label2); |
| 427 for (int i = 0; i < 64; i++) { | 507 builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK) |
| 428 builder.Jump(&label2); | 508 .JumpIfTrue(&label1); |
| 429 } | |
| 430 builder.JumpIfFalse(&label2); | |
| 431 builder.JumpIfTrue(&label1); | |
| 432 builder.Jump(&label0); | 509 builder.Jump(&label0); |
| 433 builder.Return(); | 510 builder.Return(); |
| 434 | 511 |
| 435 Handle<BytecodeArray> array = builder.ToBytecodeArray(); | 512 Handle<BytecodeArray> array = builder.ToBytecodeArray(); |
| 436 BytecodeArrayIterator iterator(array); | 513 BytecodeArrayIterator iterator(array); |
| 437 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); | 514 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); |
| 438 CHECK_EQ(iterator.GetImmediateOperand(0), 0); | 515 CHECK_EQ(iterator.GetImmediateOperand(0), 0); |
| 439 iterator.Advance(); | 516 iterator.Advance(); |
| 517 // Ignore compare operation. |
| 518 iterator.Advance(); |
| 440 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue); | 519 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue); |
| 441 CHECK_EQ(iterator.GetImmediateOperand(0), 0); | 520 CHECK_EQ(iterator.GetImmediateOperand(0), 0); |
| 442 iterator.Advance(); | 521 iterator.Advance(); |
| 522 // Ignore compare operation. |
| 523 iterator.Advance(); |
| 443 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse); | 524 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse); |
| 444 CHECK_EQ(iterator.GetImmediateOperand(0), 0); | 525 CHECK_EQ(iterator.GetImmediateOperand(0), 0); |
| 445 iterator.Advance(); | 526 iterator.Advance(); |
| 527 // Ignore binary operation. |
| 528 iterator.Advance(); |
| 529 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); |
| 530 CHECK_EQ(iterator.GetImmediateOperand(0), 0); |
| 531 iterator.Advance(); |
| 532 // Ignore binary operation. |
| 533 iterator.Advance(); |
| 534 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse); |
| 535 CHECK_EQ(iterator.GetImmediateOperand(0), 0); |
| 536 iterator.Advance(); |
| 446 for (int i = 0; i < 64; i++) { | 537 for (int i = 0; i < 64; i++) { |
| 447 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); | 538 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); |
| 448 CHECK_EQ(iterator.GetImmediateOperand(0), -i * 2 - 2); | 539 CHECK_EQ(iterator.GetImmediateOperand(0), -i * 2 - 2); |
| 449 iterator.Advance(); | 540 iterator.Advance(); |
| 450 } | 541 } |
| 542 // Ignore binary operation. |
| 543 iterator.Advance(); |
| 544 CHECK_EQ(iterator.current_bytecode(), |
| 545 Bytecode::kJumpIfToBooleanFalseConstant); |
| 546 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -132); |
| 547 iterator.Advance(); |
| 548 // Ignore binary operation. |
| 549 iterator.Advance(); |
| 550 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrueConstant); |
| 551 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -140); |
| 552 iterator.Advance(); |
| 553 // Ignore compare operation. |
| 554 iterator.Advance(); |
| 451 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalseConstant); | 555 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalseConstant); |
| 452 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -130); | 556 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -148); |
| 557 iterator.Advance(); |
| 558 // Ignore compare operation. |
| 453 iterator.Advance(); | 559 iterator.Advance(); |
| 454 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrueConstant); | 560 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrueConstant); |
| 455 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -134); | 561 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -156); |
| 456 iterator.Advance(); | 562 iterator.Advance(); |
| 457 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant); | 563 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant); |
| 458 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -138); | 564 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -162); |
| 459 iterator.Advance(); | 565 iterator.Advance(); |
| 460 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); | 566 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); |
| 461 iterator.Advance(); | 567 iterator.Advance(); |
| 462 CHECK(iterator.done()); | 568 CHECK(iterator.done()); |
| 463 } | 569 } |
| 464 | 570 |
| 465 | 571 |
| 466 TEST_F(BytecodeArrayBuilderTest, LabelReuse) { | 572 TEST_F(BytecodeArrayBuilderTest, LabelReuse) { |
| 467 BytecodeArrayBuilder builder(isolate(), zone()); | 573 BytecodeArrayBuilder builder(isolate(), zone()); |
| 468 builder.set_parameter_count(0); | 574 builder.set_parameter_count(0); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 570 | 676 |
| 571 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); | 677 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); |
| 572 iterator.Advance(); | 678 iterator.Advance(); |
| 573 CHECK(iterator.done()); | 679 CHECK(iterator.done()); |
| 574 } | 680 } |
| 575 | 681 |
| 576 | 682 |
| 577 } // namespace interpreter | 683 } // namespace interpreter |
| 578 } // namespace internal | 684 } // namespace internal |
| 579 } // namespace v8 | 685 } // namespace v8 |
| OLD | NEW |