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

Add Module.customSections #877

Merged
merged 7 commits into from
Nov 29, 2016
Merged

Add Module.customSections #877

merged 7 commits into from
Nov 29, 2016

Conversation

lukewagner
Copy link
Member

This PR adds a reflective static Module function for returning the contents of user-defined sections. The intended use case is dynamic linking: after compiling a Module which is to be dynamically linked to other instances via shared Memory/Table, the linker needs metadata to know, e.g., how much space to allocate for global data and Table entries (including zero/empty entries, so simply exposing the length of data and elem sections isn't sufficient). Providing access to metadata through user-defined sections avoids the need for some out-of-band metadata source or the need to do ad hoc binary decoding at runtime.

Two interesting details:

  • this proposal only returns user-defined sections (known sections should have separate reflective methods like exports/imports). However, by rejecting sectionName arguments that aren't already a string, we leave open the possibility of passing Number values in the future to extract known sections
  • because sections are not necessarily unique, the function returns a (possibly-empty) array of results when querying a given user-defined section name

Array sections(modueObject, sectionName)
```

If `moduleObject` is not a `WebAssembly.Module` instance, a [`TypeError`](https://tc39.github.io/ecma262/#sec-native-error-types-used-in-this-standard-typeerror)
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps s/instance/object/, to avoid confusion

Copy link
Member Author

Choose a reason for hiding this comment

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

Hey, yeah, that is confusing. In other places we just say "if x is not a Y" (no "instance" or "object"), so I'll do that here too.

@rossberg
Copy link
Member

Looks good, the only thing I wonder about is the method name, which suggests that it can return any kind of section. Would userSections be more adequate? As you say, known sections should rather get their own methods, so I wouldn't worry about extending this one. Even if we ever wanted to return raw known sections, that would probably still be addressed better with a separate method (that e.g. takes a symbolic section name instead of a meaningless number).

@lukewagner
Copy link
Member Author

Hah, I was going back and forth on exactly this. That's a good point re: known sections and symbolic names, though. I'll switch.

@lukewagner
Copy link
Member Author

(I also put back the ToString on the sectionName argument, not because I want all the crazy coercions it allows, but just for regularity since it seems everything string-taking does a ToString.)

@rossberg
Copy link
Member

LGTM

Copy link
Member

@jfbastien jfbastien left a comment

Choose a reason for hiding this comment

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

I'd rather leave this open until next week, since folks are off for Thanksgiving.

@@ -205,6 +205,25 @@ to the Object `{ module: String(i.module_name), name: String(i.item_name), kind:

Note: other fields like `signature` may be added in the future.

### `WebAssembly.Module.userSections`
Copy link
Member

Choose a reason for hiding this comment

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

We call them "unknown" sections in the binary format. I'd rather be consistent (either name is fine).

Copy link
Member Author

@lukewagner lukewagner Nov 23, 2016

Choose a reason for hiding this comment

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

Ugh, I hadn't noticed; it seems we call them both "user-defined" and "unknown" sections. Seems like we should just go with one. I actually like "unknown" better than "user defined"; it contrasts better with "known". @rossberg-chromium ?

Copy link
Member

Choose a reason for hiding this comment

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

TBH I don't like the term "user". Seems condescending.
But "unknown" is weird.
So yeah, I don't care for either name ;-)

How about "named sections" everywhere?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I have the same vague feeling re "user". I like "named".

Copy link
Member

Choose a reason for hiding this comment

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

We moved to calling these "user" sections in wabt, and in my proposed llvm binutils patch.

I think "user" is fine, and has more meaning than either "named" or "unkown" which don't seem to convey much to me. We're all used to "user_data" pointers in callbacks.

[user-defined section](BinaryEncoding.md#high-level-structure) (i.e., section with
`id` 0) whose `name` field ([decoded as UTF-8](Web.md#names)) is equal to
`sectionNameString` to an `ArrayBuffer` containing the section's `payload_data`.
(Note: `payload_data` does not include `name` or `name_len`.)
Copy link
Member

Choose a reason for hiding this comment

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

This Array is a copy of the original content, correct?

Copy link
Member Author

Choose a reason for hiding this comment

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

Well, technically ArrayBuffer, but yes. I'll add "copy of" to clarify.

Copy link
Member

Choose a reason for hiding this comment

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

I was wondering about this. Why make a copy? Don't we have the original buffer copied already (to prevent user from modifying it while compiling)? Maybe not a big deal, but it seems wasteful when we could just provide a view over the existing copy.

Copy link
Member Author

Choose a reason for hiding this comment

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

If we had the ability to return a read-only view, I'd do that, but otherwise we're in trouble if the user tries to write to the view.

Copy link
Member

Choose a reason for hiding this comment

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

Hm, too bad. Though I suppose users who are concerned about this cost for very large modules can parse the module themselves.

The `userSections` function has the signature:

```
Array userSections(modueObject, sectionName)
Copy link
Member

Choose a reason for hiding this comment

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

Typo "modueObject".

@lukewagner
Copy link
Member Author

@jfbastien Agreed, I was going to wait as well.

@rossberg
Copy link
Member

"Unknown" is weird, "named" a bit too generic. How about "custom"?

@lukewagner
Copy link
Member Author

"Custom sections" sounds fine to me. Anyone else?

@lukewagner
Copy link
Member Author

Updated, PTAL.

@jfbastien
Copy link
Member

lgtm

@binji
Copy link
Member

binji commented Nov 28, 2016

Custom is fine. But wouldn't you prefer "Bespoke"? :-)

@rossberg
Copy link
Member

lgtm

@lukewagner lukewagner merged commit e380336 into master Nov 29, 2016
@lukewagner lukewagner deleted the add-sections-method branch November 29, 2016 15:29
@lukewagner lukewagner changed the title Add Module.sections Add Module.customSections Nov 30, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants