From c74cdd99f4409f27c72850b6ea4d1aa9c241209e Mon Sep 17 00:00:00 2001 From: Ivan Boldyrev Date: Mon, 29 Jan 2024 17:13:17 +0100 Subject: [PATCH] Sketch of Rc JSON value --- Cargo.lock | 5 ++ air/Cargo.toml | 1 + .../execution_step/errors/catchable_errors.rs | 2 +- .../execution_context/cid_state.rs | 6 +- .../instruction_error/errors_utils.rs | 6 +- .../instruction_error_definition.rs | 9 ++- .../last_error_descriptor.rs | 4 +- .../execution_context/scalar_variables.rs | 8 +- .../scalar_variables/values_sparse_matrix.rs | 3 +- .../stream_maps_variables.rs | 2 +- .../stream_maps_variables/stream_map_key.rs | 59 ++++++-------- air/src/execution_step/instructions/ap.rs | 2 - .../instructions/ap/apply_to_arguments.rs | 18 ++--- air/src/execution_step/instructions/ap_map.rs | 6 +- .../instructions/call/call_result_setter.rs | 2 +- .../instructions/call/prev_result_handler.rs | 7 +- .../instructions/call/resolved_call.rs | 5 +- .../instructions/call/triplet.rs | 2 +- .../instructions/canon_stream_map_scalar.rs | 4 +- air/src/execution_step/instructions/fail.rs | 10 +-- .../execution_step/instructions/fold/utils.rs | 15 ++-- .../execution_step/lambda_applier/applier.rs | 80 +++++++++---------- .../execution_step/lambda_applier/utils.rs | 6 +- .../resolver/resolvable_impl.rs | 16 ++-- .../value_types/canon_stream.rs | 7 +- .../value_types/canon_stream_map.rs | 35 ++++---- .../execution_step/value_types/iterable.rs | 5 +- .../value_types/iterable/resolved_call.rs | 6 +- .../execution_step/value_types/jvaluable.rs | 7 +- .../value_types/jvaluable/canon_stream.rs | 15 ++-- .../value_types/jvaluable/canon_stream_map.rs | 16 ++-- .../cell_vec_resolved_call_result.rs | 19 ++--- .../value_types/jvaluable/iterable_item.rs | 19 ++--- .../jvaluable/resolved_call_result.rs | 15 ++-- air/src/execution_step/value_types/scalar.rs | 8 +- .../value_types/scalar/values.rs | 12 +-- .../execution_step/value_types/stream_map.rs | 37 ++++----- air/src/lib.rs | 2 +- avm/interface/src/call_request_parameters.rs | 1 + crates/air-lib/air-parser/Cargo.toml | 1 + .../src/ast/instruction_arguments/traits.rs | 9 +++ crates/air-lib/interpreter-data/Cargo.toml | 1 + .../interpreter-data/src/executed_state.rs | 2 +- crates/air-lib/interpreter-data/src/lib.rs | 2 +- .../air-lib/interpreter-data/src/raw_value.rs | 7 +- .../air-lib/interpreter-interface/Cargo.toml | 1 + .../src/call_request_parameters.rs | 9 ++- crates/air-lib/interpreter-value/src/lib.rs | 2 + .../interpreter-value/src/value/from.rs | 16 ++++ crates/air-lib/test-utils/Cargo.toml | 1 + .../air-lib/test-utils/src/call_services.rs | 10 +-- .../air-lib/test-utils/src/executed_state.rs | 14 ++-- crates/air-lib/test-utils/src/lib.rs | 2 +- crates/testing-framework/src/execution/mod.rs | 2 +- junk/gen-bench-data/src/dashboard.rs | 1 + 55 files changed, 285 insertions(+), 277 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fe49efe5..f161836b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -174,6 +174,7 @@ dependencies = [ "air-interpreter-cid", "air-interpreter-sede", "air-interpreter-signatures", + "air-interpreter-value", "air-utils", "aquavm-air-parser", "fluence-keypair", @@ -196,6 +197,7 @@ name = "air-interpreter-interface" version = "0.17.2" dependencies = [ "air-interpreter-sede", + "air-interpreter-value", "fluence-it-types", "marine-call-parameters", "marine-rs-sdk", @@ -275,6 +277,7 @@ dependencies = [ "air-interpreter-interface", "air-interpreter-sede", "air-interpreter-signatures", + "air-interpreter-value", "aquavm-air", "avm-interface", "avm-server", @@ -430,6 +433,7 @@ dependencies = [ "air-interpreter-interface", "air-interpreter-sede", "air-interpreter-signatures", + "air-interpreter-value", "air-lambda-ast", "air-lambda-parser", "air-log-targets", @@ -499,6 +503,7 @@ dependencies = [ name = "aquavm-air-parser" version = "0.11.1" dependencies = [ + "air-interpreter-value", "air-lambda-ast", "air-lambda-parser", "codespan", diff --git a/air/Cargo.toml b/air/Cargo.toml index bebf58b5..a4336431 100644 --- a/air/Cargo.toml +++ b/air/Cargo.toml @@ -22,6 +22,7 @@ air-interpreter-cid = { version = "0.9.0", path = "../crates/air-lib/interpreter air-interpreter-data = { version = "0.17.0", path = "../crates/air-lib/interpreter-data" } air-interpreter-sede = { version = "0.1.0", path = "../crates/air-lib/interpreter-sede" } air-interpreter-signatures = { version = "0.1.7", path = "../crates/air-lib/interpreter-signatures", features = ["rkyv"] } +air-interpreter-value = { version = "0.1.0", path = "../crates/air-lib/interpreter-value" } air-interpreter-interface = { version = "0.17.2", path = "../crates/air-lib/interpreter-interface", default-features = false } air-log-targets = { version = "0.1.0", path = "../crates/air-lib/log-targets" } air-lambda-ast = { version = "0.1.0", path = "../crates/air-lib/lambda/ast" } diff --git a/air/src/execution_step/errors/catchable_errors.rs b/air/src/execution_step/errors/catchable_errors.rs index c25cb5c8..20e15dd3 100644 --- a/air/src/execution_step/errors/catchable_errors.rs +++ b/air/src/execution_step/errors/catchable_errors.rs @@ -69,7 +69,7 @@ pub enum CatchableError { /// This error type is produced by a fail instruction. #[error("fail with '{error}' is used without corresponding xor")] - UserError { error: Rc }, + UserError { error: JValue }, /// An error occurred while trying to apply lambda to a value. #[error(transparent)] diff --git a/air/src/execution_step/execution_context/cid_state.rs b/air/src/execution_step/execution_context/cid_state.rs index 39ee54ee..27960505 100644 --- a/air/src/execution_step/execution_context/cid_state.rs +++ b/air/src/execution_step/execution_context/cid_state.rs @@ -69,7 +69,7 @@ impl ExecutionCidState { pub fn track_service_result( &mut self, - value: Rc, + value: JValue, tetraplet: RcSecurityTetraplet, argument_hash: Rc, ) -> Result, UncatchableError> { @@ -97,7 +97,7 @@ impl ExecutionCidState { .map_err(UncatchableError::from) } - pub(crate) fn get_value_by_cid(&self, cid: &CID) -> Result, UncatchableError> { + pub(crate) fn get_value_by_cid(&self, cid: &CID) -> Result { self.value_tracker .get(cid) .ok_or_else(|| UncatchableError::ValueForCidNotFound("value", cid.get_inner())) @@ -168,7 +168,7 @@ impl ExecutionCidState { } pub(crate) struct ResolvedServiceInfo { - pub(crate) value: Rc, + pub(crate) value: JValue, pub(crate) tetraplet: RcSecurityTetraplet, pub(crate) service_result_aggregate: Rc, } diff --git a/air/src/execution_step/execution_context/instruction_error/errors_utils.rs b/air/src/execution_step/execution_context/instruction_error/errors_utils.rs index 6f3fda72..deff08d6 100644 --- a/air/src/execution_step/execution_context/instruction_error/errors_utils.rs +++ b/air/src/execution_step/execution_context/instruction_error/errors_utils.rs @@ -24,8 +24,6 @@ use crate::execution_step::RcSecurityTetraplet; use crate::JValue; use crate::ToErrorCode; -use std::rc::Rc; - pub(crate) fn get_instruction_error_from_exec_error( error: &(impl ErrorAffectable + ToErrorCode + ToString), instruction: &str, @@ -57,11 +55,11 @@ pub(crate) fn get_instruction_error_from_ingredients( Some(peer_id) => error_from_raw_fields_w_peerid(error_code, error_message, instruction, peer_id), None => error_from_raw_fields(error_code, error_message, instruction), }; - get_instruction_error_from_error_object(Rc::new(error_object), tetraplet, provenance) + get_instruction_error_from_error_object(error_object, tetraplet, provenance) } pub(crate) fn get_instruction_error_from_error_object( - error: Rc, + error: JValue, tetraplet: Option, provenance: Provenance, ) -> InstructionError { diff --git a/air/src/execution_step/execution_context/instruction_error/instruction_error_definition.rs b/air/src/execution_step/execution_context/instruction_error/instruction_error_definition.rs index 8ae609fb..6abce6ed 100644 --- a/air/src/execution_step/execution_context/instruction_error/instruction_error_definition.rs +++ b/air/src/execution_step/execution_context/instruction_error/instruction_error_definition.rs @@ -22,8 +22,6 @@ use crate::JValue; use air_interpreter_data::Provenance; use serde_json::json; -use std::rc::Rc; - pub const ERROR_CODE_FIELD_NAME: &str = "error_code"; pub const MESSAGE_FIELD_NAME: &str = "message"; pub const INSTRUCTION_FIELD_NAME: &str = "instruction"; @@ -39,7 +37,7 @@ pub const NO_ERROR_ERROR_CODE: i64 = 0; #[derive(Debug, Clone)] pub struct InstructionError { /// Error object that represents the last occurred error. - pub error: Rc, + pub error: JValue, /// Tetraplet that identify host where the error occurred. pub tetraplet: Option, @@ -64,6 +62,7 @@ pub(crate) fn error_from_raw_fields_w_peerid( INSTRUCTION_FIELD_NAME: instruction, PEER_ID_FIELD_NAME: peer_id, }) + .into() } pub(crate) fn error_from_raw_fields(error_code: i64, error_message: &str, instruction: &str) -> JValue { @@ -72,6 +71,7 @@ pub(crate) fn error_from_raw_fields(error_code: i64, error_message: &str, instru MESSAGE_FIELD_NAME: error_message, INSTRUCTION_FIELD_NAME: instruction, }) + .into() } /// Checks that a scalar is a value of an object types that contains at least two fields: @@ -142,11 +142,12 @@ pub fn no_error_object() -> JValue { ERROR_CODE_FIELD_NAME: NO_ERROR_ERROR_CODE, MESSAGE_FIELD_NAME: NO_ERROR_MESSAGE, }) + .into() } pub fn no_error() -> InstructionError { InstructionError { - error: Rc::new(no_error_object()), + error: no_error_object(), tetraplet: None, provenance: Provenance::literal(), orig_catchable: None, diff --git a/air/src/execution_step/execution_context/instruction_error/last_error_descriptor.rs b/air/src/execution_step/execution_context/instruction_error/last_error_descriptor.rs index 83ae2518..6110aff8 100644 --- a/air/src/execution_step/execution_context/instruction_error/last_error_descriptor.rs +++ b/air/src/execution_step/execution_context/instruction_error/last_error_descriptor.rs @@ -23,8 +23,6 @@ use crate::execution_step::RcSecurityTetraplet; use crate::JValue; use crate::ToErrorCode; -use std::rc::Rc; - pub(crate) struct LastErrorDescriptor { error: InstructionError, @@ -56,7 +54,7 @@ impl LastErrorDescriptor { pub(crate) fn set_from_error_object( &mut self, - error: Rc, + error: JValue, tetraplet: Option, provenance: Provenance, ) { diff --git a/air/src/execution_step/execution_context/scalar_variables.rs b/air/src/execution_step/execution_context/scalar_variables.rs index 25e00f70..659aa031 100644 --- a/air/src/execution_step/execution_context/scalar_variables.rs +++ b/air/src/execution_step/execution_context/scalar_variables.rs @@ -89,7 +89,7 @@ pub(crate) struct Scalars<'i> { pub(crate) canon_streams: ValuesSparseMatrix, - pub(crate) canon_maps: ValuesSparseMatrix>, + pub(crate) canon_maps: ValuesSparseMatrix, pub(crate) iterable_variables: HashMap>, } @@ -122,10 +122,10 @@ impl<'i> Scalars<'i> { /// Returns true if there was a previous value for the provided key on the same /// fold block. - pub(crate) fn set_canon_map_value<'k: 'i>( + pub(crate) fn set_canon_map_value( &mut self, name: impl Into, - value: CanonStreamMapWithProvenance<'k>, + value: CanonStreamMapWithProvenance, ) -> ExecutionResult { self.canon_maps.set_value(name, value) } @@ -172,7 +172,7 @@ impl<'i> Scalars<'i> { .ok_or_else(|| CatchableError::VariableWasNotInitializedAfterNew(name.to_string()).into()) } - pub(crate) fn get_canon_map(&'i self, name: &str) -> ExecutionResult<&'i CanonStreamMapWithProvenance<'i>> { + pub(crate) fn get_canon_map(&'i self, name: &str) -> ExecutionResult<&'i CanonStreamMapWithProvenance> { self.canon_maps .get_value(name)? .ok_or_else(|| CatchableError::VariableWasNotInitializedAfterNew(name.to_string()).into()) diff --git a/air/src/execution_step/execution_context/scalar_variables/values_sparse_matrix.rs b/air/src/execution_step/execution_context/scalar_variables/values_sparse_matrix.rs index bf0f1d3e..e0947e4c 100644 --- a/air/src/execution_step/execution_context/scalar_variables/values_sparse_matrix.rs +++ b/air/src/execution_step/execution_context/scalar_variables/values_sparse_matrix.rs @@ -293,8 +293,7 @@ mod test { let mut scalars = ValuesSparseMatrix::new(); let value = json!(1u64); - let rc_value = Rc::new(value); - let value_aggregate = ValueAggregate::from_literal_result(LiteralAggregate::new(rc_value, "".into(), 1.into())); + let value_aggregate = ValueAggregate::from_literal_result(LiteralAggregate::new(value, "".into(), 1.into())); let value_1_name = "name_1"; scalars.set_value(value_1_name, value_aggregate.clone()).unwrap(); diff --git a/air/src/execution_step/execution_context/stream_maps_variables.rs b/air/src/execution_step/execution_context/stream_maps_variables.rs index 40cf2f12..dfae6b20 100644 --- a/air/src/execution_step/execution_context/stream_maps_variables.rs +++ b/air/src/execution_step/execution_context/stream_maps_variables.rs @@ -118,7 +118,7 @@ impl StreamMaps { pub(crate) fn add_stream_map_value( &mut self, - key: StreamMapKey<'_>, + key: StreamMapKey, value_descriptor: StreamMapValueDescriptor<'_>, ) -> ExecutionResult<()> { let StreamMapValueDescriptor { diff --git a/air/src/execution_step/execution_context/stream_maps_variables/stream_map_key.rs b/air/src/execution_step/execution_context/stream_maps_variables/stream_map_key.rs index 7dfc79f7..6eaadfb1 100644 --- a/air/src/execution_step/execution_context/stream_maps_variables/stream_map_key.rs +++ b/air/src/execution_step/execution_context/stream_maps_variables/stream_map_key.rs @@ -17,8 +17,7 @@ use crate::execution_step::ValueAggregate; use crate::JValue; -use serde::Serialize; -use std::borrow::Cow; +use air_interpreter_value::JsonString; use std::fmt::Display; use std::fmt::Formatter; @@ -27,25 +26,25 @@ pub(crate) static KEY_FIELD_NAME: &str = "key"; // TODO refactor the keys so that integer and string // value domains overlap would become impossible or less harmful. #[derive(Clone, PartialEq, Debug, Eq, Hash)] -pub(crate) enum StreamMapKey<'value> { - Str(Cow<'value, str>), +pub(crate) enum StreamMapKey { + Str(JsonString), U64(u64), I64(i64), } -impl<'value> StreamMapKey<'value> { +impl StreamMapKey { pub fn from_value(value: JValue) -> Option { match value { - JValue::String(s) => Some(StreamMapKey::Str(Cow::Owned(s))), + JValue::String(s) => Some(StreamMapKey::Str(s)), JValue::Number(n) if n.is_i64() => Some(StreamMapKey::I64(n.as_i64().unwrap())), JValue::Number(n) if n.is_u64() => Some(StreamMapKey::U64(n.as_u64().unwrap())), _ => None, } } - pub fn from_value_ref(value: &'value JValue) -> Option { + pub fn from_value_ref(value: &JValue) -> Option { match value { - JValue::String(s) => Some(StreamMapKey::Str(Cow::Borrowed(s.as_str()))), + JValue::String(s) => Some(StreamMapKey::Str(s.clone())), JValue::Number(n) if n.is_i64() => Some(StreamMapKey::I64(n.as_i64().unwrap())), JValue::Number(n) if n.is_u64() => Some(StreamMapKey::U64(n.as_u64().unwrap())), _ => None, @@ -58,25 +57,22 @@ impl<'value> StreamMapKey<'value> { StreamMapKey::from_value(key) } - pub(crate) fn into_owned(self) -> StreamMapKey<'static> { + pub(crate) fn to_key(&self) -> JsonString { match self { - StreamMapKey::Str(s) => { - let s = s.to_string(); - StreamMapKey::Str(Cow::Owned(s)) - } - StreamMapKey::U64(n) => StreamMapKey::U64(n), - StreamMapKey::I64(n) => StreamMapKey::I64(n), + StreamMapKey::Str(s) => s.clone(), + StreamMapKey::U64(n) => format!("{n}").into(), + StreamMapKey::I64(n) => format!("{n}").into(), } } } -impl From for StreamMapKey<'_> { +impl From for StreamMapKey { fn from(value: i64) -> Self { StreamMapKey::I64(value) } } -impl From for StreamMapKey<'_> { +impl From for StreamMapKey { fn from(value: u64) -> Self { StreamMapKey::U64(value) } @@ -85,40 +81,37 @@ impl From for StreamMapKey<'_> { // TODO unify all types. // This conversion is used to cast from numeric lambda accessor that leverages u32 // however larpop parser grammar uses i64 for numeric keys inserting into a stream map. -impl From for StreamMapKey<'_> { +impl From for StreamMapKey { fn from(value: u32) -> Self { StreamMapKey::I64(value.into()) } } -impl<'value> From<&'value str> for StreamMapKey<'value> { - fn from(value: &'value str) -> Self { - StreamMapKey::Str(Cow::Borrowed(value)) +impl From<&str> for StreamMapKey { + fn from(value: &str) -> Self { + StreamMapKey::Str(value.into()) } } -impl From for StreamMapKey<'static> { - fn from(value: String) -> Self { - StreamMapKey::Str(Cow::Owned(value)) +impl From for StreamMapKey { + fn from(value: JsonString) -> Self { + StreamMapKey::Str(value) } } -impl<'value> Serialize for StreamMapKey<'value> { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { +impl Into for StreamMapKey { + fn into(self) -> JValue { match self { - StreamMapKey::Str(s) => serializer.serialize_str(s), - StreamMapKey::U64(n) => serializer.serialize_u64(*n), - StreamMapKey::I64(n) => serializer.serialize_i64(*n), + StreamMapKey::Str(s) => JValue::String(s), + StreamMapKey::U64(n) => n.into(), + StreamMapKey::I64(n) => n.into(), } } } // This trait impl proposefully prints numbers the same way as strings // to use it in map-to-scalar cast. -impl<'value> Display for StreamMapKey<'value> { +impl Display for StreamMapKey { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { StreamMapKey::Str(s) => write!(f, "{}", s), diff --git a/air/src/execution_step/instructions/ap.rs b/air/src/execution_step/instructions/ap.rs index 39c7cbc5..7a7d5c71 100644 --- a/air/src/execution_step/instructions/ap.rs +++ b/air/src/execution_step/instructions/ap.rs @@ -34,8 +34,6 @@ use air_parser::ast; use air_parser::ast::Ap; use air_trace_handler::merger::MergerApResult; -use std::rc::Rc; - impl<'i> super::ExecutableInstruction<'i> for Ap<'i> { #[tracing::instrument(level = "debug", skip(exec_ctx, trace_ctx))] fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, trace_ctx: &mut TraceHandler) -> ExecutionResult<()> { diff --git a/air/src/execution_step/instructions/ap/apply_to_arguments.rs b/air/src/execution_step/instructions/ap/apply_to_arguments.rs index 8588fc99..26f2d80c 100644 --- a/air/src/execution_step/instructions/ap/apply_to_arguments.rs +++ b/air/src/execution_step/instructions/ap/apply_to_arguments.rs @@ -61,7 +61,7 @@ fn apply_const( exec_ctx: &ExecutionCtx<'_>, trace_ctx: &TraceHandler, ) -> ExecutionResult { - let value = Rc::new(value.into()); + let value = value.into(); let position = trace_ctx.trace_pos().map_err(UncatchableError::from)?; let value = ValueAggregate::from_literal_result(LiteralAggregate::new( @@ -78,7 +78,6 @@ fn apply_error<'ctx>( trace_ctx: &TraceHandler, ) -> ExecutionResult { let (value, mut tetraplets, provenance) = instruction_error.resolve(exec_ctx)?; - let value = Rc::new(value); // removing is safe because prepare_last_error always returns a vec with one element. let tetraplet = tetraplets.remove(0); let position = trace_ctx.trace_pos().map_err(UncatchableError::from)?; @@ -93,7 +92,6 @@ fn apply_last_error<'i>( trace_ctx: &TraceHandler, ) -> ExecutionResult { let (value, mut tetraplets, provenance) = error_accessor.resolve(exec_ctx)?; - let value = Rc::new(value); // removing is safe because prepare_last_error always returns a vec with one element. let tetraplet = tetraplets.remove(0); let position = trace_ctx.trace_pos().map_err(UncatchableError::from)?; @@ -134,7 +132,7 @@ fn apply_scalar_wl( ) -> ExecutionResult { let (value, mut tetraplets, provenance) = ast_scalar.resolve(exec_ctx)?; let position = trace_ctx.trace_pos().map_err(UncatchableError::from)?; - let result = ValueAggregate::new(Rc::new(value), tetraplets.remove(0), position, provenance); + let result = ValueAggregate::new(value, tetraplets.remove(0), position, provenance); Ok(result) } @@ -148,11 +146,11 @@ fn apply_canon_stream( use crate::execution_step::value_types::JValuable; let canon_stream = exec_ctx.scalars.get_canon_stream(ast_stream.name)?; - let value = JValuable::as_jvalue(&&canon_stream.canon_stream).into_owned(); + let value = JValuable::as_jvalue(&&canon_stream.canon_stream); let tetraplet = canon_stream.tetraplet().clone(); let position = trace_ctx.trace_pos().map_err(UncatchableError::from)?; let value = CanonResultAggregate::new( - Rc::new(value), + value, tetraplet.peer_pk.as_str().into(), &tetraplet.json_path, position, @@ -179,7 +177,7 @@ fn apply_canon_stream_wl( )?; let position = trace_ctx.trace_pos().map_err(UncatchableError::from)?; - let result = ValueAggregate::new(result.into_owned().into(), tetraplet.into(), position, provenance); + let result = ValueAggregate::new(result, tetraplet.into(), position, provenance); Ok(result) } @@ -191,11 +189,11 @@ fn apply_canon_stream_map( use crate::execution_step::value_types::JValuable; let canon_stream_map = exec_ctx.scalars.get_canon_map(ast_canon_stream_map.name)?; - let value = JValuable::as_jvalue(&&canon_stream_map.canon_stream_map).into_owned(); + let value = JValuable::as_jvalue(&&canon_stream_map.canon_stream_map); let tetraplet = canon_stream_map.tetraplet(); let position = trace_ctx.trace_pos().map_err(UncatchableError::from)?; let value = CanonResultAggregate::new( - Rc::new(value), + value, tetraplet.peer_pk.as_str().into(), &tetraplet.json_path, position, @@ -220,6 +218,6 @@ fn apply_canon_stream_map_wl( JValuable::apply_lambda_with_tetraplets(&canon_stream_map, lambda, exec_ctx, &Provenance::canon(cid))?; let position = trace_ctx.trace_pos().map_err(UncatchableError::from)?; - let result = ValueAggregate::new(result.into_owned().into(), tetraplet.into(), position, provenance); + let result = ValueAggregate::new(result, tetraplet.into(), position, provenance); Ok(result) } diff --git a/air/src/execution_step/instructions/ap_map.rs b/air/src/execution_step/instructions/ap_map.rs index b88f2ff9..7124cf23 100644 --- a/air/src/execution_step/instructions/ap_map.rs +++ b/air/src/execution_step/instructions/ap_map.rs @@ -61,7 +61,7 @@ fn to_merger_ap_map_result(instr: &impl ToString, trace_ctx: &mut TraceHandler) } fn populate_context<'ctx>( - key: StreamMapKey<'ctx>, + key: StreamMapKey, ap_map_result: &StreamMap<'ctx>, merger_ap_result: &MergerApResult, result: ValueAggregate, @@ -75,7 +75,7 @@ fn resolve_key_if_needed<'ctx>( key: &StreamMapKeyClause<'ctx>, exec_ctx: &ExecutionCtx<'ctx>, map_name: &str, -) -> Result, ExecutionError> { +) -> Result { match key { &StreamMapKeyClause::Literal(s) => Ok(s.into()), StreamMapKeyClause::Int(i) => Ok(i.to_owned().into()), @@ -89,7 +89,7 @@ fn resolve<'ctx>( resolvable: &impl Resolvable, exec_ctx: &ExecutionCtx<'_>, map_name: &str, -) -> Result, ExecutionError> { +) -> Result { let (value, _, _) = resolvable.resolve(exec_ctx)?; StreamMapKey::from_value(value).ok_or(CatchableError::StreamMapError(unsupported_map_key_type(map_name)).into()) } diff --git a/air/src/execution_step/instructions/call/call_result_setter.rs b/air/src/execution_step/instructions/call/call_result_setter.rs index d0c26d43..61dd8b19 100644 --- a/air/src/execution_step/instructions/call/call_result_setter.rs +++ b/air/src/execution_step/instructions/call/call_result_setter.rs @@ -65,7 +65,7 @@ pub(crate) fn populate_context_from_peer_service_result<'i>( Ok(CallResult::executed_stream_stub(service_result_agg_cid)) } CallOutputValue::None => { - let value_cid = value_to_json_cid(&*executed_result.result).map_err(UncatchableError::from)?; + let value_cid = value_to_json_cid(&executed_result.result).map_err(UncatchableError::from)?; Ok(CallResult::executed_unused(value_cid)) } diff --git a/air/src/execution_step/instructions/call/prev_result_handler.rs b/air/src/execution_step/instructions/call/prev_result_handler.rs index 5b05cfd1..6400771d 100644 --- a/air/src/execution_step/instructions/call/prev_result_handler.rs +++ b/air/src/execution_step/instructions/call/prev_result_handler.rs @@ -68,7 +68,8 @@ pub(super) fn handle_prev_state<'i>( )?; let call_service_failed: CallServiceFailed = - serde_json::from_value((*err_value).clone()).map_err(UncatchableError::MalformedCallServiceFailed)?; + serde_json::from_value(serde_json::to_value(&err_value).expect("TODO")) + .map_err(UncatchableError::MalformedCallServiceFailed)?; exec_ctx.make_subgraph_incomplete(); exec_ctx.record_call_cid(&tetraplet.peer_pk, failed_cid); @@ -212,9 +213,9 @@ fn try_to_service_result( tetraplet: &RcSecurityTetraplet, exec_ctx: &mut ExecutionCtx<'_>, trace_ctx: &mut TraceHandler, -) -> ExecutionResult> { +) -> ExecutionResult { match serde_json::from_str(&service_result.result) { - Ok(result) => Ok(Rc::new(result)), + Ok(result) => Ok(result), Err(e) => { let error_msg = format!( "call_service result '{service_result}' can't be serialized or deserialized with an error: {e}" diff --git a/air/src/execution_step/instructions/call/resolved_call.rs b/air/src/execution_step/instructions/call/resolved_call.rs index 60152739..5b20889f 100644 --- a/air/src/execution_step/instructions/call/resolved_call.rs +++ b/air/src/execution_step/instructions/call/resolved_call.rs @@ -25,6 +25,7 @@ use crate::execution_step::RcSecurityTetraplet; use crate::execution_step::RcSecurityTetraplets; use crate::execution_step::UncatchableError; use crate::trace_to_exec_err; +use crate::JValue; use crate::SecurityTetraplet; use air_interpreter_cid::value_to_json_cid; @@ -220,7 +221,7 @@ impl<'i> ResolvedCall<'i> { } /// A version of `resolve_args` that supresses joinable errors. - fn check_args(&self, exec_ctx: &ExecutionCtx<'i>) -> ExecutionResult>> { + fn check_args(&self, exec_ctx: &ExecutionCtx<'i>) -> ExecutionResult>> { let fun_result = self.collect_args(exec_ctx); CheckArgsResult::new(fun_result.map(|values| values.0)) @@ -229,7 +230,7 @@ impl<'i> ResolvedCall<'i> { fn collect_args( &self, exec_ctx: &ExecutionCtx<'i>, - ) -> ExecutionResult<(Vec, Vec)> { + ) -> ExecutionResult<(Vec, Vec)> { let function_args = self.function_arg_paths.iter(); let mut call_arguments = Vec::with_capacity(function_args.len()); let mut tetraplets = Vec::with_capacity(function_args.len()); diff --git a/air/src/execution_step/instructions/call/triplet.rs b/air/src/execution_step/instructions/call/triplet.rs index ad38dd44..a9b3cb1e 100644 --- a/air/src/execution_step/instructions/call/triplet.rs +++ b/air/src/execution_step/instructions/call/triplet.rs @@ -85,7 +85,7 @@ pub(crate) fn resolve_to_string<'i>( fn try_jvalue_to_string(jvalue: JValue, variable_name: impl Into) -> ExecutionResult { match jvalue { - JValue::String(s) => Ok(s), + JValue::String(s) => Ok(s.to_string()), _ => Err(CatchableError::NonStringValueInTripletResolution { variable_name: variable_name.into(), actual_value: jvalue, diff --git a/air/src/execution_step/instructions/canon_stream_map_scalar.rs b/air/src/execution_step/instructions/canon_stream_map_scalar.rs index d203ad4c..82b00321 100644 --- a/air/src/execution_step/instructions/canon_stream_map_scalar.rs +++ b/air/src/execution_step/instructions/canon_stream_map_scalar.rs @@ -114,10 +114,10 @@ fn create_canon_stream_producer<'closure, 'name: 'closure>( let value = stream_map .iter_unique_key_object() - .collect::>(); + .collect(); let value = ValueAggregate::from_literal_result(LiteralAggregate::new( - Rc::new(value.into()), + JValue::Object(Rc::new(value)), peer_pk.as_str().into(), 0.into(), )); diff --git a/air/src/execution_step/instructions/fail.rs b/air/src/execution_step/instructions/fail.rs index 8a095459..e9946237 100644 --- a/air/src/execution_step/instructions/fail.rs +++ b/air/src/execution_step/instructions/fail.rs @@ -57,7 +57,7 @@ fn fail_with_scalar<'i>(scalar: &ast::Scalar<'i>, exec_ctx: &mut ExecutionCtx<'i let tetraplet = tetraplet.remove(0); check_error_object(&value).map_err(CatchableError::InvalidErrorObjectError)?; - fail_with_error_object(exec_ctx, Rc::new(value), Some(tetraplet), provenance) + fail_with_error_object(exec_ctx, value, Some(tetraplet), provenance) } fn fail_with_scalar_wl<'i>(scalar: &ast::ScalarWithLambda<'i>, exec_ctx: &mut ExecutionCtx<'i>) -> ExecutionResult<()> { @@ -66,7 +66,7 @@ fn fail_with_scalar_wl<'i>(scalar: &ast::ScalarWithLambda<'i>, exec_ctx: &mut Ex let tetraplet = tetraplet.remove(0); check_error_object(&value).map_err(CatchableError::InvalidErrorObjectError)?; - fail_with_error_object(exec_ctx, Rc::new(value), Some(tetraplet), provenance) + fail_with_error_object(exec_ctx, value, Some(tetraplet), provenance) } fn fail_with_literals( @@ -87,7 +87,7 @@ fn fail_with_literals( // in (fail x y), x and y are always literals let provenance = Provenance::literal(); - fail_with_error_object(exec_ctx, Rc::new(error_object), Some(literal_tetraplet), provenance) + fail_with_error_object(exec_ctx, error_object, Some(literal_tetraplet), provenance) } fn fail_with_canon_stream( @@ -99,7 +99,7 @@ fn fail_with_canon_stream( // tetraplets always have one element here and it'll be refactored after boxed value check_error_object(&value).map_err(CatchableError::InvalidErrorObjectError)?; - fail_with_error_object(exec_ctx, Rc::new(value), Some(tetraplets.remove(0)), provenance) + fail_with_error_object(exec_ctx, value, Some(tetraplets.remove(0)), provenance) } fn fail_with_last_error(exec_ctx: &mut ExecutionCtx<'_>) -> ExecutionResult<()> { @@ -147,7 +147,7 @@ fn fail_with_error(exec_ctx: &mut ExecutionCtx<'_>) -> ExecutionResult<()> { fn fail_with_error_object( exec_ctx: &mut ExecutionCtx<'_>, - error: Rc, + error: JValue, tetraplet: Option, provenance: Provenance, ) -> ExecutionResult<()> { diff --git a/air/src/execution_step/instructions/fold/utils.rs b/air/src/execution_step/instructions/fold/utils.rs index 549c556e..1df4a4f4 100644 --- a/air/src/execution_step/instructions/fold/utils.rs +++ b/air/src/execution_step/instructions/fold/utils.rs @@ -26,7 +26,6 @@ use crate::SecurityTetraplet; use air_interpreter_data::Provenance; use air_parser::ast; -use std::borrow::Cow; use std::ops::Deref; use std::rc::Rc; @@ -65,7 +64,7 @@ pub(crate) fn create_scalar_wl_iterable<'ctx>( ScalarRef::Value(variable) => { let jvalues = select_by_lambda_from_scalar(variable.get_result(), lambda, exec_ctx)?; let tetraplet = variable.get_tetraplet().deref().clone(); - from_jvalue(jvalues, tetraplet, variable.get_provenance(), lambda) + from_jvalue(&jvalues, tetraplet, variable.get_provenance(), lambda) } ScalarRef::IterableValue(fold_state) => { let iterable_value = fold_state.iterable.peek().unwrap(); @@ -73,7 +72,7 @@ pub(crate) fn create_scalar_wl_iterable<'ctx>( let tetraplet = to_tetraplet(&iterable_value); let provenance = to_provenance(&iterable_value); - from_jvalue(jvalue, tetraplet, provenance, lambda) + from_jvalue(&jvalue, tetraplet, provenance, lambda) } } } @@ -132,12 +131,12 @@ pub(crate) fn create_canon_stream_map_wl_iterable_value( // Source canon map tetraplet is used here similar with a scalar with lens processing path. let jvalues = JValuable::apply_lambda(&canon_stream_map, lambda, exec_ctx)?; - from_jvalue(jvalues, tetraplet, provenance, lambda) + from_jvalue(&jvalues, tetraplet, provenance, lambda) } /// Constructs iterable value from resolved call result. fn from_value(call_result: ValueAggregate, variable_name: &str) -> ExecutionResult { - let len = match call_result.get_result().deref() { + let len = match call_result.get_result() { JValue::Array(array) => { if array.is_empty() { // skip fold if array is empty @@ -159,7 +158,7 @@ fn from_value(call_result: ValueAggregate, variable_name: &str) -> ExecutionResu /// Construct IterableValue from the result and given triplet. fn from_jvalue( - jvalue: Cow<'_, JValue>, + jvalue: &JValue, tetraplet: SecurityTetraplet, provenance: Provenance, lambda: &LambdaAST<'_>, @@ -167,10 +166,10 @@ fn from_jvalue( let tetraplet = populate_tetraplet_with_lambda(tetraplet, lambda); let tetraplet = Rc::new(tetraplet); - let iterable = match jvalue.as_ref() { + let iterable = match jvalue { JValue::Array(array) => array, _ => { - return Err(CatchableError::FoldIteratesOverNonArray(jvalue.into_owned(), lambda.to_string()).into()); + return Err(CatchableError::FoldIteratesOverNonArray(jvalue.clone(), lambda.to_string()).into()); } }; diff --git a/air/src/execution_step/lambda_applier/applier.rs b/air/src/execution_step/lambda_applier/applier.rs index ce9c7da9..62c88ba3 100644 --- a/air/src/execution_step/lambda_applier/applier.rs +++ b/air/src/execution_step/lambda_applier/applier.rs @@ -28,21 +28,20 @@ use crate::JValue; use crate::LambdaAST; use crate::SecurityTetraplet; +use air_interpreter_value::JsonString; use air_lambda_ast::Functor; use air_lambda_parser::ValueAccessor; use non_empty_vec::NonEmpty; -use std::borrow::Cow; -use std::ops::Deref; use std::rc::Rc; -pub(crate) struct LambdaResult<'value> { - pub(crate) result: Cow<'value, JValue>, +pub(crate) struct LambdaResult { + pub(crate) result: JValue, pub(crate) tetraplet_idx: Option, } -pub(crate) struct MapLensResult<'value> { - pub(crate) result: Cow<'value, JValue>, +pub(crate) struct MapLensResult { + pub(crate) result: JValue, pub(crate) tetraplet: RcSecurityTetraplet, } @@ -50,7 +49,7 @@ pub(crate) fn select_by_lambda_from_stream<'value>( stream: impl ExactSizeIterator + 'value, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>, -) -> ExecutionResult> { +) -> ExecutionResult { match lambda { LambdaAST::ValuePath(value_path) => select_by_path_from_stream(stream, value_path, exec_ctx), LambdaAST::Functor(functor) => Ok(select_by_functor_from_stream(stream, functor)), @@ -58,10 +57,10 @@ pub(crate) fn select_by_lambda_from_stream<'value>( } pub(crate) fn select_by_lambda_from_canon_map<'value>( - canon_map: &'value CanonStreamMap<'_>, + canon_map: &'value CanonStreamMap, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>, -) -> ExecutionResult> { +) -> ExecutionResult { match lambda { LambdaAST::ValuePath(value_path) => select_by_path_from_canon_map(canon_map, value_path, lambda, exec_ctx), LambdaAST::Functor(functor) => Ok(select_by_functor_from_canon_map(canon_map, exec_ctx, functor)), @@ -72,10 +71,10 @@ pub(crate) fn select_by_lambda_from_scalar<'value>( value: &'value JValue, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>, -) -> ExecutionResult> { +) -> ExecutionResult { match lambda { LambdaAST::ValuePath(value_path) => select_by_path_from_scalar(value, value_path.iter(), exec_ctx), - LambdaAST::Functor(functor) => select_by_functor_from_scalar(value, functor).map(Cow::Owned), + LambdaAST::Functor(functor) => select_by_functor_from_scalar(value, functor), } } @@ -83,7 +82,7 @@ fn select_by_path_from_stream<'value>( stream: impl ExactSizeIterator + 'value, lambda: &NonEmpty>, exec_ctx: &ExecutionCtx<'_>, -) -> ExecutionResult> { +) -> ExecutionResult { let stream_size = stream.len(); let (idx, body) = split_to_idx(lambda, exec_ctx)?; @@ -98,10 +97,10 @@ fn select_by_path_from_stream<'value>( } fn select_by_path_from_canon_map_stream<'value>( - stream: impl ExactSizeIterator + 'value, + stream: impl ExactSizeIterator + 'value, lambda: &NonEmpty>, exec_ctx: &ExecutionCtx<'_>, -) -> ExecutionResult> { +) -> ExecutionResult { let stream_size = stream.len(); let (idx, body) = split_to_idx(lambda, exec_ctx)?; @@ -112,11 +111,10 @@ fn select_by_path_from_canon_map_stream<'value>( let select_result = if body.is_empty() { // csm.$.key.[0] case - let result = Cow::Borrowed(value); - MapLensResult::from_cow(result, tetraplet) + MapLensResult::from_cow(value, tetraplet) } else { // csm.$.key.[0].attribute case - let result = select_by_path_from_scalar(value, body.iter(), exec_ctx)?; + let result = select_by_path_from_scalar(&value, body.iter(), exec_ctx)?; let joined = body.iter().map(ToString::to_string).collect::>().join("."); let json_path_suffix = format!(".{}", joined); @@ -129,22 +127,22 @@ fn select_by_path_from_canon_map_stream<'value>( } fn select_by_path_from_canon_map<'value>( - canon_map: &'value CanonStreamMap<'_>, + canon_map: &'value CanonStreamMap, lambda: &NonEmpty>, original_lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>, -) -> ExecutionResult> { +) -> ExecutionResult { use crate::execution_step::value_types::CanonStream; let (prefix, body) = lambda.split_first(); // HashMap<'map>::get(key: &'key K) forces key's lifetime 'key to be as good as 'map. - // This variance-derived requirement forces StreamMapKey<'static> here. + // This variance-derived requirement forces StreamMapKey here. // See https://github.com/rust-lang/rust/issues/80389#issuecomment-752067798 // for the details. - let stream_map_key: StreamMapKey<'_> = match prefix { + let stream_map_key: StreamMapKey = match prefix { ValueAccessor::ArrayAccess { idx } => (*idx).into(), - ValueAccessor::FieldAccessByName { field_name } => (*field_name).to_owned().into(), + ValueAccessor::FieldAccessByName { field_name } => JsonString::from(*field_name).to_owned().into(), ValueAccessor::FieldAccessByScalar { scalar_name } => { let scalar = exec_ctx.scalars.get_value(scalar_name)?; lambda_to_execution_error!(try_scalar_ref_as_stream_map_key(scalar))? @@ -158,14 +156,14 @@ fn select_by_path_from_canon_map<'value>( (Ok(body_part), Some(canon_stream)) => { // csm.$.key... case - let canon_stream_iter = canon_stream.iter().map(|v| (v.get_result().deref(), v.get_tetraplet())); + let canon_stream_iter = canon_stream.iter().map(|v| (v.get_result().clone(), v.get_tetraplet())); select_by_path_from_canon_map_stream(canon_stream_iter, &body_part, exec_ctx)? } (Err(..), Some(canon_stream)) => { // csm.$.key case let prefix_with_path = false; let tetraplet = update_tetraplet_with_path(canon_map.tetraplet(), original_lambda, prefix_with_path); - let value = Cow::Owned(canon_stream.as_jvalue()); + let value = canon_stream.as_jvalue(); MapLensResult::from_cow(value, tetraplet) } @@ -174,7 +172,6 @@ fn select_by_path_from_canon_map<'value>( let prefix_with_path = false; let tetraplet = update_tetraplet_with_path(canon_map.tetraplet(), original_lambda, prefix_with_path); let value = CanonStream::new(vec![], tetraplet.clone()).as_jvalue(); - let value = Cow::Owned(value); MapLensResult::from_cow(value, tetraplet) } @@ -225,23 +222,23 @@ fn update_tetraplet_with_path( fn select_by_functor_from_stream<'value>( stream: impl ExactSizeIterator + 'value, functor: &Functor, -) -> LambdaResult<'value> { +) -> LambdaResult { match functor { Functor::Length => { - let result = serde_json::json!(stream.len()); + let result = (stream.len()).into(); LambdaResult::from_value(result) } } } -fn select_by_functor_from_canon_map<'value>( - canon_map: &CanonStreamMap<'_>, +fn select_by_functor_from_canon_map( + canon_map: &CanonStreamMap, exec_ctx: &ExecutionCtx<'_>, functor: &Functor, -) -> MapLensResult<'value> { +) -> MapLensResult { match functor { Functor::Length => { - let result = serde_json::json!(canon_map.len()); + let result = (canon_map.len()).into(); MapLensResult::from_value(result, exec_ctx, functor) } } @@ -251,7 +248,7 @@ fn select_by_path_from_scalar<'value, 'accessor>( mut value: &'value JValue, lambda: impl Iterator>, exec_ctx: &ExecutionCtx<'_>, -) -> ExecutionResult> { +) -> ExecutionResult { for accessor in lambda { match accessor { ValueAccessor::ArrayAccess { idx } => { @@ -268,7 +265,7 @@ fn select_by_path_from_scalar<'value, 'accessor>( } } - Ok(Cow::Borrowed(value)) + Ok(value.clone()) } fn select_by_functor_from_scalar(value: &JValue, functor: &Functor) -> ExecutionResult { @@ -280,13 +277,14 @@ fn select_by_functor_from_scalar(value: &JValue, functor: &Functor) -> Execution ExecutionError::Catchable(Rc::new(CatchableError::LengthFunctorAppliedToNotArray(value.clone()))) })? .len(); - Ok(serde_json::json!(length)) + Ok(length.into()) } } } -impl<'value> LambdaResult<'value> { - fn from_cow(result: Cow<'value, JValue>, tetraplet_idx: usize) -> Self { +impl<'value> LambdaResult { + // TODO rename + fn from_cow(result: JValue, tetraplet_idx: usize) -> Self { Self { result, tetraplet_idx: Some(tetraplet_idx), @@ -295,17 +293,19 @@ impl<'value> LambdaResult<'value> { fn from_value(result: JValue) -> Self { Self { - result: Cow::Owned(result), + result, tetraplet_idx: None, } } } -impl<'value> MapLensResult<'value> { - fn from_cow(result: Cow<'value, JValue>, tetraplet: RcSecurityTetraplet) -> Self { +impl<'value> MapLensResult { + // TODO rename + fn from_cow(result: JValue, tetraplet: RcSecurityTetraplet) -> Self { Self { result, tetraplet } } + // TODO rename fn from_value(result: JValue, exec_ctx: &ExecutionCtx<'_>, functor: &Functor) -> Self { let tetraplet = Rc::new(SecurityTetraplet::new( exec_ctx.run_parameters.current_peer_id.to_string(), @@ -314,7 +314,7 @@ impl<'value> MapLensResult<'value> { functor.to_string(), )); Self { - result: Cow::Owned(result), + result, tetraplet, } } diff --git a/air/src/execution_step/lambda_applier/utils.rs b/air/src/execution_step/lambda_applier/utils.rs index 8a656a94..7a557fb4 100644 --- a/air/src/execution_step/lambda_applier/utils.rs +++ b/air/src/execution_step/lambda_applier/utils.rs @@ -87,16 +87,16 @@ pub(super) fn try_scalar_ref_as_idx(scalar: ScalarRef<'_>) -> LambdaResult } } -pub(super) fn try_scalar_ref_as_stream_map_key(scalar: ScalarRef<'_>) -> LambdaResult> { +pub(super) fn try_scalar_ref_as_stream_map_key(scalar: ScalarRef<'_>) -> LambdaResult { match scalar { ScalarRef::Value(map_accessor) => { - let map_accessor = map_accessor.get_result().as_ref(); + let map_accessor = map_accessor.get_result(); let map_key = StreamMapKey::from_value_ref(map_accessor).ok_or( LambdaError::CanonStreamMapAccessorHasInvalidType { map_accessor: map_accessor.clone(), }, )?; - Ok(map_key.into_owned()) + Ok(map_key) } ScalarRef::IterableValue(_map_accessor) => Err(LambdaError::CanonStreamMapAccessorMustNotBeIterable), } diff --git a/air/src/execution_step/resolver/resolvable_impl.rs b/air/src/execution_step/resolver/resolvable_impl.rs index c5460a8b..f54e6b75 100644 --- a/air/src/execution_step/resolver/resolvable_impl.rs +++ b/air/src/execution_step/resolver/resolvable_impl.rs @@ -67,7 +67,7 @@ fn resolve_errors( instruction_error: &crate::InstructionError, lens: &Option>, ctx: &ExecutionCtx<'_>, -) -> Result<(serde_json::Value, Vec>, Provenance), crate::ExecutionError> { +) -> Result<(JValue, Vec>, Provenance), crate::ExecutionError> { use crate::execution_step::InstructionError; let InstructionError { @@ -78,8 +78,8 @@ fn resolve_errors( } = instruction_error; let jvalue = match lens { - Some(error_accessor) => select_by_lambda_from_scalar(error.as_ref(), error_accessor, ctx)?.into_owned(), - None => error.as_ref().clone(), + Some(error_accessor) => select_by_lambda_from_scalar(error, error_accessor, ctx)?, + None => error.clone(), }; let tetraplets = match tetraplet { @@ -122,7 +122,7 @@ impl Resolvable for ast::CanonStream<'_> { let value: &dyn JValuable = &&canon.canon_stream; let tetraplets = value.as_tetraplets(); Ok(( - value.as_jvalue().into_owned(), + value.as_jvalue(), tetraplets, Provenance::canon(canon.cid.clone()), )) @@ -144,7 +144,7 @@ impl Resolvable for ast::ScalarWithLambda<'_> { let (value, root_provenance) = ctx.scalars.get_value(self.name)?.into_jvaluable(); let (value, tetraplet, provenance) = value.apply_lambda_with_tetraplets(&self.lambda, ctx, &root_provenance)?; let tetraplet = Rc::new(tetraplet); - Ok((value.into_owned(), vec![tetraplet], provenance)) + Ok((value, vec![tetraplet], provenance)) } } @@ -155,7 +155,7 @@ impl Resolvable for ast::CanonStreamWithLambda<'_> { let (value, tetraplet, provenance) = value.apply_lambda_with_tetraplets(&self.lambda, ctx, &Provenance::canon(canon.cid.clone()))?; let tetraplet = Rc::new(tetraplet); - Ok((value.into_owned(), vec![tetraplet], provenance)) + Ok((value, vec![tetraplet], provenance)) } } @@ -190,7 +190,7 @@ impl Resolvable for ast::CanonStreamMap<'_> { let tetraplets = value.as_tetraplets(); let provenance = Provenance::canon(canon_stream_map_with_prov.cid.clone()); - Ok((value.as_jvalue().into_owned(), tetraplets, provenance)) + Ok((value.as_jvalue(), tetraplets, provenance)) } } @@ -205,6 +205,6 @@ impl Resolvable for ast::CanonStreamMapWithLambda<'_> { let tetraplet = Rc::new(tetraplet); - Ok((value.into_owned(), vec![tetraplet], provenance)) + Ok((value, vec![tetraplet], provenance)) } } diff --git a/air/src/execution_step/value_types/canon_stream.rs b/air/src/execution_step/value_types/canon_stream.rs index 58e83458..3a8bcd20 100644 --- a/air/src/execution_step/value_types/canon_stream.rs +++ b/air/src/execution_step/value_types/canon_stream.rs @@ -57,12 +57,7 @@ impl CanonStream { } pub(crate) fn as_jvalue(&self) -> JValue { - // TODO: this clone will be removed after boxed values - let jvalue_array = self - .values - .iter() - .map(|r| r.get_result().deref().clone()) - .collect::>(); + let jvalue_array = self.values.iter().map(|r| r.get_result().clone()).collect(); JValue::Array(jvalue_array) } diff --git a/air/src/execution_step/value_types/canon_stream_map.rs b/air/src/execution_step/value_types/canon_stream_map.rs index fcefcfed..f383d8ad 100644 --- a/air/src/execution_step/value_types/canon_stream_map.rs +++ b/air/src/execution_step/value_types/canon_stream_map.rs @@ -27,6 +27,7 @@ use crate::UncatchableError; use air_interpreter_cid::CID; use air_interpreter_data::CanonResultCidAggregate; +use air_interpreter_value::JsonString; use polyplets::SecurityTetraplet; use std::collections::HashMap; @@ -36,22 +37,22 @@ use std::rc::Rc; /// Canon stream map is a read-only struct that mimics conventional map. /// The contents of a map are fixed at a specific peer. #[derive(Debug, Clone)] -pub struct CanonStreamMap<'key> { +pub struct CanonStreamMap { /// Contains all key-value pair objects in this form {"key": key, "value": value}. /// There might be multiple pairs with the same key. values: Vec, /// Index access leverages the map that does key to CanonStream mapping. - map: HashMap, CanonStream>, + map: HashMap, /// ap arg processing leverages this tetraplet tetraplet: Rc, } -impl<'key> CanonStreamMap<'key> { +impl CanonStreamMap { // The argument's tetraplet is used to produce canon streams for keys so // that the produced canon streams share tetraplets with the original canon stream // rendered by canon instruction. - pub(crate) fn from_canon_stream(canon_stream: CanonStream) -> ExecutionResult> { - let mut map: HashMap, CanonStream> = HashMap::new(); + pub(crate) fn from_canon_stream(canon_stream: CanonStream) -> ExecutionResult { + let mut map: HashMap = HashMap::new(); let tetraplet = canon_stream.tetraplet().clone(); for kvpair_obj in canon_stream.iter() { @@ -79,8 +80,8 @@ impl<'key> CanonStreamMap<'key> { } pub(crate) fn as_jvalue(&self) -> JValue { - let json_map: serde_json::Map = - self.map.iter().map(|(k, v)| (k.to_string(), v.as_jvalue())).collect(); + let json_map: air_interpreter_value::Map = + self.map.iter().map(|(k, v)| (k.to_key(), v.as_jvalue())).collect(); json_map.into() } @@ -92,14 +93,14 @@ impl<'key> CanonStreamMap<'key> { &self.tetraplet } - pub(crate) fn index<'self_l>(&'self_l self, stream_map_key: &StreamMapKey<'key>) -> Option<&'self_l CanonStream> { + pub(crate) fn index<'self_l>(&'self_l self, stream_map_key: &StreamMapKey) -> Option<&'self_l CanonStream> { self.map.get(stream_map_key) } } use std::fmt; -impl fmt::Display for CanonStreamMap<'_> { +impl fmt::Display for CanonStreamMap { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "[")?; for (key, canon_stream) in self.map.iter() { @@ -110,19 +111,19 @@ impl fmt::Display for CanonStreamMap<'_> { } #[derive(Debug, Clone)] -pub struct CanonStreamMapWithProvenance<'a> { - pub(crate) canon_stream_map: CanonStreamMap<'a>, +pub struct CanonStreamMapWithProvenance { + pub(crate) canon_stream_map: CanonStreamMap, pub(crate) cid: CID, } -impl<'a> CanonStreamMapWithProvenance<'a> { - pub(crate) fn new(canon_stream_map: CanonStreamMap<'a>, cid: CID) -> Self { +impl CanonStreamMapWithProvenance { + pub(crate) fn new(canon_stream_map: CanonStreamMap, cid: CID) -> Self { Self { canon_stream_map, cid } } } -impl<'a> Deref for CanonStreamMapWithProvenance<'a> { - type Target = CanonStreamMap<'a>; +impl<'a> Deref for CanonStreamMapWithProvenance { + type Target = CanonStreamMap; fn deref(&self) -> &Self::Target { &self.canon_stream_map @@ -146,7 +147,7 @@ fn get_value_from_obj(value_aggregate: &ValueAggregate) -> ExecutionResult) -> ValueAggregate { + fn create_value_aggregate(value: JValue) -> ValueAggregate { ValueAggregate::new( value, <_>::default(), diff --git a/air/src/execution_step/value_types/iterable.rs b/air/src/execution_step/value_types/iterable.rs index 6cc15b64..26c616c5 100644 --- a/air/src/execution_step/value_types/iterable.rs +++ b/air/src/execution_step/value_types/iterable.rs @@ -32,7 +32,6 @@ use crate::JValue; use air_interpreter_data::Provenance; use air_interpreter_data::TracePos; -use std::rc::Rc; /// This trait represent bidirectional iterator and /// is used to abstract values used in fold as iterables. @@ -62,7 +61,7 @@ pub(crate) trait Iterable<'ctx> { #[derive(Clone, Debug, Eq, PartialEq)] pub(crate) enum IterableItem<'ctx> { RefValue((&'ctx JValue, RcSecurityTetraplet, TracePos, Provenance)), - RcValue((Rc, RcSecurityTetraplet, TracePos, Provenance)), + RcValue((JValue, RcSecurityTetraplet, TracePos, Provenance)), } impl IterableItem<'_> { @@ -91,7 +90,7 @@ impl IterableItem<'_> { use IterableItem::*; let (value, tetraplet, pos, provenance) = match self { - RefValue((value, tetraplet, pos, prov)) => (Rc::new(value.clone()), tetraplet, pos, prov), + RefValue((value, tetraplet, pos, prov)) => (value.clone(), tetraplet, pos, prov), RcValue(ingredients) => ingredients, }; diff --git a/air/src/execution_step/value_types/iterable/resolved_call.rs b/air/src/execution_step/value_types/iterable/resolved_call.rs index 1fcf2df5..2f1876d8 100644 --- a/air/src/execution_step/value_types/iterable/resolved_call.rs +++ b/air/src/execution_step/value_types/iterable/resolved_call.rs @@ -21,8 +21,6 @@ use crate::foldable_next; use crate::foldable_prev; use crate::JValue; -use std::ops::Deref; - /// Used for iterating over JValue of array type. #[derive(Clone, Debug, Eq, PartialEq)] pub(crate) struct IterableResolvedCall { @@ -60,7 +58,7 @@ impl<'ctx> Iterable<'ctx> for IterableResolvedCall { let (result, tetraplet, trace_pos) = self.call_result.as_inner_parts(); let provenance = self.call_result.get_provenance(); - let jvalue = match &result.deref() { + let jvalue = match &result { JValue::Array(array) => &array[self.cursor], _ => unimplemented!("this jvalue is set only by fold instruction, so it must have an array type"), }; @@ -73,7 +71,7 @@ impl<'ctx> Iterable<'ctx> for IterableResolvedCall { } fn len(&self) -> usize { - match self.call_result.get_result().deref() { + match self.call_result.get_result() { JValue::Array(array) => array.len(), _ => unimplemented!("this jvalue is set only by fold instruction, so it must have an array type"), } diff --git a/air/src/execution_step/value_types/jvaluable.rs b/air/src/execution_step/value_types/jvaluable.rs index 143b879a..db8179fa 100644 --- a/air/src/execution_step/value_types/jvaluable.rs +++ b/air/src/execution_step/value_types/jvaluable.rs @@ -32,12 +32,11 @@ use crate::SecurityTetraplet; use air_interpreter_data::Provenance; -use std::borrow::Cow; /// Represent a value that could be transform to a JValue with or without tetraplets. pub(crate) trait JValuable { /// Applies lambda to the internal value, produces JValue. - fn apply_lambda(&self, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>) -> ExecutionResult>; + fn apply_lambda(&self, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>) -> ExecutionResult; /// Applies lambda to the internal value, produces JValue with tetraplet. // TODO self should know about own provenance, but it will require @@ -48,10 +47,10 @@ pub(crate) trait JValuable { lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>, root_provenance: &Provenance, - ) -> ExecutionResult<(Cow<'_, JValue>, SecurityTetraplet, Provenance)>; + ) -> ExecutionResult<(JValue, SecurityTetraplet, Provenance)>; /// Return internal value as borrowed if it's possible, owned otherwise. - fn as_jvalue(&self) -> Cow<'_, JValue>; + fn as_jvalue(&self) -> JValue; /// Convert this boxed value to an owned JValue. fn into_jvalue(self: Box) -> JValue; diff --git a/air/src/execution_step/value_types/jvaluable/canon_stream.rs b/air/src/execution_step/value_types/jvaluable/canon_stream.rs index 77333eed..94a2bb33 100644 --- a/air/src/execution_step/value_types/jvaluable/canon_stream.rs +++ b/air/src/execution_step/value_types/jvaluable/canon_stream.rs @@ -26,12 +26,11 @@ use crate::SecurityTetraplet; use air_interpreter_data::Provenance; -use std::borrow::Cow; use std::ops::Deref; impl JValuable for &CanonStream { - fn apply_lambda(&self, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>) -> ExecutionResult> { - let iter = self.iter().map(|v| v.get_result().deref()); + fn apply_lambda(&self, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>) -> ExecutionResult { + let iter = self.iter().map(|v| v.get_result()); let select_result = select_by_lambda_from_stream(iter, lambda, exec_ctx)?; Ok(select_result.result) @@ -42,8 +41,8 @@ impl JValuable for &CanonStream { lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>, root_provenance: &Provenance, - ) -> ExecutionResult<(Cow<'_, JValue>, SecurityTetraplet, Provenance)> { - let iter = self.iter().map(|v| v.get_result().deref()); + ) -> ExecutionResult<(JValue, SecurityTetraplet, Provenance)> { + let iter = self.iter().map(|v| v.get_result()); let select_result = select_by_lambda_from_stream(iter, lambda, exec_ctx)?; let (tetraplet, provenance) = match select_result.tetraplet_idx { @@ -69,9 +68,9 @@ impl JValuable for &CanonStream { Ok((select_result.result, tetraplet, provenance)) } - fn as_jvalue(&self) -> Cow<'_, JValue> { - let jvalue = CanonStream::as_jvalue(self); - Cow::Owned(jvalue) + #[inline] + fn as_jvalue(&self) -> JValue { + CanonStream::as_jvalue(self) } fn into_jvalue(self: Box) -> JValue { diff --git a/air/src/execution_step/value_types/jvaluable/canon_stream_map.rs b/air/src/execution_step/value_types/jvaluable/canon_stream_map.rs index 693f082b..005c69df 100644 --- a/air/src/execution_step/value_types/jvaluable/canon_stream_map.rs +++ b/air/src/execution_step/value_types/jvaluable/canon_stream_map.rs @@ -27,10 +27,9 @@ use crate::SecurityTetraplet; use air_interpreter_data::Provenance; -use std::borrow::Cow; - -impl JValuable for &CanonStreamMap<'_> { - fn apply_lambda(&self, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>) -> ExecutionResult> { +impl JValuable for &CanonStreamMap { + #[inline] + fn apply_lambda(&self, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>) -> ExecutionResult { let select_result = select_by_lambda_from_canon_map(self, lambda, exec_ctx)?; Ok(select_result.result) } @@ -40,18 +39,19 @@ impl JValuable for &CanonStreamMap<'_> { lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>, root_provenance: &Provenance, - ) -> ExecutionResult<(Cow<'_, JValue>, SecurityTetraplet, Provenance)> { + ) -> ExecutionResult<(JValue, SecurityTetraplet, Provenance)> { let MapLensResult { result, tetraplet } = select_by_lambda_from_canon_map(self, lambda, exec_ctx)?; // Provenance is borrowed from the map. Ok((result, tetraplet.as_ref().clone(), root_provenance.clone())) } - fn as_jvalue(&self) -> Cow<'_, JValue> { - let jvalue = CanonStreamMap::as_jvalue(self); - Cow::Owned(jvalue) + #[inline] + fn as_jvalue(&self) -> JValue { + CanonStreamMap::as_jvalue(self) } + #[inline] fn into_jvalue(self: Box) -> JValue { CanonStreamMap::as_jvalue(&self) } diff --git a/air/src/execution_step/value_types/jvaluable/cell_vec_resolved_call_result.rs b/air/src/execution_step/value_types/jvaluable/cell_vec_resolved_call_result.rs index 5a87e60c..f86eea3d 100644 --- a/air/src/execution_step/value_types/jvaluable/cell_vec_resolved_call_result.rs +++ b/air/src/execution_step/value_types/jvaluable/cell_vec_resolved_call_result.rs @@ -27,12 +27,9 @@ use crate::SecurityTetraplet; use air_interpreter_data::Provenance; -use std::borrow::Cow; -use std::ops::Deref; - impl JValuable for std::cell::Ref<'_, Vec> { - fn apply_lambda(&self, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>) -> ExecutionResult> { - let stream_iter = self.iter().map(|r| r.get_result().deref()); + fn apply_lambda(&self, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>) -> ExecutionResult { + let stream_iter = self.iter().map(|r| r.get_result()); let select_result = select_by_lambda_from_stream(stream_iter, lambda, exec_ctx)?; Ok(select_result.result) } @@ -42,8 +39,8 @@ impl JValuable for std::cell::Ref<'_, Vec> { lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>, root_provenance: &Provenance, - ) -> ExecutionResult<(Cow<'_, JValue>, SecurityTetraplet, Provenance)> { - let stream_iter = self.iter().map(|r| r.get_result().deref()); + ) -> ExecutionResult<(JValue, SecurityTetraplet, Provenance)> { + let stream_iter = self.iter().map(|r| r.get_result()); let select_result = select_by_lambda_from_stream(stream_iter, lambda, exec_ctx)?; let tetraplet = match select_result.tetraplet_idx { @@ -57,13 +54,13 @@ impl JValuable for std::cell::Ref<'_, Vec> { Ok((select_result.result, tetraplet, root_provenance.clone())) } - fn as_jvalue(&self) -> Cow<'_, JValue> { - let jvalue_array = self.iter().map(|r| r.get_result().deref().clone()).collect::>(); - Cow::Owned(JValue::Array(jvalue_array)) + fn as_jvalue(&self) -> JValue { + let jvalue_array = self.iter().map(|r| r.get_result().clone()).collect(); + JValue::Array(jvalue_array) } fn into_jvalue(self: Box) -> JValue { - let jvalue_array = self.iter().map(|r| r.get_result().deref().clone()).collect::>(); + let jvalue_array = self.iter().map(|r| r.get_result().clone()).collect(); JValue::Array(jvalue_array) } diff --git a/air/src/execution_step/value_types/jvaluable/iterable_item.rs b/air/src/execution_step/value_types/jvaluable/iterable_item.rs index c927b9dc..28df9106 100644 --- a/air/src/execution_step/value_types/jvaluable/iterable_item.rs +++ b/air/src/execution_step/value_types/jvaluable/iterable_item.rs @@ -27,16 +27,13 @@ use crate::SecurityTetraplet; use air_interpreter_data::Provenance; -use std::borrow::Cow; -use std::ops::Deref; - impl<'ctx> JValuable for IterableItem<'ctx> { - fn apply_lambda(&self, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>) -> ExecutionResult> { + fn apply_lambda(&self, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>) -> ExecutionResult { use super::IterableItem::*; let jvalue = match self { RefValue((jvalue, ..)) => jvalue, - RcValue((jvalue, ..)) => jvalue.deref(), + RcValue((jvalue, ..)) => jvalue, }; let selected_value = select_by_lambda_from_scalar(jvalue, lambda, exec_ctx)?; @@ -48,12 +45,12 @@ impl<'ctx> JValuable for IterableItem<'ctx> { lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>, _root_provenance: &Provenance, - ) -> ExecutionResult<(Cow<'_, JValue>, SecurityTetraplet, Provenance)> { + ) -> ExecutionResult<(JValue, SecurityTetraplet, Provenance)> { use super::IterableItem::*; let (jvalue, tetraplet, provenance) = match self { RefValue((jvalue, tetraplet, _, provenance)) => (*jvalue, tetraplet, provenance), - RcValue((jvalue, tetraplet, _, provenance)) => (jvalue.deref(), tetraplet, provenance), + RcValue((jvalue, tetraplet, _, provenance)) => (jvalue, tetraplet, provenance), }; let selected_value = select_by_lambda_from_scalar(jvalue, lambda, exec_ctx)?; @@ -62,12 +59,12 @@ impl<'ctx> JValuable for IterableItem<'ctx> { Ok((selected_value, tetraplet, provenance.clone())) } - fn as_jvalue(&self) -> Cow<'_, JValue> { + fn as_jvalue(&self) -> JValue { use super::IterableItem::*; match self { - RefValue((jvalue, ..)) => Cow::Borrowed(jvalue), - RcValue((jvalue, ..)) => Cow::Borrowed(jvalue.deref()), + RefValue((jvalue, ..)) => (*jvalue).clone(), + RcValue((jvalue, ..)) => jvalue.clone(), } } @@ -76,7 +73,7 @@ impl<'ctx> JValuable for IterableItem<'ctx> { match *self { RefValue((jvalue, ..)) => jvalue.clone(), - RcValue((jvalue, ..)) => jvalue.deref().clone(), + RcValue((jvalue, ..)) => jvalue.clone(), } } diff --git a/air/src/execution_step/value_types/jvaluable/resolved_call_result.rs b/air/src/execution_step/value_types/jvaluable/resolved_call_result.rs index f42c3287..e5dee229 100644 --- a/air/src/execution_step/value_types/jvaluable/resolved_call_result.rs +++ b/air/src/execution_step/value_types/jvaluable/resolved_call_result.rs @@ -27,11 +27,8 @@ use crate::SecurityTetraplet; use air_interpreter_data::Provenance; -use std::borrow::Cow; -use std::ops::Deref; - impl JValuable for ValueAggregate { - fn apply_lambda(&self, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>) -> ExecutionResult> { + fn apply_lambda(&self, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>) -> ExecutionResult { let selected_value = select_by_lambda_from_scalar(self.get_result(), lambda, exec_ctx)?; Ok(selected_value) } @@ -41,19 +38,21 @@ impl JValuable for ValueAggregate { lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>, _root_provenane: &Provenance, - ) -> ExecutionResult<(Cow<'_, JValue>, SecurityTetraplet, Provenance)> { + ) -> ExecutionResult<(JValue, SecurityTetraplet, Provenance)> { let selected_value = select_by_lambda_from_scalar(self.get_result(), lambda, exec_ctx)?; let tetraplet = populate_tetraplet_with_lambda(self.get_tetraplet().as_ref().clone(), lambda); Ok((selected_value, tetraplet, self.get_provenance())) } - fn as_jvalue(&self) -> Cow<'_, JValue> { - Cow::Borrowed(self.get_result()) + #[inline] + fn as_jvalue(&self) -> JValue { + self.get_result().clone() } + #[inline] fn into_jvalue(self: Box) -> JValue { - self.get_result().deref().clone() + self.get_result().clone() } fn as_tetraplets(&self) -> RcSecurityTetraplets { diff --git a/air/src/execution_step/value_types/scalar.rs b/air/src/execution_step/value_types/scalar.rs index b615f39f..9ca6a6fd 100644 --- a/air/src/execution_step/value_types/scalar.rs +++ b/air/src/execution_step/value_types/scalar.rs @@ -34,8 +34,6 @@ use air_interpreter_data::TracePos; use serde::Deserialize; use serde::Serialize; -use std::rc::Rc; - #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "snake_case", tag = "type")] pub enum ValueAggregate { @@ -76,7 +74,7 @@ impl<'i> ScalarRef<'i> { impl ValueAggregate { pub(crate) fn new( - result: Rc, + result: JValue, tetraplet: RcSecurityTetraplet, trace_pos: TracePos, provenance: Provenance, @@ -127,7 +125,7 @@ impl ValueAggregate { } } - pub(crate) fn as_inner_parts(&self) -> (&Rc, RcSecurityTetraplet, TracePos) { + pub(crate) fn as_inner_parts(&self) -> (&JValue, RcSecurityTetraplet, TracePos) { match self { ValueAggregate::Literal(ref literal) => (&literal.result, literal.get_tetraplet(), literal.trace_pos), ValueAggregate::ServiceResult { @@ -149,7 +147,7 @@ impl ValueAggregate { } } - pub fn get_result(&self) -> &Rc { + pub fn get_result(&self) -> &JValue { match self { ValueAggregate::Literal(literal) => &literal.result, ValueAggregate::ServiceResult { diff --git a/air/src/execution_step/value_types/scalar/values.rs b/air/src/execution_step/value_types/scalar/values.rs index 77efaa0f..d272b9c8 100644 --- a/air/src/execution_step/value_types/scalar/values.rs +++ b/air/src/execution_step/value_types/scalar/values.rs @@ -27,7 +27,7 @@ use std::rc::Rc; #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] // no lambda here are literal + lambda is literal pub struct LiteralAggregate { - pub result: Rc, + pub result: JValue, // this Rc is not really shared ATM, as execution passes through the Resolvable needle pub init_peer_id: Rc, // TODO #[serde(skip)] @@ -36,7 +36,7 @@ pub struct LiteralAggregate { #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] pub struct ServiceResultAggregate { - pub result: Rc, + pub result: JValue, pub tetraplet: RcSecurityTetraplet, // TODO #[serde(skip)] pub trace_pos: TracePos, @@ -44,7 +44,7 @@ pub struct ServiceResultAggregate { #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] pub struct CanonResultAggregate { - pub result: Rc, + pub result: JValue, pub peer_id: Rc, pub lambda: Rc, // TODO #[serde(skip)] @@ -52,7 +52,7 @@ pub struct CanonResultAggregate { } impl LiteralAggregate { - pub(crate) fn new(result: Rc, init_peer_id: Rc, trace_pos: TracePos) -> Self { + pub(crate) fn new(result: JValue, init_peer_id: Rc, trace_pos: TracePos) -> Self { Self { result, init_peer_id, @@ -66,7 +66,7 @@ impl LiteralAggregate { } impl ServiceResultAggregate { - pub(crate) fn new(result: Rc, tetraplet: RcSecurityTetraplet, trace_pos: TracePos) -> Self { + pub(crate) fn new(result: JValue, tetraplet: RcSecurityTetraplet, trace_pos: TracePos) -> Self { Self { result, tetraplet, @@ -76,7 +76,7 @@ impl ServiceResultAggregate { } impl CanonResultAggregate { - pub(crate) fn new(result: Rc, peer_id: Rc, lambda: &str, trace_pos: TracePos) -> Self { + pub(crate) fn new(result: JValue, peer_id: Rc, lambda: &str, trace_pos: TracePos) -> Self { Self { result, peer_id, diff --git a/air/src/execution_step/value_types/stream_map.rs b/air/src/execution_step/value_types/stream_map.rs index f3ca1312..90f4bacb 100644 --- a/air/src/execution_step/value_types/stream_map.rs +++ b/air/src/execution_step/value_types/stream_map.rs @@ -23,15 +23,17 @@ use crate::execution_step::value_types::TracePosOperate; use crate::execution_step::ExecutionResult; use crate::JValue; +use air_interpreter_value::JsonString; use air_trace_handler::TraceHandler; -use serde_json::json; -use std::rc::Rc; - pub(super) static VALUE_FIELD_NAME: &str = "value"; -pub(super) fn from_key_value(key: StreamMapKey<'_>, value: &JValue) -> Rc { - Rc::new(json!({ KEY_FIELD_NAME: key, VALUE_FIELD_NAME: value })) +pub(super) fn from_key_value(key: StreamMapKey, value: &JValue) -> JValue { + let map = maplit::hashmap! { + VALUE_FIELD_NAME => value.clone(), + KEY_FIELD_NAME => key.into(), + }; + map.into() } #[derive(Debug, Default, Clone)] @@ -46,7 +48,7 @@ impl StreamMap { pub(crate) fn insert( &mut self, - key: StreamMapKey<'_>, + key: StreamMapKey, value: &ValueAggregate, generation: Generation, ) -> ExecutionResult<()> { @@ -72,7 +74,7 @@ impl StreamMap { self.stream.iter() } - pub(crate) fn iter_unique_key_object(&self) -> impl Iterator + '_ { + pub(crate) fn iter_unique_key_object(&self) -> impl Iterator + '_ { use std::collections::HashSet; let mut met_keys = HashSet::new(); @@ -89,17 +91,11 @@ impl StreamMap { let key = object .get(KEY_FIELD_NAME) .and_then(StreamMapKey::from_value_ref) - .and_then(|key| { - if met_keys.insert(key.to_string()) { - Some(key) - } else { - None - } - })?; + .and_then(|key| if met_keys.insert(key.to_key()) { Some(key) } else { None })?; let value = object.get(VALUE_FIELD_NAME)?.clone(); - Some((key.to_string(), value)) + Some((key.to_key(), value)) }) } } @@ -130,9 +126,8 @@ mod test { use serde_json::json; use std::borrow::Cow; - use std::rc::Rc; - fn create_value_aggregate(value: Rc) -> ValueAggregate { + fn create_value_aggregate(value: JValue) -> ValueAggregate { ValueAggregate::new( value, <_>::default(), @@ -143,8 +138,8 @@ mod test { fn compare_stream_iter<'value>( mut iter: impl Iterator, - key: StreamMapKey<'_>, - value: &Rc, + key: StreamMapKey, + value: &JValue, ) -> bool { let actual_value = iter.next().map(|e| e.get_result()).unwrap(); let expected_value = from_key_value(key, value); @@ -284,9 +279,9 @@ mod test { (0..count) .map(|id| { let key = id.to_string(); - let value = json!(id); + let value = id.into(); let value = ValueAggregate::new( - Rc::new(value), + value, <_>::default(), 0.into(), air_interpreter_data::Provenance::literal(), diff --git a/air/src/lib.rs b/air/src/lib.rs index 34f60d56..88765223 100644 --- a/air/src/lib.rs +++ b/air/src/lib.rs @@ -80,6 +80,6 @@ pub mod parser { } } -pub(crate) type JValue = serde_json::Value; +pub(crate) type JValue = air_interpreter_value::JValue; use air_lambda_parser::LambdaAST; diff --git a/avm/interface/src/call_request_parameters.rs b/avm/interface/src/call_request_parameters.rs index a68ce8ec..c8146e94 100644 --- a/avm/interface/src/call_request_parameters.rs +++ b/avm/interface/src/call_request_parameters.rs @@ -65,6 +65,7 @@ impl CallRequestParams { use air_interpreter_interface::TetrapletsRepr; use air_interpreter_sede::FromSerialized; + // TODO that's different JValue! let arguments: Vec = CallArgumentsRepr .deserialize(&call_params.arguments) .map_err(|de_error| CallSeDeErrors::CallParamsArgsDeFailed { diff --git a/crates/air-lib/air-parser/Cargo.toml b/crates/air-lib/air-parser/Cargo.toml index e150e7f0..02b60891 100644 --- a/crates/air-lib/air-parser/Cargo.toml +++ b/crates/air-lib/air-parser/Cargo.toml @@ -34,6 +34,7 @@ serde_json = "1.0.108" itertools = "0.10.5" thiserror = "1.0.50" tracing = "0.1.40" +air-interpreter-value = { version = "0.1.0", path = "../interpreter-value" } [dev-dependencies] criterion = "0.5.1" diff --git a/crates/air-lib/air-parser/src/ast/instruction_arguments/traits.rs b/crates/air-lib/air-parser/src/ast/instruction_arguments/traits.rs index e910b1d1..e7b754fb 100644 --- a/crates/air-lib/air-parser/src/ast/instruction_arguments/traits.rs +++ b/crates/air-lib/air-parser/src/ast/instruction_arguments/traits.rs @@ -191,6 +191,15 @@ impl From<&Number> for serde_json::Value { } } +impl From<&Number> for air_interpreter_value::JValue { + fn from(number: &Number) -> Self { + match number { + Number::Int(value) => (*value).into(), + Number::Float(value) => (*value).into(), + } + } +} + fn display_last_error(f: &mut fmt::Formatter, lambda_ast: &Option) -> fmt::Result { use crate::parser::LAST_ERROR; diff --git a/crates/air-lib/interpreter-data/Cargo.toml b/crates/air-lib/interpreter-data/Cargo.toml index 3da1e0ae..fc73c632 100644 --- a/crates/air-lib/interpreter-data/Cargo.toml +++ b/crates/air-lib/interpreter-data/Cargo.toml @@ -20,6 +20,7 @@ aquavm-air-parser = { version = "0.11.1", path = "../air-parser" } air-interpreter-cid = { version = "0.9.0", path = "../interpreter-cid", features = ["rkyv"] } air-interpreter-signatures = { version = "0.1.7", path = "../interpreter-signatures", features = ["rkyv"] } air-interpreter-sede = { version = "0.1.0", path = "../interpreter-sede", features = ["msgpack"] } +air-interpreter-value = { version = "0.1.0", path = "../interpreter-value" } polyplets = { version = "0.6.0", path = "../polyplets", features = ["rkyv"] } fluence-keypair = { version = "0.10.4", default-features = false } diff --git a/crates/air-lib/interpreter-data/src/executed_state.rs b/crates/air-lib/interpreter-data/src/executed_state.rs index 8a503fa6..ec1ff9da 100644 --- a/crates/air-lib/interpreter-data/src/executed_state.rs +++ b/crates/air-lib/interpreter-data/src/executed_state.rs @@ -144,7 +144,7 @@ impl CallServiceFailed { } pub fn to_value(&self) -> JValue { - serde_json::to_value(self).expect("default serializer shouldn't fail") + serde_json::to_value(self).expect("default serializer shouldn't fail").into() } } diff --git a/crates/air-lib/interpreter-data/src/lib.rs b/crates/air-lib/interpreter-data/src/lib.rs index 56869552..56992eec 100644 --- a/crates/air-lib/interpreter-data/src/lib.rs +++ b/crates/air-lib/interpreter-data/src/lib.rs @@ -46,7 +46,7 @@ pub use trace::*; pub use trace_pos::*; use once_cell::sync::Lazy; -use serde_json::Value as JValue; +use air_interpreter_value::JValue; use std::str::FromStr; diff --git a/crates/air-lib/interpreter-data/src/raw_value.rs b/crates/air-lib/interpreter-data/src/raw_value.rs index 8a0d599d..e4289775 100644 --- a/crates/air-lib/interpreter-data/src/raw_value.rs +++ b/crates/air-lib/interpreter-data/src/raw_value.rs @@ -20,7 +20,6 @@ use serde::Deserialize; use serde::Serialize; use std::cell::RefCell; -use std::rc::Rc; #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(transparent)] @@ -31,11 +30,11 @@ pub struct RawValue { #[serde(skip)] #[with(::rkyv::with::Skip)] - parsed: RefCell>>, + parsed: RefCell>, } impl RawValue { - pub fn from_value(value: impl Into>) -> Self { + pub fn from_value(value: impl Into) -> Self { let value = value.into(); let raw = value.to_string().into(); Self { @@ -44,7 +43,7 @@ impl RawValue { } } - pub fn get_value(&self) -> Rc { + pub fn get_value(&self) -> JValue { let mut parsed_guard = self.parsed.borrow_mut(); let parsed_value = parsed_guard diff --git a/crates/air-lib/interpreter-interface/Cargo.toml b/crates/air-lib/interpreter-interface/Cargo.toml index 159efcc9..8529a157 100644 --- a/crates/air-lib/interpreter-interface/Cargo.toml +++ b/crates/air-lib/interpreter-interface/Cargo.toml @@ -23,6 +23,7 @@ marine-call-parameters = { version = "0.10.3", default-features = false } serde = "1.0.190" serde_json = "1.0.108" serde_bytes = "0.11.12" +air-interpreter-value = { version = "0.1.0", path = "../interpreter-value" } [features] default = ["marine"] diff --git a/crates/air-lib/interpreter-interface/src/call_request_parameters.rs b/crates/air-lib/interpreter-interface/src/call_request_parameters.rs index 8b234b77..6ac74ef9 100644 --- a/crates/air-lib/interpreter-interface/src/call_request_parameters.rs +++ b/crates/air-lib/interpreter-interface/src/call_request_parameters.rs @@ -21,6 +21,7 @@ use air_interpreter_sede::FromSerialized; use air_interpreter_sede::MsgPackFormat; use air_interpreter_sede::MsgPackMultiformat; use air_interpreter_sede::Representation; +use air_interpreter_value::JValue; use marine_call_parameters::SecurityTetraplet; #[cfg(feature = "marine")] @@ -43,13 +44,19 @@ pub type CallRequestsFormat = MsgPackMultiformat; define_simple_representation! { CallArgumentsRepr, - Vec, + Vec, CallArgumentsFormat, SerializedCallArguments } pub type CallArgumentsDeserializeError = ::DeserializeError; +impl FromSerialized> for CallArgumentsRepr { + fn deserialize(&self, repr: &[u8]) -> Result, Self::DeserializeError> { + Self.get_format().from_slice(repr) + } +} + define_simple_representation! { TetrapletsRepr, // additional implementation for Vec> is defined below diff --git a/crates/air-lib/interpreter-value/src/lib.rs b/crates/air-lib/interpreter-value/src/lib.rs index 2cce7c81..f6a03b29 100644 --- a/crates/air-lib/interpreter-value/src/lib.rs +++ b/crates/air-lib/interpreter-value/src/lib.rs @@ -15,3 +15,5 @@ mod value; pub type Map = indexmap::IndexMap; pub type JsonString = Rc; + +pub use value::JValue; diff --git a/crates/air-lib/interpreter-value/src/value/from.rs b/crates/air-lib/interpreter-value/src/value/from.rs index db2b917a..83e35456 100644 --- a/crates/air-lib/interpreter-value/src/value/from.rs +++ b/crates/air-lib/interpreter-value/src/value/from.rs @@ -293,3 +293,19 @@ where } } } + +impl From for JValue { + fn from(value: serde_json::Value) -> Self { + match value { + serde_json::Value::Null => JValue::Null, + serde_json::Value::Bool(b) => JValue::Bool(b), + serde_json::Value::Number(n) => JValue::Number(n), + serde_json::Value::String(s) => JValue::String(s.into()), + serde_json::Value::Array(a) => JValue::Array(a.into_iter().map(Into::into).collect()), + serde_json::Value::Object(o) => { + let oo = Map::from_iter(o.into_iter().map(|(k, v)| (k.into(), v.into()))); + JValue::Object(oo.into()) + } + } + } +} diff --git a/crates/air-lib/test-utils/Cargo.toml b/crates/air-lib/test-utils/Cargo.toml index 6ce2b475..399a6607 100644 --- a/crates/air-lib/test-utils/Cargo.toml +++ b/crates/air-lib/test-utils/Cargo.toml @@ -34,6 +34,7 @@ fluence-keypair = "0.10.4" ed25519-dalek = "2.1.0" rand_chacha = "0.3.1" sha2 = "0.10.6" +air-interpreter-value = { version = "0.1.0", path = "../interpreter-value" } [dev-dependencies] maplit = "1.0.2" diff --git a/crates/air-lib/test-utils/src/call_services.rs b/crates/air-lib/test-utils/src/call_services.rs index 911596a0..1ccfbbd7 100644 --- a/crates/air-lib/test-utils/src/call_services.rs +++ b/crates/air-lib/test-utils/src/call_services.rs @@ -24,7 +24,7 @@ use std::rc::Rc; pub fn unit_call_service() -> CallServiceClosure { Box::new(|_| -> CallServiceResult { - CallServiceResult::ok(json!("result from unit_call_service")) + CallServiceResult::ok(json!("result from unit_call_service").into()) }) } @@ -34,7 +34,7 @@ pub fn echo_call_service() -> CallServiceClosure { }) } -pub fn set_variable_call_service(json: JValue) -> CallServiceClosure { +pub fn set_variable_call_service(json: serde_json::Value) -> CallServiceClosure { Box::new(move |_| -> CallServiceResult { CallServiceResult::ok(json.clone()) }) } @@ -47,7 +47,7 @@ pub enum VariableOptionSource { } pub fn set_variables_call_service( - variables_mapping: HashMap, + variables_mapping: HashMap, variable_source: VariableOptionSource, ) -> CallServiceClosure { use VariableOptionSource::*; @@ -55,7 +55,7 @@ pub fn set_variables_call_service( Box::new(move |params| -> CallServiceResult { let var_name = match variable_source { Argument(id) => match params.arguments.get(id) { - Some(JValue::String(name)) => name.to_string(), + Some(serde_json::Value::String(name)) => name.to_string(), _ => "default".to_string(), }, FunctionName => params.function_name, @@ -89,7 +89,7 @@ pub fn fallible_call_service(fallible_service_id: impl Into) -> CallServ }) } -pub fn fallible_call_service_by_arg(arg: impl Into) -> CallServiceClosure { +pub fn fallible_call_service_by_arg(arg: impl Into) -> CallServiceClosure { let arg = arg.into(); Box::new(move |params| -> CallServiceResult { diff --git a/crates/air-lib/test-utils/src/executed_state.rs b/crates/air-lib/test-utils/src/executed_state.rs index a0b684b4..d9f4418e 100644 --- a/crates/air-lib/test-utils/src/executed_state.rs +++ b/crates/air-lib/test-utils/src/executed_state.rs @@ -45,7 +45,7 @@ use serde::Serialize; use std::rc::Rc; pub fn simple_value_aggregate_cid( - result: impl Into, + result: impl Into, cid_state: &mut ExecutionCidState, ) -> CID { let value = result.into(); @@ -66,9 +66,9 @@ pub fn simple_value_aggregate_cid( } pub fn value_aggregate_cid( - result: impl Into, + result: impl Into, tetraplet: SecurityTetraplet, - args: Vec, + args: Vec, cid_state: &mut ExecutionCidState, ) -> CID { let value = result.into(); @@ -76,7 +76,7 @@ pub fn value_aggregate_cid( let value_cid = cid_state.value_tracker.track_raw_value(vm_value); let tetraplet_cid = cid_state.tetraplet_tracker.track_value(tetraplet).unwrap(); - let arguments = serde_json::Value::Array(args); + let arguments = JValue::Array(args.into()); let argument_hash = value_to_json_cid(&arguments).unwrap().get_inner(); let service_result_agg = ServiceResultCidAggregate { @@ -136,7 +136,7 @@ pub fn ap(generation: impl Into) -> ExecutedState { #[derive(Debug, Serialize, Deserialize)] pub struct ValueAggregateAlike { - pub result: Rc, + pub result: JValue, pub tetraplet: Rc, // TODO convert data and remove Provenance pub provenance: Option, @@ -150,14 +150,14 @@ pub struct CanonResultAlike { /// This function takes a JSON DSL-like struct for compatibility and test writer /// convenience. -pub fn canon(canonicalized_element: JValue) -> ExecutedState { +pub fn canon(canonicalized_element: serde_json::Value) -> ExecutedState { let mut cid_state = ExecutionCidState::new(); canon_tracked(canonicalized_element, &mut cid_state) } pub fn canon_tracked( - canonicalized_element: JValue, + canonicalized_element: serde_json::Value, cid_state: &mut ExecutionCidState, ) -> ExecutedState { let canon_input = serde_json::from_value::(canonicalized_element) diff --git a/crates/air-lib/test-utils/src/lib.rs b/crates/air-lib/test-utils/src/lib.rs index fd47d8c7..fe33b861 100644 --- a/crates/air-lib/test-utils/src/lib.rs +++ b/crates/air-lib/test-utils/src/lib.rs @@ -51,7 +51,7 @@ pub mod prelude { pub type CallServiceClosure = Box CallServiceResult + 'static>; -pub type JValue = serde_json::Value; +use air_interpreter_value::JValue; #[macro_export] macro_rules! checked_call_vm { diff --git a/crates/testing-framework/src/execution/mod.rs b/crates/testing-framework/src/execution/mod.rs index 18293ca3..08620a64 100644 --- a/crates/testing-framework/src/execution/mod.rs +++ b/crates/testing-framework/src/execution/mod.rs @@ -690,7 +690,7 @@ mod tests { #[test] fn test_transformed_shared() { struct Service { - state: RefCell>, + state: RefCell>, } impl MarineService for Service { diff --git a/junk/gen-bench-data/src/dashboard.rs b/junk/gen-bench-data/src/dashboard.rs index c85d1f43..60258d66 100644 --- a/junk/gen-bench-data/src/dashboard.rs +++ b/junk/gen-bench-data/src/dashboard.rs @@ -20,6 +20,7 @@ use air_interpreter_signatures::KeyPair; use air_test_utils::key_utils::derive_dummy_keypair; use air_test_utils::prelude::*; use maplit::hashmap; +use serde_json::Value as JValue; use std::cell::RefCell; use std::collections::HashSet;