-
Notifications
You must be signed in to change notification settings - Fork 77
feat: Add new DefaultMachineRunner trait for initialization work #470
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
feat: Add new DefaultMachineRunner trait for initialization work #470
Conversation
Previously, all different machines in ckb-vm might use slightly different initialization process. This commit introduces a new DefaultMachineRunner trait, so the same initialization & usage workflow can be used for all types implementing this trait. This is a cherry-pick of nervosnetwork#469 to the develop branch. 2 more changes are applied on the develop branch: * Since AsmCoreMachine is now constant, we can simply use AsmCoreMachine instead of `Box<AsmCoreMachine>`. * nervosnetwork#343 was mostly reverted. Upon more thinking, I think the change earlier does not make sense now. It's better we provide unified initialization for the whole machine, not just for the memory part. Due to the new InstDecoder / TraceDecoder structure introduced in develop branch, more changes are required in the develop branch than 0.24.x releases. Some of those changes include: * Assembly machines now require TraceDecoder instead of InstDecoder. This means we cannot use DefaultMachineBuilder to build DefaultMachine structures for both types of VMs. The assembly machine types require more constraints. Given this consideration, DefaultMachineBuilder is removed in this commit. 2 new types RustDefaultMachineBuilder and AsmDefaultMachineBuilder are added for 2 types of VMs respectively. * A new set of types that begin with `Abstract`, such as AbstractDefaultMachineBuilder, AbstractAsmMachine, AbstractTraceMachine are introduced. One is only expected to use those types when one wants to tweak the inst/trace decoder used. Otherwise, one is safe to pick AsmMachine/AsmDefaultMachineBuilder or TraceMachine/RustDefaultMachineBuilder. So the current workflow is like following: 1. Pick a type implementing DefaultMachineRunner traits. Most likely, one would pick either AsmMachine or TraceMachine. 2. Instantiate a core machine using DefaultMachineRunner::Inner::new. 3. Based on the type picked in step 1, use AsmDefaultMachineBuilder or RustDefaultMachineBuilder to build a default machine with possible instruction cycle func, syscalls and debugger plugin. 4. Finally, use DefaultMachineRunner::new to create the final runnable machine from the default machine. For advanced usages where the decoder is customized, one can use AbstractAsmMachine or AbstractTraceMachine type. Then use AbstractDefaultMachineBuilder to build the default machine. And finally create the runnable machine. All those types accept an additional InstDecoder / TraceDecoder trait impl that allows one to customize the decoder for optimizations.
8c46b7a
to
7b92b7c
Compare
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 introducing another TraceMachineRuner
to extend DefaultMachineRunner
trait would be a lot simpler than the current associated type design:
trait DefaultMachineRunner {
fn run_with_decoder<D: InstDecoder>(&mut self, decoder: &mut D);
}
trait TraceMachineRunner: DefaultMachineRunner {
fn run_with_decoder<D: TraceDecoder>(&mut self, decoder: &mut D);
}
trait InstDecoder {}
trait TraceDecoder: InstDecoder {}
This allows us to remove the Decoder
generic type bound from most structs, for example, AbstractTraceMachine
:
pub struct AbstractTraceMachine<Inner: SupportMachine> {
pub machine: DefaultMachine<Inner>,
factory: ThreadFactory<DefaultMachine<Inner>>,
traces: Vec<Trace<DefaultMachine<Inner>>>,
}
This would actually require specifying types when calling the method, see this example. In fact a lot of the work done in this PR, is done to make sure we don't need those extra work for specifying types. I do want to design the API that when you invoke |
I see... |
Unnecessary PhantomData fields have been removed. |
Just to provide a little bit more on the background of this PR, in case anyone comes back from the future: Some of the initial design goals are as follows:
Really, the above are the original design goals. The introduction of When I was using the original
That's really the birth of While I feel this PR is long enough, a potential improvement could be added in the future: as of right now, one still needs initialization for 3 types:
Even though when someone chooses the type implementing |
Previously, all different machines in ckb-vm might use slightly different initialization process. This commit introduces a new DefaultMachineRunner trait, so the same initialization & usage workflow can be used for all types implementing this trait.
This is a cherry-pick of #469 to the develop branch. 2 more changes are applied on the develop branch:
Box<AsmCoreMachine>
.Due to the new InstDecoder / TraceDecoder structure introduced in develop branch, more changes are required in the develop branch than 0.24.x releases. Some of those changes include:
Abstract
, such as AbstractDefaultMachineBuilder, AbstractAsmMachine, AbstractTraceMachine are introduced. One is only expected to use those types when one wants to tweak the inst/trace decoder used. Otherwise, one is safe to pick AsmMachine/AsmDefaultMachineBuilder or TraceMachine/RustDefaultMachineBuilder.So the current workflow is like following:
For advanced usages where the decoder is customized, one can use AbstractAsmMachine or AbstractTraceMachine type. Then use AbstractDefaultMachineBuilder to build the default machine. And finally create the runnable machine. All those types accept an additional InstDecoder / TraceDecoder trait impl that allows one to customize the decoder for optimizations.