-
-
Notifications
You must be signed in to change notification settings - Fork 672
Description
With current master it is possible to mix unsafe and managed code at will, which can lead to all sorts of issues where unsafe code corrupts managed state. To account for this, it has been suggested to add a mechanism to either allow or disallow the mixing.
As ever so often, there are two perspectives to this.
-
Once WebAssembly GC lands it can be expected that if everything becomes a managed object, unsafe code will not be able to interfere with its internals, and if it is possible to model the entire runtime on top of safe WebAssembly features that'll make the restrictions unnecessary.
-
At this point, though, with the runtime living in linear memory alongside user code, there'll be use cases where an engine wants to restrict a user in a way that he cannot accidentally break it. It can also be expected that the runtime will stick around even if WebAssembly GC lands, to support environments that don't provide GC.
Hence I suggest to add a new compiler flag --allow-unsafe
that is equivalent to the current behavior, a new compiler flag --disallow-unsafe
that disallows the use of anything potentially unsafe in user code and a new default that acts like --allow-unsafe
but emits warnings on unsafe code, essentially hinting a user into either using the --allow-unsafe
or the --disallow-unsafe
flag.
Standard library code would not have this restriction since it cannot implement anything without resorting to unsafe code. One detail here is that, currently, the only files being considered as stdlib files are the top-level files in lib directories, so I suggest to make the top-level files essentially contagious, so that every file imported from a stdlib file becomes a stdlib file as well.
For an implementer, allowing unsafe code in lib files means that, under the --disallow-unsafe
condition, it is still possible to add unsafe code as library files using the --lib
option, for example to more efficiently implement custom collections etc.
Open questions:
- What should the compiler do if an external module, for instance a JSON parser, that is being imported relies on unsafe code? Should this always be disallowed or allowed depending on the flag, should it exclude any modules imports from the check, or should there be an option to define this on a per module basis?
- Do we need a mechanism to annotate unsafe code, like being able to declare an unsafe block of statements? How would this integrate with the proposed compiler options?
As of the respective meta issue, this should probably become our first RFC.