⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 interpreter.c

📁 专业汽车级嵌入式操作系统OSEK的源代码
💻 C
字号:
#include "trace.h"#include "types.h"#include "constants.h"#include "classes.h"#include "interpreter.h"#include "platform_hooks.h"#include "threads.h"#include "opcodes.h"#include "configure.h"#include "memory.h"#include "language.h"#include "exceptions.h"#include "specialclasses.h"#include "fields.h"#include "stack.h"#include "poll.h"#define F_OFFSET_MASK  0x0F#if DEBUG_BYTECODEextern char *OPCODE_NAME[];#endif// Interpreter globals:volatile boolean gMakeRequest;byte    gRequestCode;byte *pc;STACKWORD *localsBase;STACKWORD *stackTop;// Temporary globals:byte tempByte;byte *tempBytePtr;JFLOAT tempFloat;ConstantRecord *tempConstRec;STACKWORD tempStackWord;STACKWORD *tempWordPtr;JSHORT tempInt;  /** * Assumes pc points to 2-byte offset, and jumps. */void do_goto (boolean aCond){  if (aCond)  {    pc += (JSHORT) (((TWOBYTES) *pc << 8) | *(pc+1));    pc--;  }  else  {    pc += 2;  }}void do_isub (void){  STACKWORD poppedWord;  poppedWord = pop_word();  set_top_word (word2jint(get_top_word()) - word2jint(poppedWord));}#if FP_ARITHMETICvoid do_fcmp (JFLOAT f1, JFLOAT f2, STACKWORD def){  if (f1 > f2)    push_word (1);  else if (f1 == f2)    push_word (0);  else if (f1 < f2)    push_word (-1);  else     push_word (def);}#endif/** * @return A String instance, or JNULL if an exception was thrown *         or the static initializer of String had to be executed. */static inline Object *create_string (ConstantRecord *constantRecord,                                      byte *btAddr){  Object *ref;  Object *arr;  TWOBYTES i;  ref = new_object_checked (JAVA_LANG_STRING, btAddr);  if (ref == JNULL)    return JNULL;  arr = new_primitive_array (T_CHAR, constantRecord->constantSize);  if (arr == JNULL)  {    deallocate (obj2ptr(ref), class_size (JAVA_LANG_STRING));        return JNULL;  }  //  printf ("char array at %d\n", (int) arr);    store_word ((byte *) &(((String *) ref)->characters), 4, obj2word(arr));    for (i = 0; i < constantRecord->constantSize; i++)  {    jchar_array(arr)[i] = (JCHAR) get_constant_ptr(constantRecord)[i];    //printf ("char %d: %c\n", i, (char) (jchar_array(arr)[i]));   }  return ref;}/** * Pops the array index off the stack, assigns * both tempInt and tempBytePtr, and checks * bounds and null reference. The array reference * is the top word on the stack after this operation. * @return True if successful, false if an exception has been scheduled. */boolean array_load_helper(){  tempInt = word2jshort(pop_word());  tempBytePtr = word2ptr(get_top_ref());  if (tempBytePtr == JNULL)    throw_exception (nullPointerException);  else if (tempInt < 0 || tempInt >= get_array_length ((Object *) tempBytePtr))    throw_exception (arrayIndexOutOfBoundsException);  else    return true;  return false;}/** * Same as array_load_helper, except that it pops * the reference from the stack. */boolean array_store_helper(){  if (array_load_helper())  {    pop_ref();    return true;  }  return false;}/** * Everything runs inside here, essentially. * * To be able use only a single fast test on each instruction * several assumptions are made: * - currentThread is initialized and non-null and *   it is not set to null by any bytecode instruction. * - Thus it is not allowed to call schedule_thread() in instructions, *   use schedule_request( REQUEST_SWITCH_THREAD) instead. * - Whenever gMakeRequest is false, gRequestCode is REQUEST_TICK. * - Thus anybody who sets gRequestCode must also set gMakeRequest to true *   (using schedule_request assures this). * - Only the request handler may set gMakeRequest to false. * - The millisecond timer interrupt must set gMakeRequest to true *   for time slices to work. *  */void engine(){  byte ticks_until_switch = TICKS_PER_TIME_SLICE;  int lgginst = 0;  assert( currentThread != null, INTERPRETER0);  schedule_request( REQUEST_SWITCH_THREAD); LABEL_ENGINELOOP:   instruction_hook();  assert( currentThread != null, INTERPRETER1);  while( gMakeRequest)  {    byte requestCode = gRequestCode;    gMakeRequest = false;    gRequestCode = REQUEST_TICK;        tick_hook();    if( requestCode == REQUEST_EXIT)    {      return;    }    if( requestCode == REQUEST_TICK)      ticks_until_switch--;    if( requestCode == REQUEST_SWITCH_THREAD        || ticks_until_switch == 0){      ticks_until_switch = TICKS_PER_TIME_SLICE;#if DEBUG_THREADS      printf ("switching thread: %d\n", (int)ticks_until_switch);#endif      switch_thread();#if DEBUG_THREADS      printf ("done switching thread\n");#endif      switch_thread_hook();    }    if( currentThread == null   /* no runnable thread */        && gRequestCode == REQUEST_TICK){ /* no important request */      idle_hook();      schedule_request( REQUEST_SWITCH_THREAD);    }  }  assert( gRequestCode == REQUEST_TICK, INTERPRETER2);  assert( currentThread != null, INTERPRETER3);  //-----------------------------------------------  // SWITCH BEGINS HERE  //-----------------------------------------------  #if DEBUG_BYTECODE  printf ("0x%X: \n", (int) pc);  printf ("OPCODE (0x%X) %s\n", (int) *pc, OPCODE_NAME[*pc]);  #endif  switch (*pc++)  {    case OP_NOP:        goto LABEL_ENGINELOOP;    #include "op_stack.hc"    #include "op_locals.hc"    #include "op_arrays.hc"    #include "op_objects.hc"    #include "op_control.hc"    #include "op_other.hc"    #include "op_conversions.hc"    #include "op_logical.hc"    #include "op_arithmetic.hc"    #include "op_methods.hc"/*#ifdef VERIFY	default:		assert(false, (TWOBYTES)(pc-1) % 10000);		break;#endif*/  }  //-----------------------------------------------  // SWITCH ENDS HERE  //-----------------------------------------------   #if !FP_ARITHMETIC   throw_exception (noSuchMethodError);   #else     // This point should never be reached   #ifdef VERIFY   assert (false, 1000 + *pc);   #endif // VERIFY   #endif // FP_ARITHMETIC}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -