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 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 667 { | 667 { |
| 668 String sourceURL = sourceCode.url(); | 668 String sourceURL = sourceCode.url(); |
| 669 const String* savedSourceURL = m_sourceURL; | 669 const String* savedSourceURL = m_sourceURL; |
| 670 m_sourceURL = &sourceURL; | 670 m_sourceURL = &sourceURL; |
| 671 | 671 |
| 672 v8::HandleScope handleScope; | 672 v8::HandleScope handleScope; |
| 673 v8::Handle<v8::Context> v8Context = ScriptController::mainWorldContext(m_fra me); | 673 v8::Handle<v8::Context> v8Context = ScriptController::mainWorldContext(m_fra me); |
| 674 if (v8Context.IsEmpty()) | 674 if (v8Context.IsEmpty()) |
| 675 return ScriptValue(); | 675 return ScriptValue(); |
| 676 | 676 |
| 677 String processedString = m_frame->script()->preprocess(sourceCode.source(), sourceURL); | |
| 678 ScriptSourceCode processedSourceCode(processedString, sourceCode.url(), sour ceCode.startPosition()); | |
| 679 | |
| 677 v8::Context::Scope scope(v8Context); | 680 v8::Context::Scope scope(v8Context); |
| 678 RefPtr<Frame> protect(m_frame); | 681 RefPtr<Frame> protect(m_frame); |
| 679 v8::Local<v8::Value> object = compileAndRunScript(sourceCode); | 682 v8::Local<v8::Value> object = compileAndRunScript(processedSourceCode); |
| 680 | 683 |
| 681 m_sourceURL = savedSourceURL; | 684 m_sourceURL = savedSourceURL; |
| 682 | 685 |
| 683 if (object.IsEmpty()) | 686 if (object.IsEmpty()) |
| 684 return ScriptValue(); | 687 return ScriptValue(); |
| 685 | 688 |
| 686 return ScriptValue(object); | 689 return ScriptValue(object); |
| 687 } | 690 } |
| 688 | 691 |
| 689 void ScriptController::executeScriptInIsolatedWorld(int worldID, const Vector<Sc riptSourceCode>& sources, int extensionGroup, Vector<ScriptValue>* results) | 692 void ScriptController::executeScriptInIsolatedWorld(int worldID, const Vector<Sc riptSourceCode>& sources, int extensionGroup, Vector<ScriptValue>* results) |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 713 | 716 |
| 714 v8Results = evaluateHandleScope.Close(resultArray); | 717 v8Results = evaluateHandleScope.Close(resultArray); |
| 715 } | 718 } |
| 716 | 719 |
| 717 if (results && !v8Results.IsEmpty()) { | 720 if (results && !v8Results.IsEmpty()) { |
| 718 for (size_t i = 0; i < v8Results->Length(); ++i) | 721 for (size_t i = 0; i < v8Results->Length(); ++i) |
| 719 results->append(ScriptValue(v8Results->Get(i))); | 722 results->append(ScriptValue(v8Results->Get(i))); |
| 720 } | 723 } |
| 721 } | 724 } |
| 722 | 725 |
| 726 static const String preprocessorName = "$preprocessor.js"; | |
|
abarth-chromium
2013/06/04 06:50:23
This will create a static initializer, which isn't
johnjbarton
2013/06/04 18:41:22
Done.
| |
| 727 | |
| 728 class ScriptController::ScriptPreprocessor { | |
| 729 WTF_MAKE_NONCOPYABLE(ScriptPreprocessor); | |
| 730 public: | |
| 731 ScriptPreprocessor(const String& preprocessorScript, ScriptController* contr oller) | |
| 732 : m_controller(controller), m_isolate(controller->m_isolate) | |
| 733 { | |
| 734 v8::HandleScope scope(m_isolate); | |
| 735 | |
| 736 v8::Local<v8::Context> context = v8::Context::New(m_isolate); | |
|
abarth-chromium
2013/06/04 06:50:23
Hum... I usually push back on calls to v8::Contex
johnjbarton
2013/06/04 18:41:22
I don't know what to do here: what context shall I
| |
| 737 if (context.IsEmpty()) | |
| 738 return; | |
| 739 | |
| 740 v8::Local<v8::Value> preprocessorFunction; | |
| 741 v8::TryCatch tryCatch; | |
| 742 | |
| 743 v8::Context::Scope contextScope(context); | |
| 744 v8::Handle<v8::String> preprocessor = v8::String::New(preprocessorScript .utf8().data(), preprocessorScript.utf8().length()); | |
|
abarth-chromium
2013/06/04 06:50:23
This isn't the right way to create v8 string from
johnjbarton
2013/06/04 18:41:22
Done.
| |
| 745 preprocessorFunction = V8ScriptRunner::compileAndRunInternalScript(prepr ocessor, m_isolate); | |
| 746 | |
| 747 if (tryCatch.HasCaught()) { | |
| 748 reportException(tryCatch, preprocessorName); | |
| 749 return; | |
| 750 } | |
| 751 | |
| 752 if (preprocessorFunction.IsEmpty()) | |
| 753 m_creationError = "Internal error: The preprocessor outer script gav e no value without throwing."; | |
| 754 else if (!preprocessorFunction->IsFunction()) | |
| 755 m_creationError = "The preprocessor must compile to a function."; | |
| 756 | |
| 757 if (!m_creationError.isEmpty()) { | |
| 758 reportErrorMessage(preprocessorName); | |
| 759 return; | |
| 760 } | |
| 761 | |
| 762 m_utilityContext.set(m_isolate, context); | |
| 763 m_preprocessorFunction.set(m_isolate, v8::Handle<v8::Function>::Cast(pre processorFunction)); | |
| 764 } | |
| 765 | |
| 766 void reportException(const v8::TryCatch& tryCatch, const String& sourceName) | |
| 767 { | |
| 768 v8::Local<v8::Message> message = tryCatch.Message(); | |
| 769 if (!tryCatch.Message().IsEmpty()) | |
| 770 m_creationError = toWebCoreStringWithUndefinedOrNullCheck(message->G et()); | |
| 771 else | |
| 772 m_creationError = "Unknown exception."; | |
| 773 | |
| 774 RefPtr<ScriptCallStack> callStack = createScriptCallStack( | |
| 775 message->GetStackTrace(), ScriptCallStack::maxCallStackSizeToCapture ); | |
| 776 | |
| 777 reportErrorMessage(sourceName, message->GetLineNumber(), callStack); | |
| 778 } | |
| 779 | |
| 780 void reportErrorMessage(const String& sourceName, int lineNumber = 1, PassRe fPtr<ScriptCallStack> callStack = RefPtr<ScriptCallStack>()) | |
| 781 { | |
| 782 v8::Context::Scope contextScope(m_controller->mainWorldContext()); | |
| 783 getScriptExecutionContext()->reportException(m_creationError, lineNumber , sourceName, callStack); | |
| 784 } | |
| 785 | |
| 786 String preprocessSourceCode(const String& sourceCode, const String& sourceNa me) | |
| 787 { | |
| 788 v8::HandleScope handleScope(m_isolate); | |
| 789 if (m_preprocessorFunction.isEmpty()) | |
| 790 return sourceCode; | |
| 791 | |
| 792 v8::Local<v8::Context> context = v8::Local<v8::Context>::New(m_utilityCo ntext.get()); | |
|
abarth-chromium
2013/06/04 06:50:23
I think we have a new pattern for this sort of cod
johnjbarton
2013/06/04 18:41:22
I've changed this code and I will ask Marja to rev
| |
| 793 v8::Context::Scope contextScope(context); | |
| 794 | |
| 795 v8::Handle<v8::String> sourceCodeString = v8::String::New(sourceCode.utf 8().data(), sourceCode.utf8().length()); | |
| 796 | |
| 797 v8::Handle<v8::String> sourceNameString = v8::String::New(sourceName.utf 8().data(), sourceName.utf8().length()); | |
| 798 v8::Handle<v8::Value> argv[] = { sourceCodeString, sourceNameString }; | |
| 799 | |
| 800 v8::TryCatch tryCatch; | |
| 801 v8::Handle<v8::Value> resultValue = | |
| 802 V8ScriptRunner::callAsFunction(m_preprocessorFunction.newLocal(m_iso late), context->Global(), 2, argv); | |
| 803 | |
| 804 if (tryCatch.HasCaught()) { | |
| 805 reportException(tryCatch, sourceName); | |
| 806 return sourceCode; | |
| 807 } | |
| 808 | |
| 809 if (resultValue->IsString()) { | |
| 810 v8::String::Utf8Value utf8Value(resultValue); | |
| 811 return String::fromUTF8(*utf8Value, utf8Value.length()); | |
|
abarth-chromium
2013/06/04 06:50:23
This isn't the way we create WTFStrings from v8::S
johnjbarton
2013/06/04 18:41:22
Done.
| |
| 812 } | |
| 813 return sourceCode; | |
| 814 } | |
| 815 | |
| 816 bool hadCreationError() | |
| 817 { | |
| 818 return !m_creationError.isEmpty(); | |
| 819 } | |
| 820 | |
| 821 ~ScriptPreprocessor() | |
| 822 { | |
| 823 } | |
| 824 | |
| 825 private: | |
| 826 ScopedPersistent<v8::Context> m_utilityContext; | |
| 827 String m_preprocessorBody; | |
| 828 ScopedPersistent<v8::Function> m_preprocessorFunction; | |
| 829 ScriptController* m_controller; | |
| 830 v8::Isolate* m_isolate; | |
| 831 String m_creationError; | |
| 832 }; | |
| 833 | |
| 834 void ScriptController::setScriptPreprocessor(const String& preprocessorBody) | |
| 835 { | |
| 836 // The preprocessor will be created the first time it is needed. | |
| 837 m_scriptPreprocessor.clear(); | |
| 838 m_preprocessorSource = preprocessorBody; | |
| 839 } | |
| 840 | |
| 841 String ScriptController::preprocess(const String& scriptSource, const String& sc riptName) | |
| 842 { | |
| 843 if (m_preprocessorSource.isEmpty()) | |
| 844 return scriptSource; | |
| 845 | |
| 846 if (!m_scriptPreprocessor) | |
| 847 m_scriptPreprocessor = adoptPtr(new ScriptPreprocessor(m_preprocessorSou rce, this)); | |
| 848 | |
| 849 if (m_scriptPreprocessor->hadCreationError()) | |
| 850 return scriptSource; | |
| 851 | |
| 852 return m_scriptPreprocessor->preprocessSourceCode(scriptSource, scriptName); | |
| 853 } | |
| 854 | |
| 855 | |
| 723 } // namespace WebCore | 856 } // namespace WebCore |
| OLD | NEW |