WAIT/POST_SEM(): generalize interface (and more)
Currently used only with 'tcc_compile_sem' to protect tcc_compile(), but can be used with other semaphores Also fix deadlock when tcc_enter_state() is called recursively for the same state, for example with tcc_warning() from #pragma comment(option,"...") Also: - libtcc.c: error1(): use cstr_[v]printf() - tcc.h: set TCC_USING_DOUBLE_FOR_LDOUBLE for macho-arm64 (rather than for macho-X86_64) - tcc.h: define TCC_TARGET_MACHO on __APPLE__ by default - tcc.h: cleanup TCCState, move DEFASM token stuff to tcctok.h - tccgen.c: more static - Makefile/tcc.c: review githash - tccpe/tcctools: use read() instead of fgets() in pe_load_def() (all files opened by tcc for reading are now read via 'int fd') - configure/win32: don't preset CONFIG_TCCDIR (to allow to override it) - tcc.c -bench: do not include output/run-time
This commit is contained in:
parent
4b2c6cf3a4
commit
dda95e9b0b
14 changed files with 361 additions and 322 deletions
10
Makefile
10
Makefile
|
@ -134,7 +134,7 @@ all: $(PROGS) $(TCCLIBS) $(TCCDOCS)
|
|||
|
||||
# cross compiler targets to build
|
||||
TCC_X = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm-wince c67
|
||||
TCC_X += riscv64
|
||||
TCC_X += riscv64 arm64-osx
|
||||
# TCC_X += arm-fpa arm-fpa-ld arm-vfp arm-eabi
|
||||
|
||||
# cross libtcc1.a targets to build
|
||||
|
@ -222,10 +222,9 @@ $(TCC_FILES) : DEFINES += -DONE_SOURCE=0
|
|||
$(X)tccpp.o : $(TCCDEFS_H)
|
||||
endif
|
||||
|
||||
TCC_GIT_HASH=$(shell git rev-parse > /dev/null 2>&1 && git rev-parse --short HEAD || echo no)
|
||||
ifneq ($(TCC_GIT_HASH),no)
|
||||
MODIFIED = $(shell git diff | grep -q +++ && echo "modified ")
|
||||
$(X)tcc.o : DEFINES += -DTCC_GIT_HASH="\"$(MODIFIED)$(TCC_GIT_HASH)\""
|
||||
GITHASH := $(shell git rev-parse >/dev/null 2>&1 && git rev-parse --short HEAD || echo no)
|
||||
ifneq ($(GITHASH),no)
|
||||
DEF_GITHASH := -DTCC_GITHASH="\"$(GITHASH)$(shell git diff --quiet || echo '-mod')\""
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_debug),yes)
|
||||
|
@ -247,6 +246,7 @@ $(X)%.o : %.c $(LIBTCC_INC)
|
|||
|
||||
# additional dependencies
|
||||
$(X)tcc.o : tcctools.c
|
||||
$(X)tcc.o : DEFINES += $(DEF_GITHASH)
|
||||
|
||||
# Host Tiny C Compiler
|
||||
tcc$(EXESUF): tcc.o $(LIBTCC)
|
||||
|
|
4
configure
vendored
4
configure
vendored
|
@ -238,7 +238,7 @@ if test "$mingw32" = "yes" ; then
|
|||
source_path="."
|
||||
fi
|
||||
test -z "$prefix" && prefix="C:/Program Files/tcc"
|
||||
test -z "$tccdir" && tccdir="${prefix}"
|
||||
test -z "$tccdir" && tccdir="${prefix}" && tccdir_auto="yes"
|
||||
test -z "$bindir" && bindir="${tccdir}"
|
||||
test -z "$docdir" && docdir="${tccdir}/doc"
|
||||
test -z "$libdir" && libdir="${tccdir}/libtcc"
|
||||
|
@ -483,7 +483,7 @@ print_mak() {
|
|||
echo "/* Automatically generated by configure - do not modify */" > $TMPH
|
||||
|
||||
print_inc CONFIG_SYSROOT "$sysroot"
|
||||
print_inc CONFIG_TCCDIR "$tccdir"
|
||||
test "$tccdir_auto" = "yes" || print_inc CONFIG_TCCDIR "$tccdir"
|
||||
print_mak CONFIG_USR_INCLUDE "$tcc_usrinclude"
|
||||
print_mak CONFIG_TCC_SYSINCLUDEPATHS "$tcc_sysincludepaths"
|
||||
print_mak CONFIG_TCC_LIBPATHS "$tcc_libpaths"
|
||||
|
|
76
i386-tok.h
76
i386-tok.h
|
@ -1,6 +1,82 @@
|
|||
/* ------------------------------------------------------------------ */
|
||||
/* WARNING: relative order of tokens is important. */
|
||||
|
||||
#define DEF_BWL(x) \
|
||||
DEF(TOK_ASM_ ## x ## b, #x "b") \
|
||||
DEF(TOK_ASM_ ## x ## w, #x "w") \
|
||||
DEF(TOK_ASM_ ## x ## l, #x "l") \
|
||||
DEF(TOK_ASM_ ## x, #x)
|
||||
#define DEF_WL(x) \
|
||||
DEF(TOK_ASM_ ## x ## w, #x "w") \
|
||||
DEF(TOK_ASM_ ## x ## l, #x "l") \
|
||||
DEF(TOK_ASM_ ## x, #x)
|
||||
#ifdef TCC_TARGET_X86_64
|
||||
# define DEF_BWLQ(x) \
|
||||
DEF(TOK_ASM_ ## x ## b, #x "b") \
|
||||
DEF(TOK_ASM_ ## x ## w, #x "w") \
|
||||
DEF(TOK_ASM_ ## x ## l, #x "l") \
|
||||
DEF(TOK_ASM_ ## x ## q, #x "q") \
|
||||
DEF(TOK_ASM_ ## x, #x)
|
||||
# define DEF_WLQ(x) \
|
||||
DEF(TOK_ASM_ ## x ## w, #x "w") \
|
||||
DEF(TOK_ASM_ ## x ## l, #x "l") \
|
||||
DEF(TOK_ASM_ ## x ## q, #x "q") \
|
||||
DEF(TOK_ASM_ ## x, #x)
|
||||
# define DEF_BWLX DEF_BWLQ
|
||||
# define DEF_WLX DEF_WLQ
|
||||
/* number of sizes + 1 */
|
||||
# define NBWLX 5
|
||||
#else
|
||||
# define DEF_BWLX DEF_BWL
|
||||
# define DEF_WLX DEF_WL
|
||||
/* number of sizes + 1 */
|
||||
# define NBWLX 4
|
||||
#endif
|
||||
|
||||
#define DEF_FP1(x) \
|
||||
DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \
|
||||
DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
|
||||
DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
|
||||
DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")
|
||||
|
||||
#define DEF_FP(x) \
|
||||
DEF(TOK_ASM_ ## f ## x, "f" #x ) \
|
||||
DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
|
||||
DEF_FP1(x)
|
||||
|
||||
#define DEF_ASMTEST(x,suffix) \
|
||||
DEF_ASM(x ## o ## suffix) \
|
||||
DEF_ASM(x ## no ## suffix) \
|
||||
DEF_ASM(x ## b ## suffix) \
|
||||
DEF_ASM(x ## c ## suffix) \
|
||||
DEF_ASM(x ## nae ## suffix) \
|
||||
DEF_ASM(x ## nb ## suffix) \
|
||||
DEF_ASM(x ## nc ## suffix) \
|
||||
DEF_ASM(x ## ae ## suffix) \
|
||||
DEF_ASM(x ## e ## suffix) \
|
||||
DEF_ASM(x ## z ## suffix) \
|
||||
DEF_ASM(x ## ne ## suffix) \
|
||||
DEF_ASM(x ## nz ## suffix) \
|
||||
DEF_ASM(x ## be ## suffix) \
|
||||
DEF_ASM(x ## na ## suffix) \
|
||||
DEF_ASM(x ## nbe ## suffix) \
|
||||
DEF_ASM(x ## a ## suffix) \
|
||||
DEF_ASM(x ## s ## suffix) \
|
||||
DEF_ASM(x ## ns ## suffix) \
|
||||
DEF_ASM(x ## p ## suffix) \
|
||||
DEF_ASM(x ## pe ## suffix) \
|
||||
DEF_ASM(x ## np ## suffix) \
|
||||
DEF_ASM(x ## po ## suffix) \
|
||||
DEF_ASM(x ## l ## suffix) \
|
||||
DEF_ASM(x ## nge ## suffix) \
|
||||
DEF_ASM(x ## nl ## suffix) \
|
||||
DEF_ASM(x ## ge ## suffix) \
|
||||
DEF_ASM(x ## le ## suffix) \
|
||||
DEF_ASM(x ## ng ## suffix) \
|
||||
DEF_ASM(x ## nle ## suffix) \
|
||||
DEF_ASM(x ## g ## suffix)
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* register */
|
||||
DEF_ASM(al)
|
||||
DEF_ASM(cl)
|
||||
|
|
175
libtcc.c
175
libtcc.c
|
@ -21,6 +21,7 @@
|
|||
#if !defined ONE_SOURCE || ONE_SOURCE
|
||||
#include "tccpp.c"
|
||||
#include "tccgen.c"
|
||||
#include "tccasm.c"
|
||||
#include "tccelf.c"
|
||||
#include "tccrun.c"
|
||||
#ifdef TCC_TARGET_I386
|
||||
|
@ -50,9 +51,6 @@
|
|||
#else
|
||||
#error unknown target
|
||||
#endif
|
||||
#ifdef CONFIG_TCC_ASM
|
||||
#include "tccasm.c"
|
||||
#endif
|
||||
#ifdef TCC_TARGET_PE
|
||||
#include "tccpe.c"
|
||||
#endif
|
||||
|
@ -68,6 +66,7 @@
|
|||
|
||||
/* XXX: get rid of this ASAP (or maybe not) */
|
||||
ST_DATA struct TCCState *tcc_state;
|
||||
TCC_SEM(static tcc_compile_sem);
|
||||
|
||||
#ifdef MEM_DEBUG
|
||||
static int nb_states;
|
||||
|
@ -84,19 +83,23 @@ ST_FUNC char *normalize_slashes(char *path)
|
|||
return path;
|
||||
}
|
||||
|
||||
/* NULL if this is tcc.exe, HINSTANCE if this is libtcc.dll */
|
||||
static HMODULE tcc_module;
|
||||
|
||||
#ifndef CONFIG_TCCDIR
|
||||
/* on win32, we suppose the lib and includes are at the location of 'tcc.exe' */
|
||||
static void tcc_set_lib_path_w32(TCCState *s)
|
||||
static inline char *config_tccdir_w32(char *path)
|
||||
{
|
||||
char path[1024], *p;
|
||||
GetModuleFileNameA(tcc_module, path, sizeof path);
|
||||
char *p;
|
||||
GetModuleFileName(tcc_module, path, MAX_PATH);
|
||||
p = tcc_basename(normalize_slashes(strlwr(path)));
|
||||
if (p > path)
|
||||
--p;
|
||||
*p = 0;
|
||||
tcc_set_lib_path(s, path);
|
||||
return path;
|
||||
}
|
||||
#define CONFIG_TCCDIR config_tccdir_w32(alloca(MAX_PATH))
|
||||
#endif
|
||||
|
||||
#ifdef TCC_TARGET_PE
|
||||
static void tcc_add_systemdir(TCCState *s)
|
||||
|
@ -118,47 +121,60 @@ BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved)
|
|||
#endif
|
||||
|
||||
/********************************************************/
|
||||
#if CONFIG_TCC_SEMLOCK == 0
|
||||
#define WAIT_SEM()
|
||||
#define POST_SEM()
|
||||
#elif defined _WIN32
|
||||
static int tcc_sem_init;
|
||||
static CRITICAL_SECTION tcc_cr;
|
||||
static void wait_sem(void)
|
||||
#if CONFIG_TCC_SEMLOCK
|
||||
#if defined _WIN32
|
||||
ST_FUNC void wait_sem(TCCSem *p)
|
||||
{
|
||||
if (!tcc_sem_init)
|
||||
InitializeCriticalSection(&tcc_cr), tcc_sem_init = 1;
|
||||
EnterCriticalSection(&tcc_cr);
|
||||
if (!p->init)
|
||||
InitializeCriticalSection(&p->cr), p->init = 1;
|
||||
EnterCriticalSection(&p->cr);
|
||||
}
|
||||
ST_FUNC void post_sem(TCCSem *p)
|
||||
{
|
||||
LeaveCriticalSection(&p->cr);
|
||||
}
|
||||
#define WAIT_SEM() wait_sem()
|
||||
#define POST_SEM() LeaveCriticalSection(&tcc_cr);
|
||||
#elif defined __APPLE__
|
||||
/* Half-compatible MacOS doesn't have non-shared (process local)
|
||||
semaphores. Use the dispatch framework for lightweight locks. */
|
||||
#include <dispatch/dispatch.h>
|
||||
static int tcc_sem_init;
|
||||
static dispatch_semaphore_t tcc_sem;
|
||||
static void wait_sem(void)
|
||||
ST_FUNC void wait_sem(TCCSem *p)
|
||||
{
|
||||
if (!tcc_sem_init)
|
||||
tcc_sem = dispatch_semaphore_create(1), tcc_sem_init = 1;
|
||||
dispatch_semaphore_wait(tcc_sem, DISPATCH_TIME_FOREVER);
|
||||
if (!p->init)
|
||||
p->sem = dispatch_semaphore_create(1), p->init = 1;
|
||||
dispatch_semaphore_wait(p->sem, DISPATCH_TIME_FOREVER);
|
||||
}
|
||||
ST_FUNC void post_sem(TCCSem *p)
|
||||
{
|
||||
dispatch_semaphore_signal(p->sem);
|
||||
}
|
||||
#define WAIT_SEM() wait_sem()
|
||||
#define POST_SEM() dispatch_semaphore_signal(tcc_sem)
|
||||
#else
|
||||
#include <semaphore.h>
|
||||
static int tcc_sem_init;
|
||||
static sem_t tcc_sem;
|
||||
static void wait_sem(void)
|
||||
ST_FUNC void wait_sem(TCCSem *p)
|
||||
{
|
||||
if (!tcc_sem_init)
|
||||
sem_init(&tcc_sem, 0, 1), tcc_sem_init = 1;
|
||||
while (sem_wait (&tcc_sem) < 0 && errno == EINTR);
|
||||
if (!p->init)
|
||||
sem_init(&p->sem, 0, 1), p->init = 1;
|
||||
while (sem_wait(&p->sem) < 0 && errno == EINTR);
|
||||
}
|
||||
ST_FUNC void post_sem(TCCSem *p)
|
||||
{
|
||||
sem_post(&p->sem);
|
||||
}
|
||||
#define WAIT_SEM() wait_sem()
|
||||
#define POST_SEM() sem_post(&tcc_sem)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
PUB_FUNC void tcc_enter_state(TCCState *s1)
|
||||
{
|
||||
if (s1->error_set_jmp_enabled)
|
||||
return;
|
||||
WAIT_SEM(&tcc_compile_sem);
|
||||
tcc_state = s1;
|
||||
}
|
||||
|
||||
PUB_FUNC void tcc_exit_state(TCCState *s1)
|
||||
{
|
||||
if (s1->error_set_jmp_enabled)
|
||||
return;
|
||||
tcc_state = NULL;
|
||||
POST_SEM(&tcc_compile_sem);
|
||||
}
|
||||
|
||||
/********************************************************/
|
||||
/* copy a string and truncate it. */
|
||||
|
@ -494,52 +510,29 @@ static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char *
|
|||
}
|
||||
|
||||
/********************************************************/
|
||||
/* warning / error */
|
||||
|
||||
static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
|
||||
{
|
||||
int len;
|
||||
len = strlen(buf);
|
||||
vsnprintf(buf + len, buf_size - len, fmt, ap);
|
||||
}
|
||||
/* warn_... option bits */
|
||||
#define WARN_ON 1 /* warning is on (-Woption) */
|
||||
#define WARN_ERR 2 /* warning is an error (-Werror=option) */
|
||||
#define WARN_NOE 4 /* warning is not an error (-Wno-error=option) */
|
||||
|
||||
static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
strcat_vprintf(buf, buf_size, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
PUB_FUNC void tcc_enter_state(TCCState *s1)
|
||||
{
|
||||
WAIT_SEM();
|
||||
tcc_state = s1;
|
||||
}
|
||||
|
||||
PUB_FUNC void tcc_exit_state(void)
|
||||
{
|
||||
tcc_state = NULL;
|
||||
POST_SEM();
|
||||
}
|
||||
|
||||
#define ERROR_WARN 0
|
||||
#define ERROR_NOABORT 1
|
||||
#define ERROR_ERROR 2
|
||||
/* error1() modes */
|
||||
enum { ERROR_WARN, ERROR_NOABORT, ERROR_ERROR };
|
||||
|
||||
static void error1(int mode, const char *fmt, va_list ap)
|
||||
{
|
||||
char buf[2048];
|
||||
BufferedFile **pf, *f;
|
||||
TCCState *s1 = tcc_state;
|
||||
CString cs;
|
||||
|
||||
cstr_new(&cs);
|
||||
|
||||
buf[0] = '\0';
|
||||
if (s1 == NULL)
|
||||
/* can happen only if called from tcc_malloc(): 'out of memory' */
|
||||
goto no_file;
|
||||
|
||||
if (!s1->error_set_jmp_enabled)
|
||||
/* tcc_state just was set by tcc_enter_state() */
|
||||
tcc_exit_state();
|
||||
tcc_exit_state(s1);
|
||||
|
||||
if (mode == ERROR_WARN) {
|
||||
if (s1->warn_error)
|
||||
|
@ -567,33 +560,30 @@ static void error1(int mode, const char *fmt, va_list ap)
|
|||
}
|
||||
if (f) {
|
||||
for(pf = s1->include_stack; pf < s1->include_stack_ptr; pf++)
|
||||
strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n",
|
||||
cstr_printf(&cs, "In file included from %s:%d:\n",
|
||||
(*pf)->filename, (*pf)->line_num);
|
||||
strcat_printf(buf, sizeof(buf), "%s:%d: ",
|
||||
cstr_printf(&cs, "%s:%d: ",
|
||||
f->filename, f->line_num - !!(tok_flags & TOK_FLAG_BOL));
|
||||
} else if (s1->current_filename) {
|
||||
strcat_printf(buf, sizeof(buf), "%s: ", s1->current_filename);
|
||||
cstr_printf(&cs, "%s: ", s1->current_filename);
|
||||
}
|
||||
|
||||
no_file:
|
||||
if (0 == buf[0])
|
||||
strcat_printf(buf, sizeof(buf), "tcc: ");
|
||||
if (mode == ERROR_WARN)
|
||||
strcat_printf(buf, sizeof(buf), "warning: ");
|
||||
else
|
||||
strcat_printf(buf, sizeof(buf), "error: ");
|
||||
strcat_vprintf(buf, sizeof(buf), fmt, ap);
|
||||
if (0 == cs.size)
|
||||
cstr_printf(&cs, "tcc: ");
|
||||
cstr_printf(&cs, mode == ERROR_WARN ? "warning: " : "error: ");
|
||||
cstr_vprintf(&cs, fmt, ap);
|
||||
if (!s1 || !s1->error_func) {
|
||||
/* default case: stderr */
|
||||
if (s1 && s1->output_type == TCC_OUTPUT_PREPROCESS && s1->ppfp == stdout)
|
||||
/* print a newline during tcc -E */
|
||||
printf("\n"), fflush(stdout);
|
||||
printf("\n"); /* print a newline during tcc -E */
|
||||
fflush(stdout); /* flush -v output */
|
||||
fprintf(stderr, "%s\n", buf);
|
||||
fprintf(stderr, "%s\n", (char*)cs.data);
|
||||
fflush(stderr); /* print error/warning now (win32) */
|
||||
} else {
|
||||
s1->error_func(s1->error_opaque, buf);
|
||||
s1->error_func(s1->error_opaque, (char*)cs.data);
|
||||
}
|
||||
cstr_free(&cs);
|
||||
if (s1) {
|
||||
if (mode != ERROR_WARN)
|
||||
s1->nb_errors++;
|
||||
|
@ -718,9 +708,9 @@ static int tcc_compile(TCCState *s1, int filetype, const char *str, int fd)
|
|||
variables, which may or may not have advantages */
|
||||
|
||||
tcc_enter_state(s1);
|
||||
s1->error_set_jmp_enabled = 1;
|
||||
|
||||
if (setjmp(s1->error_jmp_buf) == 0) {
|
||||
s1->error_set_jmp_enabled = 1;
|
||||
s1->nb_errors = 0;
|
||||
|
||||
if (fd == -1) {
|
||||
|
@ -738,19 +728,16 @@ static int tcc_compile(TCCState *s1, int filetype, const char *str, int fd)
|
|||
if (s1->output_type == TCC_OUTPUT_PREPROCESS) {
|
||||
tcc_preprocess(s1);
|
||||
} else if (filetype & (AFF_TYPE_ASM | AFF_TYPE_ASMPP)) {
|
||||
#ifdef CONFIG_TCC_ASM
|
||||
tcc_assemble(s1, !!(filetype & AFF_TYPE_ASMPP));
|
||||
#else
|
||||
tcc_error_noabort("asm not supported");
|
||||
#endif
|
||||
} else {
|
||||
tccgen_compile(s1);
|
||||
}
|
||||
}
|
||||
s1->error_set_jmp_enabled = 0;
|
||||
tccgen_finish(s1);
|
||||
preprocess_end(s1);
|
||||
tcc_exit_state();
|
||||
|
||||
s1->error_set_jmp_enabled = 0;
|
||||
tcc_exit_state(s1);
|
||||
|
||||
tccelf_end_file(s1);
|
||||
return s1->nb_errors != 0 ? -1 : 0;
|
||||
|
@ -821,11 +808,7 @@ LIBTCCAPI TCCState *tcc_new(void)
|
|||
|
||||
tccelf_new(s);
|
||||
|
||||
#ifdef _WIN32
|
||||
tcc_set_lib_path_w32(s);
|
||||
#else
|
||||
tcc_set_lib_path(s, CONFIG_TCCDIR);
|
||||
#endif
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
17
tcc.c
17
tcc.c
|
@ -154,10 +154,8 @@ static const char help2[] =
|
|||
|
||||
static const char version[] =
|
||||
"tcc version "TCC_VERSION
|
||||
#ifdef TCC_GIT_HASH
|
||||
" - " TCC_GIT_HASH
|
||||
#else
|
||||
" - unknown hash"
|
||||
#ifdef TCC_GITHASH
|
||||
" "TCC_GITHASH
|
||||
#endif
|
||||
" ("
|
||||
#ifdef TCC_TARGET_I386
|
||||
|
@ -276,7 +274,7 @@ int main(int argc0, char **argv0)
|
|||
{
|
||||
TCCState *s, *s1;
|
||||
int ret, opt, n = 0, t = 0, done;
|
||||
unsigned start_time = 0;
|
||||
unsigned start_time = 0, end_time = 0;
|
||||
const char *first_file;
|
||||
int argc; char **argv;
|
||||
FILE *ppfp = stdout;
|
||||
|
@ -372,6 +370,9 @@ redo:
|
|||
done = ret || ++n >= s->nb_files;
|
||||
} while (!done && (s->output_type != TCC_OUTPUT_OBJ || s->option_r));
|
||||
|
||||
if (s->do_bench)
|
||||
end_time = getclock_ms();
|
||||
|
||||
if (s->run_test) {
|
||||
t = 0;
|
||||
} else if (s->output_type == TCC_OUTPUT_PREPROCESS) {
|
||||
|
@ -391,13 +392,15 @@ redo:
|
|||
}
|
||||
}
|
||||
|
||||
if (s->do_bench && done && !(t | ret))
|
||||
tcc_print_stats(s, getclock_ms() - start_time);
|
||||
if (done && 0 == t && 0 == ret && s->do_bench)
|
||||
tcc_print_stats(s, end_time - start_time);
|
||||
|
||||
tcc_delete(s);
|
||||
if (!done)
|
||||
goto redo; /* compile more files with -c */
|
||||
if (t)
|
||||
goto redo; /* run more tests with -dt -run */
|
||||
|
||||
if (ppfp && ppfp != stdout)
|
||||
fclose(ppfp);
|
||||
return ret;
|
||||
|
|
212
tcc.h
212
tcc.h
|
@ -55,6 +55,7 @@ extern long double strtold (const char *__nptr, char **__endptr);
|
|||
# include <windows.h>
|
||||
# include <io.h> /* open, close etc. */
|
||||
# include <direct.h> /* getcwd */
|
||||
# include <malloc.h> /* alloca */
|
||||
# ifdef __GNUC__
|
||||
# include <stdint.h>
|
||||
# endif
|
||||
|
@ -91,6 +92,9 @@ extern long double strtold (const char *__nptr, char **__endptr);
|
|||
# define __x86_64__ 1
|
||||
# endif
|
||||
# endif
|
||||
# ifndef va_copy
|
||||
# define va_copy(a,b) a = b
|
||||
# endif
|
||||
# undef CONFIG_TCC_STATIC
|
||||
#endif
|
||||
|
||||
|
@ -124,7 +128,6 @@ extern long double strtold (const char *__nptr, char **__endptr);
|
|||
# define PRINTF_LIKE(x,y) __attribute__ ((format (printf, (x), (y))))
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
# define IS_DIRSEP(c) (c == '/' || c == '\\')
|
||||
# define IS_ABSPATH(p) (IS_DIRSEP(p[0]) || (p[0] && p[1] == ':' && IS_DIRSEP(p[2])))
|
||||
|
@ -179,6 +182,9 @@ extern long double strtold (const char *__nptr, char **__endptr);
|
|||
# ifdef _WIN32
|
||||
# define TCC_TARGET_PE 1
|
||||
# endif
|
||||
# ifdef __APPLE__
|
||||
# define TCC_TARGET_MACHO 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* only native compiler supports -run */
|
||||
|
@ -226,7 +232,7 @@ extern long double strtold (const char *__nptr, char **__endptr);
|
|||
/* No ten-byte long doubles on window and macos except in
|
||||
cross-compilers made by a mingw-GCC */
|
||||
#if defined TCC_TARGET_PE \
|
||||
|| (defined TCC_TARGET_MACHO && defined TCC_TARGET_X86_64) \
|
||||
|| (defined TCC_TARGET_MACHO && defined TCC_TARGET_ARM64) \
|
||||
|| (defined _WIN32 && !defined __GNUC__)
|
||||
# define TCC_USING_DOUBLE_FOR_LDOUBLE 1
|
||||
#endif
|
||||
|
@ -236,7 +242,7 @@ extern long double strtold (const char *__nptr, char **__endptr);
|
|||
#ifndef CONFIG_SYSROOT
|
||||
# define CONFIG_SYSROOT ""
|
||||
#endif
|
||||
#ifndef CONFIG_TCCDIR
|
||||
#if !defined CONFIG_TCCDIR && !defined _WIN32
|
||||
# define CONFIG_TCCDIR "/usr/local/lib/tcc"
|
||||
#endif
|
||||
#ifndef CONFIG_LDDIR
|
||||
|
@ -751,15 +757,6 @@ struct TCCState {
|
|||
unsigned char enable_new_dtags; /* -Wl,--enable-new-dtags */
|
||||
unsigned int cversion; /* supported C ISO version, 199901 (the default), 201112, ... */
|
||||
|
||||
char *tcc_lib_path; /* CONFIG_TCCDIR or -B option */
|
||||
char *soname; /* as specified on the command line (-soname) */
|
||||
char *rpath; /* as specified on the command line (-Wl,-rpath=) */
|
||||
|
||||
/* output type, see TCC_OUTPUT_XXX */
|
||||
int output_type;
|
||||
/* output format, see TCC_OUTPUT_FORMAT_xxx */
|
||||
int output_format;
|
||||
|
||||
/* C language options */
|
||||
unsigned char char_is_unsigned;
|
||||
unsigned char leading_underscore;
|
||||
|
@ -776,10 +773,14 @@ struct TCCState {
|
|||
unsigned char warn_implicit_function_declaration;
|
||||
unsigned char warn_discarded_qualifiers;
|
||||
#define WARN_ON 1 /* warning is on (-Woption) */
|
||||
#define WARN_ERR 2 /* warning is an error (-Werror=option) */
|
||||
#define WARN_NOE 4 /* warning is not an error (-Wno-error=option) */
|
||||
unsigned char warn_num; /* temp var for tcc_warning_c() */
|
||||
|
||||
unsigned char option_r; /* option -r */
|
||||
unsigned char do_bench; /* option -bench */
|
||||
unsigned char just_deps; /* option -M */
|
||||
unsigned char gen_deps; /* option -MD */
|
||||
unsigned char include_sys_deps; /* option -MD */
|
||||
|
||||
/* compile with debug symbol (and use them if error during execution) */
|
||||
unsigned char do_debug;
|
||||
unsigned char do_backtrace;
|
||||
|
@ -789,30 +790,41 @@ struct TCCState {
|
|||
#endif
|
||||
unsigned char test_coverage; /* generate test coverage code */
|
||||
|
||||
#ifdef TCC_TARGET_ARM
|
||||
enum float_abi float_abi; /* float ABI of the generated code*/
|
||||
#endif
|
||||
int run_test; /* nth test to run with -dt -run */
|
||||
|
||||
addr_t text_addr; /* address of text section */
|
||||
unsigned char has_text_addr;
|
||||
|
||||
unsigned section_align; /* section alignment */
|
||||
|
||||
/* use GNU C extensions */
|
||||
unsigned char gnu_ext;
|
||||
/* use TinyCC extensions */
|
||||
unsigned char tcc_ext;
|
||||
|
||||
char *init_symbol; /* symbols to call at load-time (not used currently) */
|
||||
char *fini_symbol; /* symbols to call at unload-time (not used currently) */
|
||||
unsigned char dflag; /* -dX value */
|
||||
unsigned char Pflag; /* -P switch (LINE_MACRO_OUTPUT_FORMAT) */
|
||||
|
||||
#ifdef TCC_TARGET_I386
|
||||
int seg_size; /* 32. Can be 16 with i386 assembler (.code16) */
|
||||
#endif
|
||||
#ifdef TCC_TARGET_X86_64
|
||||
unsigned char nosse; /* For -mno-sse support. */
|
||||
#endif
|
||||
#ifdef TCC_TARGET_ARM
|
||||
unsigned char float_abi; /* float ABI of the generated code*/
|
||||
#endif
|
||||
|
||||
unsigned char has_text_addr;
|
||||
addr_t text_addr; /* address of text section */
|
||||
unsigned section_align; /* section alignment */
|
||||
#ifdef TCC_TARGET_I386
|
||||
int seg_size; /* 32. Can be 16 with i386 assembler (.code16) */
|
||||
#endif
|
||||
|
||||
char *tcc_lib_path; /* CONFIG_TCCDIR or -B option */
|
||||
char *soname; /* as specified on the command line (-soname) */
|
||||
char *rpath; /* as specified on the command line (-Wl,-rpath=) */
|
||||
|
||||
char *init_symbol; /* symbols to call at load-time (not used currently) */
|
||||
char *fini_symbol; /* symbols to call at unload-time (not used currently) */
|
||||
|
||||
/* output type, see TCC_OUTPUT_XXX */
|
||||
int output_type;
|
||||
/* output format, see TCC_OUTPUT_FORMAT_xxx */
|
||||
int output_format;
|
||||
/* nth test to run with -dt -run */
|
||||
int run_test;
|
||||
|
||||
/* array of all loaded dlls (including those referenced by loaded dlls) */
|
||||
DLLReference **loaded_dlls;
|
||||
|
@ -847,13 +859,6 @@ struct TCCState {
|
|||
|
||||
/* output file for preprocessing (-E) */
|
||||
FILE *ppfp;
|
||||
enum {
|
||||
LINE_MACRO_OUTPUT_FORMAT_GCC,
|
||||
LINE_MACRO_OUTPUT_FORMAT_NONE,
|
||||
LINE_MACRO_OUTPUT_FORMAT_STD,
|
||||
LINE_MACRO_OUTPUT_FORMAT_P10 = 11
|
||||
} Pflag; /* -P switch */
|
||||
char dflag; /* -dX value */
|
||||
|
||||
/* for -MD/-MF: collected dependencies for this compilation */
|
||||
char **target_deps;
|
||||
|
@ -922,11 +927,11 @@ struct TCCState {
|
|||
int nb_sym_attrs;
|
||||
/* ptr to next reloc entry reused */
|
||||
ElfW_Rel *qrel;
|
||||
# define qrel s1->qrel
|
||||
#define qrel s1->qrel
|
||||
|
||||
#ifdef TCC_TARGET_RISCV64
|
||||
struct pcrel_hi { addr_t addr, val; } last_hi;
|
||||
# define last_hi s1->last_hi
|
||||
#define last_hi s1->last_hi
|
||||
#endif
|
||||
|
||||
#ifdef TCC_TARGET_PE
|
||||
|
@ -963,8 +968,6 @@ struct TCCState {
|
|||
int rt_num_callers;
|
||||
#endif
|
||||
|
||||
int fd, cc; /* used by tcc_load_ldscript */
|
||||
|
||||
/* benchmark info */
|
||||
int total_idents;
|
||||
int total_lines;
|
||||
|
@ -974,7 +977,10 @@ struct TCCState {
|
|||
/* option -dnum (for general development purposes) */
|
||||
int g_debug;
|
||||
|
||||
/* for warnings/errors for object files*/
|
||||
/* used by tcc_load_ldscript */
|
||||
int fd, cc;
|
||||
|
||||
/* for warnings/errors for object files */
|
||||
const char *current_filename;
|
||||
|
||||
/* used by main and tcc_parse_args only */
|
||||
|
@ -982,11 +988,6 @@ struct TCCState {
|
|||
int nb_files; /* number thereof */
|
||||
int nb_libraries; /* number of libs thereof */
|
||||
char *outfile; /* output filename */
|
||||
unsigned char option_r; /* option -r */
|
||||
unsigned char do_bench; /* option -bench */
|
||||
int just_deps; /* option -M */
|
||||
int gen_deps; /* option -MD */
|
||||
int include_sys_deps; /* option -MD */
|
||||
char *deps_outfile; /* option -MF */
|
||||
int argc;
|
||||
char **argv;
|
||||
|
@ -1161,91 +1162,6 @@ struct filespec {
|
|||
/* all identifiers and strings have token above that */
|
||||
#define TOK_IDENT 256
|
||||
|
||||
#define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
|
||||
#define TOK_ASM_int TOK_INT
|
||||
#define DEF_ASMDIR(x) DEF(TOK_ASMDIR_ ## x, "." #x)
|
||||
#define TOK_ASMDIR_FIRST TOK_ASMDIR_byte
|
||||
#define TOK_ASMDIR_LAST TOK_ASMDIR_section
|
||||
|
||||
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
|
||||
/* only used for i386 asm opcodes definitions */
|
||||
#define DEF_BWL(x) \
|
||||
DEF(TOK_ASM_ ## x ## b, #x "b") \
|
||||
DEF(TOK_ASM_ ## x ## w, #x "w") \
|
||||
DEF(TOK_ASM_ ## x ## l, #x "l") \
|
||||
DEF(TOK_ASM_ ## x, #x)
|
||||
#define DEF_WL(x) \
|
||||
DEF(TOK_ASM_ ## x ## w, #x "w") \
|
||||
DEF(TOK_ASM_ ## x ## l, #x "l") \
|
||||
DEF(TOK_ASM_ ## x, #x)
|
||||
#ifdef TCC_TARGET_X86_64
|
||||
# define DEF_BWLQ(x) \
|
||||
DEF(TOK_ASM_ ## x ## b, #x "b") \
|
||||
DEF(TOK_ASM_ ## x ## w, #x "w") \
|
||||
DEF(TOK_ASM_ ## x ## l, #x "l") \
|
||||
DEF(TOK_ASM_ ## x ## q, #x "q") \
|
||||
DEF(TOK_ASM_ ## x, #x)
|
||||
# define DEF_WLQ(x) \
|
||||
DEF(TOK_ASM_ ## x ## w, #x "w") \
|
||||
DEF(TOK_ASM_ ## x ## l, #x "l") \
|
||||
DEF(TOK_ASM_ ## x ## q, #x "q") \
|
||||
DEF(TOK_ASM_ ## x, #x)
|
||||
# define DEF_BWLX DEF_BWLQ
|
||||
# define DEF_WLX DEF_WLQ
|
||||
/* number of sizes + 1 */
|
||||
# define NBWLX 5
|
||||
#else
|
||||
# define DEF_BWLX DEF_BWL
|
||||
# define DEF_WLX DEF_WL
|
||||
/* number of sizes + 1 */
|
||||
# define NBWLX 4
|
||||
#endif
|
||||
|
||||
#define DEF_FP1(x) \
|
||||
DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \
|
||||
DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
|
||||
DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
|
||||
DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")
|
||||
|
||||
#define DEF_FP(x) \
|
||||
DEF(TOK_ASM_ ## f ## x, "f" #x ) \
|
||||
DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
|
||||
DEF_FP1(x)
|
||||
|
||||
#define DEF_ASMTEST(x,suffix) \
|
||||
DEF_ASM(x ## o ## suffix) \
|
||||
DEF_ASM(x ## no ## suffix) \
|
||||
DEF_ASM(x ## b ## suffix) \
|
||||
DEF_ASM(x ## c ## suffix) \
|
||||
DEF_ASM(x ## nae ## suffix) \
|
||||
DEF_ASM(x ## nb ## suffix) \
|
||||
DEF_ASM(x ## nc ## suffix) \
|
||||
DEF_ASM(x ## ae ## suffix) \
|
||||
DEF_ASM(x ## e ## suffix) \
|
||||
DEF_ASM(x ## z ## suffix) \
|
||||
DEF_ASM(x ## ne ## suffix) \
|
||||
DEF_ASM(x ## nz ## suffix) \
|
||||
DEF_ASM(x ## be ## suffix) \
|
||||
DEF_ASM(x ## na ## suffix) \
|
||||
DEF_ASM(x ## nbe ## suffix) \
|
||||
DEF_ASM(x ## a ## suffix) \
|
||||
DEF_ASM(x ## s ## suffix) \
|
||||
DEF_ASM(x ## ns ## suffix) \
|
||||
DEF_ASM(x ## p ## suffix) \
|
||||
DEF_ASM(x ## pe ## suffix) \
|
||||
DEF_ASM(x ## np ## suffix) \
|
||||
DEF_ASM(x ## po ## suffix) \
|
||||
DEF_ASM(x ## l ## suffix) \
|
||||
DEF_ASM(x ## nge ## suffix) \
|
||||
DEF_ASM(x ## nl ## suffix) \
|
||||
DEF_ASM(x ## ge ## suffix) \
|
||||
DEF_ASM(x ## le ## suffix) \
|
||||
DEF_ASM(x ## ng ## suffix) \
|
||||
DEF_ASM(x ## nle ## suffix) \
|
||||
DEF_ASM(x ## g ## suffix)
|
||||
|
||||
#endif /* defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 */
|
||||
|
||||
enum tcc_token {
|
||||
TOK_LAST = TOK_IDENT - 1
|
||||
#define DEF(id, str) ,id
|
||||
|
@ -1306,6 +1222,7 @@ ST_FUNC void cstr_wccat(CString *cstr, int ch);
|
|||
ST_FUNC void cstr_new(CString *cstr);
|
||||
ST_FUNC void cstr_free(CString *cstr);
|
||||
ST_FUNC int cstr_printf(CString *cs, const char *fmt, ...) PRINTF_LIKE(2,3);
|
||||
ST_FUNC int cstr_vprintf(CString *cstr, const char *fmt, va_list ap);
|
||||
ST_FUNC void cstr_reset(CString *cstr);
|
||||
|
||||
ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen);
|
||||
|
@ -1397,6 +1314,13 @@ ST_DATA TokenSym **table_ident;
|
|||
#define IS_ID 2
|
||||
#define IS_NUM 4
|
||||
|
||||
enum line_macro_output_format {
|
||||
LINE_MACRO_OUTPUT_FORMAT_GCC,
|
||||
LINE_MACRO_OUTPUT_FORMAT_NONE,
|
||||
LINE_MACRO_OUTPUT_FORMAT_STD,
|
||||
LINE_MACRO_OUTPUT_FORMAT_P10 = 11
|
||||
};
|
||||
|
||||
ST_FUNC TokenSym *tok_alloc(const char *str, int len);
|
||||
ST_FUNC int tok_alloc_const(const char *str);
|
||||
ST_FUNC const char *get_tok_str(int v, CValue *cv);
|
||||
|
@ -1770,12 +1694,12 @@ ST_FUNC int tcc_load_coff(TCCState * s1, int fd);
|
|||
/* ------------ tccasm.c ------------ */
|
||||
ST_FUNC void asm_instr(void);
|
||||
ST_FUNC void asm_global_instr(void);
|
||||
ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess);
|
||||
#ifdef CONFIG_TCC_ASM
|
||||
ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, const char *name, const char **pp);
|
||||
ST_FUNC Sym* get_asm_sym(int name, Sym *csym);
|
||||
ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe);
|
||||
ST_FUNC int asm_int_expr(TCCState *s1);
|
||||
ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess);
|
||||
/* ------------ i386-asm.c ------------ */
|
||||
ST_FUNC void gen_expr32(ExprValue *pe);
|
||||
#ifdef TCC_TARGET_X86_64
|
||||
|
@ -1844,6 +1768,28 @@ ST_FUNC void tcc_tool_cross(TCCState *s, char **argv, int option);
|
|||
ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename);
|
||||
#endif
|
||||
|
||||
/********************************************************/
|
||||
#if CONFIG_TCC_SEMLOCK
|
||||
#if defined _WIN32
|
||||
typedef struct { int init; CRITICAL_SECTION cr; } TCCSem;
|
||||
#elif defined __APPLE__
|
||||
#include <dispatch/dispatch.h>
|
||||
typedef struct { int init; dispatch_semaphore_t sem; } TCCSem;
|
||||
#else
|
||||
#include <semaphore.h>
|
||||
typedef struct { int init; sem_t sem; } TCCSem;
|
||||
#endif
|
||||
ST_FUNC void wait_sem(TCCSem *p);
|
||||
ST_FUNC void post_sem(TCCSem *p);
|
||||
#define TCC_SEM(s) TCCSem s
|
||||
#define WAIT_SEM wait_sem
|
||||
#define POST_SEM post_sem
|
||||
#else
|
||||
#define TCC_SEM(s)
|
||||
#define WAIT_SEM(p)
|
||||
#define POST_SEM(p)
|
||||
#endif
|
||||
|
||||
/********************************************************/
|
||||
#undef ST_DATA
|
||||
#if ONE_SOURCE
|
||||
|
@ -1875,7 +1821,7 @@ ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename)
|
|||
#define total_bytes TCC_STATE_VAR(total_bytes)
|
||||
|
||||
PUB_FUNC void tcc_enter_state(TCCState *s1);
|
||||
PUB_FUNC void tcc_exit_state(void);
|
||||
PUB_FUNC void tcc_exit_state(TCCState *s1);
|
||||
|
||||
/* conditional warning depending on switch */
|
||||
#define tcc_warning_c(sw) TCC_SET_STATE((\
|
||||
|
|
17
tccasm.c
17
tccasm.c
|
@ -1298,4 +1298,21 @@ ST_FUNC void asm_global_instr(void)
|
|||
cstr_free(&astr);
|
||||
nocode_wanted = saved_nocode_wanted;
|
||||
}
|
||||
|
||||
/********************************************************/
|
||||
#else
|
||||
ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)
|
||||
{
|
||||
tcc_error("asm not supported");
|
||||
}
|
||||
|
||||
ST_FUNC void asm_instr(void)
|
||||
{
|
||||
tcc_error("inline asm() not supported");
|
||||
}
|
||||
|
||||
ST_FUNC void asm_global_instr(void)
|
||||
{
|
||||
tcc_error("inline asm() not supported");
|
||||
}
|
||||
#endif /* CONFIG_TCC_ASM */
|
||||
|
|
34
tccgen.c
34
tccgen.c
|
@ -97,7 +97,7 @@ static CString initstr;
|
|||
#define VT_PTRDIFF_T (VT_LONG | VT_LLONG)
|
||||
#endif
|
||||
|
||||
ST_DATA struct switch_t {
|
||||
static struct switch_t {
|
||||
struct case_t {
|
||||
int64_t v1, v2;
|
||||
int sym;
|
||||
|
@ -111,12 +111,12 @@ ST_DATA struct switch_t {
|
|||
|
||||
#define MAX_TEMP_LOCAL_VARIABLE_NUMBER 8
|
||||
/*list of temporary local variables on the stack in current function. */
|
||||
ST_DATA struct temp_local_variable {
|
||||
static struct temp_local_variable {
|
||||
int location; //offset on stack. Svalue.c.i
|
||||
short size;
|
||||
short align;
|
||||
} arr_temp_local_vars[MAX_TEMP_LOCAL_VARIABLE_NUMBER];
|
||||
short nb_temp_local_vars;
|
||||
static int nb_temp_local_vars;
|
||||
|
||||
static struct scope {
|
||||
struct scope *prev;
|
||||
|
@ -132,6 +132,11 @@ typedef struct {
|
|||
Sym *flex_array_ref;
|
||||
} init_params;
|
||||
|
||||
#if 1
|
||||
#define precedence_parser
|
||||
static void init_prec(void);
|
||||
#endif
|
||||
|
||||
/********************************************************/
|
||||
/* stab debug support */
|
||||
|
||||
|
@ -215,23 +220,6 @@ static struct {
|
|||
} tcov_data;
|
||||
|
||||
/********************************************************/
|
||||
#if 1
|
||||
#define precedence_parser
|
||||
static void init_prec(void);
|
||||
#endif
|
||||
/********************************************************/
|
||||
#ifndef CONFIG_TCC_ASM
|
||||
ST_FUNC void asm_instr(void)
|
||||
{
|
||||
tcc_error("inline asm() not supported");
|
||||
}
|
||||
ST_FUNC void asm_global_instr(void)
|
||||
{
|
||||
tcc_error("inline asm() not supported");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
static void gen_cast(CType *type);
|
||||
static void gen_cast_s(int t);
|
||||
static inline CType *pointed_type(CType *type);
|
||||
|
@ -7247,7 +7235,7 @@ static void vla_leave(struct scope *o)
|
|||
/* ------------------------------------------------------------------------- */
|
||||
/* local scopes */
|
||||
|
||||
void new_scope(struct scope *o)
|
||||
static void new_scope(struct scope *o)
|
||||
{
|
||||
/* copy and link previous scope */
|
||||
*o = *cur_scope;
|
||||
|
@ -7264,7 +7252,7 @@ void new_scope(struct scope *o)
|
|||
tcc_debug_stabn(tcc_state, N_LBRAC, ind - func_ind);
|
||||
}
|
||||
|
||||
void prev_scope(struct scope *o, int is_expr)
|
||||
static void prev_scope(struct scope *o, int is_expr)
|
||||
{
|
||||
vla_leave(o->prev);
|
||||
|
||||
|
@ -7292,7 +7280,7 @@ void prev_scope(struct scope *o, int is_expr)
|
|||
}
|
||||
|
||||
/* leave a scope via break/continue(/goto) */
|
||||
void leave_scope(struct scope *o)
|
||||
static void leave_scope(struct scope *o)
|
||||
{
|
||||
if (!o)
|
||||
return;
|
||||
|
|
|
@ -517,7 +517,7 @@ static void create_symtab(TCCState *s1, struct macho *mo)
|
|||
}
|
||||
tcc_enter_state(s1); /* qsort needs global state */
|
||||
qsort(pn, sym_end - 1, sizeof(*pn), machosymcmp);
|
||||
tcc_exit_state();
|
||||
tcc_exit_state(s1);
|
||||
mo->e2msym = tcc_malloc(sym_end * sizeof(*mo->e2msym));
|
||||
mo->e2msym[0] = -1;
|
||||
for (sym_index = 1; sym_index < sym_end; ++sym_index) {
|
||||
|
|
92
tccpe.c
92
tccpe.c
|
@ -1543,8 +1543,6 @@ static int pe_add_dllref(TCCState *s1, const char *dllname)
|
|||
return s1->nb_loaded_dlls;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
||||
static int read_mem(int fd, unsigned offset, void *buffer, unsigned len)
|
||||
{
|
||||
lseek(fd, offset, SEEK_SET);
|
||||
|
@ -1553,11 +1551,10 @@ static int read_mem(int fd, unsigned offset, void *buffer, unsigned len)
|
|||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
||||
PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp)
|
||||
static int get_dllexports(int fd, char **pp)
|
||||
{
|
||||
int l, i, n, n0, ret;
|
||||
char *p;
|
||||
int fd;
|
||||
|
||||
IMAGE_SECTION_HEADER ish;
|
||||
IMAGE_EXPORT_DIRECTORY ied;
|
||||
|
@ -1569,11 +1566,6 @@ PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp)
|
|||
|
||||
n = n0 = 0;
|
||||
p = NULL;
|
||||
ret = -1;
|
||||
|
||||
fd = open(filename, O_RDONLY | O_BINARY);
|
||||
if (fd < 0)
|
||||
goto the_end_1;
|
||||
ret = 1;
|
||||
if (!read_mem(fd, 0, &dh, sizeof dh))
|
||||
goto the_end;
|
||||
|
@ -1640,8 +1632,6 @@ found:
|
|||
the_end_0:
|
||||
ret = 0;
|
||||
the_end:
|
||||
close(fd);
|
||||
the_end_1:
|
||||
*pp = p;
|
||||
return ret;
|
||||
}
|
||||
|
@ -1694,47 +1684,53 @@ quit:
|
|||
|
||||
static char *trimfront(char *p)
|
||||
{
|
||||
while (*p && (unsigned char)*p <= ' ')
|
||||
while ((unsigned char)*p <= ' ' && *p && *p != '\n')
|
||||
++p;
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
static char *trimback(char *a, char *e)
|
||||
{
|
||||
while (e > a && (unsigned char)e[-1] <= ' ')
|
||||
--e;
|
||||
*e = 0;;
|
||||
return a;
|
||||
}*/
|
||||
|
||||
static char *get_token(char **s, char *f)
|
||||
{
|
||||
char *p = *s, *e;
|
||||
p = e = trimfront(p);
|
||||
while ((unsigned char)*e > ' ')
|
||||
++e;
|
||||
*s = trimfront(e);
|
||||
*f = **s; *e = 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
static int pe_load_def(TCCState *s1, int fd)
|
||||
{
|
||||
int state = 0, ret = -1, dllindex = 0, ord;
|
||||
char line[400], dllname[80], *p, *x;
|
||||
FILE *fp;
|
||||
|
||||
fp = fdopen(dup(fd), "rb");
|
||||
while (fgets(line, sizeof line, fp))
|
||||
{
|
||||
p = trimfront(trimback(line, strchr(line, 0)));
|
||||
if (0 == *p || ';' == *p)
|
||||
continue;
|
||||
char dllname[80], *buf, *line, *p, *x, next;
|
||||
|
||||
buf = tcc_load_text(fd);
|
||||
for (line = buf;; ++line) {
|
||||
p = get_token(&line, &next);
|
||||
if (!(*p && *p != ';'))
|
||||
goto skip;
|
||||
switch (state) {
|
||||
case 0:
|
||||
if (0 != strnicmp(p, "LIBRARY", 7))
|
||||
if (0 != stricmp(p, "LIBRARY") || next == '\n')
|
||||
goto quit;
|
||||
pstrcpy(dllname, sizeof dllname, trimfront(p+7));
|
||||
pstrcpy(dllname, sizeof dllname, get_token(&line, &next));
|
||||
++state;
|
||||
continue;
|
||||
|
||||
break;
|
||||
case 1:
|
||||
if (0 != stricmp(p, "EXPORTS"))
|
||||
goto quit;
|
||||
++state;
|
||||
continue;
|
||||
|
||||
break;
|
||||
case 2:
|
||||
dllindex = pe_add_dllref(s1, dllname);
|
||||
++state;
|
||||
|
@ -1742,33 +1738,34 @@ static int pe_load_def(TCCState *s1, int fd)
|
|||
default:
|
||||
/* get ordinal and will store in sym->st_value */
|
||||
ord = 0;
|
||||
x = strchr(p, ' ');
|
||||
if (x) {
|
||||
*x = 0, x = strrchr(x + 1, '@');
|
||||
if (x) {
|
||||
char *d;
|
||||
ord = (int)strtol(x + 1, &d, 10);
|
||||
if (*d)
|
||||
ord = 0;
|
||||
}
|
||||
if (next == '@') {
|
||||
x = get_token(&line, &next);
|
||||
ord = (int)strtol(x + 1, &x, 10);
|
||||
}
|
||||
//printf("token %s ; %s : %d\n", dllname, p, ord);
|
||||
pe_putimport(s1, dllindex, p, ord);
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
skip:
|
||||
while ((unsigned char)next > ' ')
|
||||
get_token(&line, &next);
|
||||
if (next != '\n')
|
||||
break;
|
||||
}
|
||||
ret = 0;
|
||||
quit:
|
||||
fclose(fp);
|
||||
tcc_free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
static int pe_load_dll(TCCState *s1, const char *filename)
|
||||
|
||||
static int pe_load_dll(TCCState *s1, int fd, const char *filename)
|
||||
{
|
||||
char *p, *q;
|
||||
int index, ret;
|
||||
|
||||
ret = tcc_get_dllexports(filename, &p);
|
||||
ret = get_dllexports(fd, &p);
|
||||
if (ret) {
|
||||
return -1;
|
||||
} else if (p) {
|
||||
|
@ -1780,7 +1777,6 @@ static int pe_load_dll(TCCState *s1, const char *filename)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
ST_FUNC int pe_load_file(struct TCCState *s1, int fd, const char *filename)
|
||||
{
|
||||
int ret = -1;
|
||||
|
@ -1790,7 +1786,17 @@ ST_FUNC int pe_load_file(struct TCCState *s1, int fd, const char *filename)
|
|||
else if (pe_load_res(s1, fd) == 0)
|
||||
ret = 0;
|
||||
else if (read_mem(fd, 0, buf, 4) && 0 == memcmp(buf, "MZ", 2))
|
||||
ret = pe_load_dll(s1, filename);
|
||||
ret = pe_load_dll(s1, fd, filename);
|
||||
return ret;
|
||||
}
|
||||
|
||||
PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp)
|
||||
{
|
||||
int ret, fd = open(filename, O_RDONLY | O_BINARY);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
ret = get_dllexports(fd, pp);
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
13
tccpp.c
13
tccpp.c
|
@ -404,7 +404,7 @@ ST_FUNC void cstr_reset(CString *cstr)
|
|||
cstr->size = 0;
|
||||
}
|
||||
|
||||
ST_FUNC int cstr_printf(CString *cstr, const char *fmt, ...)
|
||||
ST_FUNC int cstr_vprintf(CString *cstr, const char *fmt, va_list ap)
|
||||
{
|
||||
va_list v;
|
||||
int len, size = 80;
|
||||
|
@ -413,7 +413,7 @@ ST_FUNC int cstr_printf(CString *cstr, const char *fmt, ...)
|
|||
if (size > cstr->size_allocated)
|
||||
cstr_realloc(cstr, size);
|
||||
size = cstr->size_allocated - cstr->size;
|
||||
va_start(v, fmt);
|
||||
va_copy(v, ap);
|
||||
len = vsnprintf((char*)cstr->data + cstr->size, size, fmt, v);
|
||||
va_end(v);
|
||||
if (len > 0 && len < size)
|
||||
|
@ -424,6 +424,15 @@ ST_FUNC int cstr_printf(CString *cstr, const char *fmt, ...)
|
|||
return len;
|
||||
}
|
||||
|
||||
ST_FUNC int cstr_printf(CString *cstr, const char *fmt, ...)
|
||||
{
|
||||
va_list ap; int len;
|
||||
va_start(ap, fmt);
|
||||
len = cstr_vprintf(cstr, fmt, ap);
|
||||
va_end(ap);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* XXX: unicode ? */
|
||||
static void add_char(CString *cstr, int c)
|
||||
{
|
||||
|
|
16
tcctok.h
16
tcctok.h
|
@ -1,3 +1,4 @@
|
|||
/*********************************************************************/
|
||||
/* keywords */
|
||||
DEF(TOK_INT, "int")
|
||||
DEF(TOK_VOID, "void")
|
||||
|
@ -343,8 +344,17 @@
|
|||
DEF(TOK_longjmp, "longjmp")
|
||||
#endif
|
||||
|
||||
|
||||
/*********************************************************************/
|
||||
/* Tiny Assembler */
|
||||
DEF_ASMDIR(byte) /* must be first directive */
|
||||
#define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
|
||||
#define DEF_ASMDIR(x) DEF(TOK_ASMDIR_ ## x, "." #x)
|
||||
#define TOK_ASM_int TOK_INT
|
||||
|
||||
#define TOK_ASMDIR_FIRST TOK_ASMDIR_byte
|
||||
#define TOK_ASMDIR_LAST TOK_ASMDIR_section
|
||||
|
||||
DEF_ASMDIR(byte) /* must be first directive */
|
||||
DEF_ASMDIR(word)
|
||||
DEF_ASMDIR(align)
|
||||
DEF_ASMDIR(balign)
|
||||
|
@ -383,14 +393,16 @@
|
|||
DEF_ASMDIR(short)
|
||||
DEF_ASMDIR(long)
|
||||
DEF_ASMDIR(int)
|
||||
DEF_ASMDIR(section) /* must be last directive */
|
||||
DEF_ASMDIR(section) /* must be last directive */
|
||||
|
||||
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
|
||||
#include "i386-tok.h"
|
||||
#endif
|
||||
|
||||
#if defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64
|
||||
#include "arm-tok.h"
|
||||
#endif
|
||||
|
||||
#if defined TCC_TARGET_RISCV64
|
||||
#include "riscv64-tok.h"
|
||||
#endif
|
||||
|
|
|
@ -385,10 +385,8 @@ usage:
|
|||
ret = 0;
|
||||
|
||||
the_end:
|
||||
/* cannot free memory received from tcc_get_dllexports
|
||||
if it came from a dll */
|
||||
/* if (p)
|
||||
tcc_free(p); */
|
||||
if (p)
|
||||
tcc_free(p);
|
||||
if (fp)
|
||||
fclose(fp);
|
||||
if (op)
|
||||
|
|
|
@ -220,9 +220,10 @@ TF_TYPE(thread_test_complex, vn)
|
|||
void time_tcc(int n, const char *src)
|
||||
{
|
||||
TCCState *s;
|
||||
int ret;
|
||||
while (--n >= 0) {
|
||||
int ret, i = 0;
|
||||
while (i++ < n) {
|
||||
s = new_state(1);
|
||||
printf(" %d", i), fflush(stdout);
|
||||
ret = tcc_add_file(s, src);
|
||||
tcc_delete(s);
|
||||
if (ret < 0)
|
||||
|
@ -277,10 +278,10 @@ int main(int argc, char **argv)
|
|||
printf("\n (%u ms)\n", getclock_ms() - t);
|
||||
#endif
|
||||
#if 1
|
||||
printf("compiling tcc.c 10 times\n"), fflush(stdout);
|
||||
printf("compiling tcc.c 10 times\n "), fflush(stdout);
|
||||
t = getclock_ms();
|
||||
time_tcc(10, argv[1]);
|
||||
printf(" (%u ms)\n", getclock_ms() - t), fflush(stdout);
|
||||
printf("\n (%u ms)\n", getclock_ms() - t), fflush(stdout);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue