parsav  Diff

Differences From Artifact [e41dd1991a]:

To Artifact [15de92d877]:


    14     14   m.heapa = macro(function(ty, sz)
    15     15   	local p = m.ptr(ty:astype())
    16     16   	return `p {
    17     17   		ptr = [&ty:astype()](m.heapa_raw(sizeof(ty) * sz));
    18     18   		ct = sz;
    19     19   	}
    20     20   end)
           21  +
           22  +function m.cache(ty,sz)
           23  +	sz = sz or 32
           24  +	local struct c {
           25  +		store: ty[sz]
           26  +		top: intptr
           27  +		cur: intptr
           28  +	}
           29  +	c.name = string.format('cache<%s,%u>', tostring(ty), sz)
           30  +	terra c:insert(v: ty)
           31  +		if [ty.ptr_basetype ~= nil] then
           32  +			if self.cur < self.top then self.store[self.cur]:free() end
           33  +		end
           34  +		self.store[self.cur] = v
           35  +		self.top = lib.math.biggest(self.top, self.cur + 1)
           36  +		self.cur = (self.cur + 1) % sz
           37  +		return v
           38  +	end
           39  +	c.metamethods.__apply = terra(self: &c, idx: intptr) return &self.store[idx] end
           40  +	if ty.ptr_basetype then
           41  +		terra c:free()
           42  +			for i=0,self.top do self.store[i]:free() end
           43  +		end
           44  +	end
           45  +	return c
           46  +end
    21     47   
    22     48   local function mkptr(ty, dyn)
    23     49   	local t = terralib.types.newstruct(string.format('%s<%s>', dyn and 'ptr' or 'ref', ty))
    24     50   	t.entries = {
    25     51   		{'ptr', &ty};
    26     52   		{'ct', intptr};
    27     53   	}
    28     54   	t.ptr_basetype = ty
    29     55   	local recurse = false
    30         -	if ty:isstruct() then
    31         -		if ty.methods.free then recurse = true end
    32         -	end
           56  +	--if ty:isstruct() then
           57  +		--if ty.methods.free then recurse = true end
           58  +	--end
    33     59   	t.metamethods.__not = macro(function(self)
    34     60   		return `self.ptr
    35     61   	end)
    36     62   	if dyn then
    37     63   		t.methods = {
    38     64   			free = terra(self: &t): bool
    39     65   				[recurse and quote
................................................................................
    43     69   					m.heapf(self.ptr)
    44     70   					self.ct = 0
    45     71   					return true
    46     72   				end
    47     73   				return false
    48     74   			end;
    49     75   			init = terra(self: &t, newct: intptr): bool
           76  +				if newct == 0 then self.ct = 0 self.ptr = nil return false end
    50     77   				var nv = [&ty](m.heapa_raw(sizeof(ty) * newct))
    51     78   				if nv ~= nil then
    52     79   					self.ptr = nv
    53     80   					self.ct = newct
    54     81   					return true
    55     82   				else return false end
    56     83   			end;
................................................................................
   105    132   		{field = 'storage', type = m.ptr(ty)};
   106    133   		{field = 'sz', type = intptr};
   107    134   		{field = 'run', type = intptr};
   108    135   	}
   109    136   	local terra biggest(a: intptr, b: intptr)
   110    137   		if a > b then return a else return b end
   111    138   	end
          139  +	terra v:init(run: intptr): bool
          140  +		if not self.storage:init(run) then return false end
          141  +		self.run = run
          142  +		self.sz = 0
          143  +		return true
          144  +	end;
   112    145   	terra v:assure(n: intptr)
   113    146   		if self.storage.ct < n then
   114    147   			self.storage:resize(biggest(n, self.storage.ct + self.run))
   115    148   		end
   116    149   	end
   117         -	v.methods = {
   118         -		init = terra(self: &v, run: intptr): bool
   119         -			if not self.storage:init(run) then return false end
   120         -			self.run = run
   121         -			self.sz = 0
   122         -			return true
   123         -		end;
   124         -		new = terra(self: &v): &ty
   125         -			self:assure(self.sz + 1)
   126         -			self.sz = self.sz + 1
   127         -			return self.storage.ptr + (self.sz - 1)
   128         -		end;
   129         -		push = terra(self: &v, val: ty)
   130         -			self:assure(self.sz + 1)
   131         -			self.storage.ptr[self.sz] = val
   132         -			self.sz = self.sz + 1
   133         -		end;
   134         -		free = terra(self: &v) self.storage:free() end;
   135         -		last = terra(self: &v, idx: intptr): &ty
   136         -			if self.sz > idx then
   137         -				return self.storage.ptr + (self.sz - (idx+1))
   138         -			else lib.bail('vector underrun!') end
   139         -		end;
   140         -		crush = terra(self: &v)
   141         -			self.storage:resize(self.sz)
   142         -			return self.storage
   143         -		end;
   144         -	}
          150  +	terra v:new(): &ty
          151  +		self:assure(self.sz + 1)
          152  +		self.sz = self.sz + 1
          153  +		return self.storage.ptr + (self.sz - 1)
          154  +	end;
          155  +	terra v:push(val: ty)
          156  +		self:assure(self.sz + 1)
          157  +		self.storage.ptr[self.sz] = val
          158  +		self.sz = self.sz + 1
          159  +	end;
          160  +	terra v:free() self.storage:free() end;
          161  +	terra v:last(idx: intptr): &ty
          162  +		if self.sz > idx then
          163  +			return self.storage.ptr + (self.sz - (idx+1))
          164  +		else lib.bail('vector underrun!') end
          165  +	end;
          166  +	terra v:crush()
          167  +		self.storage:resize(self.sz)
          168  +		return self.storage
          169  +	end;
   145    170   	v.metamethods.__apply = terra(self: &v, idx: intptr): &ty -- no index??
   146    171   		if self.sz > idx then
   147    172   			return self.storage.ptr + idx
   148    173   		else lib.bail('vector overrun!') end
   149    174   	end
   150    175   	return v 
   151    176   end)
   152    177   
   153    178   return m