aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Makefile90
-rw-r--r--build_win.bat53
-rw-r--r--meson.build49
-rw-r--r--src/boot/boot.c39
-rw-r--r--src/boot/boot.janet99
-rw-r--r--src/core/array.c12
-rw-r--r--src/core/buffer.c13
-rw-r--r--src/core/compile.c4
-rw-r--r--src/core/corelib.c2
-rw-r--r--src/core/debug.c2
-rw-r--r--src/core/fiber.c6
-rw-r--r--src/core/gc.c67
-rw-r--r--src/core/marsh.c8
-rw-r--r--src/core/parse.c11
-rw-r--r--src/core/peg.c10
-rw-r--r--src/core/state.h4
-rw-r--r--src/core/string.c18
-rw-r--r--src/core/strtod.c12
-rw-r--r--src/core/symcache.c2
-rw-r--r--src/core/tuple.c2
-rw-r--r--src/core/util.c10
-rw-r--r--src/core/util.h1
-rw-r--r--src/core/vector.c2
-rw-r--r--src/include/janet.h5
-rw-r--r--src/mainclient/line.h40
-rw-r--r--src/mainclient/main.c90
-rw-r--r--src/mainclient/shell.c (renamed from src/mainclient/line.c)78
-rw-r--r--tools/xxd.c104
28 files changed, 345 insertions, 488 deletions
diff --git a/Makefile b/Makefile
index 90b4f270..0ac79570 100644
--- a/Makefile
+++ b/Makefile
@@ -39,7 +39,7 @@ DEBUGGER=gdb
CFLAGS:=$(CFLAGS) -std=c99 -Wall -Wextra -Isrc/include -Isrc/conf -fPIC -O2 -fvisibility=hidden \
-DJANET_BUILD=$(JANET_BUILD)
-LDFLAGS=-rdynamic
+LDFLAGS:=$(LDFLAGS) -rdynamic
# For installation
LDCONFIG:=ldconfig "$(LIBDIR)"
@@ -124,17 +124,11 @@ JANET_BOOT_SOURCES=src/boot/array_test.c \
src/boot/table_test.c
JANET_BOOT_HEADERS=src/boot/tests.h
-JANET_MAINCLIENT_SOURCES=src/mainclient/line.c src/mainclient/main.c
-JANET_MAINCLIENT_HEADERS=src/mainclient/line.h
-
-JANET_WEBCLIENT_SOURCES=src/webclient/main.c
-
-##################################################################
-##### The bootstrap interpreter that compiles the core image #####
-##################################################################
+##########################################################
+##### The bootstrap interpreter that creates janet.c #####
+##########################################################
-JANET_BOOT_OBJECTS=$(patsubst src/%.c,build/%.boot.o,$(JANET_CORE_SOURCES) $(JANET_BOOT_SOURCES)) \
- build/boot.gen.o
+JANET_BOOT_OBJECTS=$(patsubst src/%.c,build/%.boot.o,$(JANET_CORE_SOURCES) $(JANET_BOOT_SOURCES))
$(JANET_BOOT_OBJECTS): $(JANET_BOOT_HEADERS)
@@ -142,65 +136,18 @@ build/%.boot.o: src/%.c $(JANET_HEADERS) $(JANET_LOCAL_HEADERS)
$(CC) $(CFLAGS) -DJANET_BOOTSTRAP -o $@ -c $<
build/janet_boot: $(JANET_BOOT_OBJECTS)
- $(CC) $(CFLAGS) -DJANET_BOOTSTRAP -o $@ $^ $(CLIBS)
+ $(CC) $(CFLAGS) -DJANET_BOOTSTRAP -o $@ $(JANET_BOOT_OBJECTS) $(CLIBS)
# Now the reason we bootstrap in the first place
-build/core_image.c: build/janet_boot
- build/janet_boot $@ JANET_PATH '$(JANET_PATH)' JANET_HEADERPATH '$(INCLUDEDIR)/janet'
-
-##########################################################
-##### The main interpreter program and shared object #####
-##########################################################
-
-JANET_CORE_OBJECTS=$(patsubst src/%.c,build/%.o,$(JANET_CORE_SOURCES)) build/core_image.o
-JANET_MAINCLIENT_OBJECTS=$(patsubst src/%.c,build/%.o,$(JANET_MAINCLIENT_SOURCES))
-
-$(JANET_MAINCLIENT_OBJECTS): $(JANET_MAINCLIENT_HEADERS)
-
-# Compile the core image generated by the bootstrap build
-build/core_image.o: build/core_image.c $(JANET_HEADERS) $(JANET_LOCAL_HEADERS)
- $(CC) $(CFLAGS) -o $@ -c $<
-
-build/%.o: src/%.c $(JANET_HEADERS) $(JANET_LOCAL_HEADERS)
- $(CC) $(CFLAGS) -o $@ -c $<
-
-$(JANET_TARGET): $(JANET_CORE_OBJECTS) $(JANET_MAINCLIENT_OBJECTS)
- $(CC) $(LDFLAGS) $(CFLAGS) -o $@ $^ $(CLIBS)
-
-$(JANET_LIBRARY): $(JANET_CORE_OBJECTS)
- $(CC) $(LDFLAGS) $(CFLAGS) -shared -o $@ $^ $(CLIBS)
-
-$(JANET_STATIC_LIBRARY): $(JANET_CORE_OBJECTS)
- $(AR) rcs $@ $^
-
-#############################
-##### Generated C files #####
-#############################
-
-%.gen.o: %.gen.c
- $(CC) $(CFLAGS) -o $@ -c $<
-
-build/xxd: tools/xxd.c
- $(CC) $< -o $@
-
-build/webinit.gen.c: src/webclient/webinit.janet build/xxd
- build/xxd $< $@ janet_gen_webinit
-build/boot.gen.c: src/boot/boot.janet build/xxd
- build/xxd $< $@ janet_gen_boot
+build/janet.c: build/janet_boot src/boot/boot.janet
+ build/janet_boot . JANET_PATH '$(JANET_PATH)' JANET_HEADERPATH '$(INCLUDEDIR)/janet' > $@
########################
##### Amalgamation #####
########################
-amalg: build/shell.c build/janet.c build/janet.h build/core_image.c build/janetconf.h
-
-AMALG_SOURCE=$(JANET_LOCAL_HEADERS) $(JANET_CORE_SOURCES) build/core_image.c
-build/janet.c: $(AMALG_SOURCE) tools/amalg.janet $(JANET_TARGET)
- $(JANET_TARGET) tools/amalg.janet $(AMALG_SOURCE) > $@
-
-AMALG_SHELL_SOURCE=src/mainclient/line.h src/mainclient/line.c src/mainclient/main.c
-build/shell.c: $(JANET_TARGET) tools/amalg.janet $(AMALG_SHELL_SOURCE)
- $(JANET_TARGET) tools/amalg.janet $(AMALG_SHELL_SOURCE) > $@
+build/shell.c: src/mainclient/shell.c
+ cp $< $@
build/janet.h: src/include/janet.h
cp $< $@
@@ -208,6 +155,21 @@ build/janet.h: src/include/janet.h
build/janetconf.h: src/conf/janetconf.h
cp $< $@
+build/janet.o: build/janet.c build/janet.h build/janetconf.h
+ $(CC) $(LDFLAGS) $(CFLAGS) -c $< -o $@ -I build $(CLIBS)
+
+build/shell.o: build/shell.c build/janet.h build/janetconf.h
+ $(CC) $(LDFLAGS) $(CFLAGS) -c $< -o $@ -I build $(CLIBS)
+
+$(JANET_TARGET): build/janet.o build/shell.o
+ $(CC) $(LDFLAGS) $(CFLAGS) -o $@ $^ $(CLIBS)
+
+$(JANET_LIBRARY): build/janet.o build/shell.o
+ $(CC) $(LDFLAGS) $(CFLAGS) -shared -o $@ $^ $(CLIBS)
+
+$(JANET_STATIC_LIBRARY): build/janet.o build/shell.o
+ $(AR) rcs $@ $^
+
###################
##### Testing #####
###################
@@ -349,5 +311,5 @@ build/embed_test: build/embed_janet.o build/embed_main.o
test-amalg: build/embed_test
./build/embed_test
-.PHONY: clean install repl debug valgrind test amalg \
+.PHONY: clean install repl debug valgrind test \
valtest emscripten dist uninstall docs grammar format
diff --git a/build_win.bat b/build_win.bat
index aca1dbbe..e783064e 100644
--- a/build_win.bat
+++ b/build_win.bat
@@ -33,20 +33,6 @@ mkdir build\core
mkdir build\mainclient
mkdir build\boot
-@rem Build the xxd tool for generating sources
-cl /nologo /c tools/xxd.c /Fobuild\xxd.obj
-@if errorlevel 1 goto :BUILDFAIL
-link /nologo /out:build\xxd.exe build\xxd.obj
-@if errorlevel 1 goto :BUILDFAIL
-
-@rem Generate the embedded sources
-build\xxd.exe src\boot\boot.janet build\boot.gen.c janet_gen_boot
-@if errorlevel 1 goto :BUILDFAIL
-
-@rem Build the generated sources
-%JANET_COMPILE% /Fobuild\boot\boot.gen.obj build\boot.gen.c
-@if errorlevel 1 goto :BUILDFAIL
-
@rem Build the bootstrap interpreter
for %%f in (src\core\*.c) do (
%JANET_COMPILE% /DJANET_BOOTSTRAP /Fobuild\boot\%%~nf.obj %%f
@@ -58,48 +44,25 @@ for %%f in (src\boot\*.c) do (
)
%JANET_LINK% /out:build\janet_boot.exe build\boot\*.obj
@if errorlevel 1 goto :BUILDFAIL
-build\janet_boot build\core_image.c
-
-@rem Build the core image
-%JANET_COMPILE% /Fobuild\core_image.obj build\core_image.c
-@if errorlevel 1 goto :BUILDFAIL
+build\janet_boot . > build\janet.c
@rem Build the sources
-for %%f in (src\core\*.c) do (
- %JANET_COMPILE% /Fobuild\core\%%~nf.obj %%f
- @if errorlevel 1 goto :BUILDFAIL
-)
+%JANET_COMPILE% /Fobuild\janet.obj build\janet.c
+@if errorlevel 1 goto :BUILDFAIL
+%JANET_COMPILE% /Fobuild\shell.obj src\mainclient\shell.c
+@if errorlevel 1 goto :BUILDFAIL
@rem Build the resources
rc /nologo /fobuild\janet_win.res janet_win.rc
-@rem Build the main client
-for %%f in (src\mainclient\*.c) do (
- %JANET_COMPILE% /Fobuild\mainclient\%%~nf.obj %%f
- @if errorlevel 1 goto :BUILDFAIL
-)
-
@rem Link everything to main client
-%JANET_LINK% /out:janet.exe build\core\*.obj build\mainclient\*.obj build\core_image.obj build\janet_win.res
+%JANET_LINK% /out:janet.exe build\janet.obj build\shell.obj build\janet_win.res
@if errorlevel 1 goto :BUILDFAIL
@rem Build static library (libjanet.a)
-%JANET_LINK_STATIC% /out:build\libjanet.lib build\core\*.obj build\core_image.obj
+%JANET_LINK_STATIC% /out:build\libjanet.lib build\janet.obj
@if errorlevel 1 goto :BUILDFAIL
-@rem Gen amlag
-setlocal enabledelayedexpansion
-set "amalg_files="
-for %%f in (src\core\*.c) do (
- set "amalg_files=!amalg_files! %%f"
-)
-janet.exe tools\amalg.janet src\core\features.h src\core\util.h src\core\state.h src\core\gc.h src\core\vector.h src\core\fiber.h src\core\regalloc.h src\core\compile.h src\core\emit.h src\core\symcache.h %amalg_files% build\core_image.c > build\janet.c
-janet.exe tools\removecr.janet build\janet.c
-
-@rem Gen shell.c
-janet.exe tools\amalg.janet src\mainclient\line.h src\mainclient\line.c src\mainclient\main.c > build\shell.c
-janet.exe tools\removecr.janet build\shell.c
-
echo === Successfully built janet.exe for Windows ===
echo === Run 'build_win test' to run tests. ==
echo === Run 'build_win clean' to delete build artifacts. ===
@@ -141,7 +104,7 @@ janet.exe tools\gendoc.janet > dist\doc.html
janet.exe tools\removecr.janet dist\doc.html
copy build\janet.c dist\janet.c
-copy build\shell.c dist\shell.c
+copy src\mainclient\shell.c dist\shell.c
copy janet.exe dist\janet.exe
copy LICENSE dist\LICENSE
copy README.md dist\README.md
diff --git a/meson.build b/meson.build
index ad02b255..fe9a02f8 100644
--- a/meson.build
+++ b/meson.build
@@ -79,13 +79,6 @@ jconf = configure_file(output : 'janetconf.h',
# Include directories
incdir = include_directories(['src/include', '.'])
-# Building generated sources
-xxd = executable('xxd', 'tools/xxd.c', native : true)
-gen = generator(xxd,
- output : '@BASENAME@.gen.c',
- arguments : ['@INPUT@', '@OUTPUT@', '@EXTRA_ARGS@'])
-boot_gen = gen.process('src/boot/boot.janet', extra_args: 'janet_gen_boot')
-
# Order is important here, as some headers
# depend on other headers for the amalg target
core_headers = [
@@ -151,24 +144,27 @@ boot_src = [
]
mainclient_src = [
- 'src/mainclient/line.c',
- 'src/mainclient/main.c'
+ 'src/mainclient/shell.c'
]
# Build boot binary
-janet_boot = executable('janet-boot', core_src, boot_src, boot_gen,
+janet_boot = executable('janet-boot', core_src, boot_src,
include_directories : incdir,
c_args : '-DJANET_BOOTSTRAP',
dependencies : [m_dep, dl_dep, thread_dep],
native : true)
-# Build core image
-core_image = custom_target('core_image',
+# Build janet.c
+janetc = custom_target('janetc',
input : [janet_boot],
- output : 'core_image.gen.c',
- command : [janet_boot, '@OUTPUT@', 'JANET_PATH', janet_path, 'JANET_HEADERPATH', header_path])
+ output : 'janet.c',
+ capture : true,
+ command : [
+ janet_boot, '@CURRENT_SOURCE_DIR@',
+ 'JANET_PATH', janet_path, 'JANET_HEADERPATH', header_path
+ ])
-libjanet = library('janet', core_src, core_image,
+libjanet = library('janet', janetc,
include_directories : incdir,
dependencies : [m_dep, dl_dep, thread_dep],
install : true)
@@ -188,14 +184,14 @@ else
extra_cross_cflags = []
endif
-janet_mainclient = executable('janet', core_src, core_image, mainclient_src,
+janet_mainclient = executable('janet', janetc, mainclient_src,
include_directories : incdir,
dependencies : [m_dep, dl_dep, thread_dep],
c_args : extra_native_cflags,
install : true)
if meson.is_cross_build()
- janet_nativeclient = executable('janet-native', core_src, core_image, mainclient_src,
+ janet_nativeclient = executable('janet-native', janetc, mainclient_src,
include_directories : incdir,
dependencies : [m_dep, dl_dep, thread_dep],
c_args : extra_cross_cflags,
@@ -211,25 +207,6 @@ docs = custom_target('docs',
capture : true,
command : [janet_nativeclient, '@INPUT@'])
-# Amalgamated source
-amalg = custom_target('amalg',
- input : ['tools/amalg.janet', core_headers, core_src, core_image],
- output : ['janet.c'],
- capture : true,
- command : [janet_nativeclient, '@INPUT@'])
-amalg_shell = custom_target('amalg-shell',
- input : ['tools/amalg.janet', 'src/mainclient/line.h',
- 'src/mainclient/line.c', 'src/mainclient/main.c'],
- output : ['shell.c'],
- capture : true,
- command : [janet_nativeclient, '@INPUT@'])
-
-# Amalgamated client
-janet_amalgclient = executable('janet-amalg', amalg, amalg_shell,
- include_directories : incdir,
- dependencies : [m_dep, dl_dep, thread_dep],
- build_by_default : false)
-
# Tests
test_files = [
'test/suite0.janet',
diff --git a/src/boot/boot.c b/src/boot/boot.c
index 0caf017b..9cf64f2b 100644
--- a/src/boot/boot.c
+++ b/src/boot/boot.c
@@ -23,6 +23,13 @@
#include <janet.h>
#include "tests.h"
+#ifdef JANET_WINDOWS
+#include <windows.h>
+#define chdir(x) _chdir(x)
+#else
+#include <unistd.h>
+#endif
+
extern const unsigned char *janet_gen_boot;
extern int32_t janet_gen_boot_size;
@@ -63,13 +70,37 @@ int main(int argc, const char **argv) {
janet_def(env, "boot/config", janet_wrap_table(opts), "Boot options");
/* Run bootstrap script to generate core image */
- const char *boot_file;
+ const char *boot_filename;
#ifdef JANET_NO_SOURCEMAPS
- boot_file = NULL;
+ boot_filename = NULL;
#else
- boot_file = "boot.janet";
+ boot_filename = "boot.janet";
#endif
- status = janet_dobytes(env, janet_gen_boot, janet_gen_boot_size, boot_file, NULL);
+
+ chdir(argv[1]);
+
+ FILE *boot_file = fopen("src/boot/boot.janet", "rb");
+ if (NULL == boot_file) {
+ fprintf(stderr, "Could not open src/boot/boot.janet\n");
+ exit(1);
+ }
+
+ /* Slurp file into buffer */
+ fseek(boot_file, 0, SEEK_END);
+ size_t boot_size = ftell(boot_file);
+ fseek(boot_file, 0, SEEK_SET);
+ unsigned char *boot_buffer = malloc(boot_size);
+ if (NULL == boot_buffer) {
+ fprintf(stderr, "Failed to allocate boot buffer\n");
+ exit(1);
+ }
+ if (!fread(boot_buffer, 1, boot_size, boot_file)) {
+ fprintf(stderr, "Failed to read into boot buffer\n");
+ exit(1);
+ }
+ fclose(boot_file);
+
+ status = janet_dobytes(env, boot_buffer, boot_size, boot_filename, NULL);
/* Deinitialize vm */
janet_deinit();
diff --git a/src/boot/boot.janet b/src/boot/boot.janet
index 5b0e53a8..f1360943 100644
--- a/src/boot/boot.janet
+++ b/src/boot/boot.janet
@@ -1,5 +1,5 @@
# The core janet library
-# Copyright 2019 © Calvin Rose
+# Copyright 2020 © Calvin Rose
###
###
@@ -2391,21 +2391,88 @@
reverse-lookup (invert lookup)]
(marshal env reverse-lookup)))
+ # Create amalgamation
+
+ (def local-headers
+ ["src/core/features.h"
+ "src/core/util.h"
+ "src/core/state.h"
+ "src/core/gc.h"
+ "src/core/vector.h"
+ "src/core/fiber.h"
+ "src/core/regalloc.h"
+ "src/core/compile.h"
+ "src/core/emit.h"
+ "src/core/symcache.h"])
+
+ (def core-sources
+ ["src/core/abstract.c"
+ "src/core/array.c"
+ "src/core/asm.c"
+ "src/core/buffer.c"
+ "src/core/bytecode.c"
+ "src/core/capi.c"
+ "src/core/cfuns.c"
+ "src/core/compile.c"
+ "src/core/corelib.c"
+ "src/core/debug.c"
+ "src/core/emit.c"
+ "src/core/fiber.c"
+ "src/core/gc.c"
+ "src/core/inttypes.c"
+ "src/core/io.c"
+ "src/core/marsh.c"
+ "src/core/math.c"
+ "src/core/os.c"
+ "src/core/parse.c"
+ "src/core/peg.c"
+ "src/core/pp.c"
+ "src/core/regalloc.c"
+ "src/core/run.c"
+ "src/core/specials.c"
+ "src/core/string.c"
+ "src/core/strtod.c"
+ "src/core/struct.c"
+ "src/core/symcache.c"
+ "src/core/table.c"
+ "src/core/thread.c"
+ "src/core/tuple.c"
+ "src/core/typedarray.c"
+ "src/core/util.c"
+ "src/core/value.c"
+ "src/core/vector.c"
+ "src/core/vm.c"
+ "src/core/wrap.c"])
+
+ # Print janet.c to stdout
+ (print "/* Amalgamated build - DO NOT EDIT */")
+ (print "/* Generated from janet version " janet/version "-" janet/build " */")
+ (print "#define JANET_BUILD \"" janet/build "\"")
+ (print ```#define JANET_AMALG```)
+ (print ```#define _POSIX_C_SOURCE 200112L```)
+ (print ```#include "janet.h"```)
+
+ (defn do-one-flie
+ [fname]
+ (print "\n/* " fname " */\n")
+ (def source (slurp fname))
+ (print (string/replace-all "\r" "" source)))
+
+ (each h local-headers
+ (do-one-flie h))
+
+ (each s core-sources
+ (do-one-flie s))
+
# Create C source file that contains images a uint8_t buffer. This
# can be compiled and linked statically into the main janet library
# and example client.
- (def chunks (string/bytes image))
- (def image-file (file/open (boot/args 1) :wb))
- (file/write image-file
- "#ifndef JANET_AMALG\n"
- "#include <janet.h>\n"
- "#endif\n"
- "static const unsigned char janet_core_image_bytes[] = {\n")
- (loop [line :in (partition 10 chunks)]
- (def str (string ;(interpose ", " (map (partial string/format "0x%.2X") line))))
- (file/write image-file " " str ",\n"))
- (file/write image-file
- " 0\n};\n\n"
- "const unsigned char *janet_core_image = janet_core_image_bytes;\n"
- "size_t janet_core_image_size = sizeof(janet_core_image_bytes);\n")
- (file/close image-file))
+ (print "static const unsigned char janet_core_image_bytes[] = {")
+ (loop [line :in (partition 16 image)]
+ (prin " ")
+ (each b line
+ (prinf "0x%.2X, " b))
+ (print))
+ (print " 0\n};\n")
+ (print "const unsigned char *janet_core_image = janet_core_image_bytes;")
+ (print "size_t janet_core_image_size = sizeof(janet_core_image_bytes);"))
diff --git a/src/core/array.c b/src/core/array.c
index 22a929cf..46014d9c 100644
--- a/src/core/array.c
+++ b/src/core/array.c
@@ -56,7 +56,7 @@ JanetArray *janet_array_n(const Janet *elements, int32_t n) {
if (!array->data) {
JANET_OUT_OF_MEMORY;
}
- memcpy(array->data, elements, sizeof(Janet) * n);
+ safe_memcpy(array->data, elements, sizeof(Janet) * n);
return array;
}
@@ -235,10 +235,12 @@ static Janet cfun_array_insert(int32_t argc, Janet *argv) {
janet_panic("array overflow");
}
janet_array_ensure(array, array->count + argc - 2, 2);
- memmove(array->data + at + argc - 2,
- array->data + at,
- restsize);
- memcpy(array->data + at, argv + 2, chunksize);
+ if (restsize) {
+ memmove(array->data + at + argc - 2,
+ array->data + at,
+ restsize);
+ }
+ safe_memcpy(array->data + at, argv + 2, chunksize);
array->count += (argc - 2);
return argv[0];
}
diff --git a/src/core/buffer.c b/src/core/buffer.c
index 9691a552..1f2327a5 100644
--- a/src/core/buffer.c
+++ b/src/core/buffer.c
@@ -112,6 +112,7 @@ void janet_buffer_push_cstring(JanetBuffer *buffer, const char *cstring) {
/* Push multiple bytes into the buffer */
void janet_buffer_push_bytes(JanetBuffer *buffer, const uint8_t *string, int32_t length) {
+ if (0 == length) return;
janet_buffer_extra(buffer, length);
memcpy(buffer->data + buffer->count, string, length);
buffer->count += length;
@@ -338,11 +339,13 @@ static Janet cfun_buffer_blit(int32_t argc, Janet *argv) {
janet_panic("buffer blit out of range");
janet_buffer_ensure(dest, (int32_t) last, 2);
if (last > dest->count) dest->count = (int32_t) last;
- if (same_buf) {
- src.bytes = dest->data;
- memmove(dest->data + offset_dest, src.bytes + offset_src, length_src);
- } else {
- memcpy(dest->data + offset_dest, src.bytes + offset_src, length_src);
+ if (length_src) {
+ if (same_buf) {
+ src.bytes = dest->data;
+ memmove(dest->data + offset_dest, src.bytes + offset_src, length_src);
+ } else {
+ memcpy(dest->data + offset_dest, src.bytes + offset_src, length_src);
+ }
}
return argv[0];
}
diff --git a/src/core/compile.c b/src/core/compile.c
index c388c37d..62fb4b0b 100644
--- a/src/core/compile.c
+++ b/src/core/compile.c
@@ -713,7 +713,7 @@ JanetFuncDef *janetc_pop_funcdef(JanetCompiler *c) {
if (NULL == def->bytecode) {
JANET_OUT_OF_MEMORY;
}
- memcpy(def->bytecode, c->buffer + scope->bytecode_start, s);
+ safe_memcpy(def->bytecode, c->buffer + scope->bytecode_start, s);
janet_v__cnt(c->buffer) = scope->bytecode_start;
if (NULL != c->mapbuffer && c->source) {
size_t s = sizeof(JanetSourceMapping) * (size_t) def->bytecode_length;
@@ -721,7 +721,7 @@ JanetFuncDef *janetc_pop_funcdef(JanetCompiler *c) {
if (NULL == def->sourcemap) {
JANET_OUT_OF_MEMORY;
}
- memcpy(def->sourcemap, c->mapbuffer + scope->bytecode_start, s);
+ safe_memcpy(def->sourcemap, c->mapbuffer + scope->bytecode_start, s);
janet_v__cnt(c->mapbuffer) = scope->bytecode_start;
}
}
diff --git a/src/core/corelib.c b/src/core/corelib.c
index bb981bbe..5042ddbf 100644
--- a/src/core/corelib.c
+++ b/src/core/corelib.c
@@ -346,7 +346,7 @@ static Janet janet_core_tuple(int32_t argc, Janet *argv) {
static Janet janet_core_array(int32_t argc, Janet *argv) {
JanetArray *array = janet_array(argc);
array->count = argc;
- memcpy(array->data, argv, argc * sizeof(Janet));
+ safe_memcpy(array->data, argv, argc * sizeof(Janet));
return janet_wrap_array(array);
}
diff --git a/src/core/debug.c b/src/core/debug.c
index 3e79c641..9a7e9db5 100644
--- a/src/core/debug.c
+++ b/src/core/debug.c
@@ -275,7 +275,7 @@ static Janet doframe(JanetStackFrame *frame) {
}
/* Add stack arguments */
slots = janet_array(def->slotcount);
- memcpy(slots->data, stack, sizeof(Janet) * def->slotcount);
+ safe_memcpy(slots->data, stack, sizeof(Janet) * def->slotcount);
slots->count = def->slotcount;
janet_table_put(t, janet_ckeywordv("slots"), janet_wrap_array(slots));
}
diff --git a/src/core/fiber.c b/src/core/fiber.c
index 5e4a0845..124b9f39 100644
--- a/src/core/fiber.c
+++ b/src/core/fiber.c
@@ -65,7 +65,7 @@ JanetFiber *janet_fiber_reset(JanetFiber *fiber, JanetFunction *callee, int32_t
if (newstacktop >= fiber->capacity) {
janet_fiber_setcapacity(fiber, 2 * newstacktop);
}
- memcpy(fiber->data + fiber->stacktop, argv, argc * sizeof(Janet));
+ safe_memcpy(fiber->data + fiber->stacktop, argv, argc * sizeof(Janet));
fiber->stacktop = newstacktop;
}
if (janet_fiber_funcframe(fiber, callee)) return NULL;
@@ -135,7 +135,7 @@ void janet_fiber_pushn(JanetFiber *fiber, const Janet *arr, int32_t n) {
if (newtop > fiber->capacity) {
janet_fiber_grow(fiber, newtop);
}
- memcpy(fiber->data + fiber->stacktop, arr, n * sizeof(Janet));
+ safe_memcpy(fiber->data + fiber->stacktop, arr, n * sizeof(Janet));
fiber->stacktop = newtop;
}
@@ -217,7 +217,7 @@ static void janet_env_detach(JanetFuncEnv *env) {
if (NULL == vmem) {
JANET_OUT_OF_MEMORY;
}
- memcpy(vmem, env->as.fiber->data + env->offset, s);
+ safe_memcpy(vmem, env->as.fiber->data + env->offset, s);
env->offset = 0;
env->as.values = vmem;
}
diff --git a/src/core/gc.c b/src/core/gc.c
index b5d62ddd..ba3e3400 100644
--- a/src/core/gc.c
+++ b/src/core/gc.c
@@ -29,6 +29,11 @@
#include "util.h"
#endif
+struct JanetScratch {
+ JanetScratchFinalizer finalize;
+ long long mem[]; /* for proper alignment */
+};
+
/* GC State */
JANET_THREAD_LOCAL void *janet_vm_blocks;
JANET_THREAD_LOCAL size_t janet_vm_gc_interval;
@@ -41,14 +46,7 @@ JANET_THREAD_LOCAL size_t janet_vm_root_count;
JANET_THREAD_LOCAL size_t janet_vm_root_capacity;
/* Scratch Memory */
-#ifdef JANET_64
-#define SCRATCH_HDR_SIZE 16 /* smalloc must guarantee 16 byte alignment. */
-#elif JANET_32
-#define SCRATCH_HDR_SIZE 8 /* smalloc must guarantee 8 byte alignment. */
-#else
-#error "unknown scratch alignment"
-#endif
-JANET_THREAD_LOCAL void **janet_scratch_mem;
+JANET_THREAD_LOCAL JanetScratch **janet_scratch_mem;
JANET_THREAD_LOCAL size_t janet_scratch_cap;
JANET_THREAD_LOCAL size_t janet_scratch_len;
@@ -360,11 +358,11 @@ void *janet_gcalloc(enum JanetMemoryType type, size_t size) {
return (void *)mem;
}
-static void free_one_scratch(void *mem) {
- ScratchFinalizer finalize = *(ScratchFinalizer *)mem;
- if (finalize)
- finalize((char *)mem + SCRATCH_HDR_SIZE);
- free(mem);
+static void free_one_scratch(JanetScratch *s) {
+ if (NULL != s->finalize) {
+ s->finalize((char *) s->mem);
+ }
+ free(s);
}
/* Free all allocated scratch memory */
@@ -375,6 +373,11 @@ static void janet_free_all_scratch(void) {
janet_scratch_len = 0;
}
+static JanetScratch *janet_mem2scratch(void *mem) {
+ JanetScratch *s = (JanetScratch *)mem;
+ return s - 1;
+}
+
/* Run garbage collection */
void janet_collect(void) {
uint32_t i;
@@ -478,26 +481,26 @@ void janet_gcunlock(int handle) {
/* Scratch memory API */
void *janet_smalloc(size_t size) {
- void *mem = malloc(SCRATCH_HDR_SIZE + size);
- if (NULL == mem) {
+ JanetScratch *s = malloc(sizeof(JanetScratch) + size);
+ if (NULL == s) {
JANET_OUT_OF_MEMORY;
}
- *(ScratchFinalizer *)mem = NULL;
+ s->finalize = NULL;
if (janet_scratch_len == janet_scratch_cap) {
size_t newcap = 2 * janet_scratch_cap + 2;
- void **newmem = (void **) realloc(janet_scratch_mem, newcap * sizeof(void *));
+ JanetScratch **newmem = (JanetScratch **) realloc(janet_scratch_mem, newcap * sizeof(JanetScratch));
if (NULL == newmem) {
JANET_OUT_OF_MEMORY;
}
janet_scratch_cap = newcap;
janet_scratch_mem = newmem;
}
- janet_scratch_mem[janet_scratch_len++] = mem;
- return (char *)mem + SCRATCH_HDR_SIZE;
+ janet_scratch_mem[janet_scratch_len++] = s;
+ return (char *)(s->mem);
}
void *janet_scalloc(size_t nmemb, size_t size) {
- if (nmemb && size > (size_t) -1 / size) {
+ if (nmemb && size > SIZE_MAX / nmemb) {
JANET_OUT_OF_MEMORY;
}
size_t n = nmemb * size;
@@ -508,16 +511,16 @@ void *janet_scalloc(size_t nmemb, size_t size) {
void *janet_srealloc(void *mem, size_t size) {
if (NULL == mem) return janet_smalloc(size);
- mem = (char *)mem - SCRATCH_HDR_SIZE;
+ JanetScratch *s = janet_mem2scratch(mem);
if (janet_scratch_len) {
for (size_t i = janet_scratch_len - 1; ; i--) {
- if (janet_scratch_mem[i] == mem) {
- void *newmem = realloc(mem, size + SCRATCH_HDR_SIZE);
- if (NULL == newmem) {
+ if (janet_scratch_mem[i] == s) {
+ JanetScratch *news = realloc(s, size + sizeof(JanetScratch));
+ if (NULL == news) {
JANET_OUT_OF_MEMORY;
}
- janet_scratch_mem[i] = newmem;
- return (char *)newmem + SCRATCH_HDR_SIZE;
+ janet_scratch_mem[i] = news;
+ return (char *)(news->mem);
}
if (i == 0) break;
}
@@ -525,19 +528,19 @@ void *janet_srealloc(void *mem, size_t size) {
janet_exit("invalid janet_srealloc");
}
-void janet_sfinalizer(void *mem, ScratchFinalizer finalizer) {
- mem = (char *)mem - SCRATCH_HDR_SIZE;
- *(ScratchFinalizer *)mem = finalizer;
+void janet_sfinalizer(void *mem, JanetScratchFinalizer finalizer) {
+ JanetScratch *s = janet_mem2scratch(mem);
+ s->finalize = finalizer;
}
void janet_sfree(void *mem) {
if (NULL == mem) return;
- mem = (char *)mem - SCRATCH_HDR_SIZE;
+ JanetScratch *s = janet_mem2scratch(mem);
if (janet_scratch_len) {
for (size_t i = janet_scratch_len - 1; ; i--) {
- if (janet_scratch_mem[i] == mem) {
+ if (janet_scratch_mem[i] == s) {
janet_scratch_mem[i] = janet_scratch_mem[--janet_scratch_len];
- free_one_scratch(mem);
+ free_one_scratch(s);
return;
}
if (i == 0) break;
diff --git a/src/core/marsh.c b/src/core/marsh.c
index 263dec39..48ba55cb 100644
--- a/src/core/marsh.c
+++ b/src/core/marsh.c
@@ -95,8 +95,8 @@ void janet_env_lookup_into(JanetTable *renv, JanetTable *env, const char *prefix
const uint8_t *oldsym = janet_unwrap_symbol(env->data[i].key);
int32_t oldlen = janet_string_length(oldsym);
uint8_t *symbuf = janet_smalloc(prelen + oldlen);
- memcpy(symbuf, prefix, prelen);
- memcpy(symbuf + prelen, oldsym, oldlen);
+ safe_memcpy(symbuf, prefix, prelen);
+ safe_memcpy(symbuf + prelen, oldsym, oldlen);
Janet s = janet_symbolv(symbuf, prelen + oldlen);
janet_sfree(symbuf);
janet_table_put(renv, s, entry_getval(env->data[i].value));
@@ -1017,7 +1017,7 @@ uint8_t janet_unmarshal_byte(JanetMarshalContext *ctx) {
void janet_unmarshal_bytes(JanetMarshalContext *ctx, uint8_t *dest, size_t len) {
UnmarshalState *st = (UnmarshalState *)(ctx->u_state);
MARSH_EOS(st, ctx->data + len - 1);
- memcpy(dest, ctx->data, len);
+ safe_memcpy(dest, ctx->data, len);
ctx->data += len;
}
@@ -1139,7 +1139,7 @@ static const uint8_t *unmarshal_one(
} else { /* (lead == LB_BUFFER) */
JanetBuffer *buffer = janet_buffer(len);
buffer->count = len;
- memcpy(buffer->data, data, len);
+ safe_memcpy(buffer->data, data, len);
*out = janet_wrap_buffer(buffer);
}
janet_v_push(st->lookup, *out);
diff --git a/src/core/parse.c b/src/core/parse.c
index 5a44c494..8e477580 100644
--- a/src/core/parse.c
+++ b/src/core/parse.c
@@ -688,20 +688,19 @@ void janet_parser_clone(const JanetParser *src, JanetParser *dest) {
if (dest->bufcap) {
dest->buf = malloc(dest->bufcap);
if (!dest->buf) goto nomem;
+ memcpy(dest->buf, src->buf, dest->bufcap);
}
if (dest->argcap) {
dest->args = malloc(sizeof(Janet) * dest->argcap);
if (!dest->args) goto nomem;
+ memcpy(dest->args, src->args, dest->argcap * sizeof(Janet));
}
if (dest->statecap) {
dest->states = malloc(sizeof(JanetParseState) * dest->statecap);
if (!dest->states) goto nomem;
+ memcpy(dest->states, src->states, dest->statecap * sizeof(JanetParseState));
}
- memcpy(dest->buf, src->buf, dest->bufcap);
- memcpy(dest->args, src->args, dest->argcap * sizeof(Janet));
- memcpy(dest->states, src->states, dest->statecap * sizeof(JanetParseState));
-
return;
nomem:
@@ -808,7 +807,7 @@ static Janet cfun_parse_insert(int32_t argc, Janet *argv) {
}
p->bufcap = newcap;
}
- memcpy(p->buf + p->bufcount, str, slen);
+ safe_memcpy(p->buf + p->bufcount, str, slen);
p->bufcount = newcount;
} else {
janet_panic("cannot insert value into parser");
@@ -891,7 +890,7 @@ static Janet janet_wrap_parse_state(JanetParseState *s, Janet *args,
if (s->flags & PFLAG_CONTAINER) {
JanetArray *container_args = janet_array(s->argn);
container_args->count = s->argn;
- memcpy(container_args->data, args, sizeof(args[0])*s->argn);
+ safe_memcpy(container_args->data, args, sizeof(args[0])*s->argn);
janet_table_put(state, janet_ckeywordv("args"),
janet_wrap_array(container_args));
}
diff --git a/src/core/peg.c b/src/core/peg.c
index 53f436d6..07775412 100644
--- a/src/core/peg.c
+++ b/src/core/peg.c
@@ -348,9 +348,9 @@ tail:
if (!result) return NULL;
int32_t num_sub_captures = s->captures->count - cs.cap;
JanetArray *sub_captures = janet_array(num_sub_captures);
- memcpy(sub_captures->data,
- s->captures->data + cs.cap,
- sizeof(Janet) * num_sub_captures);
+ safe_memcpy(sub_captures->data,
+ s->captures->data + cs.cap,
+ sizeof(Janet) * num_sub_captures);
sub_captures->count = num_sub_captures;
cap_load(s, cs);
pushcap(s, janet_wrap_array(sub_captures), tag);
@@ -1227,8 +1227,8 @@ static Peg *make_peg(Builder *b) {
peg->bytecode = (uint32_t *)(mem + bytecode_start);
peg->constants = (Janet *)(mem + constants_start);
peg->num_constants = janet_v_count(b->constants);
- memcpy(peg->bytecode, b->bytecode, bytecode_size);
- memcpy(peg->constants, b->constants, constants_size);
+ safe_memcpy(peg->bytecode, b->bytecode, bytecode_size);
+ safe_memcpy(peg->constants, b->constants, constants_size);
peg->bytecode_len = janet_v_count(b->bytecode);
return peg;
}
diff --git a/src/core/state.h b/src/core/state.h
index bd3789c4..8674b07a 100644
--- a/src/core/state.h
+++ b/src/core/state.h
@@ -32,6 +32,8 @@
* be in it. However, thread local global variables for interpreter
* state should allow easy multi-threading. */
+typedef struct JanetScratch JanetScratch;
+
/* Cache the core environment */
extern JANET_THREAD_LOCAL JanetTable *janet_vm_core_env;
@@ -69,7 +71,7 @@ extern JANET_THREAD_LOCAL size_t janet_vm_root_count;
extern JANET_THREAD_LOCAL size_t janet_vm_root_capacity;
/* Scratch memory */
-extern JANET_THREAD_LOCAL void **janet_scratch_mem;
+extern JANET_THREAD_LOCAL JanetScratch **janet_scratch_mem;
extern JANET_THREAD_LOCAL size_t janet_scratch_cap;
extern JANET_THREAD_LOCAL size_t janet_scratch_len;
diff --git a/src/core/string.c b/src/core/string.c
index a8b5758d..cb00b941 100644
--- a/src/core/string.c
+++ b/src/core/string.c
@@ -51,7 +51,7 @@ const uint8_t *janet_string(const uint8_t *buf, int32_t len) {
head->length = len;
head->hash = janet_string_calchash(buf, len);
uint8_t *data = (uint8_t *)head->data;
- memcpy(data, buf, len);
+ safe_memcpy(data, buf, len);
data[len] = 0;
return data;
}
@@ -187,7 +187,7 @@ static Janet cfun_string_repeat(int32_t argc, Janet *argv) {
uint8_t *newbuf = janet_string_begin((int32_t) mulres);
uint8_t *end = newbuf + mulres;
for (uint8_t *p = newbuf; p < end; p += view.len) {
- memcpy(p, view.bytes, view.len);
+ safe_memcpy(p, view.bytes, view.len);
}
return janet_wrap_string(janet_string_end(newbuf));
}
@@ -343,11 +343,11 @@ static Janet cfun_string_replace(int32_t argc, Janet *argv) {
return janet_stringv(s.kmp.text, s.kmp.textlen);
}
buf = janet_string_begin(s.kmp.textlen - s.kmp.patlen + s.substlen);
- memcpy(buf, s.kmp.text, result);
- memcpy(buf + result, s.subst, s.substlen);
- memcpy(buf + result + s.substlen,
- s.kmp.text + result + s.kmp.patlen,
- s.kmp.textlen - result - s.kmp.patlen);
+ safe_memcpy(buf, s.kmp.text, result);
+ safe_memcpy(buf + result, s.subst, s.substlen);
+ safe_memcpy(buf + result + s.substlen,
+ s.kmp.text + result + s.kmp.patlen,
+ s.kmp.textlen - result - s.kmp.patlen);
kmp_deinit(&s.kmp);
return janet_wrap_string(janet_string_end(buf));
}
@@ -445,11 +445,11 @@ static Janet cfun_string_join(int32_t argc, Janet *argv) {
const uint8_t *chunk = NULL;
int32_t chunklen = 0;
if (i) {
- memcpy(out, joiner.bytes, joiner.len);
+ safe_memcpy(out, joiner.bytes, joiner.len);
out += joiner.len;
}
janet_bytes_view(parts.items[i], &chunk, &chunklen);
- memcpy(out, chunk, chunklen);
+ safe_memcpy(out, chunk, chunklen);
out += chunklen;
}
return janet_wrap_string(janet_string_end(buf));
diff --git a/src/core/strtod.c b/src/core/strtod.c
index 05dfac9f..78f9c8f0 100644
--- a/src/core/strtod.c
+++ b/src/core/strtod.c
@@ -447,12 +447,16 @@ int janet_scan_int64(const uint8_t *str, int32_t len, int64_t *out) {
int neg;
uint64_t bi;
if (scan_uint64(str, len, &bi, &neg)) {
- if (neg && bi <= 0x8000000000000000ULL) {
- *out = -((int64_t) bi);
+ if (neg && bi <= (UINT64_MAX / 2)) {
+ if (bi > INT64_MAX) {
+ *out = INT64_MIN;
+ } else {
+ *out = -((int64_t) bi);
+ }
return 1;
}
- if (!neg && bi <= 0x7FFFFFFFFFFFFFFFULL) {
- *out = bi;
+ if (!neg && bi <= INT64_MAX) {
+ *out = (int64_t) bi;
return 1;
}
}
diff --git a/src/core/symcache.c b/src/core/symcache.c
index 8e887d47..b8366f06 100644
--- a/src/core/symcache.c
+++ b/src/core/symcache.c
@@ -183,7 +183,7 @@ const uint8_t *janet_symbol(const uint8_t *str, int32_t len) {
head->hash = hash;
head->length = len;
newstr = (uint8_t *)(head->data);
- memcpy(newstr, str, len);
+ safe_memcpy(newstr, str, len);
newstr[len] = 0;
janet_symcache_put((const uint8_t *)newstr, bucket);
return newstr;
diff --git a/src/core/tuple.c b/src/core/tuple.c
index a75c846b..9a3415a2 100644
--- a/src/core/tuple.c
+++ b/src/core/tuple.c
@@ -49,7 +49,7 @@ const Janet *janet_tuple_end(Janet *tuple) {
/* Build a tuple with n values */
const Janet *janet_tuple_n(const Janet *values, int32_t n) {
Janet *t = janet_tuple_begin(n);
- memcpy(t, values, sizeof(Janet) * n);
+ safe_memcpy(t, values, sizeof(Janet) * n);
return janet_tuple_end(t);
}
diff --git a/src/core/util.c b/src/core/util.c
index 63c3ff92..738127a9 100644
--- a/src/core/util.c
+++ b/src/core/util.c
@@ -248,6 +248,12 @@ int32_t janet_tablen(int32_t n) {
return n + 1;
}
+/* Avoid some undefined behavior that was common in the code base. */
+void safe_memcpy(void *dest, const void *src, size_t len) {
+ if (!len) return;
+ memcpy(dest, src, len);
+}
+
/* Helper to find a value in a Janet struct or table. Returns the bucket
* containing the key, or the first empty bucket if there is no such key. */
const JanetKV *janet_dict_find(const JanetKV *buckets, int32_t cap, Janet key) {
@@ -385,7 +391,7 @@ void janet_cfuns(JanetTable *env, const char *regprefix, const JanetReg *cfuns)
if (NULL == longname_buffer) {
JANET_OUT_OF_MEMORY;
}
- memcpy(longname_buffer, regprefix, prefixlen);
+ safe_memcpy(longname_buffer, regprefix, prefixlen);
longname_buffer[prefixlen] = '/';
prefixlen++;
}
@@ -402,7 +408,7 @@ void janet_cfuns(JanetTable *env, const char *regprefix, const JanetReg *cfuns)
JANET_OUT_OF_MEMORY;
}
}
- memcpy(longname_buffer + prefixlen, cfuns->name, nmlen);
+ safe_memcpy(longname_buffer + prefixlen, cfuns->name, nmlen);
name = janet_wrap_symbol(janet_symbol(longname_buffer, totallen));
} else {
name = janet_csymbolv(cfuns->name);
diff --git a/src/core/util.h b/src/core/util.h
index 7c7f6919..5a3f5568 100644
--- a/src/core/util.h
+++ b/src/core/util.h
@@ -68,6 +68,7 @@ int32_t janet_array_calchash(const Janet *array, int32_t len);
int32_t janet_kv_calchash(const JanetKV *kvs, int32_t len);
int32_t janet_string_calchash(const uint8_t *str, int32_t len);
int32_t janet_tablen(int32_t n);
+void safe_memcpy(void *dest, const void *src, size_t len);
void janet_buffer_push_types(JanetBuffer *buffer, int types);
const JanetKV *janet_dict_find(const JanetKV *buckets, int32_t cap, Janet key);
Janet janet_dict_get(const JanetKV *buckets, int32_t cap, Janet key);
diff --git a/src/core/vector.c b/src/core/vector.c
index 794da7e1..96fe77ba 100644
--- a/src/core/vector.c
+++ b/src/core/vector.c
@@ -45,7 +45,7 @@ void *janet_v_flattenmem(void *v, int32_t itemsize) {
size_t size = (size_t) itemsize * janet_v__cnt(v);
p = malloc(size);
if (NULL != p) {
- memcpy(p, v, size);
+ safe_memcpy(p, v, size);
return p;
} else {
JANET_OUT_OF_MEMORY;
diff --git a/src/include/janet.h b/src/include/janet.h
index 5b678d04..cc8d7069 100644
--- a/src/include/janet.h
+++ b/src/include/janet.h
@@ -1360,11 +1360,12 @@ JANET_API Janet janet_mcall(const char *name, int32_t argc, Janet *argv);
JANET_API void janet_stacktrace(JanetFiber *fiber, Janet err);
/* Scratch Memory API */
-typedef void (*ScratchFinalizer)(void *);
+typedef void (*JanetScratchFinalizer)(void *);
+
JANET_API void *janet_smalloc(size_t size);
JANET_API void *janet_srealloc(void *mem, size_t size);
JANET_API void *janet_scalloc(size_t nmemb, size_t size);
-JANET_API void janet_sfinalizer(void *mem, ScratchFinalizer finalizer);
+JANET_API void janet_sfinalizer(void *mem, JanetScratchFinalizer finalizer);
JANET_API void janet_sfree(void *mem);
/* C Library helpers */
diff --git a/src/mainclient/line.h b/src/mainclient/line.h
deleted file mode 100644
index 5ff5929b..00000000
--- a/src/mainclient/line.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-* Copyright (c) 2020 Calvin Rose
-*
-* 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.
-*/
-
-#ifndef JANET_LINE_H_defined
-#define JANET_LINE_H_defined
-
-#if !defined(_POSIX_C_SOURCE)
-#define _POSIX_C_SOURCE 200112L
-#endif
-
-#ifndef JANET_AMALG
-#include <janet.h>
-#endif
-
-void janet_line_init();
-void janet_line_deinit();
-
-void janet_line_get(const char *p, JanetBuffer *buffer);
-Janet janet_line_getter(int32_t argc, Janet *argv);
-
-#endif
diff --git a/src/mainclient/main.c b/src/mainclient/main.c
deleted file mode 100644
index 2dbacbdf..00000000
--- a/src/mainclient/main.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
-* Copyright (c) 2020 Calvin Rose
-*
-* 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.
-*/
-
-#if !defined(_POSIX_C_SOURCE)
-#define _POSIX_C_SOURCE 200112L
-#endif
-
-#ifndef JANET_AMALG
-#include <janet.h>
-#include "line.h"
-#endif
-
-#ifdef _WIN32
-#include <windows.h>
-#include <shlwapi.h>
-#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
-#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
-#endif
-#endif
-
-int main(int argc, char **argv) {
- int i, status;
- JanetArray *args;
- JanetTable *env;
-
-#ifdef _WIN32
- /* Enable color console on windows 10 console and utf8 output. */
- HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
- DWORD dwMode = 0;
- GetConsoleMode(hOut, &dwMode);
- dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
- SetConsoleMode(hOut, dwMode);
- SetConsoleOutputCP(65001);
-#endif
-
- /* Set up VM */
- janet_init();
-
- /* Replace original getline with new line getter */
- JanetTable *replacements = janet_table(0);
- janet_table_put(replacements, janet_csymbolv("getline"), janet_wrap_cfunction(janet_line_getter));
- janet_line_init();
-
- /* Get core env */
- env = janet_core_env(replacements);
-
- /* Create args tuple */
- args = janet_array(argc);
- for (i = 1; i < argc; i++)
- janet_array_push(args, janet_cstringv(argv[i]));
-
- /* Save current executable path to (dyn :executable) */
- janet_table_put(env, janet_ckeywordv("executable"), janet_cstringv(argv[0]));
-
- /* Run startup script */
- Janet mainfun, out;
- janet_resolve(env, janet_csymbol("cli-main"), &mainfun);
- Janet mainargs[1] = { janet_wrap_array(args) };
- JanetFiber *fiber = janet_fiber(janet_unwrap_function(mainfun), 64, 1, mainargs);
- fiber->env = env;
- status = janet_continue(fiber, janet_wrap_nil(), &out);
- if (status != JANET_SIGNAL_OK) {
- janet_stacktrace(fiber, out);
- }
-
- /* Deinitialize vm */
- janet_deinit();
- janet_line_deinit();
-
- return status;
-}
diff --git a/src/mainclient/line.c b/src/mainclient/shell.c
index 6e0a2f0b..1ef3fd5c 100644
--- a/src/mainclient/line.c
+++ b/src/mainclient/shell.c
@@ -24,10 +24,26 @@
#define _POSIX_C_SOURCE 200112L
#endif
-#ifndef JANET_AMALG
-#include "line.h"
+#include <janet.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#include <shlwapi.h>
+#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
+#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
+#endif
#endif
+void janet_line_init();
+void janet_line_deinit();
+
+void janet_line_get(const char *p, JanetBuffer *buffer);
+Janet janet_line_getter(int32_t argc, Janet *argv);
+
+/*
+ * Line Editing
+ */
+
static JANET_THREAD_LOCAL JanetTable *gbl_complete_env;
/* Common */
@@ -80,8 +96,6 @@ void janet_line_get(const char *p, JanetBuffer *buffer) {
https://github.com/antirez/linenoise/blob/master/linenoise.c
*/
-#include <janet.h>
-
#include <termios.h>
#include <unistd.h>
#include <stdlib.h>
@@ -809,3 +823,59 @@ void janet_line_get(const char *p, JanetBuffer *buffer) {
}
#endif
+
+/*
+ * Entry
+ */
+
+int main(int argc, char **argv) {
+ int i, status;
+ JanetArray *args;
+ JanetTable *env;
+
+#ifdef _WIN32
+ /* Enable color console on windows 10 console and utf8 output. */
+ HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
+ DWORD dwMode = 0;
+ GetConsoleMode(hOut, &dwMode);
+ dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
+ SetConsoleMode(hOut, dwMode);
+ SetConsoleOutputCP(65001);
+#endif
+
+ /* Set up VM */
+ janet_init();
+
+ /* Replace original getline with new line getter */
+ JanetTable *replacements = janet_table(0);
+ janet_table_put(replacements, janet_csymbolv("getline"), janet_wrap_cfunction(janet_line_getter));
+ janet_line_init();
+
+ /* Get core env */
+ env = janet_core_env(replacements);
+
+ /* Create args tuple */
+ args = janet_array(argc);
+ for (i = 1; i < argc; i++)
+ janet_array_push(args, janet_cstringv(argv[i]));
+
+ /* Save current executable path to (dyn :executable) */
+ janet_table_put(env, janet_ckeywordv("executable"), janet_cstringv(argv[0]));
+
+ /* Run startup script */
+ Janet mainfun, out;
+ janet_resolve(env, janet_csymbol("cli-main"), &mainfun);
+ Janet mainargs[1] = { janet_wrap_array(args) };
+ JanetFiber *fiber = janet_fiber(janet_unwrap_function(mainfun), 64, 1, mainargs);
+ fiber->env = env;
+ status = janet_continue(fiber, janet_wrap_nil(), &out);
+ if (status != JANET_SIGNAL_OK) {
+ janet_stacktrace(fiber, out);
+ }
+
+ /* Deinitialize vm */
+ janet_deinit();
+ janet_line_deinit();
+
+ return status;
+}
diff --git a/tools/xxd.c b/tools/xxd.c
deleted file mode 100644
index a45f4f03..00000000
--- a/tools/xxd.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
-* Copyright (c) 2020 Calvin Rose
-*
-* 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.
-*/
-
-/* Simple clone of the xxd tool used at build time. Used to
- * create headers out of source files. Only used for core libraries
- * like the bootstrapping code and the stl. */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-
-#define BUFSIZE 1024
-#define PERLINE 10
-
-int main(int argc, const char **argv) {
-
- static const char hex[] = "0123456789ABCDEF";
- char buf[BUFSIZE];
- size_t bytesRead = 0;
- int32_t totalRead = 0;
- int lineIndex = 0;
- int line = 0;
-
- if (argc != 4) {
- fprintf(stderr, "Usage: %s infile outfile symbol\n", argv[0]);
- return 1;
- }
-
- /* Open the files */
- FILE *in = fopen(argv[1], "rb");
- FILE *out = fopen(argv[2], "wb");
-
- /* Check if files open successfully */
- if (in == NULL) {
- fprintf(stderr, "Could not open input file %s\n", argv[1]);
- return 1;
- } else if (out == NULL) {
- fprintf(stderr, "Could not open output file %s\n", argv[2]);
- return 1;
- }
-
- /* Write the header */
- fprintf(out, "/* Auto generated - DO NOT EDIT */\n\n#include <stdint.h>\n\n");
- fprintf(out, "static const unsigned char bytes_%s[] = {", argv[3]);
-
- /* Read in chunks from buffer */
- while ((bytesRead = fread(buf, 1, sizeof(buf), in)) > 0) {
- size_t i;
- totalRead += bytesRead;
- for (i = 0; i < bytesRead; ++i) {
- int byte = ((uint8_t *)buf) [i];
-
- /* Write the byte */
- if (lineIndex++ == 0) {
- if (line++)
- fputc(',', out);
- fputs("\n ", out);
- } else {
- fputs(", ", out);
- }
- fputs("0x", out);
- fputc(hex[byte >> 4], out);
- fputc(hex[byte & 0xF], out);
-
- /* Make line index wrap */
- if (lineIndex >= PERLINE)
- lineIndex = 0;
-
- }
- }
-
- /* Write the tail */
- fputs("\n};\n\n", out);
-
- fprintf(out, "const unsigned char *%s = bytes_%s;\n\n", argv[3], argv[3]);
-
- /* Write chunk size */
- fprintf(out, "int32_t %s_size = %d;\n", argv[3], totalRead);
-
- /* Close the file handles */
- fclose(in);
- fclose(out);
-
- return 0;
-}