mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-27 12:17:35 +03:00
Update disassembling
This commit is contained in:
parent
a2e31558c1
commit
acdb2b5c9b
@ -26,9 +26,6 @@ pub use variant::*;
|
||||
pub mod external;
|
||||
pub use external::*;
|
||||
|
||||
pub mod finalize;
|
||||
pub use finalize::*;
|
||||
|
||||
pub mod input;
|
||||
pub use input::*;
|
||||
|
||||
@ -49,6 +46,8 @@ use std::fmt;
|
||||
pub struct Function {
|
||||
/// Annotations on the function.
|
||||
pub annotations: Vec<Annotation>,
|
||||
/// Is this function asynchronous or synchronous?
|
||||
pub is_async: bool,
|
||||
/// Is this function a transition, inlined, or a regular function?.
|
||||
pub variant: Variant,
|
||||
/// The function identifier, e.g., `foo` in `function foo(...) { ... }`.
|
||||
@ -61,8 +60,6 @@ pub struct Function {
|
||||
pub output_type: Type,
|
||||
/// The body of the function.
|
||||
pub block: Block,
|
||||
/// An optional finalize block
|
||||
pub finalize: Option<Finalize>,
|
||||
/// The entire span of the function definition.
|
||||
pub span: Span,
|
||||
/// The ID of the node.
|
||||
@ -82,12 +79,12 @@ impl Function {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
annotations: Vec<Annotation>,
|
||||
is_async: bool,
|
||||
variant: Variant,
|
||||
identifier: Identifier,
|
||||
input: Vec<Input>,
|
||||
output: Vec<Output>,
|
||||
block: Block,
|
||||
finalize: Option<Finalize>,
|
||||
span: Span,
|
||||
id: NodeID,
|
||||
) -> Self {
|
||||
@ -103,7 +100,7 @@ impl Function {
|
||||
_ => Type::Tuple(TupleType::new(output.iter().map(get_output_type).collect())),
|
||||
};
|
||||
|
||||
Function { annotations, variant, identifier, input, output, output_type, block, finalize, span, id }
|
||||
Function { annotations, is_async, variant, identifier, input, output, output_type, block, span, id }
|
||||
}
|
||||
|
||||
/// Returns function name.
|
||||
@ -129,28 +126,22 @@ impl Function {
|
||||
_ => self.output.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(","),
|
||||
};
|
||||
write!(f, "({parameters}) -> {returns} {}", self.block)?;
|
||||
|
||||
if let Some(finalize) = &self.finalize {
|
||||
let parameters = finalize.input.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(",");
|
||||
write!(f, " finalize ({parameters}) {}", finalize.block)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FunctionStub> for Function {
|
||||
fn from(function: FunctionStub) -> Self {
|
||||
let finalize = function.finalize_stub.map(Finalize::from);
|
||||
Self {
|
||||
annotations: function.annotations,
|
||||
is_async: false,
|
||||
variant: function.variant,
|
||||
identifier: function.identifier,
|
||||
input: function.input,
|
||||
output: function.output,
|
||||
output_type: function.output_type,
|
||||
block: Block::default(),
|
||||
finalize,
|
||||
span: function.span,
|
||||
id: function.id,
|
||||
}
|
||||
|
@ -1,102 +0,0 @@
|
||||
// Copyright (C) 2019-2023 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Finalize, FunctionInput, Identifier, Input, Mode, Node, NodeID, Output, TupleType, Type};
|
||||
|
||||
use leo_span::{Span, Symbol};
|
||||
|
||||
use core::fmt;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use snarkvm::{
|
||||
prelude::{
|
||||
FinalizeType::{Future, Plaintext},
|
||||
Network,
|
||||
},
|
||||
synthesizer::program::{CommandTrait, FinalizeCore},
|
||||
};
|
||||
|
||||
/// A finalize stub.
|
||||
#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, Debug)]
|
||||
pub struct FinalizeStub {
|
||||
/// The finalize identifier.
|
||||
pub identifier: Identifier,
|
||||
/// The finalize block's input parameters.
|
||||
pub input: Vec<Input>,
|
||||
/// The finalize blocks's output declaration.
|
||||
pub output: Vec<Output>,
|
||||
/// The finalize block's output type.
|
||||
pub output_type: Type,
|
||||
/// The entire span of the finalize stub.
|
||||
pub span: Span,
|
||||
/// The ID of the node.
|
||||
pub id: NodeID,
|
||||
}
|
||||
|
||||
impl FinalizeStub {
|
||||
/// Create a new finalize stub.
|
||||
pub fn new(identifier: Identifier, input: Vec<Input>, output: Vec<Output>, span: Span, id: NodeID) -> Self {
|
||||
let output_type = match output.len() {
|
||||
0 => Type::Unit,
|
||||
1 => output[0].type_(),
|
||||
_ => Type::Tuple(TupleType::new(output.iter().map(|output| output.type_()).collect())),
|
||||
};
|
||||
|
||||
Self { identifier, input, output, output_type, span, id }
|
||||
}
|
||||
|
||||
pub fn from_snarkvm<N: Network, Command: CommandTrait<N>>(
|
||||
finalize: &FinalizeCore<N, Command>,
|
||||
program: Symbol,
|
||||
) -> Self {
|
||||
let mut inputs = Vec::new();
|
||||
|
||||
finalize.inputs().iter().enumerate().for_each(|(index, input)| {
|
||||
let arg_name = Identifier::new(Symbol::intern(&format!("a{}", index + 1)), Default::default());
|
||||
match input.finalize_type() {
|
||||
Plaintext(val) => inputs.push(Input::Internal(FunctionInput {
|
||||
identifier: arg_name,
|
||||
mode: Mode::None,
|
||||
type_: Type::from_snarkvm(val, program),
|
||||
span: Default::default(),
|
||||
id: Default::default(),
|
||||
})),
|
||||
Future(_) => {} // Don't need to worry about nested futures
|
||||
}
|
||||
});
|
||||
|
||||
Self::new(Identifier::from(finalize.name()), inputs, Vec::new(), Default::default(), Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Finalize> for FinalizeStub {
|
||||
fn from(finalize: Finalize) -> Self {
|
||||
Self::new(finalize.identifier, finalize.input, finalize.output, Default::default(), Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for FinalizeStub {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let parameters = self.input.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(",");
|
||||
let returns = match self.output.len() {
|
||||
0 => "()".to_string(),
|
||||
1 => self.output[0].to_string(),
|
||||
_ => format!("({})", self.output.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(",")),
|
||||
};
|
||||
write!(f, " finalize {}({parameters}) -> {returns}", self.identifier)
|
||||
}
|
||||
}
|
||||
|
||||
crate::simple_node_impl!(FinalizeStub);
|
@ -14,32 +14,14 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{
|
||||
finalize_stub::*,
|
||||
Annotation,
|
||||
CompositeType,
|
||||
External,
|
||||
Function,
|
||||
FunctionInput,
|
||||
FunctionOutput,
|
||||
Identifier,
|
||||
Input,
|
||||
Mode,
|
||||
Node,
|
||||
NodeID,
|
||||
Output,
|
||||
ProgramId,
|
||||
TupleType,
|
||||
Type,
|
||||
Variant,
|
||||
};
|
||||
use crate::{Annotation, CompositeType, External, Function, FunctionInput, FunctionOutput, Identifier, Input, Mode, Node, NodeID, Output, ProgramId, TupleType, Type, Variant, FutureType};
|
||||
use leo_span::{sym, Span, Symbol};
|
||||
|
||||
use crate::Type::Composite;
|
||||
use itertools::Itertools;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use snarkvm::{
|
||||
console::program::RegisterType::{ExternalRecord, Future, Plaintext, Record},
|
||||
console::program::{RegisterType::{ExternalRecord, Future, Plaintext, Record}, FinalizeType::{Future as FutureFinalizeType, Plaintext as PlaintextFinalizeType}},
|
||||
prelude::{Network, ValueType},
|
||||
synthesizer::program::{ClosureCore, CommandTrait, FunctionCore, InstructionTrait},
|
||||
};
|
||||
@ -50,6 +32,8 @@ use std::fmt;
|
||||
pub struct FunctionStub {
|
||||
/// Annotations on the function.
|
||||
pub annotations: Vec<Annotation>,
|
||||
/// Is this function asynchronous or synchronous?
|
||||
pub is_async: bool,
|
||||
/// Is this function a transition, inlined, or a regular function?.
|
||||
pub variant: Variant,
|
||||
/// The function identifier, e.g., `foo` in `function foo(...) { ... }`.
|
||||
@ -60,8 +44,6 @@ pub struct FunctionStub {
|
||||
pub output: Vec<Output>,
|
||||
/// The function's output type.
|
||||
pub output_type: Type,
|
||||
/// An optional finalize stub
|
||||
pub finalize_stub: Option<FinalizeStub>,
|
||||
/// The entire span of the function definition.
|
||||
pub span: Span,
|
||||
/// The ID of the node.
|
||||
@ -81,11 +63,11 @@ impl FunctionStub {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
annotations: Vec<Annotation>,
|
||||
is_async: bool,
|
||||
variant: Variant,
|
||||
identifier: Identifier,
|
||||
input: Vec<Input>,
|
||||
output: Vec<Output>,
|
||||
finalize_stub: Option<FinalizeStub>,
|
||||
span: Span,
|
||||
id: NodeID,
|
||||
) -> Self {
|
||||
@ -101,7 +83,7 @@ impl FunctionStub {
|
||||
_ => Type::Tuple(TupleType::new(output.iter().map(get_output_type).collect())),
|
||||
};
|
||||
|
||||
FunctionStub { annotations, variant, identifier, input, output, output_type, finalize_stub, span, id }
|
||||
FunctionStub { annotations, is_async, variant, identifier, input, output, output_type, span, id }
|
||||
}
|
||||
|
||||
/// Returns function name.
|
||||
@ -133,12 +115,7 @@ impl FunctionStub {
|
||||
};
|
||||
write!(f, "({parameters}) -> {returns}")?;
|
||||
|
||||
if let Some(finalize) = &self.finalize_stub {
|
||||
let parameters = finalize.input.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(",");
|
||||
write!(f, " finalize ({parameters})")
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Converts from snarkvm function type to leo FunctionStub, while also carrying the parent program name.
|
||||
@ -204,6 +181,7 @@ impl FunctionStub {
|
||||
|
||||
Self {
|
||||
annotations: Vec::new(),
|
||||
is_async: function.finalize_logic().is_some(),
|
||||
variant: Variant::Transition,
|
||||
identifier: Identifier::from(function.name()),
|
||||
input: function
|
||||
@ -254,12 +232,45 @@ impl FunctionStub {
|
||||
.collect_vec(),
|
||||
output: outputs,
|
||||
output_type,
|
||||
finalize_stub: function.finalize_logic().map(|f| FinalizeStub::from_snarkvm(f, program)),
|
||||
span: Default::default(),
|
||||
id: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_finalize<N: Network, Instruction: InstructionTrait<N>, Command: CommandTrait<N>>(
|
||||
function: &FunctionCore<N, Instruction, Command>,
|
||||
name: Symbol,
|
||||
) -> Self {
|
||||
Self {
|
||||
annotations: Vec::new(),
|
||||
is_async: true,
|
||||
variant: Variant::Transition,
|
||||
identifier: Identifier::new(name, Default::default()),
|
||||
input: function.finalize_logic().unwrap().inputs().iter().enumerate().map(|(index, input)| {
|
||||
Input::Internal(FunctionInput {
|
||||
identifier: Identifier::new(Symbol::intern(&format!("a{}", index + 1)), Default::default()),
|
||||
mode: Mode::Public,
|
||||
type_: match input.finalize_type() {
|
||||
PlaintextFinalizeType(val) => Type::from_snarkvm(&val, name),
|
||||
FutureFinalizeType(_) => Type::Future(Default::default()),
|
||||
},
|
||||
span: Default::default(),
|
||||
id: Default::default(),
|
||||
})
|
||||
}).collect_vec(),
|
||||
output: vec![Output::Internal(FunctionOutput {
|
||||
mode: Mode::Public,
|
||||
type_: Type::Future(FutureType { inputs: None} ),
|
||||
span: Default::default(),
|
||||
id: 0,
|
||||
})
|
||||
],
|
||||
output_type: Type::Future(FutureType { inputs: None}),
|
||||
span: Default::default(),
|
||||
id: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_closure<N: Network, Instruction: InstructionTrait<N>>(
|
||||
closure: &ClosureCore<N, Instruction>,
|
||||
program: Symbol,
|
||||
@ -293,6 +304,7 @@ impl FunctionStub {
|
||||
};
|
||||
Self {
|
||||
annotations: Vec::new(),
|
||||
is_async: false,
|
||||
variant: Variant::Standard,
|
||||
identifier: Identifier::from(closure.name()),
|
||||
input: closure
|
||||
@ -319,7 +331,6 @@ impl FunctionStub {
|
||||
output_type,
|
||||
span: Default::default(),
|
||||
id: Default::default(),
|
||||
finalize_stub: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -328,12 +339,12 @@ impl From<Function> for FunctionStub {
|
||||
fn from(function: Function) -> Self {
|
||||
Self {
|
||||
annotations: function.annotations,
|
||||
is_async: function.is_async,
|
||||
variant: function.variant,
|
||||
identifier: function.identifier,
|
||||
input: function.input,
|
||||
output: function.output,
|
||||
output_type: function.output_type,
|
||||
finalize_stub: function.finalize.map(FinalizeStub::from),
|
||||
span: function.span,
|
||||
id: function.id,
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ type CurrentNetwork = Testnet3;
|
||||
|
||||
use leo_ast::{Composite, FunctionStub, Identifier, Mapping, ProgramId, Stub};
|
||||
use leo_errors::UtilError;
|
||||
use leo_span::Symbol;
|
||||
|
||||
pub fn disassemble<N: Network, Instruction: InstructionTrait<N>, Command: CommandTrait<N>>(
|
||||
program: ProgramCore<N, Instruction, Command>,
|
||||
@ -65,6 +66,20 @@ pub fn disassemble<N: Network, Instruction: InstructionTrait<N>, Command: Comman
|
||||
(Identifier::from(id).name, FunctionStub::from_function_core(function, program_id.name.name))
|
||||
})
|
||||
.collect_vec(),
|
||||
program
|
||||
.functions()
|
||||
.iter()
|
||||
.filter_map(|(id, function)| match function.finalize_logic() {
|
||||
Some(f) => {
|
||||
let name = Symbol::intern(&format!(
|
||||
"finalize/{}",
|
||||
Symbol::intern(&Identifier::from(id).name.to_string())
|
||||
));
|
||||
Some((name, FunctionStub::from_finalize(f, name)))
|
||||
}
|
||||
None => None,
|
||||
})
|
||||
.collect_vec(),
|
||||
]
|
||||
.concat(),
|
||||
span: Default::default(),
|
||||
|
Loading…
Reference in New Issue
Block a user