This commit is contained in:
2026-05-09 15:04:44 -05:00
parent 85443ded9d
commit e2f930641e
2 changed files with 52 additions and 18 deletions

View File

@@ -354,7 +354,7 @@ do TEST "VM: arrays"
ret ret
]]):call(0) ]]):call(0)
print(vm:debug_heap()) -- print(vm:debug_heap())
assert_eq(vm:to_integer(-1), 20) assert_eq(vm:to_integer(-1), 20)
assert_eq(vm.heap:size(), 1) assert_eq(vm.heap:size(), 1)
end end
@@ -374,8 +374,8 @@ do TEST "VM: arrays GC"
assert_eq(vm.heap:size(), 0) assert_eq(vm.heap:size(), 0)
end end
do TEST "VM: GC items (1st level)" do TEST "VM: GC items (1st level) - no items removed"
local vm = VM.new():set_debug(true):load(assemble [[ local vm = VM.new():load(assemble [[
.const .const
0: "Hello " 0: "Hello "
1: "world" 1: "world"
@@ -391,10 +391,27 @@ do TEST "VM: GC items (1st level)"
ret ret
]]):call(0) ]]):call(0)
pprint(vm.heap) assert_eq(vm.heap:size(), 2)
print(vm:debug_heap()) end
do TEST "VM: GC items (1st level) - all items removed"
local vm = VM.new():load(assemble [[
.const
0: "Hello "
1: "world"
.func 0
pushn
newa
pushc 0
pushc 1
sum
seti 0
pop
gc
ret
]]):call(0)
assert_eq(vm.heap:size(), 0) assert_eq(vm.heap:size(), 0)
end end
-- TODO - arrays gc items
print('End.') print('End.')

View File

@@ -223,6 +223,9 @@ function Heap.new()
end end
function Heap:add_value(value) function Heap:add_value(value)
assert(value.type and (value.type == 'string' or value.type == 'array' or value.type == 'table'))
assert(value.value)
local key = math.random(1, math.maxinteger) local key = math.random(1, math.maxinteger)
while self.items[key] do key = math.random(1, math.maxinteger) end while self.items[key] do key = math.random(1, math.maxinteger) end
self.items[key] = value self.items[key] = value
@@ -243,14 +246,20 @@ end
function Heap:call_gc(roots) function Heap:call_gc(roots)
-- mark -- mark
local marked = {} local marked = {}
for _,v in ipairs(roots) do -- TODO - recursive, add support to array
if v.type == 'string' and v.ref then local function mark(v)
if v.type == 'string' then
if v.ref then marked[v.ref] = true end
elseif v.type == 'array' then
marked[v.ref] = true marked[v.ref] = true
else for _,vv in ipairs(self.items[v.ref].value) do mark(vv) end
error("Can't handle this type on GC")
end end
end end
for _,v in ipairs(roots) do -- TODO - recursive, add support to array
mark(v)
end
-- sweep -- sweep
for key,_ in pairs(self.items) do for key,_ in pairs(self.items) do
if not marked[key] then if not marked[key] then
@@ -303,7 +312,7 @@ function VM:push_integer(n)
end end
function VM:push_string(str) function VM:push_string(str)
self.stack:push({ type = 'string', ref = self.heap:add_value(str) }) self.stack:push({ type = 'string', ref = self.heap:add_value({ type='string', value=str }) })
return self return self
end end
@@ -313,7 +322,7 @@ function VM:push_nil()
end end
function VM:new_array() function VM:new_array()
self.stack:push({ type = 'array', ref = self.heap:add_value({}) }) self.stack:push({ type = 'array', ref = self.heap:add_value({ type='array', value={} }) })
return self return self
end end
@@ -343,7 +352,7 @@ function VM:_extract_string(value)
if value.const_ref then if value.const_ref then
return self.code.bytecode.constants[value.const_ref] return self.code.bytecode.constants[value.const_ref]
elseif value.ref then elseif value.ref then
return self.heap:get_value(value.ref) return self.heap:get_value(value.ref).value
else else
error("Incorrect string value (nor 'const_ref' or 'ref')") error("Incorrect string value (nor 'const_ref' or 'ref')")
end end
@@ -354,7 +363,7 @@ function VM:_extract_array(value)
assert(value.type == 'array') assert(value.type == 'array')
local array = self.heap:get_value(value.ref) local array = self.heap:get_value(value.ref)
if type(array) ~= 'table' then error('Expected array') end if type(array) ~= 'table' then error('Expected array') end
return self.heap:get_value(value.ref) return self.heap:get_value(value.ref).value
end end
function VM:to_string(idx) function VM:to_string(idx)
@@ -398,11 +407,11 @@ end
function VM:debug_heap() function VM:debug_heap()
local ss = { "Heap:\n" } local ss = { "Heap:\n" }
for k,v in pairs(self.heap.items) do for k,v in pairs(self.heap.items) do
if type(v) == 'string' then if v.type == 'string' then
table.insert(ss, string.format(' [%X] = "%s"', k, v)) table.insert(ss, string.format(' [%X] = "%s"', k, v.value))
elseif type(v) == 'table' then elseif v.type == 'array' then
table.insert(ss, string.format(' [%X] = [', k)) table.insert(ss, string.format(' [%X] = [', k))
local t = {}; for _,vv in ipairs(v) do t[#t+1] = self:format_value(vv) end local t = {}; for _,vv in ipairs(v.value) do t[#t+1] = self:format_value(vv) end
table.insert(ss, table.concat(t, ", ") .. ']') table.insert(ss, table.concat(t, ", ") .. ']')
else else
error('Unsupported type in heap') error('Unsupported type in heap')
@@ -585,7 +594,15 @@ function VM:_step()
-- --
elseif op.operator == 'gc' then elseif op.operator == 'gc' then
-- if self.debug then
-- print('About to run GC, current heap:')
-- print(self:debug_heap())
-- end
self.heap:call_gc(self.stack.stack) self.heap:call_gc(self.stack.stack)
-- if self.debug then
-- print('GC executed, this is the heap:')
-- print(self:debug_heap())
-- end
-- --
-- instruction not found -- instruction not found