Skip to content
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

Basic Bytecode Impl with oxc's parser #21

Closed
wants to merge 37 commits into from

Conversation

sno2
Copy link
Contributor

@sno2 sno2 commented Jun 5, 2023

No description provided.

@sno2 sno2 changed the title WIP Parser/Tokenizer Rework Basic Bytecode Impl with oxc's parser Jun 10, 2023
Copy link
Collaborator

@andreubotella andreubotella left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might not be too familiar with bytecode, but it seems odd to me that every instruction operates on an arbitrary address passed in the bytecode itself. Usually bytecode or machine code architectures are either stack-based or register-based, but you usually don't have instructions directly operating on memory addresses. This looks like an odd design to me, and it seems like it'd be much cleaner if it was a stack machine.

let mut memory = Vec::<Value>::with_capacity(self.pc as usize);

for _ in 0..self.pc {
memory.push(Value::Undefined);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed, since each instruction can specify the memory address it operates on?

@andreubotella
Copy link
Collaborator

andreubotella commented Jun 16, 2023

It also seems like the bytecode building and the interpreting could be split apart, rather than having to share the VM struct. For example, the parsing could generate the VM that then gets used to evaluate the code.

Also, what is VM meant to be exactly? Is it an agent in the JS spec (= a V8 isolate)? Is it a realm? A parsed script or module?

@sno2
Copy link
Contributor Author

sno2 commented Jun 16, 2023

I might not be too familiar with bytecode, but it seems odd to me that every instruction operates on an arbitrary address passed in the bytecode itself. Usually bytecode or machine code architectures are either stack-based or register-based, but you usually don't have instructions directly operating on memory addresses. This looks like an odd design to me, and it seems like it'd be much cleaner if it was a stack machine.

Yeah...I haven't built a bytecode interpreter before this so that makes more sense.

Do you mean something like this? (Still not really sure how these things are designed)

PushNumber 23
PushNumber 40
Add

And Add would pop 40 and 23 off a stack and then push 63?

@andreubotella
Copy link
Collaborator

Do you mean something like this? (Still not really sure how these things are designed)

PushNumber 23
PushNumber 40
Add

And Add would pop 40 and 23 off a stack and then push 63?

That's right.

Building such a bytecode might be tricker, though, since the values on top of the stack might not be the ones you need, and building the most optimal bytecode might mean moving instructions around. But you could have instructions to copy a value from elsewhere in the stack to the top, and a noop instruction to discard values from the top.

@MierenManz
Copy link
Collaborator

Maybe rather than using noop for discarding a value a noop and drop might be better? (same as for wasm)

@MierenManz
Copy link
Collaborator

Yeah...I haven't built a bytecode interpreter before this so that makes more sense.
I've built semi usable bytecode interpreters before. So I could maybe help you with that

@sno2
Copy link
Contributor Author

sno2 commented Oct 30, 2023

Stale, might be able to use later.

@sno2 sno2 closed this Oct 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants