compiler: Own function descriptors until IL publication

812133279aaf8913ee8fb4918d992ffd53fdf497df668137a7813125dc1d5456
Alexis Sellier committed ago 1 parent e76df48f
lib/std/lang/lower.rad +5 -5
1105 1105
        // as the first argument; the callee writes the return value into it.
1106 1106
        if requiresReturnParam(fnType) and not isExtern {
1107 1107
            set fnLow.returnReg = nextReg(&mut fnLow);
1108 1108
        }
1109 1109
        let lowParams = try lowerParams(&mut fnLow, *fnType, decl.sig.params, nil);
1110 -
        let func = try! alloc::allocRaw(fnLow.arena, @sizeOf(il::Fn), @alignOf(il::Fn)) as *unsafe mut il::Fn;
1110 +
        let func = try! alloc::alloc(&mut *fnLow.arena, @sizeOf(il::Fn), @alignOf(il::Fn)) as *mut il::Fn;
1111 1111
1112 1112
        // Throwing functions return a result aggregate (word-sized pointer).
1113 1113
        // TODO: The resolver should set an appropriate type that takes into account
1114 1114
        //       the throws list. It shouldn't set the return type to the "success"
1115 1115
        //       value only.
1124 1124
            blocks: &[],
1125 1125
        };
1126 1126
        let body = decl.body else {
1127 1127
            // Extern functions have no body.
1128 1128
            assert isExtern;
1129 -
            return func;
1129 +
            return (&*func) as *unsafe il::Fn;
1130 1130
        };
1131 1131
        set func.blocks = try lowerFnBody(&mut fnLow, body);
1132 1132
        set func.isLeaf = fnLow.isLeaf;
1133 1133
1134 -
        return func;
1134 +
        return (&*func) as *unsafe il::Fn;
1135 1135
    }
1136 1136
}
1137 1137
1138 1138
/// Build a qualified name of the form "Type::method".
1139 1139
unsafe fn instanceMethodName 'arena 'phase (self: &mut Lowerer 'arena 'phase, modId: ?u16, typeName: *[u8], methodName: *[u8]) -> *[u8] where 'arena: 'phase {
1272 1272
        let mut fnLow = fnLowerer(parent, node.span.offset, fnType, qualName, arena, variables);
1273 1273
        if requiresReturnParam(fnType) {
1274 1274
            set fnLow.returnReg = nextReg(&mut fnLow);
1275 1275
        }
1276 1276
        let lowParams = try lowerParams(&mut fnLow, *fnType, sig.params, receiverName);
1277 -
        let func = try! alloc::allocRaw(fnLow.arena, @sizeOf(il::Fn), @alignOf(il::Fn)) as *unsafe mut il::Fn;
1277 +
        let func = try! alloc::alloc(&mut *fnLow.arena, @sizeOf(il::Fn), @alignOf(il::Fn)) as *mut il::Fn;
1278 1278
1279 1279
        let returnType = il::Type::W64 if fnType.throwList.len > 0
1280 1280
            else ilType(fnLow.low, *fnType.returnType);
1281 1281
        set *func = il::Fn {
1282 1282
            name: qualName,
1287 1287
            blocks: &[],
1288 1288
        };
1289 1289
        set func.blocks = try lowerFnBody(&mut fnLow, body);
1290 1290
        set func.isLeaf = fnLow.isLeaf;
1291 1291
1292 -
        return func;
1292 +
        return (&*func) as *unsafe il::Fn;
1293 1293
    }
1294 1294
}
1295 1295
1296 1296
/// Lower a standalone method declaration.
1297 1297
/// Produces a function with qualified name `Type::method`.
test/tests/ssa.instruction.storage.rad +12 -0
4 4
record Input: Copy {
5 5
    /// Full-width input retained by the receiver.
6 6
    value: u64,
7 7
}
8 8
9 +
/// Construct an aggregate through a regular function return.
10 +
fn makeInput(value: u64) -> Input {
11 +
    return Input { value };
12 +
}
13 +
14 +
/// Return an aggregate after nested function calls from a method.
15 +
fn (input: &Input) advanced() -> Input {
16 +
    return makeInput(advance(input.value));
17 +
}
18 +
9 19
/// Lower a method with a receiver, explicit parameter, and nested calls.
10 20
fn (input: &Input) combine(selected: bool) -> u64 {
11 21
    return combine(input.value, selected);
12 22
}
13 23
36 46
        let value = (index as u64) + 0x100000000;
37 47
        let base = (value + 7) * 3 + (value + 14) * 5;
38 48
        assert combine(value, true) == base + (value + 21) * 11;
39 49
        assert combine(value, false) == base + (value + 21) * 13;
40 50
        let input = Input { value };
51 +
        let advanced = input.advanced();
52 +
        assert advanced.value == value + 7;
41 53
        assert input.combine(true) == base + (value + 21) * 11;
42 54
        assert input.combine(false) == base + (value + 21) * 13;
43 55
    }
44 56
    return 0;
45 57
}