-
-
Notifications
You must be signed in to change notification settings - Fork 667
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
WIP: Indirect calls on null trapping #961
Conversation
@@ -60,7 +60,7 @@ | |||
global.get $assembly/config/BGR_DEAD | |||
i32.const 16777215 | |||
i32.and | |||
else |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used the automated update feature and it did this. I'm guessing perhaps these files were generated by manual copy/paste or by hand previously maybe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like the output is from an earlier version of Binaryen. It used to emit such whitespace and I guess the example fixtures haven't been updated since then. Most likely nothing to worry about :)
@@ -462,6 +462,36 @@ export class Compiler extends DiagnosticEmitter { | |||
return module; | |||
} | |||
|
|||
addNullPointerExceptionHandling(module: Module) { | |||
if (this.options.hasFeature(Feature.EXCEPTION_HANDLING)) { | |||
let message = this.ensureStaticString("null is not a function"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This returns an index that is emitted but for some reason the string isn't interned in a data section AFAICT. Anyone see what I did wrong?
Also, bikeshedding welcome on the error message, as always.
[NativeType.I32] | ||
); | ||
|
||
module.addEvent("NullPointerException", 0, exceptionType); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For that real JavaScript feeling
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw this string is only used as a .wat debugging symbol it isn't used at runtime. Wasm exceptions don't (currently) have names like JS exceptions do. They're all WebAssembly.Runtime
instances with a message field of just wasm exception
from the JS side of things.
Yeah, there haven't been any attempts to implement exception handling yet. Mostly because - last time I checked - there wasn't a working implementation in V8 to test against. If there is one now, we could actually attempt to implement try-catch behind a flag now to level the field.
AS has those two dependencies on optional
My general feeling there is that we should first tackle exception handling in general before using it at other places, because otherwise it is very likely that one will end up with both experimental exceptions and the then-unnecessary abort import. So, for this PR it seems fine to skip exception handling for now and make this another occasion to replace with a proper exception later, like so:
Hmm, this should work. My guess is that the Overall I think it's fine to wait with exception handling related code until there is initial |
Edit: we solved this. Needed to move addNullPointerExceptionHandling() to before module.setMemory.
Okiedoke I'll see what I can do! Thanks! |
src/compiler.ts
Outdated
this.ensureFunctionType(null, Type.void), | ||
null, | ||
module.block(null, [ | ||
module.throw("NullPointerException", [module.i32(message)]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here, message
already is an i32.const
(or i64.const
once WASM64 is a thing), so this makes an i32.const(someRandomPtrToBinaryenMemory)
. Wondering if this is related to the string not showing up in static data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch! That's indeed a bug, although, it didn't seem to solve the issue when I regenerate the files. Only change was:
- i32.const 5460624
+ i32.const 24
Which that number makes much more sense for a data segment index (5460624 in hindsight should have been an obvious give away that something was wrong)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ohh I think I found the issue. I think it's too late, the module.setMemory call is made above, before the call to addNullPointerExceptionHandling, so the module misses out on any changes to the internal this.memorySegments storage.
Checking...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep that was the issue. It needs to happen before the setMemory call.
…ption-handlig is enabled, throws a Wasm exception
73047b2
to
fef1379
Compare
@jayphelps thanks for PR. Currently we get rid of null trapping function and just reserve table in zero slot for this. Closing this PR as part of 2020 vacuum as it is outdated. My expectation is that I'll eventually cannibalize the remains of this PR when making a new one. |
WIP: This PR makes indirect calls on null either trap with
unreachable
or, if exception-handling is enabled, throws a Wasm exception.I'm not sure if this is the right approach right now, since AS currently fakes exceptions using an extern call to abort() (which requires people to provide a JS implementation as an import) then uses
unreachable
.I started to do that at first, but worry that it means everyone now needs to include an abort() implementation. I considered disabling it if they use --noAssert but then again, it seems like this should be an exception and it seemed weird that --noAssert would disable that.
Then I noticed that AS actually already wraps Binaryen's exception-handling support even though it's not yet used anywhere, so I figured I'd give that a shot for fun and use this as a discussion point on whether this is instead the more correct direction?
One note: I'm usingWe solved the issue.let message = this.ensureStaticString("null is not a function");
to generate an interned string for the exception, however it doesn't seem to be working. The string doesn't seem to show up in the Wasm file (no data section at all, in fact). Did I do something wrong?