Add support for allocRecord and initArray from runtime.c.
This commit is contained in:
parent
53ee6d3ef6
commit
bef14dfa24
|
@ -25,6 +25,9 @@ class Garbage(Enum):
|
||||||
return '<<Garbage>>'
|
return '<<Garbage>>'
|
||||||
|
|
||||||
|
|
||||||
|
builtins = ['allocRecord', 'initArray']
|
||||||
|
|
||||||
|
|
||||||
def step(insns, terminator, blocks, stack_frames, ssa_env, global_env, heap,
|
def step(insns, terminator, blocks, stack_frames, ssa_env, global_env, heap,
|
||||||
tdecs, fdecs, call_res):
|
tdecs, fdecs, call_res):
|
||||||
if len(insns) == 0:
|
if len(insns) == 0:
|
||||||
|
@ -33,6 +36,23 @@ def step(insns, terminator, blocks, stack_frames, ssa_env, global_env, heap,
|
||||||
ssa_target, next_insn = insns[0]
|
ssa_target, next_insn = insns[0]
|
||||||
insns_rest = insns[1:]
|
insns_rest = insns[1:]
|
||||||
|
|
||||||
|
def store_in_ssa(res, insns_rest, terminator, blocks, stack_frames, ssa_env, heap,
|
||||||
|
call_res):
|
||||||
|
if ssa_target is not None:
|
||||||
|
if ssa_target in ssa_env:
|
||||||
|
err('Cannot assign to variable twice: {}'
|
||||||
|
.format(ssa_target))
|
||||||
|
elif res is None:
|
||||||
|
err('Cannot assign empty value to %{}'
|
||||||
|
.format(ssa_target))
|
||||||
|
else:
|
||||||
|
# TODO
|
||||||
|
print('%{} <- {}'
|
||||||
|
.format(ssa_target, res))
|
||||||
|
ssa_env[ssa_target] = res
|
||||||
|
|
||||||
|
return insns_rest, terminator, blocks, stack_frames, ssa_env, heap, call_res
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
print('Evaluating {}'
|
print('Evaluating {}'
|
||||||
.format(ll.insn2s(next_insn)))
|
.format(ll.insn2s(next_insn)))
|
||||||
|
@ -128,11 +148,26 @@ def step(insns, terminator, blocks, stack_frames, ssa_env, global_env, heap,
|
||||||
arguments_v = [eval_oper(oper, ssa_env, global_env)
|
arguments_v = [eval_oper(oper, ssa_env, global_env)
|
||||||
for ty, oper in arguments]
|
for ty, oper in arguments]
|
||||||
|
|
||||||
try:
|
if callee.val in fdecs:
|
||||||
function = fdecs[callee.val]
|
function = fdecs[callee.val]
|
||||||
except KeyError:
|
elif callee.val in builtins:
|
||||||
|
res, new_heap, should_exit = emulate_builtin(callee.val, arguments_v, ssa_env,
|
||||||
|
heap)
|
||||||
|
if should_exit:
|
||||||
|
new_insns = [(None, ll.CallResult(res))]
|
||||||
|
new_terminator = None
|
||||||
|
new_blocks = {}
|
||||||
|
new_ssa_env = ssa_env
|
||||||
|
new_stack_frames = []
|
||||||
|
new_call_res = []
|
||||||
|
return (new_insns, new_terminator, new_blocks, new_stack_frames,
|
||||||
|
new_ssa_env, heap, new_call_res)
|
||||||
|
else:
|
||||||
|
return store_in_ssa(res, insns_rest, terminator, blocks, stack_frames,
|
||||||
|
ssa_env, new_heap, call_res)
|
||||||
|
else:
|
||||||
err('Could not find function {} in environment:\n{}'
|
err('Could not find function {} in environment:\n{}'
|
||||||
.format(callee.val, list(fdecs.keys())))
|
.format(callee.val, list(fdecs.keys()) + builtins))
|
||||||
return insns_rest, terminator, blocks, stack_frames, ssa_env, heap, call_res
|
return insns_rest, terminator, blocks, stack_frames, ssa_env, heap, call_res
|
||||||
|
|
||||||
parameters = function.parameters
|
parameters = function.parameters
|
||||||
|
@ -214,20 +249,8 @@ def step(insns, terminator, blocks, stack_frames, ssa_env, global_env, heap,
|
||||||
err('Unknown LLVM instruction: {}'
|
err('Unknown LLVM instruction: {}'
|
||||||
.format(next_insn))
|
.format(next_insn))
|
||||||
|
|
||||||
if ssa_target is not None:
|
return store_in_ssa(res, insns_rest, terminator, blocks, stack_frames, ssa_env, heap,
|
||||||
if ssa_target in ssa_env:
|
call_res)
|
||||||
err('Cannot assign to variable twice: {}'
|
|
||||||
.format(ssa_target))
|
|
||||||
elif res is None:
|
|
||||||
err('Cannot assign empty value to %{}'
|
|
||||||
.format(ssa_target))
|
|
||||||
else:
|
|
||||||
# TODO
|
|
||||||
print('%{} <- {}'
|
|
||||||
.format(ssa_target, res))
|
|
||||||
ssa_env[ssa_target] = res
|
|
||||||
|
|
||||||
return insns_rest, terminator, blocks, stack_frames, ssa_env, heap, call_res
|
|
||||||
|
|
||||||
|
|
||||||
def terminate(terminator, blocks, stack_frames, ssa_env, global_env, heap, call_res):
|
def terminate(terminator, blocks, stack_frames, ssa_env, global_env, heap, call_res):
|
||||||
|
@ -503,6 +526,71 @@ def alloc_globals(gdecls, heap):
|
||||||
return global_env
|
return global_env
|
||||||
|
|
||||||
|
|
||||||
|
def emulate_builtin(name, arguments_v, ssa_env, heap):
|
||||||
|
new_heap = heap
|
||||||
|
res = None
|
||||||
|
should_exit = False
|
||||||
|
if name == 'allocRecord':
|
||||||
|
if len(arguments_v) != 1:
|
||||||
|
err('Number of arguments to {} should be 1'
|
||||||
|
.format(name))
|
||||||
|
else:
|
||||||
|
size = max(arguments_v[0], 1)
|
||||||
|
print('Allocating {} cells'
|
||||||
|
.format(size))
|
||||||
|
res = len(heap)
|
||||||
|
for i in range(size):
|
||||||
|
heap.append(Garbage.GARBAGE)
|
||||||
|
elif name == 'initArray':
|
||||||
|
if len(arguments_v) != 3:
|
||||||
|
err('Number of arguments to {} should be 3'
|
||||||
|
.format(name))
|
||||||
|
else:
|
||||||
|
num_elements = arguments_v[0]
|
||||||
|
cells_per_element = arguments_v[1]
|
||||||
|
init_ptr = arguments_v[2]
|
||||||
|
print('Allocating {} + {} + {} (size + pointer + content) cells'
|
||||||
|
.format(1, 1, num_elements * cells_per_element))
|
||||||
|
struct_begin = len(heap)
|
||||||
|
heap.append(num_elements)
|
||||||
|
heap.append(Garbage.GARBAGE) # pointer to array contents
|
||||||
|
array_begin = len(heap)
|
||||||
|
heap[struct_begin + 1] = array_begin
|
||||||
|
init_val = [heap[init_ptr + j]
|
||||||
|
for j in range(cells_per_element)]
|
||||||
|
if len(init_val) == 1:
|
||||||
|
init_val_s = init_val[0]
|
||||||
|
else:
|
||||||
|
init_val_s = '{{}}'.format(', '.join(init_val))
|
||||||
|
|
||||||
|
for i in range(num_elements):
|
||||||
|
array_last = len(heap)
|
||||||
|
for j in init_val:
|
||||||
|
heap.append(j)
|
||||||
|
|
||||||
|
if num_elements <= 0:
|
||||||
|
array_init_s = 'No elements initialized for zero length array'
|
||||||
|
else:
|
||||||
|
array_init_s = ('heap[{}..{}] <- heap[{}] = {}'
|
||||||
|
.format(array_begin, array_last,
|
||||||
|
init_ptr, init_val_s))
|
||||||
|
# TODO
|
||||||
|
print('heap[{}] <- {}, heap[{}] <- {}, --- {}'
|
||||||
|
.format(struct_begin, num_elements,
|
||||||
|
struct_begin + 1, array_begin,
|
||||||
|
array_init_s))
|
||||||
|
res = struct_begin
|
||||||
|
elif name in builtins:
|
||||||
|
TODO('Have not implemented builtin function {}, yet.'
|
||||||
|
.format(name))
|
||||||
|
else:
|
||||||
|
err('Unknown builtin function {}.'
|
||||||
|
.format(name))
|
||||||
|
return None, heap
|
||||||
|
|
||||||
|
return res, new_heap, should_exit
|
||||||
|
|
||||||
|
|
||||||
def auto_step(ast, function_name='tigermain', function_args=[1234, 5678]):
|
def auto_step(ast, function_name='tigermain', function_args=[1234, 5678]):
|
||||||
tdecls = ast.tdecls
|
tdecls = ast.tdecls
|
||||||
fdecls = ast.fdecls
|
fdecls = ast.fdecls
|
||||||
|
|
Loading…
Reference in New Issue
Block a user