mirror of
https://github.com/mirror/tinycc.git
synced 2025-01-27 06:10:06 +08:00
bcheck: remove "tcc_location()" & x86_64 double fix
using (modified) tcc_backtrace() instead. Also Also fix the original bug with doubles on x86_64. (which was not caused by incr_offset() actually). See598134fff6
Also cleanup on_exit() stuff Fromfef701b57f
This commit is contained in:
parent
ff2a372a9a
commit
3f3cbb51ed
@ -41,7 +41,7 @@
|
|||||||
#define BOUND_STATISTIC (1)
|
#define BOUND_STATISTIC (1)
|
||||||
|
|
||||||
#if BOUND_DEBUG
|
#if BOUND_DEBUG
|
||||||
#define dprintf(a...) if (print_calls) { bounds_loc; fprintf(a); }
|
#define dprintf(a...) if (print_calls) { bounds_loc(a); }
|
||||||
#else
|
#else
|
||||||
#define dprintf(a...)
|
#define dprintf(a...)
|
||||||
#endif
|
#endif
|
||||||
@ -446,7 +446,6 @@ static unsigned long long bound_splay_delete;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
int tcc_backtrace(const char *fmt, ...);
|
int tcc_backtrace(const char *fmt, ...);
|
||||||
void tcc_location(const char *fmt);
|
|
||||||
|
|
||||||
/* print a bound error message */
|
/* print a bound error message */
|
||||||
#define bound_warning(...) \
|
#define bound_warning(...) \
|
||||||
@ -463,10 +462,10 @@ void tcc_location(const char *fmt);
|
|||||||
exit(255); \
|
exit(255); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define bounds_loc \
|
#define bounds_loc(fp, ...) \
|
||||||
do { \
|
do { \
|
||||||
WAIT_SEM (); \
|
WAIT_SEM (); \
|
||||||
tcc_location("^bcheck.c^"); \
|
tcc_backtrace("^bcheck.c^\001" __VA_ARGS__); \
|
||||||
POST_SEM (); \
|
POST_SEM (); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
REDIR(__bt_init) \
|
REDIR(__bt_init) \
|
||||||
REDIR(__bt_exit) \
|
REDIR(__bt_exit) \
|
||||||
REDIR(tcc_backtrace) \
|
REDIR(tcc_backtrace) \
|
||||||
REDIR(tcc_location) \
|
|
||||||
\
|
\
|
||||||
REDIR(__bound_ptr_add) \
|
REDIR(__bound_ptr_add) \
|
||||||
REDIR(__bound_ptr_indir1) \
|
REDIR(__bound_ptr_indir1) \
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#include "../tccrun.c"
|
#include "../tccrun.c"
|
||||||
|
|
||||||
int (*__rt_error)(void*, void*, const char *, va_list);
|
int (*__rt_error)(void*, void*, const char *, va_list);
|
||||||
void (*__rt_location)(void*, void*, const char *);
|
|
||||||
__attribute__((weak)) void __bound_checking_lock(void);
|
__attribute__((weak)) void __bound_checking_lock(void);
|
||||||
__attribute__((weak)) void __bound_checking_unlock(void);
|
__attribute__((weak)) void __bound_checking_unlock(void);
|
||||||
|
|
||||||
@ -34,7 +33,6 @@ void __bt_init(rt_context *p, int num_callers)
|
|||||||
rc->num_callers = num_callers - 1;
|
rc->num_callers = num_callers - 1;
|
||||||
rc->top_func = main;
|
rc->top_func = main;
|
||||||
__rt_error = _rt_error;
|
__rt_error = _rt_error;
|
||||||
__rt_location = _rt_location;
|
|
||||||
set_exception_handler();
|
set_exception_handler();
|
||||||
} else {
|
} else {
|
||||||
p->next = rc->next, rc->next = p;
|
p->next = rc->next, rc->next = p;
|
||||||
|
16
lib/bt-log.c
16
lib/bt-log.c
@ -6,7 +6,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
int (*__rt_error)(void*, void*, const char *, va_list);
|
int (*__rt_error)(void*, void*, const char *, va_list);
|
||||||
void (*__rt_location)(void*, void*, const char *);
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# define DLL_EXPORT __declspec(dllexport)
|
# define DLL_EXPORT __declspec(dllexport)
|
||||||
@ -32,26 +31,19 @@ DLL_EXPORT int tcc_backtrace(const char *fmt, ...)
|
|||||||
ret = __rt_error(fp, ip, fmt, ap);
|
ret = __rt_error(fp, ip, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
} else {
|
} else {
|
||||||
const char *p;
|
const char *p, *nl = "\n";
|
||||||
if (fmt[0] == '^' && (p = strchr(fmt + 1, fmt[0])))
|
if (fmt[0] == '^' && (p = strchr(fmt + 1, fmt[0])))
|
||||||
fmt = p + 1;
|
fmt = p + 1;
|
||||||
|
if (fmt[0] == '\001')
|
||||||
|
++fmt, nl = "";
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
ret = vfprintf(stderr, fmt, ap);
|
ret = vfprintf(stderr, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
fprintf(stderr, "\n"), fflush(stderr);
|
fprintf(stderr, nl), fflush(stderr);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
DLL_EXPORT void tcc_location(const char *fmt)
|
|
||||||
{
|
|
||||||
if (__rt_location) {
|
|
||||||
void *fp = __builtin_frame_address(1);
|
|
||||||
void *ip = __builtin_return_address(0);
|
|
||||||
__rt_location(fp, ip, fmt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if (defined(__GNUC__) && (__GNUC__ >= 6)) || defined(__clang__)
|
#if (defined(__GNUC__) && (__GNUC__ >= 6)) || defined(__clang__)
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
2
tccgen.c
2
tccgen.c
@ -6010,7 +6010,6 @@ special_math_val:
|
|||||||
indir();
|
indir();
|
||||||
qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
|
qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
|
||||||
test_lvalue();
|
test_lvalue();
|
||||||
gaddrof();
|
|
||||||
/* expect pointer on structure */
|
/* expect pointer on structure */
|
||||||
if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
|
if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
|
||||||
expect("struct or union");
|
expect("struct or union");
|
||||||
@ -6021,6 +6020,7 @@ special_math_val:
|
|||||||
expect("field name");
|
expect("field name");
|
||||||
s = find_field(&vtop->type, tok, &cumofs);
|
s = find_field(&vtop->type, tok, &cumofs);
|
||||||
/* add field offset to pointer */
|
/* add field offset to pointer */
|
||||||
|
gaddrof();
|
||||||
vtop->type = char_pointer_type; /* change type to 'char *' */
|
vtop->type = char_pointer_type; /* change type to 'char *' */
|
||||||
vpushi(cumofs);
|
vpushi(cumofs);
|
||||||
gen_op('+');
|
gen_op('+');
|
||||||
|
168
tccrun.c
168
tccrun.c
@ -23,9 +23,9 @@
|
|||||||
/* only native compiler supports -run */
|
/* only native compiler supports -run */
|
||||||
#ifdef TCC_IS_NATIVE
|
#ifdef TCC_IS_NATIVE
|
||||||
|
|
||||||
#ifdef CONFIG_TCC_BACKTRACE
|
|
||||||
typedef struct rt_context
|
typedef struct rt_context
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_TCC_BACKTRACE
|
||||||
/* --> tccelf.c:tcc_add_btstub wants those below in that order: */
|
/* --> tccelf.c:tcc_add_btstub wants those below in that order: */
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
@ -46,15 +46,27 @@ typedef struct rt_context
|
|||||||
int num_callers;
|
int num_callers;
|
||||||
addr_t ip, fp, sp;
|
addr_t ip, fp, sp;
|
||||||
void *top_func;
|
void *top_func;
|
||||||
jmp_buf jmp_buf;
|
#endif
|
||||||
char do_jmp;
|
jmp_buf jb;
|
||||||
|
int do_jmp;
|
||||||
|
# define NR_AT_EXIT 32
|
||||||
|
int nr_exit;
|
||||||
|
void *exitfunc[NR_AT_EXIT];
|
||||||
|
void *exitarg[NR_AT_EXIT];
|
||||||
} rt_context;
|
} rt_context;
|
||||||
|
|
||||||
static rt_context g_rtctxt;
|
static rt_context g_rtctxt;
|
||||||
|
static void rt_exit(int code)
|
||||||
|
{
|
||||||
|
rt_context *rc = &g_rtctxt;
|
||||||
|
if (rc->do_jmp)
|
||||||
|
longjmp(rc->jb, code ? code : 256);
|
||||||
|
exit(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_TCC_BACKTRACE
|
||||||
static void set_exception_handler(void);
|
static void set_exception_handler(void);
|
||||||
static int _rt_error(void *fp, void *ip, const char *fmt, va_list ap);
|
static int _rt_error(void *fp, void *ip, const char *fmt, va_list ap);
|
||||||
static void _rt_location(void *fp, void *ip, const char *fmt);
|
|
||||||
static void rt_exit(int code);
|
|
||||||
#endif /* CONFIG_TCC_BACKTRACE */
|
#endif /* CONFIG_TCC_BACKTRACE */
|
||||||
|
|
||||||
/* defined when included from lib/bt-exe.c */
|
/* defined when included from lib/bt-exe.c */
|
||||||
@ -147,79 +159,35 @@ static void run_cdtors(TCCState *s1, const char *start, const char *end,
|
|||||||
((void(*)(int, char **, char **))*a++)(argc, argv, envp);
|
((void(*)(int, char **, char **))*a++)(argc, argv, envp);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define NR_AT_EXIT 32
|
static void run_on_exit(int ret)
|
||||||
|
|
||||||
static struct exit_context {
|
|
||||||
int exit_called;
|
|
||||||
int nr_exit;
|
|
||||||
void (*exitfunc[NR_AT_EXIT])(int, void *);
|
|
||||||
void *exitarg[NR_AT_EXIT];
|
|
||||||
#ifndef CONFIG_TCC_BACKTRACE
|
|
||||||
jmp_buf run_jmp_buf;
|
|
||||||
#endif
|
|
||||||
} g_exit_context;
|
|
||||||
|
|
||||||
static void init_exit(void)
|
|
||||||
{
|
{
|
||||||
struct exit_context *e = &g_exit_context;
|
rt_context *rc = &g_rtctxt;
|
||||||
|
int n = rc->nr_exit;
|
||||||
e->exit_called = 0;
|
while (n)
|
||||||
e->nr_exit = 0;
|
--n, ((void(*)(int,void*))rc->exitfunc[n])(ret, rc->exitarg[n]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void call_exit(int ret)
|
static int rt_on_exit(void *function, void *arg)
|
||||||
{
|
{
|
||||||
struct exit_context *e = &g_exit_context;
|
rt_context *rc = &g_rtctxt;
|
||||||
|
if (rc->nr_exit < NR_AT_EXIT) {
|
||||||
while (e->nr_exit) {
|
rc->exitfunc[rc->nr_exit] = function;
|
||||||
e->nr_exit--;
|
rc->exitarg[rc->nr_exit++] = arg;
|
||||||
e->exitfunc[e->nr_exit](ret, e->exitarg[e->nr_exit]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rt_atexit(void (*function)(void))
|
|
||||||
{
|
|
||||||
struct exit_context *e = &g_exit_context;
|
|
||||||
|
|
||||||
if (e->nr_exit < NR_AT_EXIT) {
|
|
||||||
e->exitfunc[e->nr_exit] = (void (*)(int, void *))function;
|
|
||||||
e->exitarg[e->nr_exit++] = NULL;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rt_on_exit(void (*function)(int, void *), void *arg)
|
static int rt_atexit(void *function)
|
||||||
{
|
{
|
||||||
struct exit_context *e = &g_exit_context;
|
return rt_on_exit(function, NULL);
|
||||||
|
|
||||||
if (e->nr_exit < NR_AT_EXIT) {
|
|
||||||
e->exitfunc[e->nr_exit] = function;
|
|
||||||
e->exitarg[e->nr_exit++] = arg;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void run_exit(int code)
|
|
||||||
{
|
|
||||||
struct exit_context *e = &g_exit_context;
|
|
||||||
|
|
||||||
e->exit_called = 1;
|
|
||||||
#ifdef CONFIG_TCC_BACKTRACE
|
|
||||||
longjmp((&g_rtctxt)->jmp_buf, code ? code : 256);
|
|
||||||
#else
|
|
||||||
longjmp(e->run_jmp_buf, code ? code : 256);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* launch the compiled program with the given arguments */
|
/* launch the compiled program with the given arguments */
|
||||||
LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
|
LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
|
||||||
{
|
{
|
||||||
int (*prog_main)(int, char **, char **), ret;
|
int (*prog_main)(int, char **, char **), ret;
|
||||||
#ifdef CONFIG_TCC_BACKTRACE
|
|
||||||
rt_context *rc = &g_rtctxt;
|
rt_context *rc = &g_rtctxt;
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
#if defined(__APPLE__) || defined(__FreeBSD__)
|
||||||
char **envp = NULL;
|
char **envp = NULL;
|
||||||
@ -233,17 +201,21 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
|
|||||||
s1->runtime_main = s1->nostdlib ? "_start" : "main";
|
s1->runtime_main = s1->nostdlib ? "_start" : "main";
|
||||||
if ((s1->dflag & 16) && (addr_t)-1 == get_sym_addr(s1, s1->runtime_main, 0, 1))
|
if ((s1->dflag & 16) && (addr_t)-1 == get_sym_addr(s1, s1->runtime_main, 0, 1))
|
||||||
return 0;
|
return 0;
|
||||||
tcc_add_symbol(s1, "exit", run_exit);
|
|
||||||
|
tcc_add_symbol(s1, "exit", rt_exit);
|
||||||
tcc_add_symbol(s1, "atexit", rt_atexit);
|
tcc_add_symbol(s1, "atexit", rt_atexit);
|
||||||
tcc_add_symbol(s1, "on_exit", rt_on_exit);
|
tcc_add_symbol(s1, "on_exit", rt_on_exit);
|
||||||
if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0)
|
if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
prog_main = (void*)get_sym_addr(s1, s1->runtime_main, 1, 1);
|
prog_main = (void*)get_sym_addr(s1, s1->runtime_main, 1, 1);
|
||||||
if ((addr_t)-1 == (addr_t)prog_main)
|
if ((addr_t)-1 == (addr_t)prog_main)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
#ifdef CONFIG_TCC_BACKTRACE
|
|
||||||
memset(rc, 0, sizeof *rc);
|
memset(rc, 0, sizeof *rc);
|
||||||
|
rc->do_jmp = 1;
|
||||||
|
|
||||||
|
#ifdef CONFIG_TCC_BACKTRACE
|
||||||
if (s1->do_debug) {
|
if (s1->do_debug) {
|
||||||
void *p;
|
void *p;
|
||||||
if (s1->dwarf) {
|
if (s1->dwarf) {
|
||||||
@ -272,11 +244,8 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
rc->top_func = tcc_get_symbol(s1, "main");
|
rc->top_func = tcc_get_symbol(s1, "main");
|
||||||
rc->num_callers = s1->rt_num_callers;
|
rc->num_callers = s1->rt_num_callers;
|
||||||
rc->do_jmp = 1;
|
|
||||||
if ((p = tcc_get_symbol(s1, "__rt_error")))
|
if ((p = tcc_get_symbol(s1, "__rt_error")))
|
||||||
*(void**)p = _rt_error;
|
*(void**)p = _rt_error;
|
||||||
if ((p = tcc_get_symbol(s1, "__rt_location")))
|
|
||||||
*(void**)p = _rt_location;
|
|
||||||
#ifdef CONFIG_TCC_BCHECK
|
#ifdef CONFIG_TCC_BCHECK
|
||||||
if (s1->do_bounds_check) {
|
if (s1->do_bounds_check) {
|
||||||
rc->bounds_start = (void*)bounds_section->sh_addr;
|
rc->bounds_start = (void*)bounds_section->sh_addr;
|
||||||
@ -291,23 +260,15 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
|
|||||||
errno = 0; /* clean errno value */
|
errno = 0; /* clean errno value */
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
init_exit();
|
|
||||||
/* These aren't C symbols, so don't need leading underscore handling. */
|
/* These aren't C symbols, so don't need leading underscore handling. */
|
||||||
run_cdtors(s1, "__init_array_start", "__init_array_end", argc, argv, envp);
|
run_cdtors(s1, "__init_array_start", "__init_array_end", argc, argv, envp);
|
||||||
#ifdef CONFIG_TCC_BACKTRACE
|
if (!(ret = setjmp(rc->jb)))
|
||||||
if (!(ret = setjmp(rc->jmp_buf)))
|
|
||||||
#else
|
|
||||||
if (!(ret = setjmp((&g_exit_context)->run_jmp_buf)))
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
ret = prog_main(argc, argv, envp);
|
ret = prog_main(argc, argv, envp);
|
||||||
}
|
|
||||||
run_cdtors(s1, "__fini_array_start", "__fini_array_end", 0, NULL, NULL);
|
run_cdtors(s1, "__fini_array_start", "__fini_array_end", 0, NULL, NULL);
|
||||||
call_exit(ret);
|
run_on_exit(ret);
|
||||||
if ((s1->dflag & 16) && ret)
|
if (s1->dflag & 16 && ret) /* tcc -dt -run ... */
|
||||||
fprintf(s1->ppfp, "[returns %d]\n", ret), fflush(s1->ppfp);
|
fprintf(s1->ppfp, "[returns %d]\n", ret), fflush(s1->ppfp);
|
||||||
if ((s1->dflag & 16) == 0 && (&g_exit_context)->exit_called)
|
|
||||||
exit(ret);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1044,7 +1005,7 @@ static int _rt_error(void *fp, void *ip, const char *fmt, va_list ap)
|
|||||||
rt_context *rc = &g_rtctxt;
|
rt_context *rc = &g_rtctxt;
|
||||||
addr_t pc = 0;
|
addr_t pc = 0;
|
||||||
char skip[100];
|
char skip[100];
|
||||||
int i, level, ret, n;
|
int i, level, ret, n, one;
|
||||||
const char *a, *b, *msg;
|
const char *a, *b, *msg;
|
||||||
|
|
||||||
if (fp) {
|
if (fp) {
|
||||||
@ -1063,6 +1024,10 @@ static int _rt_error(void *fp, void *ip, const char *fmt, va_list ap)
|
|||||||
memcpy(skip, a, b - a), skip[b - a] = 0;
|
memcpy(skip, a, b - a), skip[b - a] = 0;
|
||||||
fmt = b + 1;
|
fmt = b + 1;
|
||||||
}
|
}
|
||||||
|
one = 0;
|
||||||
|
/* hack for bcheck.c:dprintf(): one level, no newline */
|
||||||
|
if (fmt[0] == '\001')
|
||||||
|
++fmt, one = 1;
|
||||||
|
|
||||||
n = rc->num_callers ? rc->num_callers : 6;
|
n = rc->num_callers ? rc->num_callers : 6;
|
||||||
for (i = level = 0; level < n; i++) {
|
for (i = level = 0; level < n; i++) {
|
||||||
@ -1082,6 +1047,8 @@ static int _rt_error(void *fp, void *ip, const char *fmt, va_list ap)
|
|||||||
rt_vprintf(fmt, ap);
|
rt_vprintf(fmt, ap);
|
||||||
} else if (ret == -1)
|
} else if (ret == -1)
|
||||||
break;
|
break;
|
||||||
|
if (one)
|
||||||
|
break;
|
||||||
rt_printf("\n");
|
rt_printf("\n");
|
||||||
if (ret == -1 || (pc == (addr_t)rc->top_func && pc))
|
if (ret == -1 || (pc == (addr_t)rc->top_func && pc))
|
||||||
break;
|
break;
|
||||||
@ -1092,41 +1059,6 @@ static int _rt_error(void *fp, void *ip, const char *fmt, va_list ap)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _rt_location(void *fp, void *ip, const char *fmt)
|
|
||||||
{
|
|
||||||
rt_context *rc = &g_rtctxt;
|
|
||||||
addr_t pc = 0;
|
|
||||||
char skip[100];
|
|
||||||
int i, ret;
|
|
||||||
const char *a, *b;
|
|
||||||
|
|
||||||
rc->fp = (addr_t)fp;
|
|
||||||
rc->ip = (addr_t)ip;
|
|
||||||
|
|
||||||
skip[0] = 0;
|
|
||||||
/* If fmt is like "^file.c^..." then skip calls from 'file.c' */
|
|
||||||
if (fmt[0] == '^' && (b = strchr(a = fmt + 1, fmt[0])))
|
|
||||||
memcpy(skip, a, b - a), skip[b - a] = 0;
|
|
||||||
|
|
||||||
for (i = 0; ; i++) {
|
|
||||||
ret = rt_get_caller_pc(&pc, rc, i);
|
|
||||||
a = "";
|
|
||||||
if (ret != -1) {
|
|
||||||
if (rc->dwarf)
|
|
||||||
pc = rt_printline_dwarf(rc, pc, "at", skip);
|
|
||||||
else
|
|
||||||
pc = rt_printline(rc, pc, "at", skip);
|
|
||||||
if (pc == (addr_t)-1)
|
|
||||||
continue;
|
|
||||||
a = ": ";
|
|
||||||
}
|
|
||||||
rt_printf(a);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc->ip = rc->fp = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* emit a run time error at position 'pc' */
|
/* emit a run time error at position 'pc' */
|
||||||
static int rt_error(const char *fmt, ...)
|
static int rt_error(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
@ -1138,14 +1070,6 @@ static int rt_error(const char *fmt, ...)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rt_exit(int code)
|
|
||||||
{
|
|
||||||
rt_context *rc = &g_rtctxt;
|
|
||||||
if (rc->do_jmp)
|
|
||||||
longjmp(rc->jmp_buf, code ? code : 256);
|
|
||||||
exit(code);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
@ -2047,6 +2047,7 @@ void gen_opf(int op)
|
|||||||
assert(vtop->r & VT_LVAL);
|
assert(vtop->r & VT_LVAL);
|
||||||
gv(RC_FLOAT);
|
gv(RC_FLOAT);
|
||||||
vswap();
|
vswap();
|
||||||
|
fc = vtop->c.i; /* bcheck may have saved previous vtop[-1] */
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ft & VT_BTYPE) == VT_DOUBLE) {
|
if ((ft & VT_BTYPE) == VT_DOUBLE) {
|
||||||
|
Loading…
Reference in New Issue
Block a user