Skip to content

Commit

Permalink
Add more continuation ops
Browse files Browse the repository at this point in the history
  • Loading branch information
Rexagon committed Sep 23, 2024
1 parent 13d1432 commit e0107da
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 14 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion asm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "everscale-asm"
version = "0.0.9"
version = "0.0.10"
description = "Rust implementation of TVM Assembler"
include = ["src/**/*.rs", "src/**/*.tvm", "./LICENSE-*", "./README.md"]
edition.workspace = true
Expand Down
90 changes: 84 additions & 6 deletions asm/src/asm/opcodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -679,15 +679,15 @@ fn register_stackops(t: &mut Opcodes) {
// Continuation / Flow control primitives
"EXECUTE" | "CALLX" => 0xd8,
"JMPX" => 0xd9,
// TODO: CALLXARGS
"CALLXARGS" => op_callxargs,
"JMPXARGS" => 0xdb1(u4),
"RETARGS" => 0xdb2(u4),
"RET" | "RETTRUE" => 0xdb30,
"RETALT" | "RETFALSE" => 0xdb31,
"BRANCH" | "RETBOOL" => 0xdb32,
"CALLCC" => 0xdb34,
"JMPXDATA" => 0xdb35,
// TODO: CALLCCARGS
"CALLCCARGS" => op_callccargs,
"CALLXVARARGS" => 0xdb38,
"RETVARARGS" => 0xdb39,
"JMPXVARARGS" => 0xdb3a,
Expand Down Expand Up @@ -742,16 +742,16 @@ fn register_stackops(t: &mut Opcodes) {
"AGAINEND" => 0xeb,

// Continuation stack manipulation and continuation creation
// TODO: SETCONTARGS
// TODO: SETNUMARGS
"SETCONTARGS" => op_setcontargs,
"SETNUMARGS" => op_setnumargs,
"RETURNARGS" => 0xed0(u4),
"RETURNVARARGS" => 0xed10,
"SETCONTVARARGS" => 0xed11,
"SETNUMVARARGS" => 0xed12,
"BLESS" => 0xed1e,
"BLESSVARARGS" => 0xed1f,
// TODO: BLESSARGS
// TODO: BLESSNUMARGS
"BLESSARGS" => op_blessargs,
"BLESSNUMARGS" => op_blessnumargs,

// Control register and continuation savelist manipulation
"PUSHCTR" => 0xed4(c),
Expand Down Expand Up @@ -1395,6 +1395,40 @@ fn op_pldrefidx(ctx: &mut Context, instr: &ast::Instr<'_>) -> Result<(), AsmErro
.with_span(instr.span)
}

fn op_callxargs(ctx: &mut Context, instr: &ast::Instr<'_>) -> Result<(), AsmError> {
let (NatU4(p), WithSpan(Nat(r), r_span)) = instr.parse_args()?;
match r.sign() {
// DApr
Sign::NoSign | Sign::Plus => {
let r = match r.to_u8() {
Some(r) if (0..=15).contains(&r) => r,
_ => return Err(AsmError::OutOfRange(r_span)),
};
ctx.get_builder(16)
.store_u16(0xda00 | ((p as u16) << 4) | (r as u16))
}
// DB0p
Sign::Minus => {
if !matches!(r.to_i8(), Some(-1)) {
return Err(AsmError::OutOfRange(r_span));
}
ctx.get_builder(16).store_u16(0xdb00 | (p as u16))
}
}
.with_span(instr.span)
}

fn op_callccargs(ctx: &mut Context, instr: &ast::Instr<'_>) -> Result<(), AsmError> {
let (NatU4(p), WithSpan(Nat(r), r_span)) = instr.parse_args()?;
let r = match r.to_i8() {
Some(r) if (-1..=14).contains(&r) => (r as u8) & 0xf,
_ => return Err(AsmError::OutOfRange(r_span)),
};
ctx.get_builder(24)
.store_uint(0xdb3600 | ((p as u64) << 4) | (r as u64), 24)
.with_span(instr.span)
}

fn op_ifbitjmp(ctx: &mut Context, instr: &ast::Instr<'_>) -> Result<(), AsmError> {
op_ifbitjmp_impl::<false>(ctx, instr)
}
Expand Down Expand Up @@ -1434,6 +1468,50 @@ fn op_ifbitjmpref_impl<const INV: bool>(
b.store_reference(c).with_span(instr.span)
}

fn op_setcontargs(ctx: &mut Context, instr: &ast::Instr<'_>) -> Result<(), AsmError> {
let (NatU4(r), WithSpan(Nat(n), n_span)) = instr.parse_args()?;
let n = match n.to_i8() {
Some(n) if (-1..=14).contains(&n) => (n as u8) & 0xf,
_ => return Err(AsmError::OutOfRange(n_span)),
};
ctx.get_builder(16)
.store_u16(0xec00 | ((r as u16) << 4) | (n as u16))
.with_span(instr.span)
}

fn op_setnumargs(ctx: &mut Context, instr: &ast::Instr<'_>) -> Result<(), AsmError> {
let WithSpan(Nat(n), n_span) = instr.parse_args()?;
let n = match n.to_i8() {
Some(n) if (-1..=14).contains(&n) => (n as u8) & 0xf,
_ => return Err(AsmError::OutOfRange(n_span)),
};
ctx.get_builder(16)
.store_u16(0xec00 | (n as u16))
.with_span(instr.span)
}

fn op_blessargs(ctx: &mut Context, instr: &ast::Instr<'_>) -> Result<(), AsmError> {
let (NatU4(r), WithSpan(Nat(n), n_span)) = instr.parse_args()?;
let n = match n.to_i8() {
Some(n) if (-1..=14).contains(&n) => (n as u8) & 0xf,
_ => return Err(AsmError::OutOfRange(n_span)),
};
ctx.get_builder(16)
.store_u16(0xee00 | ((r as u16) << 4) | (n as u16))
.with_span(instr.span)
}

fn op_blessnumargs(ctx: &mut Context, instr: &ast::Instr<'_>) -> Result<(), AsmError> {
let WithSpan(Nat(n), n_span) = instr.parse_args()?;
let n = match n.to_i8() {
Some(n) if (-1..=14).contains(&n) => (n as u8) & 0xf,
_ => return Err(AsmError::OutOfRange(n_span)),
};
ctx.get_builder(16)
.store_u16(0xee00 | (n as u16))
.with_span(instr.span)
}

fn op_callvar(ctx: &mut Context, instr: &ast::Instr<'_>) -> Result<(), AsmError> {
// PUSH c3
op_preparevar(ctx, instr)?;
Expand Down
43 changes: 43 additions & 0 deletions asm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,4 +227,47 @@ mod tests {
);
Ok(())
}

#[test]
fn contops() -> anyhow::Result<()> {
let code = Code::assemble(
r##"
CALLXARGS 0, 2
CALLXARGS 15, 14
CALLXARGS 1, -1
CALLCCARGS 0, 2
CALLCCARGS 15, 14
CALLCCARGS 1, -1
SETCONTARGS 0, 2
SETCONTARGS 15, 14
SETCONTARGS 1, -1
BLESSARGS 0, 2
BLESSARGS 15, 14
BLESSARGS 1, -1
"##,
)?;
assert_eq!(
code.repr_hash(),
&"edb0041119c9381c6426a99abf45236c8192383e14c368775e77aa13e0c5fa79"
.parse::<HashBytes>()?
);

let code1 = Code::assemble(
r##"
SETCONTARGS 0, 2
BLESSARGS 0, 3
"##,
)?;
let code2 = Code::assemble(
r##"
SETNUMARGS 2
BLESSNUMARGS 3
"##,
)?;
assert_eq!(code1, code2);
Ok(())
}
}
4 changes: 2 additions & 2 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tvmasm"
version = "0.0.9"
version = "0.0.10"
description = "CLI for TVM Assembler"
include = ["src/**/*.rs", "src/**/*.tvm", "./LICENSE-*", "./README.md"]
edition.workspace = true
Expand All @@ -24,4 +24,4 @@ tracing-subscriber = { workspace = true }
unicode-width = { workspace = true }
everscale-types = { workspace = true, features = ["sync"] }

everscale-asm = { path = "../asm", version = "0.0.9" }
everscale-asm = { path = "../asm", version = "0.0.10" }
4 changes: 2 additions & 2 deletions macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "everscale-asm-macros"
version = "0.0.9"
version = "0.0.10"
description = "Macros for Rust implementation of TVM Assembler"
include = ["src/**/*.rs", "src/**/*.tvm", "./LICENSE-*", "./README.md"]
edition.workspace = true
Expand All @@ -17,4 +17,4 @@ proc-macro2 = { workspace = true }
quote = { workspace = true }
syn = { workspace = true, features = ["parsing"] }

everscale-asm = { path = "../asm", version = "0.0.9" }
everscale-asm = { path = "../asm", version = "0.0.10" }

0 comments on commit e0107da

Please sign in to comment.