Index: generic/gentclAPI.decls =================================================================== diff -u -rdf8c7c2f533ff443d9486b807c8c8a60d9f3b6fd -r50795c66c8a80091cfd160fd48aee2cf2381ca47 --- generic/gentclAPI.decls (.../gentclAPI.decls) (revision df8c7c2f533ff443d9486b807c8c8a60d9f3b6fd) +++ generic/gentclAPI.decls (.../gentclAPI.decls) (revision 50795c66c8a80091cfd160fd48aee2cf2381ca47) @@ -68,6 +68,10 @@ {-argName "method" -required 1 -type tclobj} {-argName "args" -type args} } +#move to right place +xotclCmd dot XOTclDotCmd { + {-argName "args" -type allargs} +} xotclCmd namespace_copycmds XOTclNSCopyCmds { {-argName "fromNs" -required 1 -type tclobj} {-argName "toNs" -required 1 -type tclobj} Index: generic/tclAPI.h =================================================================== diff -u -rdf8c7c2f533ff443d9486b807c8c8a60d9f3b6fd -r50795c66c8a80091cfd160fd48aee2cf2381ca47 --- generic/tclAPI.h (.../tclAPI.h) (revision df8c7c2f533ff443d9486b807c8c8a60d9f3b6fd) +++ generic/tclAPI.h (.../tclAPI.h) (revision 50795c66c8a80091cfd160fd48aee2cf2381ca47) @@ -133,6 +133,7 @@ static int XOTclCreateObjectSystemCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclDeprecatedCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclDispatchCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); +static int XOTclDotCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclFinalizeObjCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclInstvarCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclInterpObjCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); @@ -230,6 +231,7 @@ static int XOTclCreateObjectSystemCmd(Tcl_Interp *interp, Tcl_Obj *rootClass, Tcl_Obj *rootMetaClass); static int XOTclDeprecatedCmd(Tcl_Interp *interp, char *oldCmd, char *newCmd); static int XOTclDispatchCmd(Tcl_Interp *interp, XOTclObject *object, int withObjscope, Tcl_Obj *command, int nobjc, Tcl_Obj *CONST nobjv[]); +static int XOTclDotCmd(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); static int XOTclFinalizeObjCmd(Tcl_Interp *interp); static int XOTclInstvarCmd(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); static int XOTclInterpObjCmd(Tcl_Interp *interp, char *name, int objc, Tcl_Obj *CONST objv[]); @@ -328,6 +330,7 @@ XOTclCreateObjectSystemCmdIdx, XOTclDeprecatedCmdIdx, XOTclDispatchCmdIdx, + XOTclDotCmdIdx, XOTclFinalizeObjCmdIdx, XOTclInstvarCmdIdx, XOTclInterpObjCmdIdx, @@ -2039,6 +2042,15 @@ } static int +XOTclDotCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { + + + + return XOTclDotCmd(interp, objc, objv); + +} + +static int XOTclFinalizeObjCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { parseContext pc; @@ -2603,6 +2615,9 @@ {"command", 1, 0, convertToTclobj}, {"args", 0, 0, convertToNothing}} }, +{"::xotcl::dot", XOTclDotCmdStub, 1, { + {"args", 0, 0, convertToNothing}} +}, {"::xotcl::finalize", XOTclFinalizeObjCmdStub, 0, { } }, Index: generic/xotcl.c =================================================================== diff -u -r7a163ed30233e4e7fd241a91879777a918034e96 -r50795c66c8a80091cfd160fd48aee2cf2381ca47 --- generic/xotcl.c (.../xotcl.c) (revision 7a163ed30233e4e7fd241a91879777a918034e96) +++ generic/xotcl.c (.../xotcl.c) (revision 50795c66c8a80091cfd160fd48aee2cf2381ca47) @@ -1670,28 +1670,22 @@ static int DotCmdResolver(Tcl_Interp *interp, CONST char *cmdName, Tcl_Namespace *nsPtr, int flags, Tcl_Command *cmdPtr) { - XOTclClass *pcl; CallFrame *varFramePtr; if (*cmdName != '.' || flags & TCL_GLOBAL_ONLY) { /* ordinary names and global lookups are not for us */ return TCL_CONTINUE; } - fprintf(stderr, "DotCmdResolver called with %s\n",cmdName); - varFramePtr = Tcl_Interp_varFramePtr(interp); if (Tcl_CallFrame_isProcCallFrame(varFramePtr) & FRAME_IS_XOTCL_METHOD) { - XOTclObject *obj = ((XOTclCallStackContent *)varFramePtr->clientData)->self; - Tcl_Command cmd; - - cmdName ++; - cmd = ObjectFindMethod(interp, obj, cmdName, &pcl); - fprintf(stderr, "DotCmdResolver found %p for %s\n",cmd, cmdName); - if (cmd) { - *cmdPtr = cmd; - return TCL_OK; - } + /*fprintf(stderr, "DotCmdResolver called with %s\n",cmdName);*/ + /* + * We have a cmd starting with ".", we are in an xotcl frame, so + * forward to the dotCmd. + */ + *cmdPtr = RUNTIME_STATE(interp)->dotCmd; + return TCL_OK; } return TCL_CONTINUE; @@ -5584,19 +5578,33 @@ Tcl_Obj *CONST objv[], int flags) { register XOTclObject *obj = (XOTclObject*)clientData; int result = TCL_OK, mixinStackPushed = 0, - filterStackPushed = 0, unknown = 0, objflags, + filterStackPushed = 0, unknown = 0, objflags, shift, frameType = XOTCL_CSC_TYPE_PLAIN; char *methodName; XOTclClass *cl = NULL; Tcl_Command cmd = NULL; XOTclRuntimeState *rst = RUNTIME_STATE(interp); - Tcl_Obj *cmdName = obj->cmdName; + Tcl_Obj *cmdName = obj->cmdName, *methodObj, *cmdObj; assert(objc>0); - methodName = ObjStr(objv[1]); + if (flags & XOTCL_CM_NO_SHIFT) { + shift = 0; + cmdObj = obj->cmdName; + methodObj = objv[0]; + } else { + shift = 1; + cmdObj = objv[0]; + methodObj = objv[1]; + } + methodName = ObjStr(methodObj); +#if defined(USE_COMPILED_VAR_RESOLVER) + if (*methodName == '.') { + methodName ++; + } +#endif /*fprintf(stderr, "DoDispatch obj = %s objc = %d 0=%s methodName=%s\n", - objectName(obj), objc, ObjStr(objv[0]), methodName);*/ + objectName(obj), objc, ObjStr(cmdObj), methodName);*/ #ifdef DISPATCH_TRACE printCall(interp, "DISPATCH", objc, objv); @@ -5628,7 +5636,7 @@ if (csc && (obj != csc->self || csc->frameType != XOTCL_CSC_TYPE_ACTIVE_FILTER)) { - filterStackPushed = FilterStackPush(interp, obj, objv[1]); + filterStackPushed = FilterStackPush(interp, obj, methodObj); cmd = FilterSearchProc(interp, obj, &obj->filterStack->currentCmdPtr, &cl); if (cmd) { /*fprintf(stderr, "filterSearchProc returned cmd %p proc %p\n", cmd, proc);*/ @@ -5697,14 +5705,13 @@ if ((Tcl_Command_flags(cmd) & XOTCL_CMD_PROTECTED_METHOD) && (flags & XOTCL_CM_NO_UNKNOWN) == 0) { - XOTclCallStackContent *csc = CallStackGetTopFrame(interp, NULL); - XOTclObject *o = NULL, *self = csc ? csc->self : NULL; - - GetObjectFromObj(interp, objv[0], &o); - /*fprintf(stderr, "+++ %s is protected, therefore maybe unknown %p %s self=%p o=%p\n", - methodName, objv[0], ObjStr(objv[0]), - csc->self, o);*/ - if (o != self) { + XOTclObject *o, *lastSelf = GetSelfObj(interp); + + /* we do not want to rely on clientData, so get obj from cmdObj */ + GetObjectFromObj(interp, cmdObj, &o); + /*fprintf(stderr, "+++ %s is protected, therefore maybe unknown %p %s self=%p o=%p cd %p\n", + methodName, cmdObj, ObjStr(cmdObj), lastSelf, o, clientData);*/ + if (o != lastSelf) { /*fprintf(stderr, "+++ protected method %s is not invoked\n", methodName);*/ unknown = 1; } @@ -5713,7 +5720,7 @@ if (!unknown) { /*fprintf(stderr, "DoDispatch calls InvokeMethod with obj = %s frameType %d method %s\n", objectName(obj), frameType, methodName);*/ - if ((result = InvokeMethod(clientData, interp, objc-1, objv+1, cmd, obj, cl, + if ((result = InvokeMethod(clientData, interp, objc-shift, objv+shift, cmd, obj, cl, methodName, frameType)) == TCL_ERROR) { result = XOTclErrInProc(interp, cmdName, cl && cl->object.teardown ? cl->object.cmdName : NULL, @@ -5731,34 +5738,34 @@ Tcl_Obj *unknownObj = XOTclGlobalObjects[XOTE_UNKNOWN]; if (XOTclObjectIsClass(obj) && (flags & XOTCL_CM_NO_UNKNOWN)) { - return XOTclVarErrMsg(interp, ObjStr(objv[0]), + return XOTclVarErrMsg(interp, objectName(obj), ": unable to dispatch method '", methodName, "'", (char *) NULL); - } else if (objv[1] != unknownObj) { + } else if (methodObj != unknownObj) { /* * back off and try unknown; */ XOTclObject *obj = (XOTclObject*)clientData; ALLOC_ON_STACK(Tcl_Obj*, objc+1, tov); /* fprintf(stderr, "calling unknown for %s %s, flgs=%02x,%02x isClass=%d %p %s\n", - objectName(obj), ObjStr(objv[1]), flags, XOTCL_CM_NO_UNKNOWN, + objectName(obj), methodName, flags, XOTCL_CM_NO_UNKNOWN, XOTclObjectIsClass(obj), obj, objectName(obj)); */ tov[0] = obj->cmdName; tov[1] = unknownObj; - if (objc>1) - memcpy(tov+2, objv+1, sizeof(Tcl_Obj *)*(objc-1)); + if (objc>1) /*shift?*/ + memcpy(tov+2, objv+shift, sizeof(Tcl_Obj *)*(objc-shift)); /* fprintf(stderr, "?? %s unknown %s\n", objectName(obj), ObjStr(tov[2])); */ - result = DoDispatch(clientData, interp, objc+1, tov, flags | XOTCL_CM_NO_UNKNOWN); + result = DoDispatch(clientData, interp, objc+shift, tov, flags | XOTCL_CM_NO_UNKNOWN); FREE_ON_STACK(tov); } else { /* unknown failed */ - return XOTclVarErrMsg(interp, ObjStr(objv[0]), + return XOTclVarErrMsg(interp, objectName(obj), ": unable to dispatch method '", - ObjStr(objv[2]), "'", (char *) NULL); + ObjStr(objv[shift+1]), "'", (char *) NULL); } } @@ -10178,6 +10185,16 @@ return result; } +static int XOTclDotCmd(Tcl_Interp *interp, int nobjc, Tcl_Obj *CONST nobjv[]) { + XOTclObject *self = GetSelfObj(interp); + + if (!self) { + return XOTclVarErrMsg(interp, "Cannot resolve 'self', probably called outside the context of an XOTcl Object", + (char *) NULL); + } + return DoDispatch(self, interp, nobjc, nobjv, XOTCL_CM_NO_SHIFT); +} + static int XOTclNSCopyCmds(Tcl_Interp *interp, Tcl_Obj *fromNs, Tcl_Obj *toNs) { Tcl_Command cmd; Tcl_Obj *newFullCmdName, *oldFullCmdName; @@ -12903,6 +12920,7 @@ */ Tcl_AddInterpResolvers(interp,"xotcl", (Tcl_ResolveCmdProc*)DotCmdResolver, DotVarResolver, (Tcl_ResolveCompiledVarProc*)CompiledDotVarResolver); + RUNTIME_STATE(interp)->dotCmd = Tcl_FindCommand(interp, "::xotcl::dot", 0, 0); #endif /* Index: generic/xotclInt.h =================================================================== diff -u -rcde16e9d87173d7ef9179ce40e10c2f1f708940e -r50795c66c8a80091cfd160fd48aee2cf2381ca47 --- generic/xotclInt.h (.../xotclInt.h) (revision cde16e9d87173d7ef9179ce40e10c2f1f708940e) +++ generic/xotclInt.h (.../xotclInt.h) (revision 50795c66c8a80091cfd160fd48aee2cf2381ca47) @@ -314,6 +314,7 @@ /* flags for call method */ #define XOTCL_CM_NO_UNKNOWN 1 +#define XOTCL_CM_NO_SHIFT 2 /* * @@ -658,7 +659,8 @@ Tcl_Namespace *fakeNS; XotclStubs *xotclStubs; Tcl_CallFrame *varFramePtr; - Command *cmdPtr; + Command *cmdPtr; /* used for ACTIVE_MIXIN */ + Tcl_Command dotCmd; #if defined(PROFILE) XOTclProfile profile; #endif Index: tests/varresolutiontest.xotcl =================================================================== diff -u -r815c11d71dff9a1af0f2c48e1be2f58e201dad6a -r50795c66c8a80091cfd160fd48aee2cf2381ca47 --- tests/varresolutiontest.xotcl (.../varresolutiontest.xotcl) (revision 815c11d71dff9a1af0f2c48e1be2f58e201dad6a) +++ tests/varresolutiontest.xotcl (.../varresolutiontest.xotcl) (revision 50795c66c8a80091cfd160fd48aee2cf2381ca47) @@ -247,7 +247,8 @@ ############################################### # tests for the var resolver -###############################################Class C +############################################### +Class C C method bar0 {} {return ${.x}} C method bar1 {} {set a ${.x}; return [info exists .x],[info exists .y]} C method bar2 {} {return [info exists .x],[info exists .y]} @@ -265,4 +266,26 @@ c1 foo ? {lsort [c1 info vars]} "a x z" "array variable set via resolver" ? {lsort [c1 array names a]} "a b c" "array looks ok" -puts stderr ===EXIT + +############################################### +# first tests for the cmd resolver +############################################### +Class C +C method bar {args} { + #puts stderr "[self] bar called with [list $args]" + return $args +} +C instforward test %self bar +C method foo {} { + # this works + lappend .r [.bar x 1] + lappend .r [.test a b c] + # these kind of works, but vars are nowhere.... + .set x 1 + .incr x 1 + .incr x 1 + return [lappend .r ${.x}] +} +C create c3 +? {c3 foo} "{x 1} {a b c} 3" +