OSDN Git Service

lejos_NXJ_win32_0_5_0beta.zip
[nxt-jsp/lejos_nxj.git] / nxtOSEK / lejos_nxj / src / nxtvm / platform / unix / tvmemul.c
1 /**
2  * tvmemul.c
3  * Entry source file for TinyVM emulator.
4  */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <sys/time.h>
9 #include <signal.h>
10 #include "types.h"
11 #include "constants.h"
12 #include "classes.h"
13 #include "threads.h"
14 #include "stack.h"
15 #include "specialclasses.h"
16 #include "specialsignatures.h"
17 #include "language.h"
18 #include "memory.h"
19 #include "interpreter.h"
20 #include "exceptions.h"
21 #include "load.h"
22 #include "trace.h"
23 #include "poll.h"
24 #include "sensors.h"
25 #include "platform_hooks.h"
26
27 #define MEMORY_SIZE 8192 /* 16 Kb */
28 #define EXTRA_MEMORY_SIZE 1536 /* 3 Kb */
29 #define DEBUG_RUNS  0
30
31 byte *region;
32 Thread   *bootThread;
33 struct timeval gStart;
34 struct itimerval itimer =
35 {
36   {0, 1000},
37   {0, 1000}
38 };
39
40 int     verbose = 0;    /* If 1, print descriptive strings. */
41
42 int last_sys_time;              /* to generate ticks */
43 int last_ad_time;               /* to generate sensor reads */
44
45 void handle_uncaught_exception (Object *exception,
46                                        const Thread *thread,
47                                        const MethodRecord *methodRecord,
48                                        const MethodRecord *rootMethod,
49                                        byte *pc)
50 {
51     printf ("*** UNCAUGHT EXCEPTION/ERROR: \n");
52     printf ("--  Exception class   : %u\n", (unsigned) get_class_index (exception));
53     printf ("--  Thread            : %u\n", (unsigned) thread->threadId);
54     printf ("--  Method signature  : %u\n", (unsigned) methodRecord->signatureId);
55     printf ("--  Root method sig.  : %u\n", (unsigned) rootMethod->signatureId);
56     printf ("--  Bytecode offset   : %u\n", (unsigned) pc - 
57             (int) get_code_ptr(methodRecord));                                                 
58 }
59
60 void switch_thread_hook()
61 {
62   // NOP
63 }
64
65 FOURBYTES sys_time = 0;
66 struct timeval now;
67
68 void timer_handler(int signo)
69 {
70   gettimeofday(&now, 0);
71   // 11/17/01: Jose commented out:
72   // 03/29/02: Paul put back in. Regression tests will fail otherwise.
73   timersub(&now, &gStart, &now);
74   sys_time = now.tv_sec*1000 + now.tv_usec/1000;
75   signal(SIGALRM, timer_handler);
76 }
77
78 FOURBYTES get_sys_time_impl()
79 {
80   return sys_time;
81 }
82
83 void run(void)
84 {
85   #if DEBUG_RUNS
86   int count = 0;
87   #endif
88
89   init_poller();
90
91 #if EXECUTE_FROM_FLASH
92   {
93     MasterRecord *mrec = get_master_record();
94     int staticSize = mrec->staticStateLength;
95     int statusSize = (mrec->lastClass + 1) * sizeof( classStatusBase[0]);
96
97     staticSize = (staticSize + 1) & ~(1);
98     statusSize = (statusSize + 3) & ~(3);
99
100     classStaticStateBase = malloc( staticSize * 2);
101     classStatusBase = malloc( statusSize);
102
103     memset( classStatusBase, 0, statusSize);
104   }
105 #endif
106
107   // Initialize binary image state
108   initialize_binary();
109
110   // Initialize memory
111   {
112     TWOBYTES size;
113
114     memory_init ();
115 #if SEGMENTED_HEAP
116     size = EXTRA_MEMORY_SIZE;
117     region = (byte *) malloc (size * sizeof (TWOBYTES));
118     memory_add_region (region, region + size * sizeof (TWOBYTES));
119 #endif
120     size = MEMORY_SIZE;
121     region = (byte *) malloc (size * sizeof (TWOBYTES));
122     memory_add_region (region, region + size * sizeof (TWOBYTES));
123   }
124
125   // Initialize exceptions
126   init_exceptions();
127   // Create the boot thread (bootThread is a special global)
128   bootThread = (Thread *) new_object_for_class (JAVA_LANG_THREAD);
129   
130   #if DEBUG_THREADS
131   printf ("Created bootThread: %d. Initializing...\n", (int) bootThread);
132   #endif
133   
134   #if DEBUG_RUNS
135   for (count = 0; count < 100; count++)
136   {
137   #endif // DEBUG_RUNS
138
139   #if DEBUG_RCX_MEMORY
140   {
141     TWOBYTES numNodes, biggest, freeMem;        
142     scan_memory (&numNodes, &biggest, &freeMem);
143     printf ("nodes = %d\n", (int) numNodes);
144     printf ("biggest = %d\n", (int) biggest);
145     printf ("freeMem = %d\n", (int) freeMem);
146   }
147   #endif
148
149   init_threads();
150   if (!init_thread (bootThread))
151   {
152     printf ("Unable to initialize threading module.\n");
153     exit (1);     
154   }
155   // Execute the bytecode interpreter
156   set_program_number (0);
157   #if DEBUG_STARTUP
158   printf ("Engine starting.\n");
159   #endif
160   engine();
161   // Engine returns when all non-daemon threads are dead
162   #if DEBUG_STARTUP
163   printf ("Engine finished.\n");
164   #endif
165
166   #if DEBUG_RUNS
167   }
168   #endif // DEBUG_RUNS
169 }
170
171 /***************************************************************************
172  * int main
173  * Parses command line. Format is:
174  *      argv[0] [-v] bin_file
175  *
176  * options:
177  *      -v      Verbose mode. Prints text output rather than raw output.
178  *
179  *--------------------------------------------------------------------------
180  * To go into man page:
181  * Name:        emu-lejosrun - Emulate lejos RCX code in Unix
182  *
183  * Synosis:     emu-lejosrun [-v] bin_file
184  *
185  * Description: Executes a binary file created by the lejos compiler within
186  *              Unix rather than in the RCX environment. The Java byte-codes
187  *              are executed here, and their actions are listed rather than
188  *              executed as they would be on the real RCX device.
189  *
190  * Options:     -v      Verbose mode. Normally the output is printed in raw
191  *                      mode. The actual hex values are printed. Using this
192  *                      option displays more user-friendly output.
193  *--------------------------------------------------------------------------
194  ***************************************************************************/
195 int main (int argc, char *argv[])
196 {
197         int     c;
198         char    *file = argv[argc - 1];
199
200         /* Process any options. */
201         while(--argc > 0 && (*++argv)[0] == '-')
202                 while((c = *++argv[0]) != 0)
203                         switch (c) {
204                         case 'v':
205                                 verbose = 1;
206                                 break;
207                         default:
208                                 printf("%s: unknown option %c\n",
209                                         argv[0], c);
210                                 exit(1);
211                         }
212         if (argc != 1)
213         {
214                 printf ("%s runs a binary dumped by the linker.\n", argv[0]);
215                 printf ("Use: %s [-v] binary_file\n", argv[0]);
216                 exit (1);
217         }
218 #if DEBUG_STARTUP
219         printf ("Reading binary %s\n", file);
220 #endif
221         readBinary (file);
222         if (gettimeofday(&gStart, NULL)) 
223                 perror("main: gettimeofday");
224         timer_handler (SIGALRM);
225         if (setitimer(ITIMER_REAL, &itimer, null) < 0)
226         {
227           printf ("Failed to set interval timer\n");
228           exit(1);
229         }
230
231         init_sensors ();
232         last_ad_time = get_sys_time();
233
234         run();
235         itimer.it_value.tv_usec = 0;
236         setitimer(ITIMER_REAL, &itimer, null);
237         signal(SIGALRM, SIG_DFL);
238         exit(0);
239