#ifndef LOCAL_CONTEXT_HH
#define LOCAL_CONTEXT_HH
#include "types.hh"
#include "var_desc.hh"
#include "method_desc.hh"
class local_context {
public:
enum context_cmd {
cmd_pop_var, // start of local variable scope
cmd_push_var, // end of local variable scope
cmd_merge_ctx, // forward jump label
cmd_reset_ctx, // backward jump label
cmd_enter_ctx, // entry point
cmd_case_ctx, // switch case label
cmd_update_ctx, // backward jump
cmd_save_ctx // forward jump
} cmd;
local_context* next;
virtual vbm_operand* transfer(method_desc* method, vbm_operand* sp,
byte cop, byte& prev_cop) = 0;
local_context(context_cmd ctx_cmd, local_context** chain) {
cmd = ctx_cmd;
while (*chain != NULL && (*chain)->cmd < ctx_cmd) {
chain = &(*chain)->next;
}
next = *chain;
*chain = this;
}
};
class ctx_entry_point : public local_context {
public:
ctx_entry_point(local_context** chain)
: local_context(cmd_enter_ctx, chain) {}
virtual vbm_operand* transfer(method_desc* method,
vbm_operand* sp, byte cop, byte& prev_cop);
};
class ctx_split : public local_context {
public:
var_desc* vars;
vbm_operand* stack_pointer;
vbm_operand stack_top[2];
int switch_var_index;
int n_branches;
int in_monitor;
enum jmp_type { jmp_forward, jmp_backward };
ctx_split(local_context** chain, jmp_type type = jmp_forward)
: local_context(type == jmp_forward ? cmd_save_ctx : cmd_update_ctx, chain)
{
n_branches = 1;
}
virtual vbm_operand* transfer(method_desc* method, vbm_operand* sp,
byte cop, byte& prev_cop);
};
class ctx_merge : public local_context {
public:
ctx_split* come_from;
int case_value;
ctx_merge(local_context** chain, ctx_split* come_from_ctx)
: local_context(cmd_merge_ctx, chain)
{
come_from = come_from_ctx;
}
ctx_merge(local_context** chain, ctx_split* come_from_ctx, int value)
: local_context(cmd_case_ctx, chain)
{
come_from = come_from_ctx;
case_value = value;
}
virtual vbm_operand* transfer(method_desc* method, vbm_operand* sp,
byte cop, byte& prev_cop);
};
class ctx_pop_var : public local_context {
public:
int var_index;
ctx_pop_var(local_context** chain, int index)
: local_context(cmd_pop_var, chain), var_index(index) {}
virtual vbm_operand* transfer(method_desc* method, vbm_operand* sp,
byte cop, byte& prev_cop);
};
class ctx_push_var : public local_context {
public:
utf_string* var_name;
int var_type;
int var_index;
int var_start_pc;
ctx_push_var(local_context** chain,
utf_string* name, int type, int index, int start_pc)
: local_context(cmd_push_var, chain) {
var_name = name;
var_type = type;
var_index = index;
var_start_pc = start_pc;
}
virtual vbm_operand* transfer(method_desc* method, vbm_operand* sp,
byte cop, byte& prev_cop);
};
class ctx_reset : public local_context {
public:
int* var_store_count;
ctx_reset(local_context** chain, int* counts, int n_vars)
: local_context(cmd_reset_ctx, chain)
{
var_store_count = new int[n_vars];
memcpy(var_store_count, counts, n_vars*sizeof(int));
}
virtual vbm_operand* transfer(method_desc* method, vbm_operand* sp,
byte cop, byte& prev_cop);
};
#endif