aboutsummaryrefslogtreecommitdiff
path: root/unused.jai
blob: 04997c574b8aad9833d1e944dd3875b5188e3ff9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117



// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- //


// Check what's going on with the temp allocator:
// Is it really the responsible for these paths?
// It seems that the next beta (after 0.1.055b) compiler allows us to check this pretty easily.
//
//
// An example that uses several different allocators, then asks them all
// who owns which memory.
//
// Note that this is probably not the kind of thing you want to do at runtime
// in the steady state, as it may not be very fast, but it could be a very helpful
// debugging facility.
//

#import "Basic";
#import "Pool";
#import "Flat_Pool";
#import "rpmalloc";

main :: () {
    pool: Pool;
    flat: Flat_Pool;

    a := context.default_allocator;
    b := Allocator.{pool_allocator_proc, *pool};
    c := Allocator.{flat_pool_allocator_proc, *flat};
    d := Allocator.{rpmalloc_allocator_proc, null};

    d.proc(.STARTUP, 0, 0, null, null);  // rpmalloc needs explicit init right now, but others don't.
    
    ma := alloc(1000, allocator=a);
    mb := alloc(1000, allocator=b);
    mc := alloc(1000, allocator=c);
    md := alloc(1000, allocator=d);

    report_who_owns(ma, a, b, c, d);
    report_who_owns(mb, a, b, c, d);
    report_who_owns(mc, a, b, c, d);
    report_who_owns(md, a, b, c, d);
}

report_who_owns :: (memory: *void, allocators: .. Allocator) {
    someone_owns_this := false;
    
    print("Querying all allocators for address: %\n", memory);
    
    for allocators {
        caps, name := get_capabilities(it);
        assert((caps & .IS_THIS_YOURS) != 0);  // It had better be claiming to support this!
        
        yours := cast(bool) it.proc(.IS_THIS_YOURS, 0, 0, memory, it.data);
        print("[%] says \"%\"\n", yours, name);

        someone_owns_this ||= yours;
    }

    assert(someone_owns_this);
}


// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- //


checked_add :: (a: $T, b: T) -> result: T, overflow: bool 
#modify {
    if T.type == .INTEGER return;
    T = null;
}
{
    overflow: bool;
    result: T = a + b;

    info := type_info(T);
    if info.signed {
        // (+A) + (+B) = −C
        // (−A) + (−B) = +C
        if ((a > 0) && (b > 0) && (result < 0)) || ((a < 0) && (b < 0) && (result > 0)) {
            overflow = true;
        }
    } else {
        if result < a {
            overflow = true;
        }
    }

    return result, overflow;
}

checked_sub :: (a: $T, b: T) -> result: T, overflow: bool 
#modify {
    if T.type == .INTEGER return;
    T = null;
}
{
    overflow: bool;
    result: T = a - b;

    info := type_info(T);
    if info.signed {
        // (+A) − (−B) = −C
        // (−A) − (+B) = +C
        if ((a > 0) && (b < 0) && (result < 0)) || ((a < 0) && (b > 0) && (result > 0)) {
            overflow = true;
        }
    } else {
        if result > a {
            overflow = true;
        }
    }

    return result, overflow;
}