📄 execute.c
字号:
/*0001*//*
/*0002./ * Copyright (c) 1998-2001 Sun Microsystems, Inc. All Rights Reserved.
/*0003./ *
/*0004./ * This software is the confidential and proprietary information of Sun
/*0005./ * Microsystems, Inc. ("Confidential Information"). You shall not
/*0006./ * disclose such Confidential Information and shall use it only in
/*0007./ * accordance with the terms of the license agreement you entered into
/*0008./ * with Sun.
/*0009./ *
/*0010./ * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
/*0011./ * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
/*0012./ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
/*0013./ * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
/*0014./ * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
/*0015./ * THIS SOFTWARE OR ITS DERIVATIVES.
/*0016./ *
/*0017./ */
/*0018*/
/*0019*//*=========================================================================
/*0020./ * SYSTEM: KVM
/*0021./ * SUBSYSTEM: Bytecode interpreter
/*0022./ * FILE: execute.c
/*0023./ * OVERVIEW: This file defines the interpreter execution loop.
/*0024./ * The interpreter was completely restructured for
/*0025./ * KVM 1.0.2. This file defines the heart of the
/*0026./ * interpreter, while the actual bytecode definitions
/*0027./ * are located in file bytecodes.c.
/*0028./ * AUTHOR: Major reorganization by Nik Shaylor 9/5/2000
/*0029./ *=======================================================================*/
/*0030*/
/*0031*//*=========================================================================
/*0032./ * Local include files
/*0033./ *=======================================================================*/
/*0034*/
/*0035*/#include <global.h>
/*0036*/#include <execute.h>
/*0037*/
/*0038*//*=========================================================================
/*0039./ * Redefine the Virtual Machine global registers
/*0040./ *=======================================================================*/
/*0041*/
/*0042*/#define ip ip_global
/*0043*/#define fp fp_global
/*0044*/#define sp sp_global
/*0045*/#define lp lp_global
/*0046*/#define cp cp_global
/*0047*/
/*0048*/#undef getIP
/*0049*/#define getIP() (ip)
/*0050*/#undef getFP
/*0051*/#define getFP() (fp)
/*0052*/#undef getSP
/*0053*/#define getSP() (sp)
/*0054*/#undef getLP
/*0055*/#define getLP() (lp)
/*0056*/#undef getCP
/*0057*/#define getCP() (cp)
/*0058*/
/*0059*/#undef setIP
/*0060*/#define setIP(x) (ip = (x))
/*0061*/#undef setFP
/*0062*/#define setFP(x) (fp = (x))
/*0063*/#undef setSP
/*0064*/#define setSP(x) (sp = (x))
/*0065*/#undef setLP
/*0066*/#define setLP(x) (lp = (x))
/*0067*/#undef setCP
/*0068*/#define setCP(x) (cp = (x))
/*0069*/
/*0082*//*************************************************************************
/*0083./ * Start of infrequent bytecodes option *
/*0084./ *************************************************************************/
/*0085*/
/*0086*/OBJECT thisObjectGCSafe = NULL;
/*0087*/
/*0088*/#if SPLITINFREQUENTBYTECODES
/*0089*/
/*0090*//*=========================================================================
/*0091./ * VMSAVE - Save the VM state
/*0092./ *=======================================================================*/
/*0093*/
/*0094*/#define VMSAVE /**/
/*0095*/
/*0096*//*=========================================================================
/*0097./ * VMRESTORE - Restore the VM state
/*0098./ *=======================================================================*/
/*0099*/
/*0100*/#define VMRESTORE /**/
/*0101*/
/*0102*//*=========================================================================
/*0103./ * TOKEN - Macro to get the current bytecode
/*0104./ *=======================================================================*/
/*0105*/
/*0106*/#define TOKEN token
/*0107*/
/*0108*//*=========================================================================
/*0109./ * FUNCTION: SlowInterpret()
/*0110./ * TYPE: private operation
/*0111./ * OVERVIEW: Execute bytecode (infrequently used Java bytecodes).
/*0112./ * INTERFACE:
/*0113./ * parameters: The bytecode to be executed
/*0114./ * returns: <nothing>
/*0115./ *
/*0116./ * NOTES:
/*0117./ * This function is called by the main Interpret() loop when the
/*0118./ * main loop does not contain the code for a specific bytecode.
/*0119./ * There are two reasons for this. First, the main loop runs using
/*0120./ * local copies of the main interpreter variables (ip, sp, etc.) and
/*0121./ * when a routine needs to be called that requires access to these
/*0122./ * variables via global memory, then the local copies are written
/*0123./ * back to their global counterpoints, and this routine is called
/*0124./ * to re-dispatch the bytecode in global context. Second, any
/*0125./ * infrequently executed bytecodes are normally put here to make
/*0126./ * the main interpreter loop as small as possible -- by doing this
/*0127./ * the C compiler will often optimize the main loop better.
/*0128./ *=======================================================================*/
/*0129*/
/*0130*/void SlowInterpret(ByteCode token) {
/*0131*/ METHOD thisMethod;
/*0132*/ OBJECT thisObject;
/*0133*/ int invokerSize;
/*0134*/
/*0137*/ switch (token) {
/*0138*/
/*0139*//*=======================================================================*/
/*0140*//* Include the bytecode definitions we need for this function */
/*0141*//*=======================================================================*/
/*0142*/#define STANDARDBYTECODES 0
/*0143*/#define FLOATBYTECODES 0
/*0144*/#define FASTBYTECODES 0
/*0145*/#define INFREQUENTSTANDARDBYTECODES 1
/*0146*/#include "bytecodes.c"
/*0147*/#undef STANDARDBYTECODES
/*0148*/#undef FLOATBYTECODES
/*0149*/#undef FASTBYTECODES
/*0150*/#undef INFREQUENTSTANDARDBYTECODES
/*0151*//*=======================================================================*/
/*0152*/
/*0153*/ callMethod_interface: {
/*0154*/ invokerSize = 5; /* Size of the bytecode */
/*0155*/ goto callMethod_general;
/*0156*/ }
/*0157*/
/*0158*/ callMethod_virtual:
/*0159*/ callMethod_static:
/*0160*/ callMethod_special:
/*0161*/ invokerSize = 3; /* Size of the bytecode */
/*0162*/
/*0163*/ callMethod_general: {
/*0164*/ int res;
/*0167*/
/*0168*/ /* Check if the method is a native method */
/*0169*/ if (thisMethod->accessFlags & ACC_NATIVE) {
/*0170*/ ip += invokerSize;
/*0171*/ invokeNativeFunction(thisMethod);
/*0172*/
/*0175*/ goto reschedulePoint;
/*0176*/ }
/*0177*/
/*0178*/ if (thisMethod->accessFlags & ACC_ABSTRACT) {
/*0179*/ fatalError(KVM_MSG_ABSTRACT_METHOD_INVOKED);
/*0180*/ }
/*0181*/
/*0182*/ /* Create an execution frame for executing a Java method */
/*0183*/ thisObjectGCSafe = thisObject;
/*0184*/ res = pushFrame(thisMethod);
/*0185*/ if (res) {
/*0186*/ fp->previousIp += invokerSize;
/*0187*/ }
/*0188*/ if (res) {
/*0189*/ if (thisMethod->accessFlags & ACC_SYNCHRONIZED) {
/*0190*/ monitorEnter(thisObjectGCSafe);
/*0191*/ fp->syncObject = thisObjectGCSafe;
/*0192*/ }
/*0193*/ }
/*0194*/ thisObjectGCSafe = NULL;
/*0195*/ goto reschedulePoint;
/*0196*/ }
/*0197*/
/*0198*/ handleNullPointerException: {
/*0199*/ raiseException(NullPointerException);
/*0200*/ goto reschedulePoint;
/*0201*/ }
/*0202*/
/*0203*/ handleClassCastException: {
/*0204*/ raiseException(ClassCastException);
/*0205*/ goto reschedulePoint;
/*0206*/ }
/*0207*/
/*0208*/ default: {
/*0209*/ sprintf(str_buffer, KVM_MSG_ILLEGAL_BYTECODE_1LONGPARAM,
/*0210*/ (long)token);
/*0211*/ fatalError(str_buffer);
/*0212*/ break;
/*0213*/ }
/*0214*/
/*0215*/ }
/*0216*/
/*0217*/#if PADTABLE
/*0218*/ notImplemented:
/*0219*/#endif
/*0220*/
/*0221*/ fatalError(KVM_MSG_SLOWINTERPRETER_STOPPED);
/*0222*/
/*0223*/next3: ip+=3;
/*0224*/next0:
/*0225*/reschedulePoint:
/*0226*/ return;
/*0227*/}
/*0228*/
/*0229*//*=========================================================================
/*0230./ * Undefine the macros we needed just for this function
/*0231./ *=======================================================================*/
/*0232*/
/*0233*/#undef VMSAVE
/*0234*/#undef VMRESTORE
/*0235*/#undef TOKEN
/*0236*/
/*0237*/#endif /* SPLITINFREQUENTBYTECODES */
/*0238*/
/*0239*//*************************************************************************
/*0240./ * End of infrequent bytecodes option *
/*0241./ *************************************************************************/
/*0242*/
/*0243*//*************************************************************************
/*0244./ * Start of regular bytecodes processing *
/*0245./ *************************************************************************/
/*0246*/
/*0247*//*=========================================================================
/*0248./ * VMSAVE - Save the VM state
/*0249./ *=======================================================================*/
/*0250*/
/*0251*/#define VMSAVE { \
/*0252*/ SAVEIP \
/*0253*/ SAVEFP \
/*0254*/ SAVESP \
/*0255*/ SAVELP \
/*0256*/ SAVECP \
/*0257*/}
/*0258*/
/*0259*//*=========================================================================
/*0260./ * VMRESTORE - Restore the VM state
/*0261./ *=======================================================================*/
/*0262*/
/*0263*/#define VMRESTORE { \
/*0264*/ RESTOREIP \
/*0265*/ RESTOREFP \
/*0266*/ RESTORESP \
/*0267*/ RESTORELP \
/*0268*/ RESTORECP \
/*0269*/}
/*0270*/
/*0271*//*=========================================================================
/*0272./ * TOKEN - Macro to get the current bytecode
/*0273./ *=======================================================================*/
/*0278*/ #define TOKEN (*ip)
/*0280*/
/*0281*//*=========================================================================
/*0282./ * FUNCTION: Interpret()
/*0283./ * TYPE: Instrumentation version of Interpret()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -