View Javadoc

1   // SystemInterface.java, created Mon Feb  5 23:23:21 2001 by joewhaley
2   // Copyright (C) 2001-3 John Whaley <jwhaley@alum.mit.edu>
3   // Licensed under the terms of the GNU LGPL; see COPYING for details.
4   package joeq.Runtime;
5   
6   import java.util.Collection;
7   import java.util.Iterator;
8   import java.util.LinkedList;
9   import joeq.Class.PrimordialClassLoader;
10  import joeq.Class.jq_Class;
11  import joeq.Class.jq_InstanceField;
12  import joeq.Class.jq_StaticField;
13  import joeq.Main.jq;
14  import joeq.Memory.Address;
15  import joeq.Memory.CodeAddress;
16  import joeq.Memory.HeapAddress;
17  import joeq.Memory.StackAddress;
18  import joeq.Scheduler.jq_RegisterState;
19  import joeq.Scheduler.jq_Thread;
20  import joeq.UTF.Utf8;
21  import jwutil.util.Assert;
22  
23  /***
24   * @author  John Whaley <jwhaley@alum.mit.edu>
25   * @version $Id: SystemInterface.java 1941 2004-09-30 03:37:06Z joewhaley $
26   */
27  public abstract class SystemInterface {
28  
29      public static class ExternalLink {
30          private final String name;
31          private Library library;
32          private CodeAddress address;
33          
34          public ExternalLink(String name) {
35              this.name = name;
36              this.library = null;
37              this.address = CodeAddress.getNull();
38          }
39          
40          public CodeAddress resolve() {
41              if (!address.isNull())
42                  return address;
43              synchronized (libraries) {
44                  for (Iterator/*<Library>*/ i=libraries.iterator(); i.hasNext(); ) {
45                      Library lib = (Library) i.next();
46                      address = lib.getProcAddress(name);
47                      if (!address.isNull()) {
48                          library = lib;
49                          lib.registerLink(this);
50                          return address;
51                      }
52                  }
53              }
54              Debug.write("Error: cannot resolve external procedure ");
55              Debug.writeln(name);
56              return CodeAddress.getNull();
57          }
58          
59          public CodeAddress resolve(Library lib) {
60              if (!address.isNull())
61                  return address;
62              address = lib.getProcAddress(name);
63              if (!address.isNull()) {
64                  library = lib;
65                  lib.registerLink(this);
66              }
67              return address;
68          }
69          
70          public void unlink() {
71              if (this.library != null) {
72                  this.library.unlink(this);
73              }
74              this._unlink();
75          }
76          
77          void _unlink() {
78              this.library = null;
79              this.address = CodeAddress.getNull();
80          }
81          
82      }
83  
84      public static class Library {
85          private final String name;
86          private int/*CPointer*/ library_pointer;
87          private boolean opened;
88          private final Collection externals;
89          
90          public Library(String name) {
91              this.name = name;
92              this.opened = false;
93              this.externals = new LinkedList();
94          }
95          
96          public String getName() { return name; }
97          
98          public synchronized boolean open() {
99              if (opened) return true;
100             library_pointer = open_library(toCString(name));
101             if (library_pointer == 0) return false;
102             opened = true; return true;
103         }
104         
105         public CodeAddress getProcAddress(String procName) {
106             if (!opened) open();
107             CodeAddress x = get_proc_address(library_pointer, toCString(procName));
108             //Debug.write(name);
109             //Debug.write(" procedure ");
110             //Debug.write(procName);
111             //Debug.writeln(" = ", x);
112             return x;
113         }
114         
115         public ExternalLink resolve(String procname) {
116             ExternalLink x = new ExternalLink(procname);
117             CodeAddress c = x.resolve(this);
118             if (!c.isNull()) return x;
119             else return null;
120         }
121         
122         public synchronized void registerLink(ExternalLink e) {
123             externals.add(e);
124         }
125         
126         public synchronized void unlink(ExternalLink e) {
127             externals.remove(e);
128         }
129         
130         public synchronized void close() {
131             for (Iterator i=externals.iterator(); i.hasNext(); ) {
132                 ExternalLink x = (ExternalLink) i.next();
133                 x._unlink();
134                 i.remove();
135             }
136             if (opened) {
137                 close_library(library_pointer);
138                 opened = false;
139             }
140         }
141         
142         protected void finalize() throws Throwable {
143             super.finalize();
144             close();
145         }
146 
147     }
148     
149     public static CodeAddress open_library_4;
150     public static CodeAddress get_proc_address_8;
151     public static CodeAddress close_library_4;
152     
153     public static int/*CPointer*/ open_library(byte[] library_name) {
154         Unsafe.pushArgA(HeapAddress.addressOf(library_name));
155         try {
156             Unsafe.getThreadBlock().disableThreadSwitch();
157             int v = (int) Unsafe.invoke(open_library_4);
158             Unsafe.getThreadBlock().enableThreadSwitch();
159             return v;
160         } catch (Throwable t) { Assert.UNREACHABLE(); return 0; }
161     }
162 
163     public static void close_library(int/*CPointer*/ library) {
164         Unsafe.pushArg(library);
165         try {
166             Unsafe.getThreadBlock().disableThreadSwitch();
167             Unsafe.invoke(close_library_4);
168             Unsafe.getThreadBlock().enableThreadSwitch();
169         } catch (Throwable t) { Assert.UNREACHABLE(); }
170     }
171 
172     public static CodeAddress get_proc_address(int/*CPointer*/ library, byte[] name) {
173         Unsafe.pushArgA(HeapAddress.addressOf(name));
174         Unsafe.pushArg(library);
175         try {
176             Unsafe.getThreadBlock().disableThreadSwitch();
177             CodeAddress v = (CodeAddress) Unsafe.invokeA(get_proc_address_8);
178             Unsafe.getThreadBlock().enableThreadSwitch();
179             return v;
180         } catch (Throwable t) { Assert.UNREACHABLE(); return null; }
181     }
182     
183     public static final Collection/*<Library>*/ libraries = new LinkedList();
184     
185     public static Library registerLibrary(String libraryName) {
186         synchronized (libraries) {
187             for (Iterator i=libraries.iterator(); i.hasNext(); ) {
188                 Library lib = (Library) i.next();
189                 if (libraryName.equals(lib.getName()))
190                     return lib;
191             }
192             Library lib = new Library(libraryName);
193             if (lib.open()) {
194                 libraries.add(lib);
195                 return lib;
196             } else {
197                 return null;
198             }
199         }
200     }
201     
202     public static ExternalLink tryLink(String name) {
203         ExternalLink x = new ExternalLink(name);
204         if (!x.resolve().isNull()) return x;
205         else return null;
206     }
207     
208     public static CodeAddress debugwrite_8;
209     public static CodeAddress debugwwrite_8;
210     public static CodeAddress debugwriteln_8;
211     public static CodeAddress debugwwriteln_8;
212     public static CodeAddress syscalloc_4;
213     public static CodeAddress sysfree_4;
214     public static CodeAddress die_4;
215     public static CodeAddress currentTimeMillis_0;
216     public static CodeAddress mem_cpy_12;
217     public static CodeAddress mem_set_12;
218     public static CodeAddress file_open_12;
219     public static CodeAddress file_stat_8;
220     public static CodeAddress file_readbytes_12;
221     public static CodeAddress file_writebyte_8;
222     public static CodeAddress file_writebytes_12;
223     public static CodeAddress file_sync_4;
224     public static CodeAddress file_seek_16;
225     public static CodeAddress file_close_4;
226     public static CodeAddress console_available_0;
227     public static CodeAddress main_argc_0;
228     public static CodeAddress main_argv_length_4;
229     public static CodeAddress main_argv_8;
230     public static CodeAddress fs_getdcwd_12;
231     public static CodeAddress fs_fullpath_12;
232     public static CodeAddress fs_gettruename_4;
233     public static CodeAddress fs_getfileattributes_4;
234     public static CodeAddress fs_access_8;
235     public static CodeAddress fs_getfiletime_4;
236     public static CodeAddress fs_stat_size_4;
237     public static CodeAddress fs_remove_4;
238     public static CodeAddress fs_opendir_4;
239     public static CodeAddress fs_readdir_4;
240     public static CodeAddress fs_closedir_4;
241     public static CodeAddress fs_mkdir_4;
242     public static CodeAddress fs_rename_8;
243     public static CodeAddress fs_chmod_8;
244     public static CodeAddress fs_setfiletime_12;
245     public static CodeAddress fs_getlogicaldrives_0;
246     public static CodeAddress yield_0;
247     public static CodeAddress msleep_4;
248     public static CodeAddress create_thread_8;
249     public static CodeAddress init_thread_0;
250     public static CodeAddress resume_thread_4;
251     public static CodeAddress suspend_thread_4;
252     public static CodeAddress set_thread_priority_8;
253     public static CodeAddress allocate_stack_4;
254     public static CodeAddress get_current_thread_handle_0;
255     public static CodeAddress get_thread_context_8;
256     public static CodeAddress set_thread_context_8;
257     public static CodeAddress set_current_context_8;
258     public static CodeAddress set_interval_timer_8;
259     public static CodeAddress init_semaphore_0;
260     public static CodeAddress wait_for_single_object_8;
261     public static CodeAddress release_semaphore_8;
262 
263     public static final jq_Class _class;
264     public static final jq_StaticField _debugwrite;
265     public static final jq_StaticField _debugwriteln;
266     public static final jq_InstanceField _string_value;
267     public static final jq_InstanceField _string_offset;
268     public static final jq_InstanceField _string_count;
269     static {
270         _class = (jq_Class)PrimordialClassLoader.loader.getOrCreateBSType("Ljoeq/Runtime/SystemInterface;");
271         _debugwrite = _class.getOrCreateStaticField("debugwrite_8", "Ljoeq/Memory/CodeAddress;");
272         _debugwriteln = _class.getOrCreateStaticField("debugwriteln_8", "Ljoeq/Memory/CodeAddress;");
273         // cannot use getJavaLangString here, as it may not yet have been initialized.
274         jq_Class jls = (jq_Class)PrimordialClassLoader.loader.getOrCreateBSType("Ljava/lang/String;");
275         _string_value = jls.getOrCreateInstanceField("value", "[C");
276         _string_offset = jls.getOrCreateInstanceField("offset", "I");
277         _string_count = jls.getOrCreateInstanceField("count", "I");
278     }
279 
280     
281     public static void debugwrite(String msg) {
282         if (!jq.RunningNative) {
283             System.err.println(msg);
284             return;
285         }
286         HeapAddress value = (HeapAddress)HeapAddress.addressOf(msg).offset(_string_value.getOffset()).peek();
287         int offset = HeapAddress.addressOf(msg).offset(_string_offset.getOffset()).peek4();
288         int count = HeapAddress.addressOf(msg).offset(_string_count.getOffset()).peek4();
289         Unsafe.pushArg(count);
290         Unsafe.pushArgA(value.offset(offset*2));
291         try {
292             Unsafe.getThreadBlock().disableThreadSwitch();
293             Unsafe.invoke(debugwwrite_8);
294             Unsafe.getThreadBlock().enableThreadSwitch();
295         } catch (Throwable t) { Assert.UNREACHABLE(); }
296     }
297     
298     public static void debugwrite(Utf8 msg) {
299         msg.debugWrite();
300     }
301     
302     public static void debugwrite(byte[] msg) {
303         debugwrite(msg, msg.length);
304     }
305     
306     public static void debugwrite(byte[] msg, int count) {
307         Unsafe.pushArg(count);
308         Unsafe.pushArgA(HeapAddress.addressOf(msg));
309         try {
310             Unsafe.getThreadBlock().disableThreadSwitch();
311             Unsafe.invoke(debugwrite_8);
312             Unsafe.getThreadBlock().enableThreadSwitch();
313         } catch (Throwable t) { Assert.UNREACHABLE(); }
314     }
315     
316     public static void debugwriteln(String msg) {
317         if (!jq.RunningNative) {
318             System.err.println(msg);
319             return;
320         }
321         HeapAddress value = (HeapAddress)HeapAddress.addressOf(msg).offset(_string_value.getOffset()).peek();
322         int offset = HeapAddress.addressOf(msg).offset(_string_offset.getOffset()).peek4();
323         int count = HeapAddress.addressOf(msg).offset(_string_count.getOffset()).peek4();
324         Unsafe.pushArg(count);
325         Unsafe.pushArgA(value.offset(offset*2));
326         try {
327             Unsafe.getThreadBlock().disableThreadSwitch();
328             Unsafe.invoke(debugwwriteln_8);
329             Unsafe.getThreadBlock().enableThreadSwitch();
330         } catch (Throwable t) { Assert.UNREACHABLE(); }
331     }
332     
333     public static void debugwriteln(byte[] msg) {
334         debugwriteln(msg, msg.length);
335     }
336     
337     public static void debugwriteln(byte[] msg, int count) {
338         Unsafe.pushArg(count);
339         Unsafe.pushArgA(HeapAddress.addressOf(msg));
340         try {
341             Unsafe.getThreadBlock().disableThreadSwitch();
342             Unsafe.invoke(debugwriteln_8);
343             Unsafe.getThreadBlock().enableThreadSwitch();
344         } catch (Throwable t) { Assert.UNREACHABLE(); }
345     }
346 
347     public static Address syscalloc(int size) {
348         Unsafe.pushArg(size);
349         try {
350             Unsafe.getThreadBlock().disableThreadSwitch();
351             Address v = Unsafe.invokeA(syscalloc_4);
352             Unsafe.getThreadBlock().enableThreadSwitch();
353             return v;
354         } catch (Throwable t) { Assert.UNREACHABLE(); }
355         return null;
356     }
357     
358     public static void sysfree(Address a) {
359         Unsafe.pushArgA(a);
360         try {
361             Unsafe.getThreadBlock().disableThreadSwitch();
362             Unsafe.invoke(sysfree_4);
363             Unsafe.getThreadBlock().enableThreadSwitch();
364         } catch (Throwable t) { Assert.UNREACHABLE(); }
365     }
366 
367     public static void die(int code) {
368         Unsafe.pushArg(code);
369         try {
370             Unsafe.getThreadBlock().disableThreadSwitch();
371             Unsafe.invoke(die_4);
372             Unsafe.getThreadBlock().enableThreadSwitch();
373         } catch (Throwable t) {
374             throw new InternalError();
375         }
376     }
377     
378     public static final String DEFAULT_ENCODING = "ISO-8859-1";
379 
380     public static byte[] toCString(String s) {
381         try {
382             byte[] b = s.getBytes(DEFAULT_ENCODING);
383             byte[] b2 = new byte[b.length+1];
384             System.arraycopy(b, 0, b2, 0, b.length);
385             return b2;
386         } catch (java.io.UnsupportedEncodingException x) { return null; }
387     }
388 
389     public static String fromCString(Address p) {
390         int len;
391         for (len=0; (byte)p.offset(len).peek1()!=(byte)0; ++len) ;
392         byte[] b = new byte[len];
393         mem_cpy(HeapAddress.addressOf(b), p, len);
394         return new String(b);
395     }
396     
397     public static long currentTimeMillis() {
398         //if (!jq.RunningNative)
399         //    return System.currentTimeMillis();
400         //else
401             try {
402                 Unsafe.getThreadBlock().disableThreadSwitch();
403                 long v = Unsafe.invoke(currentTimeMillis_0);
404                 Unsafe.getThreadBlock().enableThreadSwitch();
405                 return v;
406             } catch (Throwable t) { Assert.UNREACHABLE(); }
407         return 0;
408     }
409 
410     public static void mem_cpy(Address to, Address from, int size) {
411         Unsafe.pushArg(size);
412         Unsafe.pushArgA(from);
413         Unsafe.pushArgA(to);
414         try {
415             Unsafe.getThreadBlock().disableThreadSwitch();
416             Unsafe.invoke(mem_cpy_12);
417             Unsafe.getThreadBlock().enableThreadSwitch();
418         } catch (Throwable t) { Assert.UNREACHABLE(); }
419     }
420 
421     public static void mem_set(Address to, byte b, int size) {
422         Unsafe.pushArg(size);
423         Unsafe.pushArg(b);
424         Unsafe.pushArgA(to);
425         try {
426             Unsafe.getThreadBlock().disableThreadSwitch();
427             Unsafe.invoke(mem_set_12);
428             Unsafe.getThreadBlock().enableThreadSwitch();
429         } catch (Throwable t) { Assert.UNREACHABLE(); }
430     }
431     
432     // constants from fcntl.h
433     public static final int _O_RDONLY = 0x0000;
434     public static final int _O_WRONLY = 0x0001;
435     public static final int _O_RDWR   = 0x0002;
436     public static final int _O_APPEND = 0x0008;
437     public static final int _O_CREAT  = 0x0100;
438     public static final int _O_TRUNC  = 0x0200;
439     public static final int _O_EXCL   = 0x0400;
440     public static final int _O_TEXT   = 0x4000;
441     public static final int _O_BINARY = 0x8000;
442     public static int file_open(String fn, int mode, int smode) {
443         byte[] filename = toCString(fn);
444         Unsafe.pushArg(smode);
445         Unsafe.pushArg(mode);
446         Unsafe.pushArgA(HeapAddress.addressOf(filename));
447         try {
448             Unsafe.getThreadBlock().disableThreadSwitch();
449             int v = (int)Unsafe.invoke(file_open_12);
450             Unsafe.getThreadBlock().enableThreadSwitch();
451             return v;
452         } catch (Throwable t) { Assert.UNREACHABLE(); }
453         return 0;
454     }
455     public abstract static class Stat {}
456     public static int file_stat(String fn, Stat s) {
457         byte[] filename = toCString(fn);
458         Unsafe.pushArgA(HeapAddress.addressOf(s));
459         Unsafe.pushArgA(HeapAddress.addressOf(filename));
460         try {
461             Unsafe.getThreadBlock().disableThreadSwitch();
462             int v = (int)Unsafe.invoke(file_stat_8);
463             Unsafe.getThreadBlock().enableThreadSwitch();
464             return v;
465         } catch (Throwable t) { Assert.UNREACHABLE(); }
466         return 0;
467     }
468     public static int file_readbytes(int fd, Address startAddress, int length) {
469         Unsafe.pushArg(length);
470         Unsafe.pushArgA(startAddress);
471         Unsafe.pushArg(fd);
472         try {
473             Unsafe.getThreadBlock().disableThreadSwitch();
474             int v = (int)Unsafe.invoke(file_readbytes_12);
475             Unsafe.getThreadBlock().enableThreadSwitch();
476             return v;
477         } catch (Throwable t) { Assert.UNREACHABLE(); }
478         return 0;
479     }
480     public static int file_writebyte(int fd, int b) {
481         Unsafe.pushArg(b);
482         Unsafe.pushArg(fd);
483         try {
484             Unsafe.getThreadBlock().disableThreadSwitch();
485             int v = (int)Unsafe.invoke(file_writebyte_8);
486             Unsafe.getThreadBlock().enableThreadSwitch();
487             return v;
488         } catch (Throwable t) { Assert.UNREACHABLE(); }
489         return 0;
490     }
491     public static int file_writebytes(int fd, Address startAddress, int length) {
492         Unsafe.pushArg(length);
493         Unsafe.pushArgA(startAddress);
494         Unsafe.pushArg(fd);
495         try {
496             Unsafe.getThreadBlock().disableThreadSwitch();
497             int v = (int)Unsafe.invoke(file_writebytes_12);
498             Unsafe.getThreadBlock().enableThreadSwitch();
499             return v;
500         } catch (Throwable t) { Assert.UNREACHABLE(); }
501         return 0;
502     }
503     public static int file_sync(int fd) {
504         Unsafe.pushArg(fd);
505         try {
506             Unsafe.getThreadBlock().disableThreadSwitch();
507             int v = (int)Unsafe.invoke(file_sync_4);
508             Unsafe.getThreadBlock().enableThreadSwitch();
509             return v;
510         } catch (Throwable t) { Assert.UNREACHABLE(); }
511         return 0;
512     }
513     public static final int SEEK_SET = 0; // from stdio.h
514     public static final int SEEK_CUR = 1;
515     public static final int SEEK_END = 2;
516     public static long file_seek(int fd, long offset, int origin) {
517         Unsafe.pushArg((int)origin);
518         Unsafe.pushArg((int)(offset>>32)); // hi
519         Unsafe.pushArg((int)offset);       // lo
520         Unsafe.pushArg(fd);
521         try {
522             Unsafe.getThreadBlock().disableThreadSwitch();
523             long v = Unsafe.invoke(file_seek_16);
524             Unsafe.getThreadBlock().enableThreadSwitch();
525             return v;
526         } catch (Throwable t) { Assert.UNREACHABLE(); }
527         return 0;
528     }
529     public static int file_close(int fd) {
530         Unsafe.pushArg(fd);
531         try {
532             Unsafe.getThreadBlock().disableThreadSwitch();
533             int v = (int)Unsafe.invoke(file_close_4);
534             Unsafe.getThreadBlock().enableThreadSwitch();
535             return v;
536         } catch (Throwable t) { Assert.UNREACHABLE(); }
537         return 0;
538     }
539     
540     public static int console_available() {
541         try {
542             Unsafe.getThreadBlock().disableThreadSwitch();
543             int v = (int)Unsafe.invoke(console_available_0);
544             Unsafe.getThreadBlock().enableThreadSwitch();
545             return v;
546         } catch (Throwable t) { Assert.UNREACHABLE(); }
547         return 0;
548     }
549     
550     public static int main_argc() {
551         try {
552             Unsafe.getThreadBlock().disableThreadSwitch();
553             int v = (int)Unsafe.invoke(main_argc_0);
554             Unsafe.getThreadBlock().enableThreadSwitch();
555             return v;
556         } catch (Throwable t) { Assert.UNREACHABLE(); }
557         return 0;
558     }
559     public static int main_argv_length(int i) {
560         Unsafe.pushArg(i);
561         try {
562             Unsafe.getThreadBlock().disableThreadSwitch();
563             int v = (int)Unsafe.invoke(main_argv_length_4);
564             Unsafe.getThreadBlock().enableThreadSwitch();
565             return v;
566         } catch (Throwable t) { Assert.UNREACHABLE(); }
567         return 0;
568     }
569     public static void main_argv(int i, byte[] b) {
570         Unsafe.pushArgA(HeapAddress.addressOf(b));
571         Unsafe.pushArg(i);
572         try {
573             Unsafe.getThreadBlock().disableThreadSwitch();
574             Unsafe.invoke(main_argv_8);
575             Unsafe.getThreadBlock().enableThreadSwitch();
576         } catch (Throwable t) { Assert.UNREACHABLE(); }
577     }
578     
579     public static int fs_getdcwd(int i, byte[] b) {
580         Unsafe.pushArg(b.length);
581         Unsafe.pushArgA(HeapAddress.addressOf(b));
582         Unsafe.pushArg(i);
583         try {
584             Unsafe.getThreadBlock().disableThreadSwitch();
585             int v = (int)Unsafe.invoke(fs_getdcwd_12);
586             Unsafe.getThreadBlock().enableThreadSwitch();
587             return v;
588         } catch (Throwable t) { Assert.UNREACHABLE(); }
589         return 0;
590     }
591     public static int fs_fullpath(String s, byte[] b) {
592         Unsafe.pushArg(b.length);
593         Unsafe.pushArgA(HeapAddress.addressOf(toCString(s)));
594         Unsafe.pushArgA(HeapAddress.addressOf(b));
595         try {
596             Unsafe.getThreadBlock().disableThreadSwitch();
597             int v = (int)Unsafe.invoke(fs_fullpath_12);
598             Unsafe.getThreadBlock().enableThreadSwitch();
599             return v;
600         } catch (Throwable t) { Assert.UNREACHABLE(); }
601         return 0;
602     }
603     public static Address fs_gettruename(String s) {
604         Unsafe.pushArgA(HeapAddress.addressOf(toCString(s)));
605         try {
606             Unsafe.getThreadBlock().disableThreadSwitch();
607             Address v = Unsafe.invokeA(fs_gettruename_4);
608             Unsafe.getThreadBlock().enableThreadSwitch();
609             return v;
610         } catch (Throwable t) { Assert.UNREACHABLE(); }
611         return null;
612     }
613     public static final int FILE_ATTRIBUTE_READONLY  = 0x001; // in mapiwin.h
614     public static final int FILE_ATTRIBUTE_HIDDEN    = 0x002;
615     public static final int FILE_ATTRIBUTE_SYSTEM    = 0x004;
616     public static final int FILE_ATTRIBUTE_DIRECTORY = 0x010;
617     public static final int FILE_ATTRIBUTE_ARCHIVE   = 0x020;
618     public static final int FILE_ATTRIBUTE_NORMAL    = 0x080;
619     public static final int FILE_ATTRIBUTE_TEMPORARY = 0x100;
620     public static int fs_getfileattributes(String s) {
621         Unsafe.pushArgA(HeapAddress.addressOf(toCString(s)));
622         try {
623             Unsafe.getThreadBlock().disableThreadSwitch();
624             int v = (int)Unsafe.invoke(fs_getfileattributes_4);
625             Unsafe.getThreadBlock().enableThreadSwitch();
626             return v;
627         } catch (Throwable t) { Assert.UNREACHABLE(); }
628         return 0;
629     }
630     public static int fs_access(String s, int mode) {
631         Unsafe.pushArg(mode);
632         Unsafe.pushArgA(HeapAddress.addressOf(toCString(s)));
633         try {
634             Unsafe.getThreadBlock().disableThreadSwitch();
635             int v = (int)Unsafe.invoke(fs_access_8);
636             Unsafe.getThreadBlock().enableThreadSwitch();
637             return v;
638         } catch (Throwable t) { Assert.UNREACHABLE(); }
639         return 0;
640     }
641     public static long fs_getfiletime(String s) {
642         Unsafe.pushArgA(HeapAddress.addressOf(toCString(s)));
643         try {
644             Unsafe.getThreadBlock().disableThreadSwitch();
645             long v = Unsafe.invoke(fs_getfiletime_4);
646             Unsafe.getThreadBlock().enableThreadSwitch();
647             return v;
648         } catch (Throwable t) { Assert.UNREACHABLE(); }
649         return 0L;
650     }
651     public static long fs_stat_size(String s) {
652         Unsafe.pushArgA(HeapAddress.addressOf(toCString(s)));
653         try {
654             Unsafe.getThreadBlock().disableThreadSwitch();
655             long v = Unsafe.invoke(fs_stat_size_4);
656             Unsafe.getThreadBlock().enableThreadSwitch();
657             return v;
658         } catch (Throwable t) { Assert.UNREACHABLE(); }
659         return 0L;
660     }
661     public static int fs_remove(String s) {
662         Unsafe.pushArgA(HeapAddress.addressOf(toCString(s)));
663         try {
664             Unsafe.getThreadBlock().disableThreadSwitch();
665             int v = (int)Unsafe.invoke(fs_remove_4);
666             Unsafe.getThreadBlock().enableThreadSwitch();
667             return v;
668         } catch (Throwable t) { Assert.UNREACHABLE(); }
669         return 0;
670     }
671     public static int fs_opendir(String s) {
672         Unsafe.pushArgA(HeapAddress.addressOf(toCString(s)));
673         try {
674             Unsafe.getThreadBlock().disableThreadSwitch();
675             int v = (int)Unsafe.invoke(fs_opendir_4);
676             Unsafe.getThreadBlock().enableThreadSwitch();
677             return v;
678         } catch (Throwable t) { Assert.UNREACHABLE(); }
679         return 0;
680     }
681     public static final int readdir_name_offset = 11;
682     public static Address fs_readdir(int p) {
683         Unsafe.pushArg(p);
684         try {
685             Unsafe.getThreadBlock().disableThreadSwitch();
686             Address v = Unsafe.invokeA(fs_readdir_4);
687             Unsafe.getThreadBlock().enableThreadSwitch();
688             return v;
689         } catch (Throwable t) { Assert.UNREACHABLE(); }
690         return null;
691     }
692     public static int fs_closedir(int p) {
693         Unsafe.pushArg(p);
694         try {
695             Unsafe.getThreadBlock().disableThreadSwitch();
696             int v = (int)Unsafe.invoke(fs_closedir_4);
697             Unsafe.getThreadBlock().enableThreadSwitch();
698             return v;
699         } catch (Throwable t) { Assert.UNREACHABLE(); }
700         return 0;
701     }
702     public static int fs_mkdir(String s) {
703         Unsafe.pushArgA(HeapAddress.addressOf(toCString(s)));
704         try {
705             Unsafe.getThreadBlock().disableThreadSwitch();
706             int v = (int)Unsafe.invoke(fs_mkdir_4);
707             Unsafe.getThreadBlock().enableThreadSwitch();
708             return v;
709         } catch (Throwable t) { Assert.UNREACHABLE(); }
710         return 0;
711     }
712     public static int fs_rename(String s, String s1) {
713         Unsafe.pushArgA(HeapAddress.addressOf(toCString(s1)));
714         Unsafe.pushArgA(HeapAddress.addressOf(toCString(s)));
715         try {
716             Unsafe.getThreadBlock().disableThreadSwitch();
717             int v = (int)Unsafe.invoke(fs_rename_8);
718             Unsafe.getThreadBlock().enableThreadSwitch();
719             return v;
720         } catch (Throwable t) { Assert.UNREACHABLE(); }
721         return 0;
722     }
723     public static final int _S_IEXEC  = 0x0000040; // from sys/stat.h
724     public static final int _S_IWRITE = 0x0000080;
725     public static final int _S_IREAD  = 0x0000100;
726     public static int fs_chmod(String s, int mode) {
727         Unsafe.pushArg(mode);
728         Unsafe.pushArgA(HeapAddress.addressOf(toCString(s)));
729         try {
730             Unsafe.getThreadBlock().disableThreadSwitch();
731             int v = (int)Unsafe.invoke(fs_chmod_8);
732             Unsafe.getThreadBlock().enableThreadSwitch();
733             return v;
734         } catch (Throwable t) { Assert.UNREACHABLE(); }
735         return 0;
736     }
737     public static int fs_setfiletime(String s, long time) {
738         Unsafe.pushArg((int)(time>>32)); // hi
739         Unsafe.pushArg((int)time);       // lo
740         Unsafe.pushArgA(HeapAddress.addressOf(toCString(s)));
741         try {
742             Unsafe.getThreadBlock().disableThreadSwitch();
743             int v = (int)Unsafe.invoke(fs_setfiletime_12);
744             Unsafe.getThreadBlock().enableThreadSwitch();
745             return v;
746         } catch (Throwable t) { Assert.UNREACHABLE(); }
747         return 0;
748     }
749     public static int fs_getlogicaldrives() {
750         try {
751             Unsafe.getThreadBlock().disableThreadSwitch();
752             int v = (int)Unsafe.invoke(fs_getlogicaldrives_0);
753             Unsafe.getThreadBlock().enableThreadSwitch();
754             return v;
755         } catch (Throwable t) { Assert.UNREACHABLE(); }
756         return 0;
757     }
758     public static void yield() {
759         try {
760             Unsafe.getThreadBlock().disableThreadSwitch();
761             Unsafe.invoke(yield_0);
762             Unsafe.getThreadBlock().enableThreadSwitch();
763         } catch (Throwable t) { Assert.UNREACHABLE(); }
764     }
765     public static void msleep(int ms) {
766         try {
767             Unsafe.pushArg(ms);
768             Unsafe.getThreadBlock().disableThreadSwitch();
769             Unsafe.invoke(msleep_4);
770             Unsafe.getThreadBlock().enableThreadSwitch();
771         } catch (Throwable t) { Assert.UNREACHABLE(); }
772     }
773     public static int/*CPointer*/ create_thread(CodeAddress start_address, HeapAddress param) {
774         try {
775             Unsafe.pushArgA(param);
776             Unsafe.pushArgA(start_address);
777             Unsafe.getThreadBlock().disableThreadSwitch();
778             int v = (int)Unsafe.invoke(create_thread_8);
779             Unsafe.getThreadBlock().enableThreadSwitch();
780             return v;
781         } catch (Throwable t) { Assert.UNREACHABLE(); }
782         return 0;
783     }
784     public static int init_thread() {
785         try {
786             int v = (int)Unsafe.invoke(init_thread_0);
787             return v;
788         } catch (Throwable t) { Assert.UNREACHABLE(); }
789         return 0;
790     }
791     public static int resume_thread(int/*CPointer*/ thread_handle) {
792         try {
793             Unsafe.pushArg(thread_handle);
794             Assert._assert(!Unsafe.getThreadBlock().isThreadSwitchEnabled());
795             int v = (int)Unsafe.invoke(resume_thread_4);
796             return v;
797         } catch (Throwable t) { Assert.UNREACHABLE(); }
798         return 0;
799     }
800     public static int suspend_thread(int/*CPointer*/ thread_handle) {
801         try {
802             Unsafe.pushArg(thread_handle);
803             Assert._assert(!Unsafe.getThreadBlock().isThreadSwitchEnabled());
804             int v = (int)Unsafe.invoke(suspend_thread_4);
805             return v;
806         } catch (Throwable t) { Assert.UNREACHABLE(); }
807         return 0;
808     }
809     // from winnt.h
810     public static final int THREAD_BASE_PRIORITY_LOWRT = 15;
811     public static final int THREAD_BASE_PRIORITY_MAX = 2;
812     public static final int THREAD_BASE_PRIORITY_MIN = -2;
813     public static final int THREAD_BASE_PRIORITY_IDLE = -15;
814     // from winbase.h
815     public static final int THREAD_PRIORITY_LOWEST = THREAD_BASE_PRIORITY_MIN;
816     public static final int THREAD_PRIORITY_BELOW_NORMAL = THREAD_PRIORITY_LOWEST+1;
817     public static final int THREAD_PRIORITY_NORMAL = 0;
818     public static final int THREAD_PRIORITY_HIGHEST = THREAD_BASE_PRIORITY_MAX;
819     public static final int THREAD_PRIORITY_ABOVE_NORMAL = THREAD_PRIORITY_HIGHEST-1;
820     public static final int THREAD_PRIORITY_TIME_CRITICAL = THREAD_BASE_PRIORITY_LOWRT;
821     public static final int THREAD_PRIORITY_IDLE = THREAD_BASE_PRIORITY_IDLE;
822 
823     public static int set_thread_priority(int/*CPointer*/ thread_handle, int level) {
824         try {
825             Unsafe.pushArg(level);
826             Unsafe.pushArg(thread_handle);
827             Assert._assert(!Unsafe.getThreadBlock().isThreadSwitchEnabled());
828             int v = (int)Unsafe.invoke(set_thread_priority_8);
829             return v;
830         } catch (Throwable t) { Assert.UNREACHABLE(); }
831         return 0;
832     }
833     public static StackAddress allocate_stack(int size) {
834         try {
835             Unsafe.pushArg(size);
836             Unsafe.getThreadBlock().disableThreadSwitch();
837             StackAddress v = (StackAddress)Unsafe.invokeA(allocate_stack_4);
838             Unsafe.getThreadBlock().enableThreadSwitch();
839             return v;
840         } catch (Throwable t) { Assert.UNREACHABLE(); }
841         return null;
842     }
843     public static int/*CPointer*/ get_current_thread_handle() {
844         try {
845             Assert._assert(!Unsafe.getThreadBlock().isThreadSwitchEnabled());
846             int v = (int)Unsafe.invoke(get_current_thread_handle_0);
847             return v;
848         } catch (Throwable t) { Assert.UNREACHABLE(); }
849         return 0;
850     }
851     public static boolean get_thread_context(int pid, jq_RegisterState context) {
852         try {
853             Unsafe.pushArgA(HeapAddress.addressOf(context));
854             Unsafe.pushArg(pid);
855             Assert._assert(!Unsafe.getThreadBlock().isThreadSwitchEnabled());
856             int v = (int)Unsafe.invoke(get_thread_context_8);
857             return v!=0;
858         } catch (Throwable t) { Assert.UNREACHABLE(); }
859         return false;
860     }
861     public static boolean set_thread_context(int pid, jq_RegisterState context) {
862         try {
863             Unsafe.pushArgA(HeapAddress.addressOf(context));
864             Unsafe.pushArg(pid);
865             Assert._assert(!Unsafe.getThreadBlock().isThreadSwitchEnabled());
866             int v = (int)Unsafe.invoke(set_thread_context_8);
867             return v!=0;
868         } catch (Throwable t) { Assert.UNREACHABLE(); }
869         return false;
870     }
871     public static void set_current_context(jq_Thread thread, jq_RegisterState context) {
872         try {
873             Unsafe.pushArgA(HeapAddress.addressOf(context));
874             Unsafe.pushArgA(HeapAddress.addressOf(thread));
875             Assert._assert(!Unsafe.getThreadBlock().isThreadSwitchEnabled());
876             Unsafe.invoke(set_current_context_8);
877         } catch (Throwable t) { Assert.UNREACHABLE(); }
878     }
879     public static final int ITIMER_VIRTUAL = 1;
880     public static void set_interval_timer(int type, int ms) {
881         try {
882             Unsafe.pushArg(ms);
883             Unsafe.pushArg(type);
884             Unsafe.getThreadBlock().disableThreadSwitch();
885             Unsafe.invoke(set_interval_timer_8);
886             Unsafe.getThreadBlock().enableThreadSwitch();
887         } catch (Throwable t) { Assert.UNREACHABLE(); }
888     }
889     public static int/*CPointer*/ init_semaphore() {
890         try {
891             Unsafe.getThreadBlock().disableThreadSwitch();
892             int v = (int)Unsafe.invoke(init_semaphore_0);
893             Unsafe.getThreadBlock().enableThreadSwitch();
894             return v;
895         } catch (Throwable t) { Assert.UNREACHABLE(); }
896         return 0;
897     }
898     public static final int INFINITE = -1;
899     public static final int WAIT_ABANDONED = 0x00000080;
900     public static final int WAIT_OBJECT_0  = 0x00000000;
901     public static final int WAIT_TIMEOUT   = 0x00000102;
902     public static int wait_for_single_object(int/*CPointer*/ obj, int timeout) {
903         try {
904             Unsafe.pushArg(timeout);
905             Unsafe.pushArg(obj);
906             Unsafe.getThreadBlock().disableThreadSwitch();
907             int v = (int)Unsafe.invoke(wait_for_single_object_8);
908             Unsafe.getThreadBlock().enableThreadSwitch();
909             return v;
910         } catch (Throwable t) { Assert.UNREACHABLE(); }
911         return 0;
912     }
913     public static int release_semaphore(int/*CPointer*/ semaphore, int v1) {
914         try {
915             Unsafe.pushArg(v1);
916             Unsafe.pushArg(semaphore);
917             Unsafe.getThreadBlock().disableThreadSwitch();
918             int v = (int)Unsafe.invoke(release_semaphore_8);
919             Unsafe.getThreadBlock().enableThreadSwitch();
920             return v;
921         } catch (Throwable t) { Assert.UNREACHABLE(); }
922         return 0;
923     }
924 }