Index: Makefile.in ================================================================== --- Makefile.in +++ Makefile.in @@ -8,22 +8,24 @@ LIBS = @LIBS@ INSTALL = @INSTALL@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ TCL_PACKAGE_PATH = @TCL_PACKAGE_PATH@ +TCLCONFIGPATH = @TCLCONFIGPATH@ PACKAGE_INSTALL_DIR = $(TCL_PACKAGE_PATH)/$(PACKAGE_NAME)-$(PACKAGE_VERSION) TARGETS = @TARGETS@ +TCC_CONFIGURE_OPTS = --extra-cflags='$(CFLAGS)' --with-tcl=$(TCLCONFIGPATH) srcdir = @srcdir@ all: $(TARGETS) tcc/config.h: if [ "$(srcdir)" = "." ]; then \ - cd tcc && ./configure; \ + cd tcc && ./configure $(TCC_CONFIGURE_OPTS); \ else \ mkdir tcc >/dev/null 2>/dev/null; \ - cd tcc && $(shell cd $(srcdir) && pwd)/tcc/configure; \ + cd tcc && $(shell cd $(srcdir) && pwd)/tcc/configure $(TCC_CONFIGURE_OPTS); \ fi tcc/libtcc.a: tcc/config.h $(MAKE) -C tcc libtcc.a @@ -32,11 +34,11 @@ tcltcc.o: $(srcdir)/tcltcc.c $(srcdir)/tcc/tcc.h $(srcdir)/tcc/libtcc.h tcc/config.h $(CC) $(CPPFLAGS) $(CFLAGS) -o tcltcc.o -c $(srcdir)/tcltcc.c tcltcc.@SHOBJEXT@: tcltcc.o tcc/libtcc.a - $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(SHOBJLDFLAGS) -o tcltcc.@SHOBJEXT@ tcltcc.o $(LIBS) + $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(SHOBJLDFLAGS) -o tcltcc.@SHOBJEXT@ tcltcc.o tcc/libtcc.a $(LIBS) tcltcc-static.a: tcltcc.o tcc/libtcc.a cp tcc/libtcc.a tcltcc-static.new.a $(AR) rcu tcltcc-static.new.a tcltcc.o -$(RANLIB) tcltcc-static.new.a Index: tcc.tcl ================================================================== --- tcc.tcl +++ tcc.tcl @@ -1,21 +1,21 @@ # tcc.tcl - library routines for the tcc wrapper (Mark Janssen) -namespace eval tcc { +namespace eval tcc4tcl { variable dir variable libs variable includes variable count variable command_count variable commands set dir [file dirname [info script]] - if {[info command ::tcc] == ""} { - catch { load {} tcc } + if {[info command ::tcc4tcl] == ""} { + catch { load {} tcc4tcl } } - if {[info command ::tcc] == ""} { - load [file join $dir tcctcl[info sharedlibextension]] tcc + if {[info command ::tcc4tcl] == ""} { + load [file join $dir tcltcc[info sharedlibextension]] tcc4tcl } set libs $dir/lib set includes $dir/include set count 0 set command_count 0 @@ -22,11 +22,11 @@ array set commands {} proc new {} { variable dir variable count set handle tcc_[incr count] - tcc $dir $handle + tcc4tcl $dir $handle return tcc_$count } proc tclcommand {handle name ccode} { variable commands variable command_count @@ -51,95 +51,95 @@ $handle command $tclcommand $cname } return } } -proc tcc::to_dll {code dll {libs {}}} { - tcc $::tcc::dir dll tcc_1 +proc tcc4tcl::to_dll {code dll {libs {}}} { + tcc4tcl $::tcc4tcl::dir dll tcc_1 tcc_1 add_library tcl8.5 tcc_1 add_library_path . foreach lib $libs {tcc_1 add_library $lib} if {$::tcl_platform(platform) eq "windows"} { tcc_1 define DLL_EXPORT {__declspec(dllexport)} - set f [open $::tcc::dir/c/dllcrt1.c] + set f [open $::tcc4tcl::dir/c/dllcrt1.c] tcc_1 compile [read $f] close $f - set f [open $::tcc::dir/c/dllmain.c] + set f [open $::tcc4tcl::dir/c/dllmain.c] tcc_1 compile [read $f] close $f } else { tcc_1 define DLL_EXPORT "" } tcc_1 compile $code tcc_1 output_file $dll rename tcc_1 {} } -proc ::tcc::Log {args} { +proc ::tcc4tcl::Log {args} { # puts $args } -proc ::tcc::reset {} { +proc ::tcc4tcl::reset {} { variable tcc set tcc(code) "" set tcc(cfiles) [list] set tcc(tk) 0 } # Custom helpers -proc ::tcc::checkname {n} {expr {[regexp {^[a-zA-Z0-9_]+$} $n] > 0}} -proc ::tcc::cleanname {n} {regsub -all {[^a-zA-Z0-9_]+} $n _} +proc ::tcc4tcl::checkname {n} {expr {[regexp {^[a-zA-Z0-9_]+$} $n] > 0}} +proc ::tcc4tcl::cleanname {n} {regsub -all {[^a-zA-Z0-9_]+} $n _} -proc ::tcc::ccode {code} { +proc ::tcc4tcl::ccode {code} { variable tcc Log "INJECTING CCODE" append tcc(code) $code \n } -proc ::tcc::cc {code} { +proc ::tcc4tcl::cc {code} { variable tcc if {![info exists tcc(cc)]} { set tcc(cc) tcc1 - tcc $tcc::dir $tcc(cc) + tcc4tcl $tcc4tcl::dir $tcc(cc) $tcc(cc) add_library tcl8.5 - $tcc(cc) add_include_path [file join $::tcc::dir include] + $tcc(cc) add_include_path [file join $::tcc4tcl::dir include] } Log code:$code $tcc(cc) compile $code } #----------------------------------------------------------- New DLL API -proc ::tcc::dll {{name ""}} { +proc ::tcc4tcl::dll {{name ""}} { variable count if {$name eq ""} {set name dll[incr count]} - namespace eval ::tcc::dll::$name { + namespace eval ::tcc4tcl::dll::$name { variable code "#include \n" ;# always needed variable cmds {} } - proc ::$name {cmd args} "::tcc::dll::\$cmd $name \$args" + proc ::$name {cmd args} "::tcc4tcl::dll::\$cmd $name \$args" return $name } -namespace eval ::tcc::dll {} -proc ::tcc::dll::ccode {name argl} { +namespace eval ::tcc4tcl::dll {} +proc ::tcc4tcl::dll::ccode {name argl} { append ${name}::code \n [lindex $argl 0] return } -proc ::tcc::dll::cproc {name argl} { +proc ::tcc4tcl::dll::cproc {name argl} { foreach {pname pargs rtype body} $argl break - set code [::tcc::wrapCmd $pname $pargs $rtype cx_$pname $body] + set code [::tcc4tcl::wrapCmd $pname $pargs $rtype cx_$pname $body] lappend ${name}::cmds $pname cx_$pname append ${name}::code \n $code return } -proc ::tcc::dll::write {name argl} { +proc ::tcc4tcl::dll::write {name argl} { set (-dir) . set (-code) "" ;# possible extra code to go into the _Init function set (-libs) "" set (-name) [string tolower $name] array set "" $argl append ${name}::code \n \ - [::tcc::wrapExport $(-name) [set ${name}::cmds] $(-code)] + [::tcc4tcl::wrapExport $(-name) [set ${name}::cmds] $(-code)] set outfile $(-dir)/$(-name)[info sharedlibextension] - ::tcc::to_dll [set ${name}::code] $outfile $(-libs) + ::tcc4tcl::to_dll [set ${name}::code] $outfile $(-libs) } #--------------------------------------------------------------------- -proc ::tcc::wrap {name adefs rtype {body "#"}} { +proc ::tcc4tcl::wrap {name adefs rtype {body "#"}} { set cname c_$name set wname tcl_$name array set types {} set names {} set cargs {} @@ -263,18 +263,18 @@ #puts ----code:\n$code #puts ----cbody:\n$cbody list $code $cbody } -proc ::tcc::wrapCmd {tclname argl rtype cname body} { +proc ::tcc4tcl::wrapCmd {tclname argl rtype cname body} { foreach {code cbody} [wrap $tclname $argl $rtype $body] break append code "\nstatic int $cname" append code {(ClientData cdata,Tcl_Interp *ip, int objc,Tcl_Obj* CONST objv[])} " \{" append code \n$cbody \n\}\n } -proc ::tcc::wrapExport {name cmds {body ""}} { +proc ::tcc4tcl::wrapExport {name cmds {body ""}} { set code "DLL_EXPORT int [string totitle $name]_Init(Tcl_Interp *interp)" append code " \{\n" foreach {tclname cname} $cmds { append code \ "Tcl_CreateObjCommand(interp,\"$tclname\",$cname,NULL,NULL);\n" @@ -281,18 +281,18 @@ } append code $body append code "\nreturn TCL_OK;\n\}" } #--------------------------------------------------------------------- -proc ::tcc::cproc {name adefs rtype {body "#"}} { +proc ::tcc4tcl::cproc {name adefs rtype {body "#"}} { foreach {code cbody} [wrap $name $adefs $rtype $body] break ccode $code set ns [namespace current] uplevel 1 [list ${ns}::ccommand $name {dummy ip objc objv} $cbody] } #--------------------------------------------------------------------- -proc ::tcc::cdata {name data} { +proc ::tcc4tcl::cdata {name data} { # Extract bytes from data binary scan $data c* bytes set inittext "\n" set line "" set n 0 @@ -319,11 +319,11 @@ set ns [namespace current] uplevel 1 [list ${ns}::ccommand $name {dummy ip objc objv} $cbody] return $name } #------------------------------------------------------------------- -proc ::tcc::ccommand {procname anames args} { +proc ::tcc4tcl::ccommand {procname anames args} { variable tcc # Fully qualified proc name if {[string match "::*" $procname]} { # procname is already absolute } else { @@ -363,12 +363,12 @@ uplevel 1 [list ${ns}::cc $code] Log "CREATING TCL COMMAND $procname / $cname" uplevel 1 [list $tcc(cc) command $procname $cname] unset tcc(cc) ;# can't be used for compiling anymore } -proc ::tcc::tk {args} { +proc ::tcc4tcl::tk {args} { variable tcc set tcc(tk) 1 } -::tcc::reset -namespace eval tcc {namespace export cproc ccode cdata} +::tcc4tcl::reset +namespace eval tcc4tcl {namespace export cproc ccode cdata} Index: tcltcc.c ================================================================== --- tcltcc.c +++ tcltcc.c @@ -18,10 +18,11 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include +#include #include "tcc.h" struct TclTCCState { TCCState *s; int relocated; @@ -36,23 +37,22 @@ TCCState *s ; ts = (struct TclTCCState *) cdata; s = ts->s; - Tcl_DecrRefCount(s->tcc_lib_path); - /* We can delete the compiler if the output was not to memory */ if (s->output_type != TCC_OUTPUT_MEMORY) { tcc_delete(s); ts->s = NULL; } - free(ts); + ckfree((void *) ts); } static int TccHandleCmd ( ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[]){ unsigned long val; + void *val_p; int index; int res; struct TclTCCState *ts; TCCState *s; Tcl_Obj *sym_addr; @@ -113,38 +113,43 @@ return TCL_ERROR; } else { tcc_add_library_path(s, Tcl_GetString(objv[2])); return TCL_OK; } +#if 0 case TCLTCC_ADD_SYMBOL: if (objc != 4) { Tcl_WrongNumArgs(interp, 2, objv, "symbol value"); return TCL_ERROR; } Tcl_GetLongFromObj(interp,objv[3], &val); + tcc_add_symbol(s,Tcl_GetString(objv[2]),val); return TCL_OK; +#endif case TCLTCC_COMMAND: if (objc != 4) { Tcl_WrongNumArgs(interp, 2, objv, "tclname cname"); return TCL_ERROR; } if (!ts->relocated) { - if(tcc_relocate(s)!=0) { + if(tcc_relocate(s, TCC_RELOCATE_AUTO)!=0) { Tcl_AppendResult(interp, "relocating failed", NULL); return TCL_ERROR; } else { ts->relocated=1; } } - if (tcc_get_symbol(s,&val,Tcl_GetString(objv[3]))!=0) { + + 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; } /*printf("symbol: %x\n",val); */ - Tcl_CreateObjCommand(interp,Tcl_GetString(objv[2]),(void *)val,NULL,NULL); + Tcl_CreateObjCommand(interp,Tcl_GetString(objv[2]),val_p,NULL,NULL); return TCL_OK; case TCLTCC_COMPILE: if(ts->relocated == 1) { Tcl_AppendResult(interp, "code already relocated, cannot compile more",NULL); return TCL_ERROR; @@ -175,22 +180,23 @@ if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "symbol"); return TCL_ERROR; } if (!ts->relocated) { - if(tcc_relocate(s)!=0) { + if(tcc_relocate(s, TCC_RELOCATE_AUTO)!=0) { Tcl_AppendResult(interp, "relocating failed", NULL); return TCL_ERROR; } else { ts->relocated=1; } } - if(tcc_get_symbol(s,&val,Tcl_GetString(objv[2]))!=0) { + val_p = tcc_get_symbol(s,Tcl_GetString(objv[2])); + if(val_p == NULL) { Tcl_AppendResult(interp, "symbol '", Tcl_GetString(objv[2]),"' not found", NULL); return TCL_ERROR; } - sym_addr = Tcl_NewLongObj(val); + sym_addr = Tcl_NewWideIntObj((Tcl_WideInt) val_p); Tcl_SetObjResult(interp, sym_addr); return TCL_OK; case TCLTCC_OUTPUT_FILE: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "filename"); @@ -228,11 +234,11 @@ } return TCL_OK; } static int TccCreateCmd( ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[]){ - struct TclTCCState *ts + struct TclTCCState *ts; TCCState *s; int index; static CONST char *types[] = { "memory", "exe", "dll", "obj", "preprocess", (char *) NULL }; @@ -248,30 +254,35 @@ if (Tcl_GetIndexFromObj(interp, objv[2], types, "type", 0, &index) != TCL_OK) { return TCL_ERROR; } } - s = tcc_new(objv[1]); + s = tcc_new(); + if (s == NULL) { + return(TCL_ERROR); + } + tcc_set_error_func(s, interp, (void *)&TccErrorFunc); - ts = malloc(sizeof(*ts)); + ts = (void *) ckalloc(sizeof(*ts)); ts->s = s; ts->relocated = 0; /*printf("type: %d\n", index); */ tcc_set_output_type(s,index); - Tcl_CreateObjCommand(interp,Tcl_GetString(objv[objc-1]),TccHandleCmd,s,TccCCommandDeleteProc); + Tcl_CreateObjCommand(interp,Tcl_GetString(objv[objc-1]),TccHandleCmd,ts,TccCCommandDeleteProc); return TCL_OK; } -DLL_EXPORT int Tcc_Init(Tcl_Interp *interp) { +int Tcc4tcl_Init(Tcl_Interp *interp) { #ifdef TCL_USE_STUBS if (Tcl_InitStubs(interp, "8.4" , 0) == 0L) { return TCL_ERROR; } #endif - Tcl_CreateObjCommand(interp,PACKAGE_NAME,TccCreateCmd,NULL,NULL); - Tcl_PkgProvide(interp,PACKAGE_NAME,PACKAGE_VERSION); + + Tcl_CreateObjCommand(interp, PACKAGE_NAME, TccCreateCmd, NULL, NULL); + Tcl_PkgProvide(interp, PACKAGE_NAME, PACKAGE_VERSION); return TCL_OK; }