Skip to content

Commit

Permalink
chore(codegen): ban recursion
Browse files Browse the repository at this point in the history
  • Loading branch information
clearloop committed Oct 9, 2024
1 parent 5565b0b commit 6b1d743
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 43 deletions.
8 changes: 8 additions & 0 deletions codegen/src/visitor/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::{
wasm::{HostFunc, ToLSBytes},
Error, Function, Result,
};
use anyhow::anyhow;
use opcodes::ShangHai as OpCode;

impl Function {
Expand Down Expand Up @@ -34,6 +35,13 @@ impl Function {

/// Call internal functions
fn call_internal(&mut self, index: u32) -> Result<()> {
if self.env.index == Some(index) {
return Err(anyhow!(
"Recursion is no more supported in this version, see https://github.com/zink-lang/zink/issues/248"
)
.into());
}

tracing::trace!("call internal function: index={index}");
let (params, results) = self.env.funcs.get(&index).unwrap_or(&(0, 0));

Expand Down
7 changes: 3 additions & 4 deletions compiler/filetests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,10 @@ impl Test {
let Test { module, name, wasm } = self;
tracing::info!("Compiling {module}::{name}");

let mut compiler = zinkc::Compiler::default();
// TODO: after #166
let compiler = zinkc::Compiler::default();
// TODO: after #248
if name == "fibonacci" {
// return Ok(());
compiler.config = compiler.config.dispatcher(true);
return Ok(());
}
compiler.compile(&wasm)?;
Ok(())
Expand Down
76 changes: 38 additions & 38 deletions compiler/filetests/wat/recursion/fibonacci.wat
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
(module
(type (;0;) (func (param i32) (result i32)))
(func (;0;) (type 0) (param i32) (result i32)
local.get 0
call 1)
(func (;1;) (type 0) (param i32) (result i32)
(local i32)
local.get 0
i32.const 2
i32.ge_u
if ;; label = @1
loop ;; label = @2
local.get 0 ;; 1
i32.const 1 ;; 2
i32.sub ;; 1
call 1 ;; 1
local.get 1 ;; 2
i32.add ;; 1
local.set 1 ;; 0
local.get 0 ;; 1
i32.const 2 ;; 2
i32.sub ;; 1
local.tee 0 ;; 1
i32.const 1 ;; 2
i32.gt_u ;; 1
br_if 0 (;@2;) ;; 2 -> 0
end
end
local.get 0
local.get 1
i32.add)
(memory (;0;) 16)
(global (;0;) i32 (i32.const 1048576))
(global (;1;) i32 (i32.const 1048576))
(export "memory" (memory 0))
(export "fibonacci" (func 0))
(export "recursion" (func 1))
(export "__data_end" (global 0))
(export "__heap_base" (global 1)))
(type (;0;) (func (param i32) (result i32)))
(func (;0;) (type 0) (param i32) (result i32)
local.get 0
call 1)
(func (;1;) (type 0) (param i32) (result i32)
(local i32)
local.get 0
i32.const 2
i32.ge_u
if ;; label = @1
loop ;; label = @2
local.get 0 ;; 1
i32.const 1 ;; 2
i32.sub ;; 1
call 1 ;; 1
local.get 1 ;; 2
i32.add ;; 1
local.set 1 ;; 0
local.get 0 ;; 1
i32.const 2 ;; 2
i32.sub ;; 1
local.tee 0 ;; 1
i32.const 1 ;; 2
i32.gt_u ;; 1
br_if 0 (;@2;) ;; 2 -> 0
end
end
local.get 0
local.get 1
i32.add)
(memory (;0;) 16)
(global (;0;) i32 (i32.const 1048576))
(global (;1;) i32 (i32.const 1048576))
(export "memory" (memory 0))
(export "fibonacci" (func 0))
(export "recursion" (func 1))
(export "__data_end" (global 0))
(export "__heap_base" (global 1)))
2 changes: 1 addition & 1 deletion compiler/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl Compiler {

self.compile_dispatcher(&mut parser)?;
for func in parser.funcs.into_funcs() {
self.compile_func(env.clone(), func)?;
self.compile_func(env.with_index(func.index()), func)?;
}

self.table.code_offset(self.buffer.len() as u16);
Expand Down
1 change: 1 addition & 0 deletions examples/fibonacci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ fn internal_rec(n: u64) -> u64 {
#[cfg(not(target_arch = "wasm32"))]
fn main() {}

#[ignore]
#[test]
fn test() -> anyhow::Result<()> {
use zint::{Bytes32, Contract};
Expand Down
2 changes: 2 additions & 0 deletions tests/recursion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use anyhow::Result;
use filetests::Test;
use zint::{Bytes32, Contract};

#[ignore]
#[test]
fn fibonacci() -> Result<()> {
let mut contract = Contract::from(Test::RECURSION_FIBONACCI).pure().compile()?;
Expand All @@ -16,6 +17,7 @@ fn fibonacci() -> Result<()> {

// x = 2
let info = contract.execute([2])?;
assert_eq!(info.halt, None);
assert_eq!(1.to_bytes32().to_vec(), info.ret);

// x = 3
Expand Down

0 comments on commit 6b1d743

Please sign in to comment.