compiler: Build initialized function parameter tables
8a2ef421ff998c0cebb8c28ed62308dcb048fc9ade0114d701ec4f75ea29a6a0
1 parent
7988f48b
lib/std/lang/lower.rad
+4 -6
| 3237 | 3237 | if totalLen == 0 { |
|
| 3238 | 3238 | return &[]; |
|
| 3239 | 3239 | } |
|
| 3240 | 3240 | assert fnType.paramTypes.len as u32 <= resolver::MAX_FN_PARAMS; |
|
| 3241 | 3241 | ||
| 3242 | - | let params = try! alloc::allocRawSlice( |
|
| 3243 | - | self.arena, @sizeOf(il::Param), @alignOf(il::Param), totalLen |
|
| 3244 | - | ) as *unsafe mut [il::Param]; |
|
| 3242 | + | let mut params: *mut [il::Param] = &mut []; |
|
| 3245 | 3243 | ||
| 3246 | 3244 | if let reg = self.returnReg { |
|
| 3247 | - | set params[0] = il::Param { value: reg, type: il::Type::W64 }; |
|
| 3245 | + | params.append(il::Param { value: reg, type: il::Type::W64 }, alloc::arenaAllocator(self.arena)); |
|
| 3248 | 3246 | } |
|
| 3249 | 3247 | for i in 0..fnType.paramTypes.len as u32 { |
|
| 3250 | 3248 | let type = ilType(self.low, *fnType.paramTypes[i]); |
|
| 3251 | 3249 | let reg = nextReg(self); |
|
| 3252 | 3250 | ||
| 3253 | - | set params[i + offset] = il::Param { value: reg, type }; |
|
| 3251 | + | params.append(il::Param { value: reg, type }, alloc::arenaAllocator(self.arena)); |
|
| 3254 | 3252 | ||
| 3255 | 3253 | // Declare the parameter variable. For the receiver, the name comes |
|
| 3256 | 3254 | // from the receiver node. |
|
| 3257 | 3255 | // For all other parameters, the name comes from the AST params. |
|
| 3258 | 3256 | let mut name: *[u8] = undefined; |
| 3271 | 3269 | let v = newVar(self, name, type, false, il::Val::Undef); |
|
| 3272 | 3270 | ||
| 3273 | 3271 | set self.params[i] = FnParamBinding { var: v, reg }; |
|
| 3274 | 3272 | set self.paramsLen += 1; |
|
| 3275 | 3273 | } |
|
| 3276 | - | return params; |
|
| 3274 | + | return (¶ms[..]) as *unsafe [il::Param]; |
|
| 3277 | 3275 | } |
|
| 3278 | 3276 | ||
| 3279 | 3277 | /// Resolve match subject. |
|
| 3280 | 3278 | unsafe fn lowerMatchSubject 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, subject: *ast::Node) -> MatchSubject throws (LowerError) where 'arena: 'phase, 'phase: 'function { |
|
| 3281 | 3279 | let mut val = try lowerExpr(self, subject); |
test/tests/fn.parameter.table.rad
added
+46 -0
| 1 | + | //! returns: 0 |
|
| 2 | + | ||
| 3 | + | /// Aggregate result that uses a hidden return-buffer parameter. |
|
| 4 | + | record Result: Copy { |
|
| 5 | + | /// Weighted argument sum. |
|
| 6 | + | sum: u32, |
|
| 7 | + | /// Last argument. |
|
| 8 | + | last: u64, |
|
| 9 | + | } |
|
| 10 | + | ||
| 11 | + | /// Return a scalar without explicit parameters. |
|
| 12 | + | fn zero() -> u32 { |
|
| 13 | + | return 17; |
|
| 14 | + | } |
|
| 15 | + | ||
| 16 | + | /// Return an aggregate without explicit parameters. |
|
| 17 | + | fn empty() -> Result { |
|
| 18 | + | return Result { sum: 19, last: 0x100000000 }; |
|
| 19 | + | } |
|
| 20 | + | ||
| 21 | + | /// Check each of the eight scalar parameter positions. |
|
| 22 | + | fn scalar(a: u32, b: u32, c: u32, d: u32, e: u32, f: u32, g: u32, h: u32) -> u32 { |
|
| 23 | + | return a + 2*b + 3*c + 4*d + 5*e + 6*f + 7*g + 8*h; |
|
| 24 | + | } |
|
| 25 | + | ||
| 26 | + | /// Check explicit parameters alongside the hidden return buffer. |
|
| 27 | + | fn aggregate(a: u32, b: u32, c: u32, d: u32, e: u32, f: u32, h: u64) -> Result { |
|
| 28 | + | return Result { sum: scalar(a, b, c, d, e, f, 7, h as u32), last: h }; |
|
| 29 | + | } |
|
| 30 | + | ||
| 31 | + | /// Verify parameter order over repeated scalar and aggregate calls. |
|
| 32 | + | @default fn main() -> u32 { |
|
| 33 | + | assert zero() == 17; |
|
| 34 | + | let initial = empty(); |
|
| 35 | + | assert initial.sum == 19; |
|
| 36 | + | assert initial.last == 0x100000000; |
|
| 37 | + | for index in 0..8 { |
|
| 38 | + | assert scalar(index, 2, 3, 4, 5, 6, 7, 8) == index + 203; |
|
| 39 | + | let result = aggregate(index, 2, 3, 4, 5, 6, 0x100000008); |
|
| 40 | + | assert result.sum == index + 203; |
|
| 41 | + | assert result.last == 0x100000008; |
|
| 42 | + | assert initial.sum == 19; |
|
| 43 | + | assert initial.last == 0x100000000; |
|
| 44 | + | } |
|
| 45 | + | return 0; |
|
| 46 | + | } |