Index: generic/xotcl.c =================================================================== diff -u -rd4e66214fc3323aea509676709c9b7ace64f0f50 -ra092bf2730f286db304743019da69e5ecd84eba2 --- generic/xotcl.c (.../xotcl.c) (revision d4e66214fc3323aea509676709c9b7ace64f0f50) +++ generic/xotcl.c (.../xotcl.c) (revision a092bf2730f286db304743019da69e5ecd84eba2) @@ -1535,14 +1535,21 @@ } /* Case 3: Does the variable exist in the per-object namespace? */ + +#if 0 && defined(USE_COMPILED_VAR_RESOLVER) + /* strip of a leading "." */ + if (*name == '.') { + name++; + } +#endif + *varPtr = (Tcl_Var)LookupVarFromTable(Tcl_Namespace_varTable(nsPtr), name, NULL); if (*varPtr == NULL) { /* We failed to find the variable so far, therefore we create it * here in the namespace. Note that the cases (1), (2) and (3) * TCL_CONTINUE care for variable creation if necessary. */ - key = Tcl_NewStringObj(name, -1); INCR_REF_COUNT(key); @@ -1557,6 +1564,58 @@ return *varPtr ? TCL_OK : TCL_ERROR; } +#if defined(USE_COMPILED_VAR_RESOLVER) +typedef struct xotclResolvedVarInfo { + Tcl_ResolvedVarInfo vInfo; /* This must be the first element. */ + char buffer[64]; /* for now */ +} xotclResolvedVarInfo; + +static Tcl_Var +xotclObjectVarResolver(Tcl_Interp *interp, xotclResolvedVarInfo *resVarInfo) { + XOTclObject *obj = GetSelfObj(interp); + TclVarHashTable *varTable = obj->nsPtr ? Tcl_Namespace_varTable(obj->nsPtr) : obj->varTable; + Tcl_Var var; + int new; + + /*fprintf(stderr, "Object Var Resolver, name=%s, obj %p, nsPtr %p\n",resVarInfo->buffer, obj, obj->nsPtr);*/ + var = (Tcl_Var)LookupVarFromTable(varTable, resVarInfo->buffer, NULL); + + if (var == NULL) { + /* We failed to find the variable so far, therefore we create it + * here in the namespace. Note that the cases (1), (2) and (3) + * TCL_CONTINUE care for variable creation if necessary. + */ + Tcl_Obj *key = Tcl_NewStringObj(resVarInfo->buffer, -1); + /*fprintf(stderr, "create %s in ns\n", resVarInfo->buffer);*/ + + INCR_REF_COUNT(key); + var = (Tcl_Var)VarHashCreateVar(varTable, key, &new); + DECR_REF_COUNT(key); + } + return var; +} + +int compiledVarResolver(Tcl_Interp *interp, + CONST84 char *name, int length, Tcl_Namespace *context, + Tcl_ResolvedVarInfo **rPtr) { + /* getting the self object is a weak protection against handling of wrong vars */ + XOTclObject *obj = GetSelfObj(interp); + /*fprintf(stderr, "compiled var resolver for %s, obj %p\n", name, obj);*/ + + if (obj && *name == '.') { + xotclResolvedVarInfo *vInfoPtr = (xotclResolvedVarInfo *) ckalloc(sizeof(xotclResolvedVarInfo)); + vInfoPtr->vInfo.fetchProc = xotclObjectVarResolver; + vInfoPtr->vInfo.deleteProc = NULL; + memcpy(vInfoPtr->buffer,name+1,length-1); + vInfoPtr->buffer[length-1] = 0; + *rPtr = (Tcl_ResolvedVarInfo *)vInfoPtr; + /*fprintf(stderr, ".... allocated %p\n", *rPtr);*/ + return TCL_OK; + } + return TCL_CONTINUE; +} +#endif + static Tcl_Namespace * requireObjNamespace(Tcl_Interp *interp, XOTclObject *obj) { if (!obj->nsPtr) makeObjNamespace(interp, obj); @@ -1566,7 +1625,7 @@ * and object-only ones (set, unset, ...) */ Tcl_SetNamespaceResolvers(obj->nsPtr, (Tcl_ResolveCmdProc*)NULL, - varResolver, (Tcl_ResolveCompiledVarProc*)NULL); + varResolver, /*(Tcl_ResolveCompiledVarProc*)compiledVarResolver*/NULL); return obj->nsPtr; } @@ -12720,7 +12779,16 @@ Tcl_SetVar(interp, "::xotcl::version", XOTCLVERSION, TCL_GLOBAL_ONLY); Tcl_SetVar(interp, "::xotcl::patchlevel", XOTCLPATCHLEVEL, TCL_GLOBAL_ONLY); +#if defined(USE_COMPILED_VAR_RESOLVER) /* + Tcl_SetNamespaceResolvers(Tcl_FindNamespace(interp, "::xotcl", NULL, 0), (Tcl_ResolveCmdProc*)NULL, + varResolver, (Tcl_ResolveCompiledVarProc*)compiledVarResolver); + */ + Tcl_AddInterpResolvers(interp,"xotcl", (Tcl_ResolveCmdProc*)NULL, + NULL, (Tcl_ResolveCompiledVarProc*)compiledVarResolver); +#endif + + /* * with some methods and library procs in tcl - they could go in a * xotcl.tcl file, but they're embedded here with Tcl_GlobalEval * to avoid the need to carry around a separate file at runtime.