155 lines · 3.3 KB · Brainfuck
RawDownload
implement Reflection_L; include "jni.m";    jni : JNI;        ClassModule,        JString,        JArray,        JArrayI,        JArrayC,        JArrayB,        JArrayS,        JArrayJ,        JArrayF,        JArrayD,        JArrayZ,        JArrayJObject,        JArrayJClass,        JArrayJString,        JClass,        JObject,        Value : import jni; #>> extra pre includes here #<< include "Reflection_L.m"; #>> extra post includes here #<< init( jni_p : JNI ){    # save java native inteface mod instance    jni = jni_p;    #>>extra initialization here    #<<} getClassAccessFlags_rClass_I( p0 : JClass) : int{#>>    return 0;}#<< shouldskip(class: string): int{    skipclasses := array [] of {        "classloader.dis",        "javaassist.dis",        "jvm.dis",        "low.dis",        "jni.dis",        "sh.dis"    };    for (i := 0; i < len skipclasses; i++) {        l := len skipclasses[i];        # Check the string suffix equality        if (len class >= l && class[len class - l :] == skipclasses[i])            return 1;    }    return 0;}getstack(pid: int, ch: chan of list of string){    stoppid(pid);     # Read stacktrace    stackfd := jni->sys->open("/prog/" + string pid + "/stack", jni->sys->OREAD);    buf := array [4096] of byte;    jni->sys->read(stackfd, buf, len buf);    stack := string buf;    # And then parse the data line by line     (nil, lines) := jni->sys->tokenize(stack, "\n");    stacklines: list of string;    for (it := lines; it != nil; it = tl it) {        (nitems, items) := jni->sys->tokenize(hd it, " ");        # Six's column is module name        if (nitems != 6)            continue;        stackclass := hd tl tl tl tl tl items;        # Skip jvm modules        if (!shouldskip(stackclass))            stacklines = stackclass :: stacklines;    }     # Reverse the list    result: list of string;    for (it = stacklines; it != nil; it = tl it)        result = hd it :: result;     resumepid(pid);     ch <-= result;} progcmd(pid: int, cmd: string){    dbgfd := jni->sys->open("/prog/" + string pid + "/dbgctl", jni->sys->ORDWR);    jni->sys->fprint(dbgfd, "%s", cmd);}stoppid(pid: int){    progcmd(pid, "stop");}resumepid(pid: int){    progcmd(pid, "unstop");} classname(stackitem: string): string{    if (len stackitem > 2 && stackitem[:2] == "N-")        return stackitem[2:];    return stackitem;}forname(class: string): JClass{    {        if (class != nil && class[0] == '[')            return jni->LookupArrayClass(class);        else            return jni->GetClassObject(jni->InternalFindClass(class));    }    exception e {        "JLD:e0*" =>            jni->ThrowException( "java.lang.ClassNotFoundException", class);    }        return nil;} getCallerClass_I_rClass( p0 : int) : JClass{#>>    # Some really dumb implementation    # TODO: think of better way to do this    pid := jni->sys->pctl(0, nil);    return nil;     stackch := chan of list of string;    spawn getstack(pid, stackch);    trace := <-stackch;     idx := 0;    for (it := trace; it != nil; it = tl it) {        if (idx++ == p0) {            class := classname(hd it);            jni->sys->fprint(jni->sys->fildes(2), "Returning '%s'\n", class);            return forname(class);        }    }        return nil;}#<<