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

Fixed interpreted program. #2

Merged
merged 4 commits into from
Apr 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
197 changes: 197 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,10 @@ version = "0.1.0"
authors = ["Jasper Schulz <[email protected]>"]

[dependencies]
maplit = "*"
maplit = "*"
kaktus = "0.1.2"
log = "0.3"
env_logger = "0.3"
frunk = "0.1.22"
frunk_core = "0.0.11"
boolinator = "2.4.0"
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# daly
Simple VM for a Dyon--subset
Copy link

Choose a reason for hiding this comment

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

Link to dyon website? I've never heard of dyon, so it's likely others haven't either.

Copy link

Choose a reason for hiding this comment

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

Is it just a VM, or a VM and a tracer. A bullet point below leas me to think the latter.


To run use:

cargo run

To see what is happening internally, you can enable logging:

RUST_LOG=daly cargo run

## Current state

* `main.rs` implements a simple interpreter for some dyon-bytecode. `main()` contains the bytecode of [this](https://github.com/greenMT/example-programs/blob/master/example-programs/dyon/min_loop.dyon) program.

* the interpreter traces execution of loops

* `tracerunner.rs` contains an independent execution engine for generated traces


### Optimisations

**Inlining**
Inlining of function calls is performed. Necessary steps for deoptimisation can be found in `tracerunner::Runner::recover`.
Copy link

Choose a reason for hiding this comment

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

Deoptimisation for inlining would be pulling an inlined function back out into its own unit with an activation record etc? Why would you need to do this? Are you inlining specialised versions of functions perhaps?

Copy link

Choose a reason for hiding this comment

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

Put another way, why would you want to "un-inline" a call?

Maybe this is a great idea for some reason, but it's not a conventional approach (AFAIK).

Copy link
Contributor

Choose a reason for hiding this comment

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

Let me give you a (somewhat artificial) example. Imagine you've got a function f which inspects the stack. If you inline f, you then have to deopt so that it can inspect the stack; you'd be better off not actually inlining it but you might only realise that after you've inlined it.

That said, in general, you're right. But I think the point Jasper is making is not about uninlining, so much as it's about "we called f, a guard failed, so we have to blackhole".

40 changes: 40 additions & 0 deletions src/bytecode.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@


#[derive(Debug, Clone, Copy)]
pub enum Comp {
Eq,
Lt,
Le,
Gt,
Ge,
}


#[derive(Debug, Clone)]
pub enum Instruction {
Call(String),
Return,

Add,
Cmp(Comp),

Jump(usize),
JumpIfTrue(usize),
JumpIfFalse(usize),

Load(usize),
Store(usize),
Const(usize),

Array(usize),
ArrayGet,
Push,

Loop,
Break,

// intrinsics
Len,
Print,
Clone,
}
80 changes: 80 additions & 0 deletions src/conversions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@

// XXX: there might be a macro which implements From/Into for enums

use super::*;

impl From<bool> for Value {
fn from(b: bool) -> Self {
Value::Bool(b)
}
}

impl From<Value> for bool {
fn from(val: Value) -> Self {
match val {
Value::Bool(b) => b,
_ => panic!("unexpeted Array variant"),
}
}
}

impl From<Vec<usize>> for Value {
fn from(xs: Vec<usize>) -> Self {
Value::Array(xs)
}
}

impl From<Value> for Vec<usize> {
fn from(val: Value) -> Self {
match val {
Value::Array(xs) => xs,
_ => panic!("unexpeted Array variant"),
}
}
}

impl AsMut<Vec<usize>> for Value {
fn as_mut(&mut self) -> &mut Vec<usize> {
match *self {
Value::Array(ref mut xs) => xs,
_ => panic!("unexpeted Array variant"),
}
}
}


impl From<Value> for usize {
fn from(val: Value) -> Self {
match val {
Value::Usize(n) => n,
_ => panic!("unexpeted Array variant"),
}
}
}

impl From<usize> for Value {
fn from(n: usize) -> Self {
Value::Usize(n)
}
}


impl<'a> From<&'a Instruction> for TraceInstruction {
fn from(instr: &Instruction) -> TraceInstruction {
use Instruction as I;
use TraceInstruction as TI;

match *instr {
I::Add => TI::Add,
I::Cmp(c) => TI::Cmp(c),
I::Const(c) => TI::Const(c),
I::Len => TI::Len,
I::Print => TI::Print,
I::Clone => TI::Clone,
I::Array(u) => TI::Array(u),
I::ArrayGet => TI::ArrayGet,

_ => panic!("can not convert {:?}", instr),
}
}
}
Loading