ScriptCompiler::Source ignores ScriptOrigin::ScriptID(). Is this a bug?

119 views
Skip to first unread message

A.M.

unread,
May 30, 2018, 7:00:02 PM5/30/18
to v8-users
It seems that `ScriptCompiler::Source` ignores script ID when initialized with the origin. For example, if I compile a script this way:

v8::ScriptOrigin origin(scriptName, v8::Local<v8::Integer>(), v8::Local<v8::Integer>(), v8::Local<v8::Boolean>(), v8::Integer::New(isolate, scriptID));
v8
::ScriptCompiler::Source source(scriptText, origin, cached_data);
compiledScript
= v8::ScriptCompiler::Compile(context, &source, compile_options, no_cache_reason);

When I catch an exception when running the compiled script, the script ID in the message is always 10:

if(try_catch.HasCaught()) {
    v8
::Local<v8::Integer> script_id = try_catch.Message()->GetScriptOrigin().ScriptID();
   
if(!script_id.IsEmpty()) {
        scriptID
= script_id->Int32Value(); // <-- always returns 10 for the first script

}

Compiling multiple scripts increments the script ID for each subsequent script and completely ignores the actual script ID in the origin.

Looking at `ScriptCompiler::Source`, it appears that only some origin data is kept and script ID is not tracked in `ScriptCompiler::Source`. Anybody knows if it's a bug or there is a way to set script ID for compiled scripts?

Thanks!

Andre



Ben Noordhuis

unread,
May 31, 2018, 2:43:50 AM5/31/18
to v8-users
Not a bug, as far as I'm aware. The GetScriptID() method exists
because you can retrieve the ScriptOrigin of functions and exceptions*
but newly compiled code is always assigned a new id.

* Respectively v8::Function::GetScriptOrigin() and
v8::Message::GetScriptOrigin().

A.M.

unread,
May 31, 2018, 9:31:15 AM5/31/18
to v8-users
Thanks, Ben

> Not a bug, as far as I'm aware. 

How can ths be not a bug - the script source *does take* a script ID and ignores it? Without this value being passed around, one would have to compare script names, which is more expensive.

Another thing that hints a bug in the script compiler is that Doxygen comments above `Compile` methods are out of wack and don't reflect what methods do or take.

> but newly compiled code is always assigned a new id.

If it's a new ID, what's the logic I can rely on? Why does it start at 10, does it always increment, is it per isolate, per context, per script compiler, per v8 instance, etc?

Andre

Ben Noordhuis

unread,
Jun 1, 2018, 4:06:41 AM6/1/18
to v8-users
On Thu, May 31, 2018 at 3:31 PM, A.M. <cis7...@gmail.com> wrote:
> Thanks, Ben
>
>> Not a bug, as far as I'm aware.
>
> How can ths be not a bug - the script source *does take* a script ID and
> ignores it? Without this value being passed around, one would have to
> compare script names, which is more expensive.

You can retrieve the script id after compiling with
v8::UnboundScript::GetId(). (Yes, the casing is inconsistent.)

I just noticed there doesn't seem to be a method for retrieving the id
of an es6 module but it wouldn't be hard to add one.

> Another thing that hints a bug in the script compiler is that Doxygen
> comments above `Compile` methods are out of wack and don't reflect what
> methods do or take.
>
>> but newly compiled code is always assigned a new id.
>
> If it's a new ID, what's the logic I can rely on? Why does it start at 10,
> does it always increment, is it per isolate, per context, per script
> compiler, per v8 instance, etc?

You should treat it as an arbitrary number but if you're curious why
it starts at 10, the first few are V8's internal helper scripts.

A.M.

unread,
Jun 1, 2018, 10:22:27 AM6/1/18
to v8-users


On Friday, 1 June 2018 04:06:41 UTC-4, Ben Noordhuis wrote:
You can retrieve the script id after compiling with
v8::UnboundScript::GetId().  (Yes, the casing is inconsistent.)


Can't use the script object - there are multiple scripts in play because one script "includes" other scripts and when I catch an exception, all I have is an instance of `v8::Message`, which does have the script origin that is out of sync with the actual script.
 
You should treat it as an arbitrary number but if you're curious why
it starts at 10, the first few are V8's internal helper scripts.

I assumed as much with regards to the base value, which makes it impossible to rely on that value to always be that. Thanks for confirming that.

As for the arbitrary number, it has no usefulness on its own - unless I can link it back to the script that triggered the exception with this message, how would you possibly use almost a random value that has no relation to the script that triggered that exception?

Ben Noordhuis

unread,
Jun 1, 2018, 11:48:34 AM6/1/18
to v8-users
On Fri, Jun 1, 2018 at 4:22 PM, A.M. <cis7...@gmail.com> wrote:
> As for the arbitrary number, it has no usefulness on its own - unless I can
> link it back to the script that triggered the exception with this message,
> how would you possibly use almost a random value that has no relation to the
> script that triggered that exception?

I use it for matching stack frames (v8::StackFrame::GetScriptId()) to
scripts, to know what frames are worth inspecting (user scripts vs.
non-user scripts.)

A.M.

unread,
Jun 2, 2018, 11:29:55 AM6/2/18
to v8-users
I think you just learned to live with the bug and get the best of what's working. Consider how much better that would be if you could not only distinguish user vs. non-user scripts by comparing opaque numbers (which, BTW, can change), but also identify with certainty your scripts by matching script IDs to those you fed into the v8.

Well, it doesn't look like it's going to be fixed any time soon, so I will build a map of compiled resource names and search the script referenced in `v8::Message` by name in this map. This is not as fast as using a vector index, but it will have to do for now.

Thanks for your insights, Ben, as always.

Andre
Reply all
Reply to author
Forward
0 new messages