From 5a6d8c21e09faee0bcff2aab4994c778de921b80 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Sat, 11 Aug 2018 11:42:30 +0200 Subject: [PATCH] mescc: Mes C Library: Add x86_64 libc support. * include/linux/x86_64/syscall.h: New file. * include/linux/x86/syscall.h: New file. * lib/linux/x86_64-mes-gcc/mes.c: New file. * lib/linux/x86-mes/mes.c: Rename from lib/linux/mes.c. * lib/linux/x86-mes-gcc/mes.c: Rename from lib/linux/gcc.c. * lib/linux/libc.c: Update includes. (waitpid)[__x86_64__]: Use wait4. * build-aux/build-cc.sh: Build libc too. * lib/x86-mes/x86.M1 (mov____0x8(%ebp),%esi): New macro. --- build-aux/build-cc.sh | 4 +- include/linux/x86/syscall.h | 38 +++++++ include/linux/x86_64/syscall.h | 38 +++++++ lib/libmes.c | 2 +- lib/linux/gnu.c | 26 ++--- lib/linux/libc.c | 66 ++++++----- lib/linux/tcc.c | 12 +- lib/linux/{gcc.c => x86-mes-gcc/mes.c} | 51 +++++++-- lib/linux/{ => x86-mes}/mes.c | 26 +++++ lib/linux/x86_64-mes-gcc/mes.c | 149 +++++++++++++++++++++++++ lib/x86-mes/x86.M1 | 12 +- src/gc.c | 6 +- src/mes.c | 40 +++---- 13 files changed, 376 insertions(+), 94 deletions(-) create mode 100644 include/linux/x86/syscall.h create mode 100644 include/linux/x86_64/syscall.h rename lib/linux/{gcc.c => x86-mes-gcc/mes.c} (73%) rename lib/linux/{ => x86-mes}/mes.c (80%) create mode 100644 lib/linux/x86_64-mes-gcc/mes.c diff --git a/build-aux/build-cc.sh b/build-aux/build-cc.sh index 6807b50a..596dc7e3 100755 --- a/build-aux/build-cc.sh +++ b/build-aux/build-cc.sh @@ -24,7 +24,7 @@ set -e . ${srcdest}build-aux/trace.sh # cc64 -LIBC=${LIBC-c-mini} +LIBC=${LIBC-c} # native trace "SNARF gc.c" ${srcdest}build-aux/mes-snarf.scm src/gc.c @@ -52,7 +52,7 @@ ARCHDIR=1 NOLINK=1 sh ${srcdest}build-aux/cc64-mes.sh lib/linux/x86_64-mes-gcc/c # ARCHDIR=1 NOLINK=1 sh ${srcdest}build-aux/cc64-mes.sh lib/linux/x86_64/crti # ARCHDIR=1 NOLINK=1 sh ${srcdest}build-aux/cc64-mes.sh lib/linux/x86_64/crtn ARCHDIR=1 NOLINK=1 sh ${srcdest}build-aux/cc64-mes.sh lib/libc-mini -# ARCHDIR=1 NOLINK=1 sh ${srcdest}build-aux/cc64-mes.sh lib/libc +ARCHDIR=1 NOLINK=1 sh ${srcdest}build-aux/cc64-mes.sh lib/libc # ARCHDIR=1 NOLINK=1 sh ${srcdest}build-aux/cc64-mes.sh lib/libgetopt # ARCHDIR=1 NOLINK=1 sh ${srcdest}build-aux/cc64-mes.sh lib/libc+tcc # ARCHDIR=1 NOLINK=1 sh ${srcdest}build-aux/cc64-mes.sh lib/libtcc1 diff --git a/include/linux/x86/syscall.h b/include/linux/x86/syscall.h new file mode 100644 index 00000000..7c06bd38 --- /dev/null +++ b/include/linux/x86/syscall.h @@ -0,0 +1,38 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2017 Jan (janneke) Nieuwenhuizen + * + * This file is part of GNU Mes. + * + * GNU Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * GNU Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Mes. If not, see . + */ +#ifndef __MES_LINUX_X86_SYSCALL_H +#define __MES_LINUX_X86_SYSCALL_H 1 + +// #define SYS_exit 0x01 +// #define SYS_write 0x04 + +#define SYS_fork 0x02 +#define SYS_read 0x03 +#define SYS_open 0x05 +#define SYS_waitpid 0x07 +#define SYS_wait4 0x72 +#define SYS_execve 0x0b +#define SYS_chmod 0x0f +#define SYS_access 0x21 +#define SYS_brk 0x2d +#define SYS_ioctl 0x36 +#define SYS_fsync 0x76 + +#endif // __MES_LINUX_X86_SYSCALL_H diff --git a/include/linux/x86_64/syscall.h b/include/linux/x86_64/syscall.h new file mode 100644 index 00000000..b0630dd1 --- /dev/null +++ b/include/linux/x86_64/syscall.h @@ -0,0 +1,38 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * + * This file is part of GNU Mes. + * + * GNU Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * GNU Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Mes. If not, see . + */ +#ifndef __MES_LINUX_X86_64_SYSCALL_H +#define __MES_LINUX_X86_64_SYSCALL_H 1 + +// #define SYS_write 0x01 +// #define SYS_exit 0x3c + +#define SYS_fork 0x39 +#define SYS_read 0x00 +#define SYS_open 0x02 +//#define SYS_waitpid +#define SYS_wait4 0x3d +#define SYS_execve 0x3a +#define SYS_chmod 0x5a +#define SYS_access 0x15 +#define SYS_brk 0x0c +#define SYS_ioctl 0x10 +#define SYS_fsync 0x4a + +#endif // __MES_LINUX_X86_64_SYSCALL_H diff --git a/lib/libmes.c b/lib/libmes.c index ee26d44a..22a6df59 100644 --- a/lib/libmes.c +++ b/lib/libmes.c @@ -221,7 +221,7 @@ _fdungetc_p (int fd) return _ungetc_pos > -1; } -#if POSIX || __x86_64__ +#if POSIX #define STDERR 2 int eputs (char const* s) diff --git a/lib/linux/gnu.c b/lib/linux/gnu.c index 0f0425d3..582c18bc 100644 --- a/lib/linux/gnu.c +++ b/lib/linux/gnu.c @@ -41,7 +41,7 @@ int link (char const *old_name, char const *new_name) { - return _sys_call2 (SYS_link, (int)old_name, (int)new_name); + return _sys_call2 (SYS_link, (long)old_name, (long)new_name); } pid_t @@ -59,25 +59,25 @@ getuid () int kill (pid_t pid, int signum) { - return _sys_call2 (SYS_kill, (int)pid, (int)signum); + return _sys_call2 (SYS_kill, (long)pid, (long)signum); } int rename (char const *old_name, char const *new_name) { - return _sys_call2 (SYS_rename, (int)old_name, (int)new_name); + return _sys_call2 (SYS_rename, (long)old_name, (long)new_name); } int mkdir (char const *file_name, mode_t mode) { - return _sys_call2 (SYS_mkdir, (int)file_name, (int)mode); + return _sys_call2 (SYS_mkdir, (long)file_name, (long)mode); } int dup (int old) { - return _sys_call1 (SYS_dup, (int)old); + return _sys_call1 (SYS_dup, (long)old); } gid_t @@ -103,7 +103,7 @@ fcntl (int filedes, int command, ...) va_list ap; va_start (ap, command); int data = va_arg (ap, int); - int r = _sys_call3 (SYS_fcntl, (int)filedes, (int)command, (int)data); + int r = _sys_call3 (SYS_fcntl, (long)filedes, (long)command, (long)data); va_end (ap); return r; } @@ -111,43 +111,43 @@ fcntl (int filedes, int command, ...) int pipe (int filedes[2]) { - return _sys_call1 (SYS_pipe, (int)filedes); + return _sys_call1 (SYS_pipe, (long)filedes); } int dup2 (int old, int new) { - return _sys_call2 (SYS_dup2, (int)old, (int)new); + return _sys_call2 (SYS_dup2, (long)old, (long)new); } int getrusage (int processes, struct rusage *rusage) { - return _sys_call2 (SYS_getrusage, (int)processes, (int)rusage); + return _sys_call2 (SYS_getrusage, (long)processes, (long)rusage); } int lstat (char const *file_name, struct stat *statbuf) { - return _sys_call2 (SYS_lstat, (int)file_name, (int)statbuf); + return _sys_call2 (SYS_lstat, (long)file_name, (long)statbuf); } int nanosleep (const struct timespec *requested_time, struct timespec *remaining) { - return _sys_call2 (SYS_nanosleep, (int)requested_time, (int)remaining); + return _sys_call2 (SYS_nanosleep, (long)requested_time, (long)remaining); } int setitimer (int which, struct itimerval const *new, struct itimerval *old) { - return _sys_call3 (SYS_setitimer, (int)which, (int)new, (int)old); + return _sys_call3 (SYS_setitimer, (long)which, (long)new, (long)old); } int fstat (int fd, struct stat *statbuf) { - return _sys_call2 (SYS_fstat, (int)fd, (int)statbuf); + return _sys_call2 (SYS_fstat, (long)fd, (long)statbuf); } diff --git a/lib/linux/libc.c b/lib/linux/libc.c index d9243f26..dd4aac7f 100644 --- a/lib/linux/libc.c +++ b/lib/linux/libc.c @@ -27,28 +27,23 @@ #include #include -#define SYS_fork 0x02 -#define SYS_read 0x03 -#define SYS_open 0x05 -#define SYS_waitpid 0x07 -#define SYS_execve 0x0b -#define SYS_chmod 0x0f -#define SYS_access 0x21 -#define SYS_brk 0x2d -#define SYS_ioctl 0x36 -#define SYS_fsync 0x76 - #if __MESC__ -#include +#include -#else // !__MESC__ +#elif __i386__ -#include +#include -#include +#elif __x86_64__ -#endif // !__MESC__ +#include + +#else + +#error arch not supported + +#endif int fork () @@ -59,7 +54,20 @@ fork () ssize_t read (int filedes, void *buffer, size_t size) { - return _sys_call3 (SYS_read, (int)filedes, (int)buffer, (int)size); + ssize_t bytes = _sys_call3 (SYS_read, (long)filedes, (long)buffer, (long)size); + if (__mes_debug () > 3) + { + if (bytes == 1) + { + eputs ("read fd="); eputs (itoa ((int)filedes)); eputs (" c="); eputc (*(char*)buffer); eputs ("\n"); + } + else + { + eputs ("read fd="); eputs (itoa ((int)filedes)); + eputs (" bytes="); eputs (itoa (bytes)); eputs ("\n"); + } + } + return bytes; } int @@ -75,7 +83,7 @@ open (char const *file_name, int flags, ...) _ungetc_fd = -1; } #endif - int r = _sys_call3 (SYS_open, (int)file_name, (int)flags, (int)mask); + int r = _sys_call3 (SYS_open, (long)file_name, (long)flags, (long)mask); va_end (ap); return r; } @@ -83,31 +91,37 @@ open (char const *file_name, int flags, ...) pid_t waitpid (pid_t pid, int *status_ptr, int options) { - return _sys_call3 (SYS_waitpid, (int)pid, (int)status_ptr, (int)options); +#if __i386__ + return _sys_call3 (SYS_waitpid, (long)pid, (long)status_ptr, (long)options); +#elif __x86_64__ + return _sys_call4 (SYS_wait4, (long)pid, (long)status_ptr, (long)options, 0); +#else +#error arch not supported +#endif } int execve (char const* file_name, char *const argv[], char *const env[]) { - return _sys_call3 (SYS_execve, (int)file_name, (int)argv, (int)env); + return _sys_call3 (SYS_execve, (long)file_name, (long)argv, (long)env); } int chmod (char const *file_name, mode_t mask) { - return _sys_call2 (SYS_chmod, (int)file_name, (int)mask); + return _sys_call2 (SYS_chmod, (long)file_name, (long)mask); } int access (char const *file_name, int how) { - return _sys_call2 (SYS_access, (int)file_name, (int)how); + return _sys_call2 (SYS_access, (long)file_name, (long)how); } -int +long brk (void *addr) { - return _sys_call1 (SYS_brk, (int)addr); + return _sys_call1 (SYS_brk, (long)addr); } int @@ -116,7 +130,7 @@ ioctl (int filedes, unsigned long command, ...) va_list ap; va_start (ap, command); int data = va_arg (ap, int); - int r = _sys_call3 (SYS_ioctl, (int)filedes, (int)command, (int)data); + int r = _sys_call3 (SYS_ioctl, (long)filedes, (long)command, (long)data); va_end (ap); return r; } @@ -124,5 +138,5 @@ ioctl (int filedes, unsigned long command, ...) int fsync (int filedes) { - return _sys_call1 (SYS_fsync, (int)filedes); + return _sys_call1 (SYS_fsync, (long)filedes); } diff --git a/lib/linux/tcc.c b/lib/linux/tcc.c index cee4e13e..8efc4719 100644 --- a/lib/linux/tcc.c +++ b/lib/linux/tcc.c @@ -33,35 +33,35 @@ close (int filedes) _ungetc_pos = -1; _ungetc_fd = -1; } - return _sys_call1 (SYS_close, (int)filedes); + return _sys_call1 (SYS_close, (long)filedes); } off_t lseek (int filedes, off_t offset, int whence) { - return _sys_call3 (SYS_lseek, (int)filedes, (int)offset, (int)whence); + return _sys_call3 (SYS_lseek, (long)filedes, (long)offset, (long)whence); } int unlink (char const *file_name) { - return _sys_call1 (SYS_unlink, (int)file_name); + return _sys_call1 (SYS_unlink, (long)file_name); } int rmdir (char const *file_name) { - return _sys_call1 (SYS_rmdir, (int)file_name); + return _sys_call1 (SYS_rmdir, (long)file_name); } int stat (char const *file_name, struct stat *statbuf) { - return _sys_call2 (SYS_stat, (int)file_name, (int)statbuf); + return _sys_call2 (SYS_stat, (long)file_name, (long)statbuf); } char * getcwd (char *buffer, size_t size) { - return _sys_call2 (SYS_getcwd, (int)buffer, (int)size); + return _sys_call2 (SYS_getcwd, (long)buffer, (long)size); } diff --git a/lib/linux/gcc.c b/lib/linux/x86-mes-gcc/mes.c similarity index 73% rename from lib/linux/gcc.c rename to lib/linux/x86-mes-gcc/mes.c index 9b8adfdc..261bdfe7 100644 --- a/lib/linux/gcc.c +++ b/lib/linux/x86-mes-gcc/mes.c @@ -19,11 +19,12 @@ */ #include +#include -int -_sys_call (int sys_call) +long +_sys_call (long sys_call) { - int r; + long r; asm ( "mov %1,%%eax\n\t" "int $0x80\n\t" @@ -42,10 +43,10 @@ _sys_call (int sys_call) return r; } -int -_sys_call1 (int sys_call, int one) +long +_sys_call1 (long sys_call, long one) { - int r; + long r; asm ( "mov %1,%%eax\n\t" "mov %2,%%ebx\n\t" @@ -65,10 +66,10 @@ _sys_call1 (int sys_call, int one) return r; } -int -_sys_call2 (int sys_call, int one, int two) +long +_sys_call2 (long sys_call, long one, long two) { - int r; + long r; asm ( "mov %1,%%eax\n\t" "mov %2,%%ebx\n\t" @@ -89,10 +90,10 @@ _sys_call2 (int sys_call, int one, int two) return r; } -int -_sys_call3 (int sys_call, int one, int two, int three) +long +_sys_call3 (long sys_call, long one, long two, long three) { - int r; + long r; asm ( "mov %2,%%ebx\n\t" "mov %3,%%ecx\n\t" @@ -113,3 +114,29 @@ _sys_call3 (int sys_call, int one, int two, int three) errno = 0; return r; } + +long +_sys_call4 (long sys_call, long one, long two, long three, long four) +{ + long r; + asm ( + "mov %2,%%ebx\n\t" + "mov %3,%%ecx\n\t" + "mov %4,%%edx\n\t" + "mov %5,%%esi\n\t" + "mov %1,%%eax\n\t" + "int $0x80\n\t" + "mov %%eax,%0\n\t" + : "=r" (r) + : "rm" (sys_call), "rm" (one), "rm" (two), "rm" (three), "rm" (four) + : "eax", "ebx", "ecx", "edx", "esi" + ); + if (r < 0) + { + errno = -r; + r = -1; + } + else + errno = 0; + return r; +} diff --git a/lib/linux/mes.c b/lib/linux/x86-mes/mes.c similarity index 80% rename from lib/linux/mes.c rename to lib/linux/x86-mes/mes.c index 4195f9e5..5d88cca5 100644 --- a/lib/linux/mes.c +++ b/lib/linux/x86-mes/mes.c @@ -19,6 +19,7 @@ */ #include +#include int __sys_call (int sys_call) @@ -54,6 +55,17 @@ __sys_call3 (int sys_call, int one, int two, int three) asm ("int____$0x80"); } +int +__sys_call4 (int sys_call, int one, int two, int three, int four) +{ + asm ("mov____0x8(%ebp),%eax !8"); + asm ("mov____0x8(%ebp),%ebx !12"); + asm ("mov____0x8(%ebp),%ecx !16"); + asm ("mov____0x8(%ebp),%edx !20"); + asm ("mov____0x8(%ebp),%esi !24"); + asm ("int____$0x80"); +} + int _sys_call (int sys_call) { @@ -109,3 +121,17 @@ _sys_call3 (int sys_call, int one, int two, int three) errno = 0; return r; } + +int +_sys_call4 (int sys_call, int one, int two, int three, int four) +{ + int r = __sys_call4 (sys_call, one, two, three, four); + if (r < 0) + { + errno = -r; + r = -1; + } + else + errno = 0; + return r; +} diff --git a/lib/linux/x86_64-mes-gcc/mes.c b/lib/linux/x86_64-mes-gcc/mes.c new file mode 100644 index 00000000..27dc56f6 --- /dev/null +++ b/lib/linux/x86_64-mes-gcc/mes.c @@ -0,0 +1,149 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen + * + * This file is part of GNU Mes. + * + * GNU Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * GNU Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Mes. If not, see . + */ + +#include +#include + +// HMM, merge this with x86-mes-gcc/mes.c, doing something like +// #define R0 eax +// #define R1 ebx +// +// #define R0 rax +// #define R1 rdi + +long +_sys_call (long sys_call) +{ + long r; + asm ( + "mov %1,%%rax\n\t" + "syscall \n\t" + "mov %%rax,%0\n\t" + : "=r" (r) + : "rm" (sys_call) + : "rax" + ); + if (r < 0) + { + errno = -r; + r = -1; + } + else + errno = 0; + return r; +} + +long +_sys_call1 (long sys_call, long one) +{ + long r; + asm ( + "mov %1,%%rax\n\t" + "mov %2,%%rdi\n\t" + "syscall \n\t" + "mov %%rax,%0\n\t" + : "=r" (r) + : "rm" (sys_call), "rm" (one) + : "rax", "rdi" + ); + if (r < 0) + { + errno = -r; + r = -1; + } + else + errno = 0; + return r; +} + +long +_sys_call2 (long sys_call, long one, long two) +{ + long r; + asm ( + "mov %1,%%rax\n\t" + "mov %2,%%rdi\n\t" + "mov %3,%%rsi\n\t" + "syscall \n\t" + "mov %%rax,%0\n\t" + : "=r" (r) + : "rm" (sys_call), "rm" (one), "rm" (two) + : "rax", "rdi", "rsi" + ); + if (r < 0) + { + errno = -r; + r = -1; + } + else + errno = 0; + return r; +} + +long +_sys_call3 (long sys_call, long one, long two, long three) +{ + long r; + asm ( + "mov %2,%%rdi\n\t" + "mov %3,%%rsi\n\t" + "mov %4,%%rdx\n\t" + "mov %1,%%rax\n\t" + "syscall \n\t" + "mov %%rax,%0\n\t" + : "=r" (r) + : "rm" (sys_call), "rm" (one), "rm" (two), "rm" (three) + : "rax", "rdi", "rsi", "rdx" + ); + if (r < 0) + { + errno = -r; + r = -1; + } + else + errno = 0; + return r; +} + +long +_sys_call4 (long sys_call, long one, long two, long three, long four) +{ + long r; + asm ( + "mov %2,%%rdi\n\t" + "mov %3,%%rsi\n\t" + "mov %4,%%rdx\n\t" + "mov %5,%%rcx\n\t" + "mov %1,%%rax\n\t" + "syscall \n\t" + "mov %%rax,%0\n\t" + : "=r" (r) + : "rm" (sys_call), "rm" (one), "rm" (two), "rm" (three), "rm" (four) + : "rax", "rdi", "rsi", "rdx", "rcx" + ); + if (r < 0) + { + errno = -r; + r = -1; + } + else + errno = 0; + return r; +} diff --git a/lib/x86-mes/x86.M1 b/lib/x86-mes/x86.M1 index 49952564..43f06acc 100644 --- a/lib/x86-mes/x86.M1 +++ b/lib/x86-mes/x86.M1 @@ -16,7 +16,6 @@ ### You should have received a copy of the GNU General Public License ### along with GNU Mes. If not, see . - DEFINE add____$i32,%eax 05 DEFINE add____$i32,%ecx 81c1 DEFINE add____$i32,%edx 81c2 @@ -140,6 +139,7 @@ DEFINE mov____0x8(%ebp),%ebp 8b6d DEFINE mov____0x8(%ebp),%ebx 8b5d DEFINE mov____0x8(%ebp),%ecx 8b4d DEFINE mov____0x8(%ebp),%edx 8b55 +DEFINE mov____0x8(%ebp),%esi 8b75 DEFINE mov____0x8(%ebp),%esp 8b65 DEFINE movsbl_%al,%eax 0fbec0 DEFINE movswl_%ax,%eax 0fbfc0 @@ -204,16 +204,6 @@ DEFINE xor____%ecx,%ecx 31c9 DEFINE xor____%edx,%eax 31d0 DEFINE xor____%edx,%edx 31d2 -# Deprecated. Remove after 0.14 release. -DEFINE mov____%al,0x32(%ebp) 8885 -DEFINE mov____%al,0x8(%ebp) 8845 -DEFINE mov____%ax,0x32(%ebp) 668985 -DEFINE mov____%ax,0x8(%ebp) 668945 -DEFINE movzbl_0x32(%ebp),%eax 0fb685 -DEFINE movzbl_0x8(%ebp),%edx 0fb655 -DEFINE movzwl_0x8(%ebp),%eax 0fb745 -DEFINE movzwl_0x8(%ebp),%eax 0fb745 - DEFINE SYS_exit 01000000 DEFINE SYS_fork 02000000 DEFINE SYS_read 03000000 diff --git a/src/gc.c b/src/gc.c index 9a8bc31c..13713643 100644 --- a/src/gc.c +++ b/src/gc.c @@ -73,7 +73,7 @@ gc_copy (SCM old) ///((internal)) if (NTYPE (new) == TVECTOR) { NVECTOR (new) = g_free; - for (int i=0; i 0) + if (ARENA_SIZE < MAX_ARENA_SIZE && (long)g_news > 0) #else if (ARENA_SIZE < MAX_ARENA_SIZE && g_news > 0) #endif @@ -194,7 +194,7 @@ gc_ () ///((internal)) gc_up_arena (); } - for (int i=g_free; i