@@ -30,11 +30,11 @@ static void Tcc4tclErrorFunc(Tcl_Interp * interp, char * msg) { Tcl_AppendResult(interp, msg, "\n", NULL); } -static void Tcc4tclCCommandDeleteProc (ClientData cdata) { +static void Tcc4tclCCommandDeleteProc(ClientData cdata) { struct TclTCCState *ts; TCCState *s ; ts = (struct TclTCCState *) cdata; s = ts->s; @@ -41,10 +41,22 @@ ts->s = NULL; ckfree((void *) ts); } + +static void Tcc4tclDeleteClientData(ClientData cdata) { + /* + * ClientData is a Tcl_Obj*, that was passed in + * at command creation + */ + Tcl_Obj *cdata_o = (Tcl_Obj *)cdata; + + if (cdata_o != NULL) { + Tcl_DecrRefCount(cdata_o); + } +} static int Tcc4tclHandleCmd ( ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[]){ Tcl_WideInt val; Tcl_Obj *val_o; void *val_p; @@ -134,14 +146,15 @@ val_p = (void *) val; tcc_add_symbol(s,Tcl_GetString(objv[2]), val_p); return TCL_OK; case TCC4TCL_COMMAND: - if (objc != 4) { - Tcl_WrongNumArgs(interp, 2, objv, "tclname cname"); + if (objc != 4 && objc != 5) { + Tcl_WrongNumArgs(interp, 2, objv, "tclname cname ?clientData?"); return TCL_ERROR; } + if (!ts->relocated) { if(tcc_relocate(s, TCC_RELOCATE_AUTO)!=0) { Tcl_AppendResult(interp, "relocating failed", NULL); return TCL_ERROR; } else { @@ -152,13 +165,21 @@ val_p = tcc_get_symbol(s, Tcl_GetString(objv[3])); if (val_p == NULL) { Tcl_AppendResult(interp, "symbol '", Tcl_GetString(objv[3]),"' not found", NULL); return TCL_ERROR; } + + /* the ClientData */ + if (objc == 5) { + val_o = objv[4]; + Tcl_IncrRefCount(val_o); + } else { + val_o = NULL; + } /*printf("symbol: %x\n",val); */ - Tcl_CreateObjCommand(interp,Tcl_GetString(objv[2]),val_p,NULL,NULL); + Tcl_CreateObjCommand(interp, Tcl_GetString(objv[2]), val_p, val_o, Tcc4tclDeleteClientData); return TCL_OK; case TCC4TCL_COMPILE: if(ts->relocated == 1) { Tcl_AppendResult(interp, "code already relocated, cannot compile more",NULL); return TCL_ERROR;