MCPcopy Index your code
hub / github.com/aiscriptdev/aiscript / generate_error_handler

Method generate_error_handler

aiscript-vm/src/compiler/codegen.rs:1275–1328  ·  view source on GitHub ↗
(&mut self, handler: ErrorHandler<'gc>)

Source from the content-addressed store, hash-verified

1273 }
1274
1275 fn generate_error_handler(&mut self, handler: ErrorHandler<'gc>) -> Result<(), VmError> {
1276 let error_jump = self.emit_jump(OpCode::JumpIfError(0));
1277 let end_jump = self.emit_jump(OpCode::Jump(0));
1278
1279 self.patch_jump(error_jump);
1280 if handler.propagate {
1281 // For ? operator, return error directly
1282 self.emit(OpCode::Return);
1283 } else {
1284 let is_local_scope = self.scope_depth > 0;
1285 if is_local_scope {
1286 // since the assign value isn't a local variable
1287 // Give this:
1288 // let x = function_call() |err| {}
1289 // 'x' is a globa variable which don't occupy a local variable slot
1290 self.emit(OpCode::Dup);
1291 }
1292 // Begin scope for error variable
1293 self.begin_scope();
1294 // Store error in handler variable
1295 let err_local_pos = self.declare_variable(handler.error_var, Mutability::Mutable);
1296 self.mark_initialized();
1297
1298 let has_return = matches!(
1299 handler.handler_body.last(),
1300 Some(Stmt::Return { .. }) | Some(Stmt::BlockReturn { .. })
1301 );
1302 // Generate handler body - any return here will return from entire function
1303 for stmt in handler.handler_body {
1304 self.generate_stmt(stmt)?;
1305 }
1306
1307 // Set the last expression of error handle block (aka, stack top value)
1308 // to the faield function call return value.
1309 if is_local_scope {
1310 // We are in local scope, the slot is err_local_pos - 1
1311 self.emit(OpCode::SetLocal(err_local_pos as u8 - 1));
1312 } else {
1313 // We are in global scope, don't need to minus 1
1314 self.emit(OpCode::SetLocal(err_local_pos as u8));
1315 }
1316 self.end_scope();
1317 if is_local_scope {
1318 // Pop the stack top we duplicated before
1319 self.emit(OpCode::Pop(1));
1320 }
1321 // If no return in handler, set nil as value and continue
1322 if !has_return {
1323 self.emit(OpCode::Nil);
1324 }
1325 }
1326 self.patch_jump(end_jump);
1327 Ok(())
1328 }
1329
1330 fn generate_class(
1331 &mut self,

Callers 2

generate_callMethod · 0.80
generate_invokeMethod · 0.80

Calls 8

emit_jumpMethod · 0.80
patch_jumpMethod · 0.80
emitMethod · 0.80
begin_scopeMethod · 0.80
declare_variableMethod · 0.80
mark_initializedMethod · 0.80
generate_stmtMethod · 0.80
end_scopeMethod · 0.80

Tested by

no test coverage detected