- Duplicate functionality files removed;
- Refactoring of file handling functions;
- Removed broken impliments.
Gears (C + TinyGL):
- Removed because it duplicates an existing example on Fasm and uses unsupported wrappers on the KOS API.
KosJS:
- Removed. The MuJS port is too old and not used anywhere. Support is not profitable.
Backy:
- Removed useless GCC version. Support is not profitable.
DGen-SDL and SQLite3
- Fix after removing broken "dirent.h".
Fridge:
- Moving the KOS API wrapper to avoid compilation errors.
Udis86, uARM and 8086tiny:
- Fix after removing redundant "kos_LoadConsole.h".


git-svn-id: svn://kolibrios.org@9952 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
turbocat 2024-01-04 22:20:35 +00:00
parent c6d4aab9c5
commit 9562f01892
112 changed files with 344 additions and 22302 deletions

View File

@ -276,16 +276,14 @@ void audio_callback(void *data, unsigned char *stream, int len)
}
#endif
#include <sys/kos_LoadConsole.h>
#include <conio.h>
#define kbhit con_kbhit
#define getch con_getch
// Emulator entry point
int main(int argc, char **argv)
{
load_console();
con_set_title("8086tiny");
//freopen("OUT", "w" ,stdout);
#ifndef NO_GRAPHICS
// Initialise SDL

View File

@ -11,7 +11,8 @@
//#include <sys/select.h>
#include <signal.h>
//#include <termios.h>
#include <sys/kos_LoadConsole.h>
#include <conio.h>
#define getch2 con_getch
#define cprintf printf
@ -95,8 +96,6 @@ static int readchar(void){
if (ret==0xD) {ret=0xA;}
}
return ret;
}
@ -165,8 +164,8 @@ int rootOps(void* userData, UInt32 sector, void* buf, UInt8 op){
SoC soc;
int main(int argc, char** argv){
load_console();
con_set_title("uARM");
//CONSOLE_INIT("CONSOLE");
/*
@ -228,7 +227,7 @@ void* emu_alloc(UInt32 size){
return calloc(size,1);
}
void emu_free(void* ptr){
free(ptr);

View File

@ -6,7 +6,6 @@
* See (LICENSE)
* -----------------------------------------------------------------------------
*/
#include <sys/kos_LoadConsole.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@ -14,6 +13,8 @@
#include "udis86.h"
#include "config.h"
#include <conio.h>
#if defined(__amd64__) || defined(__x86_64__)
# define FMT "l"
#else
@ -71,8 +72,8 @@ int input_hook_file(ud_t* u);
int main(int argc, char **argv)
{
load_console();
con_set_title("udi disassembler");
FILE *stream;
stream = fopen( "disasm.out", "w" );

View File

@ -116,10 +116,9 @@ CORE_SRCS:= \
sys/clock_gettime.c \
sys/close.c \
sys/conio.c \
sys/create.c \
sys/chdir.c \
sys/getcwd.c \
sys/errno.c \
sys/finfo.c \
sys/fsize.c \
sys/fstat.c \
sys/gettod.c \
sys/io.c \
@ -473,16 +472,6 @@ STDIO_SRCS= \
wscanf.c \
wsetup.c
DIRENT_SRCS= dir.c \
closedir.c \
opendir.c \
readdir.c \
rewinddir.c \
seekdir.c \
telldir.c \
scandir.c \
alphasort.c
MATH_SRCS = e_acos.c e_acosh.c e_asin.c e_atan2.c e_atanh.c e_cosh.c e_exp.c e_fmod.c \
e_hypot.c e_j0.c e_j1.c e_jn.c e_log.c e_log10.c e_pow.c e_rem_pio2.c \
e_remainder.c e_scalb.c e_sinh.c e_sqrt.c ef_acos.c ef_acosh.c ef_asin.c \
@ -539,9 +528,6 @@ STRING_OBJS = $(patsubst %.S, string/%.o, $(patsubst %.asm, string/%.o,\
STDLIB_OBJS = $(patsubst %.S, stdlib/%.o, $(patsubst %.asm, stdlib/%.o,\
$(patsubst %.c, stdlib/%.o, $(STDLIB_SRCS))))
DIRENT_OBJS = $(patsubst %.S, dirent/%.o, $(patsubst %.asm, dirent/%.o,\
$(patsubst %.c, dirent/%.o, $(DIRENT_SRCS))))
MATH_OBJS = $(patsubst %.S, math/%.o, $(patsubst %.asm, math/%.o,\
$(patsubst %.c, math/%.o, $(MATH_SRCS))))

View File

@ -1,461 +0,0 @@
CC = kos32-gcc
AR = kos32-ar
LD = kos32-ld
CFLAGS = -c -O2 -march=pentium-mmx -fomit-frame-pointer -DBUILD_DLL -DMISSING_SYSCALL_NAMES
LDFLAGS = -nostdlib -shared -s -T libcdll.lds --output-def libc.orig.def --out-implib libc.dll.a --image-base 0
ARFLAGS = crs
SDK_DIR:= $(abspath ../../..)
LIBC_TOPDIR = .
LIBC_INCLUDES = $(LIBC_TOPDIR)/include
NAME:= libc
DEFINES:= -D_IEEE_LIBM
INCLUDES:= -I $(LIBC_INCLUDES)
LIBPATH:= -L$(SDK_DIR)/lib -L/home/autobuild/tools/win32/mingw32/lib
STATIC_SRCS:= \
crt/start.S \
crt/crt1.c \
crt/crt2.c \
crt/chkstk.S \
crt/exit.S \
pe/crtloader.c
LIBDLL_SRCS:= \
crt/dllstart.c \
crt/chkstk.S \
crt/exit.S \
crt/pseudo-reloc.c \
crt/setjmp.S
LIBCDLL_SRCS:= \
crt/crtdll.c \
crt/pseudo-reloc.c \
crt/chkstk.S \
crt/exit.S \
pe/loader.c
LIBCRT_SRCS:= \
crt/start.S \
crt/chkstk.S \
crt/crt3.c \
crt/pseudo-reloc.c \
pe/crtloader.c
CORE_SRCS:= \
argz/buf_findstr.c \
argz/envz_get.c \
crt/emutls.c \
crt/thread.S \
crt/tls.S \
crt/setjmp.S \
crt/cpu_features.c \
ctype/ctype_.c \
ctype/isascii.c \
ctype/isblank.c \
ctype/isalnum.c \
ctype/isalpha.c \
ctype/iscntrl.c \
ctype/isdigit.c \
ctype/islower.c \
ctype/isupper.c \
ctype/isprint.c \
ctype/ispunct.c \
ctype/isspace.c \
ctype/iswctype.c \
ctype/iswalnum.c \
ctype/iswalpha.c \
ctype/iswblank.c \
ctype/iswcntrl.c \
ctype/iswdigit.c \
ctype/iswgraph.c \
ctype/iswlower.c \
ctype/iswprint.c \
ctype/iswpunct.c \
ctype/iswspace.c \
ctype/iswupper.c \
ctype/iswxdigit.c \
ctype/isxdigit.c \
ctype/toascii.c \
ctype/tolower.c \
ctype/toupper.c \
ctype/towctrans.c \
ctype/towlower.c \
ctype/towupper.c \
ctype/wctrans.c \
ctype/wctype.c \
errno/errno.c \
locale/locale.c \
locale/lctype.c \
locale/ldpart.c \
reent/impure.c \
reent/init_reent.c \
reent/getreent.c \
reent/mutex.c \
reent/gettimeofdayr.c \
reent/isattyr.c \
reent/openr.c \
reent/closer.c \
reent/linkr.c \
reent/readr.c \
reent/lseekr.c \
reent/fstatr.c \
reent/writer.c \
reent/timesr.c \
reent/unlinkr.c \
search/qsort.c \
search/bsearch.c \
signal/signal.c \
sys/close.c \
sys/create.c \
sys/delete.c \
sys/errno.c \
sys/finfo.c \
sys/fsize.c \
sys/fstat.c \
sys/gettod.c \
sys/io.c \
sys/ioread.c \
sys/iowrite.c \
sys/isatty.c \
sys/lseek.c \
sys/open.c \
sys/read.c \
sys/unlink.c \
sys/write.c \
sys/io_alloc.S \
time/asctime.c \
time/asctime_r.c \
time/clock.c \
time/ctime.c \
time/ctime_r.c \
time/difftime.c \
time/gettzinfo.c \
time/gmtime.c \
time/gmtime_r.c \
time/mktime.c \
time/mktm_r.c \
time/lcltime.c \
time/lcltime_r.c \
time/strftime.c \
time/time.c \
time/timelocal.c \
time/tzlock.c \
time/tzvars.c
STDLIB_SRCS= \
__atexit.c \
__call_atexit.c \
abort.c \
abs.c \
assert.c \
atexit.c \
atof.c \
atoi.c \
atol.c \
div.c \
dtoa.c \
dtoastub.c \
exit.c \
gdtoa-gethex.c \
gdtoa-hexnan.c \
getenv.c \
mprec.c \
mbtowc.c \
mbtowc_r.c \
mbrtowc.c \
mlock.c \
calloc.c \
malloc.c \
mallocr.c \
rand.c \
rand_r.c \
rand48.c \
realloc.c \
seed48.c \
srand48.c \
strtod.c \
strtol.c \
strtold.c \
strtoll.c \
strtoll_r.c \
strtoul.c \
strtoull.c \
strtoull_r.c \
system.c \
wcrtomb.c \
wctomb_r.c
STRING_SRCS= memcpy.c \
memcmp.c \
memmove.c \
memset.c \
memchr.c \
stpcpy.c \
stpncpy.c \
strcat.c \
strchr.c \
strcmp.c \
strcoll.c \
strcasecmp.c \
strncasecmp.c \
strncat.c \
strncmp.c \
strncpy.c \
strndup.c \
strndup_r.c \
strnlen.c \
strcasestr.c \
strdup.c \
strdup_r.c \
strerror.c \
strlen.c \
strrchr.c \
strpbrk.c \
strsep.c \
strstr.c \
strtok.c \
strtok_r.c \
strupr.c \
strcspn.c \
strspn.c \
strcpy.c \
u_strerr.c
STDIO_SRCS= \
clearerr.c \
diprintf.c \
dprintf.c \
printf.c \
putchar.c \
fgetc.c \
fgets.c \
fopen.c \
fclose.c \
fdopen.c \
fflush.c \
flags.c \
fileno.c \
findfp.c \
fiprintf.c \
fiscanf.c \
fprintf.c \
fputc.c \
fputs.c \
fputwc.c \
fread.c \
freopen.c \
fscanf.c \
fseek.c \
fseeko.c \
ftell.c \
ftello.c \
fwrite.c \
fvwrite.c \
fwalk.c \
putc.c \
puts.c \
refill.c \
rget.c \
remove.c \
setvbuf.c \
stdio.c \
tmpfile.c \
tmpnam.c \
ungetc.c \
vasniprintf.c \
vasnprintf.c \
vdprintf.c \
vdiprintf.c \
vscanf.c \
vsprintf.c \
vsnprintf.c \
vsscanf.c \
makebuf.c \
wsetup.c \
wbuf.c \
sccl.c \
siprintf.c \
sniprintf.c \
snprintf.c \
sprintf.c \
sscanf.c
MATH_SRCS = e_acos.c e_acosh.c e_asin.c e_atan2.c e_atanh.c e_cosh.c e_exp.c e_fmod.c \
e_hypot.c e_j0.c e_j1.c e_jn.c e_log.c e_log10.c e_pow.c e_rem_pio2.c \
e_remainder.c e_scalb.c e_sinh.c e_sqrt.c ef_acos.c ef_acosh.c ef_asin.c \
ef_atan2.c ef_atanh.c ef_cosh.c ef_exp.c ef_fmod.c ef_hypot.c ef_j0.c ef_j1.c \
ef_jn.c ef_log.c ef_log10.c ef_pow.c ef_rem_pio2.c ef_remainder.c ef_scalb.c \
ef_sinh.c ef_sqrt.c er_gamma.c er_lgamma.c erf_gamma.c erf_lgamma.c f_exp.c \
f_expf.c f_llrint.c f_llrintf.c f_llrintl.c f_lrint.c f_lrintf.c f_lrintl.c \
f_pow.c f_powf.c f_rint.c f_rintf.c f_rintl.c k_cos.c k_rem_pio2.c k_sin.c \
k_standard.c k_tan.c kf_cos.c kf_rem_pio2.c kf_sin.c kf_tan.c s_asinh.c \
s_atan.c s_cbrt.c s_ceil.c s_copysign.c s_cos.c s_erf.c s_exp10.c s_expm1.c \
s_fabs.c s_fdim.c s_finite.c s_floor.c s_fma.c s_fmax.c s_fmin.c s_fpclassify.c \
s_frexp.c s_ilogb.c s_infconst.c s_infinity.c s_isinf.c s_isinfd.c s_isnan.c \
s_isnand.c s_ldexp.c s_lib_ver.c s_llrint.c s_llround.c s_log1p.c s_log2.c \
s_logb.c s_lrint.c s_lround.c s_matherr.c s_modf.c s_nan.c s_nearbyint.c \
s_nextafter.c s_pow10.c s_remquo.c s_rint.c s_round.c s_scalbln.c s_scalbn.c \
s_signbit.c s_signif.c s_sin.c s_tan.c s_tanh.c s_trunc.c scalblnl.c scalbnl.c \
sf_asinh.c sf_atan.c sf_cbrt.c sf_ceil.c sf_copysign.c sf_cos.c sf_erf.c \
sf_exp10.c sf_expm1.c sf_fabs.c sf_fdim.c sf_finite.c sf_floor.c sf_fma.c \
sf_fmax.c sf_fmin.c sf_fpclassify.c sf_frexp.c sf_ilogb.c sf_infinity.c \
sf_isinf.c sf_isinff.c sf_isnan.c sf_isnanf.c sf_ldexp.c sf_llrint.c \
sf_llround.c sf_log1p.c sf_log2.c sf_logb.c sf_lrint.c sf_lround.c sf_modf.c \
sf_nan.c sf_nearbyint.c sf_nextafter.c sf_pow10.c sf_remquo.c sf_rint.c \
sf_round.c sf_scalbln.c sf_scalbn.c sf_signif.c sf_sin.c sf_tan.c sf_tanh.c \
sf_trunc.c w_acos.c w_acosh.c w_asin.c w_atan2.c w_atanh.c w_cosh.c w_drem.c \
w_exp.c w_exp2.c w_fmod.c w_gamma.c w_hypot.c w_j0.c w_j1.c w_jn.c w_lgamma.c \
w_log.c w_log10.c w_pow.c w_remainder.c w_scalb.c w_sincos.c w_sinh.c w_sqrt.c \
w_tgamma.c wf_acos.c wf_acosh.c wf_asin.c wf_atan2.c wf_atanh.c wf_cosh.c \
wf_drem.c wf_exp.c wf_exp2.c wf_fmod.c wf_gamma.c wf_hypot.c wf_j0.c wf_j1.c \
wf_jn.c wf_lgamma.c wf_log.c wf_log10.c wf_pow.c wf_remainder.c wf_scalb.c \
wf_sincos.c wf_sinh.c wf_sqrt.c wf_tgamma.c wr_gamma.c wr_lgamma.c wrf_gamma.c \
wrf_lgamma.c \
f_atan2.S f_atan2f.S f_frexp.S f_frexpf.S f_ldexp.S f_ldexpf.S f_log.S \
f_log10.S f_log10f.S f_logf.S f_tan.S f_tanf.S
STATIC_OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(STATIC_SRCS)))
LIBCRT_OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(LIBCRT_SRCS)))
LIBDLL_OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(LIBDLL_SRCS)))
LIBCDLL_OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(LIBCDLL_SRCS)))
CORE_OBJS = $(patsubst %.S, %.o, $(patsubst %.asm, %.obj,\
$(patsubst %.c, %.o, $(CORE_SRCS))))
STDIO_OBJS = $(patsubst %.c, stdio/%.o,$(STDIO_SRCS))
STRING_OBJS = $(patsubst %.S, string/%.o, $(patsubst %.asm, string/%.o,\
$(patsubst %.c, string/%.o, $(STRING_SRCS))))
STDLIB_OBJS = $(patsubst %.S, stdlib/%.o, $(patsubst %.asm, stdlib/%.o,\
$(patsubst %.c, stdlib/%.o, $(STDLIB_SRCS))))
MATH_OBJS = $(patsubst %.S, math/%.o, $(patsubst %.asm, math/%.o,\
$(patsubst %.c, math/%.o, $(MATH_SRCS))))
PRINTF_OBJS= stdio/vfprintf.o \
stdio/vfiprintf.o \
stdio/svfprintf.o \
stdio/svfiprintf.o \
stdio/vfscanf.o \
stdio/vfiscanf.o \
stdio/svscanf.o \
stdio/svfiscanf.o
ifeq ($(findstring static,$(MAKECMDGOALS)),static)
LIB_SRCS:= $(STATIC_SRCS)
LIB_OBJS:= $(STATIC_OBJS)
else
LIB_SRCS:= $(LIBCDLL_SRCS)
LIB_OBJS:= $(LIBCDLL_OBJS)
endif
LIB_SRCS+= \
$(CORE_SRCS) \
$(STDIO_SRCS) \
$(STRING_SRCS) \
$(STDLIB_SRCS)
LIB_OBJS+= \
$(CORE_OBJS) \
$(STRING_OBJS) \
$(STDLIB_OBJS) \
$(STDIO_OBJS) \
$(PRINTF_OBJS) \
$(MATH_OBJS)
shared: $(NAME).dll libapp.a libdll.a
$(NAME).dll: $(LIB_OBJS) $(SRC_DEP) Makefile
$(LD) $(LDFLAGS) $(LIBPATH) -o $@ $(LIB_OBJS) -lgcc --version-script libc.ver
#sed -e "s/ @[^ ]*//" libc.orig.def > libc.def
#sed -f cmd2.sed libc.def > mem
#sed -f newlib.sed mem > libc.inc
install: libc.dll libc.dll.a libapp.a libdll.a
mv -f libc.dll $(SDK_DIR)/bin
mv -f libc.dll.a $(SDK_DIR)/lib
mv -f libapp.a $(SDK_DIR)/lib
mv -f libdll.a $(SDK_DIR)/lib
libapp.a: $(LIBCRT_OBJS) Makefile
$(AR) $(ARFLAGS) libapp.a $(LIBCRT_OBJS)
libdll.a: $(LIBDLL_OBJS) Makefile
$(AR) $(ARFLAGS) libdll.a $(LIBDLL_OBJS)
static: $(NAME).a
$(NAME).a: $(LIB_OBJS) $(SRC_DEP) Makefile
$(AR) $(ARFLAGS) $(NAME).a $(LIB_OBJS)
stdio/vfprintf.o: stdio/vfprintf.c
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -fshort-enums -DFLOATING_POINT -c stdio/vfprintf.c -o $@
stdio/vfiprintf.o: stdio/vfprintf.c
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -fshort-enums -DINTEGER_ONLY -c stdio/vfprintf.c -o $@
stdio/svfprintf.o: stdio/vfprintf.c
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -fshort-enums -DSTRING_ONLY -c stdio/vfprintf.c -o $@
stdio/svfiprintf.o: stdio/vfprintf.c
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -fshort-enums -DINTEGER_ONLY -DSTRING_ONLY -c stdio/vfprintf.c -o $@
stdio/vfscanf.o: stdio/vfscanf.c
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) stdio/vfscanf.c -o $@
stdio/vfiscanf.o: stdio/vfscanf.c
$(CC) $(CFLAGS) $(DEFINES) -DINTEGER_ONLY $(INCLUDES) stdio/vfscanf.c -o $@
stdio/svscanf.o: stdio/vfscanf.c
$(CC) $(CFLAGS) $(DEFINES) -DSTRING_ONLY $(INCLUDES) stdio/vfscanf.c -o $@
stdio/svfiscanf.o: stdio/vfscanf.c
$(CC) $(CFLAGS) $(DEFINES) -DINTEGER_ONLY -DSTRING_ONLY $(INCLUDES) stdio/vfscanf.c -o $@
%.obj : %.asm Makefile
fasm $< $
%.o : %.c Makefile
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o $@ $<
clean:
-rm -f */*.o

View File

@ -99,10 +99,9 @@ CORE_SRCS = {
"sys/clock_gettime.c",
"sys/close.c",
"sys/conio.c",
"sys/create.c",
"sys/chdir.c",
"sys/getcwd.c",
"sys/errno.c",
"sys/finfo.c",
"sys/fsize.c",
"sys/fstat.c",
"sys/gettod.c",
"sys/io.c",
@ -455,18 +454,6 @@ STDIO_SRCS = {
"wsetup.c"
}
DIRENT_SRCS = {
"dir.c",
"closedir.c",
"opendir.c",
"readdir.c",
"rewinddir.c",
"seekdir.c",
"telldir.c",
"scandir.c",
"alphasort.c",
}
MATH_SRCS = {
"e_acos.c", "e_acosh.c", "e_asin.c", "e_atan2.c", "e_atanh.c", "e_cosh.c", "e_exp.c", "e_fmod.c",
"e_hypot.c", "e_j0.c", "e_j1.c", "e_jn.c", "e_log.c", "e_log10.c", "e_pow.c", "e_rem_pio2.c",
@ -518,7 +505,6 @@ LIB_SRCS += CORE_SRCS
LIB_SRCS += prepend("stdio/", STDIO_SRCS)
LIB_SRCS += prepend("string/", STRING_SRCS)
LIB_SRCS += prepend("stdlib/", STDLIB_SRCS)
LIB_SRCS += prepend("dirent/", DIRENT_SRCS)
LIB_SRCS += prepend("math/", MATH_SRCS)
ALL_OBJS = {}

View File

@ -200,6 +200,7 @@ public_jmp con_gets2, 12
public_jmp con_cls, 0
public_jmp con_getch2, 0
public_jmp con_getch, 0
public_jmp con_kbhit, 0
public_jmp con_set_cursor_pos, 8
public_jmp con_get_cursor_pos, 8
public_jmp con_write_string, 8
@ -257,6 +258,7 @@ import console, \
con_cls, 'con_cls', \
con_getch2, 'con_getch2', \
con_getch, 'con_getch', \
con_kbhit, 'con_kbhit', \
con_set_cursor_pos, 'con_set_cursor_pos',\
con_get_cursor_pos, 'con_get_cursor_pos', \
con_write_string, 'con_write_string',\

View File

@ -17,7 +17,6 @@
#include <stdio.h>
#include <unistd.h>
#include <setjmp.h>
#include <sys/kos_io.h>
struct app_hdr
{

View File

@ -1,7 +0,0 @@
#include <string.h>
#include <dirent.h>
int alphasort(const struct dirent **a, const struct dirent **b)
{
return strcoll((*a)->d_name, (*b)->d_name);
}

View File

@ -1,14 +0,0 @@
/* Copyright (C) 2021 Logaev Maxim (turbocat2001), GPLv2 */
#include <sys/dirent.h>
#include <stdlib.h>
int closedir(DIR *dir){
if(dir == NULL){
return -1;
}else{
free(dir->objs);
free(dir);
return 0;
}
}

View File

@ -1,26 +0,0 @@
/* Copyright (C) 2021 Logaev Maxim (turbocat2001), GPLv2 */
#include "ksys_fs.h"
int rmdir(const char* dir){
return _ksys_file_delete(dir);
}
int mkdir(const char* dir, unsigned fake_mode){
return _ksys_mkdir(dir);
}
int chdir(char* dir){
_ksys_setcwd(dir);
return 0;
}
char *getcwd(char *buf, unsigned size){
if(!buf){
if((buf = malloc(size))==NULL){
return NULL;
}
}
_ksys_getcwd(buf, size);
return(buf);
}

View File

@ -1,120 +0,0 @@
/* Copyright (C) 2021 Logaev Maxim (turbocat2001), GPLv2 */
#ifndef _KSYS_FS_H_
#define _KSYS_FS_H_
#include <stdint.h>
#include <stddef.h>
#define asm_inline __asm__ __volatile__
#pragma pack(push,1)
typedef struct{
unsigned p00;
union{
uint64_t p04;
struct {
unsigned p04dw;
unsigned p08dw;
};
};
unsigned p12;
union {
unsigned p16;
const char *new_name;
void *bdfe;
void *buf16;
const void *cbuf16;
};
char p20;
const char *p21;
}ksys70_t;
typedef struct {
unsigned attributes;
unsigned name_cp;
char creation_time[4];
char creation_date[4];
char last_access_time[4];
char last_access_date[4];
char last_modification_time[4];
char last_modification_date[4];
unsigned long long size;
char name[0];
}ksys_bdfe_t;
#pragma pack(pop)
static inline
int _ksys_work_files(const ksys70_t *k)
{
int status;
asm_inline(
"int $0x40"
:"=a"(status)
:"a"(70), "b"(k)
:"memory"
);
return status;
}
static inline
int _ksys_file_delete(const char *name)
{
ksys70_t k;
k.p00 = 8;
k.p20 = 0;
k.p21 = name;
return _ksys_work_files(&k);
}
static inline
int _ksys_mkdir(const char *path)
{
ksys70_t dir_opt;
dir_opt.p00 = 9;
dir_opt.p21 = path;
return _ksys_work_files(&dir_opt);
}
static inline
void _ksys_setcwd(char* dir){
asm_inline(
"int $0x40"
::"a"(30), "b"(1), "c"(dir)
);
}
static inline
void* _ksys_alloc(size_t size){
void *val;
asm_inline(
"int $0x40"
:"=a"(val)
:"a"(68),"b"(12),"c"(size)
);
return val;
}
static inline
int _ksys_free(void *mem)
{
int val;
asm_inline(
"int $0x40"
:"=a"(val)
:"a"(68),"b"(13),"c"(mem)
);
return val;
}
static inline
int _ksys_getcwd(char* buf, int bufsize){
register int val;
asm_inline(
"int $0x40"
:"=a"(val):"a"(30), "b"(2), "c"(buf), "d"(bufsize)
);
return val;
}
#endif

View File

@ -1,53 +0,0 @@
/* Copyright (C) 2021 Logaev Maxim (turbocat2001), GPLv2 */
#include <sys/dirent.h>
#include "ksys_fs.h"
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#define CHECK_DIR_ERR() if(_ksys_work_files(&inf)){ \
free((void*)inf.p16); \
errno = ENOTDIR; \
return NULL; \
}
DIR* opendir(const char* path)
{
DIR* list = malloc(sizeof(DIR));
if(list==NULL){
errno = ENOMEM;
return NULL;
}
list->pos=0;
unsigned num_of_file=0;
static ksys70_t inf;
inf.p00 = 1;
inf.p04 = 0;
inf.p12 = 2;
inf.p16 = (unsigned) malloc(32+inf.p12*560);
inf.p20 = 0;
inf.p21 = (char*)path;
CHECK_DIR_ERR();
num_of_file = *(unsigned*)(inf.p16+8);
inf.p12 = num_of_file;
free((void*)inf.p16);
inf.p16 = (unsigned)_ksys_alloc(32+inf.p12*560);
list->objs = (struct dirent*) malloc(num_of_file*sizeof(struct dirent));
CHECK_DIR_ERR();
for(int i=0; i<num_of_file; i++){
list->objs[i].d_ino = i;
list->objs[i].d_type = *(unsigned*)(inf.p16+32+(264+40)*i);
strcpy(list->objs[i].d_name,(char*)(inf.p16+32+40+(264+40)*i));
}
list->num_objs = num_of_file;
return list;
}

View File

@ -1,14 +0,0 @@
/* Copyright (C) 2021 Logaev Maxim (turbocat2001), GPLv2 */
#include <sys/dirent.h>
#include <stdlib.h>
struct dirent* readdir(DIR *dir)
{
if(dir->num_objs>dir->pos){
dir->pos++;
return &dir->objs[dir->pos-1];
}else{
return NULL;
}
}

View File

@ -1,9 +0,0 @@
/* Copyright (C) 2021 Logaev Maxim (turbocat2001), GPLv2 */
#include <sys/dirent.h>
void rewinddir(DIR *dir){
if(dir!=NULL){
dir->pos=0;
}
}

View File

@ -1,46 +0,0 @@
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stddef.h>
#define SIZE_MAX 256
int scandir(const char *path, struct dirent ***res,
int (*sel)(const struct dirent *),
int (*cmp)(const struct dirent **, const struct dirent **))
{
DIR *d = opendir(path);
struct dirent *de, **names=0, **tmp;
size_t cnt=0, len=0;
int old_errno = errno;
if (!d) return -1;
while ((errno=0), (de = readdir(d))) {
if (sel && !sel(de)) continue;
if (cnt >= len) {
len = 2*len+1;
if (len > SIZE_MAX/sizeof *names) break;
tmp = realloc(names, len * sizeof *names);
if (!tmp) break;
names = tmp;
}
names[cnt] = malloc(sizeof(struct dirent));
if (!names[cnt]) break;
memcpy(names[cnt++], de, sizeof(struct dirent));
}
closedir(d);
if (errno) {
if (names) while (cnt-->0) free(names[cnt]);
free(names);
return -1;
}
errno = old_errno;
if (cmp) qsort(names, cnt, sizeof *names, (int (*)(const void *, const void *))cmp);
*res = names;
return cnt;
}

View File

@ -1,12 +0,0 @@
/* Copyright (C) 2021 Logaev Maxim (turbocat2001), GPLv2 */
#include <sys/dirent.h>
void seekdir(DIR *dir, unsigned pos)
{
if(dir==NULL || pos>dir->num_objs){
return;
}
dir->pos=pos;
return;
}

View File

@ -1,12 +0,0 @@
/* Copyright (C) 2021 Logaev Maxim (turbocat2001), GPLv2 */
#include <sys/dirent.h>
unsigned telldir(DIR *dir)
{
if(dir!=NULL){
return dir->pos;
}else{
return 0;
}
}

View File

@ -1,16 +0,0 @@
#ifndef _DIRENT_H_
#define _DIRENT_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/cdefs.h>
#include <sys/dirent.h>
#if !defined(MAXNAMLEN) && __BSD_VISIBLE
#define MAXNAMLEN 1024
#endif
#ifdef __cplusplus
}
#endif
#endif /*_DIRENT_H_*/

View File

@ -1,679 +0,0 @@
#ifndef __KOS_32_SYS_H__
#define __KOS_32_SYS_H__
#include <newlib.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
//#ifdef CONFIG_DEBUF
// #define DBG(format,...) printf(format,##__VA_ARGS__)
//#else
// #define DBG(format,...)
//#endif
#define TYPE_3_BORDER_WIDTH 5
#define WIN_STATE_MINIMIZED 0x02
#define WIN_STATE_ROLLED 0x04
typedef unsigned int color_t;
typedef union __attribute__((packed))
{
uint32_t val;
struct
{
short x;
short y;
};
}pos_t;
typedef union __attribute__((packed))
{
uint32_t val;
struct
{
uint8_t state;
uint8_t code;
uint16_t ctrl_key;
};
}oskey_t;
typedef struct
{
unsigned handle;
unsigned io_code;
void *input;
int inp_size;
void *output;
int out_size;
}ioctl_t;
#pragma pack(push, 1)
struct proc_info
{
unsigned long cpu_usage;
unsigned short pos_in_stack;
unsigned short slot;
unsigned short reserved2;
char name[12];
unsigned long address;
unsigned long memory_usage;
unsigned long ID;
unsigned long left,top;
unsigned long width,height;
unsigned short thread_state;
unsigned short reserved3;
unsigned long cleft, ctop, cwidth, cheight;
unsigned char window_state;
unsigned char reserved4[1024-71];
};
#pragma pack(pop)
struct kolibri_system_colors {
color_t frame_area;
color_t grab_bar;
color_t grab_bar_button;
color_t grab_button_text;
color_t grab_text;
color_t work_area;
color_t work_button;
color_t work_button_text;
color_t work_text;
color_t work_graph;
};
static inline void begin_draw(void)
{
__asm__ __volatile__(
"int $0x40" ::"a"(12),"b"(1));
};
static inline
void end_draw(void)
{
__asm__ __volatile__(
"int $0x40" ::"a"(12),"b"(2));
};
static inline void
put_image(uint16_t x_coord, uint16_t y_coord,
uint16_t size_x, uint16_t size_y, void *img)
{
__asm__ __volatile__("int $0x40"
::"a"(25),
"b"(img),
"c"(size_x<<16 | size_y),
"d"(x_coord<<16 | y_coord));
};
static inline
void sys_create_window(int x, int y, int w, int h, const char *name,
color_t workcolor, uint32_t style)
{
__asm__ __volatile__(
"int $0x40"
::"a"(0),
"b"((x << 16) | ((w-1) & 0xFFFF)),
"c"((y << 16) | ((h-1) & 0xFFFF)),
"d"((style << 24) | (workcolor & 0xFFFFFF)),
"D"(name),
"S"(0) : "memory");
};
#define OLD -1
static inline
void sys_change_window(int new_x, int new_y, int new_w, int new_h)
{
__asm__ __volatile__(
"int $0x40"
::"a"(67), "b"(new_x), "c"(new_y), "d"(new_w),"S"(new_h)
);
}
static inline
void define_button(uint32_t x_w, uint32_t y_h, uint32_t id, uint32_t color)
{
__asm__ __volatile__(
"int $0x40"
::"a"(8),
"b"(x_w),
"c"(y_h),
"d"(id),
"S"(color));
};
static inline
void draw_line(int xs, int ys, int xe, int ye, color_t color)
{
__asm__ __volatile__(
"int $0x40"
::"a"(38), "d"(color),
"b"((xs << 16) | xe),
"c"((ys << 16) | ye));
}
static inline
void draw_bar(int x, int y, int w, int h, color_t color)
{
__asm__ __volatile__(
"int $0x40"
::"a"(13), "d"(color),
"b"((x << 16) | w),
"c"((y << 16) | h));
}
static inline
void draw_bitmap(void *bitmap, int x, int y, int w, int h)
{
__asm__ __volatile__(
"int $0x40"
::"a"(7), "b"(bitmap),
"c"((w << 16) | h),
"d"((x << 16) | y));
}
static inline
void draw_text_sys(const char *text, int x, int y, int len, color_t color)
{
__asm__ __volatile__(
"int $0x40"
::"a"(4),"d"(text),
"b"((x << 16) | y),
"S"(len),"c"(color)
:"memory");
}
/*
void define_button_text(int x, int y, int w, int h, uint32_t id, uint32_t color, char* text)
{
define_button(x * 65536 + w, y * 65536 + h, id, color);
int tx = ((((-strlen(text))*8)+w)/2)+x;
int ty = h/2-7+y;
draw_text_sys(text, tx, ty, strlen(text), 0x90000000);
};
*/
static inline
uint32_t get_skin_height(void)
{
uint32_t height;
__asm__ __volatile__(
"int $0x40 \n\t"
:"=a"(height)
:"a"(48),"b"(4));
return height;
};
static inline void BeginDraw(void) __attribute__ ((alias ("begin_draw")));
static inline void EndDraw(void) __attribute__ ((alias ("end_draw")));
static inline void DrawWindow(int x, int y, int w, int h, const char *name,
color_t workcolor, uint32_t style)
__attribute__ ((alias ("sys_create_window")));
static inline void DefineButton(void) __attribute__ ((alias ("define_button")));
static inline void DrawLine(int xs, int ys, int xe, int ye, color_t color)
__attribute__ ((alias ("draw_line")));
static inline void DrawBar(int x, int y, int w, int h, color_t color)
__attribute__ ((alias ("draw_bar")));
static inline void DrawBitmap(void *bitmap, int x, int y, int w, int h)
__attribute__ ((alias ("draw_bitmap")));
static inline uint32_t GetSkinHeight(void) __attribute__ ((alias ("get_skin_height")));
#define POS_SCREEN 0
#define POS_WINDOW 1
static inline
pos_t get_mouse_pos(int origin)
{
pos_t val;
__asm__ __volatile__(
"int $0x40 \n\t"
"rol $16, %%eax"
:"=a"(val)
:"a"(37),"b"(origin));
return val;
}
static inline
uint32_t get_mouse_buttons(void)
{
uint32_t val;
__asm__ __volatile__(
"int $0x40"
:"=a"(val)
:"a"(37),"b"(2));
return val;
};
static inline
uint32_t get_mouse_wheels(void)
{
uint32_t val;
__asm__ __volatile__(
"int $0x40 \n\t"
:"=a"(val)
:"a"(37),"b"(7));
return val;
};
static inline uint32_t load_cursor(void *path, uint32_t flags)
{
uint32_t val;
__asm__ __volatile__(
"int $0x40"
:"=a"(val)
:"a"(37), "b"(4), "c"(path), "d"(flags));
return val;
}
static inline uint32_t set_cursor(uint32_t cursor)
{
uint32_t old;
__asm__ __volatile__(
"int $0x40"
:"=a"(old)
:"a"(37), "b"(5), "c"(cursor));
return old;
};
#define EVM_REDRAW 1
#define EVM_KEY 2
#define EVM_BUTTON 4
#define EVM_EXIT 8
#define EVM_BACKGROUND 16
#define EVM_MOUSE 32
#define EVM_IPC 64
#define EVM_STACK 128
#define EVM_DEBUG 256
#define EVM_STACK2 512
#define EVM_MOUSE_FILTER 0x80000000
#define EVM_CURSOR_FILTER 0x40000000
static inline uint32_t set_wanted_events_mask(uint32_t event_mask)
{
uint32_t old_event_mask;
__asm__ __volatile__(
"int $0x40"
:"=a"(old_event_mask)
:"a"(40),"b"(event_mask));
return old_event_mask;
};
static inline int destroy_cursor(uint32_t cursor)
{
int ret;
__asm__ __volatile__(
"int $0x40"
:"=a"(ret)
:"a"(37), "b"(6), "c"(cursor)
:"memory");
return ret;
};
static inline pos_t GetMousePos(int origin) __attribute__ ((alias ("get_mouse_pos")));
static inline uint32_t GetMouseButtons(void) __attribute__ ((alias ("get_mouse_buttons")));
static inline uint32_t GetMouseWheels(void) __attribute__ ((alias ("get_mouse_wheels")));
static inline uint32_t LoadCursor(void *path, uint32_t flags) __attribute__ ((alias ("load_cursor")));
static inline uint32_t SetCursor(uint32_t cursor) __attribute__ ((alias ("set_cursor")));
static inline int DestroyCursor(uint32_t cursor) __attribute__ ((alias ("destroy_cursor")));
static inline
uint32_t wait_for_event(uint32_t time)
{
uint32_t val;
__asm__ __volatile__(
"int $0x40"
:"=a"(val)
:"a"(23), "b"(time));
return val;
};
static inline uint32_t check_os_event(void)
{
uint32_t val;
__asm__ __volatile__(
"int $0x40"
:"=a"(val)
:"a"(11));
return val;
};
static inline uint32_t get_os_event(void)
{
uint32_t val;
__asm__ __volatile__(
"int $0x40"
:"=a"(val)
:"a"(10));
return val;
};
static inline uint32_t GetOsEvent(void) __attribute__ ((alias ("get_os_event")));
static inline
uint32_t get_tick_count(void)
{
uint32_t val;
__asm__ __volatile__(
"int $0x40"
:"=a"(val)
:"a"(26),"b"(9));
return val;
};
static inline
uint64_t get_ns_count(void)
{
uint64_t val;
__asm__ __volatile__(
"int $0x40"
:"=A"(val)
:"a"(26), "b"(10));
return val;
};
static inline
oskey_t get_key(void)
{
oskey_t val;
__asm__ __volatile__(
"int $0x40"
:"=a"(val)
:"a"(2));
return val;
}
static inline
uint32_t get_os_button(void)
{
uint32_t val;
__asm__ __volatile__(
"int $0x40"
:"=a"(val)
:"a"(17));
return val>>8;
};
static inline uint32_t
heap_init(void)
{
uint32_t heapsize;
__asm__ __volatile__(
"int $0x40"
:"=a"(heapsize)
:"a"(68),"b"(11)
);
return heapsize;
}
static inline uint32_t get_service(char *name)
{
uint32_t retval = 0;
__asm__ __volatile__(
"int $0x40"
:"=a"(retval)
:"a"(68),"b"(16),"c"(name)
:"memory");
return retval;
};
static inline int call_service(ioctl_t *io)
{
int retval;
__asm__ __volatile__(
"int $0x40"
:"=a"(retval)
:"a"(68),"b"(17),"c"(io)
:"memory","cc");
return retval;
};
static inline void yield(void)
{
__asm__ __volatile__(
"int $0x40"
::"a"(68), "b"(1));
};
static inline void delay(uint32_t time)
{
__asm__ __volatile__(
"int $0x40"
::"a"(5), "b"(time)
:"memory");
};
static inline
void *user_alloc(size_t size)
{
void *val;
__asm__ __volatile__(
"int $0x40"
:"=a"(val)
:"a"(68),"b"(12),"c"(size));
return val;
}
static inline
int user_free(void *mem)
{
int val;
__asm__ __volatile__(
"int $0x40"
:"=a"(val)
:"a"(68),"b"(13),"c"(mem));
return val;
}
static inline
void* user_realloc(void *mem, size_t size)
{
void *val;
__asm__ __volatile__(
"int $0x40"
:"=a"(val)
:"a"(68),"b"(20),"c"(size),"d"(mem)
:"memory");
return val;
};
static inline
int *user_unmap(void *base, size_t offset, size_t size)
{
int *val;
__asm__ __volatile__(
"int $0x40"
:"=a"(val)
:"a"(68),"b"(26),"c"(base),"d"(offset),"S"(size));
return val;
};
static inline void *UserAlloc(size_t size) __attribute__ ((alias ("user_alloc")));
static inline int UserFree(void *mem) __attribute__ ((alias ("user_free")));
static inline void* UserRealloc(void *mem, size_t size) __attribute__ ((alias ("user_realloc")));
static inline int *UserUnmap(void *base, size_t offset, size_t size) __attribute__ ((alias ("user_unmap")));
typedef union
{
struct
{
void *data;
size_t size;
};
unsigned long long raw;
}ufile_t;
static inline ufile_t load_file(const char *path)
{
ufile_t uf;
__asm__ __volatile__ (
"int $0x40"
:"=A"(uf.raw)
:"a" (68), "b"(27),"c"(path));
return uf;
};
static inline ufile_t LoadFile(const char *path) __attribute__ ((alias ("load_file")));
static inline int GetScreenSize(void)
{
int retval;
__asm__ __volatile__(
"int $0x40"
:"=a"(retval)
:"a"(61), "b"(1));
return retval;
}
static inline
pos_t max_screen_size()
{
pos_t size;
pos_t size_tmp;
__asm__ __volatile__(
"int $0x40"
:"=a"(size_tmp)
:"a"(14));
size.x = size_tmp.y;
size.y = size_tmp.x;
return size;
};
static inline void get_system_colors(struct kolibri_system_colors *color_table)
{
__asm__ volatile ("int $0x40"
:
:"a"(48),"b"(3),"c"(color_table),"d"(40)
);
}
static inline void get_proc_info(char *info)
{
__asm__ __volatile__(
"int $0x40"
:
:"a"(9), "b"(info), "c"(-1)
:"memory");
};
static inline void GetProcInfo(char *info) __attribute__ ((alias ("get_proc_info")));
struct blit_call
{
int dstx;
int dsty;
int w;
int h;
int srcx;
int srcy;
int srcw;
int srch;
void *bitmap;
int stride;
};
static inline void Blit(void *bitmap, int dst_x, int dst_y,
int src_x, int src_y, int w, int h,
int src_w, int src_h, int stride)
{
volatile struct blit_call bc;
bc.dstx = dst_x;
bc.dsty = dst_y;
bc.w = w;
bc.h = h;
bc.srcx = src_x;
bc.srcy = src_y;
bc.srcw = src_w;
bc.srch = src_h;
bc.stride = stride;
bc.bitmap = bitmap;
__asm__ __volatile__(
"int $0x40"
::"a"(73),"b"(0),"c"(&bc.dstx));
};
#define TLS_KEY_PID 0
#define TLS_KEY_TID 4
#define TLS_KEY_LOW_STACK 8
#define TLS_KEY_HIGH_STACK 12
#define TLS_KEY_LIBC 16
unsigned int tls_alloc(void);
int tls_free(unsigned int key);
static inline int tls_set(unsigned int key, void *val)
{
int ret = -1;
if(key < 4096)
{
__asm__ __volatile__(
"movl %0, %%fs:(%1)"
::"r"(val),"r"(key));
ret = 0;
}
return ret;
};
static inline void *tls_get(unsigned int key)
{
void *val = (void*)-1;
if(key < 4096)
{
__asm__ __volatile__(
"movl %%fs:(%1), %0"
:"=r"(val)
:"r"(key));
};
return val;
}
int create_thread(int (*proc)(void *param), void *param, int stack_size);
void* load_library(const char *name);
void* get_proc_address(void *handle, const char *proc_name);
void enumerate_libraries(int (*callback)(void *handle, const char* name,
uint32_t base, uint32_t size, void *user_data),
void *user_data);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,14 +0,0 @@
/* BSD predecessor of POSIX.1 <dirent.h> and struct dirent */
#ifndef _SYS_DIR_H_
#define _SYS_DIR_H_
#include <dirent.h>
#define direct dirent
extern int chdir(char* dir);
extern int rmdir(const char* dir);
extern int mkdir(const char* dir, unsigned fake_mode);
#endif /*_SYS_DIR_H_*/

View File

@ -1,41 +0,0 @@
/* <dirent.h> includes <sys/dirent.h>, which is this file. On a
system which supports <dirent.h>, this file is overridden by
dirent.h in the libc/sys/.../sys directory. On a system which does
not support <dirent.h>, we will get this file which uses #error to force
an error. */
#ifdef __cplusplus
extern "C" {
#endif
#define DT_DIR 16
#define DT_REG 0
#include <limits.h>
#include <sys/types.h>
struct dirent{
ino_t d_ino;
unsigned d_type;
char d_name[256];
};
typedef struct{
struct dirent* objs;
ino_t pos;
ino_t num_objs;
}DIR;
extern int closedir(DIR *dir);
extern DIR* opendir(const char *path);
extern struct dirent* readdir(DIR *);
extern void rewinddir(DIR *dir);
extern void seekdir(DIR *dir, unsigned pos);
extern unsigned telldir(DIR *dir);
extern int scandir(const char *path, struct dirent ***res, int (*sel)(const struct dirent *), int (*cmp)(const struct dirent **, const struct dirent **));
extern int alphasort(const struct dirent **a, const struct dirent **b);
#ifdef __cplusplus
}
#endif

View File

@ -1,147 +0,0 @@
// Console.obj loading for kos32-gcc
// Writed by rgimad and maxcodehack
//
// Usage:
// #include <sys/kos_LoadConsole.h>
// load_console();
//
#include <string.h>
#include <stdlib.h>
#ifndef CONSOLE_OBJ_H
#define CONSOLE_OBJ_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef NULL
#define NULL 0
#endif
#ifndef cdecl
#define cdecl __attribute__ ((cdecl))
#endif
#ifndef stdcall
#define stdcall __attribute__ ((stdcall))
#endif
typedef unsigned int dword;
typedef unsigned short word;
const char* imports[] = {
"START", "version", "con_init", "con_write_asciiz", "con_write_string",
"con_printf", "con_exit", "con_get_flags", "con_set_flags", "con_kbhit",
"con_getch", "con_getch2", "con_gets", "con_gets2", "con_get_font_height",
"con_get_cursor_height", "con_set_cursor_height", "con_cls",
"con_get_cursor_pos", "con_set_cursor_pos", "con_set_title",
(char*)0
};
dword *version;
typedef int (stdcall * con_gets2_callback)(int keycode, char** pstr, int* pn,
int* ppos);
void stdcall (*con_init)(dword wnd_width, dword wnd_height, dword scr_width, dword scr_height, const char* title) = 0;
void stdcall (*con_exit)(int bCloseWindow) = 0;
void stdcall (*con_set_title)(const char* title) = 0;
void stdcall (*con_write_asciiz)(const char* str) = 0;
void stdcall (*con_write_string)(const char* str, dword length) = 0;
int cdecl (*con_printf)(const char* format, ...) = 0;
dword stdcall (*con_get_flags)(void) = 0;
dword stdcall (*con_set_flags)(dword new_flags) = 0;
int stdcall (*con_get_font_height)(void) = 0;
int stdcall (*con_get_cursor_height)(void) = 0;
int stdcall (*con_set_cursor_height)(int new_height) = 0;
int stdcall (*con_getch)(void) = 0;
word stdcall (*con_getch2)(void) = 0;
int stdcall (*con_kbhit)(void) = 0;
char* stdcall (*con_gets)(char* str, int n) = 0;
char* stdcall (*con_gets2)(con_gets2_callback callback, char* str, int n) = 0;
void stdcall (*con_cls)() = 0;
void stdcall (*con_get_cursor_pos)(int* px, int* py) = 0;
void stdcall (*con_set_cursor_pos)(int x, int y) = 0;
const char lib_path[] = "/sys/lib/console.obj";
void* load_library(const char *name)
{
void *table;
__asm__ __volatile__(
"int $0x40"
:"=a"(table)
:"a"(68), "b"(19), "c"(name));
return table;
}
void *load_library_procedure(void *exports, const char *name)
{
if (exports == NULL) { return 0; }
while (*(dword*)exports != 0)
{
char *str1 = (char*)(*(dword*)exports);
if (strcmp(str1, name) == 0)
{
void *ptr = (void*)*(dword*)(exports + 4);
return ptr;
}
exports += 8;
}
return 0;
}
void output_debug_string(const char *s)
{
unsigned int i = 0;
while(*(s + i))
{
__asm__ __volatile__ ("int $0x40"::"a"(63), "b"(1), "c"(*(s + i)));
i++;
}
}
void load_console()
{
void *lib = load_library(lib_path);
if (!lib)
{
output_debug_string("Console.obj loading error\r\n");
exit(1);
}
dword (*start_lib)(dword) = (dword(*)(dword))load_library_procedure(lib, imports[0]);
version = (dword*)load_library_procedure(lib, imports[1]);
con_init = (void stdcall(*)(dword,dword,dword,dword,const char*))load_library_procedure(lib, imports[2]);
con_write_asciiz = (void stdcall(*)(const char*))load_library_procedure(lib, imports[3]);
con_write_string = (void stdcall(*)(const char*,dword))load_library_procedure(lib, imports[4]);
con_printf = (int cdecl(*)(const char*,...))load_library_procedure(lib, imports[5]);
con_exit = (void stdcall(*)(int))load_library_procedure(lib, imports[6]);
con_get_flags = (dword stdcall(*)(void))load_library_procedure(lib, imports[7]);
con_set_flags = (dword stdcall(*)(dword))load_library_procedure(lib, imports[8]);
con_kbhit = (int stdcall(*)(void))load_library_procedure(lib, imports[9]);
con_getch = (int stdcall(*)(void))load_library_procedure(lib, imports[10]);
con_getch2 = (word stdcall(*)(void))load_library_procedure(lib, imports[11]);
con_gets = (char* stdcall(*)(char*,int))load_library_procedure(lib, imports[12]);
con_gets2 = (char* stdcall(*)(con_gets2_callback,char*,int))load_library_procedure(lib, imports[13]);
con_get_font_height = (int stdcall(*)(void))load_library_procedure(lib, imports[14]);
con_get_cursor_height = (int stdcall(*)(void))load_library_procedure(lib, imports[15]);
con_set_cursor_height = (int stdcall(*)(int))load_library_procedure(lib, imports[16]);
con_cls = (void stdcall(*)(void))load_library_procedure(lib, imports[17]);
con_get_cursor_pos = (void stdcall(*)(int*,int*))load_library_procedure(lib, imports[18]);
con_set_cursor_pos = (void stdcall(*)(int,int))load_library_procedure(lib, imports[19]);
con_set_title = (void stdcall(*)(const char*))load_library_procedure(lib, imports[20]);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,85 +0,0 @@
#ifndef __KOS_IO_H__
#define __KOS_IO_H__
#ifdef __cplusplus
extern "C" {
#endif
#pragma pack(push, 1)
typedef struct
{
char sec;
char min;
char hour;
char rsv;
}detime_t;
typedef struct
{
char day;
char month;
short year;
}dedate_t;
typedef struct
{
unsigned attr;
unsigned flags;
union
{
detime_t ctime;
unsigned cr_time;
};
union
{
dedate_t cdate;
unsigned cr_date;
};
union
{
detime_t atime;
unsigned acc_time;
};
union
{
dedate_t adate;
unsigned acc_date;
};
union
{
detime_t mtime;
unsigned mod_time;
};
union
{
dedate_t mdate;
unsigned mod_date;
};
unsigned size;
unsigned size_high;
} fileinfo_t;
#pragma pack(pop)
int create_file(const char *path);
int get_fileinfo(const char *path, fileinfo_t *info);
int set_fileinfo(const char *path, fileinfo_t *info);
int read_file(const char *path, void *buff,
size_t offset, size_t count, size_t *reads);
int write_file(const char *path,const void *buff,
size_t offset, size_t count, size_t *writes);
int set_file_size(const char *path, unsigned size);
void unpack(void* packed_data, void* unpacked_data) __attribute__((stdcall)) ;
static inline void set_cwd(const char* cwd)
{
__asm__ __volatile__(
"int $0x40"
::"a"(30),"b"(1),"c"(cwd));
};
#ifdef __cplusplus
}
#endif
#endif

View File

@ -21,6 +21,7 @@
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
@ -82,43 +83,48 @@ typedef struct {
} ksys_ufile_t;
typedef struct {
uint32_t p00;
uint32_t func_num;
union {
uint64_t p04;
uint64_t offset64;
struct {
uint32_t p04dw;
uint32_t p08dw;
union {
uint32_t debug;
uint32_t offset;
};
union {
uint32_t flags;
char* args;
};
};
};
uint32_t p12;
uint32_t data_size;
void* data;
union {
uint32_t p16;
const char* new_name;
void* bdfe;
void* buf16;
const void* cbuf16;
struct {
uint8_t zero;
char* path_ptr;
};
char path[0];
};
char p20;
const char* p21;
} ksys70_t;
} ksys_file_t;
typedef struct {
uint32_t status;
uint32_t rw_bytes;
} ksys70_status_t;
} ksys_file_status_t;
typedef struct {
uint32_t attributes;
uint32_t name_cp;
ksys_time_t creation_time;
ksys_date_t creation_date;
ksys_time_t last_access_time;
ksys_date_t last_access_date;
ksys_time_t last_modification_time;
ksys_date_t last_modification_date;
uint32_t attr;
uint32_t name_enc;
ksys_time_t ctime;
ksys_date_t cdate;
ksys_time_t atime;
ksys_date_t adate;
ksys_time_t mtime;
ksys_date_t mdate;
uint64_t size;
char name[0];
} ksys_bdfe_t;
} ksys_file_info_t;
#define KSYS_THREAD_INFO_SIZE 1024
@ -1483,125 +1489,166 @@ KOSAPI ksys_ufile_t _ksys_load_file_enc(const char* path, unsigned file_encoding
/*==== Function 70 - work with file system with long names support. ====*/
KOSAPI ksys70_status_t _ksys70(const ksys70_t* k)
enum KSYS_FILE_FUNC {
KSYS_FILE_READ = 0,
KSYS_FILE_READ_DIR,
KSYS_FILE_CREATE,
KSYS_FILE_WRITE,
KSYS_FILE_SET_SIZE,
KSYS_FILE_GET_INFO,
KSYS_FILE_SET_ATTR,
KSYS_FILE_EXEC,
KSYS_FILE_REMOVE,
KSYS_FILE_CREATE_DIR,
KSYS_FILE_RENAME,
};
KOSAPI ksys_file_status_t _ksys_file(const ksys_file_t* info)
{
ksys70_status_t status;
ksys_file_status_t st;
asm_inline(
"int $0x40"
: "=a"(status.status), "=b"(status.rw_bytes)
: "a"(70), "b"(k)
: "=a"(st.status), "=b"(st.rw_bytes)
: "a"(70), "b"(info)
: "memory");
return status;
return st;
}
/*====== Function 70, subfunction 0 - read file with long names support. ======*/
KOSAPI ksys70_status_t _ksys_file_read(const char* name, uint64_t offset, uint32_t size, void* buf)
KOSAPI ksys_file_status_t _ksys_file_read(const char* name, uint64_t offset, uint32_t size, void* buf)
{
ksys70_t k;
k.p00 = 0;
k.p04 = offset;
k.p12 = size;
k.buf16 = buf;
k.p20 = 0;
k.p21 = name;
return _ksys70(&k);
ksys_file_t f;
f.func_num = KSYS_FILE_READ;
f.offset64 = offset;
f.data_size = size;
f.data = buf;
f.zero = 0;
f.path_ptr = (char*)name;
return _ksys_file(&f);
}
/*===================== Function 70, subfunction 2 =====================*/
/*============ Create/rewrite file with long names support. ============*/
KOSAPI int _ksys_file_create(const char* name)
KOSAPI ksys_file_status_t _ksys_file_create(const char* name)
{
ksys70_t k;
k.p00 = 2;
k.p04dw = 0;
k.p08dw = 0;
k.p12 = 0;
k.p21 = name;
return _ksys70(&k).status;
ksys_file_t f;
f.func_num = KSYS_FILE_CREATE;
f.offset64 = 0;
f.data_size = 0;
f.data = NULL;
f.zero = 0;
f.path_ptr = (char*)name;
return _ksys_file(&f);
}
/*===================== Function 70, subfunction 3 =====================*/
/*=========== Write to existing file with long names support. ==========*/
KOSAPI ksys70_status_t _ksys_file_write(const char* name, uint64_t offset, uint32_t size, const void* buf)
KOSAPI ksys_file_status_t _ksys_file_write(const char* name, uint64_t offset, uint32_t size, const void* buf)
{
ksys70_t k;
k.p00 = 3;
k.p04 = offset;
k.p12 = size;
k.cbuf16 = buf;
k.p20 = 0;
k.p21 = name;
return _ksys70(&k);
ksys_file_t f;
f.func_num = KSYS_FILE_WRITE;
f.offset64 = offset;
f.data_size = size;
f.data = (void*)buf;
f.zero = 0;
f.path_ptr = (char*)name;
return _ksys_file(&f);
}
/*========== Function 70, subfunction 4 - set file size. =====*/
KOSAPI int _ksys_file_set_size(const char* name, uint64_t size)
{
ksys_file_t f;
f.func_num = KSYS_FILE_SET_SIZE;
f.offset64 = size;
f.data_size = 0;
f.data = NULL;
f.zero = 0;
f.path_ptr = (char*)name;
return _ksys_file(&f).status;
}
/*========== Function 70, subfunction 5 - get information on file/folder. =====*/
KOSAPI int _ksys_file_info(const char* name, ksys_bdfe_t* bdfe)
KOSAPI int _ksys_file_info(const char* name, ksys_file_info_t* info)
{
ksys70_t k;
k.p00 = 5;
k.p04dw = 0;
k.p08dw = 0;
k.p12 = 0;
k.bdfe = bdfe;
k.p20 = 0;
k.p21 = name;
return _ksys70(&k).status;
ksys_file_t f;
f.func_num = KSYS_FILE_GET_INFO;
f.offset64 = 0;
f.data_size = 0;
f.data = (void*)info;
f.zero = 0;
f.path_ptr = (char*)name;
return _ksys_file(&f).status;
}
#define _ksys_dir_info _ksys_file_info
KOSAPI uint64_t _ksys_file_get_size(const char* name, int* err)
{
ksys_file_info_t info;
*err = _ksys_file_info(name, &info);
return info.size;
}
#define _ksys_dir_info _ksys_file_info
/*=========== Function 70, subfunction 7 - start application. ===========*/
KOSAPI int _ksys_exec(const char* app_name, char* args)
KOSAPI int _ksys_exec(const char* path, char* args, bool debug)
{
ksys70_t file_opt;
file_opt.p00 = 7;
file_opt.p04dw = 0;
file_opt.p08dw = (uint32_t)args;
file_opt.p12 = 0;
file_opt.p16 = 0;
file_opt.p20 = 0;
file_opt.p21 = app_name;
return _ksys70(&file_opt).status;
ksys_file_t f;
f.func_num = KSYS_FILE_EXEC;
f.debug = debug;
f.args = args;
f.zero = 0;
f.path_ptr = (char*)path;
return _ksys_file(&f).status;
}
/*========== Function 70, subfunction 8 - delete file/folder. ==========*/
KOSAPI int _ksys_file_delete(const char* name)
KOSAPI int _ksys_file_delete(const char* path)
{
ksys70_t k;
k.p00 = 8;
k.p20 = 0;
k.p21 = name;
return _ksys70(&k).status;
ksys_file_t f;
f.func_num = KSYS_FILE_REMOVE;
f.offset64 = 0;
f.data_size = 0;
f.data = NULL;
f.zero = 0;
f.path_ptr = (char*)path;
return _ksys_file(&f).status;
}
/*============= Function 70, subfunction 9 - create folder. =============*/
KOSAPI int _ksys_mkdir(const char* path)
{
ksys70_t dir_opt;
dir_opt.p00 = 9;
dir_opt.p21 = path;
return _ksys70(&dir_opt).status;
ksys_file_t f;
f.func_num = KSYS_FILE_CREATE_DIR;
f.offset64 = 0;
f.data_size = 0;
f.data = NULL;
f.zero = 0;
f.path_ptr = (char*)path;
return _ksys_file(&f).status;
}
/*============= Function 70, subfunction 10 - rename/move. =============*/
KOSAPI int _ksys_file_rename(const char* name, const char* new_name)
{
ksys70_t k;
k.p00 = 10;
k.new_name = new_name;
k.p20 = 0;
k.p21 = name;
return _ksys70(&k).status;
ksys_file_t f;
f.func_num = KSYS_FILE_REMOVE;
f.data = (void*)new_name;
f.data_size = 0;
f.zero = 0;
f.path_ptr = (char*)name;
return _ksys_file(&f).status;
}
#define _ksys_dir_rename _ksys_file_rename
@ -1707,25 +1754,6 @@ KOSAPI int _ksys_posix_pipe2(int pipefd[2], int flags)
return err;
}
/* ######### Old names of functions and structures. Do not use again! ##########*/
#define _ksys_get_event _ksys_wait_event
#define _ksys_file_get_info _ksys_file_info
static inline int _ksys_file_read_file(const char* name, unsigned long long offset, unsigned size, void* buff, unsigned* bytes_read)
{
ksys70_status_t res = _ksys_file_read(name, offset, size, buff);
*bytes_read = res.rw_bytes;
return res.status;
}
static inline int _ksys_file_write_file(const char* name, unsigned long long offset, unsigned size, const void* buff, unsigned* bytes_write)
{
ksys70_status_t res = _ksys_file_write(name, offset, size, buff);
*bytes_write = res.rw_bytes;
return res.status;
}
#ifdef __cplusplus
}
#endif

View File

@ -1,216 +0,0 @@
#ifndef __SOCKET_H__
#define __SOCKET_H__
#include <stddef.h>
// Socket Types
#define SOCK_STREAM 1
#define SOCK_DGRAM 2
#define SOCK_RAW 3
// IP protocols
#define IPPROTO_IP 0
#define IPPROTO_ICMP 1
#define IPPROTO_TCP 6
#define IPPROTO_UDP 17
#define IPPROTO_RAW 255
// IP options
#define IP_TTL 2
// Address families
#define AF_UNSPEC 0
#define AF_LOCAL 1
#define AF_INET 2 // Default INET=IPv4
#define AF_INET4 2 // IPv4
#define AF_INET6 10 // IPv6
#define PF_UNSPEC AF_UNSPEC
#define PF_LOCAL AF_LOCAL
#define PF_INET4 AF_INET4
#define PF_INET6 AF_INET6
// internal definition
#define AI_SUPPORTED 0x40F
// for system function 76
#define API_ETH (0<<16)
#define API_IPv4 (1<<16)
#define API_ICMP (2<<16)
#define API_UDP (3<<16)
#define API_TCP (4<<16)
#define API_ARP (5<<16)
#define API_PPPOE (6<<16)
// Socket flags for user calls
#define MSG_NOFLAG 0
#define MSG_PEEK 0x02
#define MSG_DONTWAIT 0x40
// Socket levels
#define SOL_SOCKET 0xffff
//Socket options
#define SO_BINDTODEVICE (1<<9)
#define SO_NONBLOCK (1<<31)
// Error Codes
#define ENOBUFS 1
#define EINPROGRESS 2
#define EOPNOTSUPP 4
#define EWOULDBLOCK 6
#define ENOTCONN 9
#define EALREADY 10
#define EINVALUE 11
#define EMSGSIZE 12
#define ENOMEM 18
#define EADDRINUSE 20
#define ECONNREFUSED 61
#define ECONNRESET 52
#define EISCONN 56
#define ETIMEDOUT 60
#define ECONNABORTED 53
#define PORT(X) (X<<8)
int err_code;
#pragma pack(push,1)
struct sockaddr{
unsigned short sin_family;
unsigned short sin_port;
unsigned int sin_addr;
unsigned long long sin_zero;
};
#pragma pack(pop)
#pragma pack(push,1)
typedef struct{
unsigned int level;
unsigned int optionname;
unsigned int optlenght;
unsigned char options;
}optstruct;
#pragma pack(pop)
static inline int socket(int domain, int type, int protocol)
{
int socket;
asm volatile(
"int $0x40"
:"=b"(err_code), "=a"(socket)
:"a"(75), "b"(0), "c"(domain), "d"(type), "S"(protocol)
);
return socket;
}
static inline int close(int socket)
{
int status;
asm volatile(
"int $0x40"
:"=b"(err_code), "=a"(status)
:"a"(75), "b"(1), "c"(socket)
);
return status;
}
static inline int bind(int socket, const struct sockaddr *addres, int addres_len)
{
int status;
asm volatile(
"int $0x40"
:"=b"(err_code), "=a"(status)
:"a"(75), "b"(2), "c"(socket), "d"(addres), "S"(addres_len)
);
return status;
}
static inline int listen(int socket, int backlog)
{
int status;
asm volatile(
"int $0x40"
:"=b"(err_code), "=a"(status)
:"a"(75), "b"(3), "c"(socket), "d"(backlog)
);
return status;
}
static inline int connect(int socket, const struct sockaddr* address, int socket_len)
{
int status;
asm volatile(
"int $0x40"
:"=b"(err_code), "=a"(status)
:"a"(75), "b"(4), "c"(socket), "d"(address), "S"(socket_len)
);
return status;
}
static inline int accept(int socket, const struct sockaddr *address, int address_len)
{
int new_socket;
asm volatile(
"int $0x40"
:"=b"(err_code), "=a"(new_socket)
:"a"(75), "b"(5), "c"(socket), "d"(address), "S"(address_len)
);
return new_socket;
}
static inline int send(int socket, const void *message, size_t msg_len, int flag)
{
int status;
asm volatile(
"int $0x40"
:"=b"(err_code), "=a"(status)
:"a"(75), "b"(6), "c"(socket), "d"(message), "S"(msg_len), "D"(flag)
);
return status;
}
static inline int recv(int socket, void *buffer, size_t buff_len, int flag)
{
int status;
asm volatile(
"int $0x40"
:"=b"(err_code), "=a"(status)
:"a"(75), "b"(7), "c"(socket), "d"(buffer), "S"(buff_len), "D"(flag)
);
return status;
}
static inline int setsockopt(int socket,const optstruct* opt)
{
int status;
asm volatile(
"int $0x40"
:"=b"(err_code), "=a"(status)
:"a"(75), "b"(8), "c"(socket),"d"(opt)
);
return status;
}
static inline int getsockopt(int socket, optstruct* opt)
{
int status;
asm volatile(
"int $0x40"
:"=b"(err_code), "=a"(status)
:"a"(75), "b"(9), "c"(socket),"d"(opt)
);
return status;
}
static inline int socketpair(int *socket1, int *socket2)
{
asm volatile(
"int $0x40"
:"=b"(*socket2), "=a"(*socket1)
:"a"(75), "b"(10)
);
err_code=*socket2;
return *socket1;
}
#endif

View File

@ -10,6 +10,7 @@ extern "C" {
#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/_timespec.h>
#include <sys/ksys.h>
/* dj's stat defines _STAT_H_ */
#ifndef _STAT_H_
@ -147,11 +148,12 @@ struct stat
int _EXFUN(chmod,( const char *__path, mode_t __mode ));
int _EXFUN(fchmod,(int __fd, mode_t __mode));
int _EXFUN(fstat,( int __fd, struct stat *__sbuf ));
int _EXFUN(mkdir,( const char *_path, mode_t __mode ));
int _EXFUN(mkfifo,( const char *__path, mode_t __mode ));
int _EXFUN(stat,( const char *__restrict __path, struct stat *__restrict __sbuf ));
mode_t _EXFUN(umask,( mode_t __mask ));
#define mkdir(path, mode) _ksys_mkdir(path)
#if defined (__SPU__) || defined(__rtems__) || defined(__CYGWIN__) && !defined(__INSIDE_CYGWIN__)
int _EXFUN(lstat,( const char *__restrict __path, struct stat *__restrict __buf ));
int _EXFUN(mknod,( const char *__path, mode_t __mode, dev_t __dev ));

View File

@ -1,522 +0,0 @@
EXPORTS
_Balloc
_Bfree
_Exit DATA
__assert
__assert_func
__ctype_ptr__ DATA
__emutls_get_address
__errno
__fpclassifyd
__fpclassifyf
__mutex_lock
__signbitd
__signbitf
__srget_r
__swbuf_r
_atoi_r
_atol_r
_buf_findstr
_calloc_r
_cleanup
_cleanup_r
_close_r
_ctype_ DATA
_daylight DATA
_diprintf_r
_dprintf_r
_dtoa_r
_exit DATA
_f_atan2 DATA
_f_atan2f DATA
_f_exp
_f_expf
_f_frexp DATA
_f_frexpf DATA
_f_ldexp DATA
_f_ldexpf DATA
_f_llrint
_f_llrintf
_f_llrintl
_f_log DATA
_f_log10 DATA
_f_log10f DATA
_f_logf DATA
_f_lrint
_f_lrintf
_f_lrintl
_f_pow
_f_powf
_f_rint
_f_rintf
_f_rintl
_f_tan DATA
_f_tanf DATA
_fclose_r
_fdopen_r
_fflush_r
_fgetc_r
_fgets_r
_findenv
_fiprintf_r
_fiscanf_r
_fopen_r
_fprintf_r
_fputc_r
_fputs_r
_fputwc_r
_fread_r
_free_r
_freopen_r
_fscanf_r
_fseek_r
_fseeko_r
_fstat_r
_ftell_r
_ftello_r
_fwalk
_fwalk_reent
_fwrite_r
_gettimeofday
_gettimeofday_r
_global_impure_ptr DATA
_grow_handles
_init_signal
_init_signal_r
_isatty
_isatty_r
_kill_r
_localeconv_r
_lseek_r
_malloc_r
_mbrtowc_r
_mbtowc_r
_mktm_r
_mprec_log10
_open_r
_printf_r
_putc_r
_putchar_r
_puts_r
_raise_r
_read
_read_r
_realloc_r
_remove_r
_rename_r
_seed48_r
_setlocale_r
_sfread_r
_signal_r
_siprintf_r
_sniprintf_r
_snprintf_r
_sprintf_r
_srand48_r
_sscanf_r
_strdup_r
_strerror_r
_strndup_r
_strtod_r
_strtol_r
_strtoll_r
_strtoul_r
_strtoull_r
_sungetc_r
_svfiprintf_r
_svfprintf_r
_system_r
_tempnam_r
_times_r
_timezone DATA
_tls_map DATA
_tmpfile_r
_tmpnam_r
_towctrans_r
_tzname DATA
_ungetc_r
_user_strerror
_vasniprintf_r
_vasnprintf_r
_vdiprintf_r
_vdprintf_r
_vfiprintf_r
_vfiscanf_r
_vfprintf_r
_vfscanf_r
_vscanf_r
_vsnprintf_r
_vsprintf_r
_vsscanf_r
_wcrtomb_r
_wctomb_r
_wctrans_r
_wctype_r
_write_r
abort
abs
acos
acosf
acosh
acoshf
asctime
asctime_r
asin
asinf
asinh
asinhf
atan
atan2
atan2f
atanf
atanh
atanhf
atexit
atof
atoi
atol
bsearch
calloc
cbrt
cbrtf
ceil
ceilf
clearerr
clock
close
copysign
copysignf
cos
cosf
cosh
coshf
create_file
create_image
create_thread
ctime
ctime_r
debugwrite
delete_file
difftime
diprintf
div
dprintf
drem
dremf
entry DATA
envz_get
erf
erfc
erfcf
erff
exit
exp
exp10
exp10f
exp2
exp2f
expf
expm1
expm1f
fabs
fabsf
fclose
fdim
fdimf
fdopen
fflush
fgetc
fgets
fileno
finite
finitef
fiprintf
fiscanf
floor
floorf
fma
fmaf
fmax
fmaxf
fmin
fminf
fmod
fmodf
fopen
fprintf
fputc
fputs
fputwc
fread
free
freopen
frexp
frexpf
fscanf
fseek
fseeko
fstat
ftell
ftello
fwrite
gamma
gamma_r
gammaf
gammaf_r
get_entry_point
get_fileinfo
get_proc_address
getenv
gettimeofday
gmtime
gmtime_r
hypot
hypotf
ilogb
ilogbf
infinity
infinityf
init_global_reent
init_loader
init_reent
isalnum
isalpha
isascii
isblank
iscntrl
isdigit
isgraph
isinf
isinff
islower
isnan
isnanf
isprint
ispunct
isspace
isupper
iswalnum
iswalpha
iswblank
iswcntrl
iswctype
iswdigit
iswgraph
iswlower
iswprint
iswpunct
iswspace
iswupper
iswxdigit
isxdigit
j0
j0f
j1
j1f
jn
jnf
ldexp
ldexpf
lgamma
lgamma_r
lgammaf
lgammaf_r
libc_crt_startup
link_app
link_image
llrint
llrintf
llrintl
llround
llroundf
load_library
loader_env DATA
localeconv
localtime
localtime_r
log
log10
log10f
log1p
log1pf
log2
log2f
logb
logbf
logf
longjmp
lrint
lrintf
lrintl
lround
lroundf
lseek
malloc
matherr
mbrtowc
mbtowc
memalign
memchr
memcmp
memcpy
memmove
memset
mktime
modf
modff
nan
nanf
nearbyint
nearbyintf
nextafter
nextafterf
open
path_list DATA
pow
pow10
pow10f
powf
printf
putc
putchar
puts
qsort
raise
rand
rand_r
read
read_file
realloc
remainder
remainderf
remove
remquo
remquof
rename
rint
rintf
rintl
round
roundf
scalb
scalbf
scalbln
scalblnf
scalbn
scalbnf
seed48
set_file_size
setjmp
setlocale
setvbuf
signal
significand
significandf
sin
sincos
sincosf
sinf
sinh
sinhf
siprintf
sniprintf
snprintf
sprintf
sqrt
sqrtf
srand
srand48
sscanf
stpcpy
stpncpy
strcasecmp
strcasestr
strcat
strchr
strcmp
strcoll
strcpy
strcspn
strdup
strerror
strftime
strlen
strncasecmp
strncat
strncmp
strncpy
strndup
strnlen
strpbrk
strrchr
strsep
strspn
strstr
strtod
strtof
strtok
strtok_r
strtol
strtoll
strtoul
strtoull
strupr
system
tan
tanf
tanh
tanhf
tempnam
tgamma
tgammaf
time
tls_alloc DATA
tmpfile
tmpnam
toascii
tolower
toupper
towctrans
towlower
towupper
trunc
truncf
ungetc
user_alloc
validate_pe
vasniprintf
vasnprintf
vdiprintf
vdprintf
vfiprintf
vfiscanf
vfprintf
vfscanf
vscanf
vsnprintf
vsprintf
vsscanf
wcrtomb
wctrans
wctype
write
write_file
y0
y0f
y1
y1f
yn
ynf
alphasort
opendir
closedir
readdir
rewinddir
seekdir
telldir
scandir
mkdir
rmdir
chdir
dirname
getcwd

View File

@ -1,509 +0,0 @@
EXPORTS
_Balloc @1
_Bfree @2
_Exit @3 DATA
__assert @4
__assert_func @5
__ctype_ptr__ @6 DATA
__emutls_get_address @7
__errno @8
__fpclassifyd @9
__fpclassifyf @10
__mutex_lock @11
__signbitd @12
__signbitf @13
__srget_r @14
__swbuf_r @15
_atoi_r @16
_atol_r @17
_buf_findstr @18
_calloc_r @19
_cleanup @20
_cleanup_r @21
_close_r @22
_ctype_ @23 DATA
_daylight @24 DATA
_diprintf_r @25
_dprintf_r @26
_dtoa_r @27
_exit @28 DATA
_f_atan2 @29 DATA
_f_atan2f @30 DATA
_f_exp @31
_f_expf @32
_f_frexp @33 DATA
_f_frexpf @34 DATA
_f_ldexp @35 DATA
_f_ldexpf @36 DATA
_f_llrint @37
_f_llrintf @38
_f_llrintl @39
_f_log @40 DATA
_f_log10 @41 DATA
_f_log10f @42 DATA
_f_logf @43 DATA
_f_lrint @44
_f_lrintf @45
_f_lrintl @46
_f_pow @47
_f_powf @48
_f_rint @49
_f_rintf @50
_f_rintl @51
_f_tan @52 DATA
_f_tanf @53 DATA
_fclose_r @54
_fdopen_r @55
_fflush_r @56
_fgetc_r @57
_fgets_r @58
_findenv @59
_fiprintf_r @60
_fiscanf_r @61
_fopen_r @62
_fprintf_r @63
_fputc_r @64
_fputs_r @65
_fputwc_r @66
_fread_r @67
_free_r @68
_freopen_r @69
_fscanf_r @70
_fseek_r @71
_fseeko_r @72
_fstat_r @73
_ftell_r @74
_ftello_r @75
_fwalk @76
_fwalk_reent @77
_fwrite_r @78
_gettimeofday @79
_gettimeofday_r @80
_global_impure_ptr @81 DATA
_grow_handles @82
_init_signal @83
_init_signal_r @84
_isatty @85
_isatty_r @86
_kill_r @87
_localeconv_r @88
_lseek_r @89
_malloc_r @90
_mbrtowc_r @91
_mbtowc_r @92
_mktm_r @93
_mprec_log10 @94
_open_r @95
_printf_r @96
_putc_r @97
_putchar_r @98
_puts_r @99
_raise_r @100
_read @101
_read_r @102
_realloc_r @103
_remove_r @104
_rename_r @105
_seed48_r @106
_setlocale_r @107
_sfread_r @108
_signal_r @109
_siprintf_r @110
_sniprintf_r @111
_snprintf_r @112
_sprintf_r @113
_srand48_r @114
_sscanf_r @115
_strdup_r @116
_strerror_r @117
_strndup_r @118
_strtod_r @119
_strtol_r @120
_strtoll_r @121
_strtoul_r @122
_strtoull_r @123
_sungetc_r @124
_svfiprintf_r @125
_svfprintf_r @126
_system_r @127
_tempnam_r @128
_times_r @129
_timezone @130 DATA
_tls_map @131 DATA
_tmpfile_r @132
_tmpnam_r @133
_towctrans_r @134
_tzname @135 DATA
_ungetc_r @136
_user_strerror @137
_vasniprintf_r @138
_vasnprintf_r @139
_vdiprintf_r @140
_vdprintf_r @141
_vfiprintf_r @142
_vfiscanf_r @143
_vfprintf_r @144
_vfscanf_r @145
_vscanf_r @146
_vsnprintf_r @147
_vsprintf_r @148
_vsscanf_r @149
_wcrtomb_r @150
_wctomb_r @151
_wctrans_r @152
_wctype_r @153
_write_r @154
abort @155
abs @156
acos @157
acosf @158
acosh @159
acoshf @160
asctime @161
asctime_r @162
asin @163
asinf @164
asinh @165
asinhf @166
atan @167
atan2 @168
atan2f @169
atanf @170
atanh @171
atanhf @172
atexit @173
atof @174
atoi @175
atol @176
bsearch @177
calloc @178
cbrt @179
cbrtf @180
ceil @181
ceilf @182
clearerr @183
clock @184
close @185
copysign @186
copysignf @187
cos @188
cosf @189
cosh @190
coshf @191
create_file @192
create_image @193
create_thread @194
ctime @195
ctime_r @196
debugwrite @197
delete_file @198
difftime @199
diprintf @200
div @201
dprintf @202
drem @203
dremf @204
entry @205 DATA
envz_get @206
erf @207
erfc @208
erfcf @209
erff @210
exit @211
exp @212
exp10 @213
exp10f @214
exp2 @215
exp2f @216
expf @217
expm1 @218
expm1f @219
fabs @220
fabsf @221
fclose @222
fdim @223
fdimf @224
fdopen @225
fflush @226
fgetc @227
fgets @228
fileno @229
finite @230
finitef @231
fiprintf @232
fiscanf @233
floor @234
floorf @235
fma @236
fmaf @237
fmax @238
fmaxf @239
fmin @240
fminf @241
fmod @242
fmodf @243
fopen @244
fprintf @245
fputc @246
fputs @247
fputwc @248
fread @249
free @250
freopen @251
frexp @252
frexpf @253
fscanf @254
fseek @255
fseeko @256
fstat @257
ftell @258
ftello @259
fwrite @260
gamma @261
gamma_r @262
gammaf @263
gammaf_r @264
get_entry_point @265
get_fileinfo @266
get_proc_address @267
getenv @268
gettimeofday @269
gmtime @270
gmtime_r @271
hypot @272
hypotf @273
ilogb @274
ilogbf @275
infinity @276
infinityf @277
init_global_reent @278
init_loader @279
init_reent @280
isalnum @281
isalpha @282
isascii @283
isblank @284
iscntrl @285
isdigit @286
isgraph @287
isinf @288
isinff @289
islower @290
isnan @291
isnanf @292
isprint @293
ispunct @294
isspace @295
isupper @296
iswalnum @297
iswalpha @298
iswblank @299
iswcntrl @300
iswctype @301
iswdigit @302
iswgraph @303
iswlower @304
iswprint @305
iswpunct @306
iswspace @307
iswupper @308
iswxdigit @309
isxdigit @310
j0 @311
j0f @312
j1 @313
j1f @314
jn @315
jnf @316
ldexp @317
ldexpf @318
lgamma @319
lgamma_r @320
lgammaf @321
lgammaf_r @322
libc_crt_startup @323
link_app @324
link_image @325
llrint @326
llrintf @327
llrintl @328
llround @329
llroundf @330
load_library @331
loader_env @332 DATA
localeconv @333
localtime @334
localtime_r @335
log @336
log10 @337
log10f @338
log1p @339
log1pf @340
log2 @341
log2f @342
logb @343
logbf @344
logf @345
longjmp @346
lrint @347
lrintf @348
lrintl @349
lround @350
lroundf @351
lseek @352
malloc @353
matherr @354
mbrtowc @355
mbtowc @356
memalign @357
memchr @358
memcmp @359
memcpy @360
memmove @361
memset @362
mktime @363
modf @364
modff @365
nan @366
nanf @367
nearbyint @368
nearbyintf @369
nextafter @370
nextafterf @371
open @372
path_list @373 DATA
pow @374
pow10 @375
pow10f @376
powf @377
printf @378
putc @379
putchar @380
puts @381
qsort @382
raise @383
rand @384
rand_r @385
read @386
read_file @387
realloc @388
remainder @389
remainderf @390
remove @391
remquo @392
remquof @393
rename @394
rint @395
rintf @396
rintl @397
round @398
roundf @399
scalb @400
scalbf @401
scalbln @402
scalblnf @403
scalbn @404
scalbnf @405
seed48 @406
set_file_size @407
setjmp @408
setlocale @409
setvbuf @410
signal @411
significand @412
significandf @413
sin @414
sincos @415
sincosf @416
sinf @417
sinh @418
sinhf @419
siprintf @420
sniprintf @421
snprintf @422
sprintf @423
sqrt @424
sqrtf @425
srand @426
srand48 @427
sscanf @428
stpcpy @429
stpncpy @430
strcasecmp @431
strcasestr @432
strcat @433
strchr @434
strcmp @435
strcoll @436
strcpy @437
strcspn @438
strdup @439
strerror @440
strftime @441
strlen @442
strncasecmp @443
strncat @444
strncmp @445
strncpy @446
strndup @447
strnlen @448
strpbrk @449
strrchr @450
strsep @451
strspn @452
strstr @453
strtod @454
strtof @455
strtok @456
strtok_r @457
strtol @458
strtoll @459
strtoul @460
strtoull @461
strupr @462
system @463
tan @464
tanf @465
tanh @466
tanhf @467
tempnam @468
tgamma @469
tgammaf @470
time @471
tls_alloc @472 DATA
tmpfile @473
tmpnam @474
toascii @475
tolower @476
toupper @477
towctrans @478
towlower @479
towupper @480
trunc @481
truncf @482
ungetc @483
user_alloc @484
validate_pe @485
vasniprintf @486
vasnprintf @487
vdiprintf @488
vdprintf @489
vfiprintf @490
vfiscanf @491
vfprintf @492
vfscanf @493
vscanf @494
vsnprintf @495
vsprintf @496
vsscanf @497
wcrtomb @498
wctrans @499
wctype @500
write @501
write_file @502
y0 @503
y0f @504
y1 @505
y1f @506
yn @507
ynf @508

View File

@ -355,7 +355,6 @@ import libc,\
_cosf,'cosf',\
_cosh,'cosh',\
_coshf,'coshf',\
_create_file,'create_file',\
_create_image,'create_image',\
_create_thread,'create_thread',\
_ctime,'ctime',\
@ -429,7 +428,6 @@ import libc,\
_gammaf,'gammaf',\
_gammaf_r,'gammaf_r',\
_get_entry_point,'get_entry_point',\
_get_fileinfo,'get_fileinfo',\
_get_proc_address,'get_proc_address',\
_getenv,'getenv',\
_gettimeofday,'gettimeofday',\
@ -550,7 +548,6 @@ import libc,\
_rand,'rand',\
_rand_r,'rand_r',\
_read,'read',\
_read_file,'read_file',\
_realloc,'realloc',\
_remainder,'remainder',\
_remainderf,'remainderf',\
@ -570,7 +567,6 @@ import libc,\
_scalbn,'scalbn',\
_scalbnf,'scalbnf',\
_seed48,'seed48',\
_set_file_size,'set_file_size',\
_setjmp,'setjmp',\
_setlocale,'setlocale',\
_setvbuf,'setvbuf',\
@ -665,7 +661,6 @@ import libc,\
_wctrans,'wctrans',\
_wctype,'wctype',\
_write,'write',\
_write_file,'write_file',\
_y0,'y0',\
_y0f,'y0f',\
_y1,'y1',\

View File

@ -0,0 +1,11 @@
/*
* Copyright (C) KolibriOS team 2004-2024. All rights reserved.
* Distributed under terms of the GNU General Public License
*/
#include <sys/ksys.h>
int chdir(char* dir){
_ksys_setcwd(dir);
return 0;
}

View File

@ -15,7 +15,7 @@
#include <errno.h>
#include <stdlib.h>
#include <sys/unistd.h>
#include <sys/kos_io.h>
#include <sys/ksys.h>
#include "glue.h"
#include "io.h"

View File

@ -1,3 +1,8 @@
/*
* Copyright (C) KolibriOS team 2004-2024. All rights reserved.
* Distributed under terms of the GNU General Public License
*/
#include <_ansi.h>
#include <stdio.h>
#include <sys/unistd.h>
@ -16,28 +21,8 @@ static int console_read(const char *path, void *buff,
size_t offset, size_t count, size_t *done)
{
char *p = buff;
/*int cnt = 0;
short c;
char ch;*/
con_gets(p, count+1);
*done = strlen(p);
// __asm__ volatile("int3");
/*
do
{
c = con_getch2();
printf("%d\n",(char)c);
ch = (char)c;
if(ch != 0)
{
p[cnt] = ch != 0x0D ? ch : 0x0A;
con_write_string(p+cnt, 1);
cnt++;
}
}while(ch != 0x0D);
*done = cnt;
*/
return 0;
}
@ -48,7 +33,7 @@ static int console_write(const char *path, const void *buff,
*writes = count;
return 0;
};
}
void __init_conio()
{

View File

@ -1,25 +0,0 @@
#include <sys/types.h>
#include <sys/kos_io.h>
int create_file(const char *path)
{
int retval;
__asm__ __volatile__ (
"pushl $0 \n\t"
"pushl $0 \n\t"
"movl %1, 1(%%esp) \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl $2 \n\t"
"movl %%esp, %%ebx \n\t"
"movl $70, %%eax \n\t"
"int $0x40 \n\t"
"addl $28, %%esp \n\t"
:"=a" (retval)
:"r" (path)
:"ebx");
return retval;
};

View File

@ -1,48 +0,0 @@
#include <sys/types.h>
#include <sys/kos_io.h>
int get_fileinfo(const char *path, fileinfo_t *info)
{
int retval;
__asm__ __volatile__ (
"pushl $0 \n\t"
"pushl $0 \n\t"
"movl %1, 1(%%esp) \n\t"
"pushl %%ebx \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl $5 \n\t"
"movl %%esp, %%ebx \n\t"
"movl $70, %%eax \n\t"
"int $0x40 \n\t"
"addl $28, %%esp \n\t"
:"=a" (retval)
:"r" (path), "b" (info));
return retval;
};
int set_fileinfo(const char *path, fileinfo_t *info)
{
int retval;
__asm__ __volatile__ (
"pushl $0 \n\t"
"pushl $0 \n\t"
"movl %1, 1(%%esp) \n\t"
"pushl %%ebx \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl $6 \n\t"
"movl %%esp, %%ebx \n\t"
"movl $70, %%eax \n\t"
"int $0x40 \n\t"
"addl $28, %%esp \n\t"
:"=a" (retval)
:"r" (path), "b" (info));
return retval;
};

View File

@ -1,26 +0,0 @@
#include <sys/types.h>
#include <sys/kos_io.h>
int set_file_size(const char *path, unsigned size)
{
int retval;
__asm__ __volatile__(
"pushl $0 \n\t"
"pushl $0 \n\t"
"movl %%eax, 1(%%esp) \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl $0 \n\t"
"pushl %%ebx \n\t"
"push $4 \n\t"
"movl %%esp, %%ebx \n\t"
"movl $70, %%eax \n\t"
"int $0x40 \n\t"
"addl $28, %%esp \n\t"
:"=a" (retval)
:"a" (path), "b" (size));
return retval;
};

View File

@ -15,7 +15,7 @@
#include <errno.h>
#include <string.h>
#include <sys/unistd.h>
#include <sys/kos_io.h>
#include <sys/ksys.h>
#include <sys/stat.h>
#include "glue.h"
#include "io.h"
@ -25,7 +25,7 @@ _DEFUN (fstat, (fd, buf),
int fd _AND
struct stat *buf)
{
fileinfo_t info;
ksys_file_info_t info;
struct tm time;
__io_handle *ioh;
@ -33,8 +33,8 @@ _DEFUN (fstat, (fd, buf),
if( (fd < 0) || (fd >=64) )
{
errno = EBADF;
return (-1);
};
return -1;
}
memset (buf, 0, sizeof (* buf));
@ -47,7 +47,7 @@ _DEFUN (fstat, (fd, buf),
{
ioh = &__io_tab[fd];
get_fileinfo(ioh->name, &info);
_ksys_file_info(ioh->name, &info);
if (info.attr & 0x10)
buf->st_mode = S_IFDIR;

View File

@ -0,0 +1,17 @@
/*
* Copyright (C) KolibriOS team 2004-2024. All rights reserved.
* Distributed under terms of the GNU General Public License
*/
#include <stdlib.h>
#include <sys/ksys.h>
char *getcwd(char *buf, unsigned size){
if(!buf){
if((buf = malloc(size))==NULL){
return NULL;
}
}
_ksys_getcwd(buf, size);
return(buf);
}

View File

@ -1,31 +1,15 @@
/*
* Copyright (C) KolibriOS team 2004-2024. All rights reserved.
* Distributed under terms of the GNU General Public License
*/
#include <sys/types.h>
#include <sys/kos_io.h>
#include <sys/ksys.h>
int read_file(const char *path, void *buff,
size_t offset, size_t count, size_t *reads)
{
int retval;
int d0;
__asm__ __volatile__(
"pushl $0 \n\t"
"pushl $0 \n\t"
"movl %%eax, 1(%%esp) \n\t"
"pushl %%ebx \n\t"
"pushl %%edx \n\t"
"pushl $0 \n\t"
"pushl %%ecx \n\t"
"pushl $0 \n\t"
"movl %%esp, %%ebx \n\t"
"mov $70, %%eax \n\t"
"int $0x40 \n\t"
"testl %%esi, %%esi \n\t"
"jz 1f \n\t"
"movl %%ebx, (%%esi) \n\t"
"1:"
"addl $28, %%esp \n\t"
:"=a" (retval)
:"a"(path),"b"(buff),"c"(offset),"d"(count),"S"(reads));
return retval == 6 ? 0 : retval;
};
ksys_file_status_t st = _ksys_file_read(path, offset, count, buff);
*reads = st.rw_bytes;
return st.status == KSYS_FS_ERR_EOF ? 0 : st.status;
}

View File

@ -1,33 +1,20 @@
/*
* Copyright (C) KolibriOS team 2004-2024. All rights reserved.
* Distributed under terms of the GNU General Public License
*/
#include <sys/types.h>
#include <errno.h>
#include <sys/kos_io.h>
#include <sys/ksys.h>
int write_file(const char *path,const void *buff,
int write_file(const char *path, const void *buff,
size_t offset, size_t count, size_t *writes)
{
int retval;
__asm__ __volatile__(
"pushl $0 \n\t"
"pushl $0 \n\t"
"movl %%eax, 1(%%esp) \n\t"
"pushl %%ebx \n\t"
"pushl %%edx \n\t"
"pushl $0 \n\t"
"pushl %%ecx \n\t"
"pushl $3 \n\t"
"movl %%esp, %%ebx \n\t"
"mov $70, %%eax \n\t"
"int $0x40 \n\t"
"testl %%esi, %%esi \n\t"
"jz 1f \n\t"
"movl %%ebx, (%%esi) \n\t"
"1:"
"addl $28, %%esp \n\t"
:"=a" (retval)
:"a"(path),"b"(buff),"c"(offset),"d"(count),"S"(writes));
if(retval == 0)
ksys_file_status_t st = _ksys_file_write(path, offset, count, buff);
*writes = st.rw_bytes;
if(!st.status)
return 0;
else if (retval == 8)
else if (st.status == KSYS_FS_ERR_8)
return ENOSPC;
return -1;
};
}

View File

@ -1,28 +1,30 @@
/*
* Copyright (C) KolibriOS team 2004-2024. All rights reserved.
* Distributed under terms of the GNU General Public License
*/
#include <errno.h>
#include <stdlib.h>
#include <sys/unistd.h>
#include <sys/kos_io.h>
#include <sys/ksys.h>
#include "glue.h"
#include "io.h"
_off_t
_DEFUN (lseek, (fd, pos, whence),
int fd _AND
_off_t pos _AND
int whence)
{
fileinfo_t info;
ksys_file_info_t info;
__io_handle *ioh;
_off_t ret;
if( (fd < 0) || (fd >=64) )
if ((fd < 0) || (fd >=64))
{
errno = EBADF;
return (-1);
};
}
ioh = &__io_tab[fd];
@ -36,16 +38,16 @@ _DEFUN (lseek, (fd, pos, whence),
break;
case SEEK_END:
{
get_fileinfo(ioh->name, &info);
_ksys_file_info(ioh->name, &info);
ret = pos + info.size;
break;
}
default:
errno = EINVAL;
return (-1);
};
return -1;
}
ioh->offset = ret;
return( ret );
};
return ret;
}

View File

@ -15,13 +15,20 @@
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/kos_io.h>
#include <sys/ksys.h>
#include "glue.h"
#include "io.h"
#undef erro
#undef errno
extern int errno;
extern int write_file(const char *path,const void *buff,
size_t offset, size_t count, size_t *writes);
extern int read_file(const char *path, void *buff,
size_t offset, size_t count, size_t *reads);
static inline int is_slash(char c)
{
return c=='/' || c=='\\';
@ -49,7 +56,7 @@ void fix_slashes(char * in,char * out)
}
}
*out='\0';
};
}
void buildpath(char *buf, const char* file)
@ -89,26 +96,14 @@ __do_until_slash:
*ptr++ = *file++;
}
*ptr = 0;
};
static char *getccwd(char *buf, size_t size)
{
int bsize;
__asm__ __volatile__(
"int $0x40"
:"=a"(bsize)
:"a"(30),"b"(2),"c"(buf), "d"(size)
:"memory");
return buf;
};
}
int open (const char * filename, int flags, ...)
{
char buf[1024];
__io_handle *ioh;
fileinfo_t info;
ksys_file_info_t info;
int iomode, rwmode, offset;
int hid;
int err;
@ -127,28 +122,28 @@ int open (const char * filename, int flags, ...)
}
else
{
getccwd(buf, 1024);
_ksys_getcwd(buf, 1024);
buildpath(buf, filename);
}
err = get_fileinfo(buf, &info);
err = _ksys_file_info(buf, &info);
if( flags & O_EXCL &&
if (flags & O_EXCL &&
flags & O_CREAT )
{
if( !err )
if (!err)
{
errno = EEXIST;
__io_free(hid);
return (-1);
};
}
}
if( err )
if (err)
{
if(flags & O_CREAT)
err=create_file(buf);
if( err )
err = _ksys_file_create(buf).status;
if(err)
{
errno = EACCES;
__io_free(hid);
@ -156,8 +151,8 @@ int open (const char * filename, int flags, ...)
};
};
if( flags & O_TRUNC )
set_file_size(buf, 0);
if (flags & O_TRUNC)
_ksys_file_set_size(buf, 0);
ioh = &__io_tab[hid];
@ -166,25 +161,28 @@ int open (const char * filename, int flags, ...)
iomode = 0;
offset = 0;
if( rwmode == O_RDWR )
if (rwmode == O_RDWR)
iomode |= _READ | _WRITE;
else if( rwmode == O_RDONLY)
else if (rwmode == O_RDONLY)
iomode |= _READ;
else if( rwmode == O_WRONLY)
else if (rwmode == O_WRONLY)
iomode |= _WRITE;
if( flags & O_APPEND )
if (flags & O_APPEND)
{
iomode |= _APPEND;
offset = info.size;
};
}
if( flags & (O_BINARY|O_TEXT) )
if (flags & (O_BINARY|O_TEXT))
{
if( flags & O_BINARY )
if (flags & O_BINARY)
iomode |= _BINARY;
} else
}
else
{
iomode |= _BINARY;
}
ioh->name = strdup(buf);
ioh->offset = offset;
@ -193,6 +191,4 @@ int open (const char * filename, int flags, ...)
ioh->write = write_file;
return hid;
};
}

View File

@ -29,7 +29,7 @@ ssize_t read(int fd, void *buf, size_t cnt)
char *buffer = buf;
int rc;
int h;
unsigned amount_read;
size_t amount_read;
int err;
__io_handle *ioh;

View File

@ -13,7 +13,7 @@
* they apply.
*/
#include <sys/stat.h>
#include <sys/kos_io.h>
#include <sys/ksys.h>
#include <errno.h>
#include <time.h>
#include <string.h>
@ -28,16 +28,16 @@ _DEFUN (stat, (path, buf),
struct stat *buf)
{
fileinfo_t info;
ksys_file_info_t info;
struct tm time;
if( get_fileinfo(path, &info))
if (_ksys_file_info(path, &info))
{
errno = ENOENT;
return (-1);
};
}
memset (buf, 0, sizeof (* buf));
memset(buf, 0, sizeof (*buf));
buf->st_size = info.size;
@ -91,4 +91,3 @@ _DEFUN (lstat, (path, buf),
{
return stat(path, buf);
}

View File

@ -15,7 +15,6 @@
#include <errno.h>
#include <unistd.h>
#include <alloca.h>
#include <sys/kos_io.h>
#include "io.h"
#undef erro

View File

@ -7,7 +7,7 @@ STRIP = kos32-strip
INSTALLDIR ?= /home/autobuild/tools/win32/lib
CFLAGS = -U__MINGW32__ -UWIN32 -UWindows -U_WINDOWS -U_WIN32 -U__WIN32__ -U_WIN32 -DPACKAGE_NAME=\"sqlite\" -DPACKAGE_TARNAME=\"sqlite\" -DPACKAGE_VERSION=\"3.36.0\" -DPACKAGE_STRING=\"sqlite\ 3.36.0\" -DPACKAGE_BUGREPORT=\"http://www.sqlite.org\" -DPACKAGE_URL=\"\" -DPACKAGE=\"sqlite\" -DVERSION=\"3.36.0\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=0 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -DHAVE_FDATASYNC=0 -DHAVE_USLEEP=0 -DHAVE_LOCALTIME_R=1 -DHAVE_GMTIME_R=1 -DHAVE_DECL_STRERROR_R=1 -DHAVE_STRERROR_R=1 -DHAVE_EDITLINE_READLINE_H=1 -DHAVE_EDITLINE=1 -DHAVE_ZLIB_H=1 -I. -D_REENTRANT=1 -DSQLITE_THREADSAFE=0 -DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_GEOPOLY -DSQLITE_HAVE_ZLIB=1 -DSQLITE_OS_OTHER=1 -USQLITE_OS_WIN_H -DSQLITE_TEMP_STORE=3 -D_NO_STDERR -c -O2 -fomit-frame-pointer -D_KOLIBRI
CFLAGS = -U__MINGW32__ -UWIN32 -UWindows -U_WINDOWS -U_WIN32 -U__WIN32__ -U_WIN32 -DPACKAGE_NAME=\"sqlite\" -DPACKAGE_TARNAME=\"sqlite\" -DPACKAGE_VERSION=\"3.36.0\" -DPACKAGE_STRING=\"sqlite\ 3.36.0\" -DPACKAGE_BUGREPORT=\"http://www.sqlite.org\" -DPACKAGE_URL=\"\" -DPACKAGE=\"sqlite\" -DVERSION=\"3.36.0\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=0 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -DHAVE_FDATASYNC=0 -DHAVE_USLEEP=0 -DHAVE_LOCALTIME_R=1 -DHAVE_GMTIME_R=1 -DHAVE_DECL_STRERROR_R=1 -DHAVE_STRERROR_R=1 -DHAVE_EDITLINE_READLINE_H=1 -DHAVE_EDITLINE=1 -DHAVE_ZLIB_H=1 -I. -D_REENTRANT=1 -DSQLITE_THREADSAFE=0 -DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_GEOPOLY -DSQLITE_HAVE_ZLIB=1 -DSQLITE_OS_OTHER=1 -USQLITE_OS_WIN_H -DSQLITE_TEMP_STORE=3 -D_NO_STDERR -DSQLITE_OMIT_VIRTUALTABLE -c -O2 -fomit-frame-pointer -D_KOLIBRI
LDFLAGS=$(LDFLAGS_CMD)
LDFLAGS+= -shared -s -T dll.lds --entry _DllStartup --image-base=0

View File

@ -8,7 +8,7 @@ tup.include(HELPERDIR .. "/use_newlib.lua")
INCLUDES= INCLUDES .. " -I .. "
CFLAGS = CFLAGS .. " -U__WIN32__ -U_Win32 -U_WIN32 -U__MINGW32__ -UWIN32 -DSQLITE_OS_OTHER=1 -DHAVE_UNISTD_H=0 -D_NO_STDERR -DSQLITE_OMIT_POPEN -DSQLITE_THREADSAFE=0 -D_KOLIBRI -U__linux__ -DPACKAGE_NAME=\"sqlite\" -DPACKAGE_TARNAME=\"sqlite\" -DPACKAGE_VERSION=\"3.36.0\" -DPACKAGE_STRING=\"sqlite-3.36.0\" -DPACKAGE=\"sqlite\" -DVERSION=\"3.36.0\""
CFLAGS = CFLAGS .. " -U__WIN32__ -U_Win32 -U_WIN32 -U__MINGW32__ -UWIN32 -DSQLITE_OS_OTHER=1 -DHAVE_UNISTD_H=0 -D_NO_STDERR -DSQLITE_OMIT_POPEN -DSQLITE_THREADSAFE=0 -D_KOLIBRI -DSQLITE_OMIT_VIRTUALTABLE -U__linux__ -DPACKAGE_NAME=\"sqlite\" -DPACKAGE_TARNAME=\"sqlite\" -DPACKAGE_VERSION=\"3.36.0\" -DPACKAGE_STRING=\"sqlite-3.36.0\" -DPACKAGE=\"sqlite\" -DVERSION=\"3.36.0\""
LDFLAGS = LDFLAGS .. " --subsystem console "

View File

@ -102,7 +102,7 @@ typedef unsigned char u8;
# include <pwd.h>
# endif
#endif
#if (!defined(_WIN32) && !defined(WIN32)) || defined(__MINGW32__)
#if (!defined(_WIN32) && !defined(WIN32) && !defined (_KOLIBRI)) || defined(__MINGW32__)
# include <unistd.h>
# include <dirent.h>
# define GETPID getpid
@ -2209,7 +2209,9 @@ SQLITE_EXTENSION_INIT1
#include <fcntl.h>
#if !defined(_WIN32) && !defined(WIN32)
# include <unistd.h>
#ifndef _KOLIBRI
# include <dirent.h>
#endif
# include <utime.h>
# include <sys/time.h>
#else

View File

@ -1,188 +0,0 @@
#ifndef __cplusplus
//"inline" ôóíêöèè äëÿ âûçîâà ñèñòåìíûõ ôóíêöèé Kolibri â C - â èìåíè ôóíêöèè êîë-âî ïàðàìåòðîâ
//SysCall# (íîìåð_ñèñòåìíîé_ôóíêöèè, ïàðàìåòðû,...)
static inline int SysCall1 (int EAX__) __attribute__((always_inline));
static inline int SysCall2 (int EAX__, int EBX__) __attribute__((always_inline));
static inline int SysCall3 (int EAX__, int EBX__, int ECX__) __attribute__((always_inline));
static inline int SysCall4 (int EAX__, int EBX__, int ECX__, int EDX__) __attribute__((always_inline));
static inline int SysCall5 (int EAX__, int EBX__, int ECX__, int EDX__, int ESI__) __attribute__((always_inline));
static inline int SysCall6 (int EAX__, int EBX__, int ECX__, int EDX__, int ESI__, int EDI__) __attribute__((always_inline));
static inline int SysCall1 (int EAX__)
{
asm volatile(""::"a"(EAX__));
asm volatile("int $0x40");
register int res;
asm volatile("":"=a"(res):);
return res;
}
static inline int SysCall2 (int EAX__, int EBX__)
{
asm volatile(""::"a"(EAX__));
asm volatile(""::"b"(EBX__));
asm volatile("int $0x40");
register int res;
asm volatile("":"=a"(res):);
return res;
}
static inline int SysCall3 (int EAX__, int EBX__, int ECX__)
{
asm volatile(""::"a"(EAX__));
asm volatile(""::"b"(EBX__));
asm volatile(""::"c"(ECX__));
asm volatile("int $0x40");
register int res;
asm volatile("":"=a"(res):);
return res;
}
static inline int SysCall4 (int EAX__, int EBX__, int ECX__, int EDX__)
{
asm volatile(""::"a"(EAX__));
asm volatile(""::"b"(EBX__));
asm volatile(""::"c"(ECX__));
asm volatile(""::"d"(EDX__));
asm volatile("int $0x40");
register int res;
asm volatile("":"=a"(res):);
return res;
}
static inline int SysCall5 (int EAX__, int EBX__, int ECX__, int EDX__, int ESI__)
{
asm volatile(""::"a"(EAX__));
asm volatile(""::"b"(EBX__));
asm volatile(""::"c"(ECX__));
asm volatile(""::"d"(EDX__));
asm volatile(""::"S"(ESI__));
asm volatile("int $0x40");
register int res;
asm volatile("":"=a"(res):);
return res;
}
static inline int SysCall6 (int EAX__, int EBX__, int ECX__, int EDX__, int ESI__, int EDI__)
{
asm volatile(""::"a"(EAX__));
asm volatile(""::"b"(EBX__));
asm volatile(""::"c"(ECX__));
asm volatile(""::"d"(EDX__));
asm volatile(""::"S"(ESI__));
asm volatile(""::"D"(EDI__));
asm volatile("int $0x40");
register int res;
asm volatile("":"=a"(res):);
return res;
}
#else
//"inline" ôóíêöèè äëÿ âûçîâà ñèñòåìíûõ ôóíêöèé Kolibri â C++
//SysCall(íîìåð_ñèñòåìíîé_ôóíêöèè, ïàðàìåòðû,...)
static inline int SysCall (int EAX__) __attribute__((always_inline));
static inline int SysCall (int EAX__, int EBX__) __attribute__((always_inline));
static inline int SysCall (int EAX__, int EBX__, int ECX__) __attribute__((always_inline));
static inline int SysCall (int EAX__, int EBX__, int ECX__, int EDX__) __attribute__((always_inline));
static inline int SysCall (int EAX__, int EBX__, int ECX__, int EDX__, int ESI__) __attribute__((always_inline));
static inline int SysCall (int EAX__, int EBX__, int ECX__, int EDX__, int ESI__, int EDI__) __attribute__((always_inline));
static inline int SysCall (int EAX__)
{
asm volatile(""::"a"(EAX__));
asm volatile("int $0x40");
register int res;
asm volatile("":"=a"(res):);
return res;
}
static inline int SysCall (int EAX__, int EBX__)
{
asm volatile(""::"a"(EAX__));
asm volatile(""::"b"(EBX__));
asm volatile("int $0x40");
register int res;
asm volatile("":"=a"(res):);
return res;
}
static inline int SysCall (int EAX__, int EBX__, int ECX__)
{
asm volatile(""::"a"(EAX__));
asm volatile(""::"b"(EBX__));
asm volatile(""::"c"(ECX__));
asm volatile("int $0x40");
register int res;
asm volatile("":"=a"(res):);
return res;
}
static inline int SysCall (int EAX__, int EBX__, int ECX__, int EDX__)
{
asm volatile(""::"a"(EAX__));
asm volatile(""::"b"(EBX__));
asm volatile(""::"c"(ECX__));
asm volatile(""::"d"(EDX__));
asm volatile("int $0x40");
register int res;
asm volatile("":"=a"(res):);
return res;
}
static inline int SysCall (int EAX__, int EBX__, int ECX__, int EDX__, int ESI__)
{
asm volatile(""::"a"(EAX__));
asm volatile(""::"b"(EBX__));
asm volatile(""::"c"(ECX__));
asm volatile(""::"d"(EDX__));
asm volatile(""::"S"(ESI__));
asm volatile("int $0x40");
register int res;
asm volatile("":"=a"(res):);
return res;
}
static inline int SysCall (int EAX__, int EBX__, int ECX__, int EDX__, int ESI__, int EDI__)
{
asm volatile(""::"a"(EAX__));
asm volatile(""::"b"(EBX__));
asm volatile(""::"c"(ECX__));
asm volatile(""::"d"(EDX__));
asm volatile(""::"S"(ESI__));
asm volatile(""::"D"(EDI__));
asm volatile("int $0x40");
register int res;
asm volatile("":"=a"(res):);
return res;
}
#endif

View File

@ -1,11 +0,0 @@
if tup.getconfig("NO_GCC") ~= "" then return end
HELPERDIR = (tup.getconfig("HELPERDIR") == "") and "../../.." or tup.getconfig("HELPERDIR")
tup.include(HELPERDIR .. "/use_gcc.lua")
tup.include(HELPERDIR .. "/use_newlib.lua")
tup.include(HELPERDIR .. "/use_tinygl.lua")
LIBS = "-lstdc++ -lsupc++ " .. LIBS
LDFLAGS = LDFLAGS .. " --subsystem native"
compile_gcc{"fps.cpp", "main.cpp"}
link_gcc("gears")

View File

@ -1,46 +0,0 @@
#include "SysCall.h"
/*******************************************************************************
ФУНКЦИЯ ОПРЕДЕЛЕНИЯ FPS
x,y - координаты вывода FPS на окно
возвращает время в сотых долях секунды затрачиваемое на 1 цикл
*/
int time1=0;
int time2=0;
int fps1=0;
int timerend=0;
int Fps (long x, long y)//функция определения FPS
{
int tr;
time1 = SysCall(26,9);//определяем время прошедшее момента запуска системы
if (timerend==0)
{
time2=time1;
timerend=time1;
}
tr = time1 - timerend;
if ((time1 - time2) < 100)//если прошло менее 1 секунды
{ //увеличиваем счетчик fps
fps1++;
}
else
{
//выводим число fps
SysCall(13,(x<<16)+23,(y<<16)+7,0x00555555); //НАРИСОВАТЬ ПОЛОСУ
SysCall(47,4<<16,fps1,(x<<16)+y,0xfafafa);//ВЫВЕСТИ В ОКНО ПРИЛОЖЕНИЯ ЧИСЛО
fps1=0;
time2=time1;
}
timerend=time1;
return tr;
}
//******************************************************************************

View File

@ -1,351 +0,0 @@
/*
Ïðèìåð âçÿò èç íàáîðà ïðèìåðîâ áèáëèîòåêè Mesa
iadn
http://www.iadn.narod.ru
iadn@bk.ru
*/
/*
* 3-D gear wheels. This program is in the public domain.
*
* Brian Paul
*/
/*
* Newlib port by maxcodehack
*/
#include <kos32sys.h>
#include <kosgl.h> // TinyGL
#include <string.h>
#include <math.h>
#include "SysCall.h"
int Fps (long x, long y);
struct {
int x,y;
int dx,dy;
} win;
#define KEY_ESC 1
#define KEY_F 33
char *title = "Gears (F - full screen, ESC - exit)";
char *fps = "FPS:";
unsigned char FullScreen = 0;
unsigned char skin = 0x34;
oskey_t key;
proc_info* pri;
KOSGLContext cgl;
static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
static GLint gear1, gear2, gear3;
static GLfloat angle = 0.0;
static GLuint limit;
static GLuint count = 1;
/*
* Draw a gear wheel. You'll probably want to call this function when
* building a display list since we do a lot of trig here.
*
* Input: inner_radius - radius of hole at center
* outer_radius - radius at center of teeth
* width - width of gear
* teeth - number of teeth
* tooth_depth - depth of tooth
*/
static void gear( GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
GLint teeth, GLfloat tooth_depth )
{
GLint i;
GLfloat r0, r1, r2;
GLfloat angle, da;
GLfloat u, v, len;
r0 = inner_radius;
r1 = outer_radius - tooth_depth/2.0;
r2 = outer_radius + tooth_depth/2.0;
da = 2.0*M_PI / teeth / 4.0;
glShadeModel( GL_FLAT );
glNormal3f( 0.0, 0.0, 1.0 );
/* draw front face */
glBegin( GL_QUAD_STRIP );
for (i=0;i<=teeth;i++) {
angle = i * 2.0*M_PI / teeth;
glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 );
glVertex3f( r1*cos(angle), r1*sin(angle), width*0.5 );
glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 );
glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5 );
}
glEnd();
/* draw front sides of teeth */
glBegin( GL_QUADS );
da = 2.0*M_PI / teeth / 4.0;
for (i=0;i<teeth;i++) {
angle = i * 2.0*M_PI / teeth;
glVertex3f( r1*cos(angle), r1*sin(angle), width*0.5 );
glVertex3f( r2*cos(angle+da), r2*sin(angle+da), width*0.5 );
glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), width*0.5 );
glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5 );
}
glEnd();
glNormal3f( 0.0, 0.0, -1.0 );
/* draw back face */
glBegin( GL_QUAD_STRIP );
for (i=0;i<=teeth;i++) {
angle = i * 2.0*M_PI / teeth;
glVertex3f( r1*cos(angle), r1*sin(angle), -width*0.5 );
glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 );
glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 );
glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 );
}
glEnd();
/* draw back sides of teeth */
glBegin( GL_QUADS );
da = 2.0*M_PI / teeth / 4.0;
for (i=0;i<teeth;i++) {
angle = i * 2.0*M_PI / teeth;
glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 );
glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), -width*0.5 );
glVertex3f( r2*cos(angle+da), r2*sin(angle+da), -width*0.5 );
glVertex3f( r1*cos(angle), r1*sin(angle), -width*0.5 );
}
glEnd();
/* draw outward faces of teeth */
glBegin( GL_QUAD_STRIP );
for (i=0;i<teeth;i++) {
angle = i * 2.0*M_PI / teeth;
glVertex3f( r1*cos(angle), r1*sin(angle), width*0.5 );
glVertex3f( r1*cos(angle), r1*sin(angle), -width*0.5 );
u = r2*cos(angle+da) - r1*cos(angle);
v = r2*sin(angle+da) - r1*sin(angle);
len = sqrt( u*u + v*v );
u /= len;
v /= len;
glNormal3f( v, -u, 0.0 );
glVertex3f( r2*cos(angle+da), r2*sin(angle+da), width*0.5 );
glVertex3f( r2*cos(angle+da), r2*sin(angle+da), -width*0.5 );
glNormal3f( cos(angle), sin(angle), 0.0 );
glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), width*0.5 );
glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), -width*0.5 );
u = r1*cos(angle+3*da) - r2*cos(angle+2*da);
v = r1*sin(angle+3*da) - r2*sin(angle+2*da);
glNormal3f( v, -u, 0.0 );
glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5 );
glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 );
glNormal3f( cos(angle), sin(angle), 0.0 );
}
glVertex3f( r1*cos(0.0), r1*sin(0.0), width*0.5 );
glVertex3f( r1*cos(0.0), r1*sin(0.0), -width*0.5 );
glEnd();
glShadeModel( GL_SMOOTH );
/* draw inside radius cylinder */
glBegin( GL_QUAD_STRIP );
for (i=0;i<=teeth;i++) {
angle = i * 2.0*M_PI / teeth;
glNormal3f( -cos(angle), -sin(angle), 0.0 );
glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 );
glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 );
}
glEnd();
}
void init()
{
static GLfloat pos[4] = {5.0, 5.0, 10.0, 1.0 };
static GLfloat red[4] = {0.8, 0.1, 0.0, 1.0 };
static GLfloat green[4] = {0.0, 0.8, 0.2, 1.0 };
static GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0 };
glLightfv( GL_LIGHT0, GL_POSITION, pos );
glEnable( GL_CULL_FACE );
glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
glEnable( GL_DEPTH_TEST );
/* make the gears */
gear1 = glGenLists(1);
glNewList(gear1, GL_COMPILE);
glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red );
gear( 1.0, 4.0, 1.0, 20, 0.7 );
glEndList();
gear2 = glGenLists(1);
glNewList(gear2, GL_COMPILE);
glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green );
gear( 0.5, 2.0, 2.0, 10, 0.7 );
glEndList();
gear3 = glGenLists(1);
glNewList(gear3, GL_COMPILE);
glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue );
gear( 1.3, 2.0, 0.5, 10, 0.7 );
glEndList();
glEnable( GL_NORMALIZE );
glViewport(0, 0, (GLint)500, (GLint)480);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum( -1.0, 1.0, -1, 1, 5.0, 60.0 );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef( 0.0, 0.0, -40.0 );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
}
void reshape()
{
get_proc_info((char*)pri);
glViewport(0, 0, pri->width, pri->height-20);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (GLfloat)pri->width/pri->height, 1.0, 60.0);
glTranslatef( 0.0, 0.0, 20.0 );
glMatrixMode(GL_MODELVIEW);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
}
void disabletgl()
{
kosglDestroyContext(cgl);
delete pri;
}
void kos_text(int x, int y, int color, const char* text, int len)
{
asm volatile ("int $0x40"::"a"(4),"b"((x<<16) | y),"c"(color),"d"((unsigned long)text),"S"(len));
};
void Title()
{
kos_text(300,8,0x10ffffff,fps,strlen(fps));
/*kos_text(180,8,0x90ffffff,title2,strlen(title2));
kos_text(600,8,0x90ffffff,title3,strlen(title3));*/
}
void draw_window()
{
// start redraw
begin_draw();
// define&draw window
sys_create_window(win.x, win.y, win.dx, win.dy, title, 0, /*TYPEWIN(0,0,0,1,skin,0,0,0)*/skin);
// end redraw
end_draw();
// display string
Title();
}
int main()
{
win.x = 100;
win.y = 100;
win.dx = 400;
win.dy = 400;
draw_window();
cgl = kosglCreateContext( 0, 0);
kosglMakeCurrent( 0, 0, win.dx, win.dy, cgl);
init();
pri = new proc_info;
SysCall(66,1,1);
reshape();
do {
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glPushMatrix();
glRotatef( view_rotx, 1.0, 0.0, 0.0 );
glRotatef( view_roty, 0.0, 1.0, 0.0 );
glRotatef( view_rotz, 0.0, 0.0, 1.0 );
glPushMatrix();
glTranslatef( -2.0, -2.0, 0.0 );
glRotatef( angle, 0.0, 0.0, 1.0 );
glCallList(gear1);
glPopMatrix();
glPushMatrix();
glTranslatef( 4.1, -2.0, 0.0 );
glRotatef( -2.0*angle-9.0, 0.0, 0.0, 1.0 );
glCallList(gear2);
glPopMatrix();
glPushMatrix();
glTranslatef( -2.1, 4.2, 0.0 );
glRotatef( -2.0*angle-25.0, 0.0, 0.0, 1.0 );
glCallList(gear3);
glPopMatrix();
glPopMatrix();
kosglSwapBuffers();
angle += 0.01 + 0.3 * Fps (330, 8);
switch(check_os_event())
{
case 1:
draw_window();
reshape();
break;
case 2:
key = get_key();
switch(key.code) {
case KEY_F:
if(!FullScreen){
skin=0x01;
SysCall(67,0,0,SysCall(14)>>16,SysCall(14)&0xffff);
draw_window();
reshape();
FullScreen = 1;
}
else{
skin=0x34;
draw_window();
SysCall(67,win.x,win.y,win.dx,win.dy);
reshape();
FullScreen = 0;
};
break;
case KEY_ESC:
disabletgl();
return 0;
}
break;
case 3:
disabletgl();
return 0;
}
} while(1);
}

View File

@ -1,396 +0,0 @@
/*
* Programme name: Backy
* Description: The programme for backing up a file.
*
* Backy.c
* Author: JohnXenox aka Aleksandr Igorevich.
* Port to GCC: maxcodehack
*
* Works from command line, only!
*/
#define CREATION_DATE "2020.05.27"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/kos_LoadConsole.h>
#include "Backy_lib.h"
int date = 0;
int time = 0;
char years = 0;
char months = 0;
char days = 0;
char hours = 0;
char minutes = 0;
char seconds = 0;
char *data = 0;
int length = 0;
char path_in[4096] = {0};
char path_out[4096] = {0};
char num[3] = {0};
char full_date[25] = {0};
char ext[] = ".bak";
char flag = 0;
char state;
int main(int argc, char** argv)
{
// ============================================================ //
// preprocessing arguments from the command line. ============= //
//
// 0 argument - name of the programme.
// 1 argument - path to the file with name that need to be backup.
// 2 argument - the key (-o).
// 3 argument - path to the output directory without the name of the file.
// printf("Number of args: %d\n", argc);
// printf("Argv 0: %s\n", argv[0]);
// sprintf("Argv 1: %s\n\n", argv[1]);
// ============================================================ //
// process the command line arguments. ======================== //
if (argc > 1)
{
for (int i = 1; i < argc; i++)
{
// if found the key "-o", then copy output path into the array "path_out".
if (*argv[i] == '-') // && (*(argv[i] + 1) == 'o'))
{
// printf("Key -o is found!\n");
i++;
flag = 1;
if (i <= argc)
{
// copying of a current path into the array "path_out".
strcpy(path_out, argv[i]);
// printf("Path output is copyed!\n");
i++;
break;
}
}
// if input path is found, then copy it into the array "path_in".
if (*argv[i] == '/')
{
flag = 2;
// copying of a current path into the buffer.
strcpy(path_in, argv[i]);
if (flag != 1)
{
int idx = strlen(path_in);
while (path_in[idx] != '/')
{
idx--;
}
strncpy(path_out, path_in, idx);
}
// printf("Path input is copyed!\n");
}
// if found characters.
if ( (*argv[i] > '0') && (*argv[i] < '9') || \
(*argv[i] > 'A') && (*argv[i] < 'Z') || \
(*argv[i] > 'a') && (*argv[i] < 'z') )
{
flag = 3;
strcpy(path_in, argv[0]);
// printf("Arg 0 is copyed!\n");
int idx = strlen(path_in);
while (path_in[idx] != '/')
{
path_in[idx] = 0;
idx--;
}
idx++;
strcpy(path_out, path_in);
strcpy(&path_in[idx], argv[1]);
// printf("Arg 1 is added!\n");
}
}
// if not found the flag, then copy path from "path_in" into "path_out".
if ((flag == 0) && (flag != 2) && (flag != 3))
{
// copying the input path into the output path,
strcpy(path_out, path_in);
//printf("Path input is copyed into the path output!\n");
}
}
else
{
load_console();
con_set_title("Useful info!");
#if defined (lang_en)
con_printf("\n Name: Backy");
con_printf("\n Date: %s", CREATION_DATE);
con_printf("\n Description: The programme for backing up a file.\n");
con_printf("\n Author: JohnXenox\n");
con_printf("\n Usage: backy <path1> <-o path2>\n");
con_printf(" path1 - path to a file to be backuped.\n");
con_printf(" -o path2 - path to the output directory without the name of a file.\n\n");
con_printf(" Examples:\n");
con_printf(" backy test.c\n");
con_printf(" backy test.c -o /tmp0/1/\n");
con_printf(" backy /hd0/1/test.c\n");
con_printf(" backy /hd0/1/test.c -o /tmp0/1/\n");
#elif defined (lang_ru)
con_printf("\n ˆ¬ï: Backy");
con_printf("\n „ â : %s", CREATION_DATE);
con_printf("\n Ž¯¨á ­¨¥: <20>ணࠬ¬  ¤«ï ᮧ¤ ­¨ï १¥à¢­®© ª®¯¨¨ ä ©« .\n");
con_printf("\n €¢â®à: JohnXenox\n");
con_printf("\n ˆá¯®«ì§®¢ ­¨¥: backy <path1> <-o path2>\n");
con_printf(" path1 - ¯ãâì ª ä ©«ã, ª®â®àë© ­ ¤® ᪮¯¨à®¢ âì.\n");
con_printf(" -o path2 - ¯ãâì ª ¤¨à¥ªâ®à¨¨, ¢ ª®â®àãî ¡ã¤¥â ᪮¯¨à®¢ ­  १¥à¢­ ï ª®¯¨ï ä ©« .\n\n");
con_printf(" <20>ਬ¥àë:\n");
con_printf(" backy test.c\n");
con_printf(" backy test.c -o /tmp0/1/\n");
con_printf(" backy /hd0/1/test.c\n");
con_printf(" backy /hd0/1/test.c -o /tmp0/1/\n");
#endif
return 0;
}
//printf("Path_in: %s\n", path_in);
//printf("Path_out: %s\n", path_out);
// ============================================================ //
// getting the time in BCD. =================================== //
time = getTime(); // time = 0x00SSMMHH.
hours = (char)time;
minutes = (char)(time >> 8);
seconds = (char)(time >> 16);
// ============================================================ //
// getting the date in BCD. =================================== //
date = getDate(); // date = 0x00DDMMYY.
years = (char)date;
months = (char)(date >> 8);
days = (char)(date >> 16);
// ============================================================ //
// fills the array with the date in ASCII. ==================== //
char ofs = 0;
char *dta = 0;
for (char i = 0; i < 3; i++)
{
if (i == 0)
{
dta = &years;
full_date[ofs] = '2';
ofs++;
full_date[ofs] = '0';
ofs++;
}
if (i == 1)
{
dta = &months;
}
if (i == 2)
{
dta = &days;
}
itoab(*dta, num, 16);
if (num[1] == 0)
{
full_date[ofs] = '0';
ofs++;
full_date[ofs] = num[0];
}
else
{
full_date[ofs] = num[0];
ofs++;
full_date[ofs] = num[1];
}
ofs++;
if (i != 2)
{
full_date[ofs] = '.';
ofs++;
}
}
full_date[ofs] = '_';
ofs++;
// ============================================================ //
// fills the array with the time in ASCII. ==================== //
ofs = 11;
dta = 0;
for (char i = 0; i < 3; i++)
{
if (i == 0)
dta = &hours;
if (i == 1)
dta = &minutes;
if (i == 2)
dta = &seconds;
itoab(*dta, num, 16);
if (num[1] == 0)
{
full_date[ofs] = '0';
ofs++;
full_date[ofs] = num[0];
}
else
{
full_date[ofs] = num[0];
ofs++;
full_date[ofs] = num[1];
}
ofs++;
if (i < 2)
{
full_date[ofs] = '.';
}
//else
//{
// full_date[ofs] = '_';
//}
ofs++;
}
// ============================================================ //
// adding the name of the input file to the output path. ====== //
int i = 0;
int y = 0;
// searching for a zero terminator in the input path.
while (path_in[i] != 0)
{
i++;
}
// searching for a slash in the input path.
while (path_in[i] != '/')
{
i--;
}
// searching for a zero terminator in the output path.
while (path_out[y] != 0)
{
y++;
}
// searching for a slash in the output path.
if (path_out[y - 1] == '/')
{
y--;
}
// copying the input name of the file into the output path,
strcpy(&path_out[y], &path_in[i]);
// ============================================================ //
// adding the extension and full date to the path. ============ //
i = 0;
// searching for a zero terminator in the output path.
while (path_out[i] != 0)
{
i++;
}
path_out[i] = '_';
i++;
// adding full date.
strcpy(&path_out[i], full_date);
i += strlen(full_date);
// adding the extension to a path.
strncpy(&path_out[i], ext, 4);
//printf("Path_in: %s\n", path_in);
//printf("Path_out: %s\n", path_out);
data = openFile(&length, path_in);
if(data == 0)
{
load_console();
con_set_title("Backy");
#if defined (lang_en)
con_printf("\nThe file isn't found!\n");
#elif defined (lang_ru)
con_printf("\n” ©« ­¥ ­ ©¤¥­!\n");
#endif
return 13;
}
saveFile(length, data, 0, path_out);//return checkStateOnSave(saveFile(length, data, 0, path_out));
}

View File

@ -1,189 +0,0 @@
/*
* Backy_lib.h
* Author: JohnXenox aka Aleksandr Igorevich.
*/
#ifndef __Backy_lib_h__
#define __Backy_lib_h__
// Copied from TCC
char* strrev(char *p)
{
char *q = p, *res = p, z;
while(q && *q) ++q; /* find eos */
for(--q; p < q; ++p, --q)
{
z = *p;
*p = *q;
*q = z;
}
return res;
}
char* itoab(unsigned int n, char* s, int b)
{
char *ptr;
int lowbit;
ptr = s;
b >>= 1;
do {
lowbit = n & 1;
n = (n >> 1) & 0x7FFFFFFF;
*ptr = ((n % b) << 1) + lowbit;
if(*ptr < 10) *ptr += '0'; else *ptr += 55;
++ptr;
} while(n /= b);
*ptr = 0;
return strrev(s);
}
/*
typedef unsigned int uint32_t;
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned long long uint64_t;
typedef char int8_t;
typedef short int int16_t;
typedef int int32_t;
typedef long long int64_t;
*/
static inline uint32_t getDate(void)
{
uint32_t date;
__asm__ __volatile__("int $0x40":"=a"(date):"a"(29));
return date;
}
static inline uint32_t getTime(void)
{
uint32_t time;
__asm__ __volatile__("int $0x40":"=a"(time):"a"(3));
return time;
}
static inline void *openFile(uint32_t *length, const uint8_t *path)
{
uint8_t *fd;
__asm__ __volatile__ ("int $0x40":"=a"(fd), "=d"(*length):"a" (68), "b"(27),"c"(path));
return fd;
}
struct saveFileStruct
{
int p1;
int p2;
int p3;
int p4;
char* p5;
int p6;
char* p7;
};
static inline int32_t saveFile(uint32_t nbytes, uint8_t *data, uint32_t enc, uint8_t *path)
{
int32_t val;
struct saveFileStruct dt; // basic information structure.
dt.p1 = 2; // subfunction number.
dt.p2= 0; // reserved.
dt.p3 = 0; // reserved.
dt.p4 = nbytes; // number of bytes to write.
dt.p5 = data; // pointer to data.
dt.p6 = enc; // string encoding (0 = default, 1 = cp866, 2 = UTF-16LE, 3 = UTF-8).
dt.p7 = path; // pointer to path.
__asm__ __volatile__("int $0x40":"=a"(val):"a"(80), "b"(&dt):"memory");
return val;
}
int checkStateOnSave(int state)
{
#if defined (lang_en)
switch(state)
{
case 2: con_printf("\nThe function isn't supported for the given file system!\n");
return 2;
case 3: con_printf("\nUnknown file system!\n");
return 3;
case 5: con_printf("\nFile isn't found!\n");
return 5;
case 6: con_printf("\nEnd of a file, EOF!\n");
return 6;
case 7: con_printf("\nPointer lies outside of application memory!\n");
return 7;
case 8: con_printf("\nDisk is full!\n");
return 8;
case 9: con_printf("\nFile system error!\n");
return 9;
case 10: con_printf("\nAccess denied!\n");
return 10;
case 11: con_printf("\nDevice error!\n");
return 11;
case 12: con_printf("\nFile system requires more memory!\n");
return 12;
}
#elif defined (lang_ru)
switch(state)
{
case 2: con_printf("\n”ã­ªæ¨ï ­¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï ¤ ­­®© ä ©«®¢®© á¨á⥬ë!\n");
return 2;
case 3: con_printf("\n<EFBFBD>¥¨§¢¥áâ­ ï ä ©«®¢ ï á¨á⥬ !\n");
return 3;
case 5: con_printf("\n” ©« ­¥ ­ ©¤¥­!\n");
return 5;
case 6: con_printf("\n” ©« § ª®­ç¨«áï!\n");
return 6;
case 7: con_printf("\n“ª § â¥«ì ¢­¥ ¯ ¬ï⨠¯à¨«®¦¥­¨ï!\n");
return 7;
case 8: con_printf("\n„¨áª § ¯®«­¥­!\n");
return 8;
case 9: con_printf("\nŽè¨¡ª  ä ©«®¢®© á¨á⥬ë!\n");
return 9;
case 10: con_printf("\n„®áâ㯠§ ¯à¥éñ­!\n");
return 10;
case 11: con_printf("\nŽè¨¡ª  ãáâனá⢠!\n");
return 11;
case 12: con_printf("\n” ©«®¢®© á¨á⥬¥ ­¥¤®áâ â®ç­® ®¯¥à â¨¢­®© ¯ ¬ïâ¨!\n");
return 12;
}
#endif
}
#endif

View File

@ -1,25 +0,0 @@
CC = kos32-gcc
LD = kos32-ld
SDK_DIR = $(abspath ../../../../contrib/sdk)
LDFLAGS = -call_shared -nostdlib -T $(SDK_DIR)/sources/newlib/app-dynamic.lds --image-base 0
CFLAGS = -c -fno-ident -O2 -fomit-frame-pointer -fno-ident -U__WIN32__ -U_Win32 -U_WIN32 -U__MINGW32__ -UWIN32
INCLUDES = -I $(SDK_DIR)/sources/newlib/libc/include
LIBPATH = -L $(SDK_DIR)/lib -L /home/autobuild/tools/win32/mingw32/lib
ifndef LANG_
LANG_ = lang_en
endif
default: backy
backy: $(OBJECTS) Makefile
$(CC) $(CFLAGS) $(INCLUDES) -D$(LANG_) -o Backy.o Backy.c
$(LD) $(LDFLAGS) $(LIBPATH) --subsystem console -o Backy Backy.o -lgcc -lc.dll
kos32-strip -s Backy -o Backy
objcopy Backy -O binary
rm Backy.o
clean:
rm Backy

View File

@ -1,14 +0,0 @@
if tup.getconfig("NO_GCC") ~= "" then return end
HELPERDIR = (tup.getconfig("HELPERDIR") == "") and "../../.." or tup.getconfig("HELPERDIR")
tup.include(HELPERDIR .. "/use_gcc.lua")
tup.include(HELPERDIR .. "/use_newlib.lua")
if tup.getconfig("LANG") == "ru"
then CFLAGS = CFLAGS .. " -Dlang_ru"
else CFLAGS = CFLAGS .. " -Dlang_en"
end
CFLAGS = CFLAGS .. " -std=c99"
compile_gcc{"Backy.c"}
link_gcc("Backy")

View File

@ -1,6 +0,0 @@
Port backy to gcc
Languages:
Eng:
make
Rus:
env LANG_=lang_ru make

View File

@ -1,23 +0,0 @@
CC = kos32-gcc
LD = kos32-ld
OBJCOPY = objcopy
STRIP = strip
NAME = kosjs
SDK_DIR = ../../../contrib/sdk
LDFLAGS = -call_shared -nostdlib -T $(SDK_DIR)/sources/newlib/app-dynamic.lds --image-base 0
LIBPATH = -L$(SDK_DIR)/lib -L/home/autobuild/tools/win32/mingw32/lib -L libmujs
CFLAGS = -c -fno-ident -O2 -fomit-frame-pointer -fno-ident -U__WIN32__ -U_Win32 -U_WIN32 -U__MINGW32__ -UWIN32
INCLUDES = -I $(SDK_DIR)/sources/newlib/libc/include -I libmujs
all:
$(CC) $(CFLAGS) $(INCLUDES) kosjs.c import.c
$(LD) $(LDFLAGS) $(LIBPATH) --subsystem native -o $(NAME) $(NAME).o import.o -lmujs -lgcc -lc.dll
$(STRIP) -s $(NAME) -o $(NAME)
$(OBJCOPY) $(NAME) -O binary
clean:
rm -f $(NAME) *.o

View File

@ -1,13 +0,0 @@
if tup.getconfig("NO_GCC") ~= "" then return end
HELPERDIR = (tup.getconfig("HELPERDIR") == "") and "../.." or tup.getconfig("HELPERDIR")
tup.include(HELPERDIR .. "/use_gcc.lua")
tup.include(HELPERDIR .. "/use_newlib.lua")
LDFLAGS = LDFLAGS .. " -Llibmujs --subsystem native"
LIBS = "-lmujs " .. LIBS
table.insert(LIBDEPS, "libmujs/<libmujs>")
INCLUDES = INCLUDES .. " -Ilibmujs"
compile_gcc{"kosjs.c", "import.c"}
link_gcc("kosjs")

View File

@ -1,64 +0,0 @@
var button_text = 0
var button = 2
// Dynamic functions! //
//////////////////////////////////////////////////
function Delay(long)
{
KolibriSyscall(5, long, 0, 0, 0, 0)
}
function StartDraw()
{
KolibriSyscall(12, 1, 0, 0, 0, 0)
}
function EndDraw()
{
KolibriSyscall(12, 2, 0, 0, 0, 0)
}
function GetEvent()
{
return KolibriSyscallReturnEAX(10, 0, 0, 0, 0, 0)
}
//////////////////////////////////////////////////
function Redraw()
{
StartDraw()
WindowCreate(10, 40, 400, 200, "My window", 0xFFFFFF, 0x14)
WriteText("KolibriOS JS example", 15, 34, 0, 0x90000000, 0xFFFFFF)
ButtonCreate((150 << 16) + 100, (100 << 16) + 50, button, 0x177245)
// Delay(100)
WriteText("Click!", 155,115, 0, 0x91000000 | 0xFFFFFF)
WriteText(button_text, 15,100, 0, 0x92000000)
EndDraw()
}
while(1)
{
var gui_event = GetEvent()
switch(gui_event)
{
case 0:
break
case 1:
Redraw()
break
case 3:
var pressed_button = GetButtonEvent()
switch (pressed_button)
{
case 1:
Exit()
break
case button:
button_text++;
Redraw()
break
}
break
}
}

View File

@ -1,91 +0,0 @@
#include <kos32sys.h>
#include <stdio.h>
#include <stdlib.h>
#include <import.h>
static void _ButtonCreate()
{
define_button(js_touint32(J, 1),js_touint32(J,2), js_touint32(J,3), js_touint32(J,4));
}
static void _WindowCreate()
{
sys_create_window(js_toint(J, 1), js_toint(J, 2), js_toint(J, 3), js_toint(J, 4), js_tostring(J,5), js_touint32(J,6), js_touint32(J,7));
}
static void _DebugPrintS()
{
puts(js_tostring(J,1));
}
static void _GetButtonEvent()
{
js_pushnumber(J,get_os_button());
}
static void _WriteText()
{
draw_text_sys(js_tostring(J,1), js_toint32(J,2), js_toint32(J,3), js_toint32(J,4), js_touint32(J,5));
}
// KolibriSyscall(EAX, EBX, ECX, EDX, EDI, ESI)
static void _KolibriSyscall()
{
__asm__ __volatile__(
"int $0x40"
::"a"(js_toint32(J,1)),
"b"(js_toint32(J,2)),
"c"(js_toint32(J,3)),
"d"(js_toint32(J,4)),
"D"(js_toint32(J,5)),
"S"(js_toint32(J,6)) : "memory");
}
static void _KolibriSyscallReturnEAX()
{
int _eax_;
__asm__ __volatile__(
"int $0x40"
:"=a"(_eax_)
:"a"(js_toint32(J,1)),
"b"(js_toint32(J,2)),
"c"(js_toint32(J,3)),
"d"(js_toint32(J,4)),
"D"(js_toint32(J,5)),
"S"(js_toint32(J,6)) : "memory");
js_pushnumber(J, _eax_);
}
void import_functions()
{
J = js_newstate(NULL, NULL, JS_STRICT);
js_newcfunction(J, _WindowCreate, "WindowCreate", 7);
js_setglobal(J, "WindowCreate");
js_newcfunction(J, _DebugPrintS, "DebugPrintS", 0);
js_setglobal(J, "DebugPrintS");
js_newcfunction(J, _ButtonCreate, "ButtonCreate", 4);
js_setglobal(J, "ButtonCreate");
js_newcfunction(J, _GetButtonEvent, "GetButtonEvent", 0);
js_setglobal(J, "GetButtonEvent");
js_newcfunction(J, (void*)exit, "Exit", 0);
js_setglobal(J, "Exit");
js_newcfunction(J, _WriteText, "WriteText", 5);
js_setglobal(J, "WriteText");
js_newcfunction(J, _KolibriSyscall, "KolibriSyscall", 6);
js_setglobal(J, "KolibriSyscall");
js_newcfunction(J, _KolibriSyscallReturnEAX, "KolibriSyscallReturnEAX", 6);
js_setglobal(J, "KolibriSyscallReturnEAX");
}

View File

@ -1,18 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <mujs.h>
#include <import.h>
int main(int argc, char **argv)
{
if (argc == 1) {
printf("usage: %s [program.js]\n", argv[0]);
} else {
import_functions();
js_dofile(J, argv[1]);
js_freestate (J);
}
exit(0);
}

View File

@ -1 +0,0 @@
Tor Andersson <tor.andersson@artifex.com>

View File

@ -1,16 +0,0 @@
ISC License
Copyright (c) 2013-2020 Artifex Software, Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.

View File

@ -1,16 +0,0 @@
CC = kos32-gcc
SDK_DIR = ../../../../contrib/sdk
CFLAGS = -c -fno-ident -O2 -fomit-frame-pointer -fno-ident -U__WIN32__ -U_Win32 -U_WIN32 -U__MINGW32__ -UWIN32
INCLUDES = -I $(SDK_DIR)/sources/newlib/libc/include -I .
SRC := $(notdir $(wildcard *.c))
OBJECTS = $(patsubst %.c, %.o, $(SRC))
default: $(patsubst %.c,%.o,$(SRC))
ar rcs libmujs.a *.o
rm *.o
%.o : %.c Makefile $(SRC)
$(CC) $(CFLAGS) $(INCLUDES) -o $@ $<

View File

@ -1,52 +0,0 @@
MuJS: an embeddable Javascript interpreter in C.
ABOUT
MuJS is a lightweight Javascript interpreter designed for embedding in
other software to extend them with scripting capabilities.
LICENSE
MuJS is Copyright 2013-2017 Artifex Software, Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
The software is provided "as is" and the author disclaims all warranties with
regard to this software including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any special, direct,
indirect, or consequential damages or any damages whatsoever resulting from
loss of use, data or profits, whether in an action of contract, negligence
or other tortious action, arising out of or in connection with the use or
performance of this software.
COMPILING
If you are building from source you can either use the provided Unix Makefile:
make release
Or compile the source with your preferred compiler:
cc -O2 -c one.c -o libmujs.o
INSTALLING
To install the MuJS command line interpreter, static library and header file:
make prefix=/usr/local install
DOWNLOAD
The latest development source is available directly from the git repository:
git clone http://git.ghostscript.com/mujs.git
REPORTING BUGS AND PROBLEMS
Report bugs on the ghostscript bugzilla, with MuJS as the selected component.
http://bugs.ghostscript.com/
The MuJS developers hang out on IRC in the #mupdf channel on irc.freenode.net.

View File

@ -1,10 +0,0 @@
if tup.getconfig("NO_GCC") ~= "" then return end
HELPERDIR = (tup.getconfig("HELPERDIR") == "") and "../../.." or tup.getconfig("HELPERDIR")
tup.include(HELPERDIR .. "/use_gcc.lua")
tup.include(HELPERDIR .. "/use_newlib.lua")
CFLAGS = CFLAGS .. " -std=c99 -U__WIN32__ -U_Win32 -U_WIN32 -U__MINGW32__ -UWIN32"
INCLUDES = INCLUDES .. " -I ."
compile_gcc{"utftype.c", "jsproperty.c", "jsobject.c", "jsdtoa.c", "jsbuiltin.c", "jsvalue.c", "jsnumber.c", "jsparse.c", "jsstate.c", "jsgc.c", "jsrepr.c", "pp.c", "utf.c", "jsfunction.c", "jsdump.c", "regexp.c", "jsstring.c", "jsarray.c", "jsrun.c", "jsdate.c", "jscompile.c", "jslex.c", "jsboolean.c", "jserror.c", "jsintern.c", "jsmath.c", "jsregexp.c", "json.c"}
tup.rule(OBJS, "kos32-ar rcs %o %f", {"libmujs.a", "<libmujs>"})

View File

@ -1,92 +0,0 @@
"list",
"fundec",
"identifier",
"exp_identifier",
"exp_number",
"exp_string",
"exp_regexp",
"exp_undef",
"exp_null",
"exp_true",
"exp_false",
"exp_this",
"exp_array",
"exp_object",
"exp_prop_val",
"exp_prop_get",
"exp_prop_set",
"exp_fun",
"exp_index",
"exp_member",
"exp_call",
"exp_new",
"exp_postinc",
"exp_postdec",
"exp_delete",
"exp_void",
"exp_typeof",
"exp_preinc",
"exp_predec",
"exp_pos",
"exp_neg",
"exp_bitnot",
"exp_lognot",
"exp_mod",
"exp_div",
"exp_mul",
"exp_sub",
"exp_add",
"exp_ushr",
"exp_shr",
"exp_shl",
"exp_in",
"exp_instanceof",
"exp_ge",
"exp_le",
"exp_gt",
"exp_lt",
"exp_strictne",
"exp_stricteq",
"exp_ne",
"exp_eq",
"exp_bitand",
"exp_bitxor",
"exp_bitor",
"exp_logand",
"exp_logor",
"exp_cond",
"exp_ass",
"exp_ass_mul",
"exp_ass_div",
"exp_ass_mod",
"exp_ass_add",
"exp_ass_sub",
"exp_ass_shl",
"exp_ass_shr",
"exp_ass_ushr",
"exp_ass_bitand",
"exp_ass_bitxor",
"exp_ass_bitor",
"exp_comma",
"exp_var",
"stm_block",
"stm_empty",
"stm_var",
"stm_if",
"stm_do",
"stm_while",
"stm_for",
"stm_for_var",
"stm_for_in",
"stm_for_in_var",
"stm_continue",
"stm_break",
"stm_return",
"stm_with",
"stm_switch",
"stm_throw",
"stm_try",
"stm_debugger",
"stm_label",
"stm_case",
"stm_default",

View File

@ -1,6 +0,0 @@
#include "mujs.h"
#define js_toint(J, idx) js_tointeger(J, idx)
js_State *J;
void import_functions();

View File

@ -1,748 +0,0 @@
#include "jsi.h"
#include "jsvalue.h"
#include "jsbuiltin.h"
int js_getlength(js_State *J, int idx)
{
int len;
js_getproperty(J, idx, "length");
len = js_tointeger(J, -1);
js_pop(J, 1);
return len;
}
void js_setlength(js_State *J, int idx, int len)
{
js_pushnumber(J, len);
js_setproperty(J, idx < 0 ? idx - 1 : idx, "length");
}
int js_hasindex(js_State *J, int idx, int i)
{
char buf[32];
return js_hasproperty(J, idx, js_itoa(buf, i));
}
void js_getindex(js_State *J, int idx, int i)
{
char buf[32];
js_getproperty(J, idx, js_itoa(buf, i));
}
void js_setindex(js_State *J, int idx, int i)
{
char buf[32];
js_setproperty(J, idx, js_itoa(buf, i));
}
void js_delindex(js_State *J, int idx, int i)
{
char buf[32];
js_delproperty(J, idx, js_itoa(buf, i));
}
static void jsB_new_Array(js_State *J)
{
int i, top = js_gettop(J);
js_newarray(J);
if (top == 2) {
if (js_isnumber(J, 1)) {
js_copy(J, 1);
js_setproperty(J, -2, "length");
} else {
js_copy(J, 1);
js_setindex(J, -2, 0);
}
} else {
for (i = 1; i < top; ++i) {
js_copy(J, i);
js_setindex(J, -2, i - 1);
}
}
}
static void Ap_concat(js_State *J)
{
int i, top = js_gettop(J);
int n, k, len;
js_newarray(J);
n = 0;
for (i = 0; i < top; ++i) {
js_copy(J, i);
if (js_isarray(J, -1)) {
len = js_getlength(J, -1);
for (k = 0; k < len; ++k)
if (js_hasindex(J, -1, k))
js_setindex(J, -3, n++);
js_pop(J, 1);
} else {
js_setindex(J, -2, n++);
}
}
}
static void Ap_join(js_State *J)
{
char * volatile out = NULL;
const char *sep;
const char *r;
int seplen;
int k, n, len;
len = js_getlength(J, 0);
if (js_isdefined(J, 1)) {
sep = js_tostring(J, 1);
seplen = strlen(sep);
} else {
sep = ",";
seplen = 1;
}
if (len == 0) {
js_pushliteral(J, "");
return;
}
if (js_try(J)) {
js_free(J, out);
js_throw(J);
}
n = 1;
for (k = 0; k < len; ++k) {
js_getindex(J, 0, k);
if (js_isundefined(J, -1) || js_isnull(J, -1))
r = "";
else
r = js_tostring(J, -1);
n += strlen(r);
if (k == 0) {
out = js_malloc(J, n);
strcpy(out, r);
} else {
n += seplen;
out = js_realloc(J, out, n);
strcat(out, sep);
strcat(out, r);
}
js_pop(J, 1);
}
js_pushstring(J, out);
js_endtry(J);
js_free(J, out);
}
static void Ap_pop(js_State *J)
{
int n;
n = js_getlength(J, 0);
if (n > 0) {
js_getindex(J, 0, n - 1);
js_delindex(J, 0, n - 1);
js_setlength(J, 0, n - 1);
} else {
js_setlength(J, 0, 0);
js_pushundefined(J);
}
}
static void Ap_push(js_State *J)
{
int i, top = js_gettop(J);
int n;
n = js_getlength(J, 0);
for (i = 1; i < top; ++i, ++n) {
js_copy(J, i);
js_setindex(J, 0, n);
}
js_setlength(J, 0, n);
js_pushnumber(J, n);
}
static void Ap_reverse(js_State *J)
{
int len, middle, lower;
len = js_getlength(J, 0);
middle = len / 2;
lower = 0;
while (lower != middle) {
int upper = len - lower - 1;
int haslower = js_hasindex(J, 0, lower);
int hasupper = js_hasindex(J, 0, upper);
if (haslower && hasupper) {
js_setindex(J, 0, lower);
js_setindex(J, 0, upper);
} else if (hasupper) {
js_setindex(J, 0, lower);
js_delindex(J, 0, upper);
} else if (haslower) {
js_setindex(J, 0, upper);
js_delindex(J, 0, lower);
}
++lower;
}
js_copy(J, 0);
}
static void Ap_shift(js_State *J)
{
int k, len;
len = js_getlength(J, 0);
if (len == 0) {
js_setlength(J, 0, 0);
js_pushundefined(J);
return;
}
js_getindex(J, 0, 0);
for (k = 1; k < len; ++k) {
if (js_hasindex(J, 0, k))
js_setindex(J, 0, k - 1);
else
js_delindex(J, 0, k - 1);
}
js_delindex(J, 0, len - 1);
js_setlength(J, 0, len - 1);
}
static void Ap_slice(js_State *J)
{
int len, s, e, n;
double sv, ev;
js_newarray(J);
len = js_getlength(J, 0);
sv = js_tointeger(J, 1);
ev = js_isdefined(J, 2) ? js_tointeger(J, 2) : len;
if (sv < 0) sv = sv + len;
if (ev < 0) ev = ev + len;
s = sv < 0 ? 0 : sv > len ? len : sv;
e = ev < 0 ? 0 : ev > len ? len : ev;
for (n = 0; s < e; ++s, ++n)
if (js_hasindex(J, 0, s))
js_setindex(J, -2, n);
}
struct sortslot {
js_Value v;
js_State *J;
};
static int sortcmp(const void *avoid, const void *bvoid)
{
const struct sortslot *aslot = avoid, *bslot = bvoid;
const js_Value *a = &aslot->v, *b = &bslot->v;
js_State *J = aslot->J;
const char *sx, *sy;
double v;
int c;
int unx = (a->type == JS_TUNDEFINED);
int uny = (b->type == JS_TUNDEFINED);
if (unx) return !uny;
if (uny) return -1;
if (js_iscallable(J, 1)) {
js_copy(J, 1); /* copy function */
js_pushundefined(J);
js_pushvalue(J, *a);
js_pushvalue(J, *b);
js_call(J, 2);
v = js_tonumber(J, -1);
c = (v == 0) ? 0 : (v < 0) ? -1 : 1;
js_pop(J, 1);
} else {
js_pushvalue(J, *a);
js_pushvalue(J, *b);
sx = js_tostring(J, -2);
sy = js_tostring(J, -1);
c = strcmp(sx, sy);
js_pop(J, 2);
}
return c;
}
static void Ap_sort(js_State *J)
{
struct sortslot *array = NULL;
int i, n, len;
len = js_getlength(J, 0);
if (len <= 0) {
js_copy(J, 0);
return;
}
if (len >= INT_MAX / (int)sizeof(*array))
js_rangeerror(J, "array is too large to sort");
array = js_malloc(J, len * sizeof *array);
/* Holding objects where the GC cannot see them is illegal, but if we
* don't allow the GC to run we can use qsort() on a temporary array of
* js_Values for fast sorting.
*/
++J->gcpause;
if (js_try(J)) {
--J->gcpause;
js_free(J, array);
js_throw(J);
}
n = 0;
for (i = 0; i < len; ++i) {
if (js_hasindex(J, 0, i)) {
array[n].v = *js_tovalue(J, -1);
array[n].J = J;
js_pop(J, 1);
++n;
}
}
qsort(array, n, sizeof *array, sortcmp);
for (i = 0; i < n; ++i) {
js_pushvalue(J, array[i].v);
js_setindex(J, 0, i);
}
for (i = n; i < len; ++i) {
js_delindex(J, 0, i);
}
--J->gcpause;
js_endtry(J);
js_free(J, array);
js_copy(J, 0);
}
static void Ap_splice(js_State *J)
{
int top = js_gettop(J);
int len, start, del, add, k;
double f;
js_newarray(J);
len = js_getlength(J, 0);
f = js_tointeger(J, 1);
if (f < 0) f = f + len;
start = f < 0 ? 0 : f > len ? len : f;
f = js_tointeger(J, 2);
del = f < 0 ? 0 : f > len - start ? len - start : f;
/* copy deleted items to return array */
for (k = 0; k < del; ++k)
if (js_hasindex(J, 0, start + k))
js_setindex(J, -2, k);
js_setlength(J, -1, del);
/* shift the tail to resize the hole left by deleted items */
add = top - 3;
if (add < del) {
for (k = start; k < len - del; ++k) {
if (js_hasindex(J, 0, k + del))
js_setindex(J, 0, k + add);
else
js_delindex(J, 0, k + add);
}
for (k = len; k > len - del + add; --k)
js_delindex(J, 0, k - 1);
} else if (add > del) {
for (k = len - del; k > start; --k) {
if (js_hasindex(J, 0, k + del - 1))
js_setindex(J, 0, k + add - 1);
else
js_delindex(J, 0, k + add - 1);
}
}
/* copy new items into the hole */
for (k = 0; k < add; ++k) {
js_copy(J, 3 + k);
js_setindex(J, 0, start + k);
}
js_setlength(J, 0, len - del + add);
}
static void Ap_unshift(js_State *J)
{
int i, top = js_gettop(J);
int k, len;
len = js_getlength(J, 0);
for (k = len; k > 0; --k) {
int from = k - 1;
int to = k + top - 2;
if (js_hasindex(J, 0, from))
js_setindex(J, 0, to);
else
js_delindex(J, 0, to);
}
for (i = 1; i < top; ++i) {
js_copy(J, i);
js_setindex(J, 0, i - 1);
}
js_setlength(J, 0, len + top - 1);
js_pushnumber(J, len + top - 1);
}
static void Ap_toString(js_State *J)
{
int top = js_gettop(J);
js_pop(J, top - 1);
Ap_join(J);
}
static void Ap_indexOf(js_State *J)
{
int k, len, from;
len = js_getlength(J, 0);
from = js_isdefined(J, 2) ? js_tointeger(J, 2) : 0;
if (from < 0) from = len + from;
if (from < 0) from = 0;
js_copy(J, 1);
for (k = from; k < len; ++k) {
if (js_hasindex(J, 0, k)) {
if (js_strictequal(J)) {
js_pushnumber(J, k);
return;
}
js_pop(J, 1);
}
}
js_pushnumber(J, -1);
}
static void Ap_lastIndexOf(js_State *J)
{
int k, len, from;
len = js_getlength(J, 0);
from = js_isdefined(J, 2) ? js_tointeger(J, 2) : len - 1;
if (from > len - 1) from = len - 1;
if (from < 0) from = len + from;
js_copy(J, 1);
for (k = from; k >= 0; --k) {
if (js_hasindex(J, 0, k)) {
if (js_strictequal(J)) {
js_pushnumber(J, k);
return;
}
js_pop(J, 1);
}
}
js_pushnumber(J, -1);
}
static void Ap_every(js_State *J)
{
int hasthis = js_gettop(J) >= 3;
int k, len;
if (!js_iscallable(J, 1))
js_typeerror(J, "callback is not a function");
len = js_getlength(J, 0);
for (k = 0; k < len; ++k) {
if (js_hasindex(J, 0, k)) {
js_copy(J, 1);
if (hasthis)
js_copy(J, 2);
else
js_pushundefined(J);
js_copy(J, -3);
js_pushnumber(J, k);
js_copy(J, 0);
js_call(J, 3);
if (!js_toboolean(J, -1))
return;
js_pop(J, 2);
}
}
js_pushboolean(J, 1);
}
static void Ap_some(js_State *J)
{
int hasthis = js_gettop(J) >= 3;
int k, len;
if (!js_iscallable(J, 1))
js_typeerror(J, "callback is not a function");
len = js_getlength(J, 0);
for (k = 0; k < len; ++k) {
if (js_hasindex(J, 0, k)) {
js_copy(J, 1);
if (hasthis)
js_copy(J, 2);
else
js_pushundefined(J);
js_copy(J, -3);
js_pushnumber(J, k);
js_copy(J, 0);
js_call(J, 3);
if (js_toboolean(J, -1))
return;
js_pop(J, 2);
}
}
js_pushboolean(J, 0);
}
static void Ap_forEach(js_State *J)
{
int hasthis = js_gettop(J) >= 3;
int k, len;
if (!js_iscallable(J, 1))
js_typeerror(J, "callback is not a function");
len = js_getlength(J, 0);
for (k = 0; k < len; ++k) {
if (js_hasindex(J, 0, k)) {
js_copy(J, 1);
if (hasthis)
js_copy(J, 2);
else
js_pushundefined(J);
js_copy(J, -3);
js_pushnumber(J, k);
js_copy(J, 0);
js_call(J, 3);
js_pop(J, 2);
}
}
js_pushundefined(J);
}
static void Ap_map(js_State *J)
{
int hasthis = js_gettop(J) >= 3;
int k, len;
if (!js_iscallable(J, 1))
js_typeerror(J, "callback is not a function");
js_newarray(J);
len = js_getlength(J, 0);
for (k = 0; k < len; ++k) {
if (js_hasindex(J, 0, k)) {
js_copy(J, 1);
if (hasthis)
js_copy(J, 2);
else
js_pushundefined(J);
js_copy(J, -3);
js_pushnumber(J, k);
js_copy(J, 0);
js_call(J, 3);
js_setindex(J, -3, k);
js_pop(J, 1);
}
}
}
static void Ap_filter(js_State *J)
{
int hasthis = js_gettop(J) >= 3;
int k, to, len;
if (!js_iscallable(J, 1))
js_typeerror(J, "callback is not a function");
js_newarray(J);
to = 0;
len = js_getlength(J, 0);
for (k = 0; k < len; ++k) {
if (js_hasindex(J, 0, k)) {
js_copy(J, 1);
if (hasthis)
js_copy(J, 2);
else
js_pushundefined(J);
js_copy(J, -3);
js_pushnumber(J, k);
js_copy(J, 0);
js_call(J, 3);
if (js_toboolean(J, -1)) {
js_pop(J, 1);
js_setindex(J, -2, to++);
} else {
js_pop(J, 2);
}
}
}
}
static void Ap_reduce(js_State *J)
{
int hasinitial = js_gettop(J) >= 3;
int k, len;
if (!js_iscallable(J, 1))
js_typeerror(J, "callback is not a function");
len = js_getlength(J, 0);
k = 0;
if (len == 0 && !hasinitial)
js_typeerror(J, "no initial value");
/* initial value of accumulator */
if (hasinitial)
js_copy(J, 2);
else {
while (k < len)
if (js_hasindex(J, 0, k++))
break;
if (k == len)
js_typeerror(J, "no initial value");
}
while (k < len) {
if (js_hasindex(J, 0, k)) {
js_copy(J, 1);
js_pushundefined(J);
js_rot(J, 4); /* accumulator on top */
js_rot(J, 4); /* property on top */
js_pushnumber(J, k);
js_copy(J, 0);
js_call(J, 4); /* calculate new accumulator */
}
++k;
}
/* return accumulator */
}
static void Ap_reduceRight(js_State *J)
{
int hasinitial = js_gettop(J) >= 3;
int k, len;
if (!js_iscallable(J, 1))
js_typeerror(J, "callback is not a function");
len = js_getlength(J, 0);
k = len - 1;
if (len == 0 && !hasinitial)
js_typeerror(J, "no initial value");
/* initial value of accumulator */
if (hasinitial)
js_copy(J, 2);
else {
while (k >= 0)
if (js_hasindex(J, 0, k--))
break;
if (k < 0)
js_typeerror(J, "no initial value");
}
while (k >= 0) {
if (js_hasindex(J, 0, k)) {
js_copy(J, 1);
js_pushundefined(J);
js_rot(J, 4); /* accumulator on top */
js_rot(J, 4); /* property on top */
js_pushnumber(J, k);
js_copy(J, 0);
js_call(J, 4); /* calculate new accumulator */
}
--k;
}
/* return accumulator */
}
static void A_isArray(js_State *J)
{
if (js_isobject(J, 1)) {
js_Object *T = js_toobject(J, 1);
js_pushboolean(J, T->type == JS_CARRAY);
} else {
js_pushboolean(J, 0);
}
}
void jsB_initarray(js_State *J)
{
js_pushobject(J, J->Array_prototype);
{
jsB_propf(J, "Array.prototype.toString", Ap_toString, 0);
jsB_propf(J, "Array.prototype.concat", Ap_concat, 0); /* 1 */
jsB_propf(J, "Array.prototype.join", Ap_join, 1);
jsB_propf(J, "Array.prototype.pop", Ap_pop, 0);
jsB_propf(J, "Array.prototype.push", Ap_push, 0); /* 1 */
jsB_propf(J, "Array.prototype.reverse", Ap_reverse, 0);
jsB_propf(J, "Array.prototype.shift", Ap_shift, 0);
jsB_propf(J, "Array.prototype.slice", Ap_slice, 2);
jsB_propf(J, "Array.prototype.sort", Ap_sort, 1);
jsB_propf(J, "Array.prototype.splice", Ap_splice, 0); /* 2 */
jsB_propf(J, "Array.prototype.unshift", Ap_unshift, 0); /* 1 */
/* ES5 */
jsB_propf(J, "Array.prototype.indexOf", Ap_indexOf, 1);
jsB_propf(J, "Array.prototype.lastIndexOf", Ap_lastIndexOf, 1);
jsB_propf(J, "Array.prototype.every", Ap_every, 1);
jsB_propf(J, "Array.prototype.some", Ap_some, 1);
jsB_propf(J, "Array.prototype.forEach", Ap_forEach, 1);
jsB_propf(J, "Array.prototype.map", Ap_map, 1);
jsB_propf(J, "Array.prototype.filter", Ap_filter, 1);
jsB_propf(J, "Array.prototype.reduce", Ap_reduce, 1);
jsB_propf(J, "Array.prototype.reduceRight", Ap_reduceRight, 1);
}
js_newcconstructor(J, jsB_new_Array, jsB_new_Array, "Array", 0); /* 1 */
{
/* ES5 */
jsB_propf(J, "Array.isArray", A_isArray, 1);
}
js_defglobal(J, "Array", JS_DONTENUM);
}

View File

@ -1,40 +0,0 @@
#include "jsi.h"
#include "jsvalue.h"
#include "jsbuiltin.h"
static void jsB_new_Boolean(js_State *J)
{
js_newboolean(J, js_toboolean(J, 1));
}
static void jsB_Boolean(js_State *J)
{
js_pushboolean(J, js_toboolean(J, 1));
}
static void Bp_toString(js_State *J)
{
js_Object *self = js_toobject(J, 0);
if (self->type != JS_CBOOLEAN) js_typeerror(J, "not a boolean");
js_pushliteral(J, self->u.boolean ? "true" : "false");
}
static void Bp_valueOf(js_State *J)
{
js_Object *self = js_toobject(J, 0);
if (self->type != JS_CBOOLEAN) js_typeerror(J, "not a boolean");
js_pushboolean(J, self->u.boolean);
}
void jsB_initboolean(js_State *J)
{
J->Boolean_prototype->u.boolean = 0;
js_pushobject(J, J->Boolean_prototype);
{
jsB_propf(J, "Boolean.prototype.toString", Bp_toString, 0);
jsB_propf(J, "Boolean.prototype.valueOf", Bp_valueOf, 0);
}
js_newcconstructor(J, jsB_Boolean, jsB_new_Boolean, "Boolean", 1);
js_defglobal(J, "Boolean", JS_DONTENUM);
}

View File

@ -1,245 +0,0 @@
#include "jsi.h"
#include "jslex.h"
#include "jscompile.h"
#include "jsvalue.h"
#include "jsbuiltin.h"
static void jsB_globalf(js_State *J, const char *name, js_CFunction cfun, int n)
{
js_newcfunction(J, cfun, name, n);
js_defglobal(J, name, JS_DONTENUM);
}
void jsB_propf(js_State *J, const char *name, js_CFunction cfun, int n)
{
const char *pname = strrchr(name, '.');
pname = pname ? pname + 1 : name;
js_newcfunction(J, cfun, name, n);
js_defproperty(J, -2, pname, JS_DONTENUM);
}
void jsB_propn(js_State *J, const char *name, double number)
{
js_pushnumber(J, number);
js_defproperty(J, -2, name, JS_READONLY | JS_DONTENUM | JS_DONTCONF);
}
void jsB_props(js_State *J, const char *name, const char *string)
{
js_pushliteral(J, string);
js_defproperty(J, -2, name, JS_DONTENUM);
}
static void jsB_parseInt(js_State *J)
{
const char *s = js_tostring(J, 1);
int radix = js_isdefined(J, 2) ? js_tointeger(J, 2) : 10;
double sign = 1;
double n;
char *e;
while (jsY_iswhite(*s) || jsY_isnewline(*s))
++s;
if (*s == '-') {
++s;
sign = -1;
} else if (*s == '+') {
++s;
}
if (radix == 0) {
radix = 10;
if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
s += 2;
radix = 16;
}
} else if (radix < 2 || radix > 36) {
js_pushnumber(J, NAN);
return;
}
n = strtol(s, &e, radix);
if (s == e)
js_pushnumber(J, NAN);
else
js_pushnumber(J, n * sign);
}
static void jsB_parseFloat(js_State *J)
{
const char *s = js_tostring(J, 1);
char *e;
double n;
while (jsY_iswhite(*s) || jsY_isnewline(*s)) ++s;
if (!strncmp(s, "Infinity", 8))
js_pushnumber(J, INFINITY);
else if (!strncmp(s, "+Infinity", 9))
js_pushnumber(J, INFINITY);
else if (!strncmp(s, "-Infinity", 9))
js_pushnumber(J, -INFINITY);
else {
n = js_stringtofloat(s, &e);
if (e == s)
js_pushnumber(J, NAN);
else
js_pushnumber(J, n);
}
}
static void jsB_isNaN(js_State *J)
{
double n = js_tonumber(J, 1);
js_pushboolean(J, isnan(n));
}
static void jsB_isFinite(js_State *J)
{
double n = js_tonumber(J, 1);
js_pushboolean(J, isfinite(n));
}
static void Encode(js_State *J, const char *str, const char *unescaped)
{
js_Buffer *sb = NULL;
static const char *HEX = "0123456789ABCDEF";
if (js_try(J)) {
js_free(J, sb);
js_throw(J);
}
while (*str) {
int c = (unsigned char) *str++;
if (strchr(unescaped, c))
js_putc(J, &sb, c);
else {
js_putc(J, &sb, '%');
js_putc(J, &sb, HEX[(c >> 4) & 0xf]);
js_putc(J, &sb, HEX[c & 0xf]);
}
}
js_putc(J, &sb, 0);
js_pushstring(J, sb ? sb->s : "");
js_endtry(J);
js_free(J, sb);
}
static void Decode(js_State *J, const char *str, const char *reserved)
{
js_Buffer *sb = NULL;
int a, b;
if (js_try(J)) {
js_free(J, sb);
js_throw(J);
}
while (*str) {
int c = (unsigned char) *str++;
if (c != '%')
js_putc(J, &sb, c);
else {
if (!str[0] || !str[1])
js_urierror(J, "truncated escape sequence");
a = *str++;
b = *str++;
if (!jsY_ishex(a) || !jsY_ishex(b))
js_urierror(J, "invalid escape sequence");
c = jsY_tohex(a) << 4 | jsY_tohex(b);
if (!strchr(reserved, c))
js_putc(J, &sb, c);
else {
js_putc(J, &sb, '%');
js_putc(J, &sb, a);
js_putc(J, &sb, b);
}
}
}
js_putc(J, &sb, 0);
js_pushstring(J, sb ? sb->s : "");
js_endtry(J);
js_free(J, sb);
}
#define URIRESERVED ";/?:@&=+$,"
#define URIALPHA "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define URIDIGIT "0123456789"
#define URIMARK "-_.!~*`()"
#define URIUNESCAPED URIALPHA URIDIGIT URIMARK
static void jsB_decodeURI(js_State *J)
{
Decode(J, js_tostring(J, 1), URIRESERVED "#");
}
static void jsB_decodeURIComponent(js_State *J)
{
Decode(J, js_tostring(J, 1), "");
}
static void jsB_encodeURI(js_State *J)
{
Encode(J, js_tostring(J, 1), URIUNESCAPED URIRESERVED "#");
}
static void jsB_encodeURIComponent(js_State *J)
{
Encode(J, js_tostring(J, 1), URIUNESCAPED);
}
void jsB_init(js_State *J)
{
/* Create the prototype objects here, before the constructors */
J->Object_prototype = jsV_newobject(J, JS_COBJECT, NULL);
J->Array_prototype = jsV_newobject(J, JS_CARRAY, J->Object_prototype);
J->Function_prototype = jsV_newobject(J, JS_CCFUNCTION, J->Object_prototype);
J->Boolean_prototype = jsV_newobject(J, JS_CBOOLEAN, J->Object_prototype);
J->Number_prototype = jsV_newobject(J, JS_CNUMBER, J->Object_prototype);
J->String_prototype = jsV_newobject(J, JS_CSTRING, J->Object_prototype);
J->RegExp_prototype = jsV_newobject(J, JS_COBJECT, J->Object_prototype);
J->Date_prototype = jsV_newobject(J, JS_CDATE, J->Object_prototype);
/* All the native error types */
J->Error_prototype = jsV_newobject(J, JS_CERROR, J->Object_prototype);
J->EvalError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype);
J->RangeError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype);
J->ReferenceError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype);
J->SyntaxError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype);
J->TypeError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype);
J->URIError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype);
/* Create the constructors and fill out the prototype objects */
jsB_initobject(J);
jsB_initarray(J);
jsB_initfunction(J);
jsB_initboolean(J);
jsB_initnumber(J);
jsB_initstring(J);
jsB_initregexp(J);
jsB_initdate(J);
jsB_initerror(J);
jsB_initmath(J);
jsB_initjson(J);
/* Initialize the global object */
js_pushnumber(J, NAN);
js_defglobal(J, "NaN", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
js_pushnumber(J, INFINITY);
js_defglobal(J, "Infinity", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
js_pushundefined(J);
js_defglobal(J, "undefined", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
jsB_globalf(J, "parseInt", jsB_parseInt, 1);
jsB_globalf(J, "parseFloat", jsB_parseFloat, 1);
jsB_globalf(J, "isNaN", jsB_isNaN, 1);
jsB_globalf(J, "isFinite", jsB_isFinite, 1);
jsB_globalf(J, "decodeURI", jsB_decodeURI, 1);
jsB_globalf(J, "decodeURIComponent", jsB_decodeURIComponent, 1);
jsB_globalf(J, "encodeURI", jsB_encodeURI, 1);
jsB_globalf(J, "encodeURIComponent", jsB_encodeURIComponent, 1);
}

View File

@ -1,21 +0,0 @@
#ifndef js_builtin_h
#define js_builtin_h
void jsB_init(js_State *J);
void jsB_initobject(js_State *J);
void jsB_initarray(js_State *J);
void jsB_initfunction(js_State *J);
void jsB_initboolean(js_State *J);
void jsB_initnumber(js_State *J);
void jsB_initstring(js_State *J);
void jsB_initregexp(js_State *J);
void jsB_initerror(js_State *J);
void jsB_initmath(js_State *J);
void jsB_initjson(js_State *J);
void jsB_initdate(js_State *J);
void jsB_propf(js_State *J, const char *name, js_CFunction cfun, int n);
void jsB_propn(js_State *J, const char *name, double number);
void jsB_props(js_State *J, const char *name, const char *string);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,146 +0,0 @@
#ifndef js_compile_h
#define js_compile_h
enum js_OpCode
{
OP_POP, /* A -- */
OP_DUP, /* A -- A A */
OP_DUP2, /* A B -- A B A B */
OP_ROT2, /* A B -- B A */
OP_ROT3, /* A B C -- C A B */
OP_ROT4, /* A B C D -- D A B C */
OP_INTEGER, /* -K- (number-32768) */
OP_NUMBER, /* -N- <number> */
OP_STRING, /* -S- <string> */
OP_CLOSURE, /* -F- <closure> */
OP_NEWARRAY,
OP_NEWOBJECT,
OP_NEWREGEXP, /* -S,opts- <regexp> */
OP_UNDEF,
OP_NULL,
OP_TRUE,
OP_FALSE,
OP_THIS,
OP_CURRENT, /* currently executing function object */
OP_GETLOCAL, /* -K- <value> */
OP_SETLOCAL, /* <value> -K- <value> */
OP_DELLOCAL, /* -K- false */
OP_HASVAR, /* -S- ( <value> | undefined ) */
OP_GETVAR, /* -S- <value> */
OP_SETVAR, /* <value> -S- <value> */
OP_DELVAR, /* -S- <success> */
OP_IN, /* <name> <obj> -- <exists?> */
OP_INITPROP, /* <obj> <key> <val> -- <obj> */
OP_INITGETTER, /* <obj> <key> <closure> -- <obj> */
OP_INITSETTER, /* <obj> <key> <closure> -- <obj> */
OP_GETPROP, /* <obj> <name> -- <value> */
OP_GETPROP_S, /* <obj> -S- <value> */
OP_SETPROP, /* <obj> <name> <value> -- <value> */
OP_SETPROP_S, /* <obj> <value> -S- <value> */
OP_DELPROP, /* <obj> <name> -- <success> */
OP_DELPROP_S, /* <obj> -S- <success> */
OP_ITERATOR, /* <obj> -- <iobj> */
OP_NEXTITER, /* <iobj> -- ( <iobj> <name> true | false ) */
OP_EVAL, /* <args...> -(numargs)- <returnvalue> */
OP_CALL, /* <closure> <this> <args...> -(numargs)- <returnvalue> */
OP_NEW, /* <closure> <args...> -(numargs)- <returnvalue> */
OP_TYPEOF,
OP_POS,
OP_NEG,
OP_BITNOT,
OP_LOGNOT,
OP_INC, /* <x> -- ToNumber(x)+1 */
OP_DEC, /* <x> -- ToNumber(x)-1 */
OP_POSTINC, /* <x> -- ToNumber(x)+1 ToNumber(x) */
OP_POSTDEC, /* <x> -- ToNumber(x)-1 ToNumber(x) */
OP_MUL,
OP_DIV,
OP_MOD,
OP_ADD,
OP_SUB,
OP_SHL,
OP_SHR,
OP_USHR,
OP_LT,
OP_GT,
OP_LE,
OP_GE,
OP_EQ,
OP_NE,
OP_STRICTEQ,
OP_STRICTNE,
OP_JCASE,
OP_BITAND,
OP_BITXOR,
OP_BITOR,
OP_INSTANCEOF,
OP_THROW,
OP_TRY, /* -ADDR- /jump/ or -ADDR- <exception> */
OP_ENDTRY,
OP_CATCH, /* push scope chain with exception variable */
OP_ENDCATCH,
OP_WITH,
OP_ENDWITH,
OP_DEBUGGER,
OP_JUMP,
OP_JTRUE,
OP_JFALSE,
OP_RETURN,
};
struct js_Function
{
const char *name;
int script;
int lightweight;
int strict;
int arguments;
int numparams;
js_Instruction *code;
int codecap, codelen;
js_Function **funtab;
int funcap, funlen;
double *numtab;
int numcap, numlen;
const char **strtab;
int strcap, strlen;
const char **vartab;
int varcap, varlen;
const char *filename;
int line, lastline;
js_Function *gcnext;
int gcmark;
};
js_Function *jsC_compilefunction(js_State *J, js_Ast *prog);
js_Function *jsC_compilescript(js_State *J, js_Ast *prog, int default_strict);
const char *jsC_opcodestring(enum js_OpCode opcode);
void jsC_dumpfunction(js_State *J, js_Function *fun);
#endif

View File

@ -1,812 +0,0 @@
#include "jsi.h"
#include "jsvalue.h"
#include "jsbuiltin.h"
#include <time.h>
#if defined(__unix__) || defined(__APPLE__)
#include <sys/time.h>
#elif defined(_WIN32)
#include <sys/timeb.h>
#endif
#define js_optnumber(J,I,V) (js_isdefined(J,I) ? js_tonumber(J,I) : V)
static double Now(void)
{
#if defined(__unix__) || defined(__APPLE__)
struct timeval tv;
gettimeofday(&tv, NULL);
return floor(tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0);
#elif defined(_WIN32)
struct _timeb tv;
_ftime(&tv);
return tv.time * 1000.0 + tv.millitm;
#else
return time(NULL) * 1000.0;
#endif
}
static double LocalTZA(void)
{
static int once = 1;
static double tza = 0;
if (once) {
time_t now = time(NULL);
time_t utc = mktime(gmtime(&now));
time_t loc = mktime(localtime(&now));
tza = (loc - utc) * 1000;
once = 0;
}
return tza;
}
static double DaylightSavingTA(double t)
{
return 0; /* TODO */
}
/* Helpers from the ECMA 262 specification */
#define HoursPerDay 24.0
#define MinutesPerDay (HoursPerDay * MinutesPerHour)
#define MinutesPerHour 60.0
#define SecondsPerDay (MinutesPerDay * SecondsPerMinute)
#define SecondsPerHour (MinutesPerHour * SecondsPerMinute)
#define SecondsPerMinute 60.0
#define msPerDay (SecondsPerDay * msPerSecond)
#define msPerHour (SecondsPerHour * msPerSecond)
#define msPerMinute (SecondsPerMinute * msPerSecond)
#define msPerSecond 1000.0
static double pmod(double x, double y)
{
x = fmod(x, y);
if (x < 0)
x += y;
return x;
}
static int Day(double t)
{
return floor(t / msPerDay);
}
static double TimeWithinDay(double t)
{
return pmod(t, msPerDay);
}
static int DaysInYear(int y)
{
return y % 4 == 0 && (y % 100 || (y % 400 == 0)) ? 366 : 365;
}
static int DayFromYear(int y)
{
return 365 * (y - 1970) +
floor((y - 1969) / 4.0) -
floor((y - 1901) / 100.0) +
floor((y - 1601) / 400.0);
}
static double TimeFromYear(int y)
{
return DayFromYear(y) * msPerDay;
}
static int YearFromTime(double t)
{
int y = floor(t / (msPerDay * 365.2425)) + 1970;
double t2 = TimeFromYear(y);
if (t2 > t)
--y;
else if (t2 + msPerDay * DaysInYear(y) <= t)
++y;
return y;
}
static int InLeapYear(double t)
{
return DaysInYear(YearFromTime(t)) == 366;
}
static int DayWithinYear(double t)
{
return Day(t) - DayFromYear(YearFromTime(t));
}
static int MonthFromTime(double t)
{
int day = DayWithinYear(t);
int leap = InLeapYear(t);
if (day < 31) return 0;
if (day < 59 + leap) return 1;
if (day < 90 + leap) return 2;
if (day < 120 + leap) return 3;
if (day < 151 + leap) return 4;
if (day < 181 + leap) return 5;
if (day < 212 + leap) return 6;
if (day < 243 + leap) return 7;
if (day < 273 + leap) return 8;
if (day < 304 + leap) return 9;
if (day < 334 + leap) return 10;
return 11;
}
static int DateFromTime(double t)
{
int day = DayWithinYear(t);
int leap = InLeapYear(t);
switch (MonthFromTime(t)) {
case 0: return day + 1;
case 1: return day - 30;
case 2: return day - 58 - leap;
case 3: return day - 89 - leap;
case 4: return day - 119 - leap;
case 5: return day - 150 - leap;
case 6: return day - 180 - leap;
case 7: return day - 211 - leap;
case 8: return day - 242 - leap;
case 9: return day - 272 - leap;
case 10: return day - 303 - leap;
default : return day - 333 - leap;
}
}
static int WeekDay(double t)
{
return pmod(Day(t) + 4, 7);
}
static double LocalTime(double utc)
{
return utc + LocalTZA() + DaylightSavingTA(utc);
}
static double UTC(double loc)
{
return loc - LocalTZA() - DaylightSavingTA(loc - LocalTZA());
}
static int HourFromTime(double t)
{
return pmod(floor(t / msPerHour), HoursPerDay);
}
static int MinFromTime(double t)
{
return pmod(floor(t / msPerMinute), MinutesPerHour);
}
static int SecFromTime(double t)
{
return pmod(floor(t / msPerSecond), SecondsPerMinute);
}
static int msFromTime(double t)
{
return pmod(t, msPerSecond);
}
static double MakeTime(double hour, double min, double sec, double ms)
{
return ((hour * MinutesPerHour + min) * SecondsPerMinute + sec) * msPerSecond + ms;
}
static double MakeDay(double y, double m, double date)
{
/*
* The following array contains the day of year for the first day of
* each month, where index 0 is January, and day 0 is January 1.
*/
static const double firstDayOfMonth[2][12] = {
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
{0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}
};
double yd, md;
int im;
y += floor(m / 12);
m = pmod(m, 12);
im = (int)m;
if (im < 0 || im >= 12)
return NAN;
yd = floor(TimeFromYear(y) / msPerDay);
md = firstDayOfMonth[DaysInYear(y) == 366][im];
return yd + md + date - 1;
}
static double MakeDate(double day, double time)
{
return day * msPerDay + time;
}
static double TimeClip(double t)
{
if (!isfinite(t))
return NAN;
if (fabs(t) > 8.64e15)
return NAN;
return t < 0 ? -floor(-t) : floor(t);
}
static int toint(const char **sp, int w, int *v)
{
const char *s = *sp;
*v = 0;
while (w--) {
if (*s < '0' || *s > '9')
return 0;
*v = *v * 10 + (*s++ - '0');
}
*sp = s;
return 1;
}
static double parseDateTime(const char *s)
{
int y = 1970, m = 1, d = 1, H = 0, M = 0, S = 0, ms = 0;
int tza = 0;
double t;
/* Parse ISO 8601 formatted date and time: */
/* YYYY("-"MM("-"DD)?)?("T"HH":"mm(":"ss("."sss)?)?("Z"|[+-]HH(":"mm)?)?)? */
if (!toint(&s, 4, &y)) return NAN;
if (*s == '-') {
s += 1;
if (!toint(&s, 2, &m)) return NAN;
if (*s == '-') {
s += 1;
if (!toint(&s, 2, &d)) return NAN;
}
}
if (*s == 'T') {
s += 1;
if (!toint(&s, 2, &H)) return NAN;
if (*s != ':') return NAN;
s += 1;
if (!toint(&s, 2, &M)) return NAN;
if (*s == ':') {
s += 1;
if (!toint(&s, 2, &S)) return NAN;
if (*s == '.') {
s += 1;
if (!toint(&s, 3, &ms)) return NAN;
}
}
if (*s == 'Z') {
s += 1;
tza = 0;
} else if (*s == '+' || *s == '-') {
int tzh = 0, tzm = 0;
int tzs = *s == '+' ? 1 : -1;
s += 1;
if (!toint(&s, 2, &tzh)) return NAN;
if (*s == ':') {
s += 1;
if (!toint(&s, 2, &tzm)) return NAN;
}
if (tzh > 23 || tzm > 59) return NAN;
tza = tzs * (tzh * msPerHour + tzm * msPerMinute);
} else {
tza = LocalTZA();
}
}
if (*s) return NAN;
if (m < 1 || m > 12) return NAN;
if (d < 1 || d > 31) return NAN;
if (H < 0 || H > 24) return NAN;
if (M < 0 || M > 59) return NAN;
if (S < 0 || S > 59) return NAN;
if (ms < 0 || ms > 999) return NAN;
if (H == 24 && (M != 0 || S != 0 || ms != 0)) return NAN;
/* TODO: DaylightSavingTA on local times */
t = MakeDate(MakeDay(y, m-1, d), MakeTime(H, M, S, ms));
return t - tza;
}
/* date formatting */
static char *fmtdate(char *buf, double t)
{
int y = YearFromTime(t);
int m = MonthFromTime(t);
int d = DateFromTime(t);
if (!isfinite(t))
return "Invalid Date";
sprintf(buf, "%04d-%02d-%02d", y, m+1, d);
return buf;
}
static char *fmttime(char *buf, double t, double tza)
{
int H = HourFromTime(t);
int M = MinFromTime(t);
int S = SecFromTime(t);
int ms = msFromTime(t);
int tzh = HourFromTime(fabs(tza));
int tzm = MinFromTime(fabs(tza));
if (!isfinite(t))
return "Invalid Date";
if (tza == 0)
sprintf(buf, "%02d:%02d:%02d.%03dZ", H, M, S, ms);
else if (tza < 0)
sprintf(buf, "%02d:%02d:%02d.%03d-%02d:%02d", H, M, S, ms, tzh, tzm);
else
sprintf(buf, "%02d:%02d:%02d.%03d+%02d:%02d", H, M, S, ms, tzh, tzm);
return buf;
}
static char *fmtdatetime(char *buf, double t, double tza)
{
char dbuf[20], tbuf[20];
if (!isfinite(t))
return "Invalid Date";
fmtdate(dbuf, t);
fmttime(tbuf, t, tza);
sprintf(buf, "%sT%s", dbuf, tbuf);
return buf;
}
/* Date functions */
static double js_todate(js_State *J, int idx)
{
js_Object *self = js_toobject(J, idx);
if (self->type != JS_CDATE)
js_typeerror(J, "not a date");
return self->u.number;
}
static void js_setdate(js_State *J, int idx, double t)
{
js_Object *self = js_toobject(J, idx);
if (self->type != JS_CDATE)
js_typeerror(J, "not a date");
self->u.number = TimeClip(t);
js_pushnumber(J, self->u.number);
}
static void D_parse(js_State *J)
{
double t = parseDateTime(js_tostring(J, 1));
js_pushnumber(J, t);
}
static void D_UTC(js_State *J)
{
double y, m, d, H, M, S, ms, t;
y = js_tonumber(J, 1);
if (y < 100) y += 1900;
m = js_tonumber(J, 2);
d = js_optnumber(J, 3, 1);
H = js_optnumber(J, 4, 0);
M = js_optnumber(J, 5, 0);
S = js_optnumber(J, 6, 0);
ms = js_optnumber(J, 7, 0);
t = MakeDate(MakeDay(y, m, d), MakeTime(H, M, S, ms));
t = TimeClip(t);
js_pushnumber(J, t);
}
static void D_now(js_State *J)
{
js_pushnumber(J, Now());
}
static void jsB_Date(js_State *J)
{
char buf[64];
js_pushstring(J, fmtdatetime(buf, LocalTime(Now()), LocalTZA()));
}
static void jsB_new_Date(js_State *J)
{
int top = js_gettop(J);
js_Object *obj;
double t;
if (top == 1)
t = Now();
else if (top == 2) {
js_toprimitive(J, 1, JS_HNONE);
if (js_isstring(J, 1))
t = parseDateTime(js_tostring(J, 1));
else
t = TimeClip(js_tonumber(J, 1));
} else {
double y, m, d, H, M, S, ms;
y = js_tonumber(J, 1);
if (y < 100) y += 1900;
m = js_tonumber(J, 2);
d = js_optnumber(J, 3, 1);
H = js_optnumber(J, 4, 0);
M = js_optnumber(J, 5, 0);
S = js_optnumber(J, 6, 0);
ms = js_optnumber(J, 7, 0);
t = MakeDate(MakeDay(y, m, d), MakeTime(H, M, S, ms));
t = TimeClip(UTC(t));
}
obj = jsV_newobject(J, JS_CDATE, J->Date_prototype);
obj->u.number = t;
js_pushobject(J, obj);
}
static void Dp_valueOf(js_State *J)
{
double t = js_todate(J, 0);
js_pushnumber(J, t);
}
static void Dp_toString(js_State *J)
{
char buf[64];
double t = js_todate(J, 0);
js_pushstring(J, fmtdatetime(buf, LocalTime(t), LocalTZA()));
}
static void Dp_toDateString(js_State *J)
{
char buf[64];
double t = js_todate(J, 0);
js_pushstring(J, fmtdate(buf, LocalTime(t)));
}
static void Dp_toTimeString(js_State *J)
{
char buf[64];
double t = js_todate(J, 0);
js_pushstring(J, fmttime(buf, LocalTime(t), LocalTZA()));
}
static void Dp_toUTCString(js_State *J)
{
char buf[64];
double t = js_todate(J, 0);
js_pushstring(J, fmtdatetime(buf, t, 0));
}
static void Dp_toISOString(js_State *J)
{
char buf[64];
double t = js_todate(J, 0);
if (!isfinite(t))
js_rangeerror(J, "invalid date");
js_pushstring(J, fmtdatetime(buf, t, 0));
}
static void Dp_getFullYear(js_State *J)
{
double t = js_todate(J, 0);
js_pushnumber(J, YearFromTime(LocalTime(t)));
}
static void Dp_getMonth(js_State *J)
{
double t = js_todate(J, 0);
js_pushnumber(J, MonthFromTime(LocalTime(t)));
}
static void Dp_getDate(js_State *J)
{
double t = js_todate(J, 0);
js_pushnumber(J, DateFromTime(LocalTime(t)));
}
static void Dp_getDay(js_State *J)
{
double t = js_todate(J, 0);
js_pushnumber(J, WeekDay(LocalTime(t)));
}
static void Dp_getHours(js_State *J)
{
double t = js_todate(J, 0);
js_pushnumber(J, HourFromTime(LocalTime(t)));
}
static void Dp_getMinutes(js_State *J)
{
double t = js_todate(J, 0);
js_pushnumber(J, MinFromTime(LocalTime(t)));
}
static void Dp_getSeconds(js_State *J)
{
double t = js_todate(J, 0);
js_pushnumber(J, SecFromTime(LocalTime(t)));
}
static void Dp_getMilliseconds(js_State *J)
{
double t = js_todate(J, 0);
js_pushnumber(J, msFromTime(LocalTime(t)));
}
static void Dp_getUTCFullYear(js_State *J)
{
double t = js_todate(J, 0);
js_pushnumber(J, YearFromTime(t));
}
static void Dp_getUTCMonth(js_State *J)
{
double t = js_todate(J, 0);
js_pushnumber(J, MonthFromTime(t));
}
static void Dp_getUTCDate(js_State *J)
{
double t = js_todate(J, 0);
js_pushnumber(J, DateFromTime(t));
}
static void Dp_getUTCDay(js_State *J)
{
double t = js_todate(J, 0);
js_pushnumber(J, WeekDay(t));
}
static void Dp_getUTCHours(js_State *J)
{
double t = js_todate(J, 0);
js_pushnumber(J, HourFromTime(t));
}
static void Dp_getUTCMinutes(js_State *J)
{
double t = js_todate(J, 0);
js_pushnumber(J, MinFromTime(t));
}
static void Dp_getUTCSeconds(js_State *J)
{
double t = js_todate(J, 0);
js_pushnumber(J, SecFromTime(t));
}
static void Dp_getUTCMilliseconds(js_State *J)
{
double t = js_todate(J, 0);
js_pushnumber(J, msFromTime(t));
}
static void Dp_getTimezoneOffset(js_State *J)
{
double t = js_todate(J, 0);
js_pushnumber(J, (t - LocalTime(t)) / msPerMinute);
}
static void Dp_setTime(js_State *J)
{
js_setdate(J, 0, js_tonumber(J, 1));
}
static void Dp_setMilliseconds(js_State *J)
{
double t = LocalTime(js_todate(J, 0));
double h = HourFromTime(t);
double m = MinFromTime(t);
double s = SecFromTime(t);
double ms = js_tonumber(J, 1);
js_setdate(J, 0, UTC(MakeDate(Day(t), MakeTime(h, m, s, ms))));
}
static void Dp_setSeconds(js_State *J)
{
double t = LocalTime(js_todate(J, 0));
double h = HourFromTime(t);
double m = MinFromTime(t);
double s = js_tonumber(J, 1);
double ms = js_optnumber(J, 2, msFromTime(t));
js_setdate(J, 0, UTC(MakeDate(Day(t), MakeTime(h, m, s, ms))));
}
static void Dp_setMinutes(js_State *J)
{
double t = LocalTime(js_todate(J, 0));
double h = HourFromTime(t);
double m = js_tonumber(J, 1);
double s = js_optnumber(J, 2, SecFromTime(t));
double ms = js_optnumber(J, 3, msFromTime(t));
js_setdate(J, 0, UTC(MakeDate(Day(t), MakeTime(h, m, s, ms))));
}
static void Dp_setHours(js_State *J)
{
double t = LocalTime(js_todate(J, 0));
double h = js_tonumber(J, 1);
double m = js_optnumber(J, 2, MinFromTime(t));
double s = js_optnumber(J, 3, SecFromTime(t));
double ms = js_optnumber(J, 4, msFromTime(t));
js_setdate(J, 0, UTC(MakeDate(Day(t), MakeTime(h, m, s, ms))));
}
static void Dp_setDate(js_State *J)
{
double t = LocalTime(js_todate(J, 0));
double y = YearFromTime(t);
double m = MonthFromTime(t);
double d = js_tonumber(J, 1);
js_setdate(J, 0, UTC(MakeDate(MakeDay(y, m, d), TimeWithinDay(t))));
}
static void Dp_setMonth(js_State *J)
{
double t = LocalTime(js_todate(J, 0));
double y = YearFromTime(t);
double m = js_tonumber(J, 1);
double d = js_optnumber(J, 2, DateFromTime(t));
js_setdate(J, 0, UTC(MakeDate(MakeDay(y, m, d), TimeWithinDay(t))));
}
static void Dp_setFullYear(js_State *J)
{
double t = LocalTime(js_todate(J, 0));
double y = js_tonumber(J, 1);
double m = js_optnumber(J, 2, MonthFromTime(t));
double d = js_optnumber(J, 3, DateFromTime(t));
js_setdate(J, 0, UTC(MakeDate(MakeDay(y, m, d), TimeWithinDay(t))));
}
static void Dp_setUTCMilliseconds(js_State *J)
{
double t = js_todate(J, 0);
double h = HourFromTime(t);
double m = MinFromTime(t);
double s = SecFromTime(t);
double ms = js_tonumber(J, 1);
js_setdate(J, 0, MakeDate(Day(t), MakeTime(h, m, s, ms)));
}
static void Dp_setUTCSeconds(js_State *J)
{
double t = js_todate(J, 0);
double h = HourFromTime(t);
double m = MinFromTime(t);
double s = js_tonumber(J, 1);
double ms = js_optnumber(J, 2, msFromTime(t));
js_setdate(J, 0, MakeDate(Day(t), MakeTime(h, m, s, ms)));
}
static void Dp_setUTCMinutes(js_State *J)
{
double t = js_todate(J, 0);
double h = HourFromTime(t);
double m = js_tonumber(J, 1);
double s = js_optnumber(J, 2, SecFromTime(t));
double ms = js_optnumber(J, 3, msFromTime(t));
js_setdate(J, 0, MakeDate(Day(t), MakeTime(h, m, s, ms)));
}
static void Dp_setUTCHours(js_State *J)
{
double t = js_todate(J, 0);
double h = js_tonumber(J, 1);
double m = js_optnumber(J, 2, HourFromTime(t));
double s = js_optnumber(J, 3, SecFromTime(t));
double ms = js_optnumber(J, 4, msFromTime(t));
js_setdate(J, 0, MakeDate(Day(t), MakeTime(h, m, s, ms)));
}
static void Dp_setUTCDate(js_State *J)
{
double t = js_todate(J, 0);
double y = YearFromTime(t);
double m = MonthFromTime(t);
double d = js_tonumber(J, 1);
js_setdate(J, 0, MakeDate(MakeDay(y, m, d), TimeWithinDay(t)));
}
static void Dp_setUTCMonth(js_State *J)
{
double t = js_todate(J, 0);
double y = YearFromTime(t);
double m = js_tonumber(J, 1);
double d = js_optnumber(J, 2, DateFromTime(t));
js_setdate(J, 0, MakeDate(MakeDay(y, m, d), TimeWithinDay(t)));
}
static void Dp_setUTCFullYear(js_State *J)
{
double t = js_todate(J, 0);
double y = js_tonumber(J, 1);
double m = js_optnumber(J, 2, MonthFromTime(t));
double d = js_optnumber(J, 3, DateFromTime(t));
js_setdate(J, 0, MakeDate(MakeDay(y, m, d), TimeWithinDay(t)));
}
static void Dp_toJSON(js_State *J)
{
js_copy(J, 0);
js_toprimitive(J, -1, JS_HNUMBER);
if (js_isnumber(J, -1) && !isfinite(js_tonumber(J, -1))) {
js_pushnull(J);
return;
}
js_pop(J, 1);
js_getproperty(J, 0, "toISOString");
if (!js_iscallable(J, -1))
js_typeerror(J, "this.toISOString is not a function");
js_copy(J, 0);
js_call(J, 0);
}
void jsB_initdate(js_State *J)
{
J->Date_prototype->u.number = 0;
js_pushobject(J, J->Date_prototype);
{
jsB_propf(J, "Date.prototype.valueOf", Dp_valueOf, 0);
jsB_propf(J, "Date.prototype.toString", Dp_toString, 0);
jsB_propf(J, "Date.prototype.toDateString", Dp_toDateString, 0);
jsB_propf(J, "Date.prototype.toTimeString", Dp_toTimeString, 0);
jsB_propf(J, "Date.prototype.toLocaleString", Dp_toString, 0);
jsB_propf(J, "Date.prototype.toLocaleDateString", Dp_toDateString, 0);
jsB_propf(J, "Date.prototype.toLocaleTimeString", Dp_toTimeString, 0);
jsB_propf(J, "Date.prototype.toUTCString", Dp_toUTCString, 0);
jsB_propf(J, "Date.prototype.getTime", Dp_valueOf, 0);
jsB_propf(J, "Date.prototype.getFullYear", Dp_getFullYear, 0);
jsB_propf(J, "Date.prototype.getUTCFullYear", Dp_getUTCFullYear, 0);
jsB_propf(J, "Date.prototype.getMonth", Dp_getMonth, 0);
jsB_propf(J, "Date.prototype.getUTCMonth", Dp_getUTCMonth, 0);
jsB_propf(J, "Date.prototype.getDate", Dp_getDate, 0);
jsB_propf(J, "Date.prototype.getUTCDate", Dp_getUTCDate, 0);
jsB_propf(J, "Date.prototype.getDay", Dp_getDay, 0);
jsB_propf(J, "Date.prototype.getUTCDay", Dp_getUTCDay, 0);
jsB_propf(J, "Date.prototype.getHours", Dp_getHours, 0);
jsB_propf(J, "Date.prototype.getUTCHours", Dp_getUTCHours, 0);
jsB_propf(J, "Date.prototype.getMinutes", Dp_getMinutes, 0);
jsB_propf(J, "Date.prototype.getUTCMinutes", Dp_getUTCMinutes, 0);
jsB_propf(J, "Date.prototype.getSeconds", Dp_getSeconds, 0);
jsB_propf(J, "Date.prototype.getUTCSeconds", Dp_getUTCSeconds, 0);
jsB_propf(J, "Date.prototype.getMilliseconds", Dp_getMilliseconds, 0);
jsB_propf(J, "Date.prototype.getUTCMilliseconds", Dp_getUTCMilliseconds, 0);
jsB_propf(J, "Date.prototype.getTimezoneOffset", Dp_getTimezoneOffset, 0);
jsB_propf(J, "Date.prototype.setTime", Dp_setTime, 1);
jsB_propf(J, "Date.prototype.setMilliseconds", Dp_setMilliseconds, 1);
jsB_propf(J, "Date.prototype.setUTCMilliseconds", Dp_setUTCMilliseconds, 1);
jsB_propf(J, "Date.prototype.setSeconds", Dp_setSeconds, 2);
jsB_propf(J, "Date.prototype.setUTCSeconds", Dp_setUTCSeconds, 2);
jsB_propf(J, "Date.prototype.setMinutes", Dp_setMinutes, 3);
jsB_propf(J, "Date.prototype.setUTCMinutes", Dp_setUTCMinutes, 3);
jsB_propf(J, "Date.prototype.setHours", Dp_setHours, 4);
jsB_propf(J, "Date.prototype.setUTCHours", Dp_setUTCHours, 4);
jsB_propf(J, "Date.prototype.setDate", Dp_setDate, 1);
jsB_propf(J, "Date.prototype.setUTCDate", Dp_setUTCDate, 1);
jsB_propf(J, "Date.prototype.setMonth", Dp_setMonth, 2);
jsB_propf(J, "Date.prototype.setUTCMonth", Dp_setUTCMonth, 2);
jsB_propf(J, "Date.prototype.setFullYear", Dp_setFullYear, 3);
jsB_propf(J, "Date.prototype.setUTCFullYear", Dp_setUTCFullYear, 3);
/* ES5 */
jsB_propf(J, "Date.prototype.toISOString", Dp_toISOString, 0);
jsB_propf(J, "Date.prototype.toJSON", Dp_toJSON, 1);
}
js_newcconstructor(J, jsB_Date, jsB_new_Date, "Date", 0); /* 1 */
{
jsB_propf(J, "Date.parse", D_parse, 1);
jsB_propf(J, "Date.UTC", D_UTC, 7);
/* ES5 */
jsB_propf(J, "Date.now", D_now, 0);
}
js_defglobal(J, "Date", JS_DONTENUM);
}

View File

@ -1,747 +0,0 @@
/* Locale-independent implementations of string <-> double conversions. */
#include "jsi.h"
#if defined(_MSC_VER) && (_MSC_VER < 1700) /* VS2012 has stdint.h */
typedef unsigned int uint32_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endif
#include <errno.h>
#include <assert.h>
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
/*
* format exponent like sprintf(p, "e%+d", e)
*/
void
js_fmtexp(char *p, int e)
{
char se[9];
int i;
*p++ = 'e';
if(e < 0) {
*p++ = '-';
e = -e;
} else
*p++ = '+';
i = 0;
while(e) {
se[i++] = e % 10 + '0';
e /= 10;
}
while(i < 1)
se[i++] = '0';
while(i > 0)
*p++ = se[--i];
*p++ = '\0';
}
/*
* grisu2_59_56.c
*
* Grisu prints the optimal decimal representation of floating-point numbers.
*
* Copyright (c) 2009 Florian Loitsch
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
typedef struct diy_fp_t {
uint64_t f;
int e;
} diy_fp_t;
#define DIY_SIGNIFICAND_SIZE 64
#define D_1_LOG2_10 0.30102999566398114 /* 1 / lg(10) */
static const uint64_t powers_ten[] = {
0xbf29dcaba82fdeae, 0xeef453d6923bd65a, 0x9558b4661b6565f8,
0xbaaee17fa23ebf76, 0xe95a99df8ace6f54, 0x91d8a02bb6c10594,
0xb64ec836a47146fa, 0xe3e27a444d8d98b8, 0x8e6d8c6ab0787f73,
0xb208ef855c969f50, 0xde8b2b66b3bc4724, 0x8b16fb203055ac76,
0xaddcb9e83c6b1794, 0xd953e8624b85dd79, 0x87d4713d6f33aa6c,
0xa9c98d8ccb009506, 0xd43bf0effdc0ba48, 0x84a57695fe98746d,
0xa5ced43b7e3e9188, 0xcf42894a5dce35ea, 0x818995ce7aa0e1b2,
0xa1ebfb4219491a1f, 0xca66fa129f9b60a7, 0xfd00b897478238d1,
0x9e20735e8cb16382, 0xc5a890362fddbc63, 0xf712b443bbd52b7c,
0x9a6bb0aa55653b2d, 0xc1069cd4eabe89f9, 0xf148440a256e2c77,
0x96cd2a865764dbca, 0xbc807527ed3e12bd, 0xeba09271e88d976c,
0x93445b8731587ea3, 0xb8157268fdae9e4c, 0xe61acf033d1a45df,
0x8fd0c16206306bac, 0xb3c4f1ba87bc8697, 0xe0b62e2929aba83c,
0x8c71dcd9ba0b4926, 0xaf8e5410288e1b6f, 0xdb71e91432b1a24b,
0x892731ac9faf056f, 0xab70fe17c79ac6ca, 0xd64d3d9db981787d,
0x85f0468293f0eb4e, 0xa76c582338ed2622, 0xd1476e2c07286faa,
0x82cca4db847945ca, 0xa37fce126597973d, 0xcc5fc196fefd7d0c,
0xff77b1fcbebcdc4f, 0x9faacf3df73609b1, 0xc795830d75038c1e,
0xf97ae3d0d2446f25, 0x9becce62836ac577, 0xc2e801fb244576d5,
0xf3a20279ed56d48a, 0x9845418c345644d7, 0xbe5691ef416bd60c,
0xedec366b11c6cb8f, 0x94b3a202eb1c3f39, 0xb9e08a83a5e34f08,
0xe858ad248f5c22ca, 0x91376c36d99995be, 0xb58547448ffffb2e,
0xe2e69915b3fff9f9, 0x8dd01fad907ffc3c, 0xb1442798f49ffb4b,
0xdd95317f31c7fa1d, 0x8a7d3eef7f1cfc52, 0xad1c8eab5ee43b67,
0xd863b256369d4a41, 0x873e4f75e2224e68, 0xa90de3535aaae202,
0xd3515c2831559a83, 0x8412d9991ed58092, 0xa5178fff668ae0b6,
0xce5d73ff402d98e4, 0x80fa687f881c7f8e, 0xa139029f6a239f72,
0xc987434744ac874f, 0xfbe9141915d7a922, 0x9d71ac8fada6c9b5,
0xc4ce17b399107c23, 0xf6019da07f549b2b, 0x99c102844f94e0fb,
0xc0314325637a193a, 0xf03d93eebc589f88, 0x96267c7535b763b5,
0xbbb01b9283253ca3, 0xea9c227723ee8bcb, 0x92a1958a7675175f,
0xb749faed14125d37, 0xe51c79a85916f485, 0x8f31cc0937ae58d3,
0xb2fe3f0b8599ef08, 0xdfbdcece67006ac9, 0x8bd6a141006042be,
0xaecc49914078536d, 0xda7f5bf590966849, 0x888f99797a5e012d,
0xaab37fd7d8f58179, 0xd5605fcdcf32e1d7, 0x855c3be0a17fcd26,
0xa6b34ad8c9dfc070, 0xd0601d8efc57b08c, 0x823c12795db6ce57,
0xa2cb1717b52481ed, 0xcb7ddcdda26da269, 0xfe5d54150b090b03,
0x9efa548d26e5a6e2, 0xc6b8e9b0709f109a, 0xf867241c8cc6d4c1,
0x9b407691d7fc44f8, 0xc21094364dfb5637, 0xf294b943e17a2bc4,
0x979cf3ca6cec5b5b, 0xbd8430bd08277231, 0xece53cec4a314ebe,
0x940f4613ae5ed137, 0xb913179899f68584, 0xe757dd7ec07426e5,
0x9096ea6f3848984f, 0xb4bca50b065abe63, 0xe1ebce4dc7f16dfc,
0x8d3360f09cf6e4bd, 0xb080392cc4349ded, 0xdca04777f541c568,
0x89e42caaf9491b61, 0xac5d37d5b79b6239, 0xd77485cb25823ac7,
0x86a8d39ef77164bd, 0xa8530886b54dbdec, 0xd267caa862a12d67,
0x8380dea93da4bc60, 0xa46116538d0deb78, 0xcd795be870516656,
0x806bd9714632dff6, 0xa086cfcd97bf97f4, 0xc8a883c0fdaf7df0,
0xfad2a4b13d1b5d6c, 0x9cc3a6eec6311a64, 0xc3f490aa77bd60fd,
0xf4f1b4d515acb93c, 0x991711052d8bf3c5, 0xbf5cd54678eef0b7,
0xef340a98172aace5, 0x9580869f0e7aac0f, 0xbae0a846d2195713,
0xe998d258869facd7, 0x91ff83775423cc06, 0xb67f6455292cbf08,
0xe41f3d6a7377eeca, 0x8e938662882af53e, 0xb23867fb2a35b28e,
0xdec681f9f4c31f31, 0x8b3c113c38f9f37f, 0xae0b158b4738705f,
0xd98ddaee19068c76, 0x87f8a8d4cfa417ca, 0xa9f6d30a038d1dbc,
0xd47487cc8470652b, 0x84c8d4dfd2c63f3b, 0xa5fb0a17c777cf0a,
0xcf79cc9db955c2cc, 0x81ac1fe293d599c0, 0xa21727db38cb0030,
0xca9cf1d206fdc03c, 0xfd442e4688bd304b, 0x9e4a9cec15763e2f,
0xc5dd44271ad3cdba, 0xf7549530e188c129, 0x9a94dd3e8cf578ba,
0xc13a148e3032d6e8, 0xf18899b1bc3f8ca2, 0x96f5600f15a7b7e5,
0xbcb2b812db11a5de, 0xebdf661791d60f56, 0x936b9fcebb25c996,
0xb84687c269ef3bfb, 0xe65829b3046b0afa, 0x8ff71a0fe2c2e6dc,
0xb3f4e093db73a093, 0xe0f218b8d25088b8, 0x8c974f7383725573,
0xafbd2350644eead0, 0xdbac6c247d62a584, 0x894bc396ce5da772,
0xab9eb47c81f5114f, 0xd686619ba27255a3, 0x8613fd0145877586,
0xa798fc4196e952e7, 0xd17f3b51fca3a7a1, 0x82ef85133de648c5,
0xa3ab66580d5fdaf6, 0xcc963fee10b7d1b3, 0xffbbcfe994e5c620,
0x9fd561f1fd0f9bd4, 0xc7caba6e7c5382c9, 0xf9bd690a1b68637b,
0x9c1661a651213e2d, 0xc31bfa0fe5698db8, 0xf3e2f893dec3f126,
0x986ddb5c6b3a76b8, 0xbe89523386091466, 0xee2ba6c0678b597f,
0x94db483840b717f0, 0xba121a4650e4ddec, 0xe896a0d7e51e1566,
0x915e2486ef32cd60, 0xb5b5ada8aaff80b8, 0xe3231912d5bf60e6,
0x8df5efabc5979c90, 0xb1736b96b6fd83b4, 0xddd0467c64bce4a1,
0x8aa22c0dbef60ee4, 0xad4ab7112eb3929e, 0xd89d64d57a607745,
0x87625f056c7c4a8b, 0xa93af6c6c79b5d2e, 0xd389b47879823479,
0x843610cb4bf160cc, 0xa54394fe1eedb8ff, 0xce947a3da6a9273e,
0x811ccc668829b887, 0xa163ff802a3426a9, 0xc9bcff6034c13053,
0xfc2c3f3841f17c68, 0x9d9ba7832936edc1, 0xc5029163f384a931,
0xf64335bcf065d37d, 0x99ea0196163fa42e, 0xc06481fb9bcf8d3a,
0xf07da27a82c37088, 0x964e858c91ba2655, 0xbbe226efb628afeb,
0xeadab0aba3b2dbe5, 0x92c8ae6b464fc96f, 0xb77ada0617e3bbcb,
0xe55990879ddcaabe, 0x8f57fa54c2a9eab7, 0xb32df8e9f3546564,
0xdff9772470297ebd, 0x8bfbea76c619ef36, 0xaefae51477a06b04,
0xdab99e59958885c5, 0x88b402f7fd75539b, 0xaae103b5fcd2a882,
0xd59944a37c0752a2, 0x857fcae62d8493a5, 0xa6dfbd9fb8e5b88f,
0xd097ad07a71f26b2, 0x825ecc24c8737830, 0xa2f67f2dfa90563b,
0xcbb41ef979346bca, 0xfea126b7d78186bd, 0x9f24b832e6b0f436,
0xc6ede63fa05d3144, 0xf8a95fcf88747d94, 0x9b69dbe1b548ce7d,
0xc24452da229b021c, 0xf2d56790ab41c2a3, 0x97c560ba6b0919a6,
0xbdb6b8e905cb600f, 0xed246723473e3813, 0x9436c0760c86e30c,
0xb94470938fa89bcf, 0xe7958cb87392c2c3, 0x90bd77f3483bb9ba,
0xb4ecd5f01a4aa828, 0xe2280b6c20dd5232, 0x8d590723948a535f,
0xb0af48ec79ace837, 0xdcdb1b2798182245, 0x8a08f0f8bf0f156b,
0xac8b2d36eed2dac6, 0xd7adf884aa879177, 0x86ccbb52ea94baeb,
0xa87fea27a539e9a5, 0xd29fe4b18e88640f, 0x83a3eeeef9153e89,
0xa48ceaaab75a8e2b, 0xcdb02555653131b6, 0x808e17555f3ebf12,
0xa0b19d2ab70e6ed6, 0xc8de047564d20a8c, 0xfb158592be068d2f,
0x9ced737bb6c4183d, 0xc428d05aa4751e4d, 0xf53304714d9265e0,
0x993fe2c6d07b7fac, 0xbf8fdb78849a5f97, 0xef73d256a5c0f77d,
0x95a8637627989aae, 0xbb127c53b17ec159, 0xe9d71b689dde71b0,
0x9226712162ab070e, 0xb6b00d69bb55c8d1, 0xe45c10c42a2b3b06,
0x8eb98a7a9a5b04e3, 0xb267ed1940f1c61c, 0xdf01e85f912e37a3,
0x8b61313bbabce2c6, 0xae397d8aa96c1b78, 0xd9c7dced53c72256,
0x881cea14545c7575, 0xaa242499697392d3, 0xd4ad2dbfc3d07788,
0x84ec3c97da624ab5, 0xa6274bbdd0fadd62, 0xcfb11ead453994ba,
0x81ceb32c4b43fcf5, 0xa2425ff75e14fc32, 0xcad2f7f5359a3b3e,
0xfd87b5f28300ca0e, 0x9e74d1b791e07e48, 0xc612062576589ddb,
0xf79687aed3eec551, 0x9abe14cd44753b53, 0xc16d9a0095928a27,
0xf1c90080baf72cb1, 0x971da05074da7bef, 0xbce5086492111aeb,
0xec1e4a7db69561a5, 0x9392ee8e921d5d07, 0xb877aa3236a4b449,
0xe69594bec44de15b, 0x901d7cf73ab0acd9, 0xb424dc35095cd80f,
0xe12e13424bb40e13, 0x8cbccc096f5088cc, 0xafebff0bcb24aaff,
0xdbe6fecebdedd5bf, 0x89705f4136b4a597, 0xabcc77118461cefd,
0xd6bf94d5e57a42bc, 0x8637bd05af6c69b6, 0xa7c5ac471b478423,
0xd1b71758e219652c, 0x83126e978d4fdf3b, 0xa3d70a3d70a3d70a,
0xcccccccccccccccd, 0x8000000000000000, 0xa000000000000000,
0xc800000000000000, 0xfa00000000000000, 0x9c40000000000000,
0xc350000000000000, 0xf424000000000000, 0x9896800000000000,
0xbebc200000000000, 0xee6b280000000000, 0x9502f90000000000,
0xba43b74000000000, 0xe8d4a51000000000, 0x9184e72a00000000,
0xb5e620f480000000, 0xe35fa931a0000000, 0x8e1bc9bf04000000,
0xb1a2bc2ec5000000, 0xde0b6b3a76400000, 0x8ac7230489e80000,
0xad78ebc5ac620000, 0xd8d726b7177a8000, 0x878678326eac9000,
0xa968163f0a57b400, 0xd3c21bcecceda100, 0x84595161401484a0,
0xa56fa5b99019a5c8, 0xcecb8f27f4200f3a, 0x813f3978f8940984,
0xa18f07d736b90be5, 0xc9f2c9cd04674edf, 0xfc6f7c4045812296,
0x9dc5ada82b70b59e, 0xc5371912364ce305, 0xf684df56c3e01bc7,
0x9a130b963a6c115c, 0xc097ce7bc90715b3, 0xf0bdc21abb48db20,
0x96769950b50d88f4, 0xbc143fa4e250eb31, 0xeb194f8e1ae525fd,
0x92efd1b8d0cf37be, 0xb7abc627050305ae, 0xe596b7b0c643c719,
0x8f7e32ce7bea5c70, 0xb35dbf821ae4f38c, 0xe0352f62a19e306f,
0x8c213d9da502de45, 0xaf298d050e4395d7, 0xdaf3f04651d47b4c,
0x88d8762bf324cd10, 0xab0e93b6efee0054, 0xd5d238a4abe98068,
0x85a36366eb71f041, 0xa70c3c40a64e6c52, 0xd0cf4b50cfe20766,
0x82818f1281ed44a0, 0xa321f2d7226895c8, 0xcbea6f8ceb02bb3a,
0xfee50b7025c36a08, 0x9f4f2726179a2245, 0xc722f0ef9d80aad6,
0xf8ebad2b84e0d58c, 0x9b934c3b330c8577, 0xc2781f49ffcfa6d5,
0xf316271c7fc3908b, 0x97edd871cfda3a57, 0xbde94e8e43d0c8ec,
0xed63a231d4c4fb27, 0x945e455f24fb1cf9, 0xb975d6b6ee39e437,
0xe7d34c64a9c85d44, 0x90e40fbeea1d3a4b, 0xb51d13aea4a488dd,
0xe264589a4dcdab15, 0x8d7eb76070a08aed, 0xb0de65388cc8ada8,
0xdd15fe86affad912, 0x8a2dbf142dfcc7ab, 0xacb92ed9397bf996,
0xd7e77a8f87daf7fc, 0x86f0ac99b4e8dafd, 0xa8acd7c0222311bd,
0xd2d80db02aabd62c, 0x83c7088e1aab65db, 0xa4b8cab1a1563f52,
0xcde6fd5e09abcf27, 0x80b05e5ac60b6178, 0xa0dc75f1778e39d6,
0xc913936dd571c84c, 0xfb5878494ace3a5f, 0x9d174b2dcec0e47b,
0xc45d1df942711d9a, 0xf5746577930d6501, 0x9968bf6abbe85f20,
0xbfc2ef456ae276e9, 0xefb3ab16c59b14a3, 0x95d04aee3b80ece6,
0xbb445da9ca61281f, 0xea1575143cf97227, 0x924d692ca61be758,
0xb6e0c377cfa2e12e, 0xe498f455c38b997a, 0x8edf98b59a373fec,
0xb2977ee300c50fe7, 0xdf3d5e9bc0f653e1, 0x8b865b215899f46d,
0xae67f1e9aec07188, 0xda01ee641a708dea, 0x884134fe908658b2,
0xaa51823e34a7eedf, 0xd4e5e2cdc1d1ea96, 0x850fadc09923329e,
0xa6539930bf6bff46, 0xcfe87f7cef46ff17, 0x81f14fae158c5f6e,
0xa26da3999aef774a, 0xcb090c8001ab551c, 0xfdcb4fa002162a63,
0x9e9f11c4014dda7e, 0xc646d63501a1511e, 0xf7d88bc24209a565,
0x9ae757596946075f, 0xc1a12d2fc3978937, 0xf209787bb47d6b85,
0x9745eb4d50ce6333, 0xbd176620a501fc00, 0xec5d3fa8ce427b00,
0x93ba47c980e98ce0, 0xb8a8d9bbe123f018, 0xe6d3102ad96cec1e,
0x9043ea1ac7e41393, 0xb454e4a179dd1877, 0xe16a1dc9d8545e95,
0x8ce2529e2734bb1d, 0xb01ae745b101e9e4, 0xdc21a1171d42645d,
0x899504ae72497eba, 0xabfa45da0edbde69, 0xd6f8d7509292d603,
0x865b86925b9bc5c2, 0xa7f26836f282b733, 0xd1ef0244af2364ff,
0x8335616aed761f1f, 0xa402b9c5a8d3a6e7, 0xcd036837130890a1,
0x802221226be55a65, 0xa02aa96b06deb0fe, 0xc83553c5c8965d3d,
0xfa42a8b73abbf48d, 0x9c69a97284b578d8, 0xc38413cf25e2d70e,
0xf46518c2ef5b8cd1, 0x98bf2f79d5993803, 0xbeeefb584aff8604,
0xeeaaba2e5dbf6785, 0x952ab45cfa97a0b3, 0xba756174393d88e0,
0xe912b9d1478ceb17, 0x91abb422ccb812ef, 0xb616a12b7fe617aa,
0xe39c49765fdf9d95, 0x8e41ade9fbebc27d, 0xb1d219647ae6b31c,
0xde469fbd99a05fe3, 0x8aec23d680043bee, 0xada72ccc20054aea,
0xd910f7ff28069da4, 0x87aa9aff79042287, 0xa99541bf57452b28,
0xd3fa922f2d1675f2, 0x847c9b5d7c2e09b7, 0xa59bc234db398c25,
0xcf02b2c21207ef2f, 0x8161afb94b44f57d, 0xa1ba1ba79e1632dc,
0xca28a291859bbf93, 0xfcb2cb35e702af78, 0x9defbf01b061adab,
0xc56baec21c7a1916, 0xf6c69a72a3989f5c, 0x9a3c2087a63f6399,
0xc0cb28a98fcf3c80, 0xf0fdf2d3f3c30b9f, 0x969eb7c47859e744,
0xbc4665b596706115, 0xeb57ff22fc0c795a, 0x9316ff75dd87cbd8,
0xb7dcbf5354e9bece, 0xe5d3ef282a242e82, 0x8fa475791a569d11,
0xb38d92d760ec4455, 0xe070f78d3927556b, 0x8c469ab843b89563,
0xaf58416654a6babb, 0xdb2e51bfe9d0696a, 0x88fcf317f22241e2,
0xab3c2fddeeaad25b, 0xd60b3bd56a5586f2, 0x85c7056562757457,
0xa738c6bebb12d16d, 0xd106f86e69d785c8, 0x82a45b450226b39d,
0xa34d721642b06084, 0xcc20ce9bd35c78a5, 0xff290242c83396ce,
0x9f79a169bd203e41, 0xc75809c42c684dd1, 0xf92e0c3537826146,
0x9bbcc7a142b17ccc, 0xc2abf989935ddbfe, 0xf356f7ebf83552fe,
0x98165af37b2153df, 0xbe1bf1b059e9a8d6, 0xeda2ee1c7064130c,
0x9485d4d1c63e8be8, 0xb9a74a0637ce2ee1, 0xe8111c87c5c1ba9a,
0x910ab1d4db9914a0, 0xb54d5e4a127f59c8, 0xe2a0b5dc971f303a,
0x8da471a9de737e24, 0xb10d8e1456105dad, 0xdd50f1996b947519,
0x8a5296ffe33cc930, 0xace73cbfdc0bfb7b, 0xd8210befd30efa5a,
0x8714a775e3e95c78, 0xa8d9d1535ce3b396, 0xd31045a8341ca07c,
0x83ea2b892091e44e, 0xa4e4b66b68b65d61, 0xce1de40642e3f4b9,
0x80d2ae83e9ce78f4, 0xa1075a24e4421731, 0xc94930ae1d529cfd,
0xfb9b7cd9a4a7443c, 0x9d412e0806e88aa6, 0xc491798a08a2ad4f,
0xf5b5d7ec8acb58a3, 0x9991a6f3d6bf1766, 0xbff610b0cc6edd3f,
0xeff394dcff8a948f, 0x95f83d0a1fb69cd9, 0xbb764c4ca7a44410,
0xea53df5fd18d5514, 0x92746b9be2f8552c, 0xb7118682dbb66a77,
0xe4d5e82392a40515, 0x8f05b1163ba6832d, 0xb2c71d5bca9023f8,
0xdf78e4b2bd342cf7, 0x8bab8eefb6409c1a, 0xae9672aba3d0c321,
0xda3c0f568cc4f3e9, 0x8865899617fb1871, 0xaa7eebfb9df9de8e,
0xd51ea6fa85785631, 0x8533285c936b35df, 0xa67ff273b8460357,
0xd01fef10a657842c, 0x8213f56a67f6b29c, 0xa298f2c501f45f43,
0xcb3f2f7642717713, 0xfe0efb53d30dd4d8, 0x9ec95d1463e8a507,
0xc67bb4597ce2ce49, 0xf81aa16fdc1b81db, 0x9b10a4e5e9913129,
0xc1d4ce1f63f57d73, 0xf24a01a73cf2dcd0, 0x976e41088617ca02,
0xbd49d14aa79dbc82, 0xec9c459d51852ba3, 0x93e1ab8252f33b46,
0xb8da1662e7b00a17, 0xe7109bfba19c0c9d, 0x906a617d450187e2,
0xb484f9dc9641e9db, 0xe1a63853bbd26451, 0x8d07e33455637eb3,
0xb049dc016abc5e60, 0xdc5c5301c56b75f7, 0x89b9b3e11b6329bb,
0xac2820d9623bf429, 0xd732290fbacaf134, 0x867f59a9d4bed6c0,
0xa81f301449ee8c70, 0xd226fc195c6a2f8c, 0x83585d8fd9c25db8,
0xa42e74f3d032f526, 0xcd3a1230c43fb26f, 0x80444b5e7aa7cf85,
0xa0555e361951c367, 0xc86ab5c39fa63441, 0xfa856334878fc151,
0x9c935e00d4b9d8d2, 0xc3b8358109e84f07, 0xf4a642e14c6262c9,
0x98e7e9cccfbd7dbe, 0xbf21e44003acdd2d, 0xeeea5d5004981478,
0x95527a5202df0ccb, 0xbaa718e68396cffe, 0xe950df20247c83fd,
0x91d28b7416cdd27e, 0xb6472e511c81471e, 0xe3d8f9e563a198e5,
0x8e679c2f5e44ff8f, 0xb201833b35d63f73, 0xde81e40a034bcf50,
0x8b112e86420f6192, 0xadd57a27d29339f6, 0xd94ad8b1c7380874,
0x87cec76f1c830549, 0xa9c2794ae3a3c69b, 0xd433179d9c8cb841,
0x849feec281d7f329, 0xa5c7ea73224deff3, 0xcf39e50feae16bf0,
0x81842f29f2cce376, 0xa1e53af46f801c53, 0xca5e89b18b602368,
0xfcf62c1dee382c42, 0x9e19db92b4e31ba9, 0xc5a05277621be294,
0xf70867153aa2db39, 0x9a65406d44a5c903, 0xc0fe908895cf3b44,
0xf13e34aabb430a15, 0x96c6e0eab509e64d, 0xbc789925624c5fe1,
0xeb96bf6ebadf77d9, 0x933e37a534cbaae8, 0xb80dc58e81fe95a1,
0xe61136f2227e3b0a, 0x8fcac257558ee4e6, 0xb3bd72ed2af29e20,
0xe0accfa875af45a8, 0x8c6c01c9498d8b89, 0xaf87023b9bf0ee6b,
0xdb68c2ca82ed2a06, 0x892179be91d43a44, 0xab69d82e364948d4
};
static const int powers_ten_e[] = {
-1203, -1200, -1196, -1193, -1190, -1186, -1183, -1180, -1176, -1173,
-1170, -1166, -1163, -1160, -1156, -1153, -1150, -1146, -1143, -1140,
-1136, -1133, -1130, -1127, -1123, -1120, -1117, -1113, -1110, -1107,
-1103, -1100, -1097, -1093, -1090, -1087, -1083, -1080, -1077, -1073,
-1070, -1067, -1063, -1060, -1057, -1053, -1050, -1047, -1043, -1040,
-1037, -1034, -1030, -1027, -1024, -1020, -1017, -1014, -1010, -1007,
-1004, -1000, -997, -994, -990, -987, -984, -980, -977, -974, -970,
-967, -964, -960, -957, -954, -950, -947, -944, -940, -937, -934, -931,
-927, -924, -921, -917, -914, -911, -907, -904, -901, -897, -894, -891,
-887, -884, -881, -877, -874, -871, -867, -864, -861, -857, -854, -851,
-847, -844, -841, -838, -834, -831, -828, -824, -821, -818, -814, -811,
-808, -804, -801, -798, -794, -791, -788, -784, -781, -778, -774, -771,
-768, -764, -761, -758, -754, -751, -748, -744, -741, -738, -735, -731,
-728, -725, -721, -718, -715, -711, -708, -705, -701, -698, -695, -691,
-688, -685, -681, -678, -675, -671, -668, -665, -661, -658, -655, -651,
-648, -645, -642, -638, -635, -632, -628, -625, -622, -618, -615, -612,
-608, -605, -602, -598, -595, -592, -588, -585, -582, -578, -575, -572,
-568, -565, -562, -558, -555, -552, -549, -545, -542, -539, -535, -532,
-529, -525, -522, -519, -515, -512, -509, -505, -502, -499, -495, -492,
-489, -485, -482, -479, -475, -472, -469, -465, -462, -459, -455, -452,
-449, -446, -442, -439, -436, -432, -429, -426, -422, -419, -416, -412,
-409, -406, -402, -399, -396, -392, -389, -386, -382, -379, -376, -372,
-369, -366, -362, -359, -356, -353, -349, -346, -343, -339, -336, -333,
-329, -326, -323, -319, -316, -313, -309, -306, -303, -299, -296, -293,
-289, -286, -283, -279, -276, -273, -269, -266, -263, -259, -256, -253,
-250, -246, -243, -240, -236, -233, -230, -226, -223, -220, -216, -213,
-210, -206, -203, -200, -196, -193, -190, -186, -183, -180, -176, -173,
-170, -166, -163, -160, -157, -153, -150, -147, -143, -140, -137, -133,
-130, -127, -123, -120, -117, -113, -110, -107, -103, -100, -97, -93,
-90, -87, -83, -80, -77, -73, -70, -67, -63, -60, -57, -54, -50, -47,
-44, -40, -37, -34, -30, -27, -24, -20, -17, -14, -10, -7, -4, 0, 3, 6,
10, 13, 16, 20, 23, 26, 30, 33, 36, 39, 43, 46, 49, 53, 56, 59, 63, 66,
69, 73, 76, 79, 83, 86, 89, 93, 96, 99, 103, 106, 109, 113, 116, 119,
123, 126, 129, 132, 136, 139, 142, 146, 149, 152, 156, 159, 162, 166,
169, 172, 176, 179, 182, 186, 189, 192, 196, 199, 202, 206, 209, 212,
216, 219, 222, 226, 229, 232, 235, 239, 242, 245, 249, 252, 255, 259,
262, 265, 269, 272, 275, 279, 282, 285, 289, 292, 295, 299, 302, 305,
309, 312, 315, 319, 322, 325, 328, 332, 335, 338, 342, 345, 348, 352,
355, 358, 362, 365, 368, 372, 375, 378, 382, 385, 388, 392, 395, 398,
402, 405, 408, 412, 415, 418, 422, 425, 428, 431, 435, 438, 441, 445,
448, 451, 455, 458, 461, 465, 468, 471, 475, 478, 481, 485, 488, 491,
495, 498, 501, 505, 508, 511, 515, 518, 521, 524, 528, 531, 534, 538,
541, 544, 548, 551, 554, 558, 561, 564, 568, 571, 574, 578, 581, 584,
588, 591, 594, 598, 601, 604, 608, 611, 614, 617, 621, 624, 627, 631,
634, 637, 641, 644, 647, 651, 654, 657, 661, 664, 667, 671, 674, 677,
681, 684, 687, 691, 694, 697, 701, 704, 707, 711, 714, 717, 720, 724,
727, 730, 734, 737, 740, 744, 747, 750, 754, 757, 760, 764, 767, 770,
774, 777, 780, 784, 787, 790, 794, 797, 800, 804, 807, 810, 813, 817,
820, 823, 827, 830, 833, 837, 840, 843, 847, 850, 853, 857, 860, 863,
867, 870, 873, 877, 880, 883, 887, 890, 893, 897, 900, 903, 907, 910,
913, 916, 920, 923, 926, 930, 933, 936, 940, 943, 946, 950, 953, 956,
960, 963, 966, 970, 973, 976, 980, 983, 986, 990, 993, 996, 1000, 1003,
1006, 1009, 1013, 1016, 1019, 1023, 1026, 1029, 1033, 1036, 1039, 1043,
1046, 1049, 1053, 1056, 1059, 1063, 1066, 1069, 1073, 1076
};
static diy_fp_t cached_power(int k)
{
diy_fp_t res;
int index = 343 + k;
res.f = powers_ten[index];
res.e = powers_ten_e[index];
return res;
}
static int k_comp(int e, int alpha, int gamma) {
return ceil((alpha-e+63) * D_1_LOG2_10);
}
static diy_fp_t minus(diy_fp_t x, diy_fp_t y)
{
diy_fp_t r;
assert(x.e == y.e);
assert(x.f >= y.f);
r.f = x.f - y.f;
r.e = x.e;
return r;
}
static diy_fp_t multiply(diy_fp_t x, diy_fp_t y)
{
uint64_t a,b,c,d,ac,bc,ad,bd,tmp;
diy_fp_t r;
uint64_t M32 = 0xFFFFFFFF;
a = x.f >> 32; b = x.f & M32;
c = y.f >> 32; d = y.f & M32;
ac = a*c; bc = b*c; ad = a*d; bd = b*d;
tmp = (bd>>32) + (ad&M32) + (bc&M32);
tmp += 1U << 31;
r.f = ac+(ad>>32)+(bc>>32)+(tmp >>32);
r.e = x.e + y.e + 64;
return r;
}
static uint64_t double_to_uint64(double d)
{
uint64_t n;
memcpy(&n, &d, 8);
return n;
}
#define DP_SIGNIFICAND_SIZE 52
#define DP_EXPONENT_BIAS (0x3FF + DP_SIGNIFICAND_SIZE)
#define DP_MIN_EXPONENT (-DP_EXPONENT_BIAS)
#define DP_EXPONENT_MASK 0x7FF0000000000000
#define DP_SIGNIFICAND_MASK 0x000FFFFFFFFFFFFF
#define DP_HIDDEN_BIT 0x0010000000000000
static diy_fp_t double2diy_fp(double d)
{
uint64_t d64 = double_to_uint64(d);
int biased_e = (d64 & DP_EXPONENT_MASK) >> DP_SIGNIFICAND_SIZE;
uint64_t significand = (d64 & DP_SIGNIFICAND_MASK);
diy_fp_t res;
if (biased_e != 0) {
res.f = significand + DP_HIDDEN_BIT;
res.e = biased_e - DP_EXPONENT_BIAS;
} else {
res.f = significand;
res.e = DP_MIN_EXPONENT + 1;
}
return res;
}
static diy_fp_t normalize_boundary(diy_fp_t in)
{
diy_fp_t res = in;
/* Normalize now */
/* the original number could have been a denormal. */
while (! (res.f & (DP_HIDDEN_BIT << 1))) {
res.f <<= 1;
res.e--;
}
/* do the final shifts in one go. Don't forget the hidden bit (the '-1') */
res.f <<= (DIY_SIGNIFICAND_SIZE - DP_SIGNIFICAND_SIZE - 2);
res.e = res.e - (DIY_SIGNIFICAND_SIZE - DP_SIGNIFICAND_SIZE - 2);
return res;
}
static void normalized_boundaries(double d, diy_fp_t* out_m_minus, diy_fp_t* out_m_plus)
{
diy_fp_t v = double2diy_fp(d);
diy_fp_t pl, mi;
int significand_is_zero = v.f == DP_HIDDEN_BIT;
pl.f = (v.f << 1) + 1; pl.e = v.e - 1;
pl = normalize_boundary(pl);
if (significand_is_zero) {
mi.f = (v.f << 2) - 1;
mi.e = v.e - 2;
} else {
mi.f = (v.f << 1) - 1;
mi.e = v.e - 1;
}
mi.f <<= mi.e - pl.e;
mi.e = pl.e;
*out_m_plus = pl;
*out_m_minus = mi;
}
#define TEN2 100
static void digit_gen(diy_fp_t Mp, diy_fp_t delta, char* buffer, int* len, int* K)
{
uint32_t div, p1;
uint64_t p2;
int d,kappa;
diy_fp_t one;
one.f = ((uint64_t) 1) << -Mp.e; one.e = Mp.e;
p1 = Mp.f >> -one.e;
p2 = Mp.f & (one.f - 1);
*len = 0; kappa = 3; div = TEN2;
while (kappa > 0) {
d = p1 / div;
if (d || *len) buffer[(*len)++] = '0' + d;
p1 %= div; kappa--; div /= 10;
if ((((uint64_t)p1)<<-one.e)+p2 <= delta.f) {
*K += kappa; return;
}
}
do {
p2 *= 10;
d = p2 >> -one.e;
if (d || *len) buffer[(*len)++] = '0' + d;
p2 &= one.f - 1; kappa--; delta.f *= 10;
} while (p2 > delta.f);
*K += kappa;
}
int
js_grisu2(double v, char *buffer, int *K)
{
int length, mk;
diy_fp_t w_m, w_p, c_mk, Wp, Wm, delta;
int q = 64, alpha = -59, gamma = -56;
normalized_boundaries(v, &w_m, &w_p);
mk = k_comp(w_p.e + q, alpha, gamma);
c_mk = cached_power(mk);
Wp = multiply(w_p, c_mk);
Wm = multiply(w_m, c_mk);
Wm.f++; Wp.f--;
delta = minus(Wp, Wm);
*K = -mk;
digit_gen(Wp, delta, buffer, &length, K);
return length;
}
/*
* strtod.c
*
* Copyright (c) 1988-1993 The Regents of the University of California.
* Copyright (c) 1994 Sun Microsystems, Inc.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted, provided
* that the above copyright notice appear in all copies. The University of
* California makes no representations about the suitability of this software
* for any purpose. It is provided "as is" without express or implied warranty.
*/
/* Largest possible base 10 exponent. Any exponent larger than this will
* already produce underflow or overflow, so there's no need to worry about
* additional digits.
*/
static int maxExponent = 511;
/* Table giving binary powers of 10. Entry
* is 10^2^i. Used to convert decimal
* exponents into floating-point numbers.
*/
static double powersOf10[] = {
10.,
100.,
1.0e4,
1.0e8,
1.0e16,
1.0e32,
1.0e64,
1.0e128,
1.0e256
};
/* Parse a decimal ASCII floating-point number, optionally preceded by white
* space. Must have form "-I.FE-X", where I is the integer part of the
* mantissa, F is the fractional part of the mantissa, and X is the exponent.
* Either of the signs may be "+", "-", or omitted. Either I or F may be
* omitted, or both. The decimal point isn't necessary unless F is present.
* The "E" may actually be an "e". E and X may both be omitted (but not just
* one).
*/
double
js_strtod(const char *string, char **endPtr)
{
int sign, expSign = FALSE;
double fraction, dblExp, *d;
register const char *p;
register int c;
/* Exponent read from "EX" field. */
int exp = 0;
/* Exponent that derives from the fractional part. Under normal
* circumstances, it is the negative of the number of digits in F.
* However, if I is very long, the last digits of I get dropped
* (otherwise a long I with a large negative exponent could cause an
* unnecessary overflow on I alone). In this case, fracExp is
* incremented one for each dropped digit.
*/
int fracExp = 0;
/* Number of digits in mantissa. */
int mantSize;
/* Number of mantissa digits BEFORE decimal point. */
int decPt;
/* Temporarily holds location of exponent in string. */
const char *pExp;
/*
* Strip off leading blanks and check for a sign.
*/
p = string;
while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r') {
p += 1;
}
if (*p == '-') {
sign = TRUE;
p += 1;
} else {
if (*p == '+') {
p += 1;
}
sign = FALSE;
}
/*
* Count the number of digits in the mantissa (including the decimal
* point), and also locate the decimal point.
*/
decPt = -1;
for (mantSize = 0; ; mantSize += 1)
{
c = *p;
if (!(c>='0'&&c<='9')) {
if ((c != '.') || (decPt >= 0)) {
break;
}
decPt = mantSize;
}
p += 1;
}
/*
* Now suck up the digits in the mantissa. Use two integers to
* collect 9 digits each (this is faster than using floating-point).
* If the mantissa has more than 18 digits, ignore the extras, since
* they can't affect the value anyway.
*/
pExp = p;
p -= mantSize;
if (decPt < 0) {
decPt = mantSize;
} else {
mantSize -= 1; /* One of the digits was the point. */
}
if (mantSize > 18) {
fracExp = decPt - 18;
mantSize = 18;
} else {
fracExp = decPt - mantSize;
}
if (mantSize == 0) {
fraction = 0.0;
p = string;
goto done;
} else {
int frac1, frac2;
frac1 = 0;
for ( ; mantSize > 9; mantSize -= 1)
{
c = *p;
p += 1;
if (c == '.') {
c = *p;
p += 1;
}
frac1 = 10*frac1 + (c - '0');
}
frac2 = 0;
for (; mantSize > 0; mantSize -= 1)
{
c = *p;
p += 1;
if (c == '.') {
c = *p;
p += 1;
}
frac2 = 10*frac2 + (c - '0');
}
fraction = (1.0e9 * frac1) + frac2;
}
/*
* Skim off the exponent.
*/
p = pExp;
if ((*p == 'E') || (*p == 'e')) {
p += 1;
if (*p == '-') {
expSign = TRUE;
p += 1;
} else {
if (*p == '+') {
p += 1;
}
expSign = FALSE;
}
while ((*p >= '0') && (*p <= '9')) {
exp = exp * 10 + (*p - '0');
p += 1;
}
}
if (expSign) {
exp = fracExp - exp;
} else {
exp = fracExp + exp;
}
/*
* Generate a floating-point number that represents the exponent.
* Do this by processing the exponent one bit at a time to combine
* many powers of 2 of 10. Then combine the exponent with the
* fraction.
*/
if (exp < -maxExponent) {
exp = maxExponent;
expSign = TRUE;
errno = ERANGE;
} else if (exp > maxExponent) {
exp = maxExponent;
expSign = FALSE;
errno = ERANGE;
} else if (exp < 0) {
expSign = TRUE;
exp = -exp;
} else {
expSign = FALSE;
}
dblExp = 1.0;
for (d = powersOf10; exp != 0; exp >>= 1, d += 1) {
if (exp & 01) {
dblExp *= *d;
}
}
if (expSign) {
fraction /= dblExp;
} else {
fraction *= dblExp;
}
done:
if (endPtr != NULL) {
*endPtr = (char *) p;
}
if (sign) {
return -fraction;
}
return fraction;
}

View File

@ -1,924 +0,0 @@
#include "jsi.h"
#include "jsparse.h"
#include "jscompile.h"
#include "jsvalue.h"
#include "utf.h"
#include <assert.h>
static const char *astname[] = {
#include "astnames.h"
NULL
};
static const char *opname[] = {
#include "opnames.h"
NULL
};
static int minify = 0;
const char *jsP_aststring(enum js_AstType type)
{
if (type < nelem(astname)-1)
return astname[type];
return "<unknown>";
}
const char *jsC_opcodestring(enum js_OpCode opcode)
{
if (opcode < nelem(opname)-1)
return opname[opcode];
return "<unknown>";
}
static int prec(enum js_AstType type)
{
switch (type) {
case AST_IDENTIFIER:
case EXP_IDENTIFIER:
case EXP_NUMBER:
case EXP_STRING:
case EXP_REGEXP:
case EXP_UNDEF:
case EXP_NULL:
case EXP_TRUE:
case EXP_FALSE:
case EXP_THIS:
case EXP_ARRAY:
case EXP_OBJECT:
return 170;
case EXP_FUN:
case EXP_INDEX:
case EXP_MEMBER:
case EXP_CALL:
case EXP_NEW:
return 160;
case EXP_POSTINC:
case EXP_POSTDEC:
return 150;
case EXP_DELETE:
case EXP_VOID:
case EXP_TYPEOF:
case EXP_PREINC:
case EXP_PREDEC:
case EXP_POS:
case EXP_NEG:
case EXP_BITNOT:
case EXP_LOGNOT:
return 140;
case EXP_MOD:
case EXP_DIV:
case EXP_MUL:
return 130;
case EXP_SUB:
case EXP_ADD:
return 120;
case EXP_USHR:
case EXP_SHR:
case EXP_SHL:
return 110;
case EXP_IN:
case EXP_INSTANCEOF:
case EXP_GE:
case EXP_LE:
case EXP_GT:
case EXP_LT:
return 100;
case EXP_STRICTNE:
case EXP_STRICTEQ:
case EXP_NE:
case EXP_EQ:
return 90;
case EXP_BITAND: return 80;
case EXP_BITXOR: return 70;
case EXP_BITOR: return 60;
case EXP_LOGAND: return 50;
case EXP_LOGOR: return 40;
case EXP_COND:
return 30;
case EXP_ASS:
case EXP_ASS_MUL:
case EXP_ASS_DIV:
case EXP_ASS_MOD:
case EXP_ASS_ADD:
case EXP_ASS_SUB:
case EXP_ASS_SHL:
case EXP_ASS_SHR:
case EXP_ASS_USHR:
case EXP_ASS_BITAND:
case EXP_ASS_BITXOR:
case EXP_ASS_BITOR:
return 20;
#define COMMA 15
case EXP_COMMA:
return 10;
default:
return 0;
}
}
static void pc(int c)
{
putchar(c);
}
static void ps(const char *s)
{
fputs(s, stdout);
}
static void pn(int n)
{
printf("%d", n);
}
static void in(int d)
{
if (minify < 1)
while (d-- > 0)
putchar('\t');
}
static void nl(void)
{
if (minify < 2)
putchar('\n');
}
static void sp(void)
{
if (minify < 1)
putchar(' ');
}
static void comma(void)
{
putchar(',');
sp();
}
/* Pretty-printed Javascript syntax */
static void pstmlist(int d, js_Ast *list);
static void pexpi(int d, int i, js_Ast *exp);
static void pstm(int d, js_Ast *stm);
static void slist(int d, js_Ast *list);
static void sblock(int d, js_Ast *list);
static void pargs(int d, js_Ast *list)
{
while (list) {
assert(list->type == AST_LIST);
pexpi(d, COMMA, list->a);
list = list->b;
if (list)
comma();
}
}
static void parray(int d, js_Ast *list)
{
pc('[');
while (list) {
assert(list->type == AST_LIST);
pexpi(d, COMMA, list->a);
list = list->b;
if (list)
comma();
}
pc(']');
}
static void pobject(int d, js_Ast *list)
{
pc('{');
if (list) {
nl();
in(d+1);
}
while (list) {
js_Ast *kv = list->a;
assert(list->type == AST_LIST);
switch (kv->type) {
default: break;
case EXP_PROP_VAL:
pexpi(d+1, COMMA, kv->a);
pc(':'); sp();
pexpi(d+1, COMMA, kv->b);
break;
case EXP_PROP_GET:
ps("get ");
pexpi(d+1, COMMA, kv->a);
ps("()"); sp(); pc('{'); nl();
pstmlist(d+1, kv->c);
in(d+1); pc('}');
break;
case EXP_PROP_SET:
ps("set ");
pexpi(d+1, COMMA, kv->a);
pc('(');
pargs(d+1, kv->b);
pc(')'); sp(); pc('{'); nl();
pstmlist(d+1, kv->c);
in(d+1); pc('}');
break;
}
list = list->b;
if (list) {
pc(',');
nl();
in(d+1);
} else {
nl();
in(d);
}
}
pc('}');
}
static void pstr(const char *s)
{
static const char *HEX = "0123456789ABCDEF";
Rune c;
pc(minify ? '\'' : '"');
while (*s) {
s += chartorune(&c, s);
switch (c) {
case '\'': ps("\\'"); break;
case '"': ps("\\\""); break;
case '\\': ps("\\\\"); break;
case '\b': ps("\\b"); break;
case '\f': ps("\\f"); break;
case '\n': ps("\\n"); break;
case '\r': ps("\\r"); break;
case '\t': ps("\\t"); break;
default:
if (c < ' ' || c > 127) {
ps("\\u");
pc(HEX[(c>>12)&15]);
pc(HEX[(c>>8)&15]);
pc(HEX[(c>>4)&15]);
pc(HEX[c&15]);
} else {
pc(c); break;
}
}
}
pc(minify ? '\'' : '"');
}
static void pregexp(const char *prog, int flags)
{
pc('/');
ps(prog);
pc('/');
if (flags & JS_REGEXP_G) pc('g');
if (flags & JS_REGEXP_I) pc('i');
if (flags & JS_REGEXP_M) pc('m');
}
static void pbin(int d, int p, js_Ast *exp, const char *op)
{
pexpi(d, p, exp->a);
sp();
ps(op);
sp();
pexpi(d, p, exp->b);
}
static void puna(int d, int p, js_Ast *exp, const char *pre, const char *suf)
{
ps(pre);
pexpi(d, p, exp->a);
ps(suf);
}
static void pexpi(int d, int p, js_Ast *exp)
{
int tp, paren;
if (!exp) return;
tp = prec(exp->type);
paren = 0;
if (tp < p) {
pc('(');
paren = 1;
}
p = tp;
switch (exp->type) {
case AST_IDENTIFIER: ps(exp->string); break;
case EXP_IDENTIFIER: ps(exp->string); break;
case EXP_NUMBER: printf("%.9g", exp->number); break;
case EXP_STRING: pstr(exp->string); break;
case EXP_REGEXP: pregexp(exp->string, exp->number); break;
case EXP_UNDEF: break;
case EXP_NULL: ps("null"); break;
case EXP_TRUE: ps("true"); break;
case EXP_FALSE: ps("false"); break;
case EXP_THIS: ps("this"); break;
case EXP_OBJECT: pobject(d, exp->a); break;
case EXP_ARRAY: parray(d, exp->a); break;
case EXP_DELETE: puna(d, p, exp, "delete ", ""); break;
case EXP_VOID: puna(d, p, exp, "void ", ""); break;
case EXP_TYPEOF: puna(d, p, exp, "typeof ", ""); break;
case EXP_PREINC: puna(d, p, exp, "++", ""); break;
case EXP_PREDEC: puna(d, p, exp, "--", ""); break;
case EXP_POSTINC: puna(d, p, exp, "", "++"); break;
case EXP_POSTDEC: puna(d, p, exp, "", "--"); break;
case EXP_POS: puna(d, p, exp, "+", ""); break;
case EXP_NEG: puna(d, p, exp, "-", ""); break;
case EXP_BITNOT: puna(d, p, exp, "~", ""); break;
case EXP_LOGNOT: puna(d, p, exp, "!", ""); break;
case EXP_LOGOR: pbin(d, p, exp, "||"); break;
case EXP_LOGAND: pbin(d, p, exp, "&&"); break;
case EXP_BITOR: pbin(d, p, exp, "|"); break;
case EXP_BITXOR: pbin(d, p, exp, "^"); break;
case EXP_BITAND: pbin(d, p, exp, "&"); break;
case EXP_EQ: pbin(d, p, exp, "=="); break;
case EXP_NE: pbin(d, p, exp, "!="); break;
case EXP_STRICTEQ: pbin(d, p, exp, "==="); break;
case EXP_STRICTNE: pbin(d, p, exp, "!=="); break;
case EXP_LT: pbin(d, p, exp, "<"); break;
case EXP_GT: pbin(d, p, exp, ">"); break;
case EXP_LE: pbin(d, p, exp, "<="); break;
case EXP_GE: pbin(d, p, exp, ">="); break;
case EXP_IN: pbin(d, p, exp, "in"); break;
case EXP_SHL: pbin(d, p, exp, "<<"); break;
case EXP_SHR: pbin(d, p, exp, ">>"); break;
case EXP_USHR: pbin(d, p, exp, ">>>"); break;
case EXP_ADD: pbin(d, p, exp, "+"); break;
case EXP_SUB: pbin(d, p, exp, "-"); break;
case EXP_MUL: pbin(d, p, exp, "*"); break;
case EXP_DIV: pbin(d, p, exp, "/"); break;
case EXP_MOD: pbin(d, p, exp, "%"); break;
case EXP_ASS: pbin(d, p, exp, "="); break;
case EXP_ASS_MUL: pbin(d, p, exp, "*="); break;
case EXP_ASS_DIV: pbin(d, p, exp, "/="); break;
case EXP_ASS_MOD: pbin(d, p, exp, "%="); break;
case EXP_ASS_ADD: pbin(d, p, exp, "+="); break;
case EXP_ASS_SUB: pbin(d, p, exp, "-="); break;
case EXP_ASS_SHL: pbin(d, p, exp, "<<="); break;
case EXP_ASS_SHR: pbin(d, p, exp, ">>="); break;
case EXP_ASS_USHR: pbin(d, p, exp, ">>>="); break;
case EXP_ASS_BITAND: pbin(d, p, exp, "&="); break;
case EXP_ASS_BITXOR: pbin(d, p, exp, "^="); break;
case EXP_ASS_BITOR: pbin(d, p, exp, "|="); break;
case EXP_INSTANCEOF:
pexpi(d, p, exp->a);
ps(" instanceof ");
pexpi(d, p, exp->b);
break;
case EXP_COMMA:
pexpi(d, p, exp->a);
pc(','); sp();
pexpi(d, p, exp->b);
break;
case EXP_COND:
pexpi(d, p, exp->a);
sp(); pc('?'); sp();
pexpi(d, p, exp->b);
sp(); pc(':'); sp();
pexpi(d, p, exp->c);
break;
case EXP_INDEX:
pexpi(d, p, exp->a);
pc('[');
pexpi(d, 0, exp->b);
pc(']');
break;
case EXP_MEMBER:
pexpi(d, p, exp->a);
pc('.');
pexpi(d, 0, exp->b);
break;
case EXP_CALL:
pexpi(d, p, exp->a);
pc('(');
pargs(d, exp->b);
pc(')');
break;
case EXP_NEW:
ps("new ");
pexpi(d, p, exp->a);
pc('(');
pargs(d, exp->b);
pc(')');
break;
case EXP_FUN:
if (p == 0) pc('(');
ps("function ");
pexpi(d, 0, exp->a);
pc('(');
pargs(d, exp->b);
pc(')'); sp(); pc('{'); nl();
pstmlist(d, exp->c);
in(d); pc('}');
if (p == 0) pc(')');
break;
default:
ps("<UNKNOWN>");
break;
}
if (paren) pc(')');
}
static void pexp(int d, js_Ast *exp)
{
pexpi(d, 0, exp);
}
static void pvar(int d, js_Ast *var)
{
assert(var->type == EXP_VAR);
pexp(d, var->a);
if (var->b) {
sp(); pc('='); sp();
pexp(d, var->b);
}
}
static void pvarlist(int d, js_Ast *list)
{
while (list) {
assert(list->type == AST_LIST);
pvar(d, list->a);
list = list->b;
if (list)
comma();
}
}
static void pblock(int d, js_Ast *block)
{
assert(block->type == STM_BLOCK);
pc('{'); nl();
pstmlist(d, block->a);
in(d); pc('}');
}
static void pstmh(int d, js_Ast *stm)
{
if (stm->type == STM_BLOCK) {
sp();
pblock(d, stm);
} else {
nl();
pstm(d+1, stm);
}
}
static void pcaselist(int d, js_Ast *list)
{
while (list) {
js_Ast *stm = list->a;
if (stm->type == STM_CASE) {
in(d); ps("case "); pexp(d, stm->a); pc(':'); nl();
pstmlist(d, stm->b);
}
if (stm->type == STM_DEFAULT) {
in(d); ps("default:"); nl();
pstmlist(d, stm->a);
}
list = list->b;
}
}
static void pstm(int d, js_Ast *stm)
{
if (stm->type == STM_BLOCK) {
pblock(d, stm);
return;
}
in(d);
switch (stm->type) {
case AST_FUNDEC:
ps("function ");
pexp(d, stm->a);
pc('(');
pargs(d, stm->b);
pc(')'); sp(); pc('{'); nl();
pstmlist(d, stm->c);
in(d); pc('}');
break;
case STM_EMPTY:
pc(';');
break;
case STM_VAR:
ps("var ");
pvarlist(d, stm->a);
pc(';');
break;
case STM_IF:
ps("if"); sp(); pc('('); pexp(d, stm->a); pc(')');
pstmh(d, stm->b);
if (stm->c) {
nl(); in(d); ps("else");
pstmh(d, stm->c);
}
break;
case STM_DO:
ps("do");
pstmh(d, stm->a);
nl();
in(d); ps("while"); sp(); pc('('); pexp(d, stm->b); pc(')'); pc(';');
break;
case STM_WHILE:
ps("while"); sp(); pc('('); pexp(d, stm->a); pc(')');
pstmh(d, stm->b);
break;
case STM_FOR:
ps("for"); sp(); pc('(');
pexp(d, stm->a); pc(';'); sp();
pexp(d, stm->b); pc(';'); sp();
pexp(d, stm->c); pc(')');
pstmh(d, stm->d);
break;
case STM_FOR_VAR:
ps("for"); sp(); ps("(var ");
pvarlist(d, stm->a); pc(';'); sp();
pexp(d, stm->b); pc(';'); sp();
pexp(d, stm->c); pc(')');
pstmh(d, stm->d);
break;
case STM_FOR_IN:
ps("for"); sp(); pc('(');
pexp(d, stm->a); ps(" in ");
pexp(d, stm->b); pc(')');
pstmh(d, stm->c);
break;
case STM_FOR_IN_VAR:
ps("for"); sp(); ps("(var ");
pvarlist(d, stm->a); ps(" in ");
pexp(d, stm->b); pc(')');
pstmh(d, stm->c);
break;
case STM_CONTINUE:
ps("continue");
if (stm->a) {
pc(' '); pexp(d, stm->a);
}
pc(';');
break;
case STM_BREAK:
ps("break");
if (stm->a) {
pc(' '); pexp(d, stm->a);
}
pc(';');
break;
case STM_RETURN:
ps("return");
if (stm->a) {
pc(' '); pexp(d, stm->a);
}
pc(';');
break;
case STM_WITH:
ps("with"); sp(); pc('('); pexp(d, stm->a); pc(')');
pstmh(d, stm->b);
break;
case STM_SWITCH:
ps("switch"); sp(); pc('(');
pexp(d, stm->a);
pc(')'); sp(); pc('{'); nl();
pcaselist(d, stm->b);
in(d); pc('}');
break;
case STM_THROW:
ps("throw "); pexp(d, stm->a); pc(';');
break;
case STM_TRY:
ps("try");
if (minify && stm->a->type != STM_BLOCK)
pc(' ');
pstmh(d, stm->a);
if (stm->b && stm->c) {
nl(); in(d); ps("catch"); sp(); pc('('); pexp(d, stm->b); pc(')');
pstmh(d, stm->c);
}
if (stm->d) {
nl(); in(d); ps("finally");
pstmh(d, stm->d);
}
break;
case STM_LABEL:
pexp(d, stm->a); pc(':'); sp(); pstm(d, stm->b);
break;
case STM_DEBUGGER:
ps("debugger");
pc(';');
break;
default:
pexp(d, stm);
pc(';');
}
}
static void pstmlist(int d, js_Ast *list)
{
while (list) {
assert(list->type == AST_LIST);
pstm(d+1, list->a);
nl();
list = list->b;
}
}
void jsP_dumpsyntax(js_State *J, js_Ast *prog, int dominify)
{
minify = dominify;
if (prog->type == AST_LIST)
pstmlist(-1, prog);
else {
pstm(0, prog);
nl();
}
if (minify > 1)
putchar('\n');
}
/* S-expression list representation */
static void snode(int d, js_Ast *node)
{
void (*afun)(int,js_Ast*) = snode;
void (*bfun)(int,js_Ast*) = snode;
void (*cfun)(int,js_Ast*) = snode;
void (*dfun)(int,js_Ast*) = snode;
if (!node) {
return;
}
if (node->type == AST_LIST) {
slist(d, node);
return;
}
pc('(');
ps(astname[node->type]);
pc(':');
pn(node->line);
switch (node->type) {
default: break;
case AST_IDENTIFIER: pc(' '); ps(node->string); break;
case EXP_IDENTIFIER: pc(' '); ps(node->string); break;
case EXP_STRING: pc(' '); pstr(node->string); break;
case EXP_REGEXP: pc(' '); pregexp(node->string, node->number); break;
case EXP_NUMBER: printf(" %.9g", node->number); break;
case STM_BLOCK: afun = sblock; break;
case AST_FUNDEC: case EXP_FUN: cfun = sblock; break;
case EXP_PROP_GET: cfun = sblock; break;
case EXP_PROP_SET: cfun = sblock; break;
case STM_SWITCH: bfun = sblock; break;
case STM_CASE: bfun = sblock; break;
case STM_DEFAULT: afun = sblock; break;
}
if (node->a) { pc(' '); afun(d, node->a); }
if (node->b) { pc(' '); bfun(d, node->b); }
if (node->c) { pc(' '); cfun(d, node->c); }
if (node->d) { pc(' '); dfun(d, node->d); }
pc(')');
}
static void slist(int d, js_Ast *list)
{
pc('[');
while (list) {
assert(list->type == AST_LIST);
snode(d, list->a);
list = list->b;
if (list)
pc(' ');
}
pc(']');
}
static void sblock(int d, js_Ast *list)
{
ps("[\n");
in(d+1);
while (list) {
assert(list->type == AST_LIST);
snode(d+1, list->a);
list = list->b;
if (list) {
nl();
in(d+1);
}
}
nl(); in(d); pc(']');
}
void jsP_dumplist(js_State *J, js_Ast *prog)
{
minify = 0;
if (prog->type == AST_LIST)
sblock(0, prog);
else
snode(0, prog);
nl();
}
/* Compiled code */
void jsC_dumpfunction(js_State *J, js_Function *F)
{
js_Instruction *p = F->code;
js_Instruction *end = F->code + F->codelen;
int i;
minify = 0;
printf("%s(%d)\n", F->name, F->numparams);
if (F->lightweight) printf("\tlightweight\n");
if (F->arguments) printf("\targuments\n");
printf("\tsource %s:%d\n", F->filename, F->line);
for (i = 0; i < F->funlen; ++i)
printf("\tfunction %d %s\n", i, F->funtab[i]->name);
for (i = 0; i < F->varlen; ++i)
printf("\tlocal %d %s\n", i + 1, F->vartab[i]);
printf("{\n");
while (p < end) {
int ln = *p++;
int c = *p++;
printf("%5d(%3d): ", (int)(p - F->code) - 2, ln);
ps(opname[c]);
switch (c) {
case OP_INTEGER:
printf(" %ld", (long)((*p++) - 32768));
break;
case OP_NUMBER:
printf(" %.9g", F->numtab[*p++]);
break;
case OP_STRING:
pc(' ');
pstr(F->strtab[*p++]);
break;
case OP_NEWREGEXP:
pc(' ');
pregexp(F->strtab[p[0]], p[1]);
p += 2;
break;
case OP_GETVAR:
case OP_HASVAR:
case OP_SETVAR:
case OP_DELVAR:
case OP_GETPROP_S:
case OP_SETPROP_S:
case OP_DELPROP_S:
case OP_CATCH:
pc(' ');
ps(F->strtab[*p++]);
break;
case OP_GETLOCAL:
case OP_SETLOCAL:
case OP_DELLOCAL:
printf(" %s", F->vartab[*p++ - 1]);
break;
case OP_CLOSURE:
case OP_CALL:
case OP_NEW:
case OP_JUMP:
case OP_JTRUE:
case OP_JFALSE:
case OP_JCASE:
case OP_TRY:
printf(" %ld", (long)*p++);
break;
}
nl();
}
printf("}\n");
for (i = 0; i < F->funlen; ++i) {
if (F->funtab[i] != F) {
printf("function %d ", i);
jsC_dumpfunction(J, F->funtab[i]);
}
}
}
/* Runtime values */
void js_dumpvalue(js_State *J, js_Value v)
{
minify = 0;
switch (v.type) {
case JS_TUNDEFINED: printf("undefined"); break;
case JS_TNULL: printf("null"); break;
case JS_TBOOLEAN: printf(v.u.boolean ? "true" : "false"); break;
case JS_TNUMBER: printf("%.9g", v.u.number); break;
case JS_TSHRSTR: printf("'%s'", v.u.shrstr); break;
case JS_TLITSTR: printf("'%s'", v.u.litstr); break;
case JS_TMEMSTR: printf("'%s'", v.u.memstr->p); break;
case JS_TOBJECT:
if (v.u.object == J->G) {
printf("[Global]");
break;
}
switch (v.u.object->type) {
case JS_COBJECT: printf("[Object %p]", (void*)v.u.object); break;
case JS_CARRAY: printf("[Array %p]", (void*)v.u.object); break;
case JS_CFUNCTION:
printf("[Function %p, %s, %s:%d]",
(void*)v.u.object,
v.u.object->u.f.function->name,
v.u.object->u.f.function->filename,
v.u.object->u.f.function->line);
break;
case JS_CSCRIPT: printf("[Script %s]", v.u.object->u.f.function->filename); break;
case JS_CEVAL: printf("[Eval %s]", v.u.object->u.f.function->filename); break;
case JS_CCFUNCTION: printf("[CFunction %s]", v.u.object->u.c.name); break;
case JS_CBOOLEAN: printf("[Boolean %d]", v.u.object->u.boolean); break;
case JS_CNUMBER: printf("[Number %g]", v.u.object->u.number); break;
case JS_CSTRING: printf("[String'%s']", v.u.object->u.s.string); break;
case JS_CERROR: printf("[Error]"); break;
case JS_CARGUMENTS: printf("[Arguments %p]", (void*)v.u.object); break;
case JS_CITERATOR: printf("[Iterator %p]", (void*)v.u.object); break;
case JS_CUSERDATA:
printf("[Userdata %s %p]", v.u.object->u.user.tag, v.u.object->u.user.data);
break;
default: printf("[Object %p]", (void*)v.u.object); break;
}
break;
}
}
static void js_dumpproperty(js_State *J, js_Property *node)
{
minify = 0;
if (node->left->level)
js_dumpproperty(J, node->left);
printf("\t%s: ", node->name);
js_dumpvalue(J, node->value);
printf(",\n");
if (node->right->level)
js_dumpproperty(J, node->right);
}
void js_dumpobject(js_State *J, js_Object *obj)
{
minify = 0;
printf("{\n");
if (obj->properties->level)
js_dumpproperty(J, obj->properties);
printf("}\n");
}

View File

@ -1,132 +0,0 @@
#include "jsi.h"
#include "jsvalue.h"
#include "jsbuiltin.h"
#define QQ(X) #X
#define Q(X) QQ(X)
static int jsB_stacktrace(js_State *J, int skip)
{
char buf[256];
int n = J->tracetop - skip;
if (n <= 0)
return 0;
for (; n > 0; --n) {
const char *name = J->trace[n].name;
const char *file = J->trace[n].file;
int line = J->trace[n].line;
if (line > 0) {
if (name[0])
snprintf(buf, sizeof buf, "\n\tat %s (%s:%d)", name, file, line);
else
snprintf(buf, sizeof buf, "\n\tat %s:%d", file, line);
} else
snprintf(buf, sizeof buf, "\n\tat %s (%s)", name, file);
js_pushstring(J, buf);
if (n < J->tracetop - skip)
js_concat(J);
}
return 1;
}
static void Ep_toString(js_State *J)
{
const char *name = "Error";
const char *message = "";
if (!js_isobject(J, -1))
js_typeerror(J, "not an object");
if (js_hasproperty(J, 0, "name"))
name = js_tostring(J, -1);
if (js_hasproperty(J, 0, "message"))
message = js_tostring(J, -1);
if (name[0] == 0)
js_pushstring(J, message);
else if (message[0] == 0)
js_pushstring(J, name);
else {
js_pushstring(J, name);
js_pushstring(J, ": ");
js_concat(J);
js_pushstring(J, message);
js_concat(J);
}
}
static int jsB_ErrorX(js_State *J, js_Object *prototype)
{
int top = js_gettop(J);
js_pushobject(J, jsV_newobject(J, JS_CERROR, prototype));
if (top > 1) {
js_pushstring(J, js_tostring(J, 1));
js_defproperty(J, -2, "message", JS_DONTENUM);
}
if (jsB_stacktrace(J, 1))
js_defproperty(J, -2, "stackTrace", JS_DONTENUM);
return 1;
}
static void js_newerrorx(js_State *J, const char *message, js_Object *prototype)
{
js_pushobject(J, jsV_newobject(J, JS_CERROR, prototype));
js_pushstring(J, message);
js_setproperty(J, -2, "message");
if (jsB_stacktrace(J, 0))
js_setproperty(J, -2, "stackTrace");
}
#define DERROR(name, Name) \
static void jsB_##Name(js_State *J) { \
jsB_ErrorX(J, J->Name##_prototype); \
} \
void js_new##name(js_State *J, const char *s) { \
js_newerrorx(J, s, J->Name##_prototype); \
} \
void js_##name(js_State *J, const char *fmt, ...) { \
va_list ap; \
char buf[256]; \
va_start(ap, fmt); \
vsnprintf(buf, sizeof buf, fmt, ap); \
va_end(ap); \
js_newerrorx(J, buf, J->Name##_prototype); \
js_throw(J); \
}
DERROR(error, Error)
DERROR(evalerror, EvalError)
DERROR(rangeerror, RangeError)
DERROR(referenceerror, ReferenceError)
DERROR(syntaxerror, SyntaxError)
DERROR(typeerror, TypeError)
DERROR(urierror, URIError)
#undef DERROR
void jsB_initerror(js_State *J)
{
js_pushobject(J, J->Error_prototype);
{
jsB_props(J, "name", "Error");
jsB_props(J, "message", "an error has occurred");
jsB_propf(J, "Error.prototype.toString", Ep_toString, 0);
}
js_newcconstructor(J, jsB_Error, jsB_Error, "Error", 1);
js_defglobal(J, "Error", JS_DONTENUM);
#define IERROR(NAME) \
js_pushobject(J, J->NAME##_prototype); \
jsB_props(J, "name", Q(NAME)); \
js_newcconstructor(J, jsB_##NAME, jsB_##NAME, Q(NAME), 1); \
js_defglobal(J, Q(NAME), JS_DONTENUM);
IERROR(EvalError);
IERROR(RangeError);
IERROR(ReferenceError);
IERROR(SyntaxError);
IERROR(TypeError);
IERROR(URIError);
#undef IERROR
}

View File

@ -1,229 +0,0 @@
#include "jsi.h"
#include "jsparse.h"
#include "jscompile.h"
#include "jsvalue.h"
#include "jsbuiltin.h"
static void jsB_Function(js_State *J)
{
int i, top = js_gettop(J);
js_Buffer *sb = NULL;
const char *body;
js_Ast *parse;
js_Function *fun;
if (js_try(J)) {
js_free(J, sb);
jsP_freeparse(J);
js_throw(J);
}
/* p1, p2, ..., pn */
if (top > 2) {
for (i = 1; i < top - 1; ++i) {
if (i > 1)
js_putc(J, &sb, ',');
js_puts(J, &sb, js_tostring(J, i));
}
js_putc(J, &sb, ')');
js_putc(J, &sb, 0);
}
/* body */
body = js_isdefined(J, top - 1) ? js_tostring(J, top - 1) : "";
parse = jsP_parsefunction(J, "[string]", sb ? sb->s : NULL, body);
fun = jsC_compilefunction(J, parse);
js_endtry(J);
js_free(J, sb);
jsP_freeparse(J);
js_newfunction(J, fun, J->GE);
}
static void jsB_Function_prototype(js_State *J)
{
js_pushundefined(J);
}
static void Fp_toString(js_State *J)
{
js_Object *self = js_toobject(J, 0);
js_Buffer *sb = NULL;
int i;
if (!js_iscallable(J, 0))
js_typeerror(J, "not a function");
if (self->type == JS_CFUNCTION || self->type == JS_CSCRIPT || self->type == JS_CEVAL) {
js_Function *F = self->u.f.function;
if (js_try(J)) {
js_free(J, sb);
js_throw(J);
}
js_puts(J, &sb, "function ");
js_puts(J, &sb, F->name);
js_putc(J, &sb, '(');
for (i = 0; i < F->numparams; ++i) {
if (i > 0) js_putc(J, &sb, ',');
js_puts(J, &sb, F->vartab[i]);
}
js_puts(J, &sb, ") { [byte code] }");
js_putc(J, &sb, 0);
js_pushstring(J, sb->s);
js_endtry(J);
js_free(J, sb);
} else if (self->type == JS_CCFUNCTION) {
if (js_try(J)) {
js_free(J, sb);
js_throw(J);
}
js_puts(J, &sb, "function ");
js_puts(J, &sb, self->u.c.name);
js_puts(J, &sb, "() { [native code] }");
js_putc(J, &sb, 0);
js_pushstring(J, sb->s);
js_endtry(J);
js_free(J, sb);
} else {
js_pushliteral(J, "function () { }");
}
}
static void Fp_apply(js_State *J)
{
int i, n;
if (!js_iscallable(J, 0))
js_typeerror(J, "not a function");
js_copy(J, 0);
js_copy(J, 1);
if (js_isnull(J, 2) || js_isundefined(J, 2)) {
n = 0;
} else {
n = js_getlength(J, 2);
for (i = 0; i < n; ++i)
js_getindex(J, 2, i);
}
js_call(J, n);
}
static void Fp_call(js_State *J)
{
int i, top = js_gettop(J);
if (!js_iscallable(J, 0))
js_typeerror(J, "not a function");
for (i = 0; i < top; ++i)
js_copy(J, i);
js_call(J, top - 2);
}
static void callbound(js_State *J)
{
int top = js_gettop(J);
int i, fun, args, n;
fun = js_gettop(J);
js_currentfunction(J);
js_getproperty(J, fun, "__TargetFunction__");
js_getproperty(J, fun, "__BoundThis__");
args = js_gettop(J);
js_getproperty(J, fun, "__BoundArguments__");
n = js_getlength(J, args);
for (i = 0; i < n; ++i)
js_getindex(J, args, i);
js_remove(J, args);
for (i = 1; i < top; ++i)
js_copy(J, i);
js_call(J, n + top - 1);
}
static void constructbound(js_State *J)
{
int top = js_gettop(J);
int i, fun, args, n;
fun = js_gettop(J);
js_currentfunction(J);
js_getproperty(J, fun, "__TargetFunction__");
args = js_gettop(J);
js_getproperty(J, fun, "__BoundArguments__");
n = js_getlength(J, args);
for (i = 0; i < n; ++i)
js_getindex(J, args, i);
js_remove(J, args);
for (i = 1; i < top; ++i)
js_copy(J, i);
js_construct(J, n + top - 1);
}
static void Fp_bind(js_State *J)
{
int i, top = js_gettop(J);
int n;
if (!js_iscallable(J, 0))
js_typeerror(J, "not a function");
n = js_getlength(J, 0);
if (n > top - 2)
n -= top - 2;
else
n = 0;
/* Reuse target function's prototype for HasInstance check. */
js_getproperty(J, 0, "prototype");
js_newcconstructor(J, callbound, constructbound, "[bind]", n);
/* target function */
js_copy(J, 0);
js_defproperty(J, -2, "__TargetFunction__", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
/* bound this */
js_copy(J, 1);
js_defproperty(J, -2, "__BoundThis__", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
/* bound arguments */
js_newarray(J);
for (i = 2; i < top; ++i) {
js_copy(J, i);
js_setindex(J, -2, i - 2);
}
js_defproperty(J, -2, "__BoundArguments__", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
}
void jsB_initfunction(js_State *J)
{
J->Function_prototype->u.c.name = "Function.prototype";
J->Function_prototype->u.c.function = jsB_Function_prototype;
J->Function_prototype->u.c.constructor = NULL;
J->Function_prototype->u.c.length = 0;
js_pushobject(J, J->Function_prototype);
{
jsB_propf(J, "Function.prototype.toString", Fp_toString, 2);
jsB_propf(J, "Function.prototype.apply", Fp_apply, 2);
jsB_propf(J, "Function.prototype.call", Fp_call, 1);
jsB_propf(J, "Function.prototype.bind", Fp_bind, 1);
}
js_newcconstructor(J, jsB_Function, jsB_Function, "Function", 1);
js_defglobal(J, "Function", JS_DONTENUM);
}

View File

@ -1,278 +0,0 @@
#include "jsi.h"
#include "jscompile.h"
#include "jsvalue.h"
#include "jsrun.h"
#include "regexp.h"
static void jsG_freeenvironment(js_State *J, js_Environment *env)
{
js_free(J, env);
}
static void jsG_freefunction(js_State *J, js_Function *fun)
{
js_free(J, fun->funtab);
js_free(J, fun->numtab);
js_free(J, fun->strtab);
js_free(J, fun->vartab);
js_free(J, fun->code);
js_free(J, fun);
}
static void jsG_freeproperty(js_State *J, js_Property *node)
{
if (node->left->level) jsG_freeproperty(J, node->left);
if (node->right->level) jsG_freeproperty(J, node->right);
js_free(J, node);
}
static void jsG_freeiterator(js_State *J, js_Iterator *node)
{
while (node) {
js_Iterator *next = node->next;
js_free(J, node);
node = next;
}
}
static void jsG_freeobject(js_State *J, js_Object *obj)
{
if (obj->properties->level)
jsG_freeproperty(J, obj->properties);
if (obj->type == JS_CREGEXP) {
js_free(J, obj->u.r.source);
js_regfreex(J->alloc, J->actx, obj->u.r.prog);
}
if (obj->type == JS_CITERATOR)
jsG_freeiterator(J, obj->u.iter.head);
if (obj->type == JS_CUSERDATA && obj->u.user.finalize)
obj->u.user.finalize(J, obj->u.user.data);
js_free(J, obj);
}
/* Mark and add object to scan queue */
static void jsG_markobject(js_State *J, int mark, js_Object *obj)
{
obj->gcmark = mark;
obj->gcroot = J->gcroot;
J->gcroot = obj;
}
static void jsG_markfunction(js_State *J, int mark, js_Function *fun)
{
int i;
fun->gcmark = mark;
for (i = 0; i < fun->funlen; ++i)
if (fun->funtab[i]->gcmark != mark)
jsG_markfunction(J, mark, fun->funtab[i]);
}
static void jsG_markenvironment(js_State *J, int mark, js_Environment *env)
{
do {
env->gcmark = mark;
if (env->variables->gcmark != mark)
jsG_markobject(J, mark, env->variables);
env = env->outer;
} while (env && env->gcmark != mark);
}
static void jsG_markproperty(js_State *J, int mark, js_Property *node)
{
if (node->left->level) jsG_markproperty(J, mark, node->left);
if (node->right->level) jsG_markproperty(J, mark, node->right);
if (node->value.type == JS_TMEMSTR && node->value.u.memstr->gcmark != mark)
node->value.u.memstr->gcmark = mark;
if (node->value.type == JS_TOBJECT && node->value.u.object->gcmark != mark)
jsG_markobject(J, mark, node->value.u.object);
if (node->getter && node->getter->gcmark != mark)
jsG_markobject(J, mark, node->getter);
if (node->setter && node->setter->gcmark != mark)
jsG_markobject(J, mark, node->setter);
}
/* Mark everything the object can reach. */
static void jsG_scanobject(js_State *J, int mark, js_Object *obj)
{
if (obj->properties->level)
jsG_markproperty(J, mark, obj->properties);
if (obj->prototype && obj->prototype->gcmark != mark)
jsG_markobject(J, mark, obj->prototype);
if (obj->type == JS_CITERATOR && obj->u.iter.target->gcmark != mark) {
jsG_markobject(J, mark, obj->u.iter.target);
}
if (obj->type == JS_CFUNCTION || obj->type == JS_CSCRIPT || obj->type == JS_CEVAL) {
if (obj->u.f.scope && obj->u.f.scope->gcmark != mark)
jsG_markenvironment(J, mark, obj->u.f.scope);
if (obj->u.f.function && obj->u.f.function->gcmark != mark)
jsG_markfunction(J, mark, obj->u.f.function);
}
}
static void jsG_markstack(js_State *J, int mark)
{
js_Value *v = J->stack;
int n = J->top;
while (n--) {
if (v->type == JS_TMEMSTR && v->u.memstr->gcmark != mark)
v->u.memstr->gcmark = mark;
if (v->type == JS_TOBJECT && v->u.object->gcmark != mark)
jsG_markobject(J, mark, v->u.object);
++v;
}
}
void js_gc(js_State *J, int report)
{
js_Function *fun, *nextfun, **prevnextfun;
js_Object *obj, *nextobj, **prevnextobj;
js_String *str, *nextstr, **prevnextstr;
js_Environment *env, *nextenv, **prevnextenv;
unsigned int nenv = 0, nfun = 0, nobj = 0, nstr = 0, nprop = 0;
unsigned int genv = 0, gfun = 0, gobj = 0, gstr = 0, gprop = 0;
int mark;
int i;
if (J->gcpause) {
if (report)
js_report(J, "garbage collector is paused");
return;
}
mark = J->gcmark = J->gcmark == 1 ? 2 : 1;
/* Add initial roots. */
jsG_markobject(J, mark, J->Object_prototype);
jsG_markobject(J, mark, J->Array_prototype);
jsG_markobject(J, mark, J->Function_prototype);
jsG_markobject(J, mark, J->Boolean_prototype);
jsG_markobject(J, mark, J->Number_prototype);
jsG_markobject(J, mark, J->String_prototype);
jsG_markobject(J, mark, J->RegExp_prototype);
jsG_markobject(J, mark, J->Date_prototype);
jsG_markobject(J, mark, J->Error_prototype);
jsG_markobject(J, mark, J->EvalError_prototype);
jsG_markobject(J, mark, J->RangeError_prototype);
jsG_markobject(J, mark, J->ReferenceError_prototype);
jsG_markobject(J, mark, J->SyntaxError_prototype);
jsG_markobject(J, mark, J->TypeError_prototype);
jsG_markobject(J, mark, J->URIError_prototype);
jsG_markobject(J, mark, J->R);
jsG_markobject(J, mark, J->G);
jsG_markstack(J, mark);
jsG_markenvironment(J, mark, J->E);
jsG_markenvironment(J, mark, J->GE);
for (i = 0; i < J->envtop; ++i)
jsG_markenvironment(J, mark, J->envstack[i]);
/* Scan objects until none remain. */
while ((obj = J->gcroot) != NULL) {
J->gcroot = obj->gcroot;
obj->gcroot = NULL;
jsG_scanobject(J, mark, obj);
}
/* Free everything not marked. */
prevnextenv = &J->gcenv;
for (env = J->gcenv; env; env = nextenv) {
nextenv = env->gcnext;
if (env->gcmark != mark) {
*prevnextenv = nextenv;
jsG_freeenvironment(J, env);
++genv;
} else {
prevnextenv = &env->gcnext;
}
++nenv;
}
prevnextfun = &J->gcfun;
for (fun = J->gcfun; fun; fun = nextfun) {
nextfun = fun->gcnext;
if (fun->gcmark != mark) {
*prevnextfun = nextfun;
jsG_freefunction(J, fun);
++gfun;
} else {
prevnextfun = &fun->gcnext;
}
++nfun;
}
prevnextobj = &J->gcobj;
for (obj = J->gcobj; obj; obj = nextobj) {
nprop += obj->count;
nextobj = obj->gcnext;
if (obj->gcmark != mark) {
gprop += obj->count;
*prevnextobj = nextobj;
jsG_freeobject(J, obj);
++gobj;
} else {
prevnextobj = &obj->gcnext;
}
++nobj;
}
prevnextstr = &J->gcstr;
for (str = J->gcstr; str; str = nextstr) {
nextstr = str->gcnext;
if (str->gcmark != mark) {
*prevnextstr = nextstr;
js_free(J, str);
++gstr;
} else {
prevnextstr = &str->gcnext;
}
++nstr;
}
unsigned int ntot = nenv + nfun + nobj + nstr + nprop;
unsigned int gtot = genv + gfun + gobj + gstr + gprop;
unsigned int remaining = ntot - gtot;
J->gccounter = remaining;
J->gcthresh = remaining * JS_GCFACTOR;
if (report) {
char buf[256];
snprintf(buf, sizeof buf, "garbage collected (%d%%): %d/%d envs, %d/%d funs, %d/%d objs, %d/%d props, %d/%d strs",
100*gtot/ntot, genv, nenv, gfun, nfun, gobj, nobj, gprop, nprop, gstr, nstr);
js_report(J, buf);
}
}
void js_freestate(js_State *J)
{
js_Function *fun, *nextfun;
js_Object *obj, *nextobj;
js_Environment *env, *nextenv;
js_String *str, *nextstr;
if (!J)
return;
for (env = J->gcenv; env; env = nextenv)
nextenv = env->gcnext, jsG_freeenvironment(J, env);
for (fun = J->gcfun; fun; fun = nextfun)
nextfun = fun->gcnext, jsG_freefunction(J, fun);
for (obj = J->gcobj; obj; obj = nextobj)
nextobj = obj->gcnext, jsG_freeobject(J, obj);
for (str = J->gcstr; str; str = nextstr)
nextstr = str->gcnext, js_free(J, str);
jsS_freestrings(J);
js_free(J, J->lexbuf.text);
J->alloc(J->actx, J->stack, 0);
J->alloc(J->actx, J, 0);
}

View File

@ -1,265 +0,0 @@
#ifndef jsi_h
#define jsi_h
#include "mujs.h"
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdarg.h>
#include <string.h>
#include <setjmp.h>
#include <math.h>
#include <float.h>
#include <limits.h>
/* Microsoft Visual C */
#ifdef _MSC_VER
#pragma warning(disable:4996) /* _CRT_SECURE_NO_WARNINGS */
#pragma warning(disable:4244) /* implicit conversion from double to int */
#pragma warning(disable:4267) /* implicit conversion of int to smaller int */
#define inline __inline
#if _MSC_VER < 1900 /* MSVC 2015 */
#define snprintf jsW_snprintf
#define vsnprintf jsW_vsnprintf
static int jsW_vsnprintf(char *str, size_t size, const char *fmt, va_list ap)
{
int n;
n = _vsnprintf(str, size, fmt, ap);
str[size-1] = 0;
return n;
}
static int jsW_snprintf(char *str, size_t size, const char *fmt, ...)
{
int n;
va_list ap;
va_start(ap, fmt);
n = jsW_vsnprintf(str, size, fmt, ap);
va_end(ap);
return n;
}
#endif
#if _MSC_VER <= 1700 /* <= MSVC 2012 */
#define isnan(x) _isnan(x)
#define isinf(x) (!_finite(x))
#define isfinite(x) _finite(x)
static __inline int signbit(double x) { __int64 i; memcpy(&i, &x, 8); return i>>63; }
#define INFINITY (DBL_MAX+DBL_MAX)
#define NAN (INFINITY-INFINITY)
#endif
#endif
#define soffsetof(x,y) ((int)offsetof(x,y))
#define nelem(a) (int)(sizeof (a) / sizeof (a)[0])
void *js_malloc(js_State *J, int size);
void *js_realloc(js_State *J, void *ptr, int size);
void js_free(js_State *J, void *ptr);
typedef struct js_Regexp js_Regexp;
typedef struct js_Value js_Value;
typedef struct js_Object js_Object;
typedef struct js_String js_String;
typedef struct js_Ast js_Ast;
typedef struct js_Function js_Function;
typedef struct js_Environment js_Environment;
typedef struct js_StringNode js_StringNode;
typedef struct js_Jumpbuf js_Jumpbuf;
typedef struct js_StackTrace js_StackTrace;
/* Limits */
#ifndef JS_STACKSIZE
#define JS_STACKSIZE 256 /* value stack size */
#endif
#ifndef JS_ENVLIMIT
#define JS_ENVLIMIT 128 /* environment stack size */
#endif
#ifndef JS_TRYLIMIT
#define JS_TRYLIMIT 64 /* exception stack size */
#endif
#ifndef JS_GCFACTOR
/*
* GC will try to trigger when memory usage is this value times the minimum
* needed memory. E.g. if there are 100 remaining objects after GC and this
* value is 5.0, then the next GC will trigger when the overall number is 500.
* I.e. a value of 5.0 aims at 80% garbage, 20% remain-used on each GC.
* The bigger the value the less impact GC has on overall performance, but more
* memory is used and individual GC pauses are longer (but fewer).
*/
#define JS_GCFACTOR 5.0 /* memory overhead factor >= 1.0 */
#endif
#ifndef JS_ASTLIMIT
#define JS_ASTLIMIT 100 /* max nested expressions */
#endif
/* instruction size -- change to int if you get integer overflow syntax errors */
#ifdef JS_INSTRUCTION
typedef JS_INSTRUCTION js_Instruction;
#else
typedef unsigned short js_Instruction;
#endif
/* String interning */
char *js_strdup(js_State *J, const char *s);
const char *js_intern(js_State *J, const char *s);
void jsS_dumpstrings(js_State *J);
void jsS_freestrings(js_State *J);
/* Portable strtod and printf float formatting */
void js_fmtexp(char *p, int e);
int js_grisu2(double v, char *buffer, int *K);
double js_strtod(const char *as, char **aas);
/* Private stack functions */
void js_newarguments(js_State *J);
void js_newfunction(js_State *J, js_Function *function, js_Environment *scope);
void js_newscript(js_State *J, js_Function *fun, js_Environment *scope, int type);
void js_loadeval(js_State *J, const char *filename, const char *source);
js_Regexp *js_toregexp(js_State *J, int idx);
int js_isarrayindex(js_State *J, const char *str, int *idx);
int js_runeat(js_State *J, const char *s, int i);
int js_utfptrtoidx(const char *s, const char *p);
const char *js_utfidxtoptr(const char *s, int i);
void js_dup(js_State *J);
void js_dup2(js_State *J);
void js_rot2(js_State *J);
void js_rot3(js_State *J);
void js_rot4(js_State *J);
void js_rot2pop1(js_State *J);
void js_rot3pop2(js_State *J);
void js_dup1rot3(js_State *J);
void js_dup1rot4(js_State *J);
void js_RegExp_prototype_exec(js_State *J, js_Regexp *re, const char *text);
void js_trap(js_State *J, int pc); /* dump stack and environment to stdout */
struct js_StackTrace
{
const char *name;
const char *file;
int line;
};
/* Exception handling */
struct js_Jumpbuf
{
jmp_buf buf;
js_Environment *E;
int envtop;
int tracetop;
int top, bot;
int strict;
js_Instruction *pc;
};
void *js_savetrypc(js_State *J, js_Instruction *pc);
#define js_trypc(J, PC) \
setjmp(js_savetrypc(J, PC))
/* String buffer */
typedef struct js_Buffer { int n, m; char s[64]; } js_Buffer;
void js_putc(js_State *J, js_Buffer **sbp, int c);
void js_puts(js_State *J, js_Buffer **sb, const char *s);
void js_putm(js_State *J, js_Buffer **sb, const char *s, const char *e);
/* State struct */
struct js_State
{
void *actx;
void *uctx;
js_Alloc alloc;
js_Report report;
js_Panic panic;
js_StringNode *strings;
int default_strict;
int strict;
/* parser input source */
const char *filename;
const char *source;
int line;
/* lexer state */
struct { char *text; int len, cap; } lexbuf;
int lexline;
int lexchar;
int lasttoken;
int newline;
/* parser state */
int astdepth;
int lookahead;
const char *text;
double number;
js_Ast *gcast; /* list of allocated nodes to free after parsing */
/* runtime environment */
js_Object *Object_prototype;
js_Object *Array_prototype;
js_Object *Function_prototype;
js_Object *Boolean_prototype;
js_Object *Number_prototype;
js_Object *String_prototype;
js_Object *RegExp_prototype;
js_Object *Date_prototype;
js_Object *Error_prototype;
js_Object *EvalError_prototype;
js_Object *RangeError_prototype;
js_Object *ReferenceError_prototype;
js_Object *SyntaxError_prototype;
js_Object *TypeError_prototype;
js_Object *URIError_prototype;
unsigned int seed; /* Math.random seed */
int nextref; /* for js_ref use */
js_Object *R; /* registry of hidden values */
js_Object *G; /* the global object */
js_Environment *E; /* current environment scope */
js_Environment *GE; /* global environment scope (at the root) */
/* execution stack */
int top, bot;
js_Value *stack;
/* garbage collector list */
int gcpause;
int gcmark;
unsigned int gccounter, gcthresh;
js_Environment *gcenv;
js_Function *gcfun;
js_Object *gcobj;
js_String *gcstr;
js_Object *gcroot; /* gc scan list */
/* environments on the call stack but currently not in scope */
int envtop;
js_Environment *envstack[JS_ENVLIMIT];
/* debug info stack trace */
int tracetop;
js_StackTrace trace[JS_ENVLIMIT];
/* exception stack */
int trytop;
js_Jumpbuf trybuf[JS_TRYLIMIT];
};
#endif

View File

@ -1,135 +0,0 @@
#include "jsi.h"
/* Dynamically grown string buffer */
void js_putc(js_State *J, js_Buffer **sbp, int c)
{
js_Buffer *sb = *sbp;
if (!sb) {
sb = js_malloc(J, sizeof *sb);
sb->n = 0;
sb->m = sizeof sb->s;
*sbp = sb;
} else if (sb->n == sb->m) {
sb = js_realloc(J, sb, (sb->m *= 2) + soffsetof(js_Buffer, s));
*sbp = sb;
}
sb->s[sb->n++] = c;
}
void js_puts(js_State *J, js_Buffer **sb, const char *s)
{
while (*s)
js_putc(J, sb, *s++);
}
void js_putm(js_State *J, js_Buffer **sb, const char *s, const char *e)
{
while (s < e)
js_putc(J, sb, *s++);
}
/* Use an AA-tree to quickly look up interned strings. */
struct js_StringNode
{
js_StringNode *left, *right;
int level;
char string[1];
};
static js_StringNode jsS_sentinel = { &jsS_sentinel, &jsS_sentinel, 0, ""};
static js_StringNode *jsS_newstringnode(js_State *J, const char *string, const char **result)
{
int n = strlen(string);
js_StringNode *node = js_malloc(J, soffsetof(js_StringNode, string) + n + 1);
node->left = node->right = &jsS_sentinel;
node->level = 1;
memcpy(node->string, string, n + 1);
return *result = node->string, node;
}
static js_StringNode *jsS_skew(js_StringNode *node)
{
if (node->left->level == node->level) {
js_StringNode *temp = node;
node = node->left;
temp->left = node->right;
node->right = temp;
}
return node;
}
static js_StringNode *jsS_split(js_StringNode *node)
{
if (node->right->right->level == node->level) {
js_StringNode *temp = node;
node = node->right;
temp->right = node->left;
node->left = temp;
++node->level;
}
return node;
}
static js_StringNode *jsS_insert(js_State *J, js_StringNode *node, const char *string, const char **result)
{
if (node != &jsS_sentinel) {
int c = strcmp(string, node->string);
if (c < 0)
node->left = jsS_insert(J, node->left, string, result);
else if (c > 0)
node->right = jsS_insert(J, node->right, string, result);
else
return *result = node->string, node;
node = jsS_skew(node);
node = jsS_split(node);
return node;
}
return jsS_newstringnode(J, string, result);
}
static void dumpstringnode(js_StringNode *node, int level)
{
int i;
if (node->left != &jsS_sentinel)
dumpstringnode(node->left, level + 1);
printf("%d: ", node->level);
for (i = 0; i < level; ++i)
putchar('\t');
printf("'%s'\n", node->string);
if (node->right != &jsS_sentinel)
dumpstringnode(node->right, level + 1);
}
void jsS_dumpstrings(js_State *J)
{
js_StringNode *root = J->strings;
printf("interned strings {\n");
if (root && root != &jsS_sentinel)
dumpstringnode(root, 1);
printf("}\n");
}
static void jsS_freestringnode(js_State *J, js_StringNode *node)
{
if (node->left != &jsS_sentinel) jsS_freestringnode(J, node->left);
if (node->right != &jsS_sentinel) jsS_freestringnode(J, node->right);
js_free(J, node);
}
void jsS_freestrings(js_State *J)
{
if (J->strings && J->strings != &jsS_sentinel)
jsS_freestringnode(J, J->strings);
}
const char *js_intern(js_State *J, const char *s)
{
const char *result;
if (!J->strings)
J->strings = &jsS_sentinel;
J->strings = jsS_insert(J, J->strings, s, &result);
return result;
}

View File

@ -1,879 +0,0 @@
#include "jsi.h"
#include "jslex.h"
#include "utf.h"
JS_NORETURN static void jsY_error(js_State *J, const char *fmt, ...) JS_PRINTFLIKE(2,3);
static void jsY_error(js_State *J, const char *fmt, ...)
{
va_list ap;
char buf[512];
char msgbuf[256];
va_start(ap, fmt);
vsnprintf(msgbuf, 256, fmt, ap);
va_end(ap);
snprintf(buf, 256, "%s:%d: ", J->filename, J->lexline);
strcat(buf, msgbuf);
js_newsyntaxerror(J, buf);
js_throw(J);
}
static const char *tokenstring[] = {
"(end-of-file)",
"'\\x01'", "'\\x02'", "'\\x03'", "'\\x04'", "'\\x05'", "'\\x06'", "'\\x07'",
"'\\x08'", "'\\x09'", "'\\x0A'", "'\\x0B'", "'\\x0C'", "'\\x0D'", "'\\x0E'", "'\\x0F'",
"'\\x10'", "'\\x11'", "'\\x12'", "'\\x13'", "'\\x14'", "'\\x15'", "'\\x16'", "'\\x17'",
"'\\x18'", "'\\x19'", "'\\x1A'", "'\\x1B'", "'\\x1C'", "'\\x1D'", "'\\x1E'", "'\\x1F'",
"' '", "'!'", "'\"'", "'#'", "'$'", "'%'", "'&'", "'\\''",
"'('", "')'", "'*'", "'+'", "','", "'-'", "'.'", "'/'",
"'0'", "'1'", "'2'", "'3'", "'4'", "'5'", "'6'", "'7'",
"'8'", "'9'", "':'", "';'", "'<'", "'='", "'>'", "'?'",
"'@'", "'A'", "'B'", "'C'", "'D'", "'E'", "'F'", "'G'",
"'H'", "'I'", "'J'", "'K'", "'L'", "'M'", "'N'", "'O'",
"'P'", "'Q'", "'R'", "'S'", "'T'", "'U'", "'V'", "'W'",
"'X'", "'Y'", "'Z'", "'['", "'\'", "']'", "'^'", "'_'",
"'`'", "'a'", "'b'", "'c'", "'d'", "'e'", "'f'", "'g'",
"'h'", "'i'", "'j'", "'k'", "'l'", "'m'", "'n'", "'o'",
"'p'", "'q'", "'r'", "'s'", "'t'", "'u'", "'v'", "'w'",
"'x'", "'y'", "'z'", "'{'", "'|'", "'}'", "'~'", "'\\x7F'",
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
"(identifier)", "(number)", "(string)", "(regexp)",
"'<='", "'>='", "'=='", "'!='", "'==='", "'!=='",
"'<<'", "'>>'", "'>>>'", "'&&'", "'||'",
"'+='", "'-='", "'*='", "'/='", "'%='",
"'<<='", "'>>='", "'>>>='", "'&='", "'|='", "'^='",
"'++'", "'--'",
"'break'", "'case'", "'catch'", "'continue'", "'debugger'",
"'default'", "'delete'", "'do'", "'else'", "'false'", "'finally'", "'for'",
"'function'", "'if'", "'in'", "'instanceof'", "'new'", "'null'", "'return'",
"'switch'", "'this'", "'throw'", "'true'", "'try'", "'typeof'", "'var'",
"'void'", "'while'", "'with'",
};
const char *jsY_tokenstring(int token)
{
if (token >= 0 && token < (int)nelem(tokenstring))
if (tokenstring[token])
return tokenstring[token];
return "<unknown>";
}
static const char *keywords[] = {
"break", "case", "catch", "continue", "debugger", "default", "delete",
"do", "else", "false", "finally", "for", "function", "if", "in",
"instanceof", "new", "null", "return", "switch", "this", "throw",
"true", "try", "typeof", "var", "void", "while", "with",
};
int jsY_findword(const char *s, const char **list, int num)
{
int l = 0;
int r = num - 1;
while (l <= r) {
int m = (l + r) >> 1;
int c = strcmp(s, list[m]);
if (c < 0)
r = m - 1;
else if (c > 0)
l = m + 1;
else
return m;
}
return -1;
}
static int jsY_findkeyword(js_State *J, const char *s)
{
int i = jsY_findword(s, keywords, nelem(keywords));
if (i >= 0) {
J->text = keywords[i];
return TK_BREAK + i; /* first keyword + i */
}
J->text = js_intern(J, s);
return TK_IDENTIFIER;
}
int jsY_iswhite(int c)
{
return c == 0x9 || c == 0xB || c == 0xC || c == 0x20 || c == 0xA0 || c == 0xFEFF;
}
int jsY_isnewline(int c)
{
return c == 0xA || c == 0xD || c == 0x2028 || c == 0x2029;
}
#ifndef isalpha
#define isalpha(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
#endif
#ifndef isdigit
#define isdigit(c) (c >= '0' && c <= '9')
#endif
#ifndef ishex
#define ishex(c) ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))
#endif
static int jsY_isidentifierstart(int c)
{
return isalpha(c) || c == '$' || c == '_' || isalpharune(c);
}
static int jsY_isidentifierpart(int c)
{
return isdigit(c) || isalpha(c) || c == '$' || c == '_' || isalpharune(c);
}
static int jsY_isdec(int c)
{
return isdigit(c);
}
int jsY_ishex(int c)
{
return isdigit(c) || ishex(c);
}
int jsY_tohex(int c)
{
if (c >= '0' && c <= '9') return c - '0';
if (c >= 'a' && c <= 'f') return c - 'a' + 0xA;
if (c >= 'A' && c <= 'F') return c - 'A' + 0xA;
return 0;
}
static void jsY_next(js_State *J)
{
Rune c;
if (*J->source == 0) {
J->lexchar = EOF;
return;
}
J->source += chartorune(&c, J->source);
/* consume CR LF as one unit */
if (c == '\r' && *J->source == '\n')
++J->source;
if (jsY_isnewline(c)) {
J->line++;
c = '\n';
}
J->lexchar = c;
}
#define jsY_accept(J, x) (J->lexchar == x ? (jsY_next(J), 1) : 0)
#define jsY_expect(J, x) if (!jsY_accept(J, x)) jsY_error(J, "expected '%c'", x)
static void jsY_unescape(js_State *J)
{
if (jsY_accept(J, '\\')) {
if (jsY_accept(J, 'u')) {
int x = 0;
if (!jsY_ishex(J->lexchar)) { goto error; } x |= jsY_tohex(J->lexchar) << 12; jsY_next(J);
if (!jsY_ishex(J->lexchar)) { goto error; } x |= jsY_tohex(J->lexchar) << 8; jsY_next(J);
if (!jsY_ishex(J->lexchar)) { goto error; } x |= jsY_tohex(J->lexchar) << 4; jsY_next(J);
if (!jsY_ishex(J->lexchar)) { goto error; } x |= jsY_tohex(J->lexchar);
J->lexchar = x;
return;
}
error:
jsY_error(J, "unexpected escape sequence");
}
}
static void textinit(js_State *J)
{
if (!J->lexbuf.text) {
J->lexbuf.cap = 4096;
J->lexbuf.text = js_malloc(J, J->lexbuf.cap);
}
J->lexbuf.len = 0;
}
static void textpush(js_State *J, Rune c)
{
int n;
if (c == EOF)
n = 1;
else
n = runelen(c);
if (J->lexbuf.len + n > J->lexbuf.cap) {
J->lexbuf.cap = J->lexbuf.cap * 2;
J->lexbuf.text = js_realloc(J, J->lexbuf.text, J->lexbuf.cap);
}
if (c == EOF)
J->lexbuf.text[J->lexbuf.len++] = 0;
else
J->lexbuf.len += runetochar(J->lexbuf.text + J->lexbuf.len, &c);
}
static char *textend(js_State *J)
{
textpush(J, EOF);
return J->lexbuf.text;
}
static void lexlinecomment(js_State *J)
{
while (J->lexchar != EOF && J->lexchar != '\n')
jsY_next(J);
}
static int lexcomment(js_State *J)
{
/* already consumed initial '/' '*' sequence */
while (J->lexchar != EOF) {
if (jsY_accept(J, '*')) {
while (J->lexchar == '*')
jsY_next(J);
if (jsY_accept(J, '/'))
return 0;
}
else
jsY_next(J);
}
return -1;
}
static double lexhex(js_State *J)
{
double n = 0;
if (!jsY_ishex(J->lexchar))
jsY_error(J, "malformed hexadecimal number");
while (jsY_ishex(J->lexchar)) {
n = n * 16 + jsY_tohex(J->lexchar);
jsY_next(J);
}
return n;
}
#if 0
static double lexinteger(js_State *J)
{
double n = 0;
if (!jsY_isdec(J->lexchar))
jsY_error(J, "malformed number");
while (jsY_isdec(J->lexchar)) {
n = n * 10 + (J->lexchar - '0');
jsY_next(J);
}
return n;
}
static double lexfraction(js_State *J)
{
double n = 0;
double d = 1;
while (jsY_isdec(J->lexchar)) {
n = n * 10 + (J->lexchar - '0');
d = d * 10;
jsY_next(J);
}
return n / d;
}
static double lexexponent(js_State *J)
{
double sign;
if (jsY_accept(J, 'e') || jsY_accept(J, 'E')) {
if (jsY_accept(J, '-')) sign = -1;
else if (jsY_accept(J, '+')) sign = 1;
else sign = 1;
return sign * lexinteger(J);
}
return 0;
}
static int lexnumber(js_State *J)
{
double n;
double e;
if (jsY_accept(J, '0')) {
if (jsY_accept(J, 'x') || jsY_accept(J, 'X')) {
J->number = lexhex(J);
return TK_NUMBER;
}
if (jsY_isdec(J->lexchar))
jsY_error(J, "number with leading zero");
n = 0;
if (jsY_accept(J, '.'))
n += lexfraction(J);
} else if (jsY_accept(J, '.')) {
if (!jsY_isdec(J->lexchar))
return '.';
n = lexfraction(J);
} else {
n = lexinteger(J);
if (jsY_accept(J, '.'))
n += lexfraction(J);
}
e = lexexponent(J);
if (e < 0)
n /= pow(10, -e);
else if (e > 0)
n *= pow(10, e);
if (jsY_isidentifierstart(J->lexchar))
jsY_error(J, "number with letter suffix");
J->number = n;
return TK_NUMBER;
}
#else
static int lexnumber(js_State *J)
{
const char *s = J->source - 1;
if (jsY_accept(J, '0')) {
if (jsY_accept(J, 'x') || jsY_accept(J, 'X')) {
J->number = lexhex(J);
return TK_NUMBER;
}
if (jsY_isdec(J->lexchar))
jsY_error(J, "number with leading zero");
if (jsY_accept(J, '.')) {
while (jsY_isdec(J->lexchar))
jsY_next(J);
}
} else if (jsY_accept(J, '.')) {
if (!jsY_isdec(J->lexchar))
return '.';
while (jsY_isdec(J->lexchar))
jsY_next(J);
} else {
while (jsY_isdec(J->lexchar))
jsY_next(J);
if (jsY_accept(J, '.')) {
while (jsY_isdec(J->lexchar))
jsY_next(J);
}
}
if (jsY_accept(J, 'e') || jsY_accept(J, 'E')) {
if (J->lexchar == '-' || J->lexchar == '+')
jsY_next(J);
if (jsY_isdec(J->lexchar))
while (jsY_isdec(J->lexchar))
jsY_next(J);
else
jsY_error(J, "missing exponent");
}
if (jsY_isidentifierstart(J->lexchar))
jsY_error(J, "number with letter suffix");
J->number = js_strtod(s, NULL);
return TK_NUMBER;
}
#endif
static int lexescape(js_State *J)
{
int x = 0;
/* already consumed '\' */
if (jsY_accept(J, '\n'))
return 0;
switch (J->lexchar) {
case EOF: jsY_error(J, "unterminated escape sequence");
case 'u':
jsY_next(J);
if (!jsY_ishex(J->lexchar)) return 1; else { x |= jsY_tohex(J->lexchar) << 12; jsY_next(J); }
if (!jsY_ishex(J->lexchar)) return 1; else { x |= jsY_tohex(J->lexchar) << 8; jsY_next(J); }
if (!jsY_ishex(J->lexchar)) return 1; else { x |= jsY_tohex(J->lexchar) << 4; jsY_next(J); }
if (!jsY_ishex(J->lexchar)) return 1; else { x |= jsY_tohex(J->lexchar); jsY_next(J); }
textpush(J, x);
break;
case 'x':
jsY_next(J);
if (!jsY_ishex(J->lexchar)) return 1; else { x |= jsY_tohex(J->lexchar) << 4; jsY_next(J); }
if (!jsY_ishex(J->lexchar)) return 1; else { x |= jsY_tohex(J->lexchar); jsY_next(J); }
textpush(J, x);
break;
case '0': textpush(J, 0); jsY_next(J); break;
case '\\': textpush(J, '\\'); jsY_next(J); break;
case '\'': textpush(J, '\''); jsY_next(J); break;
case '"': textpush(J, '"'); jsY_next(J); break;
case 'b': textpush(J, '\b'); jsY_next(J); break;
case 'f': textpush(J, '\f'); jsY_next(J); break;
case 'n': textpush(J, '\n'); jsY_next(J); break;
case 'r': textpush(J, '\r'); jsY_next(J); break;
case 't': textpush(J, '\t'); jsY_next(J); break;
case 'v': textpush(J, '\v'); jsY_next(J); break;
default: textpush(J, J->lexchar); jsY_next(J); break;
}
return 0;
}
static int lexstring(js_State *J)
{
const char *s;
int q = J->lexchar;
jsY_next(J);
textinit(J);
while (J->lexchar != q) {
if (J->lexchar == EOF || J->lexchar == '\n')
jsY_error(J, "string not terminated");
if (jsY_accept(J, '\\')) {
if (lexescape(J))
jsY_error(J, "malformed escape sequence");
} else {
textpush(J, J->lexchar);
jsY_next(J);
}
}
jsY_expect(J, q);
s = textend(J);
J->text = js_intern(J, s);
return TK_STRING;
}
/* the ugliest language wart ever... */
static int isregexpcontext(int last)
{
switch (last) {
case ']':
case ')':
case '}':
case TK_IDENTIFIER:
case TK_NUMBER:
case TK_STRING:
case TK_FALSE:
case TK_NULL:
case TK_THIS:
case TK_TRUE:
return 0;
default:
return 1;
}
}
static int lexregexp(js_State *J)
{
const char *s;
int g, m, i;
int inclass = 0;
/* already consumed initial '/' */
textinit(J);
/* regexp body */
while (J->lexchar != '/' || inclass) {
if (J->lexchar == EOF || J->lexchar == '\n') {
jsY_error(J, "regular expression not terminated");
} else if (jsY_accept(J, '\\')) {
if (jsY_accept(J, '/')) {
textpush(J, '/');
} else {
textpush(J, '\\');
if (J->lexchar == EOF || J->lexchar == '\n')
jsY_error(J, "regular expression not terminated");
textpush(J, J->lexchar);
jsY_next(J);
}
} else {
if (J->lexchar == '[' && !inclass)
inclass = 1;
if (J->lexchar == ']' && inclass)
inclass = 0;
textpush(J, J->lexchar);
jsY_next(J);
}
}
jsY_expect(J, '/');
s = textend(J);
/* regexp flags */
g = i = m = 0;
while (jsY_isidentifierpart(J->lexchar)) {
if (jsY_accept(J, 'g')) ++g;
else if (jsY_accept(J, 'i')) ++i;
else if (jsY_accept(J, 'm')) ++m;
else jsY_error(J, "illegal flag in regular expression: %c", J->lexchar);
}
if (g > 1 || i > 1 || m > 1)
jsY_error(J, "duplicated flag in regular expression");
J->text = js_intern(J, s);
J->number = 0;
if (g) J->number += JS_REGEXP_G;
if (i) J->number += JS_REGEXP_I;
if (m) J->number += JS_REGEXP_M;
return TK_REGEXP;
}
/* simple "return [no Line Terminator here] ..." contexts */
static int isnlthcontext(int last)
{
switch (last) {
case TK_BREAK:
case TK_CONTINUE:
case TK_RETURN:
case TK_THROW:
return 1;
default:
return 0;
}
}
static int jsY_lexx(js_State *J)
{
J->newline = 0;
while (1) {
J->lexline = J->line; /* save location of beginning of token */
while (jsY_iswhite(J->lexchar))
jsY_next(J);
if (jsY_accept(J, '\n')) {
J->newline = 1;
if (isnlthcontext(J->lasttoken))
return ';';
continue;
}
if (jsY_accept(J, '/')) {
if (jsY_accept(J, '/')) {
lexlinecomment(J);
continue;
} else if (jsY_accept(J, '*')) {
if (lexcomment(J))
jsY_error(J, "multi-line comment not terminated");
continue;
} else if (isregexpcontext(J->lasttoken)) {
return lexregexp(J);
} else if (jsY_accept(J, '=')) {
return TK_DIV_ASS;
} else {
return '/';
}
}
if (J->lexchar >= '0' && J->lexchar <= '9') {
return lexnumber(J);
}
switch (J->lexchar) {
case '(': jsY_next(J); return '(';
case ')': jsY_next(J); return ')';
case ',': jsY_next(J); return ',';
case ':': jsY_next(J); return ':';
case ';': jsY_next(J); return ';';
case '?': jsY_next(J); return '?';
case '[': jsY_next(J); return '[';
case ']': jsY_next(J); return ']';
case '{': jsY_next(J); return '{';
case '}': jsY_next(J); return '}';
case '~': jsY_next(J); return '~';
case '\'':
case '"':
return lexstring(J);
case '.':
return lexnumber(J);
case '<':
jsY_next(J);
if (jsY_accept(J, '<')) {
if (jsY_accept(J, '='))
return TK_SHL_ASS;
return TK_SHL;
}
if (jsY_accept(J, '='))
return TK_LE;
return '<';
case '>':
jsY_next(J);
if (jsY_accept(J, '>')) {
if (jsY_accept(J, '>')) {
if (jsY_accept(J, '='))
return TK_USHR_ASS;
return TK_USHR;
}
if (jsY_accept(J, '='))
return TK_SHR_ASS;
return TK_SHR;
}
if (jsY_accept(J, '='))
return TK_GE;
return '>';
case '=':
jsY_next(J);
if (jsY_accept(J, '=')) {
if (jsY_accept(J, '='))
return TK_STRICTEQ;
return TK_EQ;
}
return '=';
case '!':
jsY_next(J);
if (jsY_accept(J, '=')) {
if (jsY_accept(J, '='))
return TK_STRICTNE;
return TK_NE;
}
return '!';
case '+':
jsY_next(J);
if (jsY_accept(J, '+'))
return TK_INC;
if (jsY_accept(J, '='))
return TK_ADD_ASS;
return '+';
case '-':
jsY_next(J);
if (jsY_accept(J, '-'))
return TK_DEC;
if (jsY_accept(J, '='))
return TK_SUB_ASS;
return '-';
case '*':
jsY_next(J);
if (jsY_accept(J, '='))
return TK_MUL_ASS;
return '*';
case '%':
jsY_next(J);
if (jsY_accept(J, '='))
return TK_MOD_ASS;
return '%';
case '&':
jsY_next(J);
if (jsY_accept(J, '&'))
return TK_AND;
if (jsY_accept(J, '='))
return TK_AND_ASS;
return '&';
case '|':
jsY_next(J);
if (jsY_accept(J, '|'))
return TK_OR;
if (jsY_accept(J, '='))
return TK_OR_ASS;
return '|';
case '^':
jsY_next(J);
if (jsY_accept(J, '='))
return TK_XOR_ASS;
return '^';
case EOF:
return 0; /* EOF */
}
/* Handle \uXXXX escapes in identifiers */
jsY_unescape(J);
if (jsY_isidentifierstart(J->lexchar)) {
textinit(J);
textpush(J, J->lexchar);
jsY_next(J);
jsY_unescape(J);
while (jsY_isidentifierpart(J->lexchar)) {
textpush(J, J->lexchar);
jsY_next(J);
jsY_unescape(J);
}
textend(J);
return jsY_findkeyword(J, J->lexbuf.text);
}
if (J->lexchar >= 0x20 && J->lexchar <= 0x7E)
jsY_error(J, "unexpected character: '%c'", J->lexchar);
jsY_error(J, "unexpected character: \\u%04X", J->lexchar);
}
}
void jsY_initlex(js_State *J, const char *filename, const char *source)
{
J->filename = filename;
J->source = source;
J->line = 1;
J->lasttoken = 0;
jsY_next(J); /* load first lookahead character */
}
int jsY_lex(js_State *J)
{
return J->lasttoken = jsY_lexx(J);
}
static int lexjsonnumber(js_State *J)
{
const char *s = J->source - 1;
if (J->lexchar == '-')
jsY_next(J);
if (J->lexchar == '0')
jsY_next(J);
else if (J->lexchar >= '1' && J->lexchar <= '9')
while (isdigit(J->lexchar))
jsY_next(J);
else
jsY_error(J, "unexpected non-digit");
if (jsY_accept(J, '.')) {
if (isdigit(J->lexchar))
while (isdigit(J->lexchar))
jsY_next(J);
else
jsY_error(J, "missing digits after decimal point");
}
if (jsY_accept(J, 'e') || jsY_accept(J, 'E')) {
if (J->lexchar == '-' || J->lexchar == '+')
jsY_next(J);
if (isdigit(J->lexchar))
while (isdigit(J->lexchar))
jsY_next(J);
else
jsY_error(J, "missing digits after exponent indicator");
}
J->number = js_strtod(s, NULL);
return TK_NUMBER;
}
static int lexjsonescape(js_State *J)
{
int x = 0;
/* already consumed '\' */
switch (J->lexchar) {
default: jsY_error(J, "invalid escape sequence");
case 'u':
jsY_next(J);
if (!jsY_ishex(J->lexchar)) return 1; else { x |= jsY_tohex(J->lexchar) << 12; jsY_next(J); }
if (!jsY_ishex(J->lexchar)) return 1; else { x |= jsY_tohex(J->lexchar) << 8; jsY_next(J); }
if (!jsY_ishex(J->lexchar)) return 1; else { x |= jsY_tohex(J->lexchar) << 4; jsY_next(J); }
if (!jsY_ishex(J->lexchar)) return 1; else { x |= jsY_tohex(J->lexchar); jsY_next(J); }
textpush(J, x);
break;
case '"': textpush(J, '"'); jsY_next(J); break;
case '\\': textpush(J, '\\'); jsY_next(J); break;
case '/': textpush(J, '/'); jsY_next(J); break;
case 'b': textpush(J, '\b'); jsY_next(J); break;
case 'f': textpush(J, '\f'); jsY_next(J); break;
case 'n': textpush(J, '\n'); jsY_next(J); break;
case 'r': textpush(J, '\r'); jsY_next(J); break;
case 't': textpush(J, '\t'); jsY_next(J); break;
}
return 0;
}
static int lexjsonstring(js_State *J)
{
const char *s;
textinit(J);
while (J->lexchar != '"') {
if (J->lexchar == EOF)
jsY_error(J, "unterminated string");
else if (J->lexchar < 32)
jsY_error(J, "invalid control character in string");
else if (jsY_accept(J, '\\'))
lexjsonescape(J);
else {
textpush(J, J->lexchar);
jsY_next(J);
}
}
jsY_expect(J, '"');
s = textend(J);
J->text = js_intern(J, s);
return TK_STRING;
}
int jsY_lexjson(js_State *J)
{
while (1) {
J->lexline = J->line; /* save location of beginning of token */
while (jsY_iswhite(J->lexchar) || J->lexchar == '\n')
jsY_next(J);
if ((J->lexchar >= '0' && J->lexchar <= '9') || J->lexchar == '-')
return lexjsonnumber(J);
switch (J->lexchar) {
case ',': jsY_next(J); return ',';
case ':': jsY_next(J); return ':';
case '[': jsY_next(J); return '[';
case ']': jsY_next(J); return ']';
case '{': jsY_next(J); return '{';
case '}': jsY_next(J); return '}';
case '"':
jsY_next(J);
return lexjsonstring(J);
case 'f':
jsY_next(J); jsY_expect(J, 'a'); jsY_expect(J, 'l'); jsY_expect(J, 's'); jsY_expect(J, 'e');
return TK_FALSE;
case 'n':
jsY_next(J); jsY_expect(J, 'u'); jsY_expect(J, 'l'); jsY_expect(J, 'l');
return TK_NULL;
case 't':
jsY_next(J); jsY_expect(J, 'r'); jsY_expect(J, 'u'); jsY_expect(J, 'e');
return TK_TRUE;
case EOF:
return 0; /* EOF */
}
if (J->lexchar >= 0x20 && J->lexchar <= 0x7E)
jsY_error(J, "unexpected character: '%c'", J->lexchar);
jsY_error(J, "unexpected character: \\u%04X", J->lexchar);
}
}

View File

@ -1,81 +0,0 @@
#ifndef js_lex_h
#define js_lex_h
enum
{
TK_IDENTIFIER = 256,
TK_NUMBER,
TK_STRING,
TK_REGEXP,
/* multi-character punctuators */
TK_LE,
TK_GE,
TK_EQ,
TK_NE,
TK_STRICTEQ,
TK_STRICTNE,
TK_SHL,
TK_SHR,
TK_USHR,
TK_AND,
TK_OR,
TK_ADD_ASS,
TK_SUB_ASS,
TK_MUL_ASS,
TK_DIV_ASS,
TK_MOD_ASS,
TK_SHL_ASS,
TK_SHR_ASS,
TK_USHR_ASS,
TK_AND_ASS,
TK_OR_ASS,
TK_XOR_ASS,
TK_INC,
TK_DEC,
/* keywords */
TK_BREAK,
TK_CASE,
TK_CATCH,
TK_CONTINUE,
TK_DEBUGGER,
TK_DEFAULT,
TK_DELETE,
TK_DO,
TK_ELSE,
TK_FALSE,
TK_FINALLY,
TK_FOR,
TK_FUNCTION,
TK_IF,
TK_IN,
TK_INSTANCEOF,
TK_NEW,
TK_NULL,
TK_RETURN,
TK_SWITCH,
TK_THIS,
TK_THROW,
TK_TRUE,
TK_TRY,
TK_TYPEOF,
TK_VAR,
TK_VOID,
TK_WHILE,
TK_WITH,
};
int jsY_iswhite(int c);
int jsY_isnewline(int c);
int jsY_ishex(int c);
int jsY_tohex(int c);
const char *jsY_tokenstring(int token);
int jsY_findword(const char *s, const char **list, int num);
void jsY_initlex(js_State *J, const char *filename, const char *source);
int jsY_lex(js_State *J);
int jsY_lexjson(js_State *J);
#endif

View File

@ -1,192 +0,0 @@
#include "jsi.h"
#include "jsvalue.h"
#include "jsbuiltin.h"
#include <time.h>
#define JS_RAND_MAX (0x7fffffff)
static unsigned int jsM_rand_temper(unsigned int x)
{
x ^= x>>11;
x ^= x<<7 & 0x9D2C5680;
x ^= x<<15 & 0xEFC60000;
x ^= x>>18;
return x;
}
static int jsM_rand_r(unsigned int *seed)
{
return jsM_rand_temper(*seed = *seed * 1103515245 + 12345)/2;
}
static double jsM_round(double x)
{
if (isnan(x)) return x;
if (isinf(x)) return x;
if (x == 0) return x;
if (x > 0 && x < 0.5) return 0;
if (x < 0 && x >= -0.5) return -0;
return floor(x + 0.5);
}
static void Math_abs(js_State *J)
{
js_pushnumber(J, fabs(js_tonumber(J, 1)));
}
static void Math_acos(js_State *J)
{
js_pushnumber(J, acos(js_tonumber(J, 1)));
}
static void Math_asin(js_State *J)
{
js_pushnumber(J, asin(js_tonumber(J, 1)));
}
static void Math_atan(js_State *J)
{
js_pushnumber(J, atan(js_tonumber(J, 1)));
}
static void Math_atan2(js_State *J)
{
double y = js_tonumber(J, 1);
double x = js_tonumber(J, 2);
js_pushnumber(J, atan2(y, x));
}
static void Math_ceil(js_State *J)
{
js_pushnumber(J, ceil(js_tonumber(J, 1)));
}
static void Math_cos(js_State *J)
{
js_pushnumber(J, cos(js_tonumber(J, 1)));
}
static void Math_exp(js_State *J)
{
js_pushnumber(J, exp(js_tonumber(J, 1)));
}
static void Math_floor(js_State *J)
{
js_pushnumber(J, floor(js_tonumber(J, 1)));
}
static void Math_log(js_State *J)
{
js_pushnumber(J, log(js_tonumber(J, 1)));
}
static void Math_pow(js_State *J)
{
double x = js_tonumber(J, 1);
double y = js_tonumber(J, 2);
if (!isfinite(y) && fabs(x) == 1)
js_pushnumber(J, NAN);
else
js_pushnumber(J, pow(x,y));
}
static void Math_random(js_State *J)
{
js_pushnumber(J, jsM_rand_r(&J->seed) / (JS_RAND_MAX + 1.0));
}
static void Math_round(js_State *J)
{
double x = js_tonumber(J, 1);
js_pushnumber(J, jsM_round(x));
}
static void Math_sin(js_State *J)
{
js_pushnumber(J, sin(js_tonumber(J, 1)));
}
static void Math_sqrt(js_State *J)
{
js_pushnumber(J, sqrt(js_tonumber(J, 1)));
}
static void Math_tan(js_State *J)
{
js_pushnumber(J, tan(js_tonumber(J, 1)));
}
static void Math_max(js_State *J)
{
int i, n = js_gettop(J);
double x = -INFINITY;
for (i = 1; i < n; ++i) {
double y = js_tonumber(J, i);
if (isnan(y)) {
x = y;
break;
}
if (signbit(x) == signbit(y))
x = x > y ? x : y;
else if (signbit(x))
x = y;
}
js_pushnumber(J, x);
}
static void Math_min(js_State *J)
{
int i, n = js_gettop(J);
double x = INFINITY;
for (i = 1; i < n; ++i) {
double y = js_tonumber(J, i);
if (isnan(y)) {
x = y;
break;
}
if (signbit(x) == signbit(y))
x = x < y ? x : y;
else if (signbit(y))
x = y;
}
js_pushnumber(J, x);
}
void jsB_initmath(js_State *J)
{
J->seed = time(NULL);
js_pushobject(J, jsV_newobject(J, JS_CMATH, J->Object_prototype));
{
jsB_propn(J, "E", 2.7182818284590452354);
jsB_propn(J, "LN10", 2.302585092994046);
jsB_propn(J, "LN2", 0.6931471805599453);
jsB_propn(J, "LOG2E", 1.4426950408889634);
jsB_propn(J, "LOG10E", 0.4342944819032518);
jsB_propn(J, "PI", 3.1415926535897932);
jsB_propn(J, "SQRT1_2", 0.7071067811865476);
jsB_propn(J, "SQRT2", 1.4142135623730951);
jsB_propf(J, "Math.abs", Math_abs, 1);
jsB_propf(J, "Math.acos", Math_acos, 1);
jsB_propf(J, "Math.asin", Math_asin, 1);
jsB_propf(J, "Math.atan", Math_atan, 1);
jsB_propf(J, "Math.atan2", Math_atan2, 2);
jsB_propf(J, "Math.ceil", Math_ceil, 1);
jsB_propf(J, "Math.cos", Math_cos, 1);
jsB_propf(J, "Math.exp", Math_exp, 1);
jsB_propf(J, "Math.floor", Math_floor, 1);
jsB_propf(J, "Math.log", Math_log, 1);
jsB_propf(J, "Math.max", Math_max, 0); /* 2 */
jsB_propf(J, "Math.min", Math_min, 0); /* 2 */
jsB_propf(J, "Math.pow", Math_pow, 2);
jsB_propf(J, "Math.random", Math_random, 0);
jsB_propf(J, "Math.round", Math_round, 1);
jsB_propf(J, "Math.sin", Math_sin, 1);
jsB_propf(J, "Math.sqrt", Math_sqrt, 1);
jsB_propf(J, "Math.tan", Math_tan, 1);
}
js_defglobal(J, "Math", JS_DONTENUM);
}

View File

@ -1,198 +0,0 @@
#include "jsi.h"
#include "jsvalue.h"
#include "jsbuiltin.h"
#if defined(_MSC_VER) && (_MSC_VER < 1700) /* VS2012 has stdint.h */
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endif
static void jsB_new_Number(js_State *J)
{
js_newnumber(J, js_gettop(J) > 1 ? js_tonumber(J, 1) : 0);
}
static void jsB_Number(js_State *J)
{
js_pushnumber(J, js_gettop(J) > 1 ? js_tonumber(J, 1) : 0);
}
static void Np_valueOf(js_State *J)
{
js_Object *self = js_toobject(J, 0);
if (self->type != JS_CNUMBER) js_typeerror(J, "not a number");
js_pushnumber(J, self->u.number);
}
static void Np_toString(js_State *J)
{
char buf[100];
js_Object *self = js_toobject(J, 0);
int radix = js_isundefined(J, 1) ? 10 : js_tointeger(J, 1);
if (self->type != JS_CNUMBER)
js_typeerror(J, "not a number");
if (radix == 10) {
js_pushstring(J, jsV_numbertostring(J, buf, self->u.number));
return;
}
if (radix < 2 || radix > 36)
js_rangeerror(J, "invalid radix");
/* lame number to string conversion for any radix from 2 to 36 */
{
static const char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
double number = self->u.number;
int sign = self->u.number < 0;
js_Buffer *sb = NULL;
uint64_t u, limit = ((uint64_t)1<<52);
int ndigits, exp, point;
if (number == 0) { js_pushstring(J, "0"); return; }
if (isnan(number)) { js_pushstring(J, "NaN"); return; }
if (isinf(number)) { js_pushstring(J, sign ? "-Infinity" : "Infinity"); return; }
if (sign)
number = -number;
/* fit as many digits as we want in an int */
exp = 0;
while (number * pow(radix, exp) > limit)
--exp;
while (number * pow(radix, exp+1) < limit)
++exp;
u = number * pow(radix, exp) + 0.5;
/* trim trailing zeros */
while (u > 0 && (u % radix) == 0) {
u /= radix;
--exp;
}
/* serialize digits */
ndigits = 0;
while (u > 0) {
buf[ndigits++] = digits[u % radix];
u /= radix;
}
point = ndigits - exp;
if (js_try(J)) {
js_free(J, sb);
js_throw(J);
}
if (sign)
js_putc(J, &sb, '-');
if (point <= 0) {
js_putc(J, &sb, '0');
js_putc(J, &sb, '.');
while (point++ < 0)
js_putc(J, &sb, '0');
while (ndigits-- > 0)
js_putc(J, &sb, buf[ndigits]);
} else {
while (ndigits-- > 0) {
js_putc(J, &sb, buf[ndigits]);
if (--point == 0 && ndigits > 0)
js_putc(J, &sb, '.');
}
while (point-- > 0)
js_putc(J, &sb, '0');
}
js_putc(J, &sb, 0);
js_pushstring(J, sb->s);
js_endtry(J);
js_free(J, sb);
}
}
/* Customized ToString() on a number */
static void numtostr(js_State *J, const char *fmt, int w, double n)
{
/* buf needs to fit printf("%.20f", 1e20) */
char buf[50], *e;
sprintf(buf, fmt, w, n);
e = strchr(buf, 'e');
if (e) {
int exp = atoi(e+1);
sprintf(e, "e%+d", exp);
}
js_pushstring(J, buf);
}
static void Np_toFixed(js_State *J)
{
js_Object *self = js_toobject(J, 0);
int width = js_tointeger(J, 1);
char buf[32];
double x;
if (self->type != JS_CNUMBER) js_typeerror(J, "not a number");
if (width < 0) js_rangeerror(J, "precision %d out of range", width);
if (width > 20) js_rangeerror(J, "precision %d out of range", width);
x = self->u.number;
if (isnan(x) || isinf(x) || x <= -1e21 || x >= 1e21)
js_pushstring(J, jsV_numbertostring(J, buf, x));
else
numtostr(J, "%.*f", width, x);
}
static void Np_toExponential(js_State *J)
{
js_Object *self = js_toobject(J, 0);
int width = js_tointeger(J, 1);
char buf[32];
double x;
if (self->type != JS_CNUMBER) js_typeerror(J, "not a number");
if (width < 0) js_rangeerror(J, "precision %d out of range", width);
if (width > 20) js_rangeerror(J, "precision %d out of range", width);
x = self->u.number;
if (isnan(x) || isinf(x))
js_pushstring(J, jsV_numbertostring(J, buf, x));
else
numtostr(J, "%.*e", width, self->u.number);
}
static void Np_toPrecision(js_State *J)
{
js_Object *self = js_toobject(J, 0);
int width = js_tointeger(J, 1);
char buf[32];
double x;
if (self->type != JS_CNUMBER) js_typeerror(J, "not a number");
if (width < 1) js_rangeerror(J, "precision %d out of range", width);
if (width > 21) js_rangeerror(J, "precision %d out of range", width);
x = self->u.number;
if (isnan(x) || isinf(x))
js_pushstring(J, jsV_numbertostring(J, buf, x));
else
numtostr(J, "%.*g", width, self->u.number);
}
void jsB_initnumber(js_State *J)
{
J->Number_prototype->u.number = 0;
js_pushobject(J, J->Number_prototype);
{
jsB_propf(J, "Number.prototype.valueOf", Np_valueOf, 0);
jsB_propf(J, "Number.prototype.toString", Np_toString, 1);
jsB_propf(J, "Number.prototype.toLocaleString", Np_toString, 0);
jsB_propf(J, "Number.prototype.toFixed", Np_toFixed, 1);
jsB_propf(J, "Number.prototype.toExponential", Np_toExponential, 1);
jsB_propf(J, "Number.prototype.toPrecision", Np_toPrecision, 1);
}
js_newcconstructor(J, jsB_Number, jsB_new_Number, "Number", 0); /* 1 */
{
jsB_propn(J, "MAX_VALUE", 1.7976931348623157e+308);
jsB_propn(J, "MIN_VALUE", 5e-324);
jsB_propn(J, "NaN", NAN);
jsB_propn(J, "NEGATIVE_INFINITY", -INFINITY);
jsB_propn(J, "POSITIVE_INFINITY", INFINITY);
}
js_defglobal(J, "Number", JS_DONTENUM);
}

View File

@ -1,521 +0,0 @@
#include "jsi.h"
#include "jsvalue.h"
#include "jsbuiltin.h"
static void jsB_new_Object(js_State *J)
{
if (js_isundefined(J, 1) || js_isnull(J, 1))
js_newobject(J);
else
js_pushobject(J, js_toobject(J, 1));
}
static void jsB_Object(js_State *J)
{
if (js_isundefined(J, 1) || js_isnull(J, 1))
js_newobject(J);
else
js_pushobject(J, js_toobject(J, 1));
}
static void Op_toString(js_State *J)
{
if (js_isundefined(J, 0))
js_pushliteral(J, "[object Undefined]");
else if (js_isnull(J, 0))
js_pushliteral(J, "[object Null]");
else {
js_Object *self = js_toobject(J, 0);
switch (self->type) {
case JS_COBJECT: js_pushliteral(J, "[object Object]"); break;
case JS_CARRAY: js_pushliteral(J, "[object Array]"); break;
case JS_CFUNCTION: js_pushliteral(J, "[object Function]"); break;
case JS_CSCRIPT: js_pushliteral(J, "[object Function]"); break;
case JS_CEVAL: js_pushliteral(J, "[object Function]"); break;
case JS_CCFUNCTION: js_pushliteral(J, "[object Function]"); break;
case JS_CERROR: js_pushliteral(J, "[object Error]"); break;
case JS_CBOOLEAN: js_pushliteral(J, "[object Boolean]"); break;
case JS_CNUMBER: js_pushliteral(J, "[object Number]"); break;
case JS_CSTRING: js_pushliteral(J, "[object String]"); break;
case JS_CREGEXP: js_pushliteral(J, "[object RegExp]"); break;
case JS_CDATE: js_pushliteral(J, "[object Date]"); break;
case JS_CMATH: js_pushliteral(J, "[object Math]"); break;
case JS_CJSON: js_pushliteral(J, "[object JSON]"); break;
case JS_CARGUMENTS: js_pushliteral(J, "[object Arguments]"); break;
case JS_CITERATOR: js_pushliteral(J, "[object Iterator]"); break;
case JS_CUSERDATA:
js_pushliteral(J, "[object ");
js_pushliteral(J, self->u.user.tag);
js_concat(J);
js_pushliteral(J, "]");
js_concat(J);
break;
}
}
}
static void Op_valueOf(js_State *J)
{
js_copy(J, 0);
}
static void Op_hasOwnProperty(js_State *J)
{
js_Object *self = js_toobject(J, 0);
const char *name = js_tostring(J, 1);
js_Property *ref = jsV_getownproperty(J, self, name);
js_pushboolean(J, ref != NULL);
}
static void Op_isPrototypeOf(js_State *J)
{
js_Object *self = js_toobject(J, 0);
if (js_isobject(J, 1)) {
js_Object *V = js_toobject(J, 1);
do {
V = V->prototype;
if (V == self) {
js_pushboolean(J, 1);
return;
}
} while (V);
}
js_pushboolean(J, 0);
}
static void Op_propertyIsEnumerable(js_State *J)
{
js_Object *self = js_toobject(J, 0);
const char *name = js_tostring(J, 1);
js_Property *ref = jsV_getownproperty(J, self, name);
js_pushboolean(J, ref && !(ref->atts & JS_DONTENUM));
}
static void O_getPrototypeOf(js_State *J)
{
js_Object *obj;
if (!js_isobject(J, 1))
js_typeerror(J, "not an object");
obj = js_toobject(J, 1);
if (obj->prototype)
js_pushobject(J, obj->prototype);
else
js_pushnull(J);
}
static void O_getOwnPropertyDescriptor(js_State *J)
{
js_Object *obj;
js_Property *ref;
if (!js_isobject(J, 1))
js_typeerror(J, "not an object");
obj = js_toobject(J, 1);
ref = jsV_getproperty(J, obj, js_tostring(J, 2));
if (!ref)
js_pushundefined(J);
else {
js_newobject(J);
if (!ref->getter && !ref->setter) {
js_pushvalue(J, ref->value);
js_setproperty(J, -2, "value");
js_pushboolean(J, !(ref->atts & JS_READONLY));
js_setproperty(J, -2, "writable");
} else {
if (ref->getter)
js_pushobject(J, ref->getter);
else
js_pushundefined(J);
js_setproperty(J, -2, "get");
if (ref->setter)
js_pushobject(J, ref->setter);
else
js_pushundefined(J);
js_setproperty(J, -2, "set");
}
js_pushboolean(J, !(ref->atts & JS_DONTENUM));
js_setproperty(J, -2, "enumerable");
js_pushboolean(J, !(ref->atts & JS_DONTCONF));
js_setproperty(J, -2, "configurable");
}
}
static int O_getOwnPropertyNames_walk(js_State *J, js_Property *ref, int i)
{
if (ref->left->level)
i = O_getOwnPropertyNames_walk(J, ref->left, i);
js_pushliteral(J, ref->name);
js_setindex(J, -2, i++);
if (ref->right->level)
i = O_getOwnPropertyNames_walk(J, ref->right, i);
return i;
}
static void O_getOwnPropertyNames(js_State *J)
{
js_Object *obj;
int k;
int i;
if (!js_isobject(J, 1))
js_typeerror(J, "not an object");
obj = js_toobject(J, 1);
js_newarray(J);
if (obj->properties->level)
i = O_getOwnPropertyNames_walk(J, obj->properties, 0);
else
i = 0;
if (obj->type == JS_CARRAY) {
js_pushliteral(J, "length");
js_setindex(J, -2, i++);
}
if (obj->type == JS_CSTRING) {
js_pushliteral(J, "length");
js_setindex(J, -2, i++);
for (k = 0; k < obj->u.s.length; ++k) {
js_pushnumber(J, k);
js_setindex(J, -2, i++);
}
}
if (obj->type == JS_CREGEXP) {
js_pushliteral(J, "source");
js_setindex(J, -2, i++);
js_pushliteral(J, "global");
js_setindex(J, -2, i++);
js_pushliteral(J, "ignoreCase");
js_setindex(J, -2, i++);
js_pushliteral(J, "multiline");
js_setindex(J, -2, i++);
js_pushliteral(J, "lastIndex");
js_setindex(J, -2, i++);
}
}
static void ToPropertyDescriptor(js_State *J, js_Object *obj, const char *name, js_Object *desc)
{
int haswritable = 0;
int hasvalue = 0;
int enumerable = 0;
int configurable = 0;
int writable = 0;
int atts = 0;
js_pushobject(J, obj);
js_pushobject(J, desc);
if (js_hasproperty(J, -1, "writable")) {
haswritable = 1;
writable = js_toboolean(J, -1);
js_pop(J, 1);
}
if (js_hasproperty(J, -1, "enumerable")) {
enumerable = js_toboolean(J, -1);
js_pop(J, 1);
}
if (js_hasproperty(J, -1, "configurable")) {
configurable = js_toboolean(J, -1);
js_pop(J, 1);
}
if (js_hasproperty(J, -1, "value")) {
hasvalue = 1;
js_setproperty(J, -3, name);
}
if (!writable) atts |= JS_READONLY;
if (!enumerable) atts |= JS_DONTENUM;
if (!configurable) atts |= JS_DONTCONF;
if (js_hasproperty(J, -1, "get")) {
if (haswritable || hasvalue)
js_typeerror(J, "value/writable and get/set attributes are exclusive");
} else {
js_pushundefined(J);
}
if (js_hasproperty(J, -2, "set")) {
if (haswritable || hasvalue)
js_typeerror(J, "value/writable and get/set attributes are exclusive");
} else {
js_pushundefined(J);
}
js_defaccessor(J, -4, name, atts);
js_pop(J, 2);
}
static void O_defineProperty(js_State *J)
{
if (!js_isobject(J, 1)) js_typeerror(J, "not an object");
if (!js_isobject(J, 3)) js_typeerror(J, "not an object");
ToPropertyDescriptor(J, js_toobject(J, 1), js_tostring(J, 2), js_toobject(J, 3));
js_copy(J, 1);
}
static void O_defineProperties_walk(js_State *J, js_Property *ref)
{
if (ref->left->level)
O_defineProperties_walk(J, ref->left);
if (!(ref->atts & JS_DONTENUM)) {
js_pushvalue(J, ref->value);
ToPropertyDescriptor(J, js_toobject(J, 1), ref->name, js_toobject(J, -1));
js_pop(J, 1);
}
if (ref->right->level)
O_defineProperties_walk(J, ref->right);
}
static void O_defineProperties(js_State *J)
{
js_Object *props;
if (!js_isobject(J, 1)) js_typeerror(J, "not an object");
if (!js_isobject(J, 2)) js_typeerror(J, "not an object");
props = js_toobject(J, 2);
if (props->properties->level)
O_defineProperties_walk(J, props->properties);
js_copy(J, 1);
}
static void O_create_walk(js_State *J, js_Object *obj, js_Property *ref)
{
if (ref->left->level)
O_create_walk(J, obj, ref->left);
if (!(ref->atts & JS_DONTENUM)) {
if (ref->value.type != JS_TOBJECT)
js_typeerror(J, "not an object");
ToPropertyDescriptor(J, obj, ref->name, ref->value.u.object);
}
if (ref->right->level)
O_create_walk(J, obj, ref->right);
}
static void O_create(js_State *J)
{
js_Object *obj;
js_Object *proto;
js_Object *props;
if (js_isobject(J, 1))
proto = js_toobject(J, 1);
else if (js_isnull(J, 1))
proto = NULL;
else
js_typeerror(J, "not an object or null");
obj = jsV_newobject(J, JS_COBJECT, proto);
js_pushobject(J, obj);
if (js_isdefined(J, 2)) {
if (!js_isobject(J, 2))
js_typeerror(J, "not an object");
props = js_toobject(J, 2);
if (props->properties->level)
O_create_walk(J, obj, props->properties);
}
}
static int O_keys_walk(js_State *J, js_Property *ref, int i)
{
if (ref->left->level)
i = O_keys_walk(J, ref->left, i);
if (!(ref->atts & JS_DONTENUM)) {
js_pushliteral(J, ref->name);
js_setindex(J, -2, i++);
}
if (ref->right->level)
i = O_keys_walk(J, ref->right, i);
return i;
}
static void O_keys(js_State *J)
{
js_Object *obj;
int i, k;
if (!js_isobject(J, 1))
js_typeerror(J, "not an object");
obj = js_toobject(J, 1);
js_newarray(J);
if (obj->properties->level)
i = O_keys_walk(J, obj->properties, 0);
else
i = 0;
if (obj->type == JS_CSTRING) {
for (k = 0; k < obj->u.s.length; ++k) {
js_pushnumber(J, k);
js_setindex(J, -2, i++);
}
}
}
static void O_preventExtensions(js_State *J)
{
if (!js_isobject(J, 1))
js_typeerror(J, "not an object");
js_toobject(J, 1)->extensible = 0;
js_copy(J, 1);
}
static void O_isExtensible(js_State *J)
{
if (!js_isobject(J, 1))
js_typeerror(J, "not an object");
js_pushboolean(J, js_toobject(J, 1)->extensible);
}
static void O_seal_walk(js_State *J, js_Property *ref)
{
if (ref->left->level)
O_seal_walk(J, ref->left);
ref->atts |= JS_DONTCONF;
if (ref->right->level)
O_seal_walk(J, ref->right);
}
static void O_seal(js_State *J)
{
js_Object *obj;
if (!js_isobject(J, 1))
js_typeerror(J, "not an object");
obj = js_toobject(J, 1);
obj->extensible = 0;
if (obj->properties->level)
O_seal_walk(J, obj->properties);
js_copy(J, 1);
}
static int O_isSealed_walk(js_State *J, js_Property *ref)
{
if (ref->left->level)
if (!O_isSealed_walk(J, ref->left))
return 0;
if (!(ref->atts & JS_DONTCONF))
return 0;
if (ref->right->level)
if (!O_isSealed_walk(J, ref->right))
return 0;
return 1;
}
static void O_isSealed(js_State *J)
{
js_Object *obj;
if (!js_isobject(J, 1))
js_typeerror(J, "not an object");
obj = js_toobject(J, 1);
if (obj->extensible) {
js_pushboolean(J, 0);
return;
}
if (obj->properties->level)
js_pushboolean(J, O_isSealed_walk(J, obj->properties));
else
js_pushboolean(J, 1);
}
static void O_freeze_walk(js_State *J, js_Property *ref)
{
if (ref->left->level)
O_freeze_walk(J, ref->left);
ref->atts |= JS_READONLY | JS_DONTCONF;
if (ref->right->level)
O_freeze_walk(J, ref->right);
}
static void O_freeze(js_State *J)
{
js_Object *obj;
if (!js_isobject(J, 1))
js_typeerror(J, "not an object");
obj = js_toobject(J, 1);
obj->extensible = 0;
if (obj->properties->level)
O_freeze_walk(J, obj->properties);
js_copy(J, 1);
}
static int O_isFrozen_walk(js_State *J, js_Property *ref)
{
if (ref->left->level)
if (!O_isFrozen_walk(J, ref->left))
return 0;
if (!(ref->atts & JS_READONLY))
return 0;
if (!(ref->atts & JS_DONTCONF))
return 0;
if (ref->right->level)
if (!O_isFrozen_walk(J, ref->right))
return 0;
return 1;
}
static void O_isFrozen(js_State *J)
{
js_Object *obj;
if (!js_isobject(J, 1))
js_typeerror(J, "not an object");
obj = js_toobject(J, 1);
if (obj->properties->level) {
if (!O_isFrozen_walk(J, obj->properties)) {
js_pushboolean(J, 0);
return;
}
}
js_pushboolean(J, !obj->extensible);
}
void jsB_initobject(js_State *J)
{
js_pushobject(J, J->Object_prototype);
{
jsB_propf(J, "Object.prototype.toString", Op_toString, 0);
jsB_propf(J, "Object.prototype.toLocaleString", Op_toString, 0);
jsB_propf(J, "Object.prototype.valueOf", Op_valueOf, 0);
jsB_propf(J, "Object.prototype.hasOwnProperty", Op_hasOwnProperty, 1);
jsB_propf(J, "Object.prototype.isPrototypeOf", Op_isPrototypeOf, 1);
jsB_propf(J, "Object.prototype.propertyIsEnumerable", Op_propertyIsEnumerable, 1);
}
js_newcconstructor(J, jsB_Object, jsB_new_Object, "Object", 1);
{
/* ES5 */
jsB_propf(J, "Object.getPrototypeOf", O_getPrototypeOf, 1);
jsB_propf(J, "Object.getOwnPropertyDescriptor", O_getOwnPropertyDescriptor, 2);
jsB_propf(J, "Object.getOwnPropertyNames", O_getOwnPropertyNames, 1);
jsB_propf(J, "Object.create", O_create, 2);
jsB_propf(J, "Object.defineProperty", O_defineProperty, 3);
jsB_propf(J, "Object.defineProperties", O_defineProperties, 2);
jsB_propf(J, "Object.seal", O_seal, 1);
jsB_propf(J, "Object.freeze", O_freeze, 1);
jsB_propf(J, "Object.preventExtensions", O_preventExtensions, 1);
jsB_propf(J, "Object.isSealed", O_isSealed, 1);
jsB_propf(J, "Object.isFrozen", O_isFrozen, 1);
jsB_propf(J, "Object.isExtensible", O_isExtensible, 1);
jsB_propf(J, "Object.keys", O_keys, 1);
}
js_defglobal(J, "Object", JS_DONTENUM);
}

View File

@ -1,414 +0,0 @@
#include "jsi.h"
#include "jslex.h"
#include "jsvalue.h"
#include "jsbuiltin.h"
#include "utf.h"
int js_isnumberobject(js_State *J, int idx)
{
return js_isobject(J, idx) && js_toobject(J, idx)->type == JS_CNUMBER;
}
int js_isstringobject(js_State *J, int idx)
{
return js_isobject(J, idx) && js_toobject(J, idx)->type == JS_CSTRING;
}
static void jsonnext(js_State *J)
{
J->lookahead = jsY_lexjson(J);
}
static int jsonaccept(js_State *J, int t)
{
if (J->lookahead == t) {
jsonnext(J);
return 1;
}
return 0;
}
static void jsonexpect(js_State *J, int t)
{
if (!jsonaccept(J, t))
js_syntaxerror(J, "JSON: unexpected token: %s (expected %s)",
jsY_tokenstring(J->lookahead), jsY_tokenstring(t));
}
static void jsonvalue(js_State *J)
{
int i;
const char *name;
switch (J->lookahead) {
case TK_STRING:
js_pushstring(J, J->text);
jsonnext(J);
break;
case TK_NUMBER:
js_pushnumber(J, J->number);
jsonnext(J);
break;
case '{':
js_newobject(J);
jsonnext(J);
if (jsonaccept(J, '}'))
return;
do {
if (J->lookahead != TK_STRING)
js_syntaxerror(J, "JSON: unexpected token: %s (expected string)", jsY_tokenstring(J->lookahead));
name = J->text;
jsonnext(J);
jsonexpect(J, ':');
jsonvalue(J);
js_setproperty(J, -2, name);
} while (jsonaccept(J, ','));
jsonexpect(J, '}');
break;
case '[':
js_newarray(J);
jsonnext(J);
i = 0;
if (jsonaccept(J, ']'))
return;
do {
jsonvalue(J);
js_setindex(J, -2, i++);
} while (jsonaccept(J, ','));
jsonexpect(J, ']');
break;
case TK_TRUE:
js_pushboolean(J, 1);
jsonnext(J);
break;
case TK_FALSE:
js_pushboolean(J, 0);
jsonnext(J);
break;
case TK_NULL:
js_pushnull(J);
jsonnext(J);
break;
default:
js_syntaxerror(J, "JSON: unexpected token: %s", jsY_tokenstring(J->lookahead));
}
}
static void jsonrevive(js_State *J, const char *name)
{
const char *key;
char buf[32];
/* revive is in 2 */
/* holder is in -1 */
js_getproperty(J, -1, name); /* get value from holder */
if (js_isobject(J, -1)) {
if (js_isarray(J, -1)) {
int i = 0;
int n = js_getlength(J, -1);
for (i = 0; i < n; ++i) {
jsonrevive(J, js_itoa(buf, i));
if (js_isundefined(J, -1)) {
js_pop(J, 1);
js_delproperty(J, -1, buf);
} else {
js_setproperty(J, -2, buf);
}
}
} else {
js_pushiterator(J, -1, 1);
while ((key = js_nextiterator(J, -1))) {
js_rot2(J);
jsonrevive(J, key);
if (js_isundefined(J, -1)) {
js_pop(J, 1);
js_delproperty(J, -1, key);
} else {
js_setproperty(J, -2, key);
}
js_rot2(J);
}
js_pop(J, 1);
}
}
js_copy(J, 2); /* reviver function */
js_copy(J, -3); /* holder as this */
js_pushstring(J, name); /* name */
js_copy(J, -4); /* value */
js_call(J, 2);
js_rot2pop1(J); /* pop old value, leave new value on stack */
}
static void JSON_parse(js_State *J)
{
const char *source = js_tostring(J, 1);
jsY_initlex(J, "JSON", source);
jsonnext(J);
if (js_iscallable(J, 2)) {
js_newobject(J);
jsonvalue(J);
js_defproperty(J, -2, "", 0);
jsonrevive(J, "");
} else {
jsonvalue(J);
}
}
static void fmtnum(js_State *J, js_Buffer **sb, double n)
{
if (isnan(n)) js_puts(J, sb, "null");
else if (isinf(n)) js_puts(J, sb, "null");
else if (n == 0) js_puts(J, sb, "0");
else {
char buf[40];
js_puts(J, sb, jsV_numbertostring(J, buf, n));
}
}
static void fmtstr(js_State *J, js_Buffer **sb, const char *s)
{
static const char *HEX = "0123456789ABCDEF";
int i, n;
Rune c;
js_putc(J, sb, '"');
while (*s) {
n = chartorune(&c, s);
switch (c) {
case '"': js_puts(J, sb, "\\\""); break;
case '\\': js_puts(J, sb, "\\\\"); break;
case '\b': js_puts(J, sb, "\\b"); break;
case '\f': js_puts(J, sb, "\\f"); break;
case '\n': js_puts(J, sb, "\\n"); break;
case '\r': js_puts(J, sb, "\\r"); break;
case '\t': js_puts(J, sb, "\\t"); break;
default:
if (c < ' ') {
js_putc(J, sb, '\\');
js_putc(J, sb, 'u');
js_putc(J, sb, HEX[(c>>12)&15]);
js_putc(J, sb, HEX[(c>>8)&15]);
js_putc(J, sb, HEX[(c>>4)&15]);
js_putc(J, sb, HEX[c&15]);
} else if (c < 128) {
js_putc(J, sb, c);
} else {
for (i = 0; i < n; ++i)
js_putc(J, sb, s[i]);
}
break;
}
s += n;
}
js_putc(J, sb, '"');
}
static void fmtindent(js_State *J, js_Buffer **sb, const char *gap, int level)
{
js_putc(J, sb, '\n');
while (level--)
js_puts(J, sb, gap);
}
static int fmtvalue(js_State *J, js_Buffer **sb, const char *key, const char *gap, int level);
static int filterprop(js_State *J, const char *key)
{
int i, n, found;
/* replacer/property-list is in stack slot 2 */
if (js_isarray(J, 2)) {
found = 0;
n = js_getlength(J, 2);
for (i = 0; i < n && !found; ++i) {
js_getindex(J, 2, i);
if (js_isstring(J, -1) || js_isnumber(J, -1) ||
js_isstringobject(J, -1) || js_isnumberobject(J, -1))
found = !strcmp(key, js_tostring(J, -1));
js_pop(J, 1);
}
return found;
}
return 1;
}
static void fmtobject(js_State *J, js_Buffer **sb, js_Object *obj, const char *gap, int level)
{
const char *key;
int save;
int i, n;
n = js_gettop(J) - 1;
for (i = 4; i < n; ++i)
if (js_isobject(J, i))
if (js_toobject(J, i) == js_toobject(J, -1))
js_typeerror(J, "cyclic object value");
n = 0;
js_putc(J, sb, '{');
js_pushiterator(J, -1, 1);
while ((key = js_nextiterator(J, -1))) {
if (filterprop(J, key)) {
save = (*sb)->n;
if (n) js_putc(J, sb, ',');
if (gap) fmtindent(J, sb, gap, level + 1);
fmtstr(J, sb, key);
js_putc(J, sb, ':');
if (gap)
js_putc(J, sb, ' ');
js_rot2(J);
if (!fmtvalue(J, sb, key, gap, level + 1))
(*sb)->n = save;
else
++n;
js_rot2(J);
}
}
js_pop(J, 1);
if (gap && n) fmtindent(J, sb, gap, level);
js_putc(J, sb, '}');
}
static void fmtarray(js_State *J, js_Buffer **sb, const char *gap, int level)
{
int n, i;
char buf[32];
n = js_gettop(J) - 1;
for (i = 4; i < n; ++i)
if (js_isobject(J, i))
if (js_toobject(J, i) == js_toobject(J, -1))
js_typeerror(J, "cyclic object value");
js_putc(J, sb, '[');
n = js_getlength(J, -1);
for (i = 0; i < n; ++i) {
if (i) js_putc(J, sb, ',');
if (gap) fmtindent(J, sb, gap, level + 1);
if (!fmtvalue(J, sb, js_itoa(buf, i), gap, level + 1))
js_puts(J, sb, "null");
}
if (gap && n) fmtindent(J, sb, gap, level);
js_putc(J, sb, ']');
}
static int fmtvalue(js_State *J, js_Buffer **sb, const char *key, const char *gap, int level)
{
/* replacer/property-list is in 2 */
/* holder is in -1 */
js_getproperty(J, -1, key);
if (js_isobject(J, -1)) {
if (js_hasproperty(J, -1, "toJSON")) {
if (js_iscallable(J, -1)) {
js_copy(J, -2);
js_pushstring(J, key);
js_call(J, 1);
js_rot2pop1(J);
} else {
js_pop(J, 1);
}
}
}
if (js_iscallable(J, 2)) {
js_copy(J, 2); /* replacer function */
js_copy(J, -3); /* holder as this */
js_pushstring(J, key); /* name */
js_copy(J, -4); /* old value */
js_call(J, 2);
js_rot2pop1(J); /* pop old value, leave new value on stack */
}
if (js_isobject(J, -1) && !js_iscallable(J, -1)) {
js_Object *obj = js_toobject(J, -1);
switch (obj->type) {
case JS_CNUMBER: fmtnum(J, sb, obj->u.number); break;
case JS_CSTRING: fmtstr(J, sb, obj->u.s.string); break;
case JS_CBOOLEAN: js_puts(J, sb, obj->u.boolean ? "true" : "false"); break;
case JS_CARRAY: fmtarray(J, sb, gap, level); break;
default: fmtobject(J, sb, obj, gap, level); break;
}
}
else if (js_isboolean(J, -1))
js_puts(J, sb, js_toboolean(J, -1) ? "true" : "false");
else if (js_isnumber(J, -1))
fmtnum(J, sb, js_tonumber(J, -1));
else if (js_isstring(J, -1))
fmtstr(J, sb, js_tostring(J, -1));
else if (js_isnull(J, -1))
js_puts(J, sb, "null");
else {
js_pop(J, 1);
return 0;
}
js_pop(J, 1);
return 1;
}
static void JSON_stringify(js_State *J)
{
js_Buffer *sb = NULL;
char buf[12];
const char *s, *gap;
int n;
gap = NULL;
if (js_isnumber(J, 3) || js_isnumberobject(J, 3)) {
n = js_tointeger(J, 3);
if (n < 0) n = 0;
if (n > 10) n = 10;
memset(buf, ' ', n);
buf[n] = 0;
if (n > 0) gap = buf;
} else if (js_isstring(J, 3) || js_isstringobject(J, 3)) {
s = js_tostring(J, 3);
n = strlen(s);
if (n > 10) n = 10;
memcpy(buf, s, n);
buf[n] = 0;
if (n > 0) gap = buf;
}
if (js_try(J)) {
js_free(J, sb);
js_throw(J);
}
js_newobject(J); /* wrapper */
js_copy(J, 1);
js_defproperty(J, -2, "", 0);
if (!fmtvalue(J, &sb, "", gap, 0)) {
js_pushundefined(J);
} else {
js_putc(J, &sb, 0);
js_pushstring(J, sb ? sb->s : "");
js_rot2pop1(J);
}
js_endtry(J);
js_free(J, sb);
}
void jsB_initjson(js_State *J)
{
js_pushobject(J, jsV_newobject(J, JS_CJSON, J->Object_prototype));
{
jsB_propf(J, "JSON.parse", JSON_parse, 2);
jsB_propf(J, "JSON.stringify", JSON_stringify, 3);
}
js_defglobal(J, "JSON", JS_DONTENUM);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,146 +0,0 @@
#ifndef js_parse_h
#define js_parse_h
enum js_AstType
{
AST_LIST,
AST_FUNDEC,
AST_IDENTIFIER,
EXP_IDENTIFIER,
EXP_NUMBER,
EXP_STRING,
EXP_REGEXP,
/* literals */
EXP_UNDEF, /* for array elisions */
EXP_NULL,
EXP_TRUE,
EXP_FALSE,
EXP_THIS,
EXP_ARRAY,
EXP_OBJECT,
EXP_PROP_VAL,
EXP_PROP_GET,
EXP_PROP_SET,
EXP_FUN,
/* expressions */
EXP_INDEX,
EXP_MEMBER,
EXP_CALL,
EXP_NEW,
EXP_POSTINC,
EXP_POSTDEC,
EXP_DELETE,
EXP_VOID,
EXP_TYPEOF,
EXP_PREINC,
EXP_PREDEC,
EXP_POS,
EXP_NEG,
EXP_BITNOT,
EXP_LOGNOT,
EXP_MOD,
EXP_DIV,
EXP_MUL,
EXP_SUB,
EXP_ADD,
EXP_USHR,
EXP_SHR,
EXP_SHL,
EXP_IN,
EXP_INSTANCEOF,
EXP_GE,
EXP_LE,
EXP_GT,
EXP_LT,
EXP_STRICTNE,
EXP_STRICTEQ,
EXP_NE,
EXP_EQ,
EXP_BITAND,
EXP_BITXOR,
EXP_BITOR,
EXP_LOGAND,
EXP_LOGOR,
EXP_COND,
EXP_ASS,
EXP_ASS_MUL,
EXP_ASS_DIV,
EXP_ASS_MOD,
EXP_ASS_ADD,
EXP_ASS_SUB,
EXP_ASS_SHL,
EXP_ASS_SHR,
EXP_ASS_USHR,
EXP_ASS_BITAND,
EXP_ASS_BITXOR,
EXP_ASS_BITOR,
EXP_COMMA,
EXP_VAR, /* var initializer */
/* statements */
STM_BLOCK,
STM_EMPTY,
STM_VAR,
STM_IF,
STM_DO,
STM_WHILE,
STM_FOR,
STM_FOR_VAR,
STM_FOR_IN,
STM_FOR_IN_VAR,
STM_CONTINUE,
STM_BREAK,
STM_RETURN,
STM_WITH,
STM_SWITCH,
STM_THROW,
STM_TRY,
STM_DEBUGGER,
STM_LABEL,
STM_CASE,
STM_DEFAULT,
};
typedef struct js_JumpList js_JumpList;
struct js_JumpList
{
enum js_AstType type;
int inst;
js_JumpList *next;
};
struct js_Ast
{
enum js_AstType type;
int line;
js_Ast *parent, *a, *b, *c, *d;
double number;
const char *string;
js_JumpList *jumps; /* list of break/continue jumps to patch */
int casejump; /* for switch case clauses */
js_Ast *gcnext; /* next in alloc list */
};
js_Ast *jsP_parsefunction(js_State *J, const char *filename, const char *params, const char *body);
js_Ast *jsP_parse(js_State *J, const char *filename, const char *source);
void jsP_freeparse(js_State *J);
const char *jsP_aststring(enum js_AstType type);
void jsP_dumpsyntax(js_State *J, js_Ast *prog, int minify);
void jsP_dumplist(js_State *J, js_Ast *prog);
#endif

View File

@ -1,333 +0,0 @@
#include "jsi.h"
#include "jsvalue.h"
/*
Use an AA-tree to quickly look up properties in objects:
The level of every leaf node is one.
The level of every left child is one less than its parent.
The level of every right child is equal or one less than its parent.
The level of every right grandchild is less than its grandparent.
Every node of level greater than one has two children.
A link where the child's level is equal to that of its parent is called a horizontal link.
Individual right horizontal links are allowed, but consecutive ones are forbidden.
Left horizontal links are forbidden.
skew() fixes left horizontal links.
split() fixes consecutive right horizontal links.
*/
static js_Property sentinel = {
"",
&sentinel, &sentinel,
0, 0,
{ {0}, {0}, JS_TUNDEFINED },
NULL, NULL
};
static js_Property *newproperty(js_State *J, js_Object *obj, const char *name)
{
js_Property *node = js_malloc(J, sizeof *node);
node->name = js_intern(J, name);
node->left = node->right = &sentinel;
node->level = 1;
node->atts = 0;
node->value.type = JS_TUNDEFINED;
node->value.u.number = 0;
node->getter = NULL;
node->setter = NULL;
++obj->count;
++J->gccounter;
return node;
}
static js_Property *lookup(js_Property *node, const char *name)
{
while (node != &sentinel) {
int c = strcmp(name, node->name);
if (c == 0)
return node;
else if (c < 0)
node = node->left;
else
node = node->right;
}
return NULL;
}
static js_Property *skew(js_Property *node)
{
if (node->left->level == node->level) {
js_Property *temp = node;
node = node->left;
temp->left = node->right;
node->right = temp;
}
return node;
}
static js_Property *split(js_Property *node)
{
if (node->right->right->level == node->level) {
js_Property *temp = node;
node = node->right;
temp->right = node->left;
node->left = temp;
++node->level;
}
return node;
}
static js_Property *insert(js_State *J, js_Object *obj, js_Property *node, const char *name, js_Property **result)
{
if (node != &sentinel) {
int c = strcmp(name, node->name);
if (c < 0)
node->left = insert(J, obj, node->left, name, result);
else if (c > 0)
node->right = insert(J, obj, node->right, name, result);
else
return *result = node;
node = skew(node);
node = split(node);
return node;
}
return *result = newproperty(J, obj, name);
}
static void freeproperty(js_State *J, js_Object *obj, js_Property *node)
{
js_free(J, node);
--obj->count;
}
static js_Property *delete(js_State *J, js_Object *obj, js_Property *node, const char *name)
{
js_Property *temp, *succ;
if (node != &sentinel) {
int c = strcmp(name, node->name);
if (c < 0) {
node->left = delete(J, obj, node->left, name);
} else if (c > 0) {
node->right = delete(J, obj, node->right, name);
} else {
if (node->left == &sentinel) {
temp = node;
node = node->right;
freeproperty(J, obj, temp);
} else if (node->right == &sentinel) {
temp = node;
node = node->left;
freeproperty(J, obj, temp);
} else {
succ = node->right;
while (succ->left != &sentinel)
succ = succ->left;
node->name = succ->name;
node->atts = succ->atts;
node->value = succ->value;
node->right = delete(J, obj, node->right, succ->name);
}
}
if (node->left->level < node->level - 1 ||
node->right->level < node->level - 1)
{
if (node->right->level > --node->level)
node->right->level = node->level;
node = skew(node);
node->right = skew(node->right);
node->right->right = skew(node->right->right);
node = split(node);
node->right = split(node->right);
}
}
return node;
}
js_Object *jsV_newobject(js_State *J, enum js_Class type, js_Object *prototype)
{
js_Object *obj = js_malloc(J, sizeof *obj);
memset(obj, 0, sizeof *obj);
obj->gcmark = 0;
obj->gcnext = J->gcobj;
J->gcobj = obj;
++J->gccounter;
obj->type = type;
obj->properties = &sentinel;
obj->prototype = prototype;
obj->extensible = 1;
return obj;
}
js_Property *jsV_getownproperty(js_State *J, js_Object *obj, const char *name)
{
return lookup(obj->properties, name);
}
js_Property *jsV_getpropertyx(js_State *J, js_Object *obj, const char *name, int *own)
{
*own = 1;
do {
js_Property *ref = lookup(obj->properties, name);
if (ref)
return ref;
obj = obj->prototype;
*own = 0;
} while (obj);
return NULL;
}
js_Property *jsV_getproperty(js_State *J, js_Object *obj, const char *name)
{
do {
js_Property *ref = lookup(obj->properties, name);
if (ref)
return ref;
obj = obj->prototype;
} while (obj);
return NULL;
}
static js_Property *jsV_getenumproperty(js_State *J, js_Object *obj, const char *name)
{
do {
js_Property *ref = lookup(obj->properties, name);
if (ref && !(ref->atts & JS_DONTENUM))
return ref;
obj = obj->prototype;
} while (obj);
return NULL;
}
js_Property *jsV_setproperty(js_State *J, js_Object *obj, const char *name)
{
js_Property *result;
if (!obj->extensible) {
result = lookup(obj->properties, name);
if (J->strict && !result)
js_typeerror(J, "object is non-extensible");
return result;
}
obj->properties = insert(J, obj, obj->properties, name, &result);
return result;
}
void jsV_delproperty(js_State *J, js_Object *obj, const char *name)
{
obj->properties = delete(J, obj, obj->properties, name);
}
/* Flatten hierarchy of enumerable properties into an iterator object */
static js_Iterator *itwalk(js_State *J, js_Iterator *iter, js_Property *prop, js_Object *seen)
{
if (prop->right != &sentinel)
iter = itwalk(J, iter, prop->right, seen);
if (!(prop->atts & JS_DONTENUM)) {
if (!seen || !jsV_getenumproperty(J, seen, prop->name)) {
js_Iterator *head = js_malloc(J, sizeof *head);
head->name = prop->name;
head->next = iter;
iter = head;
}
}
if (prop->left != &sentinel)
iter = itwalk(J, iter, prop->left, seen);
return iter;
}
static js_Iterator *itflatten(js_State *J, js_Object *obj)
{
js_Iterator *iter = NULL;
if (obj->prototype)
iter = itflatten(J, obj->prototype);
if (obj->properties != &sentinel)
iter = itwalk(J, iter, obj->properties, obj->prototype);
return iter;
}
js_Object *jsV_newiterator(js_State *J, js_Object *obj, int own)
{
char buf[32];
int k;
js_Object *io = jsV_newobject(J, JS_CITERATOR, NULL);
io->u.iter.target = obj;
if (own) {
io->u.iter.head = NULL;
if (obj->properties != &sentinel)
io->u.iter.head = itwalk(J, io->u.iter.head, obj->properties, NULL);
} else {
io->u.iter.head = itflatten(J, obj);
}
if (obj->type == JS_CSTRING) {
js_Iterator *tail = io->u.iter.head;
if (tail)
while (tail->next)
tail = tail->next;
for (k = 0; k < obj->u.s.length; ++k) {
js_itoa(buf, k);
if (!jsV_getenumproperty(J, obj, buf)) {
js_Iterator *node = js_malloc(J, sizeof *node);
node->name = js_intern(J, js_itoa(buf, k));
node->next = NULL;
if (!tail)
io->u.iter.head = tail = node;
else {
tail->next = node;
tail = node;
}
}
}
}
return io;
}
const char *jsV_nextiterator(js_State *J, js_Object *io)
{
int k;
if (io->type != JS_CITERATOR)
js_typeerror(J, "not an iterator");
while (io->u.iter.head) {
js_Iterator *next = io->u.iter.head->next;
const char *name = io->u.iter.head->name;
js_free(J, io->u.iter.head);
io->u.iter.head = next;
if (jsV_getproperty(J, io->u.iter.target, name))
return name;
if (io->u.iter.target->type == JS_CSTRING)
if (js_isarrayindex(J, name, &k) && k < io->u.iter.target->u.s.length)
return name;
}
return NULL;
}
/* Walk all the properties and delete them one by one for arrays */
void jsV_resizearray(js_State *J, js_Object *obj, int newlen)
{
char buf[32];
const char *s;
int k;
if (newlen < obj->u.a.length) {
if (obj->u.a.length > obj->count * 2) {
js_Object *it = jsV_newiterator(J, obj, 1);
while ((s = jsV_nextiterator(J, it))) {
k = jsV_numbertointeger(jsV_stringtonumber(J, s));
if (k >= newlen && !strcmp(s, jsV_numbertostring(J, buf, k)))
jsV_delproperty(J, obj, s);
}
} else {
for (k = newlen; k < obj->u.a.length; ++k) {
jsV_delproperty(J, obj, js_itoa(buf, k));
}
}
}
obj->u.a.length = newlen;
}

View File

@ -1,205 +0,0 @@
#include "jsi.h"
#include "jsvalue.h"
#include "jsbuiltin.h"
#include "regexp.h"
void js_newregexp(js_State *J, const char *pattern, int flags)
{
const char *error;
js_Object *obj;
Reprog *prog;
int opts;
obj = jsV_newobject(J, JS_CREGEXP, J->RegExp_prototype);
opts = 0;
if (flags & JS_REGEXP_I) opts |= REG_ICASE;
if (flags & JS_REGEXP_M) opts |= REG_NEWLINE;
prog = js_regcompx(J->alloc, J->actx, pattern, opts, &error);
if (!prog)
js_syntaxerror(J, "regular expression: %s", error);
obj->u.r.prog = prog;
obj->u.r.source = js_strdup(J, pattern);
obj->u.r.flags = flags;
obj->u.r.last = 0;
js_pushobject(J, obj);
}
void js_RegExp_prototype_exec(js_State *J, js_Regexp *re, const char *text)
{
int result;
int i;
int opts;
Resub m;
opts = 0;
if (re->flags & JS_REGEXP_G) {
if (re->last > strlen(text)) {
re->last = 0;
js_pushnull(J);
return;
}
if (re->last > 0) {
text += re->last;
opts |= REG_NOTBOL;
}
}
result = js_regexec(re->prog, text, &m, opts);
if (result < 0)
js_error(J, "regexec failed");
if (result == 0) {
js_newarray(J);
js_pushstring(J, text);
js_setproperty(J, -2, "input");
js_pushnumber(J, js_utfptrtoidx(text, m.sub[0].sp));
js_setproperty(J, -2, "index");
for (i = 0; i < m.nsub; ++i) {
js_pushlstring(J, m.sub[i].sp, m.sub[i].ep - m.sub[i].sp);
js_setindex(J, -2, i);
}
if (re->flags & JS_REGEXP_G)
re->last = re->last + (m.sub[0].ep - text);
return;
}
if (re->flags & JS_REGEXP_G)
re->last = 0;
js_pushnull(J);
}
static void Rp_test(js_State *J)
{
js_Regexp *re;
const char *text;
int result;
int opts;
Resub m;
re = js_toregexp(J, 0);
text = js_tostring(J, 1);
opts = 0;
if (re->flags & JS_REGEXP_G) {
if (re->last > strlen(text)) {
re->last = 0;
js_pushboolean(J, 0);
return;
}
if (re->last > 0) {
text += re->last;
opts |= REG_NOTBOL;
}
}
result = js_regexec(re->prog, text, &m, opts);
if (result < 0)
js_error(J, "regexec failed");
if (result == 0) {
if (re->flags & JS_REGEXP_G)
re->last = re->last + (m.sub[0].ep - text);
js_pushboolean(J, 1);
return;
}
if (re->flags & JS_REGEXP_G)
re->last = 0;
js_pushboolean(J, 0);
}
static void jsB_new_RegExp(js_State *J)
{
js_Regexp *old;
const char *pattern;
int flags;
if (js_isregexp(J, 1)) {
if (js_isdefined(J, 2))
js_typeerror(J, "cannot supply flags when creating one RegExp from another");
old = js_toregexp(J, 1);
pattern = old->source;
flags = old->flags;
} else if (js_isundefined(J, 1)) {
pattern = "(?:)";
flags = 0;
} else {
pattern = js_tostring(J, 1);
flags = 0;
}
if (strlen(pattern) == 0)
pattern = "(?:)";
if (js_isdefined(J, 2)) {
const char *s = js_tostring(J, 2);
int g = 0, i = 0, m = 0;
while (*s) {
if (*s == 'g') ++g;
else if (*s == 'i') ++i;
else if (*s == 'm') ++m;
else js_syntaxerror(J, "invalid regular expression flag: '%c'", *s);
++s;
}
if (g > 1) js_syntaxerror(J, "invalid regular expression flag: 'g'");
if (i > 1) js_syntaxerror(J, "invalid regular expression flag: 'i'");
if (m > 1) js_syntaxerror(J, "invalid regular expression flag: 'm'");
if (g) flags |= JS_REGEXP_G;
if (i) flags |= JS_REGEXP_I;
if (m) flags |= JS_REGEXP_M;
}
js_newregexp(J, pattern, flags);
}
static void jsB_RegExp(js_State *J)
{
if (js_isregexp(J, 1))
return;
jsB_new_RegExp(J);
}
static void Rp_toString(js_State *J)
{
js_Regexp *re;
char *out;
re = js_toregexp(J, 0);
out = js_malloc(J, strlen(re->source) + 6); /* extra space for //gim */
strcpy(out, "/");
strcat(out, re->source);
strcat(out, "/");
if (re->flags & JS_REGEXP_G) strcat(out, "g");
if (re->flags & JS_REGEXP_I) strcat(out, "i");
if (re->flags & JS_REGEXP_M) strcat(out, "m");
if (js_try(J)) {
js_free(J, out);
js_throw(J);
}
js_pop(J, 0);
js_pushstring(J, out);
js_endtry(J);
js_free(J, out);
}
static void Rp_exec(js_State *J)
{
js_RegExp_prototype_exec(J, js_toregexp(J, 0), js_tostring(J, 1));
}
void jsB_initregexp(js_State *J)
{
js_pushobject(J, J->RegExp_prototype);
{
jsB_propf(J, "RegExp.prototype.toString", Rp_toString, 0);
jsB_propf(J, "RegExp.prototype.test", Rp_test, 0);
jsB_propf(J, "RegExp.prototype.exec", Rp_exec, 0);
}
js_newcconstructor(J, jsB_RegExp, jsB_new_RegExp, "RegExp", 1);
js_defglobal(J, "RegExp", JS_DONTENUM);
}

View File

@ -1,289 +0,0 @@
#include "jsi.h"
#include "jslex.h"
#include "jsvalue.h"
#include "jsbuiltin.h"
#include "jscompile.h"
#include "utf.h"
static void reprvalue(js_State *J, js_Buffer **sb);
static void reprnum(js_State *J, js_Buffer **sb, double n)
{
char buf[40];
if (n == 0 && signbit(n))
js_puts(J, sb, "-0");
else
js_puts(J, sb, jsV_numbertostring(J, buf, n));
}
static void reprstr(js_State *J, js_Buffer **sb, const char *s)
{
static const char *HEX = "0123456789ABCDEF";
int i, n;
Rune c;
js_putc(J, sb, '"');
while (*s) {
n = chartorune(&c, s);
switch (c) {
case '"': js_puts(J, sb, "\\\""); break;
case '\\': js_puts(J, sb, "\\\\"); break;
case '\b': js_puts(J, sb, "\\b"); break;
case '\f': js_puts(J, sb, "\\f"); break;
case '\n': js_puts(J, sb, "\\n"); break;
case '\r': js_puts(J, sb, "\\r"); break;
case '\t': js_puts(J, sb, "\\t"); break;
default:
if (c < ' ') {
js_putc(J, sb, '\\');
js_putc(J, sb, 'x');
js_putc(J, sb, HEX[(c>>4)&15]);
js_putc(J, sb, HEX[c&15]);
} else if (c < 128) {
js_putc(J, sb, c);
} else if (c < 0x10000) {
js_putc(J, sb, '\\');
js_putc(J, sb, 'u');
js_putc(J, sb, HEX[(c>>12)&15]);
js_putc(J, sb, HEX[(c>>8)&15]);
js_putc(J, sb, HEX[(c>>4)&15]);
js_putc(J, sb, HEX[c&15]);
} else {
for (i = 0; i < n; ++i)
js_putc(J, sb, s[i]);
}
break;
}
s += n;
}
js_putc(J, sb, '"');
}
#ifndef isalpha
#define isalpha(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
#endif
#ifndef isdigit
#define isdigit(c) (c >= '0' && c <= '9')
#endif
static void reprident(js_State *J, js_Buffer **sb, const char *name)
{
const char *p = name;
if (isdigit(*p))
while (isdigit(*p))
++p;
else if (isalpha(*p) || *p == '_')
while (isdigit(*p) || isalpha(*p) || *p == '_')
++p;
if (p > name && *p == 0)
js_puts(J, sb, name);
else
reprstr(J, sb, name);
}
static void reprobject(js_State *J, js_Buffer **sb)
{
const char *key;
int i, n;
n = js_gettop(J) - 1;
for (i = 0; i < n; ++i) {
if (js_isobject(J, i)) {
if (js_toobject(J, i) == js_toobject(J, -1)) {
js_puts(J, sb, "{}");
return;
}
}
}
n = 0;
js_putc(J, sb, '{');
js_pushiterator(J, -1, 1);
while ((key = js_nextiterator(J, -1))) {
if (n++ > 0)
js_puts(J, sb, ", ");
reprident(J, sb, key);
js_puts(J, sb, ": ");
js_getproperty(J, -2, key);
reprvalue(J, sb);
js_pop(J, 1);
}
js_pop(J, 1);
js_putc(J, sb, '}');
}
static void reprarray(js_State *J, js_Buffer **sb)
{
int n, i;
n = js_gettop(J) - 1;
for (i = 0; i < n; ++i) {
if (js_isobject(J, i)) {
if (js_toobject(J, i) == js_toobject(J, -1)) {
js_puts(J, sb, "[]");
return;
}
}
}
js_putc(J, sb, '[');
n = js_getlength(J, -1);
for (i = 0; i < n; ++i) {
if (i > 0)
js_puts(J, sb, ", ");
if (js_hasindex(J, -1, i)) {
reprvalue(J, sb);
js_pop(J, 1);
}
}
js_putc(J, sb, ']');
}
static void reprfun(js_State *J, js_Buffer **sb, js_Function *fun)
{
int i;
js_puts(J, sb, "function ");
js_puts(J, sb, fun->name);
js_putc(J, sb, '(');
for (i = 0; i < fun->numparams; ++i) {
if (i > 0)
js_puts(J, sb, ", ");
js_puts(J, sb, fun->vartab[i]);
}
js_puts(J, sb, ") { [byte code] }");
}
static void reprvalue(js_State *J, js_Buffer **sb)
{
if (js_isundefined(J, -1))
js_puts(J, sb, "undefined");
else if (js_isnull(J, -1))
js_puts(J, sb, "null");
else if (js_isboolean(J, -1))
js_puts(J, sb, js_toboolean(J, -1) ? "true" : "false");
else if (js_isnumber(J, -1))
reprnum(J, sb, js_tonumber(J, -1));
else if (js_isstring(J, -1))
reprstr(J, sb, js_tostring(J, -1));
else if (js_isobject(J, -1)) {
js_Object *obj = js_toobject(J, -1);
switch (obj->type) {
default:
reprobject(J, sb);
break;
case JS_CARRAY:
reprarray(J, sb);
break;
case JS_CFUNCTION:
case JS_CSCRIPT:
case JS_CEVAL:
reprfun(J, sb, obj->u.f.function);
break;
case JS_CCFUNCTION:
js_puts(J, sb, "function ");
js_puts(J, sb, obj->u.c.name);
js_puts(J, sb, "() { [native code] }");
break;
case JS_CBOOLEAN:
js_puts(J, sb, "(new Boolean(");
js_puts(J, sb, obj->u.boolean ? "true" : "false");
js_puts(J, sb, "))");
break;
case JS_CNUMBER:
js_puts(J, sb, "(new Number(");
reprnum(J, sb, obj->u.number);
js_puts(J, sb, "))");
break;
case JS_CSTRING:
js_puts(J, sb, "(new String(");
reprstr(J, sb, obj->u.s.string);
js_puts(J, sb, "))");
break;
case JS_CREGEXP:
js_putc(J, sb, '/');
js_puts(J, sb, obj->u.r.source);
js_putc(J, sb, '/');
if (obj->u.r.flags & JS_REGEXP_G) js_putc(J, sb, 'g');
if (obj->u.r.flags & JS_REGEXP_I) js_putc(J, sb, 'i');
if (obj->u.r.flags & JS_REGEXP_M) js_putc(J, sb, 'm');
break;
case JS_CDATE:
{
char buf[40];
js_puts(J, sb, "(new Date(");
js_puts(J, sb, jsV_numbertostring(J, buf, obj->u.number));
js_puts(J, sb, "))");
}
break;
case JS_CERROR:
js_puts(J, sb, "(new ");
js_getproperty(J, -1, "name");
js_puts(J, sb, js_tostring(J, -1));
js_pop(J, 1);
js_putc(J, sb, '(');
js_getproperty(J, -1, "message");
reprstr(J, sb, js_tostring(J, -1));
js_pop(J, 1);
js_puts(J, sb, "))");
break;
case JS_CMATH:
js_puts(J, sb, "Math");
break;
case JS_CJSON:
js_puts(J, sb, "JSON");
break;
case JS_CITERATOR:
js_puts(J, sb, "[iterator ");
break;
case JS_CUSERDATA:
js_puts(J, sb, "[userdata ");
js_puts(J, sb, obj->u.user.tag);
js_putc(J, sb, ']');
break;
}
}
}
void js_repr(js_State *J, int idx)
{
js_Buffer *sb = NULL;
int savebot;
if (js_try(J)) {
js_free(J, sb);
js_throw(J);
}
js_copy(J, idx);
savebot = J->bot;
J->bot = J->top - 1;
reprvalue(J, &sb);
J->bot = savebot;
js_pop(J, 1);
js_putc(J, &sb, 0);
js_pushstring(J, sb ? sb->s : "undefined");
js_endtry(J);
js_free(J, sb);
}
const char *js_torepr(js_State *J, int idx)
{
js_repr(J, idx);
js_replace(J, idx < 0 ? idx-1 : idx);
return js_tostring(J, idx);
}
const char *js_tryrepr(js_State *J, int idx, const char *error)
{
const char *s;
if (js_try(J)) {
js_pop(J, 1);
return error;
}
s = js_torepr(J, idx);
js_endtry(J);
return s;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +0,0 @@
#ifndef js_run_h
#define js_run_h
js_Environment *jsR_newenvironment(js_State *J, js_Object *variables, js_Environment *outer);
struct js_Environment
{
js_Environment *outer;
js_Object *variables;
js_Environment *gcnext;
int gcmark;
};
#endif

View File

@ -1,298 +0,0 @@
#include "jsi.h"
#include "jsparse.h"
#include "jscompile.h"
#include "jsvalue.h"
#include "jsrun.h"
#include "jsbuiltin.h"
#include <assert.h>
#include <errno.h>
static void *js_defaultalloc(void *actx, void *ptr, int size)
{
#ifndef __has_feature
#define __has_feature(x) 0
#endif
#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
if (size == 0) {
free(ptr);
return NULL;
}
#endif
return realloc(ptr, (size_t)size);
}
static void js_defaultreport(js_State *J, const char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
}
static void js_defaultpanic(js_State *J)
{
js_report(J, "uncaught exception");
/* return to javascript to abort */
}
int js_ploadstring(js_State *J, const char *filename, const char *source)
{
if (js_try(J))
return 1;
js_loadstring(J, filename, source);
js_endtry(J);
return 0;
}
int js_ploadfile(js_State *J, const char *filename)
{
if (js_try(J))
return 1;
js_loadfile(J, filename);
js_endtry(J);
return 0;
}
const char *js_trystring(js_State *J, int idx, const char *error)
{
const char *s;
if (js_try(J)) {
js_pop(J, 1);
return error;
}
s = js_tostring(J, idx);
js_endtry(J);
return s;
}
double js_trynumber(js_State *J, int idx, double error)
{
double v;
if (js_try(J)) {
js_pop(J, 1);
return error;
}
v = js_tonumber(J, idx);
js_endtry(J);
return v;
}
int js_tryinteger(js_State *J, int idx, int error)
{
int v;
if (js_try(J)) {
js_pop(J, 1);
return error;
}
v = js_tointeger(J, idx);
js_endtry(J);
return v;
}
int js_tryboolean(js_State *J, int idx, int error)
{
int v;
if (js_try(J)) {
js_pop(J, 1);
return error;
}
v = js_toboolean(J, idx);
js_endtry(J);
return v;
}
static void js_loadstringx(js_State *J, const char *filename, const char *source, int iseval)
{
js_Ast *P;
js_Function *F;
if (js_try(J)) {
jsP_freeparse(J);
js_throw(J);
}
P = jsP_parse(J, filename, source);
F = jsC_compilescript(J, P, iseval ? J->strict : J->default_strict);
jsP_freeparse(J);
js_newscript(J, F, iseval ? (J->strict ? J->E : NULL) : J->GE, iseval ? JS_CEVAL : JS_CSCRIPT);
js_endtry(J);
}
void js_loadeval(js_State *J, const char *filename, const char *source)
{
js_loadstringx(J, filename, source, 1);
}
void js_loadstring(js_State *J, const char *filename, const char *source)
{
js_loadstringx(J, filename, source, 0);
}
void js_loadfile(js_State *J, const char *filename)
{
FILE *f;
char *s, *p;
int n, t;
f = fopen(filename, "rb");
if (!f) {
js_error(J, "cannot open file '%s': %s", filename, strerror(errno));
}
if (fseek(f, 0, SEEK_END) < 0) {
fclose(f);
js_error(J, "cannot seek in file '%s': %s", filename, strerror(errno));
}
n = ftell(f);
if (n < 0) {
fclose(f);
js_error(J, "cannot tell in file '%s': %s", filename, strerror(errno));
}
if (fseek(f, 0, SEEK_SET) < 0) {
fclose(f);
js_error(J, "cannot seek in file '%s': %s", filename, strerror(errno));
}
if (js_try(J)) {
fclose(f);
js_throw(J);
}
s = js_malloc(J, n + 1); /* add space for string terminator */
js_endtry(J);
t = fread(s, 1, (size_t)n, f);
if (t != n) {
js_free(J, s);
fclose(f);
js_error(J, "cannot read data from file '%s': %s", filename, strerror(errno));
}
s[n] = 0; /* zero-terminate string containing file data */
if (js_try(J)) {
js_free(J, s);
fclose(f);
js_throw(J);
}
/* skip first line if it starts with "#!" */
p = s;
if (p[0] == '#' && p[1] == '!') {
p += 2;
while (*p && *p != '\n')
++p;
}
js_loadstring(J, filename, p);
js_free(J, s);
fclose(f);
js_endtry(J);
}
int js_dostring(js_State *J, const char *source)
{
if (js_try(J)) {
js_report(J, js_trystring(J, -1, "Error"));
js_pop(J, 1);
return 1;
}
js_loadstring(J, "[string]", source);
js_pushundefined(J);
js_call(J, 0);
js_pop(J, 1);
js_endtry(J);
return 0;
}
int js_dofile(js_State *J, const char *filename)
{
if (js_try(J)) {
js_report(J, js_trystring(J, -1, "Error"));
js_pop(J, 1);
return 1;
}
js_loadfile(J, filename);
js_pushundefined(J);
js_call(J, 0);
js_pop(J, 1);
js_endtry(J);
return 0;
}
js_Panic js_atpanic(js_State *J, js_Panic panic)
{
js_Panic old = J->panic;
J->panic = panic;
return old;
}
void js_report(js_State *J, const char *message)
{
if (J->report)
J->report(J, message);
}
void js_setreport(js_State *J, js_Report report)
{
J->report = report;
}
void js_setcontext(js_State *J, void *uctx)
{
J->uctx = uctx;
}
void *js_getcontext(js_State *J)
{
return J->uctx;
}
js_State *js_newstate(js_Alloc alloc, void *actx, int flags)
{
js_State *J;
assert(sizeof(js_Value) == 16);
assert(soffsetof(js_Value, type) == 15);
if (!alloc)
alloc = js_defaultalloc;
J = alloc(actx, NULL, sizeof *J);
if (!J)
return NULL;
memset(J, 0, sizeof(*J));
J->actx = actx;
J->alloc = alloc;
if (flags & JS_STRICT)
J->strict = J->default_strict = 1;
J->trace[0].name = "-top-";
J->trace[0].file = "native";
J->trace[0].line = 0;
J->report = js_defaultreport;
J->panic = js_defaultpanic;
J->stack = alloc(actx, NULL, JS_STACKSIZE * sizeof *J->stack);
if (!J->stack) {
alloc(actx, NULL, 0);
return NULL;
}
J->gcmark = 1;
J->nextref = 0;
J->gcthresh = 0; /* reaches stability within ~ 2-5 GC cycles */
J->R = jsV_newobject(J, JS_COBJECT, NULL);
J->G = jsV_newobject(J, JS_COBJECT, NULL);
J->E = jsR_newenvironment(J, J->G, NULL);
J->GE = J->E;
jsB_init(J);
return J;
}

View File

@ -1,711 +0,0 @@
#include "jsi.h"
#include "jsvalue.h"
#include "jsbuiltin.h"
#include "utf.h"
#include "regexp.h"
static int js_doregexec(js_State *J, Reprog *prog, const char *string, Resub *sub, int eflags)
{
int result = js_regexec(prog, string, sub, eflags);
if (result < 0)
js_error(J, "regexec failed");
return result;
}
static const char *checkstring(js_State *J, int idx)
{
if (!js_iscoercible(J, idx))
js_typeerror(J, "string function called on null or undefined");
return js_tostring(J, idx);
}
int js_runeat(js_State *J, const char *s, int i)
{
Rune rune = EOF;
while (i-- >= 0) {
rune = *(unsigned char*)s;
if (rune < Runeself) {
if (rune == 0)
return EOF;
++s;
} else
s += chartorune(&rune, s);
}
return rune;
}
const char *js_utfidxtoptr(const char *s, int i)
{
Rune rune;
while (i-- > 0) {
rune = *(unsigned char*)s;
if (rune < Runeself) {
if (rune == 0)
return NULL;
++s;
} else
s += chartorune(&rune, s);
}
return s;
}
int js_utfptrtoidx(const char *s, const char *p)
{
Rune rune;
int i = 0;
while (s < p) {
if (*(unsigned char *)s < Runeself)
++s;
else
s += chartorune(&rune, s);
++i;
}
return i;
}
static void jsB_new_String(js_State *J)
{
js_newstring(J, js_gettop(J) > 1 ? js_tostring(J, 1) : "");
}
static void jsB_String(js_State *J)
{
js_pushstring(J, js_gettop(J) > 1 ? js_tostring(J, 1) : "");
}
static void Sp_toString(js_State *J)
{
js_Object *self = js_toobject(J, 0);
if (self->type != JS_CSTRING) js_typeerror(J, "not a string");
js_pushliteral(J, self->u.s.string);
}
static void Sp_valueOf(js_State *J)
{
js_Object *self = js_toobject(J, 0);
if (self->type != JS_CSTRING) js_typeerror(J, "not a string");
js_pushliteral(J, self->u.s.string);
}
static void Sp_charAt(js_State *J)
{
char buf[UTFmax + 1];
const char *s = checkstring(J, 0);
int pos = js_tointeger(J, 1);
Rune rune = js_runeat(J, s, pos);
if (rune >= 0) {
buf[runetochar(buf, &rune)] = 0;
js_pushstring(J, buf);
} else {
js_pushliteral(J, "");
}
}
static void Sp_charCodeAt(js_State *J)
{
const char *s = checkstring(J, 0);
int pos = js_tointeger(J, 1);
Rune rune = js_runeat(J, s, pos);
if (rune >= 0)
js_pushnumber(J, rune);
else
js_pushnumber(J, NAN);
}
static void Sp_concat(js_State *J)
{
int i, top = js_gettop(J);
int n;
char * volatile out;
const char *s;
if (top == 1)
return;
s = checkstring(J, 0);
n = strlen(s);
out = js_malloc(J, n + 1);
strcpy(out, s);
if (js_try(J)) {
js_free(J, out);
js_throw(J);
}
for (i = 1; i < top; ++i) {
s = js_tostring(J, i);
n += strlen(s);
out = js_realloc(J, out, n + 1);
strcat(out, s);
}
js_pushstring(J, out);
js_endtry(J);
js_free(J, out);
}
static void Sp_indexOf(js_State *J)
{
const char *haystack = checkstring(J, 0);
const char *needle = js_tostring(J, 1);
int pos = js_tointeger(J, 2);
int len = strlen(needle);
int k = 0;
Rune rune;
while (*haystack) {
if (k >= pos && !strncmp(haystack, needle, len)) {
js_pushnumber(J, k);
return;
}
haystack += chartorune(&rune, haystack);
++k;
}
js_pushnumber(J, -1);
}
static void Sp_lastIndexOf(js_State *J)
{
const char *haystack = checkstring(J, 0);
const char *needle = js_tostring(J, 1);
int pos = js_isdefined(J, 2) ? js_tointeger(J, 2) : (int)strlen(haystack);
int len = strlen(needle);
int k = 0, last = -1;
Rune rune;
while (*haystack && k <= pos) {
if (!strncmp(haystack, needle, len))
last = k;
haystack += chartorune(&rune, haystack);
++k;
}
js_pushnumber(J, last);
}
static void Sp_localeCompare(js_State *J)
{
const char *a = checkstring(J, 0);
const char *b = js_tostring(J, 1);
js_pushnumber(J, strcmp(a, b));
}
static void Sp_slice(js_State *J)
{
const char *str = checkstring(J, 0);
const char *ss, *ee;
int len = utflen(str);
int s = js_tointeger(J, 1);
int e = js_isdefined(J, 2) ? js_tointeger(J, 2) : len;
s = s < 0 ? s + len : s;
e = e < 0 ? e + len : e;
s = s < 0 ? 0 : s > len ? len : s;
e = e < 0 ? 0 : e > len ? len : e;
if (s < e) {
ss = js_utfidxtoptr(str, s);
ee = js_utfidxtoptr(ss, e - s);
} else {
ss = js_utfidxtoptr(str, e);
ee = js_utfidxtoptr(ss, s - e);
}
js_pushlstring(J, ss, ee - ss);
}
static void Sp_substring(js_State *J)
{
const char *str = checkstring(J, 0);
const char *ss, *ee;
int len = utflen(str);
int s = js_tointeger(J, 1);
int e = js_isdefined(J, 2) ? js_tointeger(J, 2) : len;
s = s < 0 ? 0 : s > len ? len : s;
e = e < 0 ? 0 : e > len ? len : e;
if (s < e) {
ss = js_utfidxtoptr(str, s);
ee = js_utfidxtoptr(ss, e - s);
} else {
ss = js_utfidxtoptr(str, e);
ee = js_utfidxtoptr(ss, s - e);
}
js_pushlstring(J, ss, ee - ss);
}
static void Sp_toLowerCase(js_State *J)
{
const char *src = checkstring(J, 0);
char *dst = js_malloc(J, UTFmax * strlen(src) + 1);
const char *s = src;
char *d = dst;
Rune rune;
while (*s) {
s += chartorune(&rune, s);
rune = tolowerrune(rune);
d += runetochar(d, &rune);
}
*d = 0;
if (js_try(J)) {
js_free(J, dst);
js_throw(J);
}
js_pushstring(J, dst);
js_endtry(J);
js_free(J, dst);
}
static void Sp_toUpperCase(js_State *J)
{
const char *src = checkstring(J, 0);
char *dst = js_malloc(J, UTFmax * strlen(src) + 1);
const char *s = src;
char *d = dst;
Rune rune;
while (*s) {
s += chartorune(&rune, s);
rune = toupperrune(rune);
d += runetochar(d, &rune);
}
*d = 0;
if (js_try(J)) {
js_free(J, dst);
js_throw(J);
}
js_pushstring(J, dst);
js_endtry(J);
js_free(J, dst);
}
static int istrim(int c)
{
return c == 0x9 || c == 0xB || c == 0xC || c == 0x20 || c == 0xA0 || c == 0xFEFF ||
c == 0xA || c == 0xD || c == 0x2028 || c == 0x2029;
}
static void Sp_trim(js_State *J)
{
const char *s, *e;
s = checkstring(J, 0);
while (istrim(*s))
++s;
e = s + strlen(s);
while (e > s && istrim(e[-1]))
--e;
js_pushlstring(J, s, e - s);
}
static void S_fromCharCode(js_State *J)
{
int i, top = js_gettop(J);
Rune c;
char *s, *p;
s = p = js_malloc(J, (top-1) * UTFmax + 1);
if (js_try(J)) {
js_free(J, s);
js_throw(J);
}
for (i = 1; i < top; ++i) {
c = js_touint32(J, i);
p += runetochar(p, &c);
}
*p = 0;
js_pushstring(J, s);
js_endtry(J);
js_free(J, s);
}
static void Sp_match(js_State *J)
{
js_Regexp *re;
const char *text;
int len;
const char *a, *b, *c, *e;
Resub m;
text = checkstring(J, 0);
if (js_isregexp(J, 1))
js_copy(J, 1);
else if (js_isundefined(J, 1))
js_newregexp(J, "", 0);
else
js_newregexp(J, js_tostring(J, 1), 0);
re = js_toregexp(J, -1);
if (!(re->flags & JS_REGEXP_G)) {
js_RegExp_prototype_exec(J, re, text);
return;
}
re->last = 0;
js_newarray(J);
len = 0;
a = text;
e = text + strlen(text);
while (a <= e) {
if (js_doregexec(J, re->prog, a, &m, a > text ? REG_NOTBOL : 0))
break;
b = m.sub[0].sp;
c = m.sub[0].ep;
js_pushlstring(J, b, c - b);
js_setindex(J, -2, len++);
a = c;
if (c - b == 0)
++a;
}
if (len == 0) {
js_pop(J, 1);
js_pushnull(J);
}
}
static void Sp_search(js_State *J)
{
js_Regexp *re;
const char *text;
Resub m;
text = checkstring(J, 0);
if (js_isregexp(J, 1))
js_copy(J, 1);
else if (js_isundefined(J, 1))
js_newregexp(J, "", 0);
else
js_newregexp(J, js_tostring(J, 1), 0);
re = js_toregexp(J, -1);
if (!js_doregexec(J, re->prog, text, &m, 0))
js_pushnumber(J, js_utfptrtoidx(text, m.sub[0].sp));
else
js_pushnumber(J, -1);
}
static void Sp_replace_regexp(js_State *J)
{
js_Regexp *re;
const char *source, *s, *r;
js_Buffer *sb = NULL;
int n, x;
Resub m;
source = checkstring(J, 0);
re = js_toregexp(J, 1);
if (js_doregexec(J, re->prog, source, &m, 0)) {
js_copy(J, 0);
return;
}
re->last = 0;
loop:
s = m.sub[0].sp;
n = m.sub[0].ep - m.sub[0].sp;
if (js_iscallable(J, 2)) {
js_copy(J, 2);
js_pushundefined(J);
for (x = 0; m.sub[x].sp; ++x) /* arg 0..x: substring and subexps that matched */
js_pushlstring(J, m.sub[x].sp, m.sub[x].ep - m.sub[x].sp);
js_pushnumber(J, s - source); /* arg x+2: offset within search string */
js_copy(J, 0); /* arg x+3: search string */
js_call(J, 2 + x);
r = js_tostring(J, -1);
js_putm(J, &sb, source, s);
js_puts(J, &sb, r);
js_pop(J, 1);
} else {
r = js_tostring(J, 2);
js_putm(J, &sb, source, s);
while (*r) {
if (*r == '$') {
switch (*(++r)) {
case 0: --r; /* end of string; back up */
/* fallthrough */
case '$': js_putc(J, &sb, '$'); break;
case '`': js_putm(J, &sb, source, s); break;
case '\'': js_puts(J, &sb, s + n); break;
case '&':
js_putm(J, &sb, s, s + n);
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
x = *r - '0';
if (r[1] >= '0' && r[1] <= '9')
x = x * 10 + *(++r) - '0';
if (x > 0 && x < m.nsub) {
js_putm(J, &sb, m.sub[x].sp, m.sub[x].ep);
} else {
js_putc(J, &sb, '$');
if (x > 10) {
js_putc(J, &sb, '0' + x / 10);
js_putc(J, &sb, '0' + x % 10);
} else {
js_putc(J, &sb, '0' + x);
}
}
break;
default:
js_putc(J, &sb, '$');
js_putc(J, &sb, *r);
break;
}
++r;
} else {
js_putc(J, &sb, *r++);
}
}
}
if (re->flags & JS_REGEXP_G) {
source = m.sub[0].ep;
if (n == 0) {
if (*source)
js_putc(J, &sb, *source++);
else
goto end;
}
if (!js_doregexec(J, re->prog, source, &m, REG_NOTBOL))
goto loop;
}
end:
js_puts(J, &sb, s + n);
js_putc(J, &sb, 0);
if (js_try(J)) {
js_free(J, sb);
js_throw(J);
}
js_pushstring(J, sb ? sb->s : "");
js_endtry(J);
js_free(J, sb);
}
static void Sp_replace_string(js_State *J)
{
const char *source, *needle, *s, *r;
js_Buffer *sb = NULL;
int n;
source = checkstring(J, 0);
needle = js_tostring(J, 1);
s = strstr(source, needle);
if (!s) {
js_copy(J, 0);
return;
}
n = strlen(needle);
if (js_iscallable(J, 2)) {
js_copy(J, 2);
js_pushundefined(J);
js_pushlstring(J, s, n); /* arg 1: substring that matched */
js_pushnumber(J, s - source); /* arg 2: offset within search string */
js_copy(J, 0); /* arg 3: search string */
js_call(J, 3);
r = js_tostring(J, -1);
js_putm(J, &sb, source, s);
js_puts(J, &sb, r);
js_puts(J, &sb, s + n);
js_putc(J, &sb, 0);
js_pop(J, 1);
} else {
r = js_tostring(J, 2);
js_putm(J, &sb, source, s);
while (*r) {
if (*r == '$') {
switch (*(++r)) {
case 0: --r; /* end of string; back up */
/* fallthrough */
case '$': js_putc(J, &sb, '$'); break;
case '&': js_putm(J, &sb, s, s + n); break;
case '`': js_putm(J, &sb, source, s); break;
case '\'': js_puts(J, &sb, s + n); break;
default: js_putc(J, &sb, '$'); js_putc(J, &sb, *r); break;
}
++r;
} else {
js_putc(J, &sb, *r++);
}
}
js_puts(J, &sb, s + n);
js_putc(J, &sb, 0);
}
if (js_try(J)) {
js_free(J, sb);
js_throw(J);
}
js_pushstring(J, sb ? sb->s : "");
js_endtry(J);
js_free(J, sb);
}
static void Sp_replace(js_State *J)
{
if (js_isregexp(J, 1))
Sp_replace_regexp(J);
else
Sp_replace_string(J);
}
static void Sp_split_regexp(js_State *J)
{
js_Regexp *re;
const char *text;
int limit, len, k;
const char *p, *a, *b, *c, *e;
Resub m;
text = checkstring(J, 0);
re = js_toregexp(J, 1);
limit = js_isdefined(J, 2) ? js_tointeger(J, 2) : 1 << 30;
js_newarray(J);
len = 0;
e = text + strlen(text);
/* splitting the empty string */
if (e == text) {
if (js_doregexec(J, re->prog, text, &m, 0)) {
if (len == limit) return;
js_pushliteral(J, "");
js_setindex(J, -2, 0);
}
return;
}
p = a = text;
while (a < e) {
if (js_doregexec(J, re->prog, a, &m, a > text ? REG_NOTBOL : 0))
break; /* no match */
b = m.sub[0].sp;
c = m.sub[0].ep;
/* empty string at end of last match */
if (b == p) {
++a;
continue;
}
if (len == limit) return;
js_pushlstring(J, p, b - p);
js_setindex(J, -2, len++);
for (k = 1; k < m.nsub; ++k) {
if (len == limit) return;
js_pushlstring(J, m.sub[k].sp, m.sub[k].ep - m.sub[k].sp);
js_setindex(J, -2, len++);
}
a = p = c;
}
if (len == limit) return;
js_pushstring(J, p);
js_setindex(J, -2, len);
}
static void Sp_split_string(js_State *J)
{
const char *str = checkstring(J, 0);
const char *sep = js_tostring(J, 1);
int limit = js_isdefined(J, 2) ? js_tointeger(J, 2) : 1 << 30;
int i, n;
js_newarray(J);
n = strlen(sep);
/* empty string */
if (n == 0) {
Rune rune;
for (i = 0; *str && i < limit; ++i) {
n = chartorune(&rune, str);
js_pushlstring(J, str, n);
js_setindex(J, -2, i);
str += n;
}
return;
}
for (i = 0; str && i < limit; ++i) {
const char *s = strstr(str, sep);
if (s) {
js_pushlstring(J, str, s-str);
js_setindex(J, -2, i);
str = s + n;
} else {
js_pushstring(J, str);
js_setindex(J, -2, i);
str = NULL;
}
}
}
static void Sp_split(js_State *J)
{
if (js_isundefined(J, 1)) {
js_newarray(J);
js_copy(J, 0);
js_setindex(J, -2, 0);
} else if (js_isregexp(J, 1)) {
Sp_split_regexp(J);
} else {
Sp_split_string(J);
}
}
void jsB_initstring(js_State *J)
{
J->String_prototype->u.s.string = "";
J->String_prototype->u.s.length = 0;
js_pushobject(J, J->String_prototype);
{
jsB_propf(J, "String.prototype.toString", Sp_toString, 0);
jsB_propf(J, "String.prototype.valueOf", Sp_valueOf, 0);
jsB_propf(J, "String.prototype.charAt", Sp_charAt, 1);
jsB_propf(J, "String.prototype.charCodeAt", Sp_charCodeAt, 1);
jsB_propf(J, "String.prototype.concat", Sp_concat, 0); /* 1 */
jsB_propf(J, "String.prototype.indexOf", Sp_indexOf, 1);
jsB_propf(J, "String.prototype.lastIndexOf", Sp_lastIndexOf, 1);
jsB_propf(J, "String.prototype.localeCompare", Sp_localeCompare, 1);
jsB_propf(J, "String.prototype.match", Sp_match, 1);
jsB_propf(J, "String.prototype.replace", Sp_replace, 2);
jsB_propf(J, "String.prototype.search", Sp_search, 1);
jsB_propf(J, "String.prototype.slice", Sp_slice, 2);
jsB_propf(J, "String.prototype.split", Sp_split, 2);
jsB_propf(J, "String.prototype.substring", Sp_substring, 2);
jsB_propf(J, "String.prototype.toLowerCase", Sp_toLowerCase, 0);
jsB_propf(J, "String.prototype.toLocaleLowerCase", Sp_toLowerCase, 0);
jsB_propf(J, "String.prototype.toUpperCase", Sp_toUpperCase, 0);
jsB_propf(J, "String.prototype.toLocaleUpperCase", Sp_toUpperCase, 0);
/* ES5 */
jsB_propf(J, "String.prototype.trim", Sp_trim, 0);
}
js_newcconstructor(J, jsB_String, jsB_new_String, "String", 0); /* 1 */
{
jsB_propf(J, "String.fromCharCode", S_fromCharCode, 0); /* 1 */
}
js_defglobal(J, "String", JS_DONTENUM);
}

View File

@ -1,630 +0,0 @@
#include "jsi.h"
#include "jslex.h"
#include "jscompile.h"
#include "jsvalue.h"
#include "utf.h"
#define JSV_ISSTRING(v) (v->type==JS_TSHRSTR || v->type==JS_TMEMSTR || v->type==JS_TLITSTR)
#define JSV_TOSTRING(v) (v->type==JS_TSHRSTR ? v->u.shrstr : v->type==JS_TLITSTR ? v->u.litstr : v->type==JS_TMEMSTR ? v->u.memstr->p : "")
int jsV_numbertointeger(double n)
{
if (n == 0) return 0;
if (isnan(n)) return 0;
n = (n < 0) ? -floor(-n) : floor(n);
if (n < INT_MIN) return INT_MIN;
if (n > INT_MAX) return INT_MAX;
return (int)n;
}
int jsV_numbertoint32(double n)
{
double two32 = 4294967296.0;
double two31 = 2147483648.0;
if (!isfinite(n) || n == 0)
return 0;
n = fmod(n, two32);
n = n >= 0 ? floor(n) : ceil(n) + two32;
if (n >= two31)
return n - two32;
else
return n;
}
unsigned int jsV_numbertouint32(double n)
{
return (unsigned int)jsV_numbertoint32(n);
}
short jsV_numbertoint16(double n)
{
return jsV_numbertoint32(n);
}
unsigned short jsV_numbertouint16(double n)
{
return jsV_numbertoint32(n);
}
/* obj.toString() */
static int jsV_toString(js_State *J, js_Object *obj)
{
js_pushobject(J, obj);
js_getproperty(J, -1, "toString");
if (js_iscallable(J, -1)) {
js_rot2(J);
js_call(J, 0);
if (js_isprimitive(J, -1))
return 1;
js_pop(J, 1);
return 0;
}
js_pop(J, 2);
return 0;
}
/* obj.valueOf() */
static int jsV_valueOf(js_State *J, js_Object *obj)
{
js_pushobject(J, obj);
js_getproperty(J, -1, "valueOf");
if (js_iscallable(J, -1)) {
js_rot2(J);
js_call(J, 0);
if (js_isprimitive(J, -1))
return 1;
js_pop(J, 1);
return 0;
}
js_pop(J, 2);
return 0;
}
/* ToPrimitive() on a value */
void jsV_toprimitive(js_State *J, js_Value *v, int preferred)
{
js_Object *obj;
if (v->type != JS_TOBJECT)
return;
obj = v->u.object;
if (preferred == JS_HNONE)
preferred = obj->type == JS_CDATE ? JS_HSTRING : JS_HNUMBER;
if (preferred == JS_HSTRING) {
if (jsV_toString(J, obj) || jsV_valueOf(J, obj)) {
*v = *js_tovalue(J, -1);
js_pop(J, 1);
return;
}
} else {
if (jsV_valueOf(J, obj) || jsV_toString(J, obj)) {
*v = *js_tovalue(J, -1);
js_pop(J, 1);
return;
}
}
if (J->strict)
js_typeerror(J, "cannot convert object to primitive");
v->type = JS_TLITSTR;
v->u.litstr = "[object]";
return;
}
/* ToBoolean() on a value */
int jsV_toboolean(js_State *J, js_Value *v)
{
switch (v->type) {
default:
case JS_TSHRSTR: return v->u.shrstr[0] != 0;
case JS_TUNDEFINED: return 0;
case JS_TNULL: return 0;
case JS_TBOOLEAN: return v->u.boolean;
case JS_TNUMBER: return v->u.number != 0 && !isnan(v->u.number);
case JS_TLITSTR: return v->u.litstr[0] != 0;
case JS_TMEMSTR: return v->u.memstr->p[0] != 0;
case JS_TOBJECT: return 1;
}
}
const char *js_itoa(char *out, int v)
{
char buf[32], *s = out;
unsigned int a;
int i = 0;
if (v < 0) {
a = -v;
*s++ = '-';
} else {
a = v;
}
while (a) {
buf[i++] = (a % 10) + '0';
a /= 10;
}
if (i == 0)
buf[i++] = '0';
while (i > 0)
*s++ = buf[--i];
*s = 0;
return out;
}
double js_stringtofloat(const char *s, char **ep)
{
char *end;
double n;
const char *e = s;
int isflt = 0;
if (*e == '+' || *e == '-') ++e;
while (*e >= '0' && *e <= '9') ++e;
if (*e == '.') { ++e; isflt = 1; }
while (*e >= '0' && *e <= '9') ++e;
if (*e == 'e' || *e == 'E') {
++e;
if (*e == '+' || *e == '-') ++e;
while (*e >= '0' && *e <= '9') ++e;
isflt = 1;
}
if (isflt || e - s > 9)
n = js_strtod(s, &end);
else
n = strtol(s, &end, 10);
if (end == e) {
*ep = (char*)e;
return n;
}
*ep = (char*)s;
return 0;
}
/* ToNumber() on a string */
double jsV_stringtonumber(js_State *J, const char *s)
{
char *e;
double n;
while (jsY_iswhite(*s) || jsY_isnewline(*s)) ++s;
if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X') && s[2] != 0)
n = strtol(s + 2, &e, 16);
else if (!strncmp(s, "Infinity", 8))
n = INFINITY, e = (char*)s + 8;
else if (!strncmp(s, "+Infinity", 9))
n = INFINITY, e = (char*)s + 9;
else if (!strncmp(s, "-Infinity", 9))
n = -INFINITY, e = (char*)s + 9;
else
n = js_stringtofloat(s, &e);
while (jsY_iswhite(*e) || jsY_isnewline(*e)) ++e;
if (*e) return NAN;
return n;
}
/* ToNumber() on a value */
double jsV_tonumber(js_State *J, js_Value *v)
{
switch (v->type) {
default:
case JS_TSHRSTR: return jsV_stringtonumber(J, v->u.shrstr);
case JS_TUNDEFINED: return NAN;
case JS_TNULL: return 0;
case JS_TBOOLEAN: return v->u.boolean;
case JS_TNUMBER: return v->u.number;
case JS_TLITSTR: return jsV_stringtonumber(J, v->u.litstr);
case JS_TMEMSTR: return jsV_stringtonumber(J, v->u.memstr->p);
case JS_TOBJECT:
jsV_toprimitive(J, v, JS_HNUMBER);
return jsV_tonumber(J, v);
}
}
double jsV_tointeger(js_State *J, js_Value *v)
{
return jsV_numbertointeger(jsV_tonumber(J, v));
}
/* ToString() on a number */
const char *jsV_numbertostring(js_State *J, char buf[32], double f)
{
char digits[32], *p = buf, *s = digits;
int exp, ndigits, point;
if (f == 0) return "0";
if (isnan(f)) return "NaN";
if (isinf(f)) return f < 0 ? "-Infinity" : "Infinity";
/* Fast case for integers. This only works assuming all integers can be
* exactly represented by a float. This is true for 32-bit integers and
* 64-bit floats. */
if (f >= INT_MIN && f <= INT_MAX) {
int i = (int)f;
if ((double)i == f)
return js_itoa(buf, i);
}
ndigits = js_grisu2(f, digits, &exp);
point = ndigits + exp;
if (signbit(f))
*p++ = '-';
if (point < -5 || point > 21) {
*p++ = *s++;
if (ndigits > 1) {
int n = ndigits - 1;
*p++ = '.';
while (n--)
*p++ = *s++;
}
js_fmtexp(p, point - 1);
}
else if (point <= 0) {
*p++ = '0';
*p++ = '.';
while (point++ < 0)
*p++ = '0';
while (ndigits-- > 0)
*p++ = *s++;
*p = 0;
}
else {
while (ndigits-- > 0) {
*p++ = *s++;
if (--point == 0 && ndigits > 0)
*p++ = '.';
}
while (point-- > 0)
*p++ = '0';
*p = 0;
}
return buf;
}
/* ToString() on a value */
const char *jsV_tostring(js_State *J, js_Value *v)
{
char buf[32];
const char *p;
switch (v->type) {
default:
case JS_TSHRSTR: return v->u.shrstr;
case JS_TUNDEFINED: return "undefined";
case JS_TNULL: return "null";
case JS_TBOOLEAN: return v->u.boolean ? "true" : "false";
case JS_TLITSTR: return v->u.litstr;
case JS_TMEMSTR: return v->u.memstr->p;
case JS_TNUMBER:
p = jsV_numbertostring(J, buf, v->u.number);
if (p == buf) {
int n = strlen(p);
if (n <= soffsetof(js_Value, type)) {
char *s = v->u.shrstr;
while (n--) *s++ = *p++;
*s = 0;
v->type = JS_TSHRSTR;
return v->u.shrstr;
} else {
v->u.memstr = jsV_newmemstring(J, p, n);
v->type = JS_TMEMSTR;
return v->u.memstr->p;
}
}
return p;
case JS_TOBJECT:
jsV_toprimitive(J, v, JS_HSTRING);
return jsV_tostring(J, v);
}
}
/* Objects */
static js_Object *jsV_newboolean(js_State *J, int v)
{
js_Object *obj = jsV_newobject(J, JS_CBOOLEAN, J->Boolean_prototype);
obj->u.boolean = v;
return obj;
}
static js_Object *jsV_newnumber(js_State *J, double v)
{
js_Object *obj = jsV_newobject(J, JS_CNUMBER, J->Number_prototype);
obj->u.number = v;
return obj;
}
static js_Object *jsV_newstring(js_State *J, const char *v)
{
js_Object *obj = jsV_newobject(J, JS_CSTRING, J->String_prototype);
obj->u.s.string = js_intern(J, v); /* TODO: js_String */
obj->u.s.length = utflen(v);
return obj;
}
/* ToObject() on a value */
js_Object *jsV_toobject(js_State *J, js_Value *v)
{
switch (v->type) {
default:
case JS_TSHRSTR: return jsV_newstring(J, v->u.shrstr);
case JS_TUNDEFINED: js_typeerror(J, "cannot convert undefined to object");
case JS_TNULL: js_typeerror(J, "cannot convert null to object");
case JS_TBOOLEAN: return jsV_newboolean(J, v->u.boolean);
case JS_TNUMBER: return jsV_newnumber(J, v->u.number);
case JS_TLITSTR: return jsV_newstring(J, v->u.litstr);
case JS_TMEMSTR: return jsV_newstring(J, v->u.memstr->p);
case JS_TOBJECT: return v->u.object;
}
}
void js_newobjectx(js_State *J)
{
js_Object *prototype = NULL;
if (js_isobject(J, -1))
prototype = js_toobject(J, -1);
js_pop(J, 1);
js_pushobject(J, jsV_newobject(J, JS_COBJECT, prototype));
}
void js_newobject(js_State *J)
{
js_pushobject(J, jsV_newobject(J, JS_COBJECT, J->Object_prototype));
}
void js_newarguments(js_State *J)
{
js_pushobject(J, jsV_newobject(J, JS_CARGUMENTS, J->Object_prototype));
}
void js_newarray(js_State *J)
{
js_pushobject(J, jsV_newobject(J, JS_CARRAY, J->Array_prototype));
}
void js_newboolean(js_State *J, int v)
{
js_pushobject(J, jsV_newboolean(J, v));
}
void js_newnumber(js_State *J, double v)
{
js_pushobject(J, jsV_newnumber(J, v));
}
void js_newstring(js_State *J, const char *v)
{
js_pushobject(J, jsV_newstring(J, v));
}
void js_newfunction(js_State *J, js_Function *fun, js_Environment *scope)
{
js_Object *obj = jsV_newobject(J, JS_CFUNCTION, J->Function_prototype);
obj->u.f.function = fun;
obj->u.f.scope = scope;
js_pushobject(J, obj);
{
js_pushnumber(J, fun->numparams);
js_defproperty(J, -2, "length", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
js_newobject(J);
{
js_copy(J, -2);
js_defproperty(J, -2, "constructor", JS_DONTENUM);
}
js_defproperty(J, -2, "prototype", JS_DONTENUM | JS_DONTCONF);
}
}
void js_newscript(js_State *J, js_Function *fun, js_Environment *scope, int type)
{
js_Object *obj = jsV_newobject(J, type, NULL);
obj->u.f.function = fun;
obj->u.f.scope = scope;
js_pushobject(J, obj);
}
void js_newcfunction(js_State *J, js_CFunction cfun, const char *name, int length)
{
js_Object *obj = jsV_newobject(J, JS_CCFUNCTION, J->Function_prototype);
obj->u.c.name = name;
obj->u.c.function = cfun;
obj->u.c.constructor = NULL;
obj->u.c.length = length;
js_pushobject(J, obj);
{
js_pushnumber(J, length);
js_defproperty(J, -2, "length", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
js_newobject(J);
{
js_copy(J, -2);
js_defproperty(J, -2, "constructor", JS_DONTENUM);
}
js_defproperty(J, -2, "prototype", JS_DONTENUM | JS_DONTCONF);
}
}
/* prototype -- constructor */
void js_newcconstructor(js_State *J, js_CFunction cfun, js_CFunction ccon, const char *name, int length)
{
js_Object *obj = jsV_newobject(J, JS_CCFUNCTION, J->Function_prototype);
obj->u.c.name = name;
obj->u.c.function = cfun;
obj->u.c.constructor = ccon;
obj->u.c.length = length;
js_pushobject(J, obj); /* proto obj */
{
js_pushnumber(J, length);
js_defproperty(J, -2, "length", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
js_rot2(J); /* obj proto */
js_copy(J, -2); /* obj proto obj */
js_defproperty(J, -2, "constructor", JS_DONTENUM);
js_defproperty(J, -2, "prototype", JS_DONTENUM | JS_DONTCONF);
}
}
void js_newuserdatax(js_State *J, const char *tag, void *data, js_HasProperty has, js_Put put, js_Delete delete, js_Finalize finalize)
{
js_Object *prototype = NULL;
js_Object *obj;
if (js_isobject(J, -1))
prototype = js_toobject(J, -1);
js_pop(J, 1);
obj = jsV_newobject(J, JS_CUSERDATA, prototype);
obj->u.user.tag = tag;
obj->u.user.data = data;
obj->u.user.has = has;
obj->u.user.put = put;
obj->u.user.delete = delete;
obj->u.user.finalize = finalize;
js_pushobject(J, obj);
}
void js_newuserdata(js_State *J, const char *tag, void *data, js_Finalize finalize)
{
js_newuserdatax(J, tag, data, NULL, NULL, NULL, finalize);
}
/* Non-trivial operations on values. These are implemented using the stack. */
int js_instanceof(js_State *J)
{
js_Object *O, *V;
if (!js_iscallable(J, -1))
js_typeerror(J, "instanceof: invalid operand");
if (!js_isobject(J, -2))
return 0;
js_getproperty(J, -1, "prototype");
if (!js_isobject(J, -1))
js_typeerror(J, "instanceof: 'prototype' property is not an object");
O = js_toobject(J, -1);
js_pop(J, 1);
V = js_toobject(J, -2);
while (V) {
V = V->prototype;
if (O == V)
return 1;
}
return 0;
}
void js_concat(js_State *J)
{
js_toprimitive(J, -2, JS_HNONE);
js_toprimitive(J, -1, JS_HNONE);
if (js_isstring(J, -2) || js_isstring(J, -1)) {
const char *sa = js_tostring(J, -2);
const char *sb = js_tostring(J, -1);
/* TODO: create js_String directly */
char *sab = js_malloc(J, strlen(sa) + strlen(sb) + 1);
strcpy(sab, sa);
strcat(sab, sb);
if (js_try(J)) {
js_free(J, sab);
js_throw(J);
}
js_pop(J, 2);
js_pushstring(J, sab);
js_endtry(J);
js_free(J, sab);
} else {
double x = js_tonumber(J, -2);
double y = js_tonumber(J, -1);
js_pop(J, 2);
js_pushnumber(J, x + y);
}
}
int js_compare(js_State *J, int *okay)
{
js_toprimitive(J, -2, JS_HNUMBER);
js_toprimitive(J, -1, JS_HNUMBER);
*okay = 1;
if (js_isstring(J, -2) && js_isstring(J, -1)) {
return strcmp(js_tostring(J, -2), js_tostring(J, -1));
} else {
double x = js_tonumber(J, -2);
double y = js_tonumber(J, -1);
if (isnan(x) || isnan(y))
*okay = 0;
return x < y ? -1 : x > y ? 1 : 0;
}
}
int js_equal(js_State *J)
{
js_Value *x = js_tovalue(J, -2);
js_Value *y = js_tovalue(J, -1);
retry:
if (JSV_ISSTRING(x) && JSV_ISSTRING(y))
return !strcmp(JSV_TOSTRING(x), JSV_TOSTRING(y));
if (x->type == y->type) {
if (x->type == JS_TUNDEFINED) return 1;
if (x->type == JS_TNULL) return 1;
if (x->type == JS_TNUMBER) return x->u.number == y->u.number;
if (x->type == JS_TBOOLEAN) return x->u.boolean == y->u.boolean;
if (x->type == JS_TOBJECT) return x->u.object == y->u.object;
return 0;
}
if (x->type == JS_TNULL && y->type == JS_TUNDEFINED) return 1;
if (x->type == JS_TUNDEFINED && y->type == JS_TNULL) return 1;
if (x->type == JS_TNUMBER && JSV_ISSTRING(y))
return x->u.number == jsV_tonumber(J, y);
if (JSV_ISSTRING(x) && y->type == JS_TNUMBER)
return jsV_tonumber(J, x) == y->u.number;
if (x->type == JS_TBOOLEAN) {
x->type = JS_TNUMBER;
x->u.number = x->u.boolean ? 1 : 0;
goto retry;
}
if (y->type == JS_TBOOLEAN) {
y->type = JS_TNUMBER;
y->u.number = y->u.boolean ? 1 : 0;
goto retry;
}
if ((JSV_ISSTRING(x) || x->type == JS_TNUMBER) && y->type == JS_TOBJECT) {
jsV_toprimitive(J, y, JS_HNONE);
goto retry;
}
if (x->type == JS_TOBJECT && (JSV_ISSTRING(y) || y->type == JS_TNUMBER)) {
jsV_toprimitive(J, x, JS_HNONE);
goto retry;
}
return 0;
}
int js_strictequal(js_State *J)
{
js_Value *x = js_tovalue(J, -2);
js_Value *y = js_tovalue(J, -1);
if (JSV_ISSTRING(x) && JSV_ISSTRING(y))
return !strcmp(JSV_TOSTRING(x), JSV_TOSTRING(y));
if (x->type != y->type) return 0;
if (x->type == JS_TUNDEFINED) return 1;
if (x->type == JS_TNULL) return 1;
if (x->type == JS_TNUMBER) return x->u.number == y->u.number;
if (x->type == JS_TBOOLEAN) return x->u.boolean == y->u.boolean;
if (x->type == JS_TOBJECT) return x->u.object == y->u.object;
return 0;
}

View File

@ -1,188 +0,0 @@
#ifndef js_value_h
#define js_value_h
typedef struct js_Property js_Property;
typedef struct js_Iterator js_Iterator;
/* Hint to ToPrimitive() */
enum {
JS_HNONE,
JS_HNUMBER,
JS_HSTRING
};
enum js_Type {
JS_TSHRSTR, /* type tag doubles as string zero-terminator */
JS_TUNDEFINED,
JS_TNULL,
JS_TBOOLEAN,
JS_TNUMBER,
JS_TLITSTR,
JS_TMEMSTR,
JS_TOBJECT,
};
enum js_Class {
JS_COBJECT,
JS_CARRAY,
JS_CFUNCTION,
JS_CSCRIPT, /* function created from global code */
JS_CEVAL, /* function created from eval code */
JS_CCFUNCTION, /* built-in function */
JS_CERROR,
JS_CBOOLEAN,
JS_CNUMBER,
JS_CSTRING,
JS_CREGEXP,
JS_CDATE,
JS_CMATH,
JS_CJSON,
JS_CARGUMENTS,
JS_CITERATOR,
JS_CUSERDATA,
};
/*
Short strings abuse the js_Value struct. By putting the type tag in the
last byte, and using 0 as the tag for short strings, we can use the
entire js_Value as string storage by letting the type tag serve double
purpose as the string zero terminator.
*/
struct js_Value
{
union {
int boolean;
double number;
char shrstr[8];
const char *litstr;
js_String *memstr;
js_Object *object;
} u;
char pad[7]; /* extra storage for shrstr */
char type; /* type tag and zero terminator for shrstr */
};
struct js_String
{
js_String *gcnext;
char gcmark;
char p[1];
};
struct js_Regexp
{
void *prog;
char *source;
unsigned short flags;
unsigned short last;
};
struct js_Object
{
enum js_Class type;
int extensible;
js_Property *properties;
int count; /* number of properties, for array sparseness check */
js_Object *prototype;
union {
int boolean;
double number;
struct {
const char *string;
int length;
} s;
struct {
int length;
} a;
struct {
js_Function *function;
js_Environment *scope;
} f;
struct {
const char *name;
js_CFunction function;
js_CFunction constructor;
int length;
} c;
js_Regexp r;
struct {
js_Object *target;
js_Iterator *head;
} iter;
struct {
const char *tag;
void *data;
js_HasProperty has;
js_Put put;
js_Delete delete;
js_Finalize finalize;
} user;
} u;
js_Object *gcnext; /* allocation list */
js_Object *gcroot; /* scan list */
int gcmark;
};
struct js_Property
{
const char *name;
js_Property *left, *right;
int level;
int atts;
js_Value value;
js_Object *getter;
js_Object *setter;
};
struct js_Iterator
{
const char *name;
js_Iterator *next;
};
/* jsrun.c */
js_String *jsV_newmemstring(js_State *J, const char *s, int n);
js_Value *js_tovalue(js_State *J, int idx);
void js_toprimitive(js_State *J, int idx, int hint);
js_Object *js_toobject(js_State *J, int idx);
void js_pushvalue(js_State *J, js_Value v);
void js_pushobject(js_State *J, js_Object *v);
/* jsvalue.c */
int jsV_toboolean(js_State *J, js_Value *v);
double jsV_tonumber(js_State *J, js_Value *v);
double jsV_tointeger(js_State *J, js_Value *v);
const char *jsV_tostring(js_State *J, js_Value *v);
js_Object *jsV_toobject(js_State *J, js_Value *v);
void jsV_toprimitive(js_State *J, js_Value *v, int preferred);
const char *js_itoa(char buf[32], int a);
double js_stringtofloat(const char *s, char **ep);
int jsV_numbertointeger(double n);
int jsV_numbertoint32(double n);
unsigned int jsV_numbertouint32(double n);
short jsV_numbertoint16(double n);
unsigned short jsV_numbertouint16(double n);
const char *jsV_numbertostring(js_State *J, char buf[32], double number);
double jsV_stringtonumber(js_State *J, const char *string);
/* jsproperty.c */
js_Object *jsV_newobject(js_State *J, enum js_Class type, js_Object *prototype);
js_Property *jsV_getownproperty(js_State *J, js_Object *obj, const char *name);
js_Property *jsV_getpropertyx(js_State *J, js_Object *obj, const char *name, int *own);
js_Property *jsV_getproperty(js_State *J, js_Object *obj, const char *name);
js_Property *jsV_setproperty(js_State *J, js_Object *obj, const char *name);
js_Property *jsV_nextproperty(js_State *J, js_Object *obj, const char *name);
void jsV_delproperty(js_State *J, js_Object *obj, const char *name);
js_Object *jsV_newiterator(js_State *J, js_Object *obj, int own);
const char *jsV_nextiterator(js_State *J, js_Object *iter);
void jsV_resizearray(js_State *J, js_Object *obj, int newlen);
/* jsdump.c */
void js_dumpobject(js_State *J, js_Object *obj);
void js_dumpvalue(js_State *J, js_Value v);
#endif

Some files were not shown because too many files have changed in this diff Show More