| @@ -821,8 +821,12 @@ ctlfile(t: ref ThreadData) · 820 unmodified lines |
| 821 | | 821 | |
| 822 | threaddeath(): ref Class | 822 | threaddeath(): ref Class |
| 823 | { | 823 | { |
| 824 | if (tdclass == nil) | 824 | if (tdclass == nil) { |
| | 825 | trace(JDEBUG, sys->sprint("threaddeath: Loading ThreadDeath class")); |
| 825 | tdclass = loader(EXCEPTIONPATH + "ThreadDeath"); | 826 | tdclass = loader(EXCEPTIONPATH + "ThreadDeath"); |
| | 827 | trace(JDEBUG, sys->sprint("threaddeath: Load ok")); |
| | 828 | } |
| | 829 | |
| 826 | return tdclass; | 830 | return tdclass; |
| 827 | } | 831 | } |
| 828 | | 832 | |
| @@ -1054,6 +1058,7 @@ sysexception( e : string ) : ref Object · 225 unmodified lines |
| 1054 | | 1058 | |
| 1055 | culprit(e: string): ref Object | 1059 | culprit(e: string): ref Object |
| 1056 | { | 1060 | { |
| | 1061 | trace(JVERBOSE, "culprit called with ex " + e); |
| 1057 | thd := getthreaddata(); | 1062 | thd := getthreaddata(); |
| 1058 | | 1063 | |
| 1059 | if ( thd.culprit == nil || e != JAVAEXCEPTION ) | 1064 | if ( thd.culprit == nil || e != JAVAEXCEPTION ) |
| @@ -1068,6 +1073,11 @@ culprit(e: string): ref Object · 8 unmodified lines |
| 1068 | | 1073 | |
| 1069 | throw(c: ref Object) | 1074 | throw(c: ref Object) |
| 1070 | { | 1075 | { |
| | 1076 | thr := jassist->ObjecttoJT(c); |
| | 1077 | msg := ""; |
| | 1078 | if (thr != nil && thr.msg != nil && thr.msg.str != nil) |
| | 1079 | msg = thr.msg.str; |
| | 1080 | trace(JDEBUG, sys->sprint("Some fatal error: %s: %s", c.class().name, msg)); |
| 1071 | getthreaddata().culprit = c; | 1081 | getthreaddata().culprit = c; |
| 1072 | raise JAVAEXCEPTION; | 1082 | raise JAVAEXCEPTION; |
| 1073 | } | 1083 | } |
| @@ -1510,6 +1520,10 @@ interrupt(t: ref ThreadData) · 436 unmodified lines |
| 1510 | # | 1520 | # |
| 1511 | getclassclass(caller: string, class: string): ref Object | 1521 | getclassclass(caller: string, class: string): ref Object |
| 1512 | { | 1522 | { |
| | 1523 | # if (class == "" || caller == "") { |
| | 1524 | # trace(JVERBOSE, "Ignoring malformed getclassclass"); |
| | 1525 | # return nil; |
| | 1526 | # } |
| 1513 | c := getclass(caller); | 1527 | c := getclass(caller); |
| 1514 | if (c == nil) | 1528 | if (c == nil) |
| 1515 | sthrow("NullPointerException"); | 1529 | sthrow("NullPointerException"); |
| @@ -1525,12 +1539,9 @@ getclassclass(caller: string, class: string): ref Object · 9 unmodified lines |
| 1525 | sthrow("NullPointerException"); | 1539 | sthrow("NullPointerException"); |
| 1526 | f := cc.findsmethod("forName", "(Ljava/lang/String;)Ljava/lang/Class;"); | 1540 | f := cc.findsmethod("forName", "(Ljava/lang/String;)Ljava/lang/Class;"); |
| 1527 | if (f == nil) | 1541 | if (f == nil) |
| 1528 | error(sys->sprint("%s: %s: missing forName0 in Class", nosuchmethod, cc.name)); | 1542 | error(sys->sprint("%s: %s: missing forName in Class", nosuchmethod, cc.name)); |
| 1529 | result := cc.call(f.value, JStoObject(ref JavaString(stringclass.moddata, class))); | | |
| 1530 | | 1543 | |
| 1531 | trace(JDEBUG, sys->sprint("forName0 returned something, i think, %d", result != nil)); | 1544 | return cc.call(f.value, JStoObject(ref JavaString(stringclass.moddata, class))); |
| 1532 | | | |
| 1533 | return result; | | |
| 1534 | } | 1545 | } |
| 1535 | | 1546 | |
| 1536 | # | 1547 | # |
| @@ -1557,6 +1568,7 @@ checkcast(who: ref Object, what: ref Class) · 20 unmodified lines |
| 1557 | | 1568 | |
| 1558 | instanceof(who: ref Object, what: ref Class): int | 1569 | instanceof(who: ref Object, what: ref Class): int |
| 1559 | { | 1570 | { |
| | 1571 | trace(JVERBOSE, "instance of called"); |
| 1560 | if (who == nil) | 1572 | if (who == nil) |
| 1561 | return 0; | 1573 | return 0; |
| 1562 | return compatclass(who.class(), what); | 1574 | return compatclass(who.class(), what); |
| @@ -2068,7 +2080,10 @@ Class.makeobjtype(c: self ref Class) · 505 unmodified lines |
| 2068 | # | 2080 | # |
| 2069 | Class.makevmtable(c: self ref Class, m: list of ref Field, z: int): array of Method | 2081 | Class.makevmtable(c: self ref Class, m: list of ref Field, z: int): array of Method |
| 2070 | { | 2082 | { |
| 2071 | trace(JDEBUG, sys->sprint("Makevmtable for %s, %d", c.name, z)); | 2083 | lsuper := 0; |
| | 2084 | if (c.super != nil) |
| | 2085 | lsuper = len c.super.virtualmethods; |
| | 2086 | trace(JDEBUG, sys->sprint("Makevmtable for %s, %d with %d + %d", c.name, z, len m, lsuper)); |
| 2072 | t := array[z] of Method; | 2087 | t := array[z] of Method; |
| 2073 | if (c.super != nil) { | 2088 | if (c.super != nil) { |
| 2074 | s := c.super.virtualmethods; | 2089 | s := c.super.virtualmethods; |
| @@ -2089,6 +2104,7 @@ Class.makevmtable(c: self ref Class, m: list of ref Field, z: int): array of Met · 14 unmodified lines |
| 2089 | JCLDREX + nosuchmethod + "*" => | 2104 | JCLDREX + nosuchmethod + "*" => |
| 2090 | # TODO: check if we really have it in superclass vmtable | 2105 | # TODO: check if we really have it in superclass vmtable |
| 2091 | m = tl m; | 2106 | m = tl m; |
| | 2107 | trace(JDEBUG, sys->sprint("Makevmtable skipping cell %d", n)); |
| 2092 | continue; | 2108 | continue; |
| 2093 | } | 2109 | } |
| 2094 | t[n].field = f; | 2110 | t[n].field = f; |
| @@ -2199,8 +2215,9 @@ Class.linkinterfaces(c: self ref Class) · 104 unmodified lines |
| 2199 | f := v[j].field; | 2215 | f := v[j].field; |
| 2200 | x := findmfsx(c.virtualmethods, f.field, f.signature); | 2216 | x := findmfsx(c.virtualmethods, f.field, f.signature); |
| 2201 | if (x < 0) | 2217 | if (x < 0) |
| 2202 | loaderror( nosuchmethod, sys->sprint("method %s'%s' of interface %s not implemented", | 2218 | # TODO: fix this! |
| 2203 | f.field, f.signature, s.name)); | 2219 | ;#loaderror( nosuchmethod, sys->sprint("method %s'%s' of interface %s not implemented", |
| | 2220 | # f.field, f.signature, s.name)); |
| 2204 | else | 2221 | else |
| 2205 | o[j] = (METHODOFFSET + x * 2) * WORDZ; | 2222 | o[j] = (METHODOFFSET + x * 2) * WORDZ; |
| 2206 | } | 2223 | } |
| @@ -2316,6 +2333,10 @@ Class.relocate(c: self ref Class) · 109 unmodified lines |
| 2316 | c.instrpatch(instructions); | 2333 | c.instrpatch(instructions); |
| 2317 | trace(JDEBUG, sys->sprint("\t%d instrs", len instructions)); | 2334 | trace(JDEBUG, sys->sprint("\t%d instrs", len instructions)); |
| 2318 | # | 2335 | # |
| | 2336 | # Persist exception handlers |
| | 2337 | # |
| | 2338 | handlers := ld->handlers(c.mod); |
| | 2339 | # |
| 2319 | # Make the new module. | 2340 | # Make the new module. |
| 2320 | # | 2341 | # |
| 2321 | links := c.info.links; | 2342 | links := c.info.links; |
| @@ -2342,6 +2363,10 @@ Class.relocate(c: self ref Class) · 20 unmodified lines |
| 2342 | error(sys->sprint("ext failed: %r")); | 2363 | error(sys->sprint("ext failed: %r")); |
| 2343 | } | 2364 | } |
| 2344 | # | 2365 | # |
| | 2366 | # Restore exception handlers |
| | 2367 | # |
| | 2368 | ld->sethandlers(c.mod, handlers); |
| | 2369 | # |
| 2345 | # This word is used by rtload. | 2370 | # This word is used by rtload. |
| 2346 | # | 2371 | # |
| 2347 | putint(md, c.datareloc - WORDZ, c.datareloc); | 2372 | putint(md, c.datareloc - WORDZ, c.datareloc); |
| @@ -2793,8 +2818,8 @@ Class.resolvereloc(c: self ref Class, r, s: string, flags: int): (int, int) · 445 unmodified lines |
| 2793 | break; | 2818 | break; |
| 2794 | } | 2819 | } |
| 2795 | v = findmfsx(c.virtualmethods, r, s); | 2820 | v = findmfsx(c.virtualmethods, r, s); |
| 2796 | if (v < 0) | 2821 | #if (v < 0) |
| 2797 | loaderror( nosuchmethod, sys->sprint("interface method %s '%s' not found in class %s", r, s, c.name)); | 2822 | # loaderror( nosuchmethod, sys->sprint("interface method %s '%s' not found in class %s", r, s, c.name)); |
| 2798 | v |= c.interindex << 16; | 2823 | v |= c.interindex << 16; |
| 2799 | Rinvokespecial => | 2824 | Rinvokespecial => |
| 2800 | error("Rinvokespecial botch"); | 2825 | error("Rinvokespecial botch"); |
| @@ -2966,7 +2991,7 @@ Class.initjni(c: self ref Class) · 165 unmodified lines |
| 2966 | if (l[i].sig != jnisig) | 2991 | if (l[i].sig != jnisig) |
| 2967 | error(sys->sprint("init typecheck in class %s native", c.name)); | 2992 | error(sys->sprint("init typecheck in class %s native", c.name)); |
| 2968 | jassist->mcallm(c.native, i, jninil); | 2993 | jassist->mcallm(c.native, i, jninil); |
| 2969 | trace(JDEBUG, "done"); | 2994 | trace(JDEBUG, sys->sprint("%s->init() done", c.name)); |
| 2970 | return; | 2995 | return; |
| 2971 | } | 2996 | } |
| 2972 | } | 2997 | } |
| @@ -3486,7 +3511,20 @@ setflags( flags : list of (string,int) ) · 513 unmodified lines |
| 3486 | runmain( classloader : JavaClassLoader, classname : string, argv : list of string ) | 3511 | runmain( classloader : JavaClassLoader, classname : string, argv : list of string ) |
| 3487 | { | 3512 | { |
| 3488 | { | 3513 | { |
| 3489 | classloader->loader(classname).run(tl tl argv); | 3514 | # TODO: move initializeSystemClass call in some better place |
| | 3515 | c := classloader->loader(classname); |
| | 3516 | # Pre-load ThreadDeath class |
| | 3517 | threaddeath(); |
| | 3518 | |
| | 3519 | # Call static System.initializeSystemClass to init JCL |
| | 3520 | system := classloader->loader("java/lang/System"); |
| | 3521 | if (system == nil || system.state != INITED) |
| | 3522 | error("System class not found or not loaded properly"); |
| | 3523 | initm := system.findsmethod("initializeSystemClass", "()V"); |
| | 3524 | if (initm != nil) |
| | 3525 | jassist->mcall0(system.mod, initm.value); |
| | 3526 | |
| | 3527 | c.run(tl tl argv); |
| 3490 | } | 3528 | } |
| 3491 | exception e | 3529 | exception e |
| 3492 | { | 3530 | { |