📄 language.c
字号:
/** * Runtime data structures for loaded program. */#include "types.h"#include "trace.h"#include "constants.h"#include "specialsignatures.h"#include "specialclasses.h"#include "memory.h"#include "threads.h"#include "classes.h"#include "language.h"#include "configure.h"#include "interpreter.h"#include "exceptions.h"#include "stack.h"#include "platform_hooks.h"#if 0#define get_stack_object(MREC_) ((Object *) get_ref_at ((MREC_)->numParameters - 1))#endif// Reliable globals:void *installedBinary;// Temporary globals:// (Gotta be careful with these; a lot of stuff// is not reentrant because of globals like these).static ClassRecord *tempClassRecord;static MethodRecord *tempMethodRecord;// Methods:byte get_class_index (Object *obj){ byte f; f = obj->flags.all; if (f & IS_ARRAY_MASK) return JAVA_LANG_OBJECT; return (f & CLASS_MASK);}/** * @return Method record or null. */MethodRecord *find_method (ClassRecord *classRecord, TWOBYTES methodSignature){ tempByte = classRecord->numMethods; while (tempByte--) { tempMethodRecord = get_method_record (classRecord, tempByte); if (tempMethodRecord->signatureId == methodSignature) return tempMethodRecord; } return null;}boolean dispatch_static_initializer (ClassRecord *aRec, byte *retAddr){ if (is_initialized (aRec)) return false; set_initialized (aRec); if (!has_clinit (aRec)) return false; #if DEBUG_METHODS printf ("dispatch_static_initializer: has clinit: %d, %d\n", (int) aRec, (int) retAddr); #endif dispatch_special (find_method (aRec, _6clinit_7_4_5V), retAddr); return true;}void dispatch_virtual (Object *ref, TWOBYTES signature, byte *retAddr){ MethodRecord *auxMethodRecord; byte auxByte;#if DEBUG_METHODS printf("dispatch_virtual %d\n", signature);#endif if (ref == JNULL) { throw_exception (nullPointerException); return; } auxByte = get_class_index(ref); LABEL_METHODLOOKUP: tempClassRecord = get_class_record (auxByte); auxMethodRecord = find_method (tempClassRecord, signature); if (auxMethodRecord == null) { #if SAFE if (auxByte == JAVA_LANG_OBJECT) { throw_exception (noSuchMethodError); return; } #endif auxByte = tempClassRecord->parentClass; goto LABEL_METHODLOOKUP; } if (dispatch_special (auxMethodRecord, retAddr)) { if (is_synchronized(auxMethodRecord)) { current_stackframe()->monitor = ref; enter_monitor (currentThread, ref); } }}/** * Calls static initializer if necessary before * dispatching with dispatch_special(). * @param retAddr Return bytecode address. * @param btAddr Backtrack bytecode address (in case * static initializer is executed). */void dispatch_special_checked (byte classIndex, byte methodIndex, byte *retAddr, byte *btAddr){ ClassRecord *classRecord; #if DEBUG_METHODS printf ("dispatch_special_checked: %d, %d, %d, %d\n", classIndex, methodIndex, (int) retAddr, (int) btAddr); #endif classRecord = get_class_record (classIndex); if (dispatch_static_initializer (classRecord, btAddr)) return; dispatch_special (get_method_record (classRecord, methodIndex), retAddr);}/** * @param classRecord Record for method class. * @param methodRecord Calle's method record. * @param retAddr What the PC should be upon return. * @return true iff the stack frame was pushed. */boolean dispatch_special (MethodRecord *methodRecord, byte *retAddr){ #if DEBUG_METHODS int debug_ctr; #endif StackFrame *stackFrame; byte newStackFrameIndex; #if DEBUG_BYTECODE printf ("\n------ dispatch special - %d ------------------\n\n", methodRecord->signatureId); #endif #if DEBUG_METHODS printf ("dispatch_special: %d, %d\n", (int) methodRecord, (int) retAddr); printf ("-- signature id = %d\n", methodRecord->signatureId); printf ("-- code offset = %d\n", methodRecord->codeOffset); printf ("-- flags = %d\n", methodRecord->mflags); printf ("-- num params = %d\n", methodRecord->numParameters); printf ("-- stack ptr = %d\n", (int) get_stack_ptr()); printf ("-- max stack ptr= %d\n", (int) (currentThread->stackArray + (get_array_size(currentThread->stackArray))*2)); #endif pop_words (methodRecord->numParameters); pc = retAddr; if (is_native (methodRecord)) { #if DEBUG_METHODS printf ("-- native\n"); #endif dispatch_native (methodRecord->signatureId, get_stack_ptr() + 1); // Stack frame not pushed return false; } newStackFrameIndex = currentThread->stackFrameArraySize; if (newStackFrameIndex >= get_array_length((Object *) word2ptr (currentThread->stackFrameArray))) {#if !FIXED_STACK_SIZE // int len = get_array_length((Object *) word2ptr (currentThread->stackFrameArray)); int newlen = get_array_length((Object *) word2ptr (currentThread->stackFrameArray)) * 3 / 2; JINT newStackFrameArray = JNULL; // Stack frames are indexed by a byte value so limit the size. if (newlen <= 255) { // increase the stack frame size newStackFrameArray = ptr2word(reallocate_array(word2ptr(currentThread->stackFrameArray), newlen)); } // If can't allocate new stack, give in! if (newStackFrameArray == JNULL) {#endif throw_exception (stackOverflowError); return false;#if !FIXED_STACK_SIZE } // Assign new array currentThread->stackFrameArray = newStackFrameArray;#endif } if (newStackFrameIndex == 0) { // Assign NEW stack frame stackFrame = stackframe_array(); } else { #if DEBUG_METHODS for (debug_ctr = 0; debug_ctr < methodRecord->numParameters; debug_ctr++) printf ("-- param[%d] = %ld\n", debug_ctr, (long) get_stack_ptr()[debug_ctr+1]); #endif // Save OLD stackFrame state stackFrame = stackframe_array() + (newStackFrameIndex - 1); update_stack_frame (stackFrame); // Push NEW stack frame stackFrame++; } // Increment size of stack frame array currentThread->stackFrameArraySize++; // Initialize rest of new stack frame stackFrame->methodRecord = methodRecord; stackFrame->monitor = null; stackFrame->localsBase = get_stack_ptr() + 1; // Initialize auxiliary global variables (registers) pc = get_code_ptr(methodRecord); #if DEBUG_METHODS printf ("pc set to 0x%X\n", (int) pc); #endif init_sp (stackFrame, methodRecord); update_constant_registers (stackFrame); //printf ("m %d stack = %d\n", (int) methodRecord->signatureId, (int) (localsBase - stack_array())); // Check for stack overflow // (stackTop + methodRecord->maxOperands) >= (stack_array() + STACK_SIZE); if (is_stack_overflow (methodRecord)) {#if !FIXED_STACK_SIZE StackFrame *stackBase; int i; // Need at least this many bytes // int len = (int)(stackTop + methodRecord->maxOperands) - (int)(stack_array()) - HEADER_SIZE; // Need to compute new array size (as distinct from number of bytes in array). int newlen = (((int)(stackTop + methodRecord->maxOperands) - (int)(stack_array()) - HEADER_SIZE + 1) / 4) * 3 / 2; JINT newStackArray = ptr2word(reallocate_array(word2ptr(currentThread->stackArray), newlen)); // If can't allocate new stack, give in! if (newStackArray == JNULL) {#endif throw_exception (stackOverflowError); return false;#if !FIXED_STACK_SIZE } // Adjust pointers. newlen = newStackArray - currentThread->stackArray; stackBase = stackframe_array(); stackTop = word2ptr(ptr2word(stackTop) + newlen); localsBase = word2ptr(ptr2word(localsBase) + newlen);#if DEBUG_MEMORY printf("thread=%d, stackTop(%d), localsBase(%d)=%d\n", currentThread->threadId, (int)stackTop, (int)localsBase, (int)(*localsBase));#endif for (i=currentThread->stackFrameArraySize-1; i >= 0; i--) { stackBase[i].localsBase = word2ptr(ptr2word(stackBase[i].localsBase) + newlen); stackBase[i].stackTop = word2ptr(ptr2word(stackBase[i].stackTop) + newlen);#if DEBUG_MEMORY printf("stackBase[%d].localsBase(%d) = %d\n", i, (int)stackBase[i].localsBase, (int)(*stackBase[i].localsBase));#endif } // Assign new array currentThread->stackArray = newStackArray;#endif } return true;}/** */void do_return (byte numWords){ StackFrame *stackFrame; STACKWORD *fromStackPtr; stackFrame = current_stackframe(); #if DEBUG_BYTECODE printf ("\n------ return ----- %d ------------------\n\n", stackFrame->methodRecord->signatureId); #endif #if DEBUG_METHODS printf ("do_return: method: %d # num. words: %d\n", stackFrame->methodRecord->signatureId, numWords); #endif #ifdef VERIFY assert (stackFrame != null, LANGUAGE3); #endif if (stackFrame->monitor != null) exit_monitor (currentThread, stackFrame->monitor); #if DEBUG_THREADS || DEBUG_METHODS printf ("do_return: stack frame array size: %d\n", currentThread->stackFrameArraySize); #endif if (currentThread->stackFrameArraySize == 1) { #if DEBUG_METHODS printf ("do_return: thread is done: %d\n", (int) currentThread); #endif currentThread->state = DEAD; schedule_request (REQUEST_SWITCH_THREAD); return; } // Place source ptr below data to be copied up the stack fromStackPtr = get_stack_ptr_at (numWords); // Pop stack frame currentThread->stackFrameArraySize--; stackFrame--; // Assign registers update_registers (stackFrame); #if DEBUG_METHODS printf ("do_return: stack reset to:\n"); printf ("-- stack ptr = %d\n", (int) get_stack_ptr()); #endif while (numWords--) { push_word (*(++fromStackPtr)); } }/** * @return 1 or 0. */STACKWORD instance_of (Object *obj, byte classIndex){ byte rtType; if (obj == null) return 0; rtType = get_class_index(obj); // TBD: support for interfaces if (is_interface (get_class_record(classIndex))) return 1; LABEL_INSTANCE: if (rtType == classIndex) return 1; if (rtType == JAVA_LANG_OBJECT) return 0; rtType = get_class_record(rtType)->parentClass; goto LABEL_INSTANCE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -