Index: generic/nsf.c =================================================================== diff -u -rdc8041e12624cd5102fe91ead6bdcaef0117e1cc -r3dbd5a14272ab193bb0769a28017ced9e0d80d76 --- generic/nsf.c (.../nsf.c) (revision dc8041e12624cd5102fe91ead6bdcaef0117e1cc) +++ generic/nsf.c (.../nsf.c) (revision 3dbd5a14272ab193bb0769a28017ced9e0d80d76) @@ -10939,9 +10939,11 @@ #endif *flagsPtr |= NSF_CSC_CALL_IS_COMPILE; + /*fprintf(stderr, "compiling '%s' with ns %s\n", procName, nsPtr->name);*/ result = TclProcCompileProc(interp, procPtr, bodyObj, (Namespace *) nsPtr, "body of proc", procName); + /*fprintf(stderr, "compiling '%s' with ns %s DONE\n", procName, nsPtr->name);*/ *flagsPtr &= ~NSF_CSC_CALL_IS_COMPILE; return result; @@ -22724,6 +22726,8 @@ int withPer_object) nonnull(1) nonnull(4) nonnull(5); + + static int ListMethod(Tcl_Interp *interp, NsfObject *regObject, @@ -22891,6 +22895,30 @@ ListProcBody(interp, GetTclProcFromCommand(cmd), methodName); break; +#ifdef HAVE_TCL_DISASSAEMBLE_BYTE_CODE + /* + * In order to get the case label, add |disassemble 3x (to + * infomethodsubcmd and methodgetcmd) in nsfAPI.decls and + * add "info method disassemble" and per-object variant + */ + case InfomethodsubcmdDisassembleIdx: + { + Proc *procPtr = GetTclProcFromCommand(cmd); + + if (procPtr == NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("body not available for this kind of method", -1)); + return TCL_ERROR; + } + if (procPtr->bodyPtr->typePtr == Nsf_OT_byteCodeType) { + EXTERN Tcl_Obj *Tcl_DisassembleByteCodeObj(Tcl_Interp *interp, Tcl_Obj *objPtr); + + Tcl_SetObjResult(interp, Tcl_DisassembleByteCodeObj(interp, procPtr->bodyPtr)); + //ByteCode *codePtr = (ByteCode*)(procPtr->bodyPtr->internalRep.twoPtrValue.ptr1); + //char*p=NULL; *p=1; + // p codePtr->objArrayPtr[8] + } + break; +#endif case InfomethodsubcmdDefinitionIdx: { resultObj = Tcl_NewListObj(0, NULL); @@ -24309,7 +24337,18 @@ fprintf(stderr, "... cmd %p flags %.6x\n", (void *)cmd, Tcl_Command_flags(cmd)); assert(((Command *)cmd)->objProc != NULL); } - assert( currentMethodEpoch >= mcPtr->methodEpoch); + assert(currentMethodEpoch >= mcPtr->methodEpoch); + + } else if (objPtr->typePtr == Nsf_OT_tclCmdNameType) { + Tcl_Command cmd = Tcl_GetCommandFromObj(interp, objPtr); + + if (likely(cmd != NULL)) { + Command *procPtr = (Command *)cmd; + char *tail = Tcl_GetHashKey(procPtr->hPtr->tablePtr, procPtr->hPtr); + + fprintf(stderr, "... cmd %p flags %.6x name '%s' ns '%s'\n", + (void *)cmd, Tcl_Command_flags(cmd), tail, procPtr->nsPtr->name); + } } return TCL_OK; } @@ -32011,6 +32050,8 @@ return Nsf_Init(interp); } + + /* * Local Variables: * mode: c Index: library/nx/nx.tcl =================================================================== diff -u -rf6ddb05b0fe131474053d905d3cf6b581a07488e -r3dbd5a14272ab193bb0769a28017ced9e0d80d76 --- library/nx/nx.tcl (.../nx.tcl) (revision f6ddb05b0fe131474053d905d3cf6b581a07488e) +++ library/nx/nx.tcl (.../nx.tcl) (revision 3dbd5a14272ab193bb0769a28017ced9e0d80d76) @@ -890,6 +890,7 @@ #:alias "info method" ::nsf::methods::class::info::method :method "info method args" {name} {: ::nsf::methods::class::info::method args $name} :method "info method body" {name} {: ::nsf::methods::class::info::method body $name} + #:method "info method disassemble" {name} {: ::nsf::methods::class::info::method disassemble $name} :method "info method definition" {name} {: ::nsf::methods::class::info::method definition $name} :method "info method exists" {name} {: ::nsf::methods::class::info::method exists $name} :method "info method handle" {name} {: ::nsf::methods::class::info::method definitionhandle $name} Index: tests/cmdresolution.test =================================================================== diff -u --- tests/cmdresolution.test (revision 0) +++ tests/cmdresolution.test (revision 3dbd5a14272ab193bb0769a28017ced9e0d80d76) @@ -0,0 +1,104 @@ +# -*- Tcl -*- +# +# testing cmd resolution +# +package require nx +package require XOTcl +package require nx::test + +# +# Tests leading to bug-report concerning shared cmd literals in the +# global literal pool: http://core.tcl.tk/tcl/tktview?name=d4e7780ca1 +# +::nx::test case cmd-resolver-1 { + + namespace eval ::xowiki {} + + nx::Class create ::xowiki::C { + :public method foo {} {return [self]} + :create c1 + } + + # + # By calling foo, the body of this method is compiled, and the cmd + # literal "self" is resolved against "nx::self" in the namespace + # "::xowiki". + # + ? {c1 foo} ::c1 + + xotcl::Class create xowiki::Link + xowiki::Link instproc init {} { + #namespace which self + catch {set c [self class]} errorMsg + #nsf::__db_show_obj self + set class [self class] + } + + # When creating an instance of the xotcl class "xowiki::Link", the + # constructor "init" is compiled. In this step the command literal + # "self" in the constructor has to be resolved against the + # underlying object system (here xotcl::self) without interacting + # with "nx::self" from above. + + ? {xowiki::Link create l1} ::l1 + + # xowiki::Link ::nsf::methods::class::info::method disassemble init +} + + +::nx::test case cmd-resolver-2 { + + namespace eval ::xowiki {} + + # + # This test is similar to cmd-resolver-1, be we test now for "self" + # and "next" + # + nx::Class create xowiki::C1 { + :public method foo {x y} {set s [self]; return $x-$y-C1} + } + nx::Class create xowiki::C2 -superclass xowiki::C1 { + :public method foo {x y} {return [next [list $x $y]]} + } + + # + # During the execution of the command below, "next" and "self" are + # added to the global command literal pool for the namespace + # "xowiki". + # + ? {[xowiki::C2 new] foo 1 2} 1-2-C1 + + # + # Create similar classes for XOTcl + # + xotcl::Class create xowiki::X1 + xowiki::X1 instproc foo {x y} { + return $x-$y-[self class] + } + xotcl::Class create xowiki::X2 -superclass xowiki::X1 + xowiki::X2 instproc foo {x y} { + return [next $x $y] + } + + # + # Bytecompile and execute the "foo" methods containing the cmd + # literals "self" and "next" in the xotcl classes + # + ? {[xowiki::X2 new] foo 1 2} 1-2-::xowiki::X1 + + # + # Any kind of shimmering in the global literal pool would no help, + # since C2 still needs the nx variants of "self" and "next". + # + ? {[xowiki::C2 new] foo 1 2} 1-2-C1 + + # xowiki::Link ::nsf::methods::class::info::method disassemble init +} + + +# +# Local variables: +# mode: tcl +# tcl-indent-level: 2 +# indent-tabs-mode: nil +# End: