Skip to content

Commit 95c9654

Browse files
committed
Refactor debug recorder to unify entrypoint and contract recorders
1 parent 9b22f76 commit 95c9654

File tree

4 files changed

+492
-290
lines changed

4 files changed

+492
-290
lines changed

silverscript-lang/src/compiler.rs

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::span;
1616

1717
mod debug_recording;
1818

19-
use debug_recording::{ContractRecorder, EntrypointRecorder};
19+
use debug_recording::DebugRecorder;
2020
/// Prefix used for synthetic argument bindings during inline function expansion.
2121
pub const SYNTHETIC_ARG_PREFIX: &str = "__arg_";
2222

@@ -111,7 +111,7 @@ fn compile_contract_impl<'i>(
111111
let (_contract_fields, field_prolog_script) = compile_contract_fields(&contract.fields, &constants, options, script_size)?;
112112

113113
let mut compiled_entrypoints = Vec::new();
114-
let mut recorder = ContractRecorder::new(options.record_debug_infos);
114+
let mut recorder = DebugRecorder::new(options.record_debug_infos);
115115
recorder.record_constructor_constants(&contract.params, constructor_args);
116116
for (index, func) in contract.functions.iter().enumerate() {
117117
if func.entrypoint {
@@ -125,28 +125,29 @@ fn compile_contract_impl<'i>(
125125
&functions_map,
126126
&function_order,
127127
script_size,
128+
&mut recorder,
128129
)?);
129130
}
130131
}
131132

132133
let entrypoint_script = if without_selector {
133-
let compiled = compiled_entrypoints
134+
let (name, script) = compiled_entrypoints
134135
.first()
135136
.ok_or_else(|| CompilerError::Unsupported("contract has no entrypoint functions".to_string()))?;
136-
recorder.record_compiled_entrypoint(&compiled.name, compiled.script.len(), &compiled.debug, field_prolog_script.len());
137-
compiled.script.clone()
137+
recorder.set_entrypoint_start(name, field_prolog_script.len());
138+
script.clone()
138139
} else {
139140
let mut builder = ScriptBuilder::new();
140141
let total = compiled_entrypoints.len();
141-
for (index, compiled) in compiled_entrypoints.iter().enumerate() {
142+
for (index, (name, script)) in compiled_entrypoints.iter().enumerate() {
142143
builder.add_op(OpDup)?;
143144
builder.add_i64(index as i64)?;
144145
builder.add_op(OpNumEqual)?;
145146
builder.add_op(OpIf)?;
146147
builder.add_op(OpDrop)?;
147148
let start = field_prolog_script.len() + builder.script().len();
148-
recorder.record_compiled_entrypoint(&compiled.name, compiled.script.len(), &compiled.debug, start);
149-
builder.add_ops(&compiled.script)?;
149+
recorder.set_entrypoint_start(name, start);
150+
builder.add_ops(script)?;
150151
builder.add_op(OpElse)?;
151152
if index == total - 1 {
152153
builder.add_op(OpDrop)?;
@@ -907,13 +908,6 @@ pub fn function_branch_index<'i>(contract: &ContractAst<'i>, function_name: &str
907908
.ok_or_else(|| CompilerError::Unsupported(format!("function '{function_name}' not found")))
908909
}
909910

910-
#[derive(Debug)]
911-
struct CompiledEntryPoint<'i> {
912-
name: String,
913-
script: Vec<u8>,
914-
debug: EntrypointRecorder<'i>,
915-
}
916-
917911
fn compile_entrypoint_function<'i>(
918912
function: &FunctionAst<'i>,
919913
function_index: usize,
@@ -924,7 +918,8 @@ fn compile_entrypoint_function<'i>(
924918
functions: &HashMap<String, FunctionAst<'i>>,
925919
function_order: &HashMap<String, usize>,
926920
script_size: Option<i64>,
927-
) -> Result<CompiledEntryPoint<'i>, CompilerError> {
921+
recorder: &mut DebugRecorder<'i>,
922+
) -> Result<(String, Vec<u8>), CompilerError> {
928923
let contract_field_count = contract_fields.len();
929924
let param_count = function.params.len();
930925
let mut params = function
@@ -962,7 +957,6 @@ fn compile_entrypoint_function<'i>(
962957
env.remove(&param.name);
963958
}
964959
let mut builder = ScriptBuilder::new();
965-
let mut recorder = EntrypointRecorder::new(options.record_debug_infos, function, contract_fields);
966960
let mut yields: Vec<Expr> = Vec::new();
967961

968962
if !options.allow_yield && function.body.iter().any(contains_yield) {
@@ -989,9 +983,11 @@ fn compile_entrypoint_function<'i>(
989983
}
990984
}
991985

986+
recorder.begin_entrypoint(&function.name, function, contract_fields);
987+
992988
let body_len = function.body.len();
993989
for (index, stmt) in function.body.iter().enumerate() {
994-
let guard = recorder.begin_statement(&builder, &env);
990+
recorder.begin_statement_at(builder.script().len(), &env);
995991
if let Statement::Return { exprs, .. } = stmt {
996992
if index != body_len - 1 {
997993
return Err(CompilerError::Unsupported("return statement must be the last statement".to_string()));
@@ -1017,11 +1013,11 @@ fn compile_entrypoint_function<'i>(
10171013
function_index,
10181014
&mut yields,
10191015
script_size,
1020-
&mut recorder,
1016+
recorder,
10211017
)
10221018
.map_err(|err| err.with_span(&stmt.span()))?;
10231019
}
1024-
guard.finish(&mut recorder, stmt, &builder, &env, &types)?;
1020+
recorder.finish_statement_at(stmt, builder.script().len(), &env, &types)?;
10251021
}
10261022

10271023
let yield_count = yields.len();
@@ -1060,7 +1056,9 @@ fn compile_entrypoint_function<'i>(
10601056
builder.add_op(OpDrop)?;
10611057
}
10621058
}
1063-
Ok(CompiledEntryPoint { name: function.name.clone(), script: builder.drain(), debug: recorder })
1059+
let script = builder.drain();
1060+
recorder.finish_entrypoint(script.len());
1061+
Ok((function.name.clone(), script))
10641062
}
10651063

10661064
#[allow(clippy::too_many_arguments)]
@@ -1079,7 +1077,7 @@ fn compile_statement<'i>(
10791077
function_index: usize,
10801078
yields: &mut Vec<Expr<'i>>,
10811079
script_size: Option<i64>,
1082-
recorder: &mut EntrypointRecorder<'i>,
1080+
recorder: &mut DebugRecorder<'i>,
10831081
) -> Result<(), CompilerError> {
10841082
match stmt {
10851083
Statement::VariableDefinition { type_ref, name, expr, .. } => {
@@ -1774,7 +1772,7 @@ fn compile_inline_call<'i>(
17741772
function_order: &HashMap<String, usize>,
17751773
caller_index: usize,
17761774
script_size: Option<i64>,
1777-
recorder: &mut EntrypointRecorder<'i>,
1775+
recorder: &mut DebugRecorder<'i>,
17781776
) -> Result<Vec<Expr<'i>>, CompilerError> {
17791777
let function = functions.get(name).ok_or_else(|| CompilerError::Unsupported(format!("function '{}' not found", name)))?;
17801778
let callee_index =
@@ -1848,7 +1846,7 @@ fn compile_inline_call<'i>(
18481846
let params = caller_params.clone();
18491847
let body_len = function.body.len();
18501848
for (index, stmt) in function.body.iter().enumerate() {
1851-
let guard = recorder.begin_statement(builder, &env);
1849+
recorder.begin_statement_at(builder.script().len(), &env);
18521850
if let Statement::Return { exprs, .. } = stmt {
18531851
if index != body_len - 1 {
18541852
return Err(CompilerError::Unsupported("return statement must be the last statement".to_string()));
@@ -1879,7 +1877,7 @@ fn compile_inline_call<'i>(
18791877
)
18801878
.map_err(|err| err.with_span(&stmt.span()))?;
18811879
}
1882-
guard.finish(recorder, stmt, builder, &env, &types)?;
1880+
recorder.finish_statement_at(stmt, builder.script().len(), &env, &types)?;
18831881
}
18841882
let call_end = builder.script().len();
18851883
recorder.finish_inline_call(call_span, call_end, name);
@@ -1914,7 +1912,7 @@ fn compile_if_statement<'i>(
19141912
function_index: usize,
19151913
yields: &mut Vec<Expr<'i>>,
19161914
script_size: Option<i64>,
1917-
recorder: &mut EntrypointRecorder<'i>,
1915+
recorder: &mut DebugRecorder<'i>,
19181916
) -> Result<(), CompilerError> {
19191917
let mut stack_depth = 0i64;
19201918
compile_expr(
@@ -2053,10 +2051,10 @@ fn compile_block<'i>(
20532051
function_index: usize,
20542052
yields: &mut Vec<Expr<'i>>,
20552053
script_size: Option<i64>,
2056-
recorder: &mut EntrypointRecorder<'i>,
2054+
recorder: &mut DebugRecorder<'i>,
20572055
) -> Result<(), CompilerError> {
20582056
for stmt in statements {
2059-
let guard = recorder.begin_statement(builder, env);
2057+
recorder.begin_statement_at(builder.script().len(), env);
20602058
compile_statement(
20612059
stmt,
20622060
env,
@@ -2075,7 +2073,7 @@ fn compile_block<'i>(
20752073
recorder,
20762074
)
20772075
.map_err(|err| err.with_span(&stmt.span()))?;
2078-
guard.finish(recorder, stmt, builder, env, types)?;
2076+
recorder.finish_statement_at(stmt, builder.script().len(), env, types)?;
20792077
}
20802078
Ok(())
20812079
}
@@ -2100,7 +2098,7 @@ fn compile_for_statement<'i>(
21002098
function_index: usize,
21012099
yields: &mut Vec<Expr<'i>>,
21022100
script_size: Option<i64>,
2103-
recorder: &mut EntrypointRecorder<'i>,
2101+
recorder: &mut DebugRecorder<'i>,
21042102
) -> Result<(), CompilerError> {
21052103
let start = eval_const_int(start_expr, contract_constants)?;
21062104
let end = eval_const_int(end_expr, contract_constants)?;
@@ -2113,7 +2111,7 @@ fn compile_for_statement<'i>(
21132111
let previous = env.get(&name).cloned();
21142112
for value in start..end {
21152113
env.insert(name.clone(), Expr::int(value));
2116-
recorder.record_binding(name.clone(), "int".to_string(), Expr::int(value), builder.script().len(), loop_span);
2114+
recorder.record_variable_binding(name.clone(), "int".to_string(), Expr::int(value), builder.script().len(), loop_span);
21172115
compile_block(
21182116
body,
21192117
env,

0 commit comments

Comments
 (0)