Commit e33ae81c authored by yurys's avatar yurys Committed by Commit bot

Allow passing sourceMapUrl when compiling scripts

According to Source Map specification [1] source map url can be passed either as a magic comment at the end of script or as SourceMap http header. We already parse the former value and expose it on Script object. This change allows to unify the way we deal with source map urls received in http header by providing api for passing that url into the script being compiled.

source_map_url is intentionally not passed into CompilationCacheScript::Lookup. The cache is anyways disabled when debugger is on.

[1] https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit

LOG=Y
BUG=chromium:462572

Review URL: https://codereview.chromium.org/983603003

Cr-Commit-Position: refs/heads/master@{#27017}
parent 1382879f
......@@ -991,13 +991,15 @@ class ScriptOrigin {
Handle<Integer> resource_column_offset = Handle<Integer>(),
Handle<Boolean> resource_is_shared_cross_origin = Handle<Boolean>(),
Handle<Integer> script_id = Handle<Integer>(),
Handle<Boolean> resource_is_embedder_debug_script = Handle<Boolean>())
Handle<Boolean> resource_is_embedder_debug_script = Handle<Boolean>(),
Handle<Value> source_map_url = Handle<Value>())
: resource_name_(resource_name),
resource_line_offset_(resource_line_offset),
resource_column_offset_(resource_column_offset),
resource_is_embedder_debug_script_(resource_is_embedder_debug_script),
resource_is_shared_cross_origin_(resource_is_shared_cross_origin),
script_id_(script_id) {}
script_id_(script_id),
source_map_url_(source_map_url) {}
V8_INLINE Handle<Value> ResourceName() const;
V8_INLINE Handle<Integer> ResourceLineOffset() const;
V8_INLINE Handle<Integer> ResourceColumnOffset() const;
......@@ -1007,6 +1009,7 @@ class ScriptOrigin {
V8_INLINE Handle<Boolean> ResourceIsEmbedderDebugScript() const;
V8_INLINE Handle<Boolean> ResourceIsSharedCrossOrigin() const;
V8_INLINE Handle<Integer> ScriptID() const;
V8_INLINE Handle<Value> SourceMapUrl() const;
private:
Handle<Value> resource_name_;
......@@ -1015,6 +1018,7 @@ class ScriptOrigin {
Handle<Boolean> resource_is_embedder_debug_script_;
Handle<Boolean> resource_is_shared_cross_origin_;
Handle<Integer> script_id_;
Handle<Value> source_map_url_;
};
......@@ -1164,6 +1168,7 @@ class V8_EXPORT ScriptCompiler {
Handle<Integer> resource_column_offset;
Handle<Boolean> resource_is_embedder_debug_script;
Handle<Boolean> resource_is_shared_cross_origin;
Handle<Value> source_map_url;
// Cached data from previous compilation (if a kConsume*Cache flag is
// set), or hold newly generated cache data (kProduce*Cache flags) are
......@@ -7001,6 +7006,9 @@ Handle<Integer> ScriptOrigin::ScriptID() const {
}
Handle<Value> ScriptOrigin::SourceMapUrl() const { return source_map_url_; }
ScriptCompiler::Source::Source(Local<String> string, const ScriptOrigin& origin,
CachedData* data)
: source_string(string),
......@@ -7009,6 +7017,7 @@ ScriptCompiler::Source::Source(Local<String> string, const ScriptOrigin& origin,
resource_column_offset(origin.ResourceColumnOffset()),
resource_is_embedder_debug_script(origin.ResourceIsEmbedderDebugScript()),
resource_is_shared_cross_origin(origin.ResourceIsSharedCrossOrigin()),
source_map_url(origin.SourceMapUrl()),
cached_data(data) {}
......
......@@ -215,6 +215,24 @@ class CallDepthScope {
} // namespace
static ScriptOrigin GetScriptOriginForScript(i::Isolate* isolate,
i::Handle<i::Script> script) {
i::Handle<i::Object> scriptName(i::Script::GetNameOrSourceURL(script));
i::Handle<i::Object> source_map_url(script->source_mapping_url(), isolate);
v8::Isolate* v8_isolate =
reinterpret_cast<v8::Isolate*>(script->GetIsolate());
v8::ScriptOrigin origin(
Utils::ToLocal(scriptName),
v8::Integer::New(v8_isolate, script->line_offset()->value()),
v8::Integer::New(v8_isolate, script->column_offset()->value()),
v8::Boolean::New(v8_isolate, script->is_shared_cross_origin()),
v8::Integer::New(v8_isolate, script->id()->value()),
v8::Boolean::New(v8_isolate, script->is_embedder_debug_script()),
Utils::ToLocal(source_map_url));
return origin;
}
// --- E x c e p t i o n B e h a v i o r ---
......@@ -1630,6 +1648,7 @@ MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal(
{ i::HandleScope scope(isolate);
i::HistogramTimerScope total(isolate->counters()->compile_script(), true);
i::Handle<i::Object> name_obj;
i::Handle<i::Object> source_map_url;
int line_offset = 0;
int column_offset = 0;
bool is_embedder_debug_script = false;
......@@ -1652,10 +1671,13 @@ MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal(
is_embedder_debug_script =
source->resource_is_embedder_debug_script->IsTrue();
}
if (!source->source_map_url.IsEmpty()) {
source_map_url = Utils::OpenHandle(*(source->source_map_url));
}
i::Handle<i::SharedFunctionInfo> result = i::Compiler::CompileScript(
str, name_obj, line_offset, column_offset, is_embedder_debug_script,
is_shared_cross_origin, isolate->native_context(), NULL, &script_data,
options, i::NOT_NATIVES_CODE, is_module);
is_shared_cross_origin, source_map_url, isolate->native_context(), NULL,
&script_data, options, i::NOT_NATIVES_CODE, is_module);
has_pending_exception = result.is_null();
if (has_pending_exception && script_data != NULL) {
// This case won't happen during normal operation; we have compiled
......@@ -1902,6 +1924,11 @@ MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
script->set_is_embedder_debug_script(
origin.ResourceIsEmbedderDebugScript()->IsTrue());
}
if (!origin.SourceMapUrl().IsEmpty()) {
script->set_source_mapping_url(
*Utils::OpenHandle(*(origin.SourceMapUrl())));
}
source->info->set_script(script);
source->info->SetContext(isolate->native_context());
......@@ -2168,17 +2195,7 @@ ScriptOrigin Message::GetScriptOrigin() const {
i::Handle<i::JSValue> script_value =
i::Handle<i::JSValue>::cast(script_wraper);
i::Handle<i::Script> script(i::Script::cast(script_value->value()));
i::Handle<i::Object> scriptName(i::Script::GetNameOrSourceURL(script));
v8::Isolate* v8_isolate =
reinterpret_cast<v8::Isolate*>(script->GetIsolate());
v8::ScriptOrigin origin(
Utils::ToLocal(scriptName),
v8::Integer::New(v8_isolate, script->line_offset()->value()),
v8::Integer::New(v8_isolate, script->column_offset()->value()),
v8::Boolean::New(v8_isolate, script->is_shared_cross_origin()),
v8::Integer::New(v8_isolate, script->id()->value()),
v8::Boolean::New(v8_isolate, script->is_embedder_debug_script()));
return origin;
return GetScriptOriginForScript(isolate, script);
}
......@@ -4476,16 +4493,7 @@ ScriptOrigin Function::GetScriptOrigin() const {
i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
if (func->shared()->script()->IsScript()) {
i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
i::Handle<i::Object> scriptName = i::Script::GetNameOrSourceURL(script);
v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(func->GetIsolate());
v8::ScriptOrigin origin(
Utils::ToLocal(scriptName),
v8::Integer::New(isolate, script->line_offset()->value()),
v8::Integer::New(isolate, script->column_offset()->value()),
v8::Boolean::New(isolate, script->is_shared_cross_origin()),
v8::Integer::New(isolate, script->id()->value()),
v8::Boolean::New(isolate, script->is_embedder_debug_script()));
return origin;
return GetScriptOriginForScript(func->GetIsolate(), script);
}
return v8::ScriptOrigin(Handle<Value>());
}
......
......@@ -1465,8 +1465,8 @@ bool Genesis::CompileScriptCached(Isolate* isolate,
Handle<String> script_name =
factory->NewStringFromUtf8(name).ToHandleChecked();
function_info = Compiler::CompileScript(
source, script_name, 0, 0, false, false, top_context, extension, NULL,
ScriptCompiler::kNoCompileOptions,
source, script_name, 0, 0, false, false, Handle<Object>(), top_context,
extension, NULL, ScriptCompiler::kNoCompileOptions,
use_runtime_context ? NATIVES_CODE : NOT_NATIVES_CODE, false);
if (function_info.is_null()) return false;
if (cache != NULL) cache->Add(name, function_info);
......
......@@ -1263,8 +1263,8 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
Handle<SharedFunctionInfo> Compiler::CompileScript(
Handle<String> source, Handle<Object> script_name, int line_offset,
int column_offset, bool is_embedder_debug_script,
bool is_shared_cross_origin, Handle<Context> context,
v8::Extension* extension, ScriptData** cached_data,
bool is_shared_cross_origin, Handle<Object> source_map_url,
Handle<Context> context, v8::Extension* extension, ScriptData** cached_data,
ScriptCompiler::CompileOptions compile_options, NativesFlag natives,
bool is_module) {
Isolate* isolate = source->GetIsolate();
......@@ -1335,6 +1335,9 @@ Handle<SharedFunctionInfo> Compiler::CompileScript(
}
script->set_is_shared_cross_origin(is_shared_cross_origin);
script->set_is_embedder_debug_script(is_embedder_debug_script);
if (!source_map_url.is_null()) {
script->set_source_mapping_url(*source_map_url);
}
// Compile the function and add it to the cache.
CompilationInfoWithZone info(script);
......
......@@ -811,8 +811,9 @@ class Compiler : public AllStatic {
static Handle<SharedFunctionInfo> CompileScript(
Handle<String> source, Handle<Object> script_name, int line_offset,
int column_offset, bool is_debugger_script, bool is_shared_cross_origin,
Handle<Context> context, v8::Extension* extension,
ScriptData** cached_data, ScriptCompiler::CompileOptions compile_options,
Handle<Object> source_map_url, Handle<Context> context,
v8::Extension* extension, ScriptData** cached_data,
ScriptCompiler::CompileOptions compile_options,
NativesFlag is_natives_code, bool is_module);
static Handle<SharedFunctionInfo> CompileStreamedScript(CompilationInfo* info,
......
......@@ -637,8 +637,8 @@ bool Debug::CompileDebuggerScript(Isolate* isolate, int index) {
// Compile the script.
Handle<SharedFunctionInfo> function_info;
function_info = Compiler::CompileScript(
source_code, script_name, 0, 0, false, false, context, NULL, NULL,
ScriptCompiler::kNoCompileOptions, NATIVES_CODE, false);
source_code, script_name, 0, 0, false, false, Handle<Object>(), context,
NULL, NULL, ScriptCompiler::kNoCompileOptions, NATIVES_CODE, false);
// Silently ignore stack overflows during compilation.
if (function_info.is_null()) {
......
......@@ -33,7 +33,7 @@ static Handle<JSFunction> Compile(const char* source) {
->NewStringFromUtf8(CStrVector(source))
.ToHandleChecked();
Handle<SharedFunctionInfo> shared_function = Compiler::CompileScript(
source_code, Handle<String>(), 0, 0, false, false,
source_code, Handle<String>(), 0, 0, false, false, Handle<Object>(),
Handle<Context>(isolate->native_context()), NULL, NULL,
v8::ScriptCompiler::kNoCompileOptions, NOT_NATIVES_CODE, false);
return isolate->factory()->NewFunctionFromSharedFunctionInfo(
......
......@@ -3894,6 +3894,7 @@ static void check_message_3(v8::Handle<v8::Message> message,
CHECK(message->GetScriptOrigin().ResourceIsSharedCrossOrigin()->Value());
CHECK(message->GetScriptOrigin().ResourceIsEmbedderDebugScript()->Value());
CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue());
CHECK_EQ(7.40, message->GetScriptOrigin().SourceMapUrl()->NumberValue());
message_received = true;
}
......@@ -3905,10 +3906,10 @@ TEST(MessageHandler3) {
CHECK(!message_received);
v8::V8::AddMessageListener(check_message_3);
LocalContext context;
v8::ScriptOrigin origin =
v8::ScriptOrigin(v8_str("6.75"), v8::Integer::New(isolate, 1),
v8::Integer::New(isolate, 2), v8::True(isolate),
Handle<v8::Integer>(), v8::True(isolate));
v8::ScriptOrigin origin = v8::ScriptOrigin(
v8_str("6.75"), v8::Integer::New(isolate, 1),
v8::Integer::New(isolate, 2), v8::True(isolate), Handle<v8::Integer>(),
v8::True(isolate), v8_str("7.40"));
v8::Handle<v8::Script> script =
Script::Compile(v8_str("throw 'error'"), &origin);
script->Run();
......@@ -16280,7 +16281,8 @@ THREADED_TEST(ScriptOrigin) {
v8::String::NewFromUtf8(env->GetIsolate(), "test"),
v8::Integer::New(env->GetIsolate(), 1),
v8::Integer::New(env->GetIsolate(), 1), v8::True(env->GetIsolate()),
v8::Handle<v8::Integer>(), v8::True(env->GetIsolate()));
v8::Handle<v8::Integer>(), v8::True(env->GetIsolate()),
v8::String::NewFromUtf8(env->GetIsolate(), "http://sourceMapUrl"));
v8::Handle<v8::String> script = v8::String::NewFromUtf8(
env->GetIsolate(), "function f() {}\n\nfunction g() {}");
v8::Script::Compile(script, &origin)->Run();
......@@ -16295,6 +16297,10 @@ THREADED_TEST(ScriptOrigin) {
CHECK_EQ(1, script_origin_f.ResourceLineOffset()->Int32Value());
CHECK(script_origin_f.ResourceIsSharedCrossOrigin()->Value());
CHECK(script_origin_f.ResourceIsEmbedderDebugScript()->Value());
printf("is name = %d\n", script_origin_f.SourceMapUrl()->IsUndefined());
CHECK_EQ(0, strcmp("http://sourceMapUrl",
*v8::String::Utf8Value(script_origin_f.SourceMapUrl())));
v8::ScriptOrigin script_origin_g = g->GetScriptOrigin();
CHECK_EQ(0, strcmp("test",
......@@ -16302,6 +16308,8 @@ THREADED_TEST(ScriptOrigin) {
CHECK_EQ(1, script_origin_g.ResourceLineOffset()->Int32Value());
CHECK(script_origin_g.ResourceIsSharedCrossOrigin()->Value());
CHECK(script_origin_g.ResourceIsEmbedderDebugScript()->Value());
CHECK_EQ(0, strcmp("http://sourceMapUrl",
*v8::String::Utf8Value(script_origin_g.SourceMapUrl())));
}
......
......@@ -60,7 +60,7 @@ static Handle<JSFunction> Compile(const char* source) {
Handle<String> source_code = isolate->factory()->NewStringFromUtf8(
CStrVector(source)).ToHandleChecked();
Handle<SharedFunctionInfo> shared_function = Compiler::CompileScript(
source_code, Handle<String>(), 0, 0, false, false,
source_code, Handle<String>(), 0, 0, false, false, Handle<Object>(),
Handle<Context>(isolate->native_context()), NULL, NULL,
v8::ScriptCompiler::kNoCompileOptions, NOT_NATIVES_CODE, false);
return isolate->factory()->NewFunctionFromSharedFunctionInfo(
......
......@@ -808,10 +808,10 @@ int CountBuiltins() {
static Handle<SharedFunctionInfo> CompileScript(
Isolate* isolate, Handle<String> source, Handle<String> name,
ScriptData** cached_data, v8::ScriptCompiler::CompileOptions options) {
return Compiler::CompileScript(source, name, 0, 0, false, false,
Handle<Context>(isolate->native_context()),
NULL, cached_data, options, NOT_NATIVES_CODE,
false);
return Compiler::CompileScript(
source, name, 0, 0, false, false, Handle<Object>(),
Handle<Context>(isolate->native_context()), NULL, cached_data, options,
NOT_NATIVES_CODE, false);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment