From 738b3b03836135e62c6bd2b92ceb4259374a010d Mon Sep 17 00:00:00 2001 From: Richard Kiss Date: Mon, 23 Aug 2021 14:04:03 -0700 Subject: [PATCH] Use `Dialect` where possible. --- ...hia_dialect_factory.rs => chia_dialect.rs} | 26 +++--- src/lib.rs | 2 +- src/py/run_generator.rs | 28 +++--- src/py/run_program.rs | 92 +++++-------------- src/run_program.rs | 2 +- 5 files changed, 52 insertions(+), 98 deletions(-) rename src/{chia_dialect_factory.rs => chia_dialect.rs} (82%) diff --git a/src/chia_dialect_factory.rs b/src/chia_dialect.rs similarity index 82% rename from src/chia_dialect_factory.rs rename to src/chia_dialect.rs index a36d2db0..7e0e827e 100644 --- a/src/chia_dialect_factory.rs +++ b/src/chia_dialect.rs @@ -11,22 +11,18 @@ use crate::run_program::OperatorHandler; const QUOTE_KW: [u8; 1] = [1]; const APPLY_KW: [u8; 1] = [2]; - -pub fn chia_op_handler(strict: bool) -> Box { - let f_lookup: FLookup = f_lookup_for_hashmap(chia_opcode_mapping()); - - Box::new(OperatorHandlerWithMode { f_lookup, strict }) -} - -pub fn chia_dialect(strict: bool) -> Dialect { - Dialect::new("E_KW, &APPLY_KW, chia_op_handler(strict)) -} - pub struct OperatorHandlerWithMode { f_lookup: FLookup, strict: bool, } +impl OperatorHandlerWithMode { + pub fn new_with_hashmap(hashmap: HashMap>, strict: bool) -> Self { + let f_lookup: FLookup = f_lookup_for_hashmap(hashmap); + OperatorHandlerWithMode { f_lookup, strict } + } +} + impl OperatorHandler for OperatorHandlerWithMode { fn op( &self, @@ -88,3 +84,11 @@ pub fn chia_opcode_mapping() -> HashMap> { } h } + +pub fn chia_op_handler(strict: bool) -> OperatorHandlerWithMode { + OperatorHandlerWithMode::new_with_hashmap(chia_opcode_mapping(), strict) +} + +pub fn chia_dialect(strict: bool) -> Dialect { + Dialect::new("E_KW, &APPLY_KW, Box::new(chia_op_handler(strict))) +} diff --git a/src/lib.rs b/src/lib.rs index 1ed2a712..e5a3eca1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,5 @@ pub mod allocator; -pub mod chia_dialect_factory; +pub mod chia_dialect; pub mod core_ops; pub mod cost; pub mod dialect; diff --git a/src/py/run_generator.rs b/src/py/run_generator.rs index 11acac31..fac1f957 100644 --- a/src/py/run_generator.rs +++ b/src/py/run_generator.rs @@ -1,5 +1,7 @@ use crate::allocator::{Allocator, NodePtr}; +use crate::chia_dialect::OperatorHandlerWithMode; use crate::cost::Cost; +use crate::dialect::Dialect; use crate::gen::conditions::{parse_spends, Condition, SpendConditionSummary}; use crate::gen::opcodes::{ ConditionOpcode, AGG_SIG_ME, AGG_SIG_UNSAFE, ASSERT_HEIGHT_ABSOLUTE, ASSERT_HEIGHT_RELATIVE, @@ -7,12 +9,10 @@ use crate::gen::opcodes::{ }; use crate::gen::validation_error::{ErrorCode, ValidationErr}; use crate::int_to_bytes::u64_to_bytes; -use crate::py::run_program::OperatorHandlerWithMode; use crate::reduction::{EvalErr, Reduction}; -use crate::run_program::{run_program, STRICT_MODE}; +use crate::run_program::STRICT_MODE; use crate::serialize::node_from_bytes; -use crate::f_table::f_lookup_for_hashmap; use crate::py::lazy_node::LazyNode; use std::collections::HashMap; @@ -215,24 +215,22 @@ pub fn run_generator( flags: u32, ) -> PyResult<(Option, Vec, Cost)> { let mut allocator = Allocator::new(); - let f_lookup = f_lookup_for_hashmap(opcode_lookup_by_name); let strict: bool = (flags & STRICT_MODE) != 0; - let f = OperatorHandlerWithMode::new(f_lookup, strict); let program = node_from_bytes(&mut allocator, program)?; let args = node_from_bytes(&mut allocator, args)?; + let dialect = Dialect::new( + &[quote_kw], + &[apply_kw], + Box::new(OperatorHandlerWithMode::new_with_hashmap( + opcode_lookup_by_name, + strict, + )), + ); let r = py.allow_threads( || -> Result<(Option, Cost, Vec), EvalErr> { - let Reduction(cost, node) = run_program( - &mut allocator, - program, - args, - &[quote_kw], - &[apply_kw], - max_cost, - &f, - None, - )?; + let Reduction(cost, node) = + dialect.run_program(&mut allocator, program, args, max_cost)?; // we pass in what's left of max_cost here, to fail early in case the // cost of a condition brings us over the cost limit match parse_spends(&allocator, node, max_cost - cost, flags) { diff --git a/src/py/run_program.rs b/src/py/run_program.rs index c4a87897..7b428fc4 100644 --- a/src/py/run_program.rs +++ b/src/py/run_program.rs @@ -1,56 +1,18 @@ use std::collections::HashMap; use std::rc::Rc; -use crate::allocator::{Allocator, NodePtr}; +use crate::allocator::Allocator; +use crate::chia_dialect::OperatorHandlerWithMode; use crate::cost::Cost; -use crate::err_utils::err; -use crate::f_table::{f_lookup_for_hashmap, FLookup}; -use crate::more_ops::op_unknown; +use crate::dialect::Dialect; use crate::node::Node; use crate::py::lazy_node::LazyNode; -use crate::reduction::Response; -use crate::run_program::{run_program, OperatorHandler, STRICT_MODE}; +use crate::run_program::STRICT_MODE; use crate::serialize::{node_from_bytes, node_to_bytes, serialized_length_from_bytes}; use pyo3::prelude::*; use pyo3::types::{PyBytes, PyDict}; -pub struct OperatorHandlerWithMode { - f_lookup: FLookup, - strict: bool, -} - -impl OperatorHandlerWithMode { - pub fn new(l: FLookup, strict: bool) -> OperatorHandlerWithMode { - OperatorHandlerWithMode { - f_lookup: l, - strict, - } - } -} - -impl OperatorHandler for OperatorHandlerWithMode { - fn op( - &self, - allocator: &mut Allocator, - o: NodePtr, - argument_list: NodePtr, - max_cost: Cost, - ) -> Response { - let b = &allocator.atom(o); - if b.len() == 1 { - if let Some(f) = self.f_lookup[b[0] as usize] { - return f(allocator, argument_list, max_cost); - } - } - if self.strict { - err(o, "unimplemented operator") - } else { - op_unknown(allocator, o, argument_list, max_cost) - } - } -} - #[pyfunction] pub fn serialize_and_run_program( py: Python, @@ -125,24 +87,19 @@ pub fn deserialize_and_run_program( flags: u32, ) -> PyResult<(Cost, Py)> { let mut allocator = Allocator::new(); - let f_lookup = f_lookup_for_hashmap(opcode_lookup_by_name); let strict: bool = (flags & STRICT_MODE) != 0; - let f = OperatorHandlerWithMode { f_lookup, strict }; + let dialect = Dialect::new( + &[quote_kw], + &[apply_kw], + Box::new(OperatorHandlerWithMode::new_with_hashmap( + opcode_lookup_by_name, + strict, + )), + ); let program = node_from_bytes(&mut allocator, program)?; let args = node_from_bytes(&mut allocator, args)?; - let r = py.allow_threads(|| { - run_program( - &mut allocator, - program, - args, - &[quote_kw], - &[apply_kw], - max_cost, - &f, - None, - ) - }); + let r = py.allow_threads(|| dialect.run_program(&mut allocator, program, args, max_cost)); match r { Ok(reduction) => { let node_as_blob = node_to_bytes(&Node::new(&allocator, reduction.1))?; @@ -192,24 +149,19 @@ pub fn deserialize_and_run_program2( flags: u32, ) -> PyResult<(Cost, LazyNode)> { let mut allocator = Allocator::new(); - let f_lookup = f_lookup_for_hashmap(opcode_lookup_by_name); let strict: bool = (flags & STRICT_MODE) != 0; - let f = OperatorHandlerWithMode { f_lookup, strict }; let program = node_from_bytes(&mut allocator, program)?; let args = node_from_bytes(&mut allocator, args)?; + let dialect = Dialect::new( + &[quote_kw], + &[apply_kw], + Box::new(OperatorHandlerWithMode::new_with_hashmap( + opcode_lookup_by_name, + strict, + )), + ); - let r = py.allow_threads(|| { - run_program( - &mut allocator, - program, - args, - &[quote_kw], - &[apply_kw], - max_cost, - &f, - None, - ) - }); + let r = py.allow_threads(|| dialect.run_program(&mut allocator, program, args, max_cost)); match r { Ok(reduction) => { let val = LazyNode::new(Rc::new(allocator), reduction.1); diff --git a/src/run_program.rs b/src/run_program.rs index abf2f9f5..83514e99 100644 --- a/src/run_program.rs +++ b/src/run_program.rs @@ -19,7 +19,7 @@ const TRAVERSE_BASE_COST: Cost = 40; const TRAVERSE_COST_PER_ZERO_BYTE: Cost = 4; const TRAVERSE_COST_PER_BIT: Cost = 4; -pub trait OperatorHandler { +pub trait OperatorHandler: Sync { fn op(&self, allocator: &mut Allocator, op: NodePtr, args: NodePtr, max_cost: Cost) -> Response; }