diff --git a/CHANGELOG.md b/CHANGELOG.md index 9695b4b4..7bb0b8a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ # Changelog All notable changes to this project will be documented in this file. +## Unreleased +- Change default fiber stack limit to the maximum value of a 32 bit signed integer. +- Some bug fixes with `jpm` +- Add `os/arch` to get ISA that janet was compiled for +- Add color to stacktraces via `(dyn :err-color)` + ## 1.2.0 - 2019-08-08 - Add `take` and `drop` functions that are easier to use compared to the existing slice functions. diff --git a/appveyor.yml b/appveyor.yml index ef1f09b9..382d9cf3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -15,9 +15,10 @@ matrix: # skip unsupported combinations init: -- call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars32.bat" + - call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars32.bat" install: + - set JANET_BUILD=%appveyor_repo_commit:~0,7% - choco install nsis -y -pre # Replace makensis.exe and files with special long string build. This should # prevent issues when setting PATH during installation. @@ -27,6 +28,8 @@ install: # We need to reload vcvars after refreshing - call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars32.bat" - build_win test-install + - set janet_outname=%appveyor_repo_tag_name% + - if "%janet_outname%"=="" set janet_outname=v1.2.0 build: off only_commits: @@ -35,8 +38,20 @@ only_commits: - src/ artifacts: - - path: janet-v1.2.0-windows-installer.exe - name: janet-v1.2.0-windows-installer.exe + - name: janet.c + path: dist\janet.c + type: File + - name: janet.h + path: dist\janet.h + type: File + - name: janetconf.h + path: dist\janetconf.h + type: File + - name: "janet-$(janet_outname)-windows" + path: dist + type: Zip + - path: "janet-$(janet_outname)-windows-installer.exe" + name: "janet-$(janet_outname)-windows-installer.exe" type: File deploy: @@ -44,7 +59,7 @@ deploy: provider: GitHub auth_token: secure: lwEXy09qhj2jSH9s1C/KvCkAUqJSma8phFR+0kbsfUc3rVxpNK5uD3z9Md0SjYRx - artifact: janet-windows + artifact: /janet.*/ draft: true on: APPVEYOR_REPO_TAG: true diff --git a/build_win.bat b/build_win.bat index 054c8a7c..6bda6464 100644 --- a/build_win.bat +++ b/build_win.bat @@ -23,36 +23,41 @@ @set JANET_LINK=link /nologo @set JANET_LINK_STATIC=lib /nologo +@rem Add janet build tag +if not "%JANET_BUILD%" == "" ( + @set JANET_COMPILE=%JANET_COMPILE% /DJANET_BUILD="\"%JANET_BUILD%\"" +) + mkdir build 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 +cl /nologo /c tools/xxd.c /Fobuild\xxd.obj @if errorlevel 1 goto :BUILDFAIL -@link /nologo /out:build\xxd.exe build\xxd.obj +link /nologo /out:build\xxd.exe build\xxd.obj @if errorlevel 1 goto :BUILDFAIL @rem Generate the embedded sources -@build\xxd.exe src\mainclient\init.janet build\init.gen.c janet_gen_init +build\xxd.exe src\mainclient\init.janet build\init.gen.c janet_gen_init @if errorlevel 1 goto :BUILDFAIL -@build\xxd.exe src\boot\boot.janet build\boot.gen.c janet_gen_boot +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\mainclient\init.gen.obj build\init.gen.c +%JANET_COMPILE% /Fobuild\mainclient\init.gen.obj build\init.gen.c @if errorlevel 1 goto :BUILDFAIL -@%JANET_COMPILE% /Fobuild\boot\boot.gen.obj build\boot.gen.c +%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 + %JANET_COMPILE% /DJANET_BOOTSTRAP /Fobuild\boot\%%~nf.obj %%f @if errorlevel 1 goto :BUILDFAIL ) for %%f in (src\boot\*.c) do ( - @%JANET_COMPILE% /DJANET_BOOTSTRAP /Fobuild\boot\%%~nf.obj %%f + %JANET_COMPILE% /DJANET_BOOTSTRAP /Fobuild\boot\%%~nf.obj %%f @if errorlevel 1 goto :BUILDFAIL ) %JANET_LINK% /out:build\janet_boot.exe build\boot\*.obj @@ -60,12 +65,12 @@ for %%f in (src\boot\*.c) do ( build\janet_boot build\core_image.c @rem Build the core image -@%JANET_COMPILE% /Fobuild\core_image.obj build\core_image.c +%JANET_COMPILE% /Fobuild\core_image.obj build\core_image.c @if errorlevel 1 goto :BUILDFAIL @rem Build the sources for %%f in (src\core\*.c) do ( - @%JANET_COMPILE% /Fobuild\core\%%~nf.obj %%f + %JANET_COMPILE% /Fobuild\core\%%~nf.obj %%f @if errorlevel 1 goto :BUILDFAIL ) @@ -74,7 +79,7 @@ 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 + %JANET_COMPILE% /Fobuild\mainclient\%%~nf.obj %%f @if errorlevel 1 goto :BUILDFAIL ) diff --git a/janet-installer.nsi b/janet-installer.nsi index b9f9f0f8..417222a6 100644 --- a/janet-installer.nsi +++ b/janet-installer.nsi @@ -25,7 +25,19 @@ VIFileVersion "${PRODUCT_VERSION}" # Basics Name "Janet" -OutFile "janet-v${VERSION}-windows-installer.exe" + +# Do some NSIS-fu to figure out at compile time if we are in appveyor +!define OUTNAME $%APPVEYOR_REPO_TAG_NAME% +!define "CHECK_${OUTNAME}" +!define DOLLAR "$" +!ifdef CHECK_${DOLLAR}%APPVEYOR_REPO_TAG_NAME% + # We are not in the appveyor environment, use version name + !define OUTNAME_PART v${VERSION} +!else + # We are in appveyor, use git tag name for installer + !define OUTNAME_PART ${OUTNAME} +!endif +OutFile "janet-${OUTNAME_PART}-windows-installer.exe" # Some Configuration !define APPNAME "Janet" diff --git a/meson_options.txt b/meson_options.txt index afa8f0b9..b63c8ec1 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -14,7 +14,7 @@ option('int_types', type : 'boolean', value : true) option('recursion_guard', type : 'integer', min : 10, max : 8000, value : 1024) option('max_proto_depth', type : 'integer', min : 10, max : 8000, value : 200) option('max_macro_expand', type : 'integer', min : 1, max : 8000, value : 200) -option('stack_max', type : 'integer', min : 8096, max : 1000000000, value : 16384) +option('stack_max', type : 'integer', min : 8096, max : 0x7fffffff, value : 0x7fffffff) option('arch_name', type : 'string', value: '') option('os_name', type : 'string', value: '') diff --git a/src/core/array.c b/src/core/array.c index 62fa7844..39acff80 100644 --- a/src/core/array.c +++ b/src/core/array.c @@ -64,7 +64,9 @@ void janet_array_ensure(JanetArray *array, int32_t capacity, int32_t growth) { Janet *newData; Janet *old = array->data; if (capacity <= array->capacity) return; - capacity *= growth; + int64_t new_capacity = capacity * growth; + if (new_capacity > INT32_MAX) new_capacity = INT32_MAX; + capacity = (int32_t) new_capacity; newData = realloc(old, capacity * sizeof(Janet)); if (NULL == newData) { JANET_OUT_OF_MEMORY; diff --git a/src/core/fiber.c b/src/core/fiber.c index d4fa5e82..cb1eea93 100644 --- a/src/core/fiber.c +++ b/src/core/fiber.c @@ -87,19 +87,27 @@ void janet_fiber_setcapacity(JanetFiber *fiber, int32_t n) { fiber->capacity = n; } +/* Grow fiber if needed */ +static void janet_fiber_grow(JanetFiber *fiber, int32_t needed) { + int32_t cap = needed > (INT32_MAX / 2) ? INT32_MAX : 2 * needed; + janet_fiber_setcapacity(fiber, cap); +} + /* Push a value on the next stack frame */ void janet_fiber_push(JanetFiber *fiber, Janet x) { + if (fiber->stacktop == INT32_MAX) janet_panic("stack overflow"); if (fiber->stacktop >= fiber->capacity) { - janet_fiber_setcapacity(fiber, 2 * fiber->stacktop); + janet_fiber_grow(fiber, fiber->stacktop); } fiber->data[fiber->stacktop++] = x; } /* Push 2 values on the next stack frame */ void janet_fiber_push2(JanetFiber *fiber, Janet x, Janet y) { + if (fiber->stacktop >= INT32_MAX - 1) janet_panic("stack overflow"); int32_t newtop = fiber->stacktop + 2; if (newtop > fiber->capacity) { - janet_fiber_setcapacity(fiber, 2 * newtop); + janet_fiber_grow(fiber, newtop); } fiber->data[fiber->stacktop] = x; fiber->data[fiber->stacktop + 1] = y; @@ -108,9 +116,10 @@ void janet_fiber_push2(JanetFiber *fiber, Janet x, Janet y) { /* Push 3 values on the next stack frame */ void janet_fiber_push3(JanetFiber *fiber, Janet x, Janet y, Janet z) { + if (fiber->stacktop >= INT32_MAX - 2) janet_panic("stack overflow"); int32_t newtop = fiber->stacktop + 3; if (newtop > fiber->capacity) { - janet_fiber_setcapacity(fiber, 2 * newtop); + janet_fiber_grow(fiber, newtop); } fiber->data[fiber->stacktop] = x; fiber->data[fiber->stacktop + 1] = y; @@ -120,9 +129,10 @@ void janet_fiber_push3(JanetFiber *fiber, Janet x, Janet y, Janet z) { /* Push an array on the next stack frame */ void janet_fiber_pushn(JanetFiber *fiber, const Janet *arr, int32_t n) { + if (fiber->stacktop > INT32_MAX - n) janet_panic("stack overflow"); int32_t newtop = fiber->stacktop + n; if (newtop > fiber->capacity) { - janet_fiber_setcapacity(fiber, 2 * newtop); + janet_fiber_grow(fiber, newtop); } memcpy(fiber->data + fiber->stacktop, arr, n * sizeof(Janet)); fiber->stacktop = newtop; diff --git a/src/core/vm.c b/src/core/vm.c index 21bec2e8..7a2016a8 100644 --- a/src/core/vm.c +++ b/src/core/vm.c @@ -628,6 +628,9 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in, JanetFiberStatus status) VM_OP(JOP_TAILCALL) { Janet callee = stack[D]; + if (fiber->stacktop > fiber->maxstack) { + vm_throw("stack overflow"); + } if (janet_checktype(callee, JANET_KEYWORD)) { vm_commit(); callee = resolve_method(callee, fiber); diff --git a/src/include/janet.h b/src/include/janet.h index b8c651db..1d597ae9 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -171,11 +171,10 @@ extern "C" { /* Maximum depth to follow table prototypes before giving up and returning nil. */ #define JANET_MAX_MACRO_EXPAND 200 -/* Define max stack size for stacks before raising a stack overflow error. - * If this is not defined, fiber stacks can grow without limit (until memory - * runs out) */ +/* Define default max stack size for stacks before raising a stack overflow error. + * This can also be set on a per fiber basis. */ #ifndef JANET_STACK_MAX -#define JANET_STACK_MAX 16384 +#define JANET_STACK_MAX 0x7fffffff #endif /* Use nanboxed values - uses 8 bytes per value instead of 12 or 16.