implement lookupswitch
This commit is contained in:
parent
de4d8761f1
commit
f10429927b
2
Makefile
2
Makefile
@ -7,7 +7,7 @@ CC ?= gcc
|
|||||||
ARCH = -m32
|
ARCH = -m32
|
||||||
CFLAGS += -Wall -Werror -Wfatal-errors -Wno-error=unused-variable -fstack-protector -std=c2x -g
|
CFLAGS += -Wall -Werror -Wfatal-errors -Wno-error=unused-variable -fstack-protector -std=c2x -g
|
||||||
CFLAGS += -DDEBUG
|
CFLAGS += -DDEBUG
|
||||||
#CFLAGS += -DDEBUG_PRINT
|
CFLAGS += -DDEBUG_PRINT
|
||||||
OPT ?= -O0
|
OPT ?= -O0
|
||||||
DEPFLAGS = -MMD -MP
|
DEPFLAGS = -MMD -MP
|
||||||
|
|
||||||
|
17
c/decode.c
17
c/decode.c
@ -82,11 +82,22 @@ static inline int32_t aligned_s4(const void * buf)
|
|||||||
#define TABLESWITCH_NEXT_PC \
|
#define TABLESWITCH_NEXT_PC \
|
||||||
(args + (3 * 4) + ((highbyte - lowbyte + 1) * 4))
|
(args + (3 * 4) + ((highbyte - lowbyte + 1) * 4))
|
||||||
|
|
||||||
#define LOOKUPSWITCH_ARGS assert(false);
|
#define LOOKUPSWITCH_ARGS \
|
||||||
|
uint32_t args = ((pc + 1) + 3) & (~3); \
|
||||||
|
int32_t defaultbyte = aligned_s4(&code[args + 0]); \
|
||||||
|
int32_t npairs = aligned_s4(&code[args + 4]); \
|
||||||
|
const int32_t * table = (const int32_t *)&code[args + 8];
|
||||||
|
|
||||||
#define LOOKUPSWITCH_PRINT_ARGS()
|
#define LOOKUPSWITCH_PRINT_ARGS() \
|
||||||
|
do { \
|
||||||
|
for (int i = 0; i < npairs; i++) { \
|
||||||
|
debugf(" %d: %d\n", aligned_s4(&table[i * 2]), aligned_s4(&table[i * 2 + 1])); \
|
||||||
|
} \
|
||||||
|
debugf("default: %d\n", defaultbyte); \
|
||||||
|
} while (0);
|
||||||
|
|
||||||
#define LOOKUPSWITCH_NEXT_PC 0
|
#define LOOKUPSWITCH_NEXT_PC \
|
||||||
|
(args + (2 * 4) + (npairs * 2 * 4))
|
||||||
|
|
||||||
#define WIDE_ARGS assert(false);
|
#define WIDE_ARGS assert(false);
|
||||||
|
|
||||||
|
@ -2165,7 +2165,7 @@ void decode_execute_instruction(struct vm * vm, const uint8_t * code, uint32_t p
|
|||||||
{
|
{
|
||||||
LOOKUPSWITCH_ARGS;
|
LOOKUPSWITCH_ARGS;
|
||||||
vm->current_frame->next_pc = LOOKUPSWITCH_NEXT_PC;
|
vm->current_frame->next_pc = LOOKUPSWITCH_NEXT_PC;
|
||||||
op_lookupswitch(vm);
|
op_lookupswitch(vm, defaultbyte, npairs, table);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 172: // ireturn
|
case 172: // ireturn
|
||||||
|
13
c/execute.c
13
c/execute.c
@ -1467,9 +1467,18 @@ void op_lneg(struct vm * vm)
|
|||||||
operand_stack_push_u64(vm->current_frame, result);
|
operand_stack_push_u64(vm->current_frame, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_lookupswitch(struct vm * vm)
|
void op_lookupswitch(struct vm * vm, int32_t defaultbyte, int32_t npairs, const int32_t * table)
|
||||||
{
|
{
|
||||||
assert(!"op_lookupswitch");
|
int32_t key = operand_stack_pop_u32(vm->current_frame);
|
||||||
|
for (int i = 0; i < npairs; i++) {
|
||||||
|
int32_t match = BE_BSWAP32(table[i * 2]);
|
||||||
|
if (key == match) {
|
||||||
|
int32_t offset = BE_BSWAP32(table[i * 2 + 1]);
|
||||||
|
vm->current_frame->pc = vm->current_frame->pc + offset;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vm->current_frame->pc = vm->current_frame->pc + defaultbyte;
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_lor(struct vm * vm)
|
void op_lor(struct vm * vm)
|
||||||
|
@ -177,7 +177,7 @@ void op_lload_2(struct vm * vm);
|
|||||||
void op_lload_3(struct vm * vm);
|
void op_lload_3(struct vm * vm);
|
||||||
void op_lmul(struct vm * vm);
|
void op_lmul(struct vm * vm);
|
||||||
void op_lneg(struct vm * vm);
|
void op_lneg(struct vm * vm);
|
||||||
void op_lookupswitch(struct vm * vm);
|
void op_lookupswitch(struct vm * vm, int32_t defaultbyte, int32_t npairs, const int32_t * table);
|
||||||
void op_lor(struct vm * vm);
|
void op_lor(struct vm * vm);
|
||||||
void op_lrem(struct vm * vm);
|
void op_lrem(struct vm * vm);
|
||||||
void op_lreturn(struct vm * vm);
|
void op_lreturn(struct vm * vm);
|
||||||
|
BIN
opcodes.ods
BIN
opcodes.ods
Binary file not shown.
18
p/LookupSwitch.java
Normal file
18
p/LookupSwitch.java
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package p;
|
||||||
|
|
||||||
|
class LookupSwitch {
|
||||||
|
static int foo(int a) {
|
||||||
|
switch (a) {
|
||||||
|
case 1: return 5;
|
||||||
|
case 10: return 42;
|
||||||
|
case 100: return 432;
|
||||||
|
case 1000: return 999;
|
||||||
|
case 10000: return 9999;
|
||||||
|
default: return 123;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main() {
|
||||||
|
foo(10);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user