Wasm: Implement checked behaviors.#5002
Conversation
3e2bdcf to
8f607a2
Compare
cd80489 to
12f2093
Compare
69200de to
b06100a
Compare
|
This is still based on #4993 but otherwise it's now ready for review. /cc @tanishiking |
tanishiking
left a comment
There was a problem hiding this comment.
Mostly nitpicks, looks good from my side
| ThrowableArgConsructorName) | ||
| }, | ||
|
|
||
| instantiateClass(ClassClass, AnyArgConstructorName), |
| // TODO: only emit this when required by checked behaviors | ||
| jsValueDescription: ((x) => | ||
| (typeof x === 'number') | ||
| ? ((x === 0 && 1 / x < 0) ? "number(-0)" : ("number(" + x + ")")) |
There was a problem hiding this comment.
[nit]
Object.is(x, -0) might be a bit clearer?
| */ | ||
|
|
||
| fb += wa.LocalGet(objParam) | ||
| fb += wa.Call(genFunctionID.typeTest(DoubleRef)) |
There was a problem hiding this comment.
[note]
We reach here if
- (1) the
objParamis JS number - (2) the
objParamis neither JS number nor an instance ofjava.lang.Number
typeTest(DoubleRef) will be true for (1) because it calls the tD: (x) => typeof x === 'number'.
| fb += LocalGet(indexParam) | ||
| fb += LocalGet(strParam) | ||
| fb += Call(genFunctionID.stringLength) | ||
| fb += I32GeU // unsigned comparison makes negative values of index larger than the length |
There was a problem hiding this comment.
In an extreme scenario, when index=-2^31 and str.length=2^31 + 1, it will be evaluated to false.
Should we care about this corner case?
i32.const -2147483648
i32.const 2147483649
i32.ge_u
;; falseAh, that never happens in the JS runtimes:
In V8 (used by Chrome and Node), the maximum length is 2^29 - 24 (~1GiB). On 32-bit systems, the maximum length is 2^28 - 16 (~512MiB).
In Firefox, the maximum length is 2^30 - 2 (~2GiB). Before Firefox 65, the maximum length was 2^28 - 1 (~512MiB).
In Safari, the maximum length is 2^31 - 1 (~4GiB).
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length
| // check ongoing initialization | ||
| if (semantics.moduleInit != CheckedBehavior.Unchecked) { | ||
| val initFlagID = genGlobalID.forModuleInitFlag(className) | ||
|
|
||
| // if being initialized | ||
| fb += wa.GlobalGet(initFlagID) | ||
| fb.ifThen() { | ||
| if (semantics.moduleInit == CheckedBehavior.Compliant) { |
There was a problem hiding this comment.
[note]
We reach this point when the globalInstance for the class is not yet available. If semantics.moduleInit is set to Compliant, module access will have no effect because it assumes the module has already been initialized by storeModules.
If semantics.moduleInit is set to Fatal, throw an exception.
| * block resultType $noNPELabel | ||
| * block $npeLabel | ||
| * body | ||
| * br $npeLabel |
| private def genCheckNonNull(): Unit = { | ||
| if (semantics.nullPointers != CheckedBehavior.Unchecked) | ||
| private def genCheckNonNullFor(tree: Tree): Unit = { | ||
| if (semantics.nullPointers != CheckedBehavior.Unchecked && nullabilityLevelOf(tree) >= Nullable) |
There was a problem hiding this comment.
[note]
We can ignore NonNullableMaybeWasmNullable here, because unlike genAsNonNullOrNPE we don't expect to have (wasm) non-null value on the stack after this null check.
589e4c9 to
8be61eb
Compare
|
Rebased. |
8be61eb to
aa58b4d
Compare
|
Rebased on top of the non-nullable reference types. |
e3eba31 to
066a11e
Compare
This is a theoretical issue. We have no source syntax to generate an `asInstanceOf[string]`. This was discovered while auditing all the `RefAsNonNull`s in `FunctionEmitter` to implement checked NPEs.
066a11e to
906276c
Compare
Based on #4993 but otherwise ready to review. The first commit belonging to this PR is "Wasm: Implement checked asInstanceOfs.".