Diff
Not logged in

Differences From Artifact [13663a1205]:

To Artifact [a3cbb23ea4]:


49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
static int		SetLambdaFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static int              ProcEatArgs(Tcl_Interp *interp,CallFrame *framePtr,Tcl_Obj *argspec,Tcl_Obj *values);

static Tcl_NRPostProc ApplyNR2;
static Tcl_NRPostProc InterpProcNR2;
static Tcl_NRPostProc Uplevel_Callback;

#undef TIP_479_AS_COMPILED_LOCALS 1
/*
 * The ProcBodyObjType type
 */

const Tcl_ObjType tclProcBodyType = {
    "procbody",			/* name for this type */
    ProcBodyFree,		/* FreeInternalRep function */







<







49
50
51
52
53
54
55

56
57
58
59
60
61
62
static int		SetLambdaFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static int              ProcEatArgs(Tcl_Interp *interp,CallFrame *framePtr,Tcl_Obj *argspec,Tcl_Obj *values);

static Tcl_NRPostProc ApplyNR2;
static Tcl_NRPostProc InterpProcNR2;
static Tcl_NRPostProc Uplevel_Callback;


/*
 * The ProcBodyObjType type
 */

const Tcl_ObjType tclProcBodyType = {
    "procbody",			/* name for this type */
    ProcBodyFree,		/* FreeInternalRep function */
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
    TclVarHashTable *tablePtr,
    Tcl_Obj *key,
    int *newPtr)
{
    Tcl_HashEntry *hPtr = Tcl_CreateHashEntry(&tablePtr->table, key, newPtr);

    if (hPtr) {
        /* printf(" CREATED %s\n",Tcl_GetString(key)); */
	return VarHashGetValue(hPtr);
    } else {
	return NULL;
    }
}

void ProcSetLocalVar (
    CallFrame *framePtr,
    Tcl_Obj *varNamePtr, 	/* Scaler name */
    Tcl_Obj *valuePtr           /* Value to set */
) {
    int i, varLen, idx, isNew;
    const char *varName = TclGetStringFromObj(varNamePtr, &varLen);
    int localLen, localCt = framePtr->numCompiledLocals;
    Tcl_Obj **objPtrPtr = &framePtr->localCachePtr->varName0;
    const char *localNameStr;
    TclVarHashTable *tablePtr;	/* Points to the hashtable, if any, in which
				 * to look up the variable. */
    Var *varPtr;		/* Points to the Var structure returned for
				 * the variable. */

    varPtr = NULL;
    idx=-1;
    isNew=-1;
#ifdef TIP_479_AS_COMPILED_LOCALS
    for (i=0 ; i<localCt ; i++, objPtrPtr++) {
	register Tcl_Obj *objPtr = *objPtrPtr;

	if (objPtr) {
	    localNameStr = TclGetStringFromObj(objPtr, &localLen);
	    /* printf("Compiled Local %s %d len: %d\n",localNameStr,i, localLen); fflush(stdout); */
	    if ((varLen == localLen) && (varName[0] == localNameStr[0])
			&& !memcmp(varName, localNameStr, varLen)) {
		idx=i;
		/* printf("Compiled Locals Match %s %d\n",varName,i); fflush(stdout); */
		varPtr=(Var *) &framePtr->compiledLocals[i];
		break;
	    }
	}
    }
#endif
    if(!varPtr) {
        tablePtr = framePtr->varTablePtr;

        if (tablePtr == NULL) {
            tablePtr = ckalloc(sizeof(TclVarHashTable));
            TclInitVarHashTable(tablePtr, NULL);
            framePtr->varTablePtr = tablePtr;
            //printf("Created varTablePtr\n");
        }
        varPtr = VarHashCreateVar(tablePtr, varNamePtr, &isNew);
    }
    varPtr->flags=VAR_ARGUMENT;
    varPtr->value.objPtr=valuePtr;
    Tcl_IncrRefCount(valuePtr);
    /*
    printf("Wrote value for %s = %s %d %d %p\n",
       Tcl_GetString(varNamePtr),Tcl_GetString(valuePtr),idx,isNew,varPtr);
    */
}

int ProcEatArgs(
    Tcl_Interp *interp,
    CallFrame *framePtr,
    Tcl_Obj *argspec,
    Tcl_Obj *argsValuePtr







<




















<



<





<



<





<


<




<






<
<
<
<







148
149
150
151
152
153
154

155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174

175
176
177

178
179
180
181
182

183
184
185

186
187
188
189
190

191
192

193
194
195
196

197
198
199
200
201
202




203
204
205
206
207
208
209
    TclVarHashTable *tablePtr,
    Tcl_Obj *key,
    int *newPtr)
{
    Tcl_HashEntry *hPtr = Tcl_CreateHashEntry(&tablePtr->table, key, newPtr);

    if (hPtr) {

	return VarHashGetValue(hPtr);
    } else {
	return NULL;
    }
}

void ProcSetLocalVar (
    CallFrame *framePtr,
    Tcl_Obj *varNamePtr, 	/* Scaler name */
    Tcl_Obj *valuePtr           /* Value to set */
) {
    int i, varLen, idx, isNew;
    const char *varName = TclGetStringFromObj(varNamePtr, &varLen);
    int localLen, localCt = framePtr->numCompiledLocals;
    Tcl_Obj **objPtrPtr = &framePtr->localCachePtr->varName0;
    const char *localNameStr;
    TclVarHashTable *tablePtr;	/* Points to the hashtable, if any, in which
				 * to look up the variable. */
    Var *varPtr;		/* Points to the Var structure returned for
				 * the variable. */

    varPtr = NULL;
    idx=-1;
    isNew=-1;

    for (i=0 ; i<localCt ; i++, objPtrPtr++) {
	register Tcl_Obj *objPtr = *objPtrPtr;

	if (objPtr) {
	    localNameStr = TclGetStringFromObj(objPtr, &localLen);

	    if ((varLen == localLen) && (varName[0] == localNameStr[0])
			&& !memcmp(varName, localNameStr, varLen)) {
		idx=i;

		varPtr=(Var *) &framePtr->compiledLocals[i];
		break;
	    }
	}
    }

    if(!varPtr) {
        tablePtr = framePtr->varTablePtr;

        if (tablePtr == NULL) {
            tablePtr = ckalloc(sizeof(TclVarHashTable));
            TclInitVarHashTable(tablePtr, NULL);
            framePtr->varTablePtr = tablePtr;

        }
        varPtr = VarHashCreateVar(tablePtr, varNamePtr, &isNew);
    }
    varPtr->flags=VAR_ARGUMENT;
    varPtr->value.objPtr=valuePtr;
    Tcl_IncrRefCount(valuePtr);




}

int ProcEatArgs(
    Tcl_Interp *interp,
    CallFrame *framePtr,
    Tcl_Obj *argspec,
    Tcl_Obj *argsValuePtr
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
            continue;
        }
        if(Tcl_DictObjGet(interp,fieldspec,obj_const_mandatory,&mandatoryObj)!=TCL_OK) return TCL_ERROR;
        if(mandatoryObj) {
            if(Tcl_GetBooleanFromObj(interp,mandatoryObj,&mandatory)) return TCL_ERROR;
        }
        if(mandatory) {
            printf("Did not find %s\n",Tcl_GetString(fieldname));
            Tcl_AppendResult(interp,"Error: ", Tcl_GetString(fieldname), " is required", (char *)NULL);
            return TCL_ERROR;
        }
    }
    fflush(stdout);
    Tcl_DictObjDone(&search);
    return TCL_OK;
}

int Tcl_AtArgsObjCmd(
    ClientData clientData,
    Tcl_Interp *interp,







<




<







252
253
254
255
256
257
258

259
260
261
262

263
264
265
266
267
268
269
            continue;
        }
        if(Tcl_DictObjGet(interp,fieldspec,obj_const_mandatory,&mandatoryObj)!=TCL_OK) return TCL_ERROR;
        if(mandatoryObj) {
            if(Tcl_GetBooleanFromObj(interp,mandatoryObj,&mandatory)) return TCL_ERROR;
        }
        if(mandatory) {

            Tcl_AppendResult(interp,"Error: ", Tcl_GetString(fieldname), " is required", (char *)NULL);
            return TCL_ERROR;
        }
    }

    Tcl_DictObjDone(&search);
    return TCL_OK;
}

int Tcl_AtArgsObjCmd(
    ClientData clientData,
    Tcl_Interp *interp,
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
	    }
	    memcpy(localPtr->name, fieldValues[0], nameLength + 1);
	    if ((i == numArgs - 1)
		    && (localPtr->nameLength == 4)
		    && (localPtr->name[0] == 'a')
		    && (strcmp(localPtr->name, "args") == 0)) {
		localPtr->flags |= VAR_IS_ARGS;
#ifdef TIP_479_AS_COMPILED_LOCALS
		if(fieldCount == 2) {
		    /*
		    ** TIP 479
		    ** Use the otherwise ignored default field for the last
		    ** parameter named args as a dict-based specification for
		    ** named parameters
		    */







<







888
889
890
891
892
893
894

895
896
897
898
899
900
901
	    }
	    memcpy(localPtr->name, fieldValues[0], nameLength + 1);
	    if ((i == numArgs - 1)
		    && (localPtr->nameLength == 4)
		    && (localPtr->name[0] == 'a')
		    && (strcmp(localPtr->name, "args") == 0)) {
		localPtr->flags |= VAR_IS_ARGS;

		if(fieldCount == 2) {
		    /*
		    ** TIP 479
		    ** Use the otherwise ignored default field for the last
		    ** parameter named args as a dict-based specification for
		    ** named parameters
		    */
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
                    localPtr->nextPtr = NULL;
                    localPtr->nameLength = FieldLen;
                    localPtr->frameIndex = i;
	            localPtr->flags = VAR_ARGUMENT;
                    localPtr->resolveInfo = NULL;
		    localPtr->defValuePtr = argspec;
		    Tcl_IncrRefCount(localPtr->defValuePtr);
                    printf("named parameter %s # %d %d\n",Fieldname,procPtr->numCompiledLocals,localPtr->flags);

                    for (; !done ; Tcl_DictObjNext(&search, &fieldname, &fieldspec, &done)) {
                        /* Allocate one slot for each of the other named parameters */
                        Tcl_Obj *variable,*defaultObj,*mandatoryObj;
                        int mandatory=1;

                        variable=NULL;
                        defaultObj=NULL;







<
<







923
924
925
926
927
928
929


930
931
932
933
934
935
936
                    localPtr->nextPtr = NULL;
                    localPtr->nameLength = FieldLen;
                    localPtr->frameIndex = i;
	            localPtr->flags = VAR_ARGUMENT;
                    localPtr->resolveInfo = NULL;
		    localPtr->defValuePtr = argspec;
		    Tcl_IncrRefCount(localPtr->defValuePtr);


                    for (; !done ; Tcl_DictObjNext(&search, &fieldname, &fieldspec, &done)) {
                        /* Allocate one slot for each of the other named parameters */
                        Tcl_Obj *variable,*defaultObj,*mandatoryObj;
                        int mandatory=1;

                        variable=NULL;
                        defaultObj=NULL;
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
        	        procPtr->lastLocalPtr->nextPtr = localPtr;
 		        procPtr->lastLocalPtr = localPtr;
 		     	memcpy(localPtr->name, Fieldname, FieldLen + 1);
                        localPtr->nextPtr = NULL;
                        localPtr->nameLength = FieldLen;
                        localPtr->frameIndex = i;
	                localPtr->flags = VAR_ARGUMENT;
                        printf("named parameter %s # %d %d\n",Fieldname,procPtr->numCompiledLocals,localPtr->flags);
                        localPtr->resolveInfo = NULL;
                        if(defaultObj) {
                            localPtr->defValuePtr=defaultObj;
                            Tcl_IncrRefCount(localPtr->defValuePtr);
                        } else {
                            localPtr->defValuePtr=NULL;
                        }
		    }
		}
#endif
	    }
	}
        fflush(stdout);
	ckfree(fieldValues);
    }

    *procPtrPtr = procPtr;
    ckfree(argArray);
    return TCL_OK;








<









<


<







955
956
957
958
959
960
961

962
963
964
965
966
967
968
969
970

971
972

973
974
975
976
977
978
979
        	        procPtr->lastLocalPtr->nextPtr = localPtr;
 		        procPtr->lastLocalPtr = localPtr;
 		     	memcpy(localPtr->name, Fieldname, FieldLen + 1);
                        localPtr->nextPtr = NULL;
                        localPtr->nameLength = FieldLen;
                        localPtr->frameIndex = i;
	                localPtr->flags = VAR_ARGUMENT;

                        localPtr->resolveInfo = NULL;
                        if(defaultObj) {
                            localPtr->defValuePtr=defaultObj;
                            Tcl_IncrRefCount(localPtr->defValuePtr);
                        } else {
                            localPtr->defValuePtr=NULL;
                        }
		    }
		}

	    }
	}

	ckfree(fieldValues);
    }

    *procPtrPtr = procPtr;
    ckfree(argArray);
    return TCL_OK;

1730
1731
1732
1733
1734
1735
1736

1737
1738
1739
1740
1741
1742
1743
{
    CallFrame *framePtr = ((Interp *)interp)->varFramePtr;
    register Proc *procPtr = framePtr->procPtr;
    ByteCode *codePtr = procPtr->bodyPtr->internalRep.twoPtrValue.ptr1;
    register Var *varPtr, *defPtr;
    int localCt = procPtr->numCompiledLocals, numArgs, argCt, i, imax;
    Tcl_Obj *const *argObjs;

    /*
     * Make sure that the local cache of variable names and initial values has
     * been initialised properly .
     */
    if (localCt) {
	if (!codePtr->localCachePtr) {
	    InitLocalCache(procPtr) ;







>







1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
{
    CallFrame *framePtr = ((Interp *)interp)->varFramePtr;
    register Proc *procPtr = framePtr->procPtr;
    ByteCode *codePtr = procPtr->bodyPtr->internalRep.twoPtrValue.ptr1;
    register Var *varPtr, *defPtr;
    int localCt = procPtr->numCompiledLocals, numArgs, argCt, i, imax;
    Tcl_Obj *const *argObjs;
    Tcl_Obj *argSpec=NULL,*argsValuePtr=NULL;
    /*
     * Make sure that the local cache of variable names and initial values has
     * been initialised properly .
     */
    if (localCt) {
	if (!codePtr->localCachePtr) {
	    InitLocalCache(procPtr) ;
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
    /*
     * When we get here, the last formal argument remains to be defined:
     * defPtr and varPtr point to the last argument to be initialized.
     */

    varPtr->flags = 0;
    if (defPtr && defPtr->flags & VAR_IS_ARGS) {
        Tcl_Obj *argsValuePtr;
        /*
        ** Build a conventional list of arguments
        ** past the last positional argument, and call it
        ** args
        */
        argsValuePtr = Tcl_NewListObj(argCt-i, argObjs+i);
        varPtr->value.objPtr = argsValuePtr;
	if (defPtr->value.objPtr) {
            /*
            ** TIP 479
            ** Feed dict values into compiled locals
            ** If a required parameter is missing ProcEatArgs
            ** will return TCL_ERROR.
            */
            if(ProcEatArgs(interp,framePtr,defPtr->value.objPtr,argsValuePtr)
               != TCL_OK) goto incorrectArgs;
        }
        Tcl_IncrRefCount(argsValuePtr);	/* Local var is a reference. */
    } else if (argCt == numArgs) {
	Tcl_Obj *objPtr = argObjs[i];

	varPtr->value.objPtr = objPtr;
	Tcl_IncrRefCount(objPtr);	/* Local var is a reference. */
    } else if ((argCt < numArgs) && defPtr && defPtr->value.objPtr) {







<







|
<
<
<
<
<
<
<
<
<







1788
1789
1790
1791
1792
1793
1794

1795
1796
1797
1798
1799
1800
1801
1802









1803
1804
1805
1806
1807
1808
1809
    /*
     * When we get here, the last formal argument remains to be defined:
     * defPtr and varPtr point to the last argument to be initialized.
     */

    varPtr->flags = 0;
    if (defPtr && defPtr->flags & VAR_IS_ARGS) {

        /*
        ** Build a conventional list of arguments
        ** past the last positional argument, and call it
        ** args
        */
        argsValuePtr = Tcl_NewListObj(argCt-i, argObjs+i);
        varPtr->value.objPtr = argsValuePtr;
        argSpec=defPtr->value.objPtr;









        Tcl_IncrRefCount(argsValuePtr);	/* Local var is a reference. */
    } else if (argCt == numArgs) {
	Tcl_Obj *objPtr = argObjs[i];

	varPtr->value.objPtr = objPtr;
	Tcl_IncrRefCount(objPtr);	/* Local var is a reference. */
    } else if ((argCt < numArgs) && defPtr && defPtr->value.objPtr) {
1856
1857
1858
1859
1860
1861
1862










1863
1864
1865
1866
1867
1868
1869
	if (!framePtr->nsPtr->compiledVarResProc
		&& !((Interp *)interp)->resolverPtr) {
	    memset(varPtr, 0, (localCt - numArgs)*sizeof(Var));
	} else {
	    InitResolvedLocals(interp, codePtr, varPtr, framePtr->nsPtr);
	}
    }










    return TCL_OK;

    /*
     * Initialise all compiled locals to avoid problems at DeleteLocalVars.
     */

  incorrectArgs:







>
>
>
>
>
>
>
>
>
>







1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
	if (!framePtr->nsPtr->compiledVarResProc
		&& !((Interp *)interp)->resolverPtr) {
	    memset(varPtr, 0, (localCt - numArgs)*sizeof(Var));
	} else {
	    InitResolvedLocals(interp, codePtr, varPtr, framePtr->nsPtr);
	}
    }
    if(argSpec) {
        /*
        ** TIP 479
        ** Feed dict values into compiled locals
        ** If a required parameter is missing ProcEatArgs
        ** will return TCL_ERROR.
        */
        if(ProcEatArgs(interp,framePtr,argSpec,argsValuePtr)
           != TCL_OK) goto incorrectArgs;
    }
    return TCL_OK;

    /*
     * Initialise all compiled locals to avoid problems at DeleteLocalVars.
     */

  incorrectArgs: