VM: add support for coalescing and capture-parent-scope - #1132
Conversation
…s that looks at the stack but does not pop from it (like SkipIfNotUnit).
|
@ImTheSquid I've reversed the re-numbering of the instructions, as well as not using any Based on your idea, I've started working on a "capabilities" system that identified the syntax features used by an AST. Then it'll be written into the artifact instead of the feature flags. A feature not used by an artifact and not built into the client still runs fine, even if the artifact was originally written by a build that enabled such a feature. So for example, if an artifact is written by a normal build, but loaded in a build with Matching capabilities is fine, but we'd run into the problem of detecting corrupted bytecode, which may corrupt the capability flags, turning a required cap into not. In that case, the verifier needs to double check instructions such that they always abide by the declared capabilities. |
|
@ImTheSquid while refining this, I discovered that the It wasn't hard to implement, so I just added that in. Now the VM really has feature parity with the AST walker. |
ImTheSquid
left a comment
There was a problem hiding this comment.
Small style nits, looking good for the most part!
|
@ImTheSquid Changed made. Pls check it for one final round. |
Coalesce Support
This PR adds support for coalescing operators, such as
??,?.and?[...]to the VM. Previously, coalescing operators are not lowered.New opcode
A new opcode,
Op::SkipIfNotUnitis introduced. This opcode is namedSkipbecause, unlikeJumpopcodes, it does not pop the value off the stack. Instead, it only inspects the value and jumps if the value is not().This new opcode is necessary to implement the
??coalescing operator.Version is bumped
Artifact version is bumped because a new flag is written for the chaining types (
Step::Index,Step::Propertyand `Step::Method) which makes it non backwards compatible with previous written artifacts.Implementation
??is implemented by the newOp::SkipIfNotUnitopcode.?[...]and?.are implemented by adding a newflagsfield to the chaining types and short-circuiting where the receiver is().Capture Parent Scope
Rhai has a feature that, if you put a
!in a function call, it acts sorta like a "macro" -- i.e. it appears to run in-place, being able to see all variables visible at the call site.The result is 42 + 10 = 52 instead of an error, because Rhai takes the function call as capturing the parent's scope.
Essentially it is equivalent to:
Opcode changes
Four new
_CAPTUREversions of theOp::CALL_XXXopcodes are introduced.Implementation
The flag
capture_parent_scopehas always been available forExpr::FnCall. When it is set totrue, call functions with the current scope instead of creating an empty new one.