]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
Implement the exception-handling opcodes for the interpreter.
authorRhys Weatherley <rweather@southern-storm.com.au>
Tue, 11 May 2004 04:58:12 +0000 (04:58 +0000)
committerRhys Weatherley <rweather@southern-storm.com.au>
Tue, 11 May 2004 04:58:12 +0000 (04:58 +0000)
ChangeLog
jit/jit-rules-interp.c
jit/jit-rules-interp.h

index e81a63c39bbca7307e96ea8c13c765bc37ea0cfc..d7f0308d9fdd267651846ae003da2f1e2a9a6dce 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,9 @@
        jit/jit-interp.h, jit/jit-opcode.c, jit/jit-rules-interp.c:
        round out the function call handling opcodes for the interpreter.
 
+       * jit/jit-rules-interp.c, jit/jit-rules-interp.h: implement
+       the exception-handling opcodes for the interpreter.
+
 2004-05-10  Rhys Weatherley  <rweather@southern-storm.com.au>
 
        * jit/jit-reg-alloc.c, jit/jit-reg-alloc.h, jit/jit-rules-interp.c:
index f5620b2b6e51e328da38db343c46f8e0db3ee35a..fc5f051fcbf2297e0d0495621c0a4cc620f50c7d 100644 (file)
@@ -614,11 +614,13 @@ void *_jit_gen_prolog(jit_gencode_t gen, jit_function_t func, void *buf)
 {
        /* Output the jit_function_interp structure at the beginning */
        jit_function_interp_t interp = (jit_function_interp_t)buf;
+       unsigned int max_working_area =
+               gen->max_working_area + gen->extra_working_space;
        interp->func = func;
        interp->args_size = _jit_interp_calculate_arg_size(func, func->signature);
        interp->frame_size =
-               (func->builder->frame_size + gen->max_working_area) * sizeof(jit_item);
-       interp->working_area = gen->max_working_area;
+               (func->builder->frame_size + max_working_area) * sizeof(jit_item);
+       interp->working_area = max_working_area;
        return buf;
 }
 
@@ -931,8 +933,6 @@ void _jit_gen_insn(jit_gencode_t gen, jit_function_t func,
 
        switch(insn->opcode)
        {
-               /* TODO */
-
                case JIT_OP_BR:
                {
                        /* Unconditional branch */
@@ -968,6 +968,7 @@ void _jit_gen_insn(jit_gencode_t gen, jit_function_t func,
                case JIT_OP_BR_ITRUE:
                case JIT_OP_BR_LFALSE:
                case JIT_OP_BR_LTRUE:
+               case JIT_OP_CALL_FILTER:
                {
                        /* Unary branch */
                        label = get_branch_dest(block, insn);
@@ -1211,6 +1212,77 @@ void _jit_gen_insn(jit_gencode_t gen, jit_function_t func,
                }
                break;
 
+               case JIT_OP_THROW:
+               {
+                       /* Throw an exception */
+                       reg = _jit_regs_load_to_top
+                               (gen, insn->value1,
+                                (insn->flags & (JIT_INSN_VALUE1_NEXT_USE |
+                                                                JIT_INSN_VALUE1_LIVE)), 0);
+                       jit_cache_opcode(&(gen->posn), insn->opcode);
+                       _jit_regs_free_reg(gen, reg, 1);
+               }
+               break;
+
+               case JIT_OP_LOAD_PC:
+               {
+                       /* Load the current program counter onto the stack */
+                       if(_jit_regs_num_used(gen, 0) >= JIT_NUM_REGS)
+                       {
+                               _jit_regs_spill_all(gen);
+                       }
+                       jit_cache_opcode(&(gen->posn), insn->opcode);
+                       reg = _jit_regs_new_top(gen, insn->dest, 0);
+                       adjust_working(gen, 1);
+               }
+               break;
+
+               case JIT_OP_ENTER_CATCH:
+               case JIT_OP_CALL_FILTER_RETURN:
+               {
+                       /* The top of stack currently contains "dest" */
+                       _jit_regs_set_value(gen, 0, insn->dest, 0);
+                       adjust_working(gen, 1);
+               }
+               break;
+
+               case JIT_OP_ENTER_FINALLY:
+               {
+                       /* Record that the finally return address is on the stack */
+                       ++(gen->extra_working_space);
+               }
+               break;
+
+               case JIT_OP_LEAVE_FINALLY:
+               {
+                       /* Leave a finally clause */
+                       jit_cache_opcode(&(gen->posn), insn->opcode);
+               }
+               break;
+
+               case JIT_OP_ENTER_FILTER:
+               {
+                       /* The top of stack contains "dest" and a return address */
+                       ++(gen->extra_working_space);
+                       _jit_regs_set_value(gen, 0, insn->dest, 0);
+                       adjust_working(gen, 1);
+               }
+               break;
+
+               case JIT_OP_LEAVE_FILTER:
+               {
+                       /* Leave a filter clause, returning a particular value */
+                       if(!_jit_regs_is_top(gen, insn->value1) ||
+                          _jit_regs_num_used(gen, 0) != 1)
+                       {
+                               _jit_regs_spill_all(gen);
+                       }
+                       reg = _jit_regs_load_to_top(gen, insn->value1, 0, 0);
+                       jit_cache_opcode(&(gen->posn), insn->opcode);
+                       _jit_regs_free_reg(gen, reg, 1);
+               }
+               break;
+
                case JIT_OP_RETURN_REG:
                {
                        /* Push a function return value back onto the stack */
index 68112b2996eafb8fa0d1f86961b4bcddd9184983..8f4505ef40fb7e65147203ffd9965fe26bd48b8e 100644 (file)
@@ -95,11 +95,13 @@ extern      "C" {
  */
 #define        jit_extra_gen_state     \
                        int working_area; \
-                       int max_working_area
+                       int max_working_area; \
+                       int extra_working_space
 #define        jit_extra_gen_init(gen) \
                        do { \
                                (gen)->working_area = 0; \
                                (gen)->max_working_area = 0; \
+                               (gen)->extra_working_space = 0; \
                        } while (0)
 #define        jit_extra_gen_cleanup(gen)      do { ; } while (0)