1 #ifndef LOCAL_CONTEXT_HH
2 #define LOCAL_CONTEXT_HH
3 
4 #include "types.hh"
5 #include "var_desc.hh"
6 #include "method_desc.hh"
7 
8 class local_context {
9 public:
10   enum context_cmd {
11     cmd_pop_var,    // start of local variable scope
12     cmd_push_var,   // end of local variable scope
13     cmd_merge_ctx,  // forward jump label
14     cmd_reset_ctx,  // backward jump label
15     cmd_enter_ctx,  // entry point
16     cmd_case_ctx,   // switch case label
17     cmd_update_ctx, // backward jump
18     cmd_save_ctx    // forward jump
19   } cmd;
20 
21   local_context* next;
22 
23   virtual vbm_operand* transfer(method_desc* method, vbm_operand* sp,
24                                 byte cop, byte& prev_cop) = 0;
25 
local_context(context_cmd ctx_cmd,local_context ** chain)26   local_context(context_cmd ctx_cmd, local_context** chain) {
27     cmd = ctx_cmd;
28     while (*chain != NULL && (*chain)->cmd < ctx_cmd) {
29       chain = &(*chain)->next;
30     }
31     next = *chain;
32     *chain = this;
33   }
34 };
35 
36 class ctx_entry_point : public local_context {
37 public:
ctx_entry_point(local_context ** chain)38   ctx_entry_point(local_context** chain)
39     : local_context(cmd_enter_ctx, chain) {}
40 
41   virtual vbm_operand* transfer(method_desc* method,
42                                 vbm_operand* sp, byte cop, byte& prev_cop);
43 };
44 
45 class ctx_split : public local_context {
46 public:
47   var_desc*    vars;
48   vbm_operand* stack_pointer;
49   vbm_operand  stack_top[2];
50   int          switch_var_index;
51   int          n_branches;
52   int          in_monitor;
53 
54   enum jmp_type { jmp_forward, jmp_backward };
55 
ctx_split(local_context ** chain,jmp_type type=jmp_forward)56   ctx_split(local_context** chain, jmp_type type = jmp_forward)
57     : local_context(type == jmp_forward ? cmd_save_ctx : cmd_update_ctx, chain)
58   {
59     n_branches = 1;
60   }
61 
62   virtual vbm_operand* transfer(method_desc* method, vbm_operand* sp,
63                                 byte cop, byte& prev_cop);
64 };
65 
66 class ctx_merge : public local_context {
67 public:
68   ctx_split* come_from;
69   int        case_value;
70 
ctx_merge(local_context ** chain,ctx_split * come_from_ctx)71   ctx_merge(local_context** chain, ctx_split* come_from_ctx)
72     : local_context(cmd_merge_ctx, chain)
73   {
74     come_from = come_from_ctx;
75   }
76 
ctx_merge(local_context ** chain,ctx_split * come_from_ctx,int value)77   ctx_merge(local_context** chain, ctx_split* come_from_ctx, int value)
78     : local_context(cmd_case_ctx, chain)
79   {
80     come_from = come_from_ctx;
81     case_value = value;
82   }
83 
84   virtual vbm_operand* transfer(method_desc* method, vbm_operand* sp,
85                                 byte cop, byte& prev_cop);
86 };
87 
88 class ctx_pop_var : public local_context {
89 public:
90   int var_index;
91 
ctx_pop_var(local_context ** chain,int index)92   ctx_pop_var(local_context** chain, int index)
93     : local_context(cmd_pop_var, chain), var_index(index) {}
94 
95   virtual vbm_operand* transfer(method_desc* method, vbm_operand* sp,
96                                 byte cop, byte& prev_cop);
97 };
98 
99 class ctx_push_var : public local_context {
100 public:
101   utf_string* var_name;
102   int         var_type;
103   int         var_index;
104   int         var_start_pc;
105 
ctx_push_var(local_context ** chain,utf_string * name,int type,int index,int start_pc)106   ctx_push_var(local_context** chain,
107                utf_string* name, int type, int index, int start_pc)
108     : local_context(cmd_push_var, chain) {
109     var_name = name;
110     var_type = type;
111     var_index = index;
112     var_start_pc = start_pc;
113   }
114 
115 
116   virtual vbm_operand* transfer(method_desc* method, vbm_operand* sp,
117                                 byte cop, byte& prev_cop);
118 };
119 
120 class ctx_reset : public local_context {
121 public:
122   int* var_store_count;
123 
ctx_reset(local_context ** chain,int * counts,int n_vars)124   ctx_reset(local_context** chain, int* counts, int n_vars)
125     : local_context(cmd_reset_ctx, chain)
126   {
127     var_store_count = new int[n_vars];
128     memcpy(var_store_count, counts, n_vars*sizeof(int));
129   }
130 
131   virtual vbm_operand* transfer(method_desc* method, vbm_operand* sp,
132                                 byte cop, byte& prev_cop);
133 };
134 
135 #endif
136