.
This commit is contained in:
@@ -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.')
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user