-
Notifications
You must be signed in to change notification settings - Fork 258
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
Rename _start
#19
Comments
I think the wasm start function is nice since it reuses more of the webassembly spec and keeps WASI a bit more minimal. |
That's a good point, we should consider that option as well. There is a potential wrinkle, in that a module's exports aren't available to other code while its wasm start function is executing. We'll need to convince ourselves that we'll never have a situation where wasm code calls out into something that then calls one of the wasm code's exports. |
I can think of a situation where the wasm start function can't be used: a language runtime that JIT compiles a new wasm module and tries to link with itself so the new module can use functions that are built-in to the runtime. |
I would agree with @wanderer in that I'd naively expect the native wasm |
@programmerjake Regardless of whether we use the wasm start function or an export with a designated name, we can always omit it in modules intended to be used as libraries. @alexcrichton That's half of it. The other half is the question of whether we'll ever need to support cyclic imports. With cyclic imports, a module could contain a wasm start function which calls an imported function from another module which tries to call one of the first module's exports. Also, with cyclic imports, if we use wasm start functions, it's unclear if we could guarantee that a dynamic library's static constructors are called before a main executable's main function. |
I'm also in favor of the native wasm start function. |
@alexcrichton, it goes quite a bit deeper. The start function is meant for initialisation. The current semantics provides strong guarantees about that, namely, that every exported function can safely assume that this initialisation has already been performed when it is called. If we were to break this invariant then that would be a breaking change, because exported functions would now need to defensively check against potentially uninitialised state in order to maintain the module's internal invariants -- it's like being able to invoke a method on an object without the guarantee that its constructor has run. |
@rossberg So then the native wasm start function is more like ELF's |
@npmccallum, I actually have lobbied a bit at times for allowing multiple start functions. :) I don't have a particular opinion about finish functions, since I never had any need for them. But both could be added. |
@rossberg So it sounds like we need three things: |
oh yeah that could be problematic. Especially if someone tries to implement WASI in the browser. In the browser to implement any system call that reads or writes to memory either the module needs to import or export memory. The easiest way is to export the memory. (The other way, importing memory is a bit harder given an arbitrary binary b/c there is no way to know the initial memory size the module expects without doing introspection on the binary (webmassembly.Module.imports doesn't return that info :( )) |
@wanderer, the latter will of course be rectified by the JS type reflection proposal. ;) |
@sunfishcode ah that's an excellent point! I'll admit though that I don't really have a good vision of what multi-wasm-modules looks like in WASI. Is the vision that it's similar to dynamic linking in the native world where there's a main executable with a few dynamic libraries automatically loaded? I'd be curious it would be possible to rationalize a multi-wasm-module world with using the @rossberg ah that's also a good point, but is the invariant that exports can rely on the I do feel like there's some similarity to the commands/reactors discussion in the sense that a wasi "reactor" I think the start function being thought of as initialization definitely makes sense. In the "command" mode it may not make as much sense to reinterpret |
@alexcrichton, ES module integration does not break that property. All cycles conceptually go through JS stubs, and you'd get a JS exception if you tried to invoke a Wasm export too early. |
I had previously had the issue with exports being unavailable before start function running which limits what you can do with wasm. I could not setup an exported memory. I would vote for using a different named function as convention. E.g. |
It's unfortunate that we didn't leave ourselves a way to extend this in the binary format. I suppose we'd have to add a new section if we want to provide this in the core wasm spec. |
@binji, does anything prevent us from allowing multiple start sections? |
Good point, I guess not. It doesn't really match the rest of the format, but adding a new section is probably worse. |
just to make sure this is explicitly stated, it would be impossible to load a wasi module using the wasm js api (or anything that approximates it, like v8's c++ api for wasm) if it used wasm's start directive, because you need to grab the memory export first. |
@devsnek I don't quite understand this comment. The start function of a wasm module is invoked as part of instantiating a module with its imports; no memory export is required here, since the start function is inside the module itself. This is independent of the embedding. |
@titzer assuming you run this with something resembling the wasm js api: (module
(import "wasi_unstable" "fd_write"
(func $fd_write (param i32) (param i32) (param i32) (result i32)))
(memory (export "memory") 1)
(data (i32.const 16)
"Hello, World"
)
(func $hello
(i32.store (i32.const 0) (i32.const 12))
(i32.store (i32.const 4) (i32.const 16))
;; implementation of fd_write really needs access to that
;; `memory` export right here, but `new WebAssembly.Instance`
;; hasn't even returned yet, the export isn't accessable
(call $fd_write (i32.const 1) (i32.const 0) (i32.const 1))
(drop)
)
(start $hello)
;; (export "_start" (func $hello))
) |
Thanks for the example, now I see what you are saying. Indeed, if the imported functions (like |
Doesn't WASI import its memory so that these cases can work out? Edit: It seems like WASI would need to import its memory in the WASM start function scenario. This overall case of a memory import and using the WASM start function does seem like it would better support the ES module integration semantics for WASI to run when imported instead of needing a custom call to the _start function. |
@sunfishcode Hi, We're moving away from preview-1(legacy wasi) and towards component model, do we still need to talk about |
Currently WASI program are launched by calling a function named
_start
. This is the name that C compilers have historically used. It's an option question whether we should just use the wasm start function rather than having an export with a designated name. However, as long as_start
is not the wasm start function, it'd be good to use a different name to avoid confusion.The text was updated successfully, but these errors were encountered: