-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: magic bytes to constant op codes #23
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we maybe remove the read_instruction
method? At least in the code, with that we are matching two times the bytes then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good observation, will discuss with @george-cosma too the perfect way to go about it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed it and made it look cleaner. Sadly we still have to use the strip_bytes
command quite often (especially on multibyte instructions - please see executor/mod.rs, specifically and look at multibyte instructions).
let local_idx = wasm.read_var_u32().unwrap_validated() as LocalIdx; | ||
let local = locals.get(local_idx); | ||
trace!("Instruction: local.get [] -> [{local:?}]"); | ||
stack.push_value(local.clone()); | ||
} | ||
// local.set [t] -> [] | ||
0x21 => { | ||
[LOCAL_SET, ..] => { | ||
let local_idx = wasm.read_var_u32().unwrap_validated() as LocalIdx; | ||
let local = locals.get_mut(local_idx); | ||
let value = stack.pop_value(local.to_ty()); | ||
trace!("Instruction: local.set [{local:?}] -> []"); | ||
*local = value; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wherever an instruction is followed by arguments, we could take these directly:
[LOCAL_SET, local_idx, ..] => {
let local = locals.get_mut(local_idx);
let value = stack.pop_value(local.to_ty());
trace!("Instruction: local.set [{local:?}] -> []");
*local = value;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this could work, we also have to make sure we increment the pc and modify the current
of the WasmReader
instance accordingly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally we could get rid of the current in WasmReader IMHO
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved from current
being a &[u8]
to having a pc
being a usize
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still an architectural design that I need your input on. For each argument we still need to do a call to strip_bytes
, do you want me to continue on this path? (read directly from the slice and call strip_bytes
) Or do you want me to keep the current implementation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would just like to add a few arguments against reading the arguments of operations while matching like this: [SOME_OPCODE, some_argument, ..] => { ... }
.
- This only works for arguments of fixed size. In WASM, however, integers are encoded with variable length (see here). Unfortunately, as far as I know, there is no elegant solution for matching them directly in the slice.
- By matching the arguments directly in the slice, we decouple reading the argument bytes from advancing the program counter, which in my opinion is not very rusty. I think it is more error-prone, and puts the additional responsibility on the developer to make sure that the program counter is always incremented by the correct amount.
Don't get me wrong: The strip_bytes
method is far from the best solution.
Maybe the best way is to write a macro with macro_rules!
for the whole match
statement, which allows us to match variable-length arguments. This macro could then also increment the program counter accordingly.
1d2cd50
to
efa6eac
Compare
@nerodesu017 Are you ok if I take over this branch, trying to finish the work? |
I am fine with that! |
I just figured that all the clear changes that we want already landed in 761bd78 . Considering that and the comment in #23 (comment), I would suggest we close this PR. This take on the matching of opcodes (which I unfortunately proposed) has some serious flaws as pointed out in the comment above. |
Pull Request Overview
This pull request changes the way we handle opcodes: from using magic bytes to using constants.
Testing Strategy
This pull request was tested locally.
TODO or Help Wanted
N/A
Formatting
cargo fmt
cargo check
cargo build
nix fmt
treefmt
Github Issue
N/A
Author
Signed-off-by: Popescu Adrian [email protected]