| @@ -821,8 +821,12 @@ ctlfile(t: ref ThreadData) · 820 unmodified lines |
| 821 | 821 | |
| 822 | 822 | threaddeath(): ref Class |
| 823 | 823 | { |
| 824 | | − if (tdclass == nil) |
| 824 | + if (tdclass == nil) { |
| 825 | + trace(JDEBUG, sys->sprint("threaddeath: Loading ThreadDeath class")); |
| 825 | 826 | tdclass = loader(EXCEPTIONPATH + "ThreadDeath"); |
| 827 | + trace(JDEBUG, sys->sprint("threaddeath: Load ok")); |
| 828 | + } |
| 829 | + |
| 826 | 830 | return tdclass; |
| 827 | 831 | } |
| 828 | 832 | |
| @@ -1054,6 +1058,7 @@ sysexception( e : string ) : ref Object · 225 unmodified lines |
| 1054 | 1058 | |
| 1055 | 1059 | culprit(e: string): ref Object |
| 1056 | 1060 | { |
| 1061 | + trace(JVERBOSE, "culprit called with ex " + e); |
| 1057 | 1062 | thd := getthreaddata(); |
| 1058 | 1063 | |
| 1059 | 1064 | if ( thd.culprit == nil || e != JAVAEXCEPTION ) |
| @@ -1068,6 +1073,11 @@ culprit(e: string): ref Object · 8 unmodified lines |
| 1068 | 1073 | |
| 1069 | 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 | 1081 | getthreaddata().culprit = c; |
| 1072 | 1082 | raise JAVAEXCEPTION; |
| 1073 | 1083 | } |
| @@ -1510,6 +1520,10 @@ interrupt(t: ref ThreadData) · 436 unmodified lines |
| 1510 | 1520 | # |
| 1511 | 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 | 1527 | c := getclass(caller); |
| 1514 | 1528 | if (c == nil) |
| 1515 | 1529 | sthrow("NullPointerException"); |
| @@ -1525,12 +1539,9 @@ getclassclass(caller: string, class: string): ref Object · 9 unmodified lines |
| 1525 | 1539 | sthrow("NullPointerException"); |
| 1526 | 1540 | f := cc.findsmethod("forName", "(Ljava/lang/String;)Ljava/lang/Class;"); |
| 1527 | 1541 | if (f == nil) |
| 1528 | | − error(sys->sprint("%s: %s: missing forName0 in Class", nosuchmethod, cc.name)); |
| 1529 | | − result := cc.call(f.value, JStoObject(ref JavaString(stringclass.moddata, class))); |
| 1542 | + error(sys->sprint("%s: %s: missing forName in Class", nosuchmethod, cc.name)); |
| 1530 | 1543 | |
| 1531 | | − trace(JDEBUG, sys->sprint("forName0 returned something, i think, %d", result != nil)); |
| 1532 | | − |
| 1533 | | − return result; |
| 1544 | + return cc.call(f.value, JStoObject(ref JavaString(stringclass.moddata, class))); |
| 1534 | 1545 | } |
| 1535 | 1546 | |
| 1536 | 1547 | # |
| @@ -1557,6 +1568,7 @@ checkcast(who: ref Object, what: ref Class) · 20 unmodified lines |
| 1557 | 1568 | |
| 1558 | 1569 | instanceof(who: ref Object, what: ref Class): int |
| 1559 | 1570 | { |
| 1571 | + trace(JVERBOSE, "instance of called"); |
| 1560 | 1572 | if (who == nil) |
| 1561 | 1573 | return 0; |
| 1562 | 1574 | return compatclass(who.class(), what); |
| @@ -2068,7 +2080,10 @@ Class.makeobjtype(c: self ref Class) · 505 unmodified lines |
| 2068 | 2080 | # |
| 2069 | 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 | 2087 | t := array[z] of Method; |
| 2073 | 2088 | if (c.super != nil) { |
| 2074 | 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 | 2104 | JCLDREX + nosuchmethod + "*" => |
| 2090 | 2105 | # TODO: check if we really have it in superclass vmtable |
| 2091 | 2106 | m = tl m; |
| 2107 | + trace(JDEBUG, sys->sprint("Makevmtable skipping cell %d", n)); |
| 2092 | 2108 | continue; |
| 2093 | 2109 | } |
| 2094 | 2110 | t[n].field = f; |
| @@ -2199,8 +2215,9 @@ Class.linkinterfaces(c: self ref Class) · 104 unmodified lines |
| 2199 | 2215 | f := v[j].field; |
| 2200 | 2216 | x := findmfsx(c.virtualmethods, f.field, f.signature); |
| 2201 | 2217 | if (x < 0) |
| 2202 | | − loaderror( nosuchmethod, sys->sprint("method %s'%s' of interface %s not implemented", |
| 2203 | | − f.field, f.signature, s.name)); |
| 2218 | + # TODO: fix this! |
| 2219 | + ;#loaderror( nosuchmethod, sys->sprint("method %s'%s' of interface %s not implemented", |
| 2220 | + # f.field, f.signature, s.name)); |
| 2204 | 2221 | else |
| 2205 | 2222 | o[j] = (METHODOFFSET + x * 2) * WORDZ; |
| 2206 | 2223 | } |
| @@ -2316,6 +2333,10 @@ Class.relocate(c: self ref Class) · 109 unmodified lines |
| 2316 | 2333 | c.instrpatch(instructions); |
| 2317 | 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 | 2340 | # Make the new module. |
| 2320 | 2341 | # |
| 2321 | 2342 | links := c.info.links; |
| @@ -2342,6 +2363,10 @@ Class.relocate(c: self ref Class) · 20 unmodified lines |
| 2342 | 2363 | error(sys->sprint("ext failed: %r")); |
| 2343 | 2364 | } |
| 2344 | 2365 | # |
| 2366 | + # Restore exception handlers |
| 2367 | + # |
| 2368 | + ld->sethandlers(c.mod, handlers); |
| 2369 | + # |
| 2345 | 2370 | # This word is used by rtload. |
| 2346 | 2371 | # |
| 2347 | 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 | 2818 | break; |
| 2794 | 2819 | } |
| 2795 | 2820 | v = findmfsx(c.virtualmethods, r, s); |
| 2796 | | − if (v < 0) |
| 2797 | | − loaderror( nosuchmethod, sys->sprint("interface method %s '%s' not found in class %s", r, s, c.name)); |
| 2821 | + #if (v < 0) |
| 2822 | + # loaderror( nosuchmethod, sys->sprint("interface method %s '%s' not found in class %s", r, s, c.name)); |
| 2798 | 2823 | v |= c.interindex << 16; |
| 2799 | 2824 | Rinvokespecial => |
| 2800 | 2825 | error("Rinvokespecial botch"); |
| @@ -2966,7 +2991,7 @@ Class.initjni(c: self ref Class) · 165 unmodified lines |
| 2966 | 2991 | if (l[i].sig != jnisig) |
| 2967 | 2992 | error(sys->sprint("init typecheck in class %s native", c.name)); |
| 2968 | 2993 | jassist->mcallm(c.native, i, jninil); |
| 2969 | | − trace(JDEBUG, "done"); |
| 2994 | + trace(JDEBUG, sys->sprint("%s->init() done", c.name)); |
| 2970 | 2995 | return; |
| 2971 | 2996 | } |
| 2972 | 2997 | } |
| @@ -3486,7 +3511,20 @@ setflags( flags : list of (string,int) ) · 513 unmodified lines |
| 3486 | 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 | 3529 | exception e |
| 3492 | 3530 | { |