|
1 | | -use std::fmt; |
| 1 | +use std::{fmt, sync::Arc}; |
2 | 2 |
|
| 3 | +use crate::CallableValue; |
3 | 4 | use crate::builtins::BuiltinFunction; |
4 | 5 | use crate::vm::{OpCode, Program, Value, ValueType, checked_int_div}; |
5 | 6 |
|
@@ -1245,6 +1246,55 @@ pub(crate) fn record_trace_with_local_count( |
1245 | 1246 | if inline_frame.is_none() |
1246 | 1247 | && let Ok(candidate) = candidate |
1247 | 1248 | { |
| 1249 | + let prototype = &program.callable_prototypes[candidate.prototype_id as usize]; |
| 1250 | + let expected_callable = builder |
| 1251 | + .append_value_inst( |
| 1252 | + current_block, |
| 1253 | + ip, |
| 1254 | + SsaValueRepr::Tagged, |
| 1255 | + SsaInstKind::Constant(Value::Callable(Arc::new(CallableValue { |
| 1256 | + prototype_id: candidate.prototype_id, |
| 1257 | + kind: prototype.kind, |
| 1258 | + env: None, |
| 1259 | + }))), |
| 1260 | + ) |
| 1261 | + .map_err(|err| TraceRecordError::InvalidIr(err.to_string()))?; |
| 1262 | + let callable_matches = builder |
| 1263 | + .append_value_inst( |
| 1264 | + current_block, |
| 1265 | + ip, |
| 1266 | + SsaValueRepr::Bool, |
| 1267 | + SsaInstKind::ValueCmpEq { |
| 1268 | + lhs: callable.value.id, |
| 1269 | + rhs: expected_callable.id, |
| 1270 | + }, |
| 1271 | + ) |
| 1272 | + .map_err(|err| TraceRecordError::InvalidIr(err.to_string()))?; |
| 1273 | + let identity_exit = |
| 1274 | + add_symbolic_exit(&mut builder, ip, &frame, inline_frame.as_ref()); |
| 1275 | + let (guarded_block, guarded_frame, guard_args) = continue_with_inline_frame( |
| 1276 | + &mut builder, |
| 1277 | + &frame, |
| 1278 | + &mut inline_frame, |
| 1279 | + "inline_callable_identity", |
| 1280 | + )?; |
| 1281 | + builder |
| 1282 | + .set_terminator( |
| 1283 | + current_block, |
| 1284 | + SsaTerminator::BranchBool { |
| 1285 | + condition: callable_matches.id, |
| 1286 | + if_true: SsaBranchTarget::Block { |
| 1287 | + target: guarded_block, |
| 1288 | + args: guard_args, |
| 1289 | + }, |
| 1290 | + if_false: SsaBranchTarget::Exit(identity_exit), |
| 1291 | + }, |
| 1292 | + ) |
| 1293 | + .map_err(|err| TraceRecordError::InvalidIr(err.to_string()))?; |
| 1294 | + current_block = guarded_block; |
| 1295 | + frame = guarded_frame; |
| 1296 | + op_names.push("inline_callable_identity_guard".to_string()); |
| 1297 | + |
1248 | 1298 | let operand_base = frame.stack.len() - usize::from(argc) - 1; |
1249 | 1299 | let mut operands = frame.stack.split_off(operand_base); |
1250 | 1300 | let _callable = operands.remove(0); |
|
0 commit comments