compiler: Check aggregate value emission
22ef76058cc6811e47b63883311d34970a1720f4c7ccc359c806a887e063babc
1 parent
63b266a5
lib/std/lang/lower.rad
+12 -9
| 4444 | 4444 | } |
|
| 4445 | 4445 | return index as i64; |
|
| 4446 | 4446 | } |
|
| 4447 | 4447 | ||
| 4448 | 4448 | /// Reserve stack storage for a value of the given type. |
|
| 4449 | - | unsafe fn emitReserve 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, typ: resolver::Type) -> il::Reg throws (LowerError) where 'arena: 'phase, 'phase: 'function { |
|
| 4450 | - | let layout = resolver::getTypeLayout(typ); |
|
| 4451 | - | return emitReserveLayout(self, layout); |
|
| 4449 | + | fn emitReserve 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, typ: resolver::Type) -> il::Reg throws (LowerError) where 'arena: 'phase, 'phase: 'function { |
|
| 4450 | + | unsafe { |
|
| 4451 | + | let layout = resolver::getTypeLayout(typ); |
|
| 4452 | + | return emitReserveLayout(self, layout); |
|
| 4453 | + | } |
|
| 4452 | 4454 | } |
|
| 4453 | 4455 | ||
| 4454 | 4456 | /// Reserve stack storage with an explicit layout. |
|
| 4455 | 4457 | fn emitReserveLayout 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, layout: resolver::Layout) -> il::Reg where 'arena: 'phase, 'phase: 'function { |
|
| 4456 | 4458 | let dst = nextReg(self); |
| 4462 | 4464 | }); |
|
| 4463 | 4465 | return dst; |
|
| 4464 | 4466 | } |
|
| 4465 | 4467 | ||
| 4466 | 4468 | /// Store a value into an address. |
|
| 4467 | - | unsafe fn emitStore 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, base: il::Reg, offset: i32, typ: resolver::Type, src: il::Val) throws (LowerError) where 'arena: 'phase, 'phase: 'function { |
|
| 4469 | + | fn emitStore 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, base: il::Reg, offset: i32, typ: resolver::Type, src: il::Val) throws (LowerError) where 'arena: 'phase, 'phase: 'function { |
|
| 4468 | 4470 | // `undefined` values need no store. |
|
| 4469 | 4471 | if let case il::Val::Undef = src { |
|
| 4470 | 4472 | return; |
|
| 4471 | 4473 | } |
|
| 4472 | 4474 | if isAggregateType(typ) { |
|
| 4473 | 4475 | let dst = emitPtrOffset(self, base, offset); |
|
| 4474 | 4476 | let src = emitValToReg(self, src); |
|
| 4475 | - | let layout = resolver::getTypeLayout(typ); |
|
| 4476 | - | ||
| 4477 | - | emit(self, il::Instr::Blit { dst, src, size: il::Val::Imm(layout.size as i64) }); |
|
| 4477 | + | unsafe { |
|
| 4478 | + | let layout = resolver::getTypeLayout(typ); |
|
| 4479 | + | emit(self, il::Instr::Blit { dst, src, size: il::Val::Imm(layout.size as i64) }); |
|
| 4480 | + | } |
|
| 4478 | 4481 | } else { |
|
| 4479 | 4482 | emit(self, il::Instr::Store { |
|
| 4480 | 4483 | typ: ilType(self.low, typ), |
|
| 4481 | 4484 | src, |
|
| 4482 | 4485 | dst: base, |
| 4484 | 4487 | }); |
|
| 4485 | 4488 | } |
|
| 4486 | 4489 | } |
|
| 4487 | 4490 | ||
| 4488 | 4491 | /// Allocate stack space for a value and store it. Returns a pointer to the value. |
|
| 4489 | - | unsafe fn emitStackVal 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, typ: resolver::Type, val: il::Val) -> il::Val throws (LowerError) where 'arena: 'phase, 'phase: 'function { |
|
| 4492 | + | fn emitStackVal 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, typ: resolver::Type, val: il::Val) -> il::Val throws (LowerError) where 'arena: 'phase, 'phase: 'function { |
|
| 4490 | 4493 | let ptr = try emitReserve(self, typ); |
|
| 4491 | 4494 | try emitStore(self, ptr, 0, typ, val); |
|
| 4492 | 4495 | return il::Val::Reg(ptr); |
|
| 4493 | 4496 | } |
|
| 4494 | 4497 | ||
| 4495 | 4498 | /// Generic helper to build any tagged aggregate. |
|
| 4496 | 4499 | /// Reserves space based on the provided layout, stores the tag, and optionally |
|
| 4497 | 4500 | /// stores the payload value at `valOffset`. |
|
| 4498 | - | unsafe fn buildTagged 'arena 'phase 'function ( |
|
| 4501 | + | fn buildTagged 'arena 'phase 'function ( |
|
| 4499 | 4502 | self: &mut FnLowerer 'arena 'phase 'function, |
|
| 4500 | 4503 | layout: resolver::Layout, |
|
| 4501 | 4504 | tag: i64, |
|
| 4502 | 4505 | payload: ?il::Val, |
|
| 4503 | 4506 | payloadType: resolver::Type, |