implement lookupswitch
This commit is contained in:
parent
de4d8761f1
commit
f10429927b
2
Makefile
2
Makefile
@ -7,7 +7,7 @@ CC ?= gcc
|
||||
ARCH = -m32
|
||||
CFLAGS += -Wall -Werror -Wfatal-errors -Wno-error=unused-variable -fstack-protector -std=c2x -g
|
||||
CFLAGS += -DDEBUG
|
||||
#CFLAGS += -DDEBUG_PRINT
|
||||
CFLAGS += -DDEBUG_PRINT
|
||||
OPT ?= -O0
|
||||
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 \
|
||||
(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);
|
||||
|
||||
|
@ -2165,7 +2165,7 @@ void decode_execute_instruction(struct vm * vm, const uint8_t * code, uint32_t p
|
||||
{
|
||||
LOOKUPSWITCH_ARGS;
|
||||
vm->current_frame->next_pc = LOOKUPSWITCH_NEXT_PC;
|
||||
op_lookupswitch(vm);
|
||||
op_lookupswitch(vm, defaultbyte, npairs, table);
|
||||
break;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -177,7 +177,7 @@ void op_lload_2(struct vm * vm);
|
||||
void op_lload_3(struct vm * vm);
|
||||
void op_lmul(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_lrem(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