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>>'
|
||||
|
||||
|
||||
builtins = ['allocRecord', 'initArray']
|
||||
|
||||
|
||||
def step(insns, terminator, blocks, stack_frames, ssa_env, global_env, heap,
|
||||
tdecs, fdecs, call_res):
|
||||
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]
|
||||
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
|
||||
print('Evaluating {}'
|
||||
.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)
|
||||
for ty, oper in arguments]
|
||||
|
||||
try:
|
||||
if callee.val in fdecs:
|
||||
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{}'
|
||||
.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
|
||||
|
||||
parameters = function.parameters
|
||||
|
@ -214,20 +249,8 @@ def step(insns, terminator, blocks, stack_frames, ssa_env, global_env, heap,
|
|||
err('Unknown LLVM instruction: {}'
|
||||
.format(next_insn))
|
||||
|
||||
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
|
||||
return store_in_ssa(res, insns_rest, terminator, blocks, stack_frames, ssa_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
|
||||
|
||||
|
||||
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]):
|
||||
tdecls = ast.tdecls
|
||||
fdecls = ast.fdecls
|
||||
|
|
Loading…
Reference in New Issue
Block a user