4 ms·
I don't think there's any significant advance in the bytecode beyond e.g. JVM bytecode. The difference is in the surface area of the standard library -- Java a
by iainmerrick 2y ago
I don't think there's any significant advance in the bytecode beyond e.g. JVM bytecode.
The difference is in the surface area of the standard library -- Java applets exposed a lot of stuff that turned out to have a lot of security holes, and it was basically impossible to guarantee there weren't further holes. In WASM, the linear memory and very simple OS interface makes the sandboxing much more tractable.
- titzer 2y agoI worked on JVM bytecode for a significant number of years before working on Wasm. JVM bytecode verification is non-trivial, not only to specify, but to implement efficiently. In Java 6 the class file format introduced stack maps to tame a worst-case O(n^3) bytecode verification overhead, which had become a DoS attack vector. Structured control flow makes Wasm validation effectively linear and vastly simpler to understand and vet. Wasm cleaned up a number of JVM bytecode issues, such as massive redundancy between class files (duplicate constant pool entries), length limitations (Wasm uses LEBs everywhere), typing of locals, more arithmetic instructions, with signedness and floating point that closer matches hardware, addition of SIMD, explicit tail calls, and now first-class functions and a lower-level object model.
- kaba0 2y agoAre they validating code to the same degree though? Like, there are obviously learned lessons in how WASM is designed, but at the same time JVM byte code being at a slightly higher level of abstraction can outright make certain incorrect code impossible to express, so it may not be apples to oranges. What I’m thinking of is simply memory corruption issues from the linear memory model, and while these can only corrupt the given process, not anything outside, it is still not something the JVM allows.
- titzer 2y agoWasm bytecode verification is more strict than JVM bytecode verification. For example, JVM locals don't have declared types, they are inferred by the abstract interpretation algorithm (one of the reasons for the afore-mentioned O(n^3) worst case). In Wasm bytecode, all locals have declared types. Wasm GC also introduces non-null reference types, and the validation algorithm guarantees that locals of declared non-null type cannot be used before being initialized. That's also done as part of the single-pass verification. Wasm GC has a lower-level object model and type system than the JVM (basically structs, arrays, and first-class functions, to which object models are lowered), so it's possible that a higher-level type system, when lowered to Wasm GC, may not be enforceable at the bytecode level. So you could, e.g. screw up the virtual dispatch sequence of a Java method call and end up with a Wasm runtime type error.
- jeberle 2y agoThx for this perspective and info. Regarding "signedness and floating point that closer matches hardware", I'm not seeing unsigned integers. Are they supported? I see only: > Two’s complement signed integers in 32 bits and optionally 64 bits. https://webassembly.org/docs/portability/#assumptions-for-efficient-execution https://webassembly.org/docs/portability/#assumptions-for-ef... And nothing suggesting unsigned ints here: https://webassembly.org/features/ https://webassembly.org/features/
- Laremere 2y agoWasm makes no distinction between signed and unsigned integers as variables, only calling them integers. The relevant operations are split between signed and unsigned. https://webassembly.github.io/spec/core/appendix/index-instructions.html https://webassembly.github.io/spec/core/appendix/index-instr... See how there's only i32.load and i32.eq, but there's i32.lt_u and i32.lt_s. Loading bits from memory or comparing them is the same operation bit for bit for each of signed and unsigned. However, less than requires knowing the desired signess, and is split between signed and unsigned.
- flohofwoe 2y agoSigned and unsigned are just different views on the same bits. CPU registers don't carry signedness either after all, the value they carry is neither signed nor unsigned until you look at the bits and decide to "view" them as a signed or unsigned number. With the two's complement convention, the concept of 'signedness' only matters when a narrow integer value needs to be extended to a wider value (e.g. 8-bit to 16-bit), specifically whether the new bits needs to be replicated from the narrow value's topmost bit (for signed extension) or set to zero (for unsigned extension). It would be interesting to speculate what a high level language would look like with such sign-agnostic "Schroedinger's integer types").
- jeberle 2y agoCPU instruction sets do account for signed vs unsigned integers. SHR vs SAR for example. It's part of the ISAs. I'm calling this out as AFAIK, the JVM has no support for unsigned ints and so that in turn makes WASM a little more compelling. https://en.wikibooks.org/wiki/X86_Assembly/Shift_and_Rotate https://en.wikibooks.org/wiki/X86_Assembly/Shift_and_Rotate
- iainmerrick 2y agoI stand corrected! That’s great information, thanks. I didn’t know JVM bytecode had so many problems.