Reimplement optional chain and nullish coalesce #1694
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This reimplements #1591, #1593, and #1624 to fix the problems highlighted in #1688. It also replaces #1684.
Basically it implements both
??
and?.
operators.The structure in the IR is simplified; there is just a node property to mark that the property access is optional.
The bytecode generated (for both the compiled JVM class, and our interpreter) for
a?.b
is something of this kind:I have added two new conditional jump instructions in the interpreter,
IF_NULL_UNDEF
andIF_NOT_NULL_UNDEF
, to implement the comparison and the if with a small number of instructions. There is also a new methodOptRuntime.isNullOrUndefined
for compiled mode, to avoid repeating threeif
in a row in each generated class (and, anyway, the JVM might do the inlining itself if it looks useful).The approach is inspired by what other JS engines do; for example,
v8-debug
will print this fora?.b
:One non-obvious detail is that if you have
a?.b.c
, the access toc
is implied to be optional. This is necessary to implement the short circuiting, as required by the spec. The current implementation is not super optimized; it will basically do:Obviously the second
if
should be collapsed with the first, but I found this really complex to implement, so I did not. We get a bit worse performances than other JS engines, but hopefully this pattern is not too common to be a significant problem.For normal property access
a.b
there is no change in bytecode or runtime instructions.Note that this PR is only partial - function calls such as
a.b?.()
, which were already present in #1593, are implemented in #1702