Skip to content
Closed
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
2 changes: 2 additions & 0 deletions cli/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub struct RunArgs {
breadth_first: bool,
#[arg(long, short = 'H', value_parser = parse_size)]
heap: Option<usize>,
pub args: Vec<String>,
}

impl RunArgs {
Expand All @@ -46,6 +47,7 @@ impl RunArgs {
let mut extrinsics = Extrinsics::default();

host.register_default_extrinsics(&mut extrinsics);
host.register_runtime_extrinsics(&mut extrinsics, self.args);
host.insert_nets(&nets);

let main = host.get("::").expect("missing main");
Expand Down
1 change: 1 addition & 0 deletions cli/src/ivy_cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ impl IvyReplCommand {
let mut extrinsics = Extrinsics::default();

host.register_default_extrinsics(&mut extrinsics);
host.register_runtime_extrinsics(&mut extrinsics, self.run_args.args);
host.insert_nets(&nets);

let mut ivm = IVM::new(&heap, &extrinsics);
Expand Down
2 changes: 2 additions & 0 deletions cli/src/vine_cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ pub struct VineReplCommand {
echo: bool,
#[arg(long)]
no_debug: bool,
args: Vec<String>,
}

impl VineReplCommand {
Expand All @@ -332,6 +333,7 @@ impl VineReplCommand {
let heap = Heap::new();
let mut extrinsics = Extrinsics::default();
host.register_default_extrinsics(&mut extrinsics);
host.register_runtime_extrinsics(&mut extrinsics, self.args);

let mut ivm = IVM::new(&heap, &extrinsics);
let config = Config::new(!self.no_debug, false);
Expand Down
141 changes: 140 additions & 1 deletion ivm/src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
use core::{
fmt::{self, Debug},
marker::PhantomData,
ops::{Deref, DerefMut},
};

use std::{fs::File, io};

use crate::{ivm::IVM, port::Tag, wire::Wire, word::Word};

macro_rules! trait_alias {
Expand Down Expand Up @@ -183,9 +186,16 @@ impl<'ivm> Debug for ExtVal<'ivm> {
}
}

#[derive(Clone, Copy)]
pub struct ExtTy<'ivm, T>(ExtTyId<'ivm>, PhantomData<fn(T) -> T>);

impl<'ivm, T> Clone for ExtTy<'ivm, T> {
fn clone(&self) -> Self {
*self
}
}

impl<'ivm, T> Copy for ExtTy<'ivm, T> {}

impl<'ivm, T> ExtTy<'ivm, T> {
pub fn new_unchecked(ty_id: ExtTyId<'ivm>) -> Self {
Self(ty_id, PhantomData)
Expand Down Expand Up @@ -267,6 +277,7 @@ impl<'ivm> ExtTyCast<'ivm> for f32 {
}
}

#[derive(Default)]
#[repr(align(8))]
pub struct Aligned<T>(T);

Expand All @@ -287,6 +298,134 @@ impl<'ivm> ExtTyCast<'ivm> for f64 {
}
}

#[derive(Default)]
pub struct ExtList<'ivm> {
values: Box<Aligned<Vec<ExtVal<'ivm>>>>,
}

impl<'ivm> ExtList<'ivm> {
pub fn is_empty(&self) -> bool {
self.len() == 0
}

pub fn len(&self) -> usize {
self.values.0.len()
}

pub fn push(&mut self, value: ExtVal<'ivm>) {
self.values.0.push(value);
}

pub fn pop(&mut self) -> Option<ExtVal<'ivm>> {
self.values.0.pop()
}

pub fn into_inner(self) -> Vec<ExtVal<'ivm>> {
self.values.0
}
}

impl<'ivm> From<Vec<ExtVal<'ivm>>> for ExtList<'ivm> {
fn from(values: Vec<ExtVal<'ivm>>) -> Self {
Self { values: Box::new(Aligned(values)) }
}
}

impl<'ivm> ExtTyCast<'ivm> for ExtList<'ivm> {
const COPY: bool = false;

#[inline(always)]
fn into_payload(self) -> Word {
let pointer = Box::into_raw(self.values);
Word::from_ptr(pointer.cast())
}

#[inline(always)]
unsafe fn from_payload(payload: Word) -> Self {
let ptr = payload.ptr().cast_mut().cast();
let values = unsafe { Box::from_raw(ptr) };
Self { values }
}
}

pub struct ExtFile(Box<Aligned<File>>);

impl From<File> for ExtFile {
fn from(file: File) -> Self {
Self(Box::new(Aligned(file)))
}
}

impl Deref for ExtFile {
type Target = File;

fn deref(&self) -> &Self::Target {
&self.0.0
}
}

impl DerefMut for ExtFile {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0.0
}
}

impl<'ivm> ExtTyCast<'ivm> for ExtFile {
const COPY: bool = false;

#[inline(always)]
fn into_payload(self) -> Word {
let pointer = Box::into_raw(self.0);
Word::from_ptr(pointer.cast())
}

#[inline(always)]
unsafe fn from_payload(payload: Word) -> Self {
let ptr = payload.ptr().cast_mut().cast();
let file = unsafe { Box::from_raw(ptr) };
Self(file)
}
}

pub struct ExtIoError(Box<Aligned<io::Error>>);

impl From<io::Error> for ExtIoError {
fn from(error: io::Error) -> Self {
Self(Box::new(Aligned(error)))
}
}

impl Deref for ExtIoError {
type Target = io::Error;

fn deref(&self) -> &Self::Target {
&self.0.0
}
}

impl DerefMut for ExtIoError {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0.0
}
}

impl<'ivm> ExtTyCast<'ivm> for ExtIoError {
const COPY: bool = false;

#[inline(always)]
fn into_payload(self) -> Word {
let pointer = Box::into_raw(self.0);
Word::from_ptr(pointer.cast())
}

#[inline(always)]
unsafe fn from_payload(payload: Word) -> Self {
let ptr = payload.ptr().cast_mut().cast();
let error = unsafe { Box::from_raw(ptr) };
Self(error)
}
}

/// Used for the `IO` extrinsic type.
impl<'ivm> ExtTyCast<'ivm> for () {
const COPY: bool = false;
Expand Down
Loading