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}
This commit is contained in:
yurys 2015-03-05 05:03:42 -08:00 committed by Commit bot
parent 1382879f29
commit e33ae81ce1
10 changed files with 73 additions and 44 deletions

View File

@ -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) {}

View File

@ -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>());
}

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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()) {

View File

@ -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(

View File

@ -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())));
}

View File

@ -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(

View File

@ -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);
}