📄 interp.c
字号:
/* * Copyright (C) 2003, 2004, 2005, 2006, 2007 * Robert Lougher <rob@lougher.org.uk>. * * This file is part of JamVM. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */#define _GNU_SOURCE#include <stdio.h>#include <arpa/inet.h>#include <stdlib.h>#include <string.h>#include <math.h>#include "jam.h"#include "thread.h"#include "lock.h"#include "interp.h"#ifdef DIRECT#ifdef INLINING#include "interp-inlining.h"#else#include "interp-direct.h"#endif#else#include "interp-indirect.h"#endifuintptr_t *executeJava() {#ifdef THREADED#define L(opcode, level, label) &&opc##opcode##_##level##_##label#ifdef DIRECT#define D(opcode, level, label) &&rewrite_lock#else#define D(opcode, level, label) L(opcode, level, label)#endif#ifdef INLINING#define I(opcode, level, label) L(opcode, level, label)#else#define I(opcode, level, label) &&rewrite_lock#endif#ifdef INLINING#define DEF_HANDLER_TABLES(level) \ DEF_HANDLER_TABLE(level, START); \ DEF_HANDLER_TABLE(level, ENTRY); \ DEF_HANDLER_TABLE(level, END);#else#define DEF_HANDLER_TABLES(level) \ DEF_HANDLER_TABLE(level, ENTRY);#endif#define DEF_HANDLER_TABLE(lvl,lbl) \ HANDLER_TABLE_T *handlers_##lvl##_##lbl[] = { \ L(0,lvl,lbl), L(1,lvl,lbl), L(2,lvl,lbl), L(3,lvl,lbl), L(4,lvl,lbl), \ L(5,lvl,lbl), L(6,lvl,lbl), L(7,lvl,lbl), L(8,lvl,lbl), L(9,lvl,lbl), \ L(10,lvl,lbl), L(11,lvl,lbl), L(12,lvl,lbl), L(13,lvl,lbl), L(14,lvl,lbl), \ L(15,lvl,lbl), L(16,lvl,lbl), L(17,lvl,lbl), L(18,lvl,lbl), D(19,lvl,lbl), \ L(20,lvl,lbl), L(21,lvl,lbl), L(22,lvl,lbl), L(23,lvl,lbl), L(24,lvl,lbl), \ L(25,lvl,lbl), L(26,lvl,lbl), L(27,lvl,lbl), L(28,lvl,lbl), L(29,lvl,lbl), \ L(30,lvl,lbl), L(31,lvl,lbl), L(32,lvl,lbl), L(33,lvl,lbl), L(34,lvl,lbl), \ L(35,lvl,lbl), L(36,lvl,lbl), L(37,lvl,lbl), L(38,lvl,lbl), L(39,lvl,lbl), \ L(40,lvl,lbl), L(41,lvl,lbl), D(42,lvl,lbl), L(43,lvl,lbl), L(44,lvl,lbl), \ L(45,lvl,lbl), L(46,lvl,lbl), L(47,lvl,lbl), L(48,lvl,lbl), L(49,lvl,lbl), \ L(50,lvl,lbl), L(51,lvl,lbl), L(52,lvl,lbl), L(53,lvl,lbl), L(54,lvl,lbl), \ L(55,lvl,lbl), L(56,lvl,lbl), L(57,lvl,lbl), L(58,lvl,lbl), L(59,lvl,lbl), \ L(60,lvl,lbl), L(61,lvl,lbl), L(62,lvl,lbl), L(63,lvl,lbl), L(64,lvl,lbl), \ L(65,lvl,lbl), L(66,lvl,lbl), L(67,lvl,lbl), L(68,lvl,lbl), L(69,lvl,lbl), \ L(70,lvl,lbl), L(71,lvl,lbl), L(72,lvl,lbl), L(73,lvl,lbl), L(74,lvl,lbl), \ L(75,lvl,lbl), L(76,lvl,lbl), L(77,lvl,lbl), L(78,lvl,lbl), L(79,lvl,lbl), \ L(80,lvl,lbl), L(81,lvl,lbl), L(82,lvl,lbl), L(83,lvl,lbl), L(84,lvl,lbl), \ L(85,lvl,lbl), L(86,lvl,lbl), L(87,lvl,lbl), L(88,lvl,lbl), L(89,lvl,lbl), \ L(90,lvl,lbl), L(91,lvl,lbl), L(92,lvl,lbl), L(93,lvl,lbl), L(94,lvl,lbl), \ L(95,lvl,lbl), L(96,lvl,lbl), L(97,lvl,lbl), L(98,lvl,lbl), L(99,lvl,lbl), \ L(100,lvl,lbl), L(101,lvl,lbl), L(102,lvl,lbl), L(103,lvl,lbl), L(104,lvl,lbl), \ L(105,lvl,lbl), L(106,lvl,lbl), L(107,lvl,lbl), L(108,lvl,lbl), L(109,lvl,lbl), \ L(110,lvl,lbl), L(111,lvl,lbl), L(112,lvl,lbl), L(113,lvl,lbl), L(114,lvl,lbl), \ L(115,lvl,lbl), L(116,lvl,lbl), L(117,lvl,lbl), L(118,lvl,lbl), L(119,lvl,lbl), \ L(120,lvl,lbl), L(121,lvl,lbl), L(122,lvl,lbl), L(123,lvl,lbl), L(124,lvl,lbl), \ L(125,lvl,lbl), L(126,lvl,lbl), L(127,lvl,lbl), L(128,lvl,lbl), L(129,lvl,lbl), \ L(130,lvl,lbl), L(131,lvl,lbl), L(132,lvl,lbl), L(133,lvl,lbl), L(134,lvl,lbl), \ L(135,lvl,lbl), L(136,lvl,lbl), L(137,lvl,lbl), L(138,lvl,lbl), L(139,lvl,lbl), \ L(140,lvl,lbl), L(141,lvl,lbl), L(142,lvl,lbl), L(143,lvl,lbl), L(144,lvl,lbl), \ L(145,lvl,lbl), L(146,lvl,lbl), L(147,lvl,lbl), L(148,lvl,lbl), L(149,lvl,lbl), \ L(150,lvl,lbl), L(151,lvl,lbl), L(152,lvl,lbl), L(153,lvl,lbl), L(154,lvl,lbl), \ L(155,lvl,lbl), L(156,lvl,lbl), L(157,lvl,lbl), L(158,lvl,lbl), L(159,lvl,lbl), \ L(160,lvl,lbl), L(161,lvl,lbl), L(162,lvl,lbl), L(163,lvl,lbl), L(164,lvl,lbl), \ L(165,lvl,lbl), L(166,lvl,lbl), L(167,lvl,lbl), L(168,lvl,lbl), L(169,lvl,lbl), \ L(170,lvl,lbl), L(171,lvl,lbl), L(172,lvl,lbl), L(173,lvl,lbl), L(174,lvl,lbl), \ L(175,lvl,lbl), L(176,lvl,lbl), L(177,lvl,lbl), L(178,lvl,lbl), L(179,lvl,lbl), \ L(180,lvl,lbl), L(181,lvl,lbl), L(182,lvl,lbl), L(183,lvl,lbl), L(184,lvl,lbl), \ L(185,lvl,lbl), &&unused, L(187,lvl,lbl), L(188,lvl,lbl), L(189,lvl,lbl), \ L(190,lvl,lbl), L(191,lvl,lbl), L(192,lvl,lbl), L(193,lvl,lbl), L(194,lvl,lbl), \ L(195,lvl,lbl), D(196,lvl,lbl), L(197,lvl,lbl), L(198,lvl,lbl), L(199,lvl,lbl), \ L(200,lvl,lbl), L(201,lvl,lbl), &&unused, L(203,lvl,lbl), L(204,lvl,lbl), \ &&unused, L(206,lvl,lbl), L(207,lvl,lbl), L(208,lvl,lbl), L(209,lvl,lbl), \ L(210,lvl,lbl), L(211,lvl,lbl), L(212,lvl,lbl), L(213,lvl,lbl), L(214,lvl,lbl), \ L(215,lvl,lbl), L(216,lvl,lbl), &&unused, &&unused, &&unused, &&unused, \ &&unused, &&unused, &&unused, &&unused, &&unused, D(226,lvl,lbl), \ D(227,lvl,lbl), D(228,lvl,lbl), L(229,lvl,lbl), D(230,lvl,lbl), L(231,lvl,lbl), \ L(232,lvl,lbl), L(233,lvl,lbl), &&unused, L(235,lvl,lbl), &&unused, \ &&unused, L(238,lvl,lbl), L(239,lvl,lbl), &&unused, &&unused, &&unused, \ L(243,lvl,lbl), L(244,lvl,lbl), L(245,lvl,lbl), I(246,lvl,lbl), &&unused, \ &&unused, &&unused, &&unused, &&unused, &&unused, &&unused, &&unused, \ &&unused} DEF_HANDLER_TABLES(0);#ifdef USE_CACHE DEF_HANDLER_TABLES(1); DEF_HANDLER_TABLES(2);#ifdef INLINING static const void **handlers[] = {handlers_0_ENTRY, handlers_1_ENTRY, handlers_2_ENTRY, handlers_0_START, handlers_1_START, handlers_2_START, handlers_0_END, handlers_1_END, handlers_2_END};#else static const void **handlers[] = {handlers_0_ENTRY, handlers_1_ENTRY, handlers_2_ENTRY};#endif#else#ifdef INLINING static const void **handlers[] = {handlers_0_ENTRY, handlers_0_START, handlers_0_END};#else static const void **handlers[] = {handlers_0_ENTRY};#endif#endif#ifdef INLINING extern int inlining_inited; if(!inlining_inited) return (uintptr_t*)handlers; int oob_array_index = 0; void *throwOOBLabel = &&throwOOB; void *throwNullLabel = &&throwNull; void *throwArithmeticExcepLabel = &&throwArithmeticExcep;#endif#ifdef PREFETCH const void *next_handler;#endif#ifdef USE_CACHE union { struct { uintptr_t v1; uintptr_t v2; } i; long long l; } cache;#endif#endif CodePntr pc; ExecEnv *ee = getExecEnv(); Frame *frame = ee->last_frame; MethodBlock *mb = frame->mb; uintptr_t *lvars = frame->lvars; uintptr_t *ostack = frame->ostack; ConstantPool *cp = &(CLASS_CB(mb->class)->constant_pool); Object *this = (Object*)lvars[0]; MethodBlock *new_mb; Class *new_class; uintptr_t *arg1; PREPARE_MB(mb); pc = (CodePntr)mb->code;#ifdef THREADEDrewrite_lock: DISPATCH_FIRST#else while(TRUE) { switch(*pc) { default:#endifunused:#ifndef DIRECT jam_printf("Unrecognised opcode %d in: %s.%s\n", *pc, CLASS_CB(mb->class)->name, mb->name); exitVM(1);#endif#ifdef INLINING throwOOBLabel = NULL; throwNullLabel = NULL; throwArithmeticExcepLabel = NULL;#endif#define MULTI_LEVEL_OPCODES(level) \ DEF_OPC(OPC_ICONST_M1, level, \ PUSH_##level(-1, 1); \ ) \ \ DEF_OPC_3(OPC_ACONST_NULL, \ OPC_ICONST_0, \ OPC_FCONST_0, level, \ PUSH_##level(0, 1); \ ) \ \ DEF_OPC(OPC_ICONST_1, level, \ PUSH_##level(1, 1); \ ) \ \ DEF_OPC(OPC_ICONST_2, level, \ PUSH_##level(2, 1); \ ) \ \ DEF_OPC(OPC_ICONST_3, level, \ PUSH_##level(3, 1); \ ) \ \ DEF_OPC(OPC_ICONST_4, level, \ PUSH_##level(4, 1); \ ) \ \ DEF_OPC(OPC_ICONST_5, level, \ PUSH_##level(5, 1); \ ) \ \ DEF_OPC(OPC_FCONST_1, level, \ PUSH_##level(FLOAT_1_BITS, 1); \ ) \ \ DEF_OPC(OPC_FCONST_2, level, \ PUSH_##level(FLOAT_2_BITS, 1); \ ) \ \ DEF_OPC(OPC_SIPUSH, level, \ PUSH_##level(DOUBLE_SIGNED(pc), 3); \ ) \ \ DEF_OPC(OPC_BIPUSH, level, \ PUSH_##level(SINGLE_SIGNED(pc), 2); \ ) \ \ DEF_OPC(OPC_LDC_QUICK, level, \ PUSH_##level(RESOLVED_CONSTANT(pc), 2); \ ) \ \ DEF_OPC(OPC_LDC_W_QUICK, level, \ PUSH_##level(CP_INFO(cp, DOUBLE_INDEX(pc)), 3); \ ) \ \ DEF_OPC_3(OPC_ILOAD, \ OPC_FLOAD, \ OPC_ALOAD, level, \ PUSH_##level(lvars[SINGLE_INDEX(pc)], 2); \ ) \ \ DEF_OPC(OPC_ALOAD_THIS, level, \ ALOAD_THIS(level); \ ) \ \ DEF_OPC_2(OPC_ILOAD_0, \ OPC_FLOAD_0, level, \ PUSH_##level(lvars[0], 1) \ ) \ \ DEF_OPC_3(OPC_ILOAD_1, \ OPC_FLOAD_1, \ OPC_ALOAD_1, level, \ PUSH_##level(lvars[1], 1); \ ) \ \ DEF_OPC_3(OPC_ILOAD_2, \ OPC_FLOAD_2, \ OPC_ALOAD_2, level, \ PUSH_##level(lvars[2], 1); \ ) \ \ DEF_OPC_3(OPC_ILOAD_3, \ OPC_FLOAD_3, \ OPC_ALOAD_3, level, \ PUSH_##level(lvars[3], 1); \ ) \ \ DEF_OPC_3(OPC_ISTORE, \ OPC_FSTORE, \ OPC_ASTORE, level, \ POP_##level(lvars[SINGLE_INDEX(pc)], 2); \ ) \ \ DEF_OPC_3(OPC_ISTORE_0, \ OPC_ASTORE_0, \ OPC_FSTORE_0, level, \ POP_##level(lvars[0], 1); \ ) \ \ DEF_OPC_3(OPC_ISTORE_1, \ OPC_ASTORE_1, \ OPC_FSTORE_1, level, \ POP_##level(lvars[1], 1); \ ) \ \ DEF_OPC_3(OPC_ISTORE_2, \ OPC_ASTORE_2, \ OPC_FSTORE_2, level, \ POP_##level(lvars[2], 1); \ ) \ \ DEF_OPC_3(OPC_ISTORE_3, \ OPC_ASTORE_3, \ OPC_FSTORE_3, level, \ POP_##level(lvars[3], 1); \ ) \ \ DEF_OPC(OPC_IADD, level, \ BINARY_OP_##level(+); \ ) \ \ DEF_OPC(OPC_ISUB, level, \ BINARY_OP_##level(-); \ ) \ \ DEF_OPC(OPC_IMUL, level, \ BINARY_OP_##level(*); \ ) \ \ DEF_OPC(OPC_IDIV, level, \ ZERO_DIVISOR_CHECK_##level; \ BINARY_OP_##level(/); \ ) \ \ DEF_OPC(OPC_IREM, level, \ ZERO_DIVISOR_CHECK_##level; \ BINARY_OP_##level(%); \ ) \ \ DEF_OPC(OPC_IAND, level, \ BINARY_OP_##level(&); \ ) \ \ DEF_OPC(OPC_IOR, level, \ BINARY_OP_##level(|); \ ) \ \ DEF_OPC(OPC_IXOR, level, \ BINARY_OP_##level(^); \ ) \ \ DEF_OPC(OPC_INEG, level, \ UNARY_MINUS_##level; \ ) \ \ DEF_OPC(OPC_ISHL, level, \ SHIFT_OP_##level(int, <<); \ ) \ \ DEF_OPC(OPC_ISHR, level, \ SHIFT_OP_##level(int, >>); \ ) \ \ DEF_OPC(OPC_IUSHR, level, \ SHIFT_OP_##level(unsigned int, >>); \ ) \ \ DEF_OPC_2(OPC_IF_ACMPEQ, \ OPC_IF_ICMPEQ, level, \ IF_ICMP_##level(==); \ ) \ \ DEF_OPC_2(OPC_IF_ACMPNE, \ OPC_IF_ICMPNE, level, \ IF_ICMP_##level(!=); \ ) \ \ DEF_OPC(OPC_IF_ICMPLT, level, \ IF_ICMP_##level(<); \ ) \ \ DEF_OPC(OPC_IF_ICMPGE, level, \ IF_ICMP_##level(>=); \ ) \ \ DEF_OPC(OPC_IF_ICMPGT, level, \ IF_ICMP_##level(>); \ ) \ \ DEF_OPC(OPC_IF_ICMPLE, level, \ IF_ICMP_##level(<=); \ ) \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -