Browse Source

Fix some issues with importing values

The previous commit intrduced a couple of bugs.
While importing values from the parent worked importing
values from a higher ancestor or calling siblings was broken.
This commit fixes these issues
pull/15/head
Jakob Löw 7 years ago
parent
commit
780b4b816a
  1. 4
      include/jit/jit-insn.h
  2. 9
      jit/jit-compile.c
  3. 83
      jit/jit-insn.c

4
include/jit/jit-insn.h

@ -256,8 +256,8 @@ int jit_insn_setup_for_nested
(jit_function_t func, int nested_level, int reg) JIT_NOTHROW;
int jit_insn_flush_struct(jit_function_t func, jit_value_t value) JIT_NOTHROW;
jit_value_t jit_insn_get_frame_pointer(jit_function_t func) JIT_NOTHROW;
jit_value_t jit_insn_get_parent_frame_of
(jit_function_t func, jit_value_t frame_pointer) JIT_NOTHROW;
jit_value_t jit_insn_get_parent_frame_pointer_of
(jit_function_t func, jit_function_t target) JIT_NOTHROW;
jit_value_t jit_insn_import
(jit_function_t func, jit_value_t value) JIT_NOTHROW;
int jit_insn_push(jit_function_t func, jit_value_t value) JIT_NOTHROW;

9
jit/jit-compile.c

@ -222,15 +222,6 @@ compile_block(jit_gencode_t gen, jit_function_t func, jit_block_t block)
break;
#endif
case JIT_OP_IMPORT:
_jit_gen_fix_value(insn->value2);
insn->opcode = JIT_OP_ADD_RELATIVE;
insn->value2 = jit_value_create_nint_constant(func, jit_type_nint,
insn->value2->frame_offset);
_jit_gen_insn(gen, func, block, insn);
break;
#ifndef JIT_BACKEND_INTERP
case JIT_OP_INCOMING_REG:
/* Assign a register to an incoming value */

83
jit/jit-insn.c

@ -23,7 +23,6 @@
#include "jit-internal.h"
#include "jit-rules.h"
#include "jit-setjmp.h"
#include "jit-apply-rules.h"
#if HAVE_STDLIB_H
# include <stdlib.h>
#endif
@ -6338,19 +6337,64 @@ jit_insn_get_frame_pointer(jit_function_t func)
return jit_insn_address_of(func, dummy);
}
static jit_value_t
find_frame_of(jit_function_t func, jit_function_t target,
jit_function_t func_start, jit_value_t frame_start)
{
/* Find the nesting level */
int nesting_level = 0;
jit_function_t current_func = func_start;
while(current_func != 0 && current_func != target)
{
if(!current_func->parent_frame)
{
/* One of the ancestors is not correctly set up */
return 0;
}
current_func = current_func->nested_parent;
nesting_level++;
}
if(!current_func)
{
/* The value is not accessible from this scope */
return 0;
}
current_func = func_start;
while(frame_start != 0 && nesting_level-- > 0)
{
jit_value_ref(func, current_func->parent_frame);
_jit_gen_fix_value(current_func->parent_frame);
frame_start = jit_insn_load_relative(func, frame_start,
current_func->parent_frame->frame_offset, jit_type_void_ptr);
current_func = current_func->nested_parent;
}
if(!frame_start)
{
return 0;
}
return frame_start;
}
/*@
* @deftypefun jit_value_t jit_insn_get_parent_frame_of (jit_function_t @var{func}, jit_value_t @var{frame_pointer})
* Retrieve the parent frame of @var{frame_pointer}. Using this function
* multiple times allows importing values from grandparents. The initial
* @var{frame_pointer} can be obtained from @code{jit_insn_get_frame_pointer}.
* @deftypefun jit_value_t jit_insn_get_parent_frame_pointer_of (jit_function_t @var{func}, jit_function_t @var{target})
* Retrieve the frame pointer of the parent of @var{target}. This only works
* when @var{target} is a sibling, an ancestor, or a sibling of one of the
* ancestors of @var{func}.
* Returns NULL if out of memory.
* @end deftypefun
@*/
jit_value_t
jit_insn_get_parent_frame_of(jit_function_t func, jit_value_t frame_pointer)
jit_insn_get_parent_frame_pointer_of(jit_function_t func, jit_function_t target)
{
return jit_insn_load_relative(func, frame_pointer,
JIT_APPLY_PARENT_FRAME_OFFSET, jit_type_void_ptr);
if(func == target->nested_parent)
return jit_insn_get_frame_pointer(func);
else
return find_frame_of(func, target->nested_parent,
func->nested_parent, func->parent_frame);
}
/*@
@ -6386,24 +6430,13 @@ jit_insn_import(jit_function_t func, jit_value_t value)
value, jit_type_void_ptr);
}
/* Find the frame of the ancestor the value is from */
jit_value_t current_frame = func->parent_frame;
jit_function_t current_func = func->nested_parent;
while(current_func != 0 && current_func != value_func)
{
current_frame = jit_insn_get_parent_frame_of(func, current_frame);
current_func = current_func->nested_parent;
}
if(!current_func)
{
/* The value is not accessible from this scope */
return 0;
}
jit_value_t value_frame = find_frame_of(func, value_func,
func->nested_parent, func->parent_frame);
jit_value_ref(func, value);
_jit_gen_fix_value(value);
/* Output the relevant import instruction, which will also cause
it to be marked as a non-local addressable by "jit_value_ref" */
return apply_binary(func, JIT_OP_IMPORT, current_frame, value,
jit_type_void_ptr);
return jit_insn_add_relative(func, value_frame, value->frame_offset);
}
/*@

Loading…
Cancel
Save