compiler: Check call result emission
694546bb6afa877ec9f19f19a12318c240861d38c1fc1edb580315f853a66976
1 parent
90c7b202
lib/std/lang/lower.rad
+21 -15
| 7217 | 7217 | /// |
|
| 7218 | 7218 | /// All call lowering paths (regular, trait method, standalone method) converge |
|
| 7219 | 7219 | /// here after preparing the callee value, function type, and argument array. |
|
| 7220 | 7220 | /// The `args` slice must already include a slot at index zero for the hidden |
|
| 7221 | 7221 | /// return parameter; that slot is filled by this function. |
|
| 7222 | - | unsafe fn emitCallValue 'arena 'phase 'function ( |
|
| 7222 | + | fn emitCallValue 'arena 'phase 'function ( |
|
| 7223 | 7223 | self: &mut FnLowerer 'arena 'phase 'function, |
|
| 7224 | 7224 | callee: il::Val, |
|
| 7225 | 7225 | fnInfo: *resolver::FnType, |
|
| 7226 | 7226 | args: *mut [il::Val], |
|
| 7227 | 7227 | ) -> il::Val throws (LowerError) where 'arena: 'phase, 'phase: 'function { |
|
| 7228 | 7228 | let retTy = *fnInfo.returnType; |
|
| 7229 | 7229 | ||
| 7230 | 7230 | if requiresReturnParam(fnInfo) { |
|
| 7231 | 7231 | if fnInfo.throwList.len > 0 { |
|
| 7232 | - | let layout = resolver::getResultLayout(retTy, fnInfo.throwList); |
|
| 7233 | - | set args[0] = il::Val::Reg(emitReserveLayout(self, layout)); |
|
| 7232 | + | unsafe { |
|
| 7233 | + | let layout = resolver::getResultLayout(retTy, fnInfo.throwList); |
|
| 7234 | + | set args[0] = il::Val::Reg(emitReserveLayout(self, layout)); |
|
| 7235 | + | } |
|
| 7234 | 7236 | } else { |
|
| 7235 | 7237 | set args[0] = il::Val::Reg(try emitReserve(self, retTy)); |
|
| 7236 | 7238 | } |
|
| 7237 | 7239 | let dst = nextReg(self); |
|
| 7238 | 7240 | ||
| 7239 | - | emit(self, il::Instr::Call { |
|
| 7240 | - | retTy: il::Type::W64, |
|
| 7241 | - | dst, |
|
| 7242 | - | func: callee, |
|
| 7243 | - | args: (&mut args[..]) as *unsafe mut [il::Val], |
|
| 7244 | - | }); |
|
| 7241 | + | unsafe { |
|
| 7242 | + | emit(self, il::Instr::Call { |
|
| 7243 | + | retTy: il::Type::W64, |
|
| 7244 | + | dst, |
|
| 7245 | + | func: callee, |
|
| 7246 | + | args: (&mut args[..]) as *unsafe mut [il::Val], |
|
| 7247 | + | }); |
|
| 7248 | + | } |
|
| 7245 | 7249 | return il::Val::Reg(dst); |
|
| 7246 | 7250 | } |
|
| 7247 | 7251 | let mut dst: ?il::Reg = nil; |
|
| 7248 | 7252 | if retTy <> resolver::Type::Void and retTy <> resolver::Type::Never { |
|
| 7249 | 7253 | set dst = nextReg(self); |
|
| 7250 | 7254 | } |
|
| 7251 | - | emit(self, il::Instr::Call { |
|
| 7252 | - | retTy: ilType(self.low, retTy), |
|
| 7253 | - | dst, |
|
| 7254 | - | func: callee, |
|
| 7255 | - | args: (&mut args[..]) as *unsafe mut [il::Val], |
|
| 7256 | - | }); |
|
| 7255 | + | unsafe { |
|
| 7256 | + | emit(self, il::Instr::Call { |
|
| 7257 | + | retTy: ilType(self.low, retTy), |
|
| 7258 | + | dst, |
|
| 7259 | + | func: callee, |
|
| 7260 | + | args: (&mut args[..]) as *unsafe mut [il::Val], |
|
| 7261 | + | }); |
|
| 7262 | + | } |
|
| 7257 | 7263 | ||
| 7258 | 7264 | if retTy == resolver::Type::Never { |
|
| 7259 | 7265 | emit(self, il::Instr::Unreachable); |
|
| 7260 | 7266 | } |
|
| 7261 | 7267 | if let d = dst { |