6 #include "interpreter.h"
7 #include "platform_hooks.h"
10 #include "configure.h"
13 #include "exceptions.h"
14 #include "specialclasses.h"
20 #define F_OFFSET_MASK 0x0F
23 extern char *OPCODE_NAME[];
26 // Interpreter globals:
28 volatile boolean gMakeRequest;
30 unsigned int gNextProgram;
31 unsigned int gNextProgramSize;
34 STACKWORD *localsBase;
42 ConstantRecord *tempConstRec;
43 STACKWORD tempStackWord;
44 STACKWORD *tempWordPtr;
48 * Assumes pc points to 2-byte offset, and jumps.
50 void do_goto (boolean aCond)
54 pc += (JSHORT) (((TWOBYTES) *pc << 8) | *(pc+1));
67 poppedWord = pop_word();
68 set_top_word (word2jint(get_top_word()) - word2jint(poppedWord));
73 void do_fcmp (JFLOAT f1, JFLOAT f2, STACKWORD def)
88 * @return A String instance, or JNULL if an exception was thrown
89 * or the static initializer of String had to be executed.
91 static inline Object *create_string (ConstantRecord *constantRecord,
98 ref = new_object_checked (JAVA_LANG_STRING, btAddr);
101 arr = new_primitive_array (T_CHAR, constantRecord->constantSize);
104 deallocate (obj2ptr(ref), class_size (JAVA_LANG_STRING));
108 // printf ("char array at %d\n", (int) arr);
110 store_word ((byte *) &(((String *) ref)->characters), 4, obj2word(arr));
112 for (i = 0; i < constantRecord->constantSize; i++)
114 jchar_array(arr)[i] = (JCHAR) get_constant_ptr(constantRecord)[i];
116 //printf ("char %d: %c\n", i, (char) (jchar_array(arr)[i]));
122 * Pops the array index off the stack, assigns
123 * both tempInt and tempBytePtr, and checks
124 * bounds and null reference. The array reference
125 * is the top word on the stack after this operation.
126 * @return True if successful, false if an exception has been scheduled.
128 boolean array_load_helper()
130 tempInt = word2jshort(pop_word());
131 tempBytePtr = word2ptr(get_top_ref());
132 if (tempBytePtr == JNULL)
133 throw_exception (nullPointerException);
134 else if (tempInt < 0 || tempInt >= get_array_length ((Object *) tempBytePtr))
135 throw_exception (arrayIndexOutOfBoundsException);
142 * Same as array_load_helper, except that it pops
143 * the reference from the stack.
145 boolean array_store_helper()
147 if (array_load_helper())
156 * Everything runs inside here, essentially.
158 * To be able use only a single fast test on each instruction
159 * several assumptions are made:
160 * - currentThread is initialized and non-null and
161 * it is not set to null by any bytecode instruction.
162 * - Thus it is not allowed to call schedule_thread() in instructions,
163 * use schedule_request( REQUEST_SWITCH_THREAD) instead.
164 * - Whenever gMakeRequest is false, gRequestCode is REQUEST_TICK.
165 * - Thus anybody who sets gRequestCode must also set gMakeRequest to true
166 * (using schedule_request assures this).
167 * - Only the request handler may set gMakeRequest to false.
168 * - The millisecond timer interrupt must set gMakeRequest to true
169 * for time slices to work.
174 byte ticks_until_switch = TICKS_PER_TIME_SLICE;
176 assert( currentThread != null, INTERPRETER0);
178 schedule_request( REQUEST_SWITCH_THREAD);
183 assert( currentThread != null, INTERPRETER1);
187 byte requestCode = gRequestCode;
189 gMakeRequest = false;
190 gRequestCode = REQUEST_TICK;
194 if( requestCode == REQUEST_EXIT)
199 if( requestCode == REQUEST_TICK)
200 ticks_until_switch--;
202 if( requestCode == REQUEST_SWITCH_THREAD
203 || ticks_until_switch == 0){
204 ticks_until_switch = TICKS_PER_TIME_SLICE;
206 printf ("switching thread: %d\n", (int)ticks_until_switch);
210 printf ("done switching thread\n");
212 switch_thread_hook();
214 if( currentThread == null /* no runnable thread */
215 && gRequestCode == REQUEST_TICK){ /* no important request */
217 schedule_request( REQUEST_SWITCH_THREAD);
221 assert( gRequestCode == REQUEST_TICK, INTERPRETER2);
222 assert( currentThread != null, INTERPRETER3);
224 //-----------------------------------------------
225 // SWITCH BEGINS HERE
226 //-----------------------------------------------
229 printf ("0x%X: \n", (int) pc);
230 printf ("OPCODE (0x%X) %s\n", (int) *pc, OPCODE_NAME[*pc]);
236 goto LABEL_ENGINELOOP;
238 #include "op_stack.hc"
239 #include "op_locals.hc"
240 #include "op_arrays.hc"
241 #include "op_objects.hc"
242 #include "op_control.hc"
243 #include "op_other.hc"
244 #include "op_conversions.hc"
245 #include "op_logical.hc"
246 #include "op_arithmetic.hc"
247 #include "op_methods.hc"
252 assert(false, (TWOBYTES)(pc-1) % 10000);
258 //-----------------------------------------------
260 //-----------------------------------------------
264 throw_exception (noSuchMethodError);
268 // This point should never be reached
271 assert (false, 1000 + *pc);
274 #endif // FP_ARITHMETIC