📄 pvmjac.c
字号:
case J_OPC_if_acmpeq: case J_OPC_if_acmpne: jac_microcode_stack_pop(S, 2); break; /* pop three and dispose */ case J_OPC_lcmp: case J_OPC_dcmpl: case J_OPC_dcmpg: jac_microcode_stack_pop(S, 3); break; /* pop all and dispose */ case J_OPC_ireturn: case J_OPC_lreturn: case J_OPC_freturn: case J_OPC_dreturn: case J_OPC_return: jac_microcode_stack_empty(S); break; /* set stack top to writable */ case J_OPC_arraylength: case J_OPC_instanceof: jac_microcode_stack_write(S, -1, JAC_TYP_Writable); break; case J_OPC_multianewarray: { ju1 dimension = pre_instr_multianewarray_dimension(instr); jac_microcode_stack_pop(S, dimension - 1); } break; case J_OPC_dup: jac_microcode_stack_push_type(S, jac_microcode_stack_read(S, -1)); break; case J_OPC_dup_x1: { char value1 = jac_microcode_stack_read(S, -1); char value2 = jac_microcode_stack_read(S, -2); jac_microcode_stack_write(S, -2, value1); jac_microcode_stack_write(S, -1, value2); jac_microcode_stack_push_type(S, value1); } break; case J_OPC_dup_x2: { char value1 = jac_microcode_stack_read(S, -1); char value2 = jac_microcode_stack_read(S, -2); char value3 = jac_microcode_stack_read(S, -3); jac_microcode_stack_write(S, -3, value1); jac_microcode_stack_write(S, -2, value3); jac_microcode_stack_write(S, -1, value2); jac_microcode_stack_push_type(S, value1); } break; case J_OPC_dup2: { char value1 = jac_microcode_stack_read(S, -1); char value2 = jac_microcode_stack_read(S, -2); jac_microcode_stack_push_type(S, value2); jac_microcode_stack_push_type(S, value1); } break; case J_OPC_dup2_x1: { char value1 = jac_microcode_stack_read(S, -1); char value2 = jac_microcode_stack_read(S, -2); char value3 = jac_microcode_stack_read(S, -3); jac_microcode_stack_write(S, -3, value2); jac_microcode_stack_write(S, -2, value1); jac_microcode_stack_write(S, -1, value3); jac_microcode_stack_push_type(S, value2); jac_microcode_stack_push_type(S, value1); } break; case J_OPC_dup2_x2: { char value1 = jac_microcode_stack_read(S, -1); char value2 = jac_microcode_stack_read(S, -2); char value3 = jac_microcode_stack_read(S, -3); char value4 = jac_microcode_stack_read(S, -4); jac_microcode_stack_write(S, -4, value2); jac_microcode_stack_write(S, -3, value1); jac_microcode_stack_write(S, -2, value4); jac_microcode_stack_write(S, -1, value3); jac_microcode_stack_push_type(S, value2); jac_microcode_stack_push_type(S, value1); } break; case J_OPC_swap: { char value1 = jac_microcode_stack_read(S, -1); char value2 = jac_microcode_stack_read(S, -2); jac_microcode_stack_write(S, -2, value1); jac_microcode_stack_write(S, -1, value2); } break; /* load locals into stack */ case J_OPC_aload_0: case J_OPC_aload_1: case J_OPC_aload_2: case J_OPC_aload_3: index = opcode - J_OPC_aload_0; goto COMMON_aload; case J_OPC_aload: index = pre_instr_locals_index(instr); COMMON_aload: jac_microcode_load(S, index); break; /* store one stack word into locals */ case J_OPC_istore_0: case J_OPC_istore_1: case J_OPC_istore_2: case J_OPC_istore_3: index = opcode - J_OPC_istore_0; goto COMMON_store; case J_OPC_fstore_0: case J_OPC_fstore_1: case J_OPC_fstore_2: case J_OPC_fstore_3: index = opcode - J_OPC_fstore_0; goto COMMON_store; case J_OPC_astore_0: case J_OPC_astore_1: case J_OPC_astore_2: case J_OPC_astore_3: index = opcode - J_OPC_astore_0; goto COMMON_store; case J_OPC_istore: case J_OPC_fstore: case J_OPC_astore: index = pre_instr_locals_index(instr); COMMON_store: jac_microcode_store(S, index); break; /* store two stack words into locals */ case J_OPC_lstore_0: case J_OPC_lstore_1: case J_OPC_lstore_2: case J_OPC_lstore_3: index = opcode - J_OPC_lstore_0; goto COMMON_store2; case J_OPC_dstore_0: case J_OPC_dstore_1: case J_OPC_dstore_2: case J_OPC_dstore_3: index = opcode - J_OPC_dstore_0; goto COMMON_store2; case J_OPC_lstore: case J_OPC_dstore: index = pre_instr_locals_index(instr); COMMON_store2: jac_microcode_store(S, index); jac_microcode_store(S, index+1); break; /* wide */ case J_OPC_wide: index = pre_instr_locals_wide_index(instr); switch (pre_instr_locals_wide_widened_opcode(instr)) { /* push one writable */ case J_OPC_iload: case J_OPC_fload: jac_microcode_stack_push_type(S, JAC_TYP_Writable); break; /* load locals into stack */ case J_OPC_aload: index = pre_instr_locals_index(instr); jac_microcode_load(S, index); break; /* push two writable */ case J_OPC_lload: case J_OPC_dload: jac_microcode_stack_push_type(S, JAC_TYP_Writable); jac_microcode_stack_push_type(S, JAC_TYP_Writable); break; /* store one stack word into locals */ case J_OPC_istore: case J_OPC_fstore: case J_OPC_astore: index = pre_instr_locals_index(instr); jac_microcode_store(S, index); break; /* store two stack words into locals */ case J_OPC_lstore: case J_OPC_dstore: index = pre_instr_locals_index(instr); jac_microcode_store(S, index); jac_microcode_store(S, index+1); break; /* no op */ case J_OPC_ret: case J_OPC_iinc: break; default: j_assert_not_reached(); } break; /* pop and dispose two, and then push one writable */ case J_OPC_baload: case J_OPC_caload: case J_OPC_saload: case J_OPC_iaload: case J_OPC_faload: jac_microcode_stack_pop(S, 1); jac_microcode_stack_write(S, -1, JAC_TYP_Writable); break; /* pop and dispose two, and then push two writable */ case J_OPC_laload: case J_OPC_daload: jac_microcode_stack_write(S, -2, JAC_TYP_Writable); break; /* store to array of primitives */ case J_OPC_bastore: case J_OPC_castore: case J_OPC_sastore: case J_OPC_iastore: case J_OPC_fastore: if (jac_microcode_stack_read(S, -3) == JAC_TYP_ReadOnly) return false; jac_microcode_stack_pop(S, 3); /* fall thru */ case J_OPC_lastore: case J_OPC_dastore: if (jac_microcode_stack_read(S, -4) == JAC_TYP_ReadOnly) return false; jac_microcode_stack_pop(S, 4); break; case J_OPC_aastore: if (jac_microcode_stack_read(S, -1) == JAC_TYP_ReadOnly || jac_microcode_stack_read(S, -3) == JAC_TYP_ReadOnly) return false; jac_microcode_stack_pop(S, 3); break; /* athrow */ case J_OPC_athrow: if (jac_microcode_stack_pop_type(S) == JAC_TYP_ReadOnly) false; break; case J_OPC_areturn: /* check return type, and then pop all and dispose */ { char type = jac_microcode_stack_read(S, 0); if (! jac_subtype(type, return_type)) return false; jac_microcode_stack_empty(S); } break; case J_OPC_getfield: { /* Pop objectref */ char type = jac_microcode_stack_pop_type(S); char value; /* Decide what value to push */ ju2 index = pre_instr_cp_wide_index(instr); const char *descriptor = pre_constant_pool_fieldref_descriptor(constant_pool, index); const char *annotation = jac_get_constant_annotation(commitments, constant_pool, index); if (type == JAC_TYP_ReadOnly && (*descriptor == J_ASCII_reference || *descriptor == J_ASCII_array)) value = JAC_TYP_ReadOnly; else if (annotation == 0) value = JAC_TYP_Writable; else value = *annotation; /* Push value */ switch (*descriptor) { case J_ASCII_long: case J_ASCII_double: jac_microcode_stack_push_type(S, value); default: jac_microcode_stack_push_type(S, value); } } break; case J_OPC_getstatic: { /* Decide what value to push */ ju2 index = pre_instr_cp_wide_index(instr); const char *descriptor = pre_constant_pool_fieldref_descriptor(constant_pool, index); const char *annotation = jac_get_constant_annotation(commitments, constant_pool, index); char value = ((annotation == 0) ? JAC_TYP_Writable : *annotation); /* Push value */ switch (*descriptor) { case J_ASCII_long: case J_ASCII_double: jac_microcode_stack_push_type(S, value); default: jac_microcode_stack_push_type(S, value); } } break; case J_OPC_putfield: { ju2 index = pre_instr_cp_wide_index(instr); const char *descriptor = pre_constant_pool_fieldref_descriptor(constant_pool, index); switch (*descriptor) { case J_ASCII_boolean: case J_ASCII_byte: case J_ASCII_char: case J_ASCII_short: case J_ASCII_int: case J_ASCII_float: { char objectref = jac_microcode_stack_read(S, -2); if (objectref == JAC_TYP_ReadOnly) return false; jac_microcode_stack_pop(S, 2); } break; case J_ASCII_long: case J_ASCII_double: { char objectref = jac_microcode_stack_read(S, -3); if (objectref == JAC_TYP_ReadOnly) return false; jac_microcode_stack_pop(S, 3); } break; case J_ASCII_reference: case J_ASCII_array: { char objectref = jac_microcode_stack_read(S, -2); if (objectref == JAC_TYP_ReadOnly) return false; char value = jac_microcode_stack_read(S, -1); const char *annotation = jac_get_constant_annotation(commitments, constant_pool, index); if (! jac_subtype(value, ((annotation == 0) ? JAC_TYP_Writable : *annotation))) return false; jac_microcode_stack_pop(S, 2); } break; default: j_assert_not_reached(); } } break; case J_OPC_putstatic: { ju2 index = pre_instr_cp_wide_index(instr); const char *descriptor = pre_constant_pool_fieldref_descriptor(constant_pool, index); switch (*descriptor) { case J_ASCII_boolean: case J_ASCII_byte: case J_ASCII_char: case J_ASCII_short: case J_ASCII_int: case J_ASCII_float: jac_microcode_stack_pop(S, 1); break; case J_ASCII_long: case J_ASCII_double: jac_microcode_stack_pop(S, 2); break; case J_ASCII_reference: case J_ASCII_array: { char value = jac_microcode_stack_pop_type(S); const char *annotation = jac_get_constant_annotation(commitments, constant_pool, index); if (! jac_subtype(value, ((annotation == 0) ? JAC_TYP_Writable : *annotation))) return false; } break; default: j_assert_not_reached(); } } break; case J_OPC_invokespecial: case J_OPC_invokevirtual: case J_OPC_invokestatic: case J_OPC_invokeinterface: { /* Get descriptor and annotation */ ju2 index; if (opcode == J_OPC_invokeinterface) { index = pre_instr_invokeinterface_index(instr); } else { index = pre_instr_cp_wide_index(instr); } const char *descriptor = pre_constant_pool_methodref_descriptor(constant_pool, index); const char *annotation = jac_get_constant_annotation(commitments, constant_pool, index); /* Pop all arguments */ ju2 nargs = j_utf8_method_descriptor_words_count(descriptor); if (opcode != J_OPC_invokestatic) nargs += 1; jac_microcode_stack_pop(S, nargs); /* Check arguments and push return type */ ju2 i; if (annotation == 0) { /* Make sure all arguments are writable */ for (i = 0; i < nargs; i++) if (jac_microcode_stack_read(S, i) == JAC_TYP_ReadOnly) return false; /* Push writable as return type */ switch (j_utf8_method_descriptor_return_type(descriptor)[0]) { case J_ASCII_long: case J_ASCII_double: jac_microcode_stack_push_type(S, JAC_TYP_Writable); default: jac_microcode_stack_push_type(S, JAC_TYP_Writable); case J_ASCII_void: ; } } else { i = 0; /* Process objectref if there is any */ if (opcode == J_OPC_invokestatic) { /* No objectref to check */ ++annotation; /* objectref */ ++annotation; /* left bracket */ } else { /* Check objectref */ char objectref = jac_microcode_stack_read(S, i); ++i; if (! jac_subtype(objectref, *annotation)) return false; ++annotation; /* objectref */ ++annotation; /* left bracket */ } /* Check rest of arguments */ for (; i < nargs; i++) { char word = jac_microcode_stack_read(S, i); ++i; if (! jac_subtype(word, *annotation)) return false; ++annotation; } /* Push return type */ ++annotation; /* right bracket */ switch (j_utf8_method_descriptor_return_type(descriptor)[0]) { case J_ASCII_long: case J_ASCII_double: jac_microcode_stack_push_type(S, *annotation); default: jac_microcode_stack_push_type(S, *annotation); case J_ASCII_void: ; } } } break; default: j_assert_not_reached(); } /* switch */#ifdef JAC_PVM_DEBUG fprintf(stderr, "After:\n"); jac_print_state(stderr, S);#endif /* * Propagate effect to successor states */ ju4 k; switch (opcode) { case J_OPC_nop: case J_OPC_aconst_null: case J_OPC_iconst_m1: case J_OPC_iconst_0: case J_OPC_iconst_1: case J_OPC_iconst_2: case J_OPC_iconst_3: case J_OPC_iconst_4: case J_OPC_iconst_5: case J_OPC_lconst_0: case J_OPC_lconst_1: case J_OPC_bipush: case J_OPC_sipush: case J_OPC_fconst_0: case J_OPC_fconst_1: case J_OPC_fconst_2: case J_OPC_dconst_0: case J_OPC_dconst_1: case J_OPC_ldc: case J_OPC_ldc_w: case J_OPC_ldc2_w: case J_OPC_iload: case J_OPC_lload: case J_OPC_fload: case J_OPC_dload: case J_OPC_aload: case J_OPC_iload_0: case J_OPC_iload_1:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -