mirror of
https://github.com/fluencelabs/aquavm
synced 2025-03-15 20:40:50 +00:00
Remove RefCell from streams (#227)
This commit is contained in:
parent
9ae79f44ff
commit
c00b453a48
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -13,7 +13,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "air"
|
name = "air"
|
||||||
version = "0.20.0"
|
version = "0.21.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"air-execution-info-collector",
|
"air-execution-info-collector",
|
||||||
"air-interpreter-data",
|
"air-interpreter-data",
|
||||||
@ -51,7 +51,7 @@ version = "0.1.0"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "air-interpreter"
|
name = "air-interpreter"
|
||||||
version = "0.20.0"
|
version = "0.21.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"air",
|
"air",
|
||||||
"air-log-targets",
|
"air-log-targets",
|
||||||
|
@ -81,7 +81,7 @@ fn variable_to_generations(variable: &ast::Variable<'_>, exec_ctx: &ExecutionCtx
|
|||||||
// unwrap here is safe because this function will be called only
|
// unwrap here is safe because this function will be called only
|
||||||
// when this stream's been created
|
// when this stream's been created
|
||||||
let stream = exec_ctx.streams.get(stream.name, stream.position).unwrap();
|
let stream = exec_ctx.streams.get(stream.name, stream.position).unwrap();
|
||||||
let generation = match stream.borrow().generations_count() {
|
let generation = match stream.generations_count() {
|
||||||
0 => 0,
|
0 => 0,
|
||||||
n => n - 1,
|
n => n - 1,
|
||||||
};
|
};
|
||||||
|
@ -42,7 +42,7 @@ pub(crate) fn set_local_result<'i>(
|
|||||||
// TODO: refactor this generation handling
|
// TODO: refactor this generation handling
|
||||||
let generation = match exec_ctx.streams.get(stream.name, stream.position) {
|
let generation = match exec_ctx.streams.get(stream.name, stream.position) {
|
||||||
Some(stream) => {
|
Some(stream) => {
|
||||||
let generation = match stream.borrow().generations_count() {
|
let generation = match stream.generations_count() {
|
||||||
0 => 0,
|
0 => 0,
|
||||||
n => n - 1,
|
n => n - 1,
|
||||||
};
|
};
|
||||||
|
@ -22,7 +22,6 @@ use crate::SecurityTetraplet;
|
|||||||
|
|
||||||
use air_parser::ast;
|
use air_parser::ast;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
@ -48,11 +47,10 @@ pub(crate) fn construct_scalar_iterable_value<'ctx>(
|
|||||||
|
|
||||||
/// Constructs iterable value for given stream iterable.
|
/// Constructs iterable value for given stream iterable.
|
||||||
pub(crate) fn construct_stream_iterable_values(
|
pub(crate) fn construct_stream_iterable_values(
|
||||||
stream: &RefCell<Stream>,
|
stream: &Stream,
|
||||||
start: Generation,
|
start: Generation,
|
||||||
end: Generation,
|
end: Generation,
|
||||||
) -> Vec<IterableValue> {
|
) -> Vec<IterableValue> {
|
||||||
let stream = stream.borrow();
|
|
||||||
let stream_iter = match stream.slice_iter(start, end) {
|
let stream_iter = match stream.slice_iter(start, end) {
|
||||||
Some(stream_iter) => stream_iter,
|
Some(stream_iter) => stream_iter,
|
||||||
None => return vec![],
|
None => return vec![],
|
||||||
|
@ -25,13 +25,11 @@ use super::TraceHandler;
|
|||||||
use crate::execution_step::boxed_value::Stream;
|
use crate::execution_step::boxed_value::Stream;
|
||||||
use crate::log_instruction;
|
use crate::log_instruction;
|
||||||
use crate::trace_to_exec_err;
|
use crate::trace_to_exec_err;
|
||||||
use air_parser::ast;
|
|
||||||
use stream_cursor::StreamCursor;
|
use stream_cursor::StreamCursor;
|
||||||
|
|
||||||
|
use air_parser::ast;
|
||||||
use air_parser::ast::FoldStream;
|
use air_parser::ast::FoldStream;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
|
||||||
|
|
||||||
impl<'i> ExecutableInstruction<'i> for FoldStream<'i> {
|
impl<'i> ExecutableInstruction<'i> for FoldStream<'i> {
|
||||||
fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, trace_ctx: &mut TraceHandler) -> ExecutionResult<()> {
|
fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, trace_ctx: &mut TraceHandler) -> ExecutionResult<()> {
|
||||||
log_instruction!(fold, exec_ctx, trace_ctx);
|
log_instruction!(fold, exec_ctx, trace_ctx);
|
||||||
@ -118,16 +116,16 @@ fn should_stop_iteration(iteration_result: &ExecutionResult<bool>) -> bool {
|
|||||||
|
|
||||||
/// Safety: this function should be called iff stream is present in context
|
/// Safety: this function should be called iff stream is present in context
|
||||||
fn add_new_generation_if_non_empty(stream: &ast::Stream<'_>, exec_ctx: &mut ExecutionCtx<'_>) {
|
fn add_new_generation_if_non_empty(stream: &ast::Stream<'_>, exec_ctx: &mut ExecutionCtx<'_>) {
|
||||||
let stream = exec_ctx.streams.get(stream.name, stream.position).unwrap();
|
let stream = exec_ctx.streams.get_mut(stream.name, stream.position).unwrap();
|
||||||
stream.borrow_mut().add_new_generation_if_non_empty();
|
stream.add_new_generation_if_non_empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Safety: this function should be called iff stream is present in context
|
/// Safety: this function should be called iff stream is present in context
|
||||||
fn remove_new_generation_if_non_empty<'ctx>(
|
fn remove_new_generation_if_non_empty<'ctx>(
|
||||||
stream: &ast::Stream<'_>,
|
stream: &ast::Stream<'_>,
|
||||||
exec_ctx: &'ctx mut ExecutionCtx<'_>,
|
exec_ctx: &'ctx mut ExecutionCtx<'_>,
|
||||||
) -> &'ctx RefCell<Stream> {
|
) -> &'ctx Stream {
|
||||||
let stream = exec_ctx.streams.get(stream.name, stream.position).unwrap();
|
let stream = exec_ctx.streams.get_mut(stream.name, stream.position).unwrap();
|
||||||
stream.borrow_mut().remove_last_generation_if_empty();
|
stream.remove_last_generation_if_empty();
|
||||||
stream
|
stream
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,6 @@ use crate::execution_step::air::fold::IterableValue;
|
|||||||
use crate::execution_step::boxed_value::Generation;
|
use crate::execution_step::boxed_value::Generation;
|
||||||
use crate::execution_step::boxed_value::Stream;
|
use crate::execution_step::boxed_value::Stream;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
|
||||||
|
|
||||||
pub(super) struct StreamCursor {
|
pub(super) struct StreamCursor {
|
||||||
last_seen_generation: u32,
|
last_seen_generation: u32,
|
||||||
}
|
}
|
||||||
@ -32,10 +30,10 @@ impl StreamCursor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn construct_iterables(&mut self, stream: &RefCell<Stream>) -> Vec<IterableValue> {
|
pub(super) fn construct_iterables(&mut self, stream: &Stream) -> Vec<IterableValue> {
|
||||||
let iterables =
|
let iterables =
|
||||||
construct_stream_iterable_values(stream, Generation::Nth(self.last_seen_generation), Generation::Last);
|
construct_stream_iterable_values(stream, Generation::Nth(self.last_seen_generation), Generation::Last);
|
||||||
self.last_seen_generation = stream.borrow().non_empty_generations_count() as u32;
|
self.last_seen_generation = stream.non_empty_generations_count() as u32;
|
||||||
|
|
||||||
iterables
|
iterables
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ use std::ops::Deref;
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct StreamJvaluableIngredients<'stream> {
|
pub(crate) struct StreamJvaluableIngredients<'stream> {
|
||||||
pub(crate) stream: std::cell::Ref<'stream, Stream>,
|
pub(crate) stream: &'stream Stream,
|
||||||
pub(crate) generation: Generation,
|
pub(crate) generation: Generation,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ impl JValuable for StreamJvaluableIngredients<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn as_jvalue(&self) -> Cow<'_, JValue> {
|
fn as_jvalue(&self) -> Cow<'_, JValue> {
|
||||||
let jvalue = self.stream.deref().clone().as_jvalue(self.generation).unwrap();
|
let jvalue = self.stream.as_jvalue(self.generation).unwrap();
|
||||||
Cow::Owned(jvalue)
|
Cow::Owned(jvalue)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ impl JValuable for StreamJvaluableIngredients<'_> {
|
|||||||
use crate::execution_step::boxed_value::StreamIter;
|
use crate::execution_step::boxed_value::StreamIter;
|
||||||
|
|
||||||
impl<'stream> StreamJvaluableIngredients<'stream> {
|
impl<'stream> StreamJvaluableIngredients<'stream> {
|
||||||
pub(crate) fn new(stream: std::cell::Ref<'stream, Stream>, generation: Generation) -> Self {
|
pub(crate) fn new(stream: &'stream Stream, generation: Generation) -> Self {
|
||||||
Self { stream, generation }
|
Self { stream, generation }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ impl<'stream> StreamJvaluableIngredients<'stream> {
|
|||||||
Generation::Last => unreachable!(),
|
Generation::Last => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Err(StreamDontHaveSuchGeneration(self.stream.deref().clone(), generation as usize).into())
|
Err(StreamDontHaveSuchGeneration(self.stream.clone(), generation as usize).into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,6 @@ use crate::execution_step::ValueAggregate;
|
|||||||
use air_interpreter_data::GlobalStreamGens;
|
use air_interpreter_data::GlobalStreamGens;
|
||||||
use air_interpreter_data::RestrictedStreamGens;
|
use air_interpreter_data::RestrictedStreamGens;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
@ -43,17 +42,22 @@ pub(crate) struct Streams {
|
|||||||
|
|
||||||
struct StreamDescriptor {
|
struct StreamDescriptor {
|
||||||
pub(self) span: Span,
|
pub(self) span: Span,
|
||||||
// TODO: get rid of RefCell in a separate PR
|
pub(self) stream: Stream,
|
||||||
pub(self) stream: RefCell<Stream>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Streams {
|
impl Streams {
|
||||||
pub(crate) fn get(&self, name: &str, position: usize) -> Option<&RefCell<Stream>> {
|
pub(crate) fn get(&self, name: &str, position: usize) -> Option<&Stream> {
|
||||||
self.streams
|
self.streams
|
||||||
.get(name)
|
.get(name)
|
||||||
.and_then(|descriptors| find_closest(descriptors.iter(), position))
|
.and_then(|descriptors| find_closest(descriptors.iter(), position))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_mut(&mut self, name: &str, position: usize) -> Option<&mut Stream> {
|
||||||
|
self.streams
|
||||||
|
.get_mut(name)
|
||||||
|
.and_then(|descriptors| find_closest_mut(descriptors.iter_mut(), position))
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn add_stream_value(
|
pub(crate) fn add_stream_value(
|
||||||
&mut self,
|
&mut self,
|
||||||
value: ValueAggregate,
|
value: ValueAggregate,
|
||||||
@ -61,8 +65,8 @@ impl Streams {
|
|||||||
stream_name: &str,
|
stream_name: &str,
|
||||||
position: usize,
|
position: usize,
|
||||||
) -> ExecutionResult<u32> {
|
) -> ExecutionResult<u32> {
|
||||||
match self.get(stream_name, position) {
|
match self.get_mut(stream_name, position) {
|
||||||
Some(stream) => stream.borrow_mut().add_value(value, generation),
|
Some(stream) => stream.add_value(value, generation),
|
||||||
None => {
|
None => {
|
||||||
// streams could be created in three ways:
|
// streams could be created in three ways:
|
||||||
// - after met new instruction with stream name that isn't present in streams
|
// - after met new instruction with stream name that isn't present in streams
|
||||||
@ -80,7 +84,7 @@ impl Streams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn add_global_stream(&mut self, name: String, stream: Stream) {
|
pub(crate) fn add_global_stream(&mut self, name: String, stream: Stream) {
|
||||||
let descriptor = StreamDescriptor::global(RefCell::new(stream));
|
let descriptor = StreamDescriptor::global(stream);
|
||||||
self.streams.insert(name, vec![descriptor]);
|
self.streams.insert(name, vec![descriptor]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +94,7 @@ impl Streams {
|
|||||||
.stream_generation_from_data(&name, span.left as u32, iteration as usize)
|
.stream_generation_from_data(&name, span.left as u32, iteration as usize)
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
let new_stream = RefCell::new(Stream::from_generations_count(generations_count as usize));
|
let new_stream = Stream::from_generations_count(generations_count as usize);
|
||||||
let new_descriptor = StreamDescriptor::restricted(new_stream, span);
|
let new_descriptor = StreamDescriptor::restricted(new_stream, span);
|
||||||
match self.streams.entry(name) {
|
match self.streams.entry(name) {
|
||||||
Occupied(mut entry) => {
|
Occupied(mut entry) => {
|
||||||
@ -112,11 +116,7 @@ impl Streams {
|
|||||||
self.streams.remove(&name);
|
self.streams.remove(&name);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.collect_stream_generation(
|
self.collect_stream_generation(name, position, last_descriptor.stream.generations_count() as u32);
|
||||||
name,
|
|
||||||
position,
|
|
||||||
last_descriptor.stream.borrow().generations_count() as u32,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This method must be called at the end of execution, because it contains logic to collect
|
/// This method must be called at the end of execution, because it contains logic to collect
|
||||||
@ -131,7 +131,7 @@ impl Streams {
|
|||||||
// unwrap is safe here because of invariant that streams contains non-empty vectors,
|
// unwrap is safe here because of invariant that streams contains non-empty vectors,
|
||||||
// moreover it must contain only one value, because this method is called at the end
|
// moreover it must contain only one value, because this method is called at the end
|
||||||
// of the execution
|
// of the execution
|
||||||
let generation = descriptors.pop().unwrap().stream.borrow().generations_count();
|
let generation = descriptors.pop().unwrap().stream.generations_count();
|
||||||
(name, generation as u32)
|
(name, generation as u32)
|
||||||
})
|
})
|
||||||
.collect::<GlobalStreamGens>();
|
.collect::<GlobalStreamGens>();
|
||||||
@ -165,14 +165,14 @@ impl Streams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl StreamDescriptor {
|
impl StreamDescriptor {
|
||||||
pub(self) fn global(stream: RefCell<Stream>) -> Self {
|
pub(self) fn global(stream: Stream) -> Self {
|
||||||
Self {
|
Self {
|
||||||
span: Span::new(0, usize::MAX),
|
span: Span::new(0, usize::MAX),
|
||||||
stream,
|
stream,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(self) fn restricted(stream: RefCell<Stream>, span: Span) -> Self {
|
pub(self) fn restricted(stream: Stream, span: Span) -> Self {
|
||||||
Self { span, stream }
|
Self { span, stream }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -180,7 +180,7 @@ impl StreamDescriptor {
|
|||||||
fn find_closest<'d>(
|
fn find_closest<'d>(
|
||||||
descriptors: impl DoubleEndedIterator<Item = &'d StreamDescriptor>,
|
descriptors: impl DoubleEndedIterator<Item = &'d StreamDescriptor>,
|
||||||
position: usize,
|
position: usize,
|
||||||
) -> Option<&'d RefCell<Stream>> {
|
) -> Option<&'d Stream> {
|
||||||
// descriptors are placed in a order of decreasing scopes, so it's enough to get the latest suitable
|
// descriptors are placed in a order of decreasing scopes, so it's enough to get the latest suitable
|
||||||
for descriptor in descriptors.rev() {
|
for descriptor in descriptors.rev() {
|
||||||
if descriptor.span.contains_position(position) {
|
if descriptor.span.contains_position(position) {
|
||||||
@ -191,6 +191,20 @@ fn find_closest<'d>(
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn find_closest_mut<'d>(
|
||||||
|
descriptors: impl DoubleEndedIterator<Item = &'d mut StreamDescriptor>,
|
||||||
|
position: usize,
|
||||||
|
) -> Option<&'d mut Stream> {
|
||||||
|
// descriptors are placed in a order of decreasing scopes, so it's enough to get the latest suitable
|
||||||
|
for descriptor in descriptors.rev() {
|
||||||
|
if descriptor.span.contains_position(position) {
|
||||||
|
return Some(&mut descriptor.stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
use air_parser::ast::Span;
|
use air_parser::ast::Span;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
@ -207,12 +221,6 @@ impl fmt::Display for Streams {
|
|||||||
|
|
||||||
impl fmt::Display for StreamDescriptor {
|
impl fmt::Display for StreamDescriptor {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(
|
write!(f, " <{}> - <{}>: {}", self.span.left, self.span.right, self.stream)
|
||||||
f,
|
|
||||||
" <{}> - <{}>: {}",
|
|
||||||
self.span.left,
|
|
||||||
self.span.right,
|
|
||||||
self.stream.borrow()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ pub(crate) fn resolve_variable<'ctx, 'i>(
|
|||||||
} => {
|
} => {
|
||||||
match ctx.streams.get(name, position) {
|
match ctx.streams.get(name, position) {
|
||||||
Some(stream) => {
|
Some(stream) => {
|
||||||
let ingredients = StreamJvaluableIngredients::new(stream.borrow(), generation);
|
let ingredients = StreamJvaluableIngredients::new(stream, generation);
|
||||||
Ok(Box::new(ingredients))
|
Ok(Box::new(ingredients))
|
||||||
}
|
}
|
||||||
// return an empty stream for not found stream
|
// return an empty stream for not found stream
|
||||||
|
Loading…
x
Reference in New Issue
Block a user