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
|
local p = m.ptr(ty:astype())
return `p {
ptr = [&ty:astype()](m.heapa_raw(sizeof(ty) * sz));
ct = sz;
}
end)
m.ptr = terralib.memoize(function(ty)
local t = terralib.types.newstruct(string.format('ptr<%s>', ty))
t.entries = {
{'ptr', &ty};
{'ct', intptr};
}
t.ptr_basetype = ty
local recurse = false
if ty:isstruct() then
if ty.methods.free then recurse = true end
end
t.metamethods.__not = macro(function(self)
return `self.ptr
end)
t.methods = {
free = terra(self: &t): bool
[recurse and quote
self.ptr:free()
end or {}]
if self.ct > 0 then
m.heapf(self.ptr)
self.ct = 0
return true
end
return false
end;
init = terra(self: &t, newct: intptr): bool
var nv = [&ty](m.heapa_raw(sizeof(ty) * newct))
if nv ~= nil then
self.ptr = nv
self.ct = newct
return true
else return false end
end;
resize = terra(self: &t, newct: intptr): bool
var nv: &ty
if self.ct > 0
then nv = [&ty](m.heapr_raw(self.ptr, sizeof(ty) * newct))
else nv = [&ty](m.heapa_raw(sizeof(ty) * newct))
end
if nv ~= nil then
self.ptr = nv
self.ct = newct
return true
else return false end
end;
}
return t
end)
m.vec = terralib.memoize(function(ty)
local v = terralib.types.newstruct(string.format('vec<%s>', ty.name))
v.entries = {
{field = 'storage', type = m.ptr(ty)};
{field = 'sz', type = intptr};
{field = 'run', type = intptr};
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|
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
|
local p = m.ptr(ty:astype())
return `p {
ptr = [&ty:astype()](m.heapa_raw(sizeof(ty) * sz));
ct = sz;
}
end)
local function mkptr(ty, dyn)
local t = terralib.types.newstruct(string.format('%s<%s>', dyn and 'ptr' or 'ref', ty))
t.entries = {
{'ptr', &ty};
{'ct', intptr};
}
t.ptr_basetype = ty
local recurse = false
if ty:isstruct() then
if ty.methods.free then recurse = true end
end
t.metamethods.__not = macro(function(self)
return `self.ptr
end)
if dyn then
t.methods = {
free = terra(self: &t): bool
[recurse and quote
self.ptr:free()
end or {}]
if self.ct > 0 then
m.heapf(self.ptr)
self.ct = 0
return true
end
return false
end;
init = terra(self: &t, newct: intptr): bool
var nv = [&ty](m.heapa_raw(sizeof(ty) * newct))
if nv ~= nil then
self.ptr = nv
self.ct = newct
return true
else return false end
end;
resize = terra(self: &t, newct: intptr): bool
var nv: &ty
if self.ct > 0
then nv = [&ty](m.heapr_raw(self.ptr, sizeof(ty) * newct))
else nv = [&ty](m.heapa_raw(sizeof(ty) * newct))
end
if nv ~= nil then
self.ptr = nv
self.ct = newct
return true
else return false end
end;
}
terra t:ensure(n: intptr)
if self.ptr == nil then
if not self:init(n) then return t {ptr=nil,ct=0} end
end
if self.ct >= n then return @self end
self:resize(n)
return @self
end
end
terra t:advance(n: intptr)
self.ptr = self.ptr + n
self.ct = self.ct - n
return self.ptr
end
if not ty:isstruct() then
terra t:cmp_raw(other: &ty)
for i=0, self.ct do
if self.ptr[i] ~= other[i] then return false end
end
return true
end
terra t:cmp(other: t)
if other.ct ~= self.ct then return false end
return self:cmp_raw(other.ptr)
end
end
return t
end
m.ptr = terralib.memoize(function(ty) return mkptr(ty, true) end)
m.ref = terralib.memoize(function(ty) return mkptr(ty, false) end)
m.vec = terralib.memoize(function(ty)
local v = terralib.types.newstruct(string.format('vec<%s>', ty.name))
v.entries = {
{field = 'storage', type = m.ptr(ty)};
{field = 'sz', type = intptr};
{field = 'run', type = intptr};
|