@@ -20,26 +20,47 @@ typedef enum {
2020 i_iconst_3 = 0x6 ,
2121 i_iconst_4 = 0x7 ,
2222 i_iconst_5 = 0x8 ,
23+ i_lconst_0 = 0x9 ,
24+ i_lconst_1 = 0xa ,
2325 i_bipush = 0x10 ,
2426 i_sipush = 0x11 ,
2527 i_ldc = 0x12 ,
28+ i_ldc2_w = 0x14 ,
2629 i_iload = 0x15 ,
30+ i_lload = 0x16 ,
2731 i_iload_0 = 0x1a ,
2832 i_iload_1 = 0x1b ,
2933 i_iload_2 = 0x1c ,
3034 i_iload_3 = 0x1d ,
35+ i_lload_0 = 0x1e ,
36+ i_lload_1 = 0x1f ,
37+ i_lload_2 = 0x20 ,
38+ i_lload_3 = 0x21 ,
3139 i_istore = 0x36 ,
40+ i_lstore = 0x37 ,
3241 i_istore_0 = 0x3b ,
3342 i_istore_1 = 0x3c ,
3443 i_istore_2 = 0x3d ,
3544 i_istore_3 = 0x3e ,
45+ i_lstore_0 = 0x3f ,
46+ i_lstore_1 = 0x40 ,
47+ i_lstore_2 = 0x41 ,
48+ i_lstore_3 = 0x42 ,
3649 i_iadd = 0x60 ,
50+ i_ladd = 0x61 ,
3751 i_isub = 0x64 ,
52+ i_lsub = 0x65 ,
3853 i_imul = 0x68 ,
54+ i_lmul = 0x69 ,
3955 i_idiv = 0x6c ,
56+ i_ldiv = 0x6d ,
4057 i_irem = 0x70 ,
58+ i_lrem = 0x71 ,
4159 i_ineg = 0x74 ,
4260 i_iinc = 0x84 ,
61+ i_i2l = 0x85 ,
62+ i_l2i = 0x88 ,
63+ i_lcmp = 0x94 ,
4364 i_ifeq = 0x99 ,
4465 i_ifne = 0x9a ,
4566 i_iflt = 0x9b ,
@@ -54,6 +75,7 @@ typedef enum {
5475 i_if_icmple = 0xa4 ,
5576 i_goto = 0xa7 ,
5677 i_ireturn = 0xac ,
78+ i_lreturn = 0xad ,
5779 i_return = 0xb1 ,
5880 i_getstatic = 0xb2 ,
5981 i_invokevirtual = 0xb6 ,
@@ -128,10 +150,10 @@ static inline void ineg(stack_frame_t *op_stack)
128150
129151static inline void invokevirtual (stack_frame_t * op_stack )
130152{
131- int32_t op = pop_int (op_stack );
153+ int64_t op = pop_int (op_stack );
132154
133155 /* FIXME: the implement is not correct. */
134- printf ("%d \n" , op );
156+ printf ("%ld \n" , op );
135157}
136158
137159static inline void iconst (stack_frame_t * op_stack , uint8_t current )
@@ -183,6 +205,18 @@ stack_entry_t *execute(method_t *method,
183205 return ret ;
184206 }
185207
208+ /* Return long from method */
209+ case i_lreturn : {
210+ stack_entry_t * ret = malloc (sizeof (stack_entry_t ));
211+ ret -> entry .long_value = (int64_t ) pop_int (op_stack );
212+ ret -> type = STACK_ENTRY_LONG ;
213+ 214+ free (op_stack -> store );
215+ free (op_stack );
216+ 217+ return ret ;
218+ }
219+ 186220 /* Return void from method */
187221 case i_return : {
188222 stack_entry_t * ret = malloc (sizeof (stack_entry_t ));
@@ -211,6 +245,9 @@ stack_entry_t *execute(method_t *method,
211245 case STACK_ENTRY_INT :
212246 push_int (op_stack , exec_res -> entry .int_value );
213247 break ;
248+ case STACK_ENTRY_LONG :
249+ push_long (op_stack , exec_res -> entry .long_value );
250+ break ;
214251 case STACK_ENTRY_NONE :
215252 /* nothing */
216253 break ;
@@ -223,6 +260,20 @@ stack_entry_t *execute(method_t *method,
223260 break ;
224261 }
225262
263+ /* Compare long */
264+ case i_lcmp : {
265+ int64_t op1 = pop_int (op_stack ), op2 = pop_int (op_stack );
266+ if (op1 < op2 ) {
267+ push_int (op_stack , 1 );
268+ } else if (op1 == op2 ) {
269+ push_int (op_stack , 0 );
270+ } else {
271+ push_int (op_stack , -1 );
272+ }
273+ pc += 1 ;
274+ break ;
275+ }
276+ 226277 /* Branch if int comparison with zero succeeds: if equals */
227278 case i_ifeq : {
228279 uint8_t param1 = code_buf [pc + 1 ], param2 = code_buf [pc + 2 ];
@@ -393,6 +444,56 @@ stack_entry_t *execute(method_t *method,
393444 break ;
394445 }
395446
447+ /* Push long or double from run-time constant pool (wide index) */
448+ case i_ldc2_w : {
449+ uint8_t param1 = code_buf [pc + 1 ], param2 = code_buf [pc + 2 ];
450+ uint16_t index = ((param1 << 8 ) | param2 );
451+ 452+ uint64_t high = ((CONSTANT_LongOrDouble_info * ) get_constant (
453+ & clazz -> constant_pool , index )
454+ -> info )
455+ -> high_bytes ;
456+ uint64_t low = ((CONSTANT_LongOrDouble_info * ) get_constant (
457+ & clazz -> constant_pool , index )
458+ -> info )
459+ -> low_bytes ;
460+ int64_t value = high << 32 | low ;
461+ push_long (op_stack , value );
462+ pc += 3 ;
463+ break ;
464+ }
465+ 466+ /* Load long from local variable */
467+ case i_lload : {
468+ int32_t param = code_buf [pc + 1 ];
469+ int64_t loaded ;
470+ loaded = locals [param ].entry .long_value ;
471+ push_long (op_stack , loaded );
472+ 473+ pc += 2 ;
474+ break ;
475+ }
476+ 477+ /* FIXME: this implementation has some bugs.
478+ * In standard JVM, one stack entry only store four
479+ * bytes data, so in some method descriptor (e.g (JJ)V)
480+ * the long value will store in locals[0] and locals[2]
481+ * rather than locals[0] and locals[1].
482+ */
483+ /* Load long from local variable */
484+ case i_lload_0 :
485+ case i_lload_1 :
486+ case i_lload_2 :
487+ case i_lload_3 : {
488+ int64_t param = current - i_lload_0 ;
489+ int64_t loaded ;
490+ loaded = locals [param ].entry .long_value ;
491+ push_long (op_stack , loaded );
492+ 493+ pc += 1 ;
494+ break ;
495+ }
496+ 396497 /* Load int from local variable */
397498 case i_iload_0 :
398499 case i_iload_1 :
@@ -419,6 +520,31 @@ stack_entry_t *execute(method_t *method,
419520 break ;
420521 }
421522
523+ /* Store long into local variable */
524+ case i_lstore : {
525+ int32_t param = code_buf [pc + 1 ];
526+ int64_t stored = pop_int (op_stack );
527+ locals [param ].entry .long_value = stored ;
528+ locals [param ].type = STACK_ENTRY_LONG ;
529+ 530+ pc += 2 ;
531+ break ;
532+ }
533+ 534+ /* Store long into local variable */
535+ case i_lstore_0 :
536+ case i_lstore_1 :
537+ case i_lstore_2 :
538+ case i_lstore_3 : {
539+ int32_t param = current - i_lstore_0 ;
540+ int64_t stored = pop_int (op_stack );
541+ locals [param ].entry .long_value = stored ;
542+ locals [param ].type = STACK_ENTRY_LONG ;
543+ 544+ pc += 1 ;
545+ break ;
546+ }
547+ 422548 /* Store int into local variable */
423549 case i_istore : {
424550 int32_t param = code_buf [pc + 1 ];
@@ -451,6 +577,24 @@ stack_entry_t *execute(method_t *method,
451577 break ;
452578 }
453579
580+ /* Convert int to long */
581+ case i_i2l : {
582+ int32_t stored = pop_int (op_stack );
583+ push_long (op_stack , (int64_t ) stored );
584+ 585+ pc += 1 ;
586+ break ;
587+ }
588+ 589+ /* Convert int to char */
590+ case i_l2i : {
591+ int64_t stored = pop_int (op_stack );
592+ push_int (op_stack , (int32_t ) stored );
593+ 594+ pc += 1 ;
595+ break ;
596+ }
597+ 454598 /* Push byte */
455599 case i_bipush :
456600 bipush (op_stack , pc , code_buf );
@@ -463,31 +607,81 @@ stack_entry_t *execute(method_t *method,
463607 pc += 1 ;
464608 break ;
465609
610+ /* Add long */
611+ case i_ladd : {
612+ int64_t op1 = pop_int (op_stack );
613+ int64_t op2 = pop_int (op_stack );
614+ 615+ push_long (op_stack , op1 + op2 );
616+ pc += 1 ;
617+ break ;
618+ }
619+ 466620 /* Subtract int */
467621 case i_isub :
468622 isub (op_stack );
469623 pc += 1 ;
470624 break ;
471625
626+ /* Subtract long */
627+ case i_lsub : {
628+ int64_t op1 = pop_int (op_stack );
629+ int64_t op2 = pop_int (op_stack );
630+ 631+ push_long (op_stack , op2 - op1 );
632+ pc += 1 ;
633+ break ;
634+ }
635+ 472636 /* Multiply int */
473637 case i_imul :
474638 imul (op_stack );
475639 pc += 1 ;
476640 break ;
477641
642+ /* Multiply long */
643+ case i_lmul : {
644+ int64_t op1 = pop_int (op_stack );
645+ int64_t op2 = pop_int (op_stack );
646+ 647+ push_long (op_stack , op1 * op2 );
648+ pc += 1 ;
649+ break ;
650+ }
651+ 478652 /* Divide int */
479653 case i_idiv :
480654 idiv (op_stack );
481655 pc += 1 ;
482656 break ;
483657
658+ /* Divide long */
659+ case i_ldiv : {
660+ int64_t op1 = pop_int (op_stack );
661+ int64_t op2 = pop_int (op_stack );
662+ 663+ push_long (op_stack , op2 / op1 );
664+ pc += 1 ;
665+ break ;
666+ }
667+ 484668 /* Remainder int */
485669 case i_irem :
486670 irem (op_stack );
487671 pc += 1 ;
488672 break ;
489673
490- /* Negate int */
674+ /* Remainder long */
675+ case i_lrem : {
676+ int64_t op1 = pop_int (op_stack );
677+ int64_t op2 = pop_int (op_stack );
678+ 679+ push_long (op_stack , op2 % op1 );
680+ pc += 1 ;
681+ break ;
682+ }
683+ 684+ /* Negate int */
491685 case i_ineg :
492686 ineg (op_stack );
493687 pc += 1 ;
@@ -517,6 +711,14 @@ stack_entry_t *execute(method_t *method,
517711 pc += 1 ;
518712 break ;
519713
714+ /* Push long constant */
715+ case i_lconst_0 :
716+ case i_lconst_1 : {
717+ push_long (op_stack , current - i_lconst_0 );
718+ pc += 1 ;
719+ break ;
720+ }
721+ 520722 /* Push short */
521723 case i_sipush :
522724 sipush (op_stack , pc , code_buf );
0 commit comments