Index: generic/gentclAPI.tcl =================================================================== diff -u -r44b916888bf0d89743347039b35ede09e7d9b945 -r0681f4a21fef723a8d6f5a4da698e5b70189765d --- generic/gentclAPI.tcl (.../gentclAPI.tcl) (revision 44b916888bf0d89743347039b35ede09e7d9b945) +++ generic/gentclAPI.tcl (.../gentclAPI.tcl) (revision 0681f4a21fef723a8d6f5a4da698e5b70189765d) @@ -202,6 +202,7 @@ } else { $cDefs $pre + parseContextRelease(&pc); $call $post } Index: generic/tclAPI.h =================================================================== diff -u -r44b916888bf0d89743347039b35ede09e7d9b945 -r0681f4a21fef723a8d6f5a4da698e5b70189765d --- generic/tclAPI.h (.../tclAPI.h) (revision 44b916888bf0d89743347039b35ede09e7d9b945) +++ generic/tclAPI.h (.../tclAPI.h) (revision 0681f4a21fef723a8d6f5a4da698e5b70189765d) @@ -352,6 +352,7 @@ char *name = (char *)pc.clientData[0]; Tcl_Obj *value = (Tcl_Obj *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclCheckBooleanArgs(interp, name, value); } @@ -370,6 +371,7 @@ char *name = (char *)pc.clientData[0]; Tcl_Obj *value = (Tcl_Obj *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclCheckRequiredArgs(interp, name, value); } @@ -388,6 +390,7 @@ } else { char *name = (char *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclCAllocMethod(interp, cl, name); } @@ -406,6 +409,7 @@ } else { char *name = (char *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclCCreateMethod(interp, cl, name, objc, objv); } @@ -424,6 +428,7 @@ } else { Tcl_Obj *object = (Tcl_Obj *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclCDeallocMethod(interp, cl, object); } @@ -443,6 +448,7 @@ char *filter = (char *)pc.clientData[0]; Tcl_Obj *guard = (Tcl_Obj *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclCInstFilterGuardMethod(interp, cl, filter, guard); } @@ -468,6 +474,7 @@ int withVerbose = (int )pc.clientData[6]; Tcl_Obj *target = (Tcl_Obj *)pc.clientData[7]; + parseContextRelease(&pc); return XOTclCInstForwardMethod(interp, cl, method, withDefault, withEarlybinding, withMethodprefix, withObjscope, withOnerror, withVerbose, target, objc-pc.lastobjc, objv+pc.lastobjc); } @@ -487,6 +494,7 @@ char *mixin = (char *)pc.clientData[0]; Tcl_Obj *guard = (Tcl_Obj *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclCInstMixinGuardMethod(interp, cl, mixin, guard); } @@ -505,6 +513,7 @@ } else { char *name = (char *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclCInstParametercmdMethod(interp, cl, name); } @@ -527,6 +536,7 @@ Tcl_Obj *precondition = (Tcl_Obj *)pc.clientData[3]; Tcl_Obj *postcondition = (Tcl_Obj *)pc.clientData[4]; + parseContextRelease(&pc); return XOTclCInstProcMethod(interp, cl, name, args, body, precondition, postcondition); } @@ -549,6 +559,7 @@ Tcl_Obj *precondition = (Tcl_Obj *)pc.clientData[3]; Tcl_Obj *postcondition = (Tcl_Obj *)pc.clientData[4]; + parseContextRelease(&pc); return XOTclCInstProcMethodC(interp, cl, name, args, body, precondition, postcondition); } @@ -567,6 +578,7 @@ } else { Tcl_Obj *invariantlist = (Tcl_Obj *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclCInvariantsMethod(interp, cl, invariantlist); } @@ -585,6 +597,7 @@ } else { XOTclObject *withChildof = (XOTclObject *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclCNewMethod(interp, cl, withChildof, objc-pc.lastobjc, objv+pc.lastobjc); } @@ -603,6 +616,7 @@ } else { Tcl_Obj *name = (Tcl_Obj *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclCRecreateMethod(interp, cl, name, objc, objv); } @@ -621,6 +635,7 @@ } else { char *name = (char *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclCUnknownMethod(interp, cl, name, objc, objv); } @@ -639,6 +654,7 @@ XOTclClass *class = (XOTclClass *)pc.clientData[0]; char *pattern = (char *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclClassInfoHeritageMethod(interp, class, pattern); } @@ -668,6 +684,7 @@ return TCL_OK; } + parseContextRelease(&pc); returnCode = XOTclClassInfoInstancesMethod(interp, class, withClosure, patternString, patternObj); if (pattern) { @@ -690,6 +707,7 @@ XOTclClass *class = (XOTclClass *)pc.clientData[0]; char *methodName = (char *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclClassInfoInstargsMethod(interp, class, methodName); } @@ -708,6 +726,7 @@ XOTclClass *class = (XOTclClass *)pc.clientData[0]; char *methodName = (char *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclClassInfoInstbodyMethod(interp, class, methodName); } @@ -726,6 +745,7 @@ XOTclClass *class = (XOTclClass *)pc.clientData[0]; char *pattern = (char *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclClassInfoInstcommandsMethod(interp, class, pattern); } @@ -746,6 +766,7 @@ char *arg = (char *)pc.clientData[2]; Tcl_Obj *var = (Tcl_Obj *)pc.clientData[3]; + parseContextRelease(&pc); return XOTclClassInfoInstdefaultMethod(interp, class, methodName, arg, var); } @@ -765,6 +786,7 @@ int withGuards = (int )pc.clientData[1]; char *pattern = (char *)pc.clientData[2]; + parseContextRelease(&pc); return XOTclClassInfoInstfilterMethod(interp, class, withGuards, pattern); } @@ -783,6 +805,7 @@ XOTclClass *class = (XOTclClass *)pc.clientData[0]; char *filter = (char *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclClassInfoInstfilterguardMethod(interp, class, filter); } @@ -802,6 +825,7 @@ int withDefinition = (int )pc.clientData[1]; char *pattern = (char *)pc.clientData[2]; + parseContextRelease(&pc); return XOTclClassInfoInstforwardMethod(interp, class, withDefinition, pattern); } @@ -819,6 +843,7 @@ } else { XOTclClass *class = (XOTclClass *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclClassInfoInstinvarMethod(interp, class); } @@ -849,6 +874,7 @@ return TCL_OK; } + parseContextRelease(&pc); returnCode = XOTclClassInfoInstmixinMethod(interp, class, withClosure, withGuards, patternString, patternObj); if (pattern) { @@ -871,6 +897,7 @@ XOTclClass *class = (XOTclClass *)pc.clientData[0]; char *mixin = (char *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclClassInfoInstmixinguardMethod(interp, class, mixin); } @@ -900,6 +927,7 @@ return TCL_OK; } + parseContextRelease(&pc); returnCode = XOTclClassInfoInstmixinofMethod(interp, class, withClosure, patternString, patternObj); if (pattern) { @@ -922,6 +950,7 @@ XOTclClass *class = (XOTclClass *)pc.clientData[0]; char *methodName = (char *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclClassInfoInstnonposargsMethod(interp, class, methodName); } @@ -940,6 +969,7 @@ XOTclClass *class = (XOTclClass *)pc.clientData[0]; char *pattern = (char *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclClassInfoInstparametercmdMethod(interp, class, pattern); } @@ -958,6 +988,7 @@ XOTclClass *class = (XOTclClass *)pc.clientData[0]; char *methodName = (char *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclClassInfoInstpostMethod(interp, class, methodName); } @@ -976,6 +1007,7 @@ XOTclClass *class = (XOTclClass *)pc.clientData[0]; char *methodName = (char *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclClassInfoInstpreMethod(interp, class, methodName); } @@ -994,6 +1026,7 @@ XOTclClass *class = (XOTclClass *)pc.clientData[0]; char *pattern = (char *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclClassInfoInstprocsMethod(interp, class, pattern); } @@ -1023,6 +1056,7 @@ return TCL_OK; } + parseContextRelease(&pc); returnCode = XOTclClassInfoMixinofMethod(interp, class, withClosure, patternString, patternObj); if (pattern) { @@ -1044,6 +1078,7 @@ } else { XOTclClass *class = (XOTclClass *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclClassInfoParameterMethod(interp, class); } @@ -1061,6 +1096,7 @@ } else { XOTclClass *class = (XOTclClass *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclClassInfoSlotsMethod(interp, class); } @@ -1090,6 +1126,7 @@ return TCL_OK; } + parseContextRelease(&pc); returnCode = XOTclClassInfoSubclassMethod(interp, class, withClosure, patternString, patternObj); if (pattern) { @@ -1113,6 +1150,7 @@ int withClosure = (int )pc.clientData[1]; Tcl_Obj *pattern = (Tcl_Obj *)pc.clientData[2]; + parseContextRelease(&pc); return XOTclClassInfoSuperclassMethod(interp, class, withClosure, pattern); } @@ -1131,6 +1169,7 @@ XOTclObject *object = (XOTclObject *)pc.clientData[0]; char *methodName = (char *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclObjInfoArgsMethod(interp, object, methodName); } @@ -1149,6 +1188,7 @@ XOTclObject *object = (XOTclObject *)pc.clientData[0]; char *methodName = (char *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclObjInfoBodyMethod(interp, object, methodName); } @@ -1166,6 +1206,7 @@ } else { XOTclObject *object = (XOTclObject *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclObjInfoCheckMethod(interp, object); } @@ -1184,6 +1225,7 @@ XOTclObject *object = (XOTclObject *)pc.clientData[0]; char *pattern = (char *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclObjInfoChildrenMethod(interp, object, pattern); } @@ -1201,6 +1243,7 @@ } else { XOTclObject *object = (XOTclObject *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclObjInfoClassMethod(interp, object); } @@ -1219,6 +1262,7 @@ XOTclObject *object = (XOTclObject *)pc.clientData[0]; char *pattern = (char *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclObjInfoCommandsMethod(interp, object, pattern); } @@ -1239,6 +1283,7 @@ char *arg = (char *)pc.clientData[2]; Tcl_Obj *var = (Tcl_Obj *)pc.clientData[3]; + parseContextRelease(&pc); return XOTclObjInfoDefaultMethod(interp, object, methodName, arg, var); } @@ -1259,6 +1304,7 @@ int withGuards = (int )pc.clientData[2]; char *pattern = (char *)pc.clientData[3]; + parseContextRelease(&pc); return XOTclObjInfoFilterMethod(interp, object, withOrder, withGuards, pattern); } @@ -1277,6 +1323,7 @@ XOTclObject *object = (XOTclObject *)pc.clientData[0]; char *filter = (char *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclObjInfoFilterguardMethod(interp, object, filter); } @@ -1296,6 +1343,7 @@ int withDefinition = (int )pc.clientData[1]; char *pattern = (char *)pc.clientData[2]; + parseContextRelease(&pc); return XOTclObjInfoForwardMethod(interp, object, withDefinition, pattern); } @@ -1313,6 +1361,7 @@ } else { XOTclObject *object = (XOTclObject *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclObjInfoHasnamespaceMethod(interp, object); } @@ -1330,6 +1379,7 @@ } else { XOTclObject *object = (XOTclObject *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclObjInfoInvarMethod(interp, object); } @@ -1352,6 +1402,7 @@ int withIncontext = (int )pc.clientData[4]; char *pattern = (char *)pc.clientData[5]; + parseContextRelease(&pc); return XOTclObjInfoMethodsMethod(interp, object, withNoprocs, withNocmds, withNomixins, withIncontext, pattern); } @@ -1382,6 +1433,7 @@ return TCL_OK; } + parseContextRelease(&pc); returnCode = XOTclObjInfoMixinMethod(interp, object, withGuards, withOrder, patternString, patternObj); if (pattern) { @@ -1404,6 +1456,7 @@ XOTclObject *object = (XOTclObject *)pc.clientData[0]; char *mixin = (char *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclObjInfoMixinguardMethod(interp, object, mixin); } @@ -1422,6 +1475,7 @@ XOTclObject *object = (XOTclObject *)pc.clientData[0]; char *methodName = (char *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclObjInfoNonposargsMethod(interp, object, methodName); } @@ -1440,6 +1494,7 @@ XOTclObject *object = (XOTclObject *)pc.clientData[0]; char *pattern = (char *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclObjInfoParametercmdMethod(interp, object, pattern); } @@ -1457,6 +1512,7 @@ } else { XOTclObject *object = (XOTclObject *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclObjInfoParentMethod(interp, object); } @@ -1475,6 +1531,7 @@ XOTclObject *object = (XOTclObject *)pc.clientData[0]; char *methodName = (char *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclObjInfoPostMethod(interp, object, methodName); } @@ -1493,6 +1550,7 @@ XOTclObject *object = (XOTclObject *)pc.clientData[0]; char *methodName = (char *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclObjInfoPreMethod(interp, object, methodName); } @@ -1512,6 +1570,7 @@ int withIntrinsic = (int )pc.clientData[1]; char *pattern = (char *)pc.clientData[2]; + parseContextRelease(&pc); return XOTclObjInfoPrecedenceMethod(interp, object, withIntrinsic, pattern); } @@ -1530,6 +1589,7 @@ XOTclObject *object = (XOTclObject *)pc.clientData[0]; char *pattern = (char *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclObjInfoProcsMethod(interp, object, pattern); } @@ -1548,6 +1608,7 @@ XOTclObject *object = (XOTclObject *)pc.clientData[0]; char *pattern = (char *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclObjInfoSlotObjectsMethod(interp, object, pattern); } @@ -1566,6 +1627,7 @@ XOTclObject *object = (XOTclObject *)pc.clientData[0]; char *pattern = (char *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclObjInfoVarsMethod(interp, object, pattern); } @@ -1586,6 +1648,7 @@ int withReset = (int )pc.clientData[1]; Tcl_Obj *name = (Tcl_Obj *)pc.clientData[2]; + parseContextRelease(&pc); return XOTclOAutonameMethod(interp, obj, withInstance, withReset, name); } @@ -1604,6 +1667,7 @@ } else { Tcl_Obj *flag = (Tcl_Obj *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclOCheckMethod(interp, obj, flag); } @@ -1622,6 +1686,7 @@ } else { + parseContextRelease(&pc); return XOTclOCleanupMethod(interp, obj); } @@ -1640,6 +1705,7 @@ } else { + parseContextRelease(&pc); return XOTclOConfigureMethod(interp, obj, objc, objv); } @@ -1658,6 +1724,7 @@ } else { + parseContextRelease(&pc); return XOTclODestroyMethod(interp, obj); } @@ -1676,6 +1743,7 @@ } else { char *var = (char *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclOExistsMethod(interp, obj, var); } @@ -1695,6 +1763,7 @@ char *filter = (char *)pc.clientData[0]; Tcl_Obj *guard = (Tcl_Obj *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclOFilterGuardMethod(interp, obj, filter, guard); } @@ -1713,6 +1782,7 @@ } else { char *filter = (char *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclOFilterSearchMethod(interp, obj, filter); } @@ -1738,6 +1808,7 @@ int withVerbose = (int )pc.clientData[6]; Tcl_Obj *target = (Tcl_Obj *)pc.clientData[7]; + parseContextRelease(&pc); return XOTclOForwardMethod(interp, obj, method, withDefault, withEarlybinding, withMethodprefix, withObjscope, withOnerror, withVerbose, target, objc-pc.lastobjc, objv+pc.lastobjc); } @@ -1756,6 +1827,7 @@ } else { + parseContextRelease(&pc); return XOTclOInstVarMethod(interp, obj, objc, objv); } @@ -1774,6 +1846,7 @@ } else { Tcl_Obj *invariantlist = (Tcl_Obj *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclOInvariantsMethod(interp, obj, invariantlist); } @@ -1792,6 +1865,7 @@ } else { Tcl_Obj *class = (Tcl_Obj *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclOIsClassMethod(interp, obj, class); } @@ -1810,6 +1884,7 @@ } else { Tcl_Obj *metaclass = (Tcl_Obj *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclOIsMetaClassMethod(interp, obj, metaclass); } @@ -1828,6 +1903,7 @@ } else { Tcl_Obj *class = (Tcl_Obj *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclOIsMixinMethod(interp, obj, class); } @@ -1846,6 +1922,7 @@ } else { Tcl_Obj *object = (Tcl_Obj *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclOIsObjectMethod(interp, obj, object); } @@ -1864,6 +1941,7 @@ } else { Tcl_Obj *class = (Tcl_Obj *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclOIsTypeMethod(interp, obj, class); } @@ -1883,6 +1961,7 @@ char *mixin = (char *)pc.clientData[0]; Tcl_Obj *guard = (Tcl_Obj *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclOMixinGuardMethod(interp, obj, mixin, guard); } @@ -1901,6 +1980,7 @@ } else { + parseContextRelease(&pc); return XOTclONextMethod(interp, obj, objc, objv); } @@ -1919,6 +1999,7 @@ } else { + parseContextRelease(&pc); return XOTclONoinitMethod(interp, obj); } @@ -1937,6 +2018,7 @@ } else { char *name = (char *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclOParametercmdMethod(interp, obj, name); } @@ -1959,6 +2041,7 @@ Tcl_Obj *precondition = (Tcl_Obj *)pc.clientData[3]; Tcl_Obj *postcondition = (Tcl_Obj *)pc.clientData[4]; + parseContextRelease(&pc); return XOTclOProcMethod(interp, obj, name, args, body, precondition, postcondition); } @@ -1977,6 +2060,7 @@ } else { char *name = (char *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclOProcSearchMethod(interp, obj, name); } @@ -1995,6 +2079,7 @@ } else { + parseContextRelease(&pc); return XOTclORequireNamespaceMethod(interp, obj); } @@ -2014,6 +2099,7 @@ Tcl_Obj *var = (Tcl_Obj *)pc.clientData[0]; Tcl_Obj *value = (Tcl_Obj *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclOSetMethod(interp, obj, var, value); } @@ -2032,6 +2118,7 @@ } else { + parseContextRelease(&pc); return XOTclOSetvaluesMethod(interp, obj, objc, objv); } @@ -2050,6 +2137,7 @@ } else { + parseContextRelease(&pc); return XOTclOUplevelMethod(interp, obj, objc, objv); } @@ -2068,6 +2156,7 @@ } else { + parseContextRelease(&pc); return XOTclOUpvarMethod(interp, obj, objc, objv); } @@ -2086,6 +2175,7 @@ } else { + parseContextRelease(&pc); return XOTclOVolatileMethod(interp, obj); } @@ -2104,6 +2194,7 @@ } else { char *varname = (char *)pc.clientData[0]; + parseContextRelease(&pc); return XOTclOVwaitMethod(interp, obj, varname); } @@ -2126,6 +2217,7 @@ int withProtected = (int )pc.clientData[4]; Tcl_Obj *cmdName = (Tcl_Obj *)pc.clientData[5]; + parseContextRelease(&pc); return XOTclAliasCmd(interp, object, methodName, withObjscope, withPer_object, withProtected, cmdName); } @@ -2144,6 +2236,7 @@ int configureoption = (int )pc.clientData[0]; Tcl_Obj *value = (Tcl_Obj *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclConfigureCmd(interp, configureoption, value); } @@ -2165,6 +2258,7 @@ int methodproperty = (int )pc.clientData[3]; Tcl_Obj *value = (Tcl_Obj *)pc.clientData[4]; + parseContextRelease(&pc); return XOTclMethodPropertyCmd(interp, object, methodName, withPer_object, methodproperty, value); } @@ -2183,6 +2277,7 @@ int withLocal = (int )pc.clientData[0]; Tcl_Obj *method = (Tcl_Obj *)pc.clientData[1]; + parseContextRelease(&pc); return XOTclMyCmd(interp, withLocal, method, objc-pc.lastobjc, objv+pc.lastobjc); } @@ -2202,6 +2297,7 @@ int relationtype = (int )pc.clientData[1]; Tcl_Obj *value = (Tcl_Obj *)pc.clientData[2]; + parseContextRelease(&pc); return XOTclRelationCmd(interp, object, relationtype, value); } @@ -2221,6 +2317,7 @@ Tcl_Obj *variable = (Tcl_Obj *)pc.clientData[1]; Tcl_Obj *value = (Tcl_Obj *)pc.clientData[2]; + parseContextRelease(&pc); return XOTclSetInstvarCmd(interp, object, variable, value); } Index: generic/xotcl.c =================================================================== diff -u -r44b916888bf0d89743347039b35ede09e7d9b945 -r0681f4a21fef723a8d6f5a4da698e5b70189765d --- generic/xotcl.c (.../xotcl.c) (revision 44b916888bf0d89743347039b35ede09e7d9b945) +++ generic/xotcl.c (.../xotcl.c) (revision 0681f4a21fef723a8d6f5a4da698e5b70189765d) @@ -149,30 +149,43 @@ ClientData clientData; } aliasCmdClientData; -#define PARSE_CONTEXT_PREALLOC 15 +#define PARSE_CONTEXT_PREALLOC 10 typedef struct { ClientData *clientData; Tcl_Obj **objv; Tcl_Obj **full_objv; - ClientData clientData_[PARSE_CONTEXT_PREALLOC]; - Tcl_Obj *objv_[PARSE_CONTEXT_PREALLOC+1]; + ClientData clientData_static[PARSE_CONTEXT_PREALLOC]; + Tcl_Obj *objv_static[PARSE_CONTEXT_PREALLOC+1]; int lastobjc; int objc; } parseContext; void parseContextInit(parseContext *pc, int objc, Tcl_Obj *procName) { if (objc < PARSE_CONTEXT_PREALLOC) { + /* the single larger memset below .... */ memset(pc, 0, sizeof(parseContext)); - pc->objv = &pc->objv_[1]; - pc->full_objv = &pc->objv_[0]; - pc->clientData = &pc->clientData_[0]; - /*memset(pc->clientData, 0, sizeof(ClientData)*(objc)); - memset(pc->objv+1, 0, sizeof(Tcl_Obj*)*(objc));*/ - pc->objv_[0] = procName; + /* ... is faster than the two smaller memsets below */ + /* memset(pc->clientData_static, 0, sizeof(ClientData)*(objc)); + memset(pc->objv_static, 0, sizeof(Tcl_Obj*)*(objc+1));*/ + pc->full_objv = &pc->objv_static[0]; + pc->clientData = &pc->clientData_static[0]; } else { - Tcl_Panic("objc to large, not implemented", NULL); + pc->full_objv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj*)*(objc+1)); + pc->clientData = (ClientData*)ckalloc(sizeof(ClientData)*objc); + /*fprintf(stderr,"ParseContextMalloc %d objc, %p %p\n",objc,pc->full_objv,pc->clientData);*/ + memset(pc->full_objv, 0, sizeof(Tcl_Obj*)*(objc+1)); + memset(pc->clientData, 0, sizeof(ClientData)*(objc)); } + pc->objv = &pc->full_objv[1]; + pc->full_objv[0] = procName; } +void parseContextRelease(parseContext *pc) { + if (pc->objv != &pc->objv_static[1]) { + /*fprintf(stderr,"release free %p %p\n",pc->full_objv,pc->clientData);*/ + ckfree((char *)pc->full_objv); + ckfree((char *)pc->clientData); + } +} typedef argDefinition interfaceDefinition[10]; @@ -2154,10 +2167,10 @@ XOTclAddPMethod(Tcl_Interp *interp, XOTcl_Object *object, CONST char *methodName, Tcl_ObjCmdProc *proc, ClientData clientData, Tcl_CmdDeleteProc *dp) { int flags = 0; - if (clientData == (ClientData) XOTCL_NONLEAF_METHOD) { - fprintf(stderr, "XOTclAddPMethod(,,,, XOTCL_NONLEAF_METHOD,) deprecated.\n" - "Use XOTclAddObjectMethod(,,,,,, XOTCL_NONLEAF_METHOD) instead.\n"); - flags = XOTCL_NONLEAF_METHOD; + if (clientData == (ClientData) XOTCL_CMD_NONLEAF_METHOD) { + fprintf(stderr, "XOTclAddPMethod(,,,, XOTCL_CMD_NONLEAF_METHOD,) deprecated.\n" + "Use XOTclAddObjectMethod(,,,,,, XOTCL_CMD_NONLEAF_METHOD) instead.\n"); + flags = XOTCL_CMD_NONLEAF_METHOD; clientData = NULL; } return XOTclAddObjectMethod(interp, object, methodName, proc, clientData, dp, flags); @@ -2184,10 +2197,10 @@ XOTclAddIMethod(Tcl_Interp *interp, XOTcl_Class *class, CONST char *methodName, Tcl_ObjCmdProc *proc, ClientData clientData, Tcl_CmdDeleteProc *dp) { int flags = 0; - if (clientData == (ClientData) XOTCL_NONLEAF_METHOD) { - fprintf(stderr, "XOTclAddIMethod(,,,, XOTCL_NONLEAF_METHOD,) deprecated.\n" - "Use XOTclAddInstanceMethod(,,,,,, XOTCL_NONLEAF_METHOD) instead.\n"); - flags = XOTCL_NONLEAF_METHOD; + if (clientData == (ClientData) XOTCL_CMD_NONLEAF_METHOD) { + fprintf(stderr, "XOTclAddIMethod(,,,, XOTCL_CMD_NONLEAF_METHOD,) deprecated.\n" + "Use XOTclAddInstanceMethod(,,,,,, XOTCL_CMD_NONLEAF_METHOD) instead.\n"); + flags = XOTCL_CMD_NONLEAF_METHOD; clientData = NULL; } return XOTclAddInstanceMethod(interp, class, methodName, proc, clientData, dp, flags); @@ -5436,12 +5449,25 @@ /*fprintf(stderr,"\tproc=%s cp=%p %d\n", Tcl_GetCommandName(interp, cmd),cp, isTclProc);*/ # if defined(CANONICAL_ARGS) + /* + If the method to be invoked hasnonposArgs, we have to call the + argument parser with the argument definitions. The argument + definitions are looked up in canonicalNonpositionalArgs via a + hash table, which causes a per-proc overhead. It would be + certainly nicer and more efficient to store both the argument + definitions in the Tcl Proc structure, which has unfortunately + no clientData. + + If would be already nice if the Proc structure would contain a + "flags" variable, where we could check, whether nonposArgs are + provided. This would make method invocations as efficient as + without nonposArgs. + + */ { parseContext pc; - int rc; + int rc = canonicalNonpositionalArgs(&pc, interp, objc, objv); - rc = canonicalNonpositionalArgs(&pc, interp, objc, objv); - if (rc == TCL_CONTINUE) { result = PushProcCallFrame(cp, interp, objc, objv, /*isLambda*/ 0); } else { @@ -5454,7 +5480,7 @@ #endif result = PushProcCallFrame(cp, interp, pc.objc+1, pc.full_objv, /*isLambda*/ 0); } - } + } # else result = PushProcCallFrame(cp, interp, objc, objv, /*isLambda*/ 0); #endif @@ -5539,7 +5565,7 @@ tclCmdClientData *tcd = (tclCmdClientData *)cp; tcd->obj = obj; assert((TclIsProc((Command *)cmd) == NULL)); - } else if (cp == (ClientData)XOTCL_NONLEAF_METHOD) { + } else if (cp == (ClientData)XOTCL_CMD_NONLEAF_METHOD) { cp = clientData; assert((TclIsProc((Command *)cmd) == NULL)); } @@ -5693,7 +5719,7 @@ protected method, called on a different object. In this case, we call as well the unknown method */ - if ((Tcl_Command_flags(cmd) & XOTCL_PROTECTED_METHOD) && + if ((Tcl_Command_flags(cmd) & XOTCL_CMD_PROTECTED_METHOD) && (flags & XOTCL_CM_NO_UNKNOWN) == 0) { XOTclCallStackContent *csc = CallStackGetTopFrame(interp); XOTclObject *o = NULL; @@ -6247,6 +6273,7 @@ nonposArg = (XOTclNonposArgs*)ckalloc(sizeof(XOTclNonposArgs)); nonposArg->slotObj = NULL; nonposArg->ifd = interface; + /*fprintf(stderr, "ifsize = %d\n",ifPtr-interface);*/ *parsedIfPtr = interface; /* TODO only for CANONICAL_ARGS */ @@ -9748,7 +9775,7 @@ } } - if (((Command *) cmd)->flags & XOTCL_PROTECTED_METHOD) { + if (((Command *) cmd)->flags & XOTCL_CMD_PROTECTED_METHOD) { /*fprintf(stderr, "--- dont list protected name '%s'\n", key);*/ continue; } @@ -10073,7 +10100,7 @@ } if (withProtected) { - flags = XOTCL_PROTECTED_METHOD; + flags = XOTCL_CMD_PROTECTED_METHOD; } if (allocation == 'c') { @@ -10155,9 +10182,9 @@ protected = (methodproperty == methodpropertyProtectedIdx); if (protected) { - Tcl_Command_flags(cmd) |= XOTCL_PROTECTED_METHOD; + Tcl_Command_flags(cmd) |= XOTCL_CMD_PROTECTED_METHOD; } else { - Tcl_Command_flags(cmd) &= XOTCL_PROTECTED_METHOD; + Tcl_Command_flags(cmd) &= XOTCL_CMD_PROTECTED_METHOD; } } else { /* slotobj */ Tcl_HashTable **nonposArgsTable = allocation == 'o' ? @@ -12188,7 +12215,7 @@ ClientData clientData; if (objProc) { clientData = Tcl_Command_objClientData(cmd); - if (clientData == NULL || clientData == (ClientData)XOTCL_NONLEAF_METHOD) { + if (clientData == NULL || clientData == (ClientData)XOTCL_CMD_NONLEAF_METHOD) { /* if client data not null, we would have to copy the client data; we don't know its size...., so rely on introspection for copying */ @@ -12197,7 +12224,7 @@ } } else { clientData = Tcl_Command_clientData(cmd); - if (clientData == NULL || clientData == (ClientData)XOTCL_NONLEAF_METHOD) { + if (clientData == NULL || clientData == (ClientData)XOTCL_CMD_NONLEAF_METHOD) { Tcl_CreateCommand(interp, newName, Tcl_Command_proc(cmd), Tcl_Command_clientData(cmd), deleteProc); } @@ -12401,8 +12428,10 @@ /* ifdSize is per construction the same as objc */ rc = parseObjv(interp, objc, objv, objv[0], nonposArgs->ifd, objc, pcPtr); - if (rc != TCL_OK) + if (rc != TCL_OK) { + parseContextRelease(pcPtr); return rc; + } for (aPtr = nonposArgs->ifd, i=0; aPtr->name; aPtr++, i++) { char *argName = aPtr->name; @@ -12427,6 +12456,7 @@ /* TODO: default value is not jet checked; should be in arg parsing */ /*fprintf(stderr,"=== setting default value '%s' for var '%s'\n",ObjStr(aPtr->defaultValue),argName);*/ } else if (aPtr->required) { + parseContextRelease(pcPtr); return XOTclVarErrMsg(interp, "method ",procName, ": required argument '", argName, "' is missing", (char *) NULL); } else { @@ -12447,7 +12477,7 @@ } else { /* Tcl_UnsetVar2(interp, "args", NULL, 0); */ } - + parseContextRelease(pcPtr); return TCL_OK; } @@ -12476,8 +12506,10 @@ rc = parseObjv(interp, objc, objv, proc, nonposArgs->ifd, objc, &pc); DECR_REF_COUNT(proc); - if (rc != TCL_OK) + if (rc != TCL_OK) { + parseContextRelease(pcPtr); return rc; + } for (aPtr = nonposArgs->ifd, i=0; aPtr->name; aPtr++, i++) { char *argName = aPtr->name; @@ -12506,6 +12538,7 @@ /*fprintf(stderr,"=== setting default value '%s' for var '%s'\n",ObjStr(aPtr->defaultValue),argName);*/ Tcl_SetVar2Ex(interp, argName, NULL, aPtr->defaultValue, 0); } else if (aPtr->required) { + parseContextRelease(pcPtr); return XOTclVarErrMsg(interp, "method ",procName, ": required argument '", argName, "' is missing", (char *) NULL); } @@ -12521,7 +12554,7 @@ } else { Tcl_UnsetVar2(interp, "args", NULL, 0); } - + parseContextRelease(pcPtr); return TCL_OK; } #endif Index: generic/xotcl.h =================================================================== diff -u -r44b916888bf0d89743347039b35ede09e7d9b945 -r0681f4a21fef723a8d6f5a4da698e5b70189765d --- generic/xotcl.h (.../xotcl.h) (revision 44b916888bf0d89743347039b35ede09e7d9b945) +++ generic/xotcl.h (.../xotcl.h) (revision 0681f4a21fef723a8d6f5a4da698e5b70189765d) @@ -129,10 +129,10 @@ # endif #endif -#define XOTCL_PROTECTED_METHOD 0x00010000 -#define XOTCL_NONLEAF_METHOD 0x00020000 +#define XOTCL_CMD_PROTECTED_METHOD 0x00010000 +/* XOTCL_CMD_NONLEAF_METHOD is used to flag, if a Method implemented via cmd calls "next" */ +#define XOTCL_CMD_NONLEAF_METHOD 0x00020000 - /* * A special definition used to allow this header file to be included * in resource files so that they can get obtain version information from