Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Specify display conventions for wasm locations #1053

Merged
merged 8 commits into from
May 22, 2017
Merged
42 changes: 42 additions & 0 deletions Web.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,48 @@ MIME type mismatch or `opaque` response types
[reject](http://tc39.github.io/ecma262/#sec-rejectpromise) the Promise with a
`WebAssembly.CompileError`.

## Developer-facing display conventions

Browsers, JavaScript engines, and offline tools have common ways of referring to
JavaScript artifacts and language constructs. For example, locations in
JavaScript source code are printed in stack traces or error messages, and are
represented naturally as decimal-format lines and columns in text files. Names
of functions and variables are taken directly from the sources. Therefore (for
example) even though the exact format of Error.stack strings does not always
match, the locations are easily understandable and the same across browsers.

To achive the same goal of a common representations for WebAssembly constructs, the
following conventions are adopted.

A WebAssembly location is a reference to a particular instruction in the binary, and may be
displayed by a browser or engine in similar contexts as JavaScript source locations.
It has the following format:
`${url}:wasm-function[${funcIndex}]:0x${pcOffset}`
Where
* `${url}` is the URL associated with the module (e.g. via a response object), if any.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the format if there is no URL? Is the field just empty? Is the colon still included?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there should be something, rather than empty. The note below addresses that, but I agree it's not clear at this line.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise if it's empty there would be no way to tell different modules apart if they didn't have URLs. Obviously it's still possible to have collisions if the instantiation location is used, but at least it would allow a developer to avoid them if they cared.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reworded to clarify.

* `${funcIndex}` is an index the [function index space](https://github.com/WebAssembly/design/blob/master/Modules.md#function-index-space).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: index into the ...
Also, the URL can be relative (just "Modules.md#...").

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

* `${pcOffset}` is the offset in the module binary of the first byte of the instruction, printed in hexadecimal with lower-case digits.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0x prefix or not?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but in this formulation the 0x is part of the template and not part of the substituted value. Do you think we should switch that? It would mean that this line would say something like "${pcOffset} is the offset ... printed in hexadecimal with lower-case digits and a leading 0x prefix" which seems a little more awkward, but I don't have a strong opinion on that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dunno, all I'm saying is this isn't clear. Whichever way works for me.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switched to more-or-less that wording. I agree it's clearer.


Notes:
* The URL field may be interpreted differently depending on the context. For
example offline tools may use a file name; or when the ArrayBuffer-based
`WebAssembly.instantiate` API is used in a browser, it may display the
location of the API call instead.
* Using hexadecimal for module offsets matches common conventions in native tools
such as objdump (where addresses are printed in hex) and makes them visually
distinct from JavaScript line numbers. Other numbers are represented in decimal.

Names of functions may also be displayed if the module contains a `"name"`
section; these can be used in the same contexts as JavaScript functions.
If there are no names provided, then engines should somehow indicate this;
(it may be sufficient to simply use e.g. an empty string if the name is
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function number instead of empty string?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In a stack trace this would be kind of redundant. e.g. in SpiderMonkey, the full stacktrace entry would be
${name}@${location} where ${location} would include the wasm function number for wasm, and ${name} is already empty for top-level JS code not in a function.
For V8 the format is currently
at ${name} (${location}) for wasm and when there is a JS function, and just at ${location} for for top-level JS.
So the point is that there is already precedent for empty JS function names that browsers might want to reuse. OTOH I'm not opposed to a little redundancy in the name of making things clearer either.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK I guess this wording is unclear to me.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reworded to clarify.

immediately adjacent to a WebAssembly location, as its format clearly indicates
that the function is a WebAssembly function). Note also that this document does
not specify the full format of strings such as stack frame representations;
this allows engines to continue using their existing formats for JavaScript
(which existing code may already be depending on) while still printing
WebAssembly frames in a format consistent with JavaScript.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you also add a Note saying somewhere that these conventions do not describe the value of the .name property of exported WebAssembly functions which is precisely [defined](JS.md#exported-function-exotic-objects) to be ToString(function-index)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha good point. Would we want a way to map one to the other as a standalone function?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You you mean like some new JS API for producing the module_name.func_name? That seems possible, but it also makes the names section (more) semantically visible (than before), so I guess it depends on what our use case is.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. My thinking it: we already let developers access the name section so they don't have to parse their own module... but then they need to parse the name section to get that information! Cut the middle-person. 😄

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that makes sense if client code would otherwise be doing their own binary parsing that we've already done. With the other Module reflection methods, our motivating use case was module loaders (and specific experience with incorporating wasm into SystemJS). It'd be nice to have some specific user who is wanting to programmatically access these function names.

Anyhow, this probably belongs in a different issue.


## Modules

WebAssembly's [modules](Modules.md) allow for natural [integration with
Expand Down