Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(357)

Side by Side Diff: Source/bindings/v8/ScriptController.cpp

Issue 13575004: Apply script preprocessor to Web page scripts only. (Closed) Base URL: https://chromium.googlesource.com/external/WebKit_trimmed.git@master
Patch Set: rebase Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698