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/isolate.h" | 5 #include "src/isolate.h" |
6 | 6 |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 | 8 |
9 #include <fstream> // NOLINT(readability/streams) | 9 #include <fstream> // NOLINT(readability/streams) |
10 #include <sstream> | 10 #include <sstream> |
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 case StackFrame::JAVA_SCRIPT: | 454 case StackFrame::JAVA_SCRIPT: |
455 case StackFrame::OPTIMIZED: | 455 case StackFrame::OPTIMIZED: |
456 case StackFrame::INTERPRETED: | 456 case StackFrame::INTERPRETED: |
457 case StackFrame::BUILTIN: { | 457 case StackFrame::BUILTIN: { |
458 JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame); | 458 JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame); |
459 // Set initial size to the maximum inlining level + 1 for the outermost | 459 // Set initial size to the maximum inlining level + 1 for the outermost |
460 // function. | 460 // function. |
461 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); | 461 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); |
462 js_frame->Summarize(&frames); | 462 js_frame->Summarize(&frames); |
463 for (int i = frames.length() - 1; i >= 0; i--) { | 463 for (int i = frames.length() - 1; i >= 0; i--) { |
464 Handle<JSFunction> fun = frames[i].function(); | 464 const auto& summ = frames[i].AsJavaScript(); |
| 465 Handle<JSFunction> fun = summ.function(); |
465 | 466 |
466 // Filter out internal frames that we do not want to show. | 467 // Filter out internal frames that we do not want to show. |
467 if (!helper.IsVisibleInStackTrace(*fun)) continue; | 468 if (!helper.IsVisibleInStackTrace(*fun)) continue; |
468 | 469 |
469 Handle<Object> recv = frames[i].receiver(); | 470 Handle<Object> recv = frames[i].receiver(); |
470 Handle<AbstractCode> abstract_code = frames[i].abstract_code(); | 471 Handle<AbstractCode> abstract_code = summ.abstract_code(); |
471 const int offset = frames[i].code_offset(); | 472 const int offset = frames[i].code_offset(); |
472 | 473 |
473 bool force_constructor = false; | 474 bool force_constructor = false; |
474 if (frame->type() == StackFrame::BUILTIN) { | 475 if (frame->type() == StackFrame::BUILTIN) { |
475 // Help CallSite::IsConstructor correctly detect hand-written | 476 // Help CallSite::IsConstructor correctly detect hand-written |
476 // construct stubs. | 477 // construct stubs. |
477 if (Code::cast(*abstract_code)->is_construct_stub()) { | 478 if (Code::cast(*abstract_code)->is_construct_stub()) { |
478 force_constructor = true; | 479 force_constructor = true; |
479 } | 480 } |
480 } | 481 } |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
620 eval_key_ = | 621 eval_key_ = |
621 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("isEval")); | 622 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("isEval")); |
622 } | 623 } |
623 if (options & StackTrace::kIsConstructor) { | 624 if (options & StackTrace::kIsConstructor) { |
624 constructor_key_ = factory()->InternalizeOneByteString( | 625 constructor_key_ = factory()->InternalizeOneByteString( |
625 STATIC_CHAR_VECTOR("isConstructor")); | 626 STATIC_CHAR_VECTOR("isConstructor")); |
626 } | 627 } |
627 } | 628 } |
628 | 629 |
629 Handle<JSObject> NewStackFrameObject(FrameSummary& summ) { | 630 Handle<JSObject> NewStackFrameObject(FrameSummary& summ) { |
630 int position = summ.abstract_code()->SourcePosition(summ.code_offset()); | 631 if (summ.IsJavaScript()) return NewStackFrameObject(summ.AsJavaScript()); |
631 return NewStackFrameObject(summ.function(), position, | 632 if (summ.IsWasm()) return NewStackFrameObject(summ.AsWasm()); |
632 summ.is_constructor()); | 633 UNREACHABLE(); |
| 634 return Handle<JSObject>::null(); |
633 } | 635 } |
634 | 636 |
635 Handle<JSObject> NewStackFrameObject(Handle<JSFunction> fun, int position, | 637 Handle<JSObject> NewStackFrameObject( |
636 bool is_constructor) { | 638 const FrameSummary::JavaScriptFrameSummary& summ) { |
637 Handle<JSObject> stack_frame = | 639 Handle<JSObject> stack_frame = |
638 factory()->NewJSObject(isolate_->object_function()); | 640 factory()->NewJSObject(isolate_->object_function()); |
639 Handle<Script> script(Script::cast(fun->shared()->script()), isolate_); | 641 Handle<Script> script = Handle<Script>::cast(summ.script()); |
640 | 642 |
641 if (!line_key_.is_null()) { | 643 if (!line_key_.is_null()) { |
642 Script::PositionInfo info; | 644 Script::PositionInfo info; |
643 bool valid_pos = | 645 bool valid_pos = Script::GetPositionInfo(script, summ.SourcePosition(), |
644 Script::GetPositionInfo(script, position, &info, Script::WITH_OFFSET); | 646 &info, Script::WITH_OFFSET); |
645 | 647 |
646 if (!column_key_.is_null() && valid_pos) { | 648 if (!column_key_.is_null() && valid_pos) { |
647 JSObject::AddProperty(stack_frame, column_key_, | 649 JSObject::AddProperty(stack_frame, column_key_, |
648 handle(Smi::FromInt(info.column + 1), isolate_), | 650 handle(Smi::FromInt(info.column + 1), isolate_), |
649 NONE); | 651 NONE); |
650 } | 652 } |
651 JSObject::AddProperty(stack_frame, line_key_, | 653 JSObject::AddProperty(stack_frame, line_key_, |
652 handle(Smi::FromInt(info.line + 1), isolate_), | 654 handle(Smi::FromInt(info.line + 1), isolate_), |
653 NONE); | 655 NONE); |
654 } | 656 } |
(...skipping 14 matching lines...) Expand all Loading... |
669 NONE); | 671 NONE); |
670 } | 672 } |
671 | 673 |
672 if (!eval_key_.is_null()) { | 674 if (!eval_key_.is_null()) { |
673 Handle<Object> is_eval = factory()->ToBoolean( | 675 Handle<Object> is_eval = factory()->ToBoolean( |
674 script->compilation_type() == Script::COMPILATION_TYPE_EVAL); | 676 script->compilation_type() == Script::COMPILATION_TYPE_EVAL); |
675 JSObject::AddProperty(stack_frame, eval_key_, is_eval, NONE); | 677 JSObject::AddProperty(stack_frame, eval_key_, is_eval, NONE); |
676 } | 678 } |
677 | 679 |
678 if (!function_key_.is_null()) { | 680 if (!function_key_.is_null()) { |
679 Handle<Object> fun_name = JSFunction::GetDebugName(fun); | 681 Handle<String> fun_name = summ.FunctionName(); |
680 JSObject::AddProperty(stack_frame, function_key_, fun_name, NONE); | 682 JSObject::AddProperty(stack_frame, function_key_, fun_name, NONE); |
681 } | 683 } |
682 | 684 |
683 if (!constructor_key_.is_null()) { | 685 if (!constructor_key_.is_null()) { |
684 Handle<Object> is_constructor_obj = factory()->ToBoolean(is_constructor); | 686 Handle<Object> is_constructor_obj = |
| 687 factory()->ToBoolean(summ.is_constructor()); |
685 JSObject::AddProperty(stack_frame, constructor_key_, is_constructor_obj, | 688 JSObject::AddProperty(stack_frame, constructor_key_, is_constructor_obj, |
686 NONE); | 689 NONE); |
687 } | 690 } |
688 return stack_frame; | 691 return stack_frame; |
689 } | 692 } |
690 | 693 |
691 Handle<JSObject> NewStackFrameObject(BuiltinExitFrame* frame) { | 694 Handle<JSObject> NewStackFrameObject(BuiltinExitFrame* frame) { |
692 Handle<JSObject> stack_frame = | 695 Handle<JSObject> stack_frame = |
693 factory()->NewJSObject(isolate_->object_function()); | 696 factory()->NewJSObject(isolate_->object_function()); |
694 Handle<JSFunction> fun = handle(frame->function(), isolate_); | 697 Handle<JSFunction> fun = handle(frame->function(), isolate_); |
695 if (!function_key_.is_null()) { | 698 if (!function_key_.is_null()) { |
696 Handle<Object> fun_name = JSFunction::GetDebugName(fun); | 699 Handle<Object> fun_name = JSFunction::GetDebugName(fun); |
697 JSObject::AddProperty(stack_frame, function_key_, fun_name, NONE); | 700 JSObject::AddProperty(stack_frame, function_key_, fun_name, NONE); |
698 } | 701 } |
699 | 702 |
700 // We don't have a script and hence cannot set line and col positions. | 703 // We don't have a script and hence cannot set line and col positions. |
701 DCHECK(!fun->shared()->script()->IsScript()); | 704 DCHECK(!fun->shared()->script()->IsScript()); |
702 | 705 |
703 return stack_frame; | 706 return stack_frame; |
704 } | 707 } |
705 | 708 |
706 Handle<JSObject> NewStackFrameObject(WasmCompiledFrame* frame) { | 709 Handle<JSObject> NewStackFrameObject( |
| 710 const FrameSummary::WasmFrameSummary& summ) { |
707 Handle<JSObject> stack_frame = | 711 Handle<JSObject> stack_frame = |
708 factory()->NewJSObject(isolate_->object_function()); | 712 factory()->NewJSObject(isolate_->object_function()); |
709 | 713 |
710 if (!function_key_.is_null()) { | 714 if (!function_key_.is_null()) { |
711 Handle<WasmCompiledModule> compiled_module( | 715 Handle<WasmCompiledModule> compiled_module( |
712 frame->wasm_instance()->compiled_module(), isolate_); | 716 summ.wasm_instance()->compiled_module(), isolate_); |
713 Handle<String> name = WasmCompiledModule::GetFunctionName( | 717 Handle<String> name = WasmCompiledModule::GetFunctionName( |
714 isolate_, compiled_module, frame->function_index()); | 718 isolate_, compiled_module, summ.function_index()); |
715 JSObject::AddProperty(stack_frame, function_key_, name, NONE); | 719 JSObject::AddProperty(stack_frame, function_key_, name, NONE); |
716 } | 720 } |
717 // Encode the function index as line number (1-based). | 721 // Encode the function index as line number (1-based). |
718 if (!line_key_.is_null()) { | 722 if (!line_key_.is_null()) { |
719 JSObject::AddProperty( | 723 JSObject::AddProperty( |
720 stack_frame, line_key_, | 724 stack_frame, line_key_, |
721 isolate_->factory()->NewNumberFromInt(frame->function_index() + 1), | 725 isolate_->factory()->NewNumberFromInt(summ.function_index() + 1), |
722 NONE); | 726 NONE); |
723 } | 727 } |
724 // Encode the byte offset as column (1-based). | 728 // Encode the byte offset as column (1-based). |
725 if (!column_key_.is_null()) { | 729 if (!column_key_.is_null()) { |
726 Code* code = frame->LookupCode(); | 730 int position = summ.byte_offset(); |
727 int offset = static_cast<int>(frame->pc() - code->instruction_start()); | |
728 int position = AbstractCode::cast(code)->SourcePosition(offset); | |
729 // Make position 1-based. | 731 // Make position 1-based. |
730 if (position >= 0) ++position; | 732 if (position >= 0) ++position; |
731 JSObject::AddProperty(stack_frame, column_key_, | 733 JSObject::AddProperty(stack_frame, column_key_, |
732 isolate_->factory()->NewNumberFromInt(position), | 734 isolate_->factory()->NewNumberFromInt(position), |
733 NONE); | 735 NONE); |
734 } | 736 } |
735 if (!script_id_key_.is_null()) { | 737 if (!script_id_key_.is_null()) { |
736 int script_id = frame->script()->id(); | 738 int script_id = summ.script()->id(); |
737 JSObject::AddProperty(stack_frame, script_id_key_, | 739 JSObject::AddProperty(stack_frame, script_id_key_, |
738 handle(Smi::FromInt(script_id), isolate_), NONE); | 740 handle(Smi::FromInt(script_id), isolate_), NONE); |
739 } | 741 } |
740 | 742 |
741 return stack_frame; | 743 return stack_frame; |
742 } | 744 } |
743 | 745 |
744 private: | 746 private: |
745 inline Factory* factory() { return isolate_->factory(); } | 747 inline Factory* factory() { return isolate_->factory(); } |
746 | 748 |
(...skipping 16 matching lines...) Expand all Loading... |
763 // Ensure no negative values. | 765 // Ensure no negative values. |
764 int limit = Max(frame_limit, 0); | 766 int limit = Max(frame_limit, 0); |
765 Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit); | 767 Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit); |
766 Handle<FixedArray> stack_trace_elems( | 768 Handle<FixedArray> stack_trace_elems( |
767 FixedArray::cast(stack_trace->elements()), this); | 769 FixedArray::cast(stack_trace->elements()), this); |
768 | 770 |
769 int frames_seen = 0; | 771 int frames_seen = 0; |
770 for (StackTraceFrameIterator it(this); !it.done() && (frames_seen < limit); | 772 for (StackTraceFrameIterator it(this); !it.done() && (frames_seen < limit); |
771 it.Advance()) { | 773 it.Advance()) { |
772 StandardFrame* frame = it.frame(); | 774 StandardFrame* frame = it.frame(); |
773 if (frame->is_java_script()) { | 775 // Set initial size to the maximum inlining level + 1 for the outermost |
774 // Set initial size to the maximum inlining level + 1 for the outermost | 776 // function. |
775 // function. | 777 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); |
776 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); | 778 frame->Summarize(&frames); |
777 JavaScriptFrame::cast(frame)->Summarize(&frames); | 779 for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) { |
778 for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) { | 780 // Filter frames from other security contexts. |
779 Handle<JSFunction> fun = frames[i].function(); | 781 if (!(options & StackTrace::kExposeFramesAcrossSecurityOrigins) && |
780 // Filter frames from other security contexts. | 782 !this->context()->HasSameSecurityTokenAs(*frames[i].native_context())) |
781 if (!(options & StackTrace::kExposeFramesAcrossSecurityOrigins) && | 783 continue; |
782 !this->context()->HasSameSecurityTokenAs(fun->context())) | 784 Handle<JSObject> new_frame_obj = helper.NewStackFrameObject(frames[i]); |
783 continue; | |
784 Handle<JSObject> new_frame_obj = helper.NewStackFrameObject(frames[i]); | |
785 stack_trace_elems->set(frames_seen, *new_frame_obj); | |
786 frames_seen++; | |
787 } | |
788 } else { | |
789 DCHECK(frame->is_wasm()); | |
790 WasmCompiledFrame* wasm_frame = WasmCompiledFrame::cast(frame); | |
791 Handle<JSObject> new_frame_obj = helper.NewStackFrameObject(wasm_frame); | |
792 stack_trace_elems->set(frames_seen, *new_frame_obj); | 785 stack_trace_elems->set(frames_seen, *new_frame_obj); |
793 frames_seen++; | 786 frames_seen++; |
794 } | 787 } |
795 } | 788 } |
796 | 789 |
797 stack_trace->set_length(Smi::FromInt(frames_seen)); | 790 stack_trace->set_length(Smi::FromInt(frames_seen)); |
798 return stack_trace; | 791 return stack_trace; |
799 } | 792 } |
800 | 793 |
801 | 794 |
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1338 HandlerTable::CatchPrediction PredictException(JavaScriptFrame* frame) { | 1331 HandlerTable::CatchPrediction PredictException(JavaScriptFrame* frame) { |
1339 HandlerTable::CatchPrediction prediction; | 1332 HandlerTable::CatchPrediction prediction; |
1340 if (frame->is_optimized()) { | 1333 if (frame->is_optimized()) { |
1341 if (frame->LookupExceptionHandlerInTable(nullptr, nullptr) > 0) { | 1334 if (frame->LookupExceptionHandlerInTable(nullptr, nullptr) > 0) { |
1342 // This optimized frame will catch. It's handler table does not include | 1335 // This optimized frame will catch. It's handler table does not include |
1343 // exception prediction, and we need to use the corresponding handler | 1336 // exception prediction, and we need to use the corresponding handler |
1344 // tables on the unoptimized code objects. | 1337 // tables on the unoptimized code objects. |
1345 List<FrameSummary> summaries; | 1338 List<FrameSummary> summaries; |
1346 frame->Summarize(&summaries); | 1339 frame->Summarize(&summaries); |
1347 for (const FrameSummary& summary : summaries) { | 1340 for (const FrameSummary& summary : summaries) { |
1348 Handle<AbstractCode> code = summary.abstract_code(); | 1341 Handle<AbstractCode> code = summary.AsJavaScript().abstract_code(); |
1349 if (code->IsCode() && code->kind() == AbstractCode::BUILTIN) { | 1342 if (code->IsCode() && code->kind() == AbstractCode::BUILTIN) { |
1350 if (code->GetCode()->is_promise_rejection()) { | 1343 if (code->GetCode()->is_promise_rejection()) { |
1351 return HandlerTable::PROMISE; | 1344 return HandlerTable::PROMISE; |
1352 } | 1345 } |
1353 | 1346 |
1354 // This the exception throw in PromiseHandle which doesn't | 1347 // This the exception throw in PromiseHandle which doesn't |
1355 // cause a promise rejection. | 1348 // cause a promise rejection. |
1356 if (code->GetCode()->is_exception_caught()) { | 1349 if (code->GetCode()->is_exception_caught()) { |
1357 return HandlerTable::CAUGHT; | 1350 return HandlerTable::CAUGHT; |
1358 } | 1351 } |
1359 } | 1352 } |
1360 | 1353 |
1361 if (code->kind() == AbstractCode::OPTIMIZED_FUNCTION) { | 1354 if (code->kind() == AbstractCode::OPTIMIZED_FUNCTION) { |
1362 DCHECK(summary.function()->shared()->asm_function()); | 1355 DCHECK(summary.AsJavaScript().function()->shared()->asm_function()); |
1363 // asm code cannot contain try-catch. | 1356 // asm code cannot contain try-catch. |
1364 continue; | 1357 continue; |
1365 } | 1358 } |
1366 // Must have been constructed from a bytecode array. | 1359 // Must have been constructed from a bytecode array. |
1367 CHECK_EQ(AbstractCode::INTERPRETED_FUNCTION, code->kind()); | 1360 CHECK_EQ(AbstractCode::INTERPRETED_FUNCTION, code->kind()); |
1368 int code_offset = summary.code_offset(); | 1361 int code_offset = summary.code_offset(); |
1369 BytecodeArray* bytecode = code->GetBytecodeArray(); | 1362 BytecodeArray* bytecode = code->GetBytecodeArray(); |
1370 HandlerTable* table = HandlerTable::cast(bytecode->handler_table()); | 1363 HandlerTable* table = HandlerTable::cast(bytecode->handler_table()); |
1371 int index = table->LookupRange(code_offset, nullptr, &prediction); | 1364 int index = table->LookupRange(code_offset, nullptr, &prediction); |
1372 if (index <= 0) continue; | 1365 if (index <= 0) continue; |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1496 line->PrintOn(out); | 1489 line->PrintOn(out); |
1497 PrintF(out, "\n"); | 1490 PrintF(out, "\n"); |
1498 } | 1491 } |
1499 } | 1492 } |
1500 } | 1493 } |
1501 | 1494 |
1502 bool Isolate::ComputeLocation(MessageLocation* target) { | 1495 bool Isolate::ComputeLocation(MessageLocation* target) { |
1503 StackTraceFrameIterator it(this); | 1496 StackTraceFrameIterator it(this); |
1504 if (it.done()) return false; | 1497 if (it.done()) return false; |
1505 StandardFrame* frame = it.frame(); | 1498 StandardFrame* frame = it.frame(); |
1506 // TODO(clemensh): handle wasm frames | |
1507 if (!frame->is_java_script()) return false; | |
1508 JSFunction* fun = JavaScriptFrame::cast(frame)->function(); | |
1509 Object* script = fun->shared()->script(); | |
1510 if (!script->IsScript() || | |
1511 (Script::cast(script)->source()->IsUndefined(this))) { | |
1512 return false; | |
1513 } | |
1514 Handle<Script> casted_script(Script::cast(script), this); | |
1515 // Compute the location from the function and the relocation info of the | 1499 // Compute the location from the function and the relocation info of the |
1516 // baseline code. For optimized code this will use the deoptimization | 1500 // baseline code. For optimized code this will use the deoptimization |
1517 // information to get canonical location information. | 1501 // information to get canonical location information. |
1518 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); | 1502 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); |
1519 JavaScriptFrame::cast(frame)->Summarize(&frames); | 1503 frame->Summarize(&frames); |
1520 FrameSummary& summary = frames.last(); | 1504 FrameSummary& summary = frames.last(); |
1521 int pos = summary.abstract_code()->SourcePosition(summary.code_offset()); | 1505 int pos = summary.SourcePosition(); |
1522 *target = MessageLocation(casted_script, pos, pos + 1, handle(fun, this)); | 1506 Handle<JSFunction> fun; |
| 1507 Handle<Object> script = summary.script(); |
| 1508 if (!script->IsScript() || |
| 1509 (Script::cast(*script)->source()->IsUndefined(this))) { |
| 1510 return false; |
| 1511 } |
| 1512 |
| 1513 // TODO(wasm): Remove this once trap-if is always on. |
| 1514 // Background: Without trap-if, the information on the stack trace is |
| 1515 // incomplete (see bug v8:5007). |
| 1516 if (summary.IsWasmCompiled() && !FLAG_wasm_trap_if) return false; |
| 1517 |
| 1518 if (summary.IsJavaScript()) fun = summary.AsJavaScript().function(); |
| 1519 *target = MessageLocation(Handle<Script>::cast(script), pos, pos + 1, fun); |
1523 return true; | 1520 return true; |
1524 } | 1521 } |
1525 | 1522 |
1526 bool Isolate::ComputeLocationFromException(MessageLocation* target, | 1523 bool Isolate::ComputeLocationFromException(MessageLocation* target, |
1527 Handle<Object> exception) { | 1524 Handle<Object> exception) { |
1528 if (!exception->IsJSObject()) return false; | 1525 if (!exception->IsJSObject()) return false; |
1529 | 1526 |
1530 Handle<Name> start_pos_symbol = factory()->error_start_pos_symbol(); | 1527 Handle<Name> start_pos_symbol = factory()->error_start_pos_symbol(); |
1531 Handle<Object> start_pos = JSReceiver::GetDataProperty( | 1528 Handle<Object> start_pos = JSReceiver::GetDataProperty( |
1532 Handle<JSObject>::cast(exception), start_pos_symbol); | 1529 Handle<JSObject>::cast(exception), start_pos_symbol); |
(...skipping 2130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3663 // Then check whether this scope intercepts. | 3660 // Then check whether this scope intercepts. |
3664 if ((flag & intercept_mask_)) { | 3661 if ((flag & intercept_mask_)) { |
3665 intercepted_flags_ |= flag; | 3662 intercepted_flags_ |= flag; |
3666 return true; | 3663 return true; |
3667 } | 3664 } |
3668 return false; | 3665 return false; |
3669 } | 3666 } |
3670 | 3667 |
3671 } // namespace internal | 3668 } // namespace internal |
3672 } // namespace v8 | 3669 } // namespace v8 |
OLD | NEW |