Skip to content

Commit

Permalink
feature: add custom dependencies to Executor resolver,
Browse files Browse the repository at this point in the history
Temporarily switch to `from_u32_unchecked` to use `bitcast` and avoid
checks.
  • Loading branch information
greenhat committed Nov 28, 2024
1 parent e86c402 commit ce9f1e0
Show file tree
Hide file tree
Showing 17 changed files with 371 additions and 247 deletions.
5 changes: 5 additions & 0 deletions frontend-wasm/src/intrinsics/felt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ pub(crate) fn convert_felt_intrinsics(
let inst = builder.ins().cast(args[0], Felt, span);
vec![inst]
}
"from_u32_unchecked" => {
assert_eq!(args.len(), 1, "{} takes exactly one argument", func_id);
let inst = builder.ins().bitcast(args[0], Felt, span);
vec![inst]
}
"as_u64" => {
assert_eq!(args.len(), 1, "{} takes exactly one argument", func_id);
// we're casting to i64 instead of u64 because Wasm doesn't have u64
Expand Down
46 changes: 33 additions & 13 deletions midenc-debug/src/exec/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use miden_assembly::Library as CompiledLibrary;
use miden_core::{Program, StackInputs, Word};
use miden_package::{
Dependency, DependencyName, DependencyResolution, DependencyResolver, LocalResolution,
MemDependencyResolverByDigest, SystemLibraryId,
MastArtifact, MemDependencyResolverByDigest, SystemLibraryId,
};
use miden_processor::{
AdviceInputs, ContextId, ExecutionError, Felt, MastForest, MemAdviceProvider, Process,
Expand All @@ -35,17 +35,23 @@ pub struct Executor {
stack: StackInputs,
advice: AdviceInputs,
libraries: Vec<Arc<MastForest>>,
dependency_resolver: MemDependencyResolverByDigest,
}
impl Executor {
/// Construct an executor with the given arguments on the operand stack
pub fn new(args: Vec<Felt>) -> Self {
let mut resolver = MemDependencyResolverByDigest::default();
resolver.add(*STDLIB.digest(), STDLIB.clone().into());
resolver.add(*BASE.digest(), BASE.clone().into());
Self {
stack: StackInputs::new(args).expect("invalid stack inputs"),
advice: AdviceInputs::default(),
libraries: Default::default(),
dependency_resolver: resolver,
}
}

/// Construct the executor with the given inputs and adds dependencies from the given package
pub fn for_package(
package: &miden_package::Package,
args: Vec<Felt>,
Expand All @@ -57,25 +63,35 @@ impl Executor {
package.name,
DisplayHex::new(&package.digest().as_bytes())
);

let mut exec = Self::new(args);
exec.with_dependencies(&package.manifest.dependencies)?;
log::debug!("executor created");
Ok(exec)
}

let mut resolver = MemDependencyResolverByDigest::default();
resolver.add(*STDLIB.digest(), STDLIB.clone().into());
resolver.add(*BASE.digest(), BASE.clone().into());
/// Adds dependencies to the executor
pub fn with_dependencies(&mut self, dependencies: &[Dependency]) -> Result<&mut Self, Report> {
use midenc_hir::formatter::DisplayHex;

for dep in &package.manifest.dependencies {
match resolver.resolve(dep) {
for dep in dependencies {
match self.dependency_resolver.resolve(dep) {
Some(resolution) => {
log::debug!("dependency {:?} resolved to {:?}", dep, resolution);
log::debug!("loading library from package dependency: {:?}", dep);
match resolution {
DependencyResolution::Local(LocalResolution::Library(lib)) => {
let library = lib.as_ref();
log::debug!("loading library from package dependency: {:?}", dep);
exec.with_mast_forest(lib.mast_forest().clone());
self.with_mast_forest(lib.mast_forest().clone());
}
DependencyResolution::Local(LocalResolution::Package(_)) => {
todo!("local package dependencies are not yet supported in executor")
DependencyResolution::Local(LocalResolution::Package(pkg)) => {
if let MastArtifact::Library(lib) = &pkg.mast {
self.with_mast_forest(lib.mast_forest().clone());
} else {
Err(Report::msg(format!(
"expected package {} to contain library",
pkg.name
)))?;
}
}
}
}
Expand All @@ -85,10 +101,10 @@ impl Executor {

log::debug!("executor created");

Ok(exec)
Ok(self)
}

/// Set the contents of memory for the shadow stack frame of the entrypoint
/// Set the contents of memory for the shadow stack frame of the entrypint
pub fn with_advice_inputs(&mut self, advice: AdviceInputs) -> &mut Self {
self.advice.extend(advice);
self
Expand Down Expand Up @@ -290,6 +306,10 @@ impl Executor {
let out = self.execute(program, session);
out.parse_result().expect("invalid result")
}

pub fn dependency_resolver_mut(&mut self) -> &mut MemDependencyResolverByDigest {
&mut self.dependency_resolver
}
}

#[track_caller]
Expand Down
16 changes: 13 additions & 3 deletions sdk/stdlib-sys/src/intrinsics/felt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ extern "C" {
#[link_name = "from-u64-unchecked"]
fn extern_from_u64_unchecked(value: u64) -> Felt;

#[link_name = "from-u32-unchecked"]
fn extern_from_u32_unchecked(value: u32) -> Felt;

#[link_name = "as_u64"]
fn extern_as_u64(felt: Felt) -> u64;

Expand Down Expand Up @@ -68,9 +71,11 @@ extern "C" {
macro_rules! felt {
// Trigger a compile-time error if the value is not a constant
($value:literal) => {{
const VALUE: u64 = $value as u64;
assert!(VALUE <= Felt::M, "Invalid Felt value, must be >= 0 and <= 2^64 - 2^32 + 1");
Felt::from_u64_unchecked(VALUE)
// const VALUE: u64 = $value as u64;
// assert!(VALUE <= Felt::M, "Invalid Felt value, must be >= 0 and <= 2^64 - 2^32 + 1");
// Temporarily switch to `from_u32_unchecked` to use `bitcast` and avoid checks.
const VALUE: u32 = $value as u32;
Felt::from_u32_unchecked(VALUE)
}};
}

Expand All @@ -94,6 +99,11 @@ impl Felt {
unsafe { extern_from_u64_unchecked(value) }
}

#[inline(always)]
pub fn from_u32_unchecked(value: u32) -> Self {
unsafe { extern_from_u32_unchecked(value) }
}

#[inline(always)]
pub fn new(value: u64) -> Result<Self, FeltError> {
if value > Self::M {
Expand Down
7 changes: 5 additions & 2 deletions sdk/stdlib-sys/src/stdlib/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
extern crate alloc;
use alloc::vec::Vec;

use crate::intrinsics::{Felt, Word};
use crate::{
felt,
intrinsics::{Felt, Word},
};

#[link(wasm_import_module = "miden:core-import/[email protected]")]
extern "C" {
Expand Down Expand Up @@ -96,7 +99,7 @@ pub fn pipe_double_words_to_memory(num_words: Felt) -> (Word, Vec<Felt>) {
let end_ptr = unsafe { write_ptr.add(num_words_in_felts) };
// Place for returned C, B, A, write_ptr
let mut ret_area = ::core::mem::MaybeUninit::<Result>::uninit();
let zero = Felt::from_u64_unchecked(0);
let zero = felt!(0);
unsafe {
extern_pipe_double_words_to_memory(
zero,
Expand Down
11 changes: 1 addition & 10 deletions tests/integration/expected/rust_sdk/cross_ctx_account.masm
Original file line number Diff line number Diff line change
Expand Up @@ -409,16 +409,7 @@ end


export."miden:cross-ctx-account/[email protected]#process-felt"
exec."wit_bindgen_rt::run_ctors_once"
push.0.1
dup.1
dup.1
push.4294967295.1
exec.::std::math::u64::lt
assert
mul.4294967296
add
add
exec."wit_bindgen_rt::run_ctors_once" push.3 add
end


16 changes: 8 additions & 8 deletions tests/integration/expected/rust_sdk/cross_ctx_account.wat
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,21 @@
(instance
(type (;0;) (func (param "a" float32) (param "b" float32) (result float32)))
(export (;0;) "add" (func (type 0)))
(type (;1;) (func (param "a" u64) (result float32)))
(export (;1;) "from-u64-unchecked" (func (type 1)))
(type (;1;) (func (param "a" u32) (result float32)))
(export (;1;) "from-u32-unchecked" (func (type 1)))
)
)
(import "miden:core-import/[email protected]" (instance (;2;) (type 2)))
(core module (;0;)
(type (;0;) (func (param i64) (result f32)))
(type (;0;) (func (param i32) (result f32)))
(type (;1;) (func (param f32 f32) (result f32)))
(type (;2;) (func (result i32)))
(type (;3;) (func))
(type (;4;) (func (param i32 i32) (result i32)))
(type (;5;) (func (param i32 i32 i32 i32) (result i32)))
(type (;6;) (func (param f32) (result f32)))
(type (;7;) (func (param i32 i32 i32) (result i32)))
(import "miden:core-import/[email protected]" "from-u64-unchecked" (func $miden_stdlib_sys::intrinsics::felt::extern_from_u64_unchecked (;0;) (type 0)))
(import "miden:core-import/[email protected]" "from-u32-unchecked" (func $miden_stdlib_sys::intrinsics::felt::extern_from_u32_unchecked (;0;) (type 0)))
(import "miden:core-import/[email protected]" "add" (func $miden_stdlib_sys::intrinsics::felt::extern_add (;1;) (type 1)))
(import "miden:core-import/[email protected]" "heap-base" (func $miden_sdk_alloc::heap_base (;2;) (type 2)))
(func $__wasm_call_ctors (;3;) (type 3))
Expand Down Expand Up @@ -66,8 +66,8 @@
(func $miden:cross-ctx-account/[email protected]#process-felt (;7;) (type 6) (param f32) (result f32)
call $wit_bindgen_rt::run_ctors_once
local.get 0
i64.const 1
call $miden_stdlib_sys::intrinsics::felt::extern_from_u64_unchecked
i32.const 3
call $miden_stdlib_sys::intrinsics::felt::extern_from_u32_unchecked
call $miden_stdlib_sys::intrinsics::felt::extern_add
)
(func $cabi_realloc_wit_bindgen_0_28_0 (;8;) (type 5) (param i32 i32 i32 i32) (result i32)
Expand Down Expand Up @@ -206,11 +206,11 @@
)
(alias export 2 "add" (func (;0;)))
(core func (;0;) (canon lower (func 0)))
(alias export 2 "from-u64-unchecked" (func (;1;)))
(alias export 2 "from-u32-unchecked" (func (;1;)))
(core func (;1;) (canon lower (func 1)))
(core instance (;0;)
(export "add" (func 0))
(export "from-u64-unchecked" (func 1))
(export "from-u32-unchecked" (func 1))
)
(alias export 1 "heap-base" (func (;2;)))
(core func (;2;) (canon lower (func 2)))
Expand Down
18 changes: 2 additions & 16 deletions tests/integration/expected/rust_sdk/cross_ctx_note.masm
Original file line number Diff line number Diff line change
Expand Up @@ -411,23 +411,9 @@ end

export."miden:base/[email protected]#note-script"
exec."wit_bindgen_rt::run_ctors_once"
push.0.7
dup.1
dup.1
push.4294967295.1
exec.::std::math::u64::lt
assert
mul.4294967296
add
push.7
exec.::miden:cross-ctx-account/[email protected]::"process-felt"
push.0.10
dup.1
dup.1
push.4294967295.1
exec.::std::math::u64::lt
assert
mul.4294967296
add
push.10
assert_eq
end

Expand Down
20 changes: 10 additions & 10 deletions tests/integration/expected/rust_sdk/cross_ctx_note.wat
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,23 @@
(import "miden:core-import/[email protected]" (instance (;2;) (type 3)))
(type (;4;)
(instance
(type (;0;) (func (param "a" u64) (result float32)))
(export (;0;) "from-u64-unchecked" (func (type 0)))
(type (;0;) (func (param "a" u32) (result float32)))
(export (;0;) "from-u32-unchecked" (func (type 0)))
(type (;1;) (func (param "a" float32) (param "b" float32)))
(export (;1;) "assert-eq" (func (type 1)))
)
)
(import "miden:core-import/[email protected]" (instance (;3;) (type 4)))
(core module (;0;)
(type (;0;) (func (param i64) (result f32)))
(type (;0;) (func (param i32) (result f32)))
(type (;1;) (func (param f32) (result f32)))
(type (;2;) (func (param f32 f32)))
(type (;3;) (func (result i32)))
(type (;4;) (func))
(type (;5;) (func (param i32 i32) (result i32)))
(type (;6;) (func (param i32 i32 i32 i32) (result i32)))
(type (;7;) (func (param i32 i32 i32) (result i32)))
(import "miden:core-import/[email protected]" "from-u64-unchecked" (func $miden_stdlib_sys::intrinsics::felt::extern_from_u64_unchecked (;0;) (type 0)))
(import "miden:core-import/[email protected]" "from-u32-unchecked" (func $miden_stdlib_sys::intrinsics::felt::extern_from_u32_unchecked (;0;) (type 0)))
(import "miden:cross-ctx-account/[email protected]" "process-felt" (func $cross_ctx_note::bindings::miden::cross_ctx_account::foo::process_felt::wit_import (;1;) (type 1)))
(import "miden:core-import/[email protected]" "assert-eq" (func $miden_stdlib_sys::intrinsics::felt::extern_assert_eq (;2;) (type 2)))
(import "miden:core-import/[email protected]" "heap-base" (func $miden_sdk_alloc::heap_base (;3;) (type 3)))
Expand Down Expand Up @@ -76,11 +76,11 @@
)
(func $miden:base/[email protected]#note-script (;8;) (type 4)
call $wit_bindgen_rt::run_ctors_once
i64.const 7
call $miden_stdlib_sys::intrinsics::felt::extern_from_u64_unchecked
i32.const 7
call $miden_stdlib_sys::intrinsics::felt::extern_from_u32_unchecked
call $cross_ctx_note::bindings::miden::cross_ctx_account::foo::process_felt::wit_import
i64.const 10
call $miden_stdlib_sys::intrinsics::felt::extern_from_u64_unchecked
i32.const 10
call $miden_stdlib_sys::intrinsics::felt::extern_from_u32_unchecked
call $miden_stdlib_sys::intrinsics::felt::extern_assert_eq
)
(func $cabi_realloc_wit_bindgen_0_28_0 (;9;) (type 6) (param i32 i32 i32 i32) (result i32)
Expand Down Expand Up @@ -217,12 +217,12 @@
(elem (;0;) (i32.const 1) func $cross_ctx_note::bindings::__link_custom_section_describing_imports $cabi_realloc)
(data $.rodata (;0;) (i32.const 1048576) "\01\00\00\00\01\00\00\00\01\00\00\00\01\00\00\00\01\00\00\00\01\00\00\00\01\00\00\00\01\00\00\00\01\00\00\00\02\00\00\00")
)
(alias export 3 "from-u64-unchecked" (func (;0;)))
(alias export 3 "from-u32-unchecked" (func (;0;)))
(core func (;0;) (canon lower (func 0)))
(alias export 3 "assert-eq" (func (;1;)))
(core func (;1;) (canon lower (func 1)))
(core instance (;0;)
(export "from-u64-unchecked" (func 0))
(export "from-u32-unchecked" (func 0))
(export "assert-eq" (func 1))
)
(alias export 1 "process-felt" (func (;2;)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
(block 0
(let (v1 felt) (const.felt 0))
(let (v2 felt) (exec #miden_base_sys::bindings::account::get_id))
(let (v3 i64) (const.i64 42))
(let (v4 felt) (cast v3))
(let (v3 i32) (const.i32 42))
(let (v4 felt) (bitcast v3))
(let (v5 felt) (add.unchecked v4 v2))
(br (block 1 v5)))

Expand All @@ -63,14 +63,14 @@
(let (v7 i32) (band v5 v6))
(let (v8 (ptr i32)) (global.symbol #__stack_pointer))
(store v8 v7)
(let (v9 i64) (const.i64 1))
(let (v10 felt) (cast v9))
(let (v11 i64) (const.i64 2))
(let (v12 felt) (cast v11))
(let (v13 i64) (const.i64 3))
(let (v14 felt) (cast v13))
(let (v15 i64) (const.i64 4))
(let (v16 felt) (cast v15))
(let (v9 i32) (const.i32 1))
(let (v10 felt) (bitcast v9))
(let (v11 i32) (const.i32 2))
(let (v12 felt) (bitcast v11))
(let (v13 i32) (const.i32 3))
(let (v14 felt) (bitcast v13))
(let (v15 i32) (const.i32 4))
(let (v16 felt) (bitcast v15))
(let (v17 u32) (bitcast v7))
(let (v18 u32) (add.checked v17 12))
(let (v19 u32) (mod.unchecked v18 4))
Expand Down Expand Up @@ -1300,8 +1300,8 @@
(assertz 250 v18)
(let (v19 (ptr i32)) (inttoptr v17))
(let (v20 i32) (load v19))
(let (v21 i64) (const.i64 0))
(let (v22 felt) (cast v21))
(let (v21 i32) (const.i32 0))
(let (v22 felt) (bitcast v21))
(let (v23 i32) (const.i32 4))
(let (v24 u32) (bitcast v23))
(let (v25 i32) (shl.wrapping v12 v24))
Expand Down
Loading

0 comments on commit ce9f1e0

Please sign in to comment.