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

Unified 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: Oops, no JS-builts Created 7 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/bindings/v8/ScriptController.h ('k') | Source/bindings/v8/ScriptDebugServer.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/bindings/v8/ScriptController.cpp
diff --git a/Source/bindings/v8/ScriptController.cpp b/Source/bindings/v8/ScriptController.cpp
index 6be8d4ad162110a1353ea517e097938f23f494e6..1eab79649545c655bef63679b2a8fd6cecfde372 100644
--- a/Source/bindings/v8/ScriptController.cpp
+++ b/Source/bindings/v8/ScriptController.cpp
@@ -674,9 +674,12 @@ ScriptValue ScriptController::executeScriptInMainWorld(const ScriptSourceCode& s
if (v8Context.IsEmpty())
return ScriptValue();
+ String processedString = m_frame->script()->preprocess(sourceCode.source(), sourceURL);
+ ScriptSourceCode processedSourceCode(processedString, sourceCode.url(), sourceCode.startPosition());
+
v8::Context::Scope scope(v8Context);
RefPtr<Frame> protect(m_frame);
- v8::Local<v8::Value> object = compileAndRunScript(sourceCode);
+ v8::Local<v8::Value> object = compileAndRunScript(processedSourceCode);
m_sourceURL = savedSourceURL;
@@ -720,4 +723,134 @@ void ScriptController::executeScriptInIsolatedWorld(int worldID, const Vector<Sc
}
}
+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.
+
+class ScriptController::ScriptPreprocessor {
+ WTF_MAKE_NONCOPYABLE(ScriptPreprocessor);
+public:
+ ScriptPreprocessor(const String& preprocessorScript, ScriptController* controller)
+ : m_controller(controller), m_isolate(controller->m_isolate)
+ {
+ v8::HandleScope scope(m_isolate);
+
+ 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
+ if (context.IsEmpty())
+ return;
+
+ v8::Local<v8::Value> preprocessorFunction;
+ v8::TryCatch tryCatch;
+
+ v8::Context::Scope contextScope(context);
+ 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.
+ preprocessorFunction = V8ScriptRunner::compileAndRunInternalScript(preprocessor, m_isolate);
+
+ if (tryCatch.HasCaught()) {
+ reportException(tryCatch, preprocessorName);
+ return;
+ }
+
+ if (preprocessorFunction.IsEmpty())
+ m_creationError = "Internal error: The preprocessor outer script gave no value without throwing.";
+ else if (!preprocessorFunction->IsFunction())
+ m_creationError = "The preprocessor must compile to a function.";
+
+ if (!m_creationError.isEmpty()) {
+ reportErrorMessage(preprocessorName);
+ return;
+ }
+
+ m_utilityContext.set(m_isolate, context);
+ m_preprocessorFunction.set(m_isolate, v8::Handle<v8::Function>::Cast(preprocessorFunction));
+ }
+
+ void reportException(const v8::TryCatch& tryCatch, const String& sourceName)
+ {
+ v8::Local<v8::Message> message = tryCatch.Message();
+ if (!tryCatch.Message().IsEmpty())
+ m_creationError = toWebCoreStringWithUndefinedOrNullCheck(message->Get());
+ else
+ m_creationError = "Unknown exception.";
+
+ RefPtr<ScriptCallStack> callStack = createScriptCallStack(
+ message->GetStackTrace(), ScriptCallStack::maxCallStackSizeToCapture);
+
+ reportErrorMessage(sourceName, message->GetLineNumber(), callStack);
+ }
+
+ void reportErrorMessage(const String& sourceName, int lineNumber = 1, PassRefPtr<ScriptCallStack> callStack = RefPtr<ScriptCallStack>())
+ {
+ v8::Context::Scope contextScope(m_controller->mainWorldContext());
+ getScriptExecutionContext()->reportException(m_creationError, lineNumber, sourceName, callStack);
+ }
+
+ String preprocessSourceCode(const String& sourceCode, const String& sourceName)
+ {
+ v8::HandleScope handleScope(m_isolate);
+ if (m_preprocessorFunction.isEmpty())
+ return sourceCode;
+
+ v8::Local<v8::Context> context = v8::Local<v8::Context>::New(m_utilityContext.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
+ v8::Context::Scope contextScope(context);
+
+ v8::Handle<v8::String> sourceCodeString = v8::String::New(sourceCode.utf8().data(), sourceCode.utf8().length());
+
+ v8::Handle<v8::String> sourceNameString = v8::String::New(sourceName.utf8().data(), sourceName.utf8().length());
+ v8::Handle<v8::Value> argv[] = { sourceCodeString, sourceNameString };
+
+ v8::TryCatch tryCatch;
+ v8::Handle<v8::Value> resultValue =
+ V8ScriptRunner::callAsFunction(m_preprocessorFunction.newLocal(m_isolate), context->Global(), 2, argv);
+
+ if (tryCatch.HasCaught()) {
+ reportException(tryCatch, sourceName);
+ return sourceCode;
+ }
+
+ if (resultValue->IsString()) {
+ v8::String::Utf8Value utf8Value(resultValue);
+ 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.
+ }
+ return sourceCode;
+ }
+
+ bool hadCreationError()
+ {
+ return !m_creationError.isEmpty();
+ }
+
+ ~ScriptPreprocessor()
+ {
+ }
+
+private:
+ ScopedPersistent<v8::Context> m_utilityContext;
+ String m_preprocessorBody;
+ ScopedPersistent<v8::Function> m_preprocessorFunction;
+ ScriptController* m_controller;
+ v8::Isolate* m_isolate;
+ String m_creationError;
+};
+
+void ScriptController::setScriptPreprocessor(const String& preprocessorBody)
+{
+ // The preprocessor will be created the first time it is needed.
+ m_scriptPreprocessor.clear();
+ m_preprocessorSource = preprocessorBody;
+}
+
+String ScriptController::preprocess(const String& scriptSource, const String& scriptName)
+{
+ if (m_preprocessorSource.isEmpty())
+ return scriptSource;
+
+ if (!m_scriptPreprocessor)
+ m_scriptPreprocessor = adoptPtr(new ScriptPreprocessor(m_preprocessorSource, this));
+
+ if (m_scriptPreprocessor->hadCreationError())
+ return scriptSource;
+
+ return m_scriptPreprocessor->preprocessSourceCode(scriptSource, scriptName);
+}
+
+
} // namespace WebCore
« no previous file with comments | « Source/bindings/v8/ScriptController.h ('k') | Source/bindings/v8/ScriptDebugServer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698