| ︙ | | | ︙ | |
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
* Copyright (c) 1994-1998 Sun Microsystems, Inc.
* Copyright (c) 2004-2006 Miguel Sofer
* Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: tclProc.c,v 1.46.2.38 2007/10/02 18:29:27 dgp Exp $
*/
#include "tclInt.h"
#include "tclCompile.h"
/*
* Prototypes for static functions in this file
|
|
|
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
* Copyright (c) 1994-1998 Sun Microsystems, Inc.
* Copyright (c) 2004-2006 Miguel Sofer
* Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: tclProc.c,v 1.46.2.39 2007/11/12 20:40:48 dgp Exp $
*/
#include "tclInt.h"
#include "tclCompile.h"
/*
* Prototypes for static functions in this file
|
| ︙ | | | ︙ | |
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
|
* means that the same code can not be shared by two procedures that
* have a different number of arguments, even if their bodies are
* identical. Note that we don't use Tcl_DuplicateObj since we would
* not want any bytecode internal representation.
*/
if (Tcl_IsShared(bodyPtr)) {
bytes = Tcl_GetStringFromObj(bodyPtr, &length);
bodyPtr = Tcl_NewStringObj(bytes, length);
}
/*
* Create and initialize a Proc structure for the procedure. We
* increment the ref count of the procedure's body object since there
* will be a reference to it in the Proc structure.
|
|
|
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
|
* means that the same code can not be shared by two procedures that
* have a different number of arguments, even if their bodies are
* identical. Note that we don't use Tcl_DuplicateObj since we would
* not want any bytecode internal representation.
*/
if (Tcl_IsShared(bodyPtr)) {
bytes = TclGetStringFromObj(bodyPtr, &length);
bodyPtr = Tcl_NewStringObj(bytes, length);
}
/*
* Create and initialize a Proc structure for the procedure. We
* increment the ref count of the procedure's body object since there
* will be a reference to it in the Proc structure.
|
| ︙ | | | ︙ | |
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
|
* argument specifier. If the body is precompiled, processing is limited
* to checking that the parsed argument is consistent with the one stored
* in the Proc.
*
* THIS FAILS IF THE ARG LIST OBJECT'S STRING REP CONTAINS NULS.
*/
args = Tcl_GetStringFromObj(argsPtr, &length);
result = Tcl_SplitList(interp, args, &numArgs, &argArray);
if (result != TCL_OK) {
goto procError;
}
if (precompiled) {
if (numArgs > procPtr->numArgs) {
|
|
|
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
|
* argument specifier. If the body is precompiled, processing is limited
* to checking that the parsed argument is consistent with the one stored
* in the Proc.
*
* THIS FAILS IF THE ARG LIST OBJECT'S STRING REP CONTAINS NULS.
*/
args = TclGetStringFromObj(argsPtr, &length);
result = Tcl_SplitList(interp, args, &numArgs, &argArray);
if (result != TCL_OK) {
goto procError;
}
if (precompiled) {
if (numArgs > procPtr->numArgs) {
|
| ︙ | | | ︙ | |
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
|
/*
* Compare the default value if any.
*/
if (localPtr->defValuePtr != NULL) {
int tmpLength;
char *tmpPtr = Tcl_GetStringFromObj(localPtr->defValuePtr,
&tmpLength);
if ((valueLength != tmpLength) ||
strncmp(fieldValues[1], tmpPtr, (size_t) tmpLength)) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"procedure \"%s\": formal parameter \"%s\" has "
"default value inconsistent with precompiled body",
|
|
|
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
|
/*
* Compare the default value if any.
*/
if (localPtr->defValuePtr != NULL) {
int tmpLength;
char *tmpPtr = TclGetStringFromObj(localPtr->defValuePtr,
&tmpLength);
if ((valueLength != tmpLength) ||
strncmp(fieldValues[1], tmpPtr, (size_t) tmpLength)) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"procedure \"%s\": formal parameter \"%s\" has "
"default value inconsistent with precompiled body",
|
| ︙ | | | ︙ | |
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
|
}
/* TODO: Consider skipping the typePtr checks */
} else if (objPtr->typePtr == &tclIntType
#ifndef NO_WIDE_TYPE
|| objPtr->typePtr == &tclWideIntType
#endif
) {
if (Tcl_GetIntFromObj(NULL, objPtr, &level) != TCL_OK || level < 0) {
goto levelError;
}
level = curLevel - level;
} else if (*name == '#') {
if (Tcl_GetInt(interp, name+1, &level) != TCL_OK || level < 0) {
goto levelError;
}
|
|
|
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
|
}
/* TODO: Consider skipping the typePtr checks */
} else if (objPtr->typePtr == &tclIntType
#ifndef NO_WIDE_TYPE
|| objPtr->typePtr == &tclWideIntType
#endif
) {
if (TclGetIntFromObj(NULL, objPtr, &level) != TCL_OK || level < 0) {
goto levelError;
}
level = curLevel - level;
} else if (*name == '#') {
if (Tcl_GetInt(interp, name+1, &level) != TCL_OK || level < 0) {
goto levelError;
}
|
| ︙ | | | ︙ | |
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
|
*/
code = iPtr->returnCode;
if (code == TCL_ERROR) {
iPtr->flags |= ERR_LEGACY_COPY;
}
}
return code;
}
/*
*----------------------------------------------------------------------
*
* TclGetObjInterpProc --
|
>
|
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
|
*/
code = iPtr->returnCode;
if (code == TCL_ERROR) {
iPtr->flags |= ERR_LEGACY_COPY;
}
}
iPtr->flags |= INTERP_RESULT_UNCLEAN;
return code;
}
/*
*----------------------------------------------------------------------
*
* TclGetObjInterpProc --
|
| ︙ | | | ︙ | |
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
|
Proc *procPtr;
/*
* Convert objPtr to list type first; if it cannot be converted, or if its
* length is not 2, then it cannot be converted to lambdaType.
*/
result = Tcl_ListObjGetElements(interp, objPtr, &objc, &objv);
if ((result != TCL_OK) || ((objc != 2) && (objc != 3))) {
TclNewLiteralStringObj(errPtr, "can't interpret \"");
Tcl_AppendObjToObj(errPtr, objPtr);
Tcl_AppendToObj(errPtr, "\" as a lambda expression", -1);
Tcl_SetObjResult(interp, errPtr);
return TCL_ERROR;
}
|
|
|
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
|
Proc *procPtr;
/*
* Convert objPtr to list type first; if it cannot be converted, or if its
* length is not 2, then it cannot be converted to lambdaType.
*/
result = TclListObjGetElements(interp, objPtr, &objc, &objv);
if ((result != TCL_OK) || ((objc != 2) && (objc != 3))) {
TclNewLiteralStringObj(errPtr, "can't interpret \"");
Tcl_AppendObjToObj(errPtr, objPtr);
Tcl_AppendToObj(errPtr, "\" as a lambda expression", -1);
Tcl_SetObjResult(interp, errPtr);
return TCL_ERROR;
}
|
| ︙ | | | ︙ | |
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
|
* Set the namespace for this lambda: given by objv[2] understood as a
* global reference, or else global per default.
*/
if (objc == 2) {
TclNewLiteralStringObj(nsObjPtr, "::");
} else {
char *nsName = Tcl_GetString(objv[2]);
if ((*nsName != ':') || (*(nsName+1) != ':')) {
TclNewLiteralStringObj(nsObjPtr, "::");
Tcl_AppendObjToObj(nsObjPtr, objv[2]);
} else {
nsObjPtr = objv[2];
}
|
|
|
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
|
* Set the namespace for this lambda: given by objv[2] understood as a
* global reference, or else global per default.
*/
if (objc == 2) {
TclNewLiteralStringObj(nsObjPtr, "::");
} else {
char *nsName = TclGetString(objv[2]);
if ((*nsName != ':') || (*(nsName+1) != ':')) {
TclNewLiteralStringObj(nsObjPtr, "::");
Tcl_AppendObjToObj(nsObjPtr, objv[2]);
} else {
nsObjPtr = objv[2];
}
|
| ︙ | | | ︙ | |
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
|
* Also requires making tclCmdNameType non-static in tclObj.c
*/
Tcl_Obj *elemPtr;
int numElem;
if ((lambdaPtr->typePtr == &tclCmdNameType) ||
(Tcl_ListObjGetElements(interp, lambdaPtr, &numElem,
&elemPtr) == TCL_OK && numElem == 1)) {
return Tcl_EvalObjv(interp, objc-1, objv+1, 0);
}
}
#endif
if ((procPtr == NULL) || (procPtr->iPtr != iPtr)) {
|
|
|
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
|
* Also requires making tclCmdNameType non-static in tclObj.c
*/
Tcl_Obj *elemPtr;
int numElem;
if ((lambdaPtr->typePtr == &tclCmdNameType) ||
(TclListObjGetElements(interp, lambdaPtr, &numElem,
&elemPtr) == TCL_OK && numElem == 1)) {
return Tcl_EvalObjv(interp, objc-1, objv+1, 0);
}
}
#endif
if ((procPtr == NULL) || (procPtr->iPtr != iPtr)) {
|
| ︙ | | | ︙ | |