Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2008, 2009 Google Inc. All rights reserved. | 2 * Copyright (C) 2008, 2009 Google Inc. All rights reserved. |
| 3 * Copyright (C) 2009 Apple Inc. All rights reserved. | 3 * Copyright (C) 2009 Apple Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
| 7 * met: | 7 * met: |
| 8 * | 8 * |
| 9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 661 | 661 |
| 662 String scriptResult; | 662 String scriptResult; |
| 663 if (!result.getString(scriptResult)) | 663 if (!result.getString(scriptResult)) |
| 664 return true; | 664 return true; |
| 665 | 665 |
| 666 // We're still in a frame, so there should be a DocumentLoader. | 666 // We're still in a frame, so there should be a DocumentLoader. |
| 667 ASSERT(m_frame->document()->loader()); | 667 ASSERT(m_frame->document()->loader()); |
| 668 | 668 |
| 669 if (!locationChangeBefore && m_frame->navigationScheduler()->locationChangeP ending()) | 669 if (!locationChangeBefore && m_frame->navigationScheduler()->locationChangeP ending()) |
| 670 return true; | 670 return true; |
| 671 | 671 |
| 672 // DocumentWriter::replaceDocument can cause the DocumentLoader to get deref 'ed and possible destroyed, | 672 // DocumentWriter::replaceDocument can cause the DocumentLoader to get deref 'ed and possible destroyed, |
| 673 // so protect it with a RefPtr. | 673 // so protect it with a RefPtr. |
| 674 if (RefPtr<DocumentLoader> loader = m_frame->document()->loader()) | 674 if (RefPtr<DocumentLoader> loader = m_frame->document()->loader()) |
| 675 loader->replaceDocument(scriptResult, ownerDocument.get()); | 675 loader->replaceDocument(scriptResult, ownerDocument.get()); |
| 676 return true; | 676 return true; |
| 677 } | 677 } |
| 678 | 678 |
| 679 ScriptValue ScriptController::executeScriptInMainWorld(const ScriptSourceCode& s ourceCode) | 679 ScriptValue ScriptController::executeScriptInMainWorld(const ScriptSourceCode& s ourceCode) |
| 680 { | 680 { |
| 681 String sourceURL = sourceCode.url(); | 681 String sourceURL = sourceCode.url(); |
| 682 const String* savedSourceURL = m_sourceURL; | 682 const String* savedSourceURL = m_sourceURL; |
| 683 m_sourceURL = &sourceURL; | 683 m_sourceURL = &sourceURL; |
| 684 | 684 |
| 685 v8::HandleScope handleScope; | 685 v8::HandleScope handleScope; |
| 686 v8::Handle<v8::Context> v8Context = ScriptController::mainWorldContext(m_fra me); | 686 v8::Handle<v8::Context> v8Context = ScriptController::mainWorldContext(m_fra me); |
| 687 if (v8Context.IsEmpty()) | 687 if (v8Context.IsEmpty()) |
| 688 return ScriptValue(); | 688 return ScriptValue(); |
| 689 | 689 |
| 690 String processedString = m_frame->script()->preprocess(sourceCode.source(), sourceURL); | |
| 691 ScriptSourceCode processedSourceCode(processedString, sourceCode.url(), sour ceCode.startPosition()); | |
| 692 | |
| 690 v8::Context::Scope scope(v8Context); | 693 v8::Context::Scope scope(v8Context); |
| 691 RefPtr<Frame> protect(m_frame); | 694 RefPtr<Frame> protect(m_frame); |
| 692 v8::Local<v8::Value> object = compileAndRunScript(sourceCode); | 695 v8::Local<v8::Value> object = compileAndRunScript(processedSourceCode); |
| 693 | 696 |
| 694 m_sourceURL = savedSourceURL; | 697 m_sourceURL = savedSourceURL; |
| 695 | 698 |
| 696 if (object.IsEmpty()) | 699 if (object.IsEmpty()) |
| 697 return ScriptValue(); | 700 return ScriptValue(); |
| 698 | 701 |
| 699 return ScriptValue(object); | 702 return ScriptValue(object); |
| 700 } | 703 } |
| 701 | 704 |
| 702 void ScriptController::executeScriptInIsolatedWorld(int worldID, const Vector<Sc riptSourceCode>& sources, int extensionGroup, Vector<ScriptValue>* results) | 705 void ScriptController::executeScriptInIsolatedWorld(int worldID, const Vector<Sc riptSourceCode>& sources, int extensionGroup, Vector<ScriptValue>* results) |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 726 | 729 |
| 727 v8Results = evaluateHandleScope.Close(resultArray); | 730 v8Results = evaluateHandleScope.Close(resultArray); |
| 728 } | 731 } |
| 729 | 732 |
| 730 if (results && !v8Results.IsEmpty()) { | 733 if (results && !v8Results.IsEmpty()) { |
| 731 for (size_t i = 0; i < v8Results->Length(); ++i) | 734 for (size_t i = 0; i < v8Results->Length(); ++i) |
| 732 results->append(ScriptValue(v8Results->Get(i))); | 735 results->append(ScriptValue(v8Results->Get(i))); |
| 733 } | 736 } |
| 734 } | 737 } |
| 735 | 738 |
| 739 class ScriptController::ScriptPreprocessor { | |
| 740 WTF_MAKE_NONCOPYABLE(ScriptPreprocessor); | |
| 741 public: | |
| 742 ScriptPreprocessor(const String& preprocessorScript, ScriptController* contr oller) | |
| 743 : m_controller(controller), m_isolate(controller->m_isolate) | |
|
abarth-chromium
2013/07/08 23:57:08
The correct style is to use separate lines for eac
johnjbarton
2013/07/09 22:44:54
Done.
| |
| 744 { | |
| 745 v8::HandleScope scope(m_isolate); | |
|
abarth-chromium
2013/07/08 23:57:08
Is it safe to hold the isolate across call stacks?
johnjbarton
2013/07/09 22:44:54
ScriptController holds an isolate so I guess it is
| |
| 746 | |
| 747 v8::TryCatch tryCatch; | |
| 748 tryCatch.SetVerbose(true); | |
| 749 ScriptSourceCode preprocessor(preprocessorScript); | |
| 750 Vector<ScriptSourceCode> sources; | |
| 751 sources.append(preprocessor); | |
| 752 Vector<ScriptValue> scriptResults; | |
| 753 controller->executeScriptInIsolatedWorld(ScriptPreprocessorIsolatedWorld Id, sources, 0, &scriptResults); | |
| 754 | |
| 755 ScriptValue preprocessorFunction = scriptResults[0]; | |
|
abarth-chromium
2013/07/08 23:57:08
What if scriptResults is empty ?
johnjbarton
2013/07/09 22:44:54
executeScriptInIsolatedWorld maps sources onto scr
| |
| 756 if (!preprocessorFunction.isFunction()) { | |
| 757 v8::Context::Scope contextScope(m_controller->mainWorldContext()); | |
| 758 String notAFunction = String("The preprocessor must compile to a fun ction."); | |
| 759 String preprocessorName = String("reloadPreprocessorOptionSource.js" ); | |
| 760 getScriptExecutionContext()->reportException(notAFunction, 1, prepro cessorName, RefPtr<ScriptCallStack>()); | |
| 761 return; | |
|
abarth-chromium
2013/07/08 23:57:08
I don't understand what you're trying to do there.
johnjbarton
2013/07/09 22:44:54
Done.
| |
| 762 } | |
| 763 | |
| 764 m_preprocessorFunction.set(m_isolate, v8::Handle<v8::Function>::Cast(pre processorFunction.v8Value())); | |
| 765 } | |
| 766 | |
| 767 String preprocessSourceCode(const String& sourceCode, const String& sourceNa me) | |
| 768 { | |
| 769 v8::HandleScope handleScope(m_isolate); | |
| 770 if (m_preprocessorFunction.isEmpty()) | |
| 771 return sourceCode; | |
|
abarth-chromium
2013/07/08 23:57:08
You can do this before creating the handleScope
johnjbarton
2013/07/09 22:44:54
Done, pls recheck the new location.
| |
| 772 | |
| 773 RefPtr<DOMWrapperWorld> world = DOMWrapperWorld::ensureIsolatedWorld(Scr iptPreprocessorIsolatedWorldId, 0); | |
| 774 V8WindowShell* isolatedWorldShell = m_controller->windowShell(world.get( )); | |
| 775 | |
| 776 if (!isolatedWorldShell->isContextInitialized()) | |
| 777 return sourceCode; | |
|
abarth-chromium
2013/07/08 23:57:08
When does this happy? How can m_preprocessorFunct
johnjbarton
2013/07/09 22:44:54
Done.
| |
| 778 | |
| 779 v8::Local<v8::Context> context = isolatedWorldShell->context(); | |
| 780 v8::Context::Scope contextScope(context); | |
| 781 v8::Handle<v8::String> sourceCodeString = v8String(sourceCode, m_isolate ); | |
| 782 v8::Handle<v8::String> sourceNameString = v8String(sourceName, m_isolate ); | |
| 783 v8::Handle<v8::Value> argv[] = { sourceCodeString, sourceNameString }; | |
| 784 | |
| 785 v8::TryCatch tryCatch; | |
| 786 tryCatch.SetVerbose(true); | |
| 787 m_isPreprocessing = true; | |
|
abarth-chromium
2013/07/08 23:57:08
Please use TemporaryChange to make sure we handle
johnjbarton
2013/07/09 22:44:54
Done.
| |
| 788 v8::Handle<v8::Value> resultValue = | |
| 789 V8ScriptRunner::callAsFunction(m_preprocessorFunction.newLocal(m_iso late), context->Global(), 2, argv); | |
|
abarth-chromium
2013/07/08 23:57:08
2 -> WTF_ARRAY_LENGTH
johnjbarton
2013/07/09 22:44:54
Done.
| |
| 790 m_isPreprocessing = false; | |
| 791 | |
| 792 if (!resultValue.IsEmpty() && resultValue->IsString()) | |
| 793 return toWebCoreStringWithNullCheck(resultValue); | |
| 794 | |
| 795 return sourceCode; | |
| 796 } | |
| 797 | |
| 798 bool hasPreprocessorFunction() | |
| 799 { | |
| 800 return !m_preprocessorFunction.isEmpty(); | |
| 801 } | |
| 802 | |
| 803 bool isPreprocessing() | |
| 804 { | |
| 805 return m_isPreprocessing; | |
| 806 } | |
| 807 | |
| 808 ~ScriptPreprocessor() | |
| 809 { | |
| 810 } | |
|
abarth-chromium
2013/07/08 23:57:08
The compiler will generate this function for you.
| |
| 811 | |
| 812 private: | |
| 813 String m_preprocessorBody; | |
| 814 ScopedPersistent<v8::Function> m_preprocessorFunction; | |
|
abarth-chromium
2013/07/08 23:57:08
Does this leak memory?
johnjbarton
2013/07/09 22:44:54
Destructing the ScriptPreprocessor destructs the m
| |
| 815 ScriptController* m_controller; | |
| 816 v8::Isolate* m_isolate; | |
| 817 bool m_isPreprocessing; | |
| 818 }; | |
| 819 | |
| 820 bool ScriptController::hasScriptPreprocessor() | |
| 821 { | |
| 822 return m_scriptPreprocessor && m_scriptPreprocessor->hasPreprocessorFunction (); | |
| 823 } | |
| 824 | |
| 825 bool ScriptController::isScriptPreprocessing() | |
| 826 { | |
| 827 return hasScriptPreprocessor() && m_scriptPreprocessor->isPreprocessing(); | |
| 828 } | |
| 829 | |
| 830 void ScriptController::setScriptPreprocessor(const String& preprocessorBody) | |
| 831 { | |
| 832 // The preprocessor will be created the first time it is needed. | |
| 833 m_scriptPreprocessor.clear(); | |
| 834 m_preprocessorSource = preprocessorBody; | |
|
abarth-chromium
2013/07/08 23:57:08
Why not store m_preprocessorSource in m_scriptPrep
johnjbarton
2013/07/09 22:44:54
At this point in the page setup the debugger has n
| |
| 835 } | |
| 836 | |
| 837 String ScriptController::preprocess(const String& scriptSource, const String& sc riptName) | |
| 838 { | |
| 839 if (m_preprocessorSource.isEmpty()) | |
| 840 return scriptSource; | |
| 841 | |
| 842 if (!m_scriptPreprocessor) | |
| 843 m_scriptPreprocessor = adoptPtr(new ScriptPreprocessor(m_preprocessorSou rce, this)); | |
| 844 | |
| 845 if (!m_scriptPreprocessor->hasPreprocessorFunction()) | |
| 846 return scriptSource; | |
| 847 | |
| 848 return m_scriptPreprocessor->preprocessSourceCode(scriptSource, scriptName); | |
|
abarth-chromium
2013/07/08 23:57:08
Don't we need to clear the m_scriptPreprocessor on
johnjbarton
2013/07/09 22:44:54
We clear the m_scriptPreprocessor whenever PageDeb
| |
| 849 } | |
| 850 | |
| 851 | |
| 736 } // namespace WebCore | 852 } // namespace WebCore |
| OLD | NEW |