Index: TODO =================================================================== diff -u -r75a621dace63d1282e9abd6f0f4da5fbe11d47c5 -rb2edd7ca322d0135e310c1ee1ce0cc1b39e7c86d --- TODO (.../TODO) (revision 75a621dace63d1282e9abd6f0f4da5fbe11d47c5) +++ TODO (.../TODO) (revision b2edd7ca322d0135e310c1ee1ce0cc1b39e7c86d) @@ -3973,7 +3973,15 @@ * pertain perobjectdispatch and keepcallerself in serializer * extend regression test +nsf.c: +- refactor ObjectCmdMethodDispatch() for clarity +- prepare work on object method dispatches with + KEEP_CALLER_SELF and no NSF_PER_OBJECT_DISPATCH +- explorative implementation of object method dispatches with + KEEP_CALLER_SELF and no NSF_PER_OBJECT_DISPATCH +- extend regression test + ======================================================================== TODO: Index: generic/nsf.c =================================================================== diff -u -r80f0bcea5ed8961fe0d7d9fcb1d7e5d407951823 -rb2edd7ca322d0135e310c1ee1ce0cc1b39e7c86d --- generic/nsf.c (.../nsf.c) (revision 80f0bcea5ed8961fe0d7d9fcb1d7e5d407951823) +++ generic/nsf.c (.../nsf.c) (revision b2edd7ca322d0135e310c1ee1ce0cc1b39e7c86d) @@ -9631,12 +9631,47 @@ Tcl_GetCommandName(interp, cmd), NSF_CSC_TYPE_PLAIN, flags); #endif +#if 1 + /* simple and brutal */ + if (likely(invokedObject->nsPtr != NULL)) { + subMethodCmd = FindMethod(invokedObject->nsPtr, subMethodName); + } else { + subMethodCmd = NULL; + } + + if (subMethodCmd == NULL) { + /* no -system handling */ + actualClass = SearchPLMethod(invokedObject->cl->order, subMethodName, &subMethodCmd, NSF_CMD_CALL_PRIVATE_METHOD); + } + if (likely(subMethodCmd != NULL)) { + cscPtr->objc = objc; + cscPtr->objv = objv; + Nsf_PushFrameCsc(interp, cscPtr, framePtr); + result = MethodDispatch(actualSelf, + interp, objc-1, objv+1, + subMethodCmd, actualSelf, actualClass, subMethodName, + cscPtr->frameType|NSF_CSC_TYPE_ENSEMBLE, + (cscPtr->flags & 0xFF)|NSF_CSC_IMMEDIATE); + Nsf_PopFrameCsc(interp, framePtr); + return result; + } + + /*fprintf(stderr, "... objv[0] %s cmd %p %s csc %p\n", + ObjStr(objv[0]), subMethodCmd, subMethodName, cscPtr); */ + + if (0) { + fprintf(stderr, "new unknown\n"); + return DispatchUnknownMethod(interp, invokedObject, /* objc-1, objv+1*/ objc, objv, actualSelf->cmdName, + objv[1], NSF_CM_NO_OBJECT_METHOD|NSF_CSC_IMMEDIATE); + } +#endif return ObjectDispatch(actualSelf, interp, objc, objv, NSF_CM_KEEP_CALLER_SELF); } /* * NSF_PER_OBJECT_DISPATCH is set */ + if (likely(invokedObject->nsPtr != NULL)) { subMethodCmd = FindMethod(invokedObject->nsPtr, subMethodName); } else { Index: tests/submethods.test =================================================================== diff -u -rfa67c09e3501aa2efa5799977b62ef2e8454e529 -rb2edd7ca322d0135e310c1ee1ce0cc1b39e7c86d --- tests/submethods.test (.../submethods.test) (revision fa67c09e3501aa2efa5799977b62ef2e8454e529) +++ tests/submethods.test (.../submethods.test) (revision b2edd7ca322d0135e310c1ee1ce0cc1b39e7c86d) @@ -323,7 +323,8 @@ ? {obj ifoo} ::ns1::obj::info ? {obj foo} {wrong # args: should be ":info"} - # now we overwrite the object specific method with an object + # Now we try to overwrite the object specific method with an object + # named "info" ? {Object create obj::info} "refuse to overwrite cmd ::ns1::obj::info; delete/rename it before overwriting" rename obj::info "" ? {Object create obj::info} ::ns1::obj::info @@ -710,11 +711,14 @@ ::nsf::object::property obj::child perobjectdispatch false ? {obj link1 foo} {::obj::child} - ? {obj link2 foo} {::obj: unable to dispatch method 'foo'} + #? {obj link2 foo} {::obj: unable to dispatch method 'foo'} + ? {obj link2 foo} {::obj} ? {obj link3 foo} {::obj::child} - ? {obj link4 foo} {::obj: unable to dispatch method 'foo'} + #? {obj link4 foo} {::obj: unable to dispatch method 'foo'} + ? {obj link4 foo} {::obj} ? {obj link5 foo} {::obj::child} - ? {obj child foo} {::obj: unable to dispatch method 'foo'} + #? {obj child foo} {::obj: unable to dispatch method 'foo'} + ? {obj child foo} {::obj} ? {lsort [obj info methods child]} {child} ? {lsort [obj info methods]} {child link1 link2 link3 link4 link5} @@ -751,9 +755,12 @@ # The dispatch via object aliased method calls actually "d1 bar", # although c1 is in the dispatch path - ? {d1 c1 bar} d1-::d1 - ? {d1 c1 foo} D-::d1 - ? {d1 c1 baz} "::d1: unable to dispatch method 'baz'" + #? {d1 c1 bar} d1-::d1 + #? {d1 c1 foo} D-::d1 + #? {d1 c1 baz} "::d1: unable to dispatch method 'baz'" + ? {d1 c1 bar} c1-::d1 + ? {d1 c1 foo} C-::d1 + ? {d1 c1 baz} c1-::d1 # The destroy destroys actually d1, not c1, although destroy is # dispatched originally on c1