From e0a02191a2d42b92fca740ccebb47d0f57000e74 Mon Sep 17 00:00:00 2001 From: John Viega Date: Wed, 17 Jul 2024 08:39:53 -0400 Subject: [PATCH] Housekeeping: code reorg and build process redo (#87) - Reorganized the con4m src and include directories to make them more sane (haven't gone IWYU though, just more sane on the file system) - Retool the build process; the dev command now lets you switch profiles with 'dev profile' and passes any additional config options to meson. There are now MORE config options, including 'show_preprocessor_config' which dumps emits compiler warnings with the values of preproc config info. - Fix the issue w/ CON4M_ROOT being necessary to run tests. - Remove unnecessary alignment specs - Remove depreciation warning. --- .github/workflows/test.yml | 5 +- dev | 353 ++++++++---- doc/reference.md | 2 +- include/{con4m => adts}/box.h | 0 include/{con4m => adts}/buffer.h | 3 - include/{con4m => adts}/codepoint.h | 0 include/{con4m => adts}/dict.h | 0 .../{con4m/datatypes/box.h => adts/dt_box.h} | 0 .../datatypes/buffers.h => adts/dt_buffers.h} | 0 .../callbacks.h => adts/dt_callbacks.h} | 0 .../codepoints.h => adts/dt_codepoints.h} | 0 .../datatypes/flags.h => adts/dt_flags.h} | 0 .../datatypes/grids.h => adts/dt_grids.h} | 0 .../datatypes/lists.h => adts/dt_lists.h} | 0 .../datatypes/mixed.h => adts/dt_mixed.h} | 0 .../datatypes/streams.h => adts/dt_streams.h} | 0 .../datatypes/strings.h => adts/dt_strings.h} | 0 .../datatypes/trees.h => adts/dt_trees.h} | 0 .../datatypes/tuples.h => adts/dt_tuples.h} | 0 include/{con4m => adts}/flags.h | 0 include/{con4m => adts}/grid.h | 0 include/{con4m => adts}/list.h | 0 include/{con4m => adts}/mixed.h | 0 include/{con4m => adts}/set.h | 0 include/{con4m => adts}/stream.h | 0 include/{con4m => adts}/string.h | 0 include/{con4m => adts}/tree.h | 0 include/{con4m => adts}/tuple.h | 0 .../compiler/{datatypes/cfg.h => dt_cfgs.h} | 0 .../{datatypes/compile.h => dt_compile.h} | 0 .../{datatypes/error.h => dt_errors.h} | 0 .../compiler/{datatypes/file.h => dt_files.h} | 0 .../compiler/{datatypes/lex.h => dt_lex.h} | 0 .../{datatypes/nodeinfo.h => dt_nodeinfo.h} | 0 .../{datatypes/parse.h => dt_parse.h} | 0 .../{datatypes/scope.h => dt_scopes.h} | 0 .../compiler/{datatypes/spec.h => dt_specs.h} | 0 include/con4m.h | 175 ++---- include/con4m/config.h | 220 ++++++++ include/con4m/datatypes.h | 72 +-- .../datatypes/memory.h => core/dt_alloc.h} | 22 +- .../exceptions.h => core/dt_exceptions.h} | 0 .../{con4m/datatypes/ffi.h => core/dt_ffi.h} | 0 .../datatypes/kargs.h => core/dt_kargs.h} | 0 .../literals.h => core/dt_literals.h} | 0 .../datatypes/objects.h => core/dt_objects.h} | 0 .../datatypes/types.h => core/dt_types.h} | 0 .../{con4m/datatypes/ufi.h => core/dt_ufi.h} | 0 .../{con4m/datatypes/vm.h => core/dt_vm.h} | 16 +- include/{con4m => core}/exception.h | 2 +- include/{con4m => core}/ffi.h | 0 include/{con4m => core}/gc.h | 84 +-- include/{con4m => core}/init.h | 0 include/{con4m => core}/kargs.h | 0 include/{con4m => core}/literal.h | 0 include/{con4m => core}/marshal.h | 0 include/{con4m => core}/object.h | 0 include/{con4m => core}/refcount.h | 7 +- include/{con4m => core}/type.h | 7 +- include/{con4m => core}/typestore.h | 0 include/{con4m => core}/vm.h | 0 .../datatypes/crypto.h => crypto/dt_crypto.h} | 0 include/hatrack/crown.h | 2 +- include/hatrack/dict.h | 2 +- include/{con4m => io}/ansi.h | 0 include/{con4m/datatypes/io.h => io/dt_io.h} | 0 include/{con4m => io}/subproc.h | 0 include/{con4m => io}/switchboard.h | 0 include/{con4m => io}/term.h | 0 include/{con4m => util}/breaks.h | 0 include/{con4m => util}/cbacktrace.h | 2 +- include/{con4m => util}/color.h | 0 include/{con4m => util}/conststr.h | 0 .../datatypes/colors.h => util/dt_colors.h} | 0 .../datatypes/format.h => util/dt_format.h} | 0 .../datatypes/styles.h => util/dt_styles.h} | 0 .../dt_tree_patterns.h} | 0 include/{con4m => util}/format.h | 0 include/{con4m => util}/fp.h | 0 include/{con4m => util}/hex.h | 0 include/{con4m => util}/macros.h | 0 include/{con4m => util}/math.h | 0 include/{con4m => util}/path.h | 0 include/{con4m => util}/random.h | 0 include/{con4m => util}/style.h | 0 include/{con4m => util}/styledb.h | 0 include/{con4m => util}/tree_pattern.h | 0 include/{con4m => util}/watch.h | 8 - include/{con4m => util}/wrappers.h | 0 meson.build | 512 +++++++++++------- meson.options | 121 ++++- src/README.md | 21 + src/adts/README.md | 46 ++ src/{con4m => adts}/box.c | 0 src/{con4m => adts}/buffer.c | 0 src/{con4m => adts}/callback.c | 0 src/{con4m => adts}/dict.c | 0 src/{con4m => adts}/flags.c | 0 src/{con4m => adts}/grid.c | 0 src/{con4m => adts}/hatlists.c | 0 src/{con4m => adts}/ipaddr.c | 0 src/{con4m => adts}/list.c | 0 src/{con4m => adts}/mixed.c | 0 src/{con4m => adts}/numbers.c | 0 src/{con4m => adts}/set.c | 0 src/{con4m => adts}/streams.c | 0 src/{con4m => adts}/string.c | 0 src/{con4m => adts}/tree.c | 0 src/{con4m => adts}/tuple.c | 0 src/{con4m => }/compiler/ast_utils.c | 0 src/{con4m => }/compiler/cfg.c | 0 src/{con4m => }/compiler/cfg_build.c | 0 src/{con4m => }/compiler/check_pass.c | 0 src/{con4m => }/compiler/codegen.c | 0 src/{con4m => }/compiler/compile.c | 0 src/{con4m => }/compiler/decl_pass.c | 0 src/{con4m => }/compiler/disasm.c | 2 + src/{con4m => }/compiler/errors.c | 0 src/{con4m => }/compiler/lex.c | 0 src/{con4m => }/compiler/memory_layout.c | 0 src/{con4m => }/compiler/objgen.c | 0 src/{con4m => }/compiler/parse.c | 0 src/{con4m => }/compiler/scope.c | 0 src/{con4m => }/compiler/specs.c | 0 src/{con4m => core}/attrstore.c | 0 src/{con4m => core}/collect.c | 29 +- src/{con4m => core}/exceptions.c | 0 src/{con4m => core}/ffi.c | 0 src/{con4m => core}/gcbase.c | 33 +- src/{con4m => core}/init.c | 0 src/{con4m => core}/kargs.c | 9 - src/{con4m => core}/literals.c | 0 src/{con4m => core}/marshal.c | 0 src/{con4m => core}/object.c | 2 +- src/{con4m => core}/types.c | 0 src/{con4m => core}/typestore.c | 0 src/{con4m => core}/vm.c | 12 +- src/{con4m => core}/vmmarshal.c | 0 src/crypto/README.md | 4 + src/{con4m => }/crypto/sha.c | 0 src/{con4m => io}/ansi.c | 0 src/{con4m => io}/subproc.c | 0 src/{con4m => io}/switchboard.c | 0 src/{con4m => io}/term.c | 0 src/{con4m => util}/breaks.c | 0 src/{con4m => util}/colors.c | 0 src/{con4m => util}/conststr.c | 0 src/{con4m => util}/ctrace.c | 2 +- src/{con4m => util}/format.c | 0 src/{con4m => util}/fptostr.c | 0 src/{con4m => util}/hex.c | 0 src/{con4m => util}/path.c | 2 +- src/{con4m => util}/richlit.c | 0 src/{con4m => util}/static/colors.c | 0 src/{con4m => util}/static/richlit.c | 0 src/util/static_config.c | 140 +++++ src/{con4m => util}/style.c | 0 src/{con4m => util}/styledb.c | 3 + src/{con4m => util}/tree_pattern.c | 0 src/{con4m => util}/watch.c | 0 src/{con4m => util}/wrappers.c | 0 161 files changed, 1252 insertions(+), 668 deletions(-) rename include/{con4m => adts}/box.h (100%) rename include/{con4m => adts}/buffer.h (85%) rename include/{con4m => adts}/codepoint.h (100%) rename include/{con4m => adts}/dict.h (100%) rename include/{con4m/datatypes/box.h => adts/dt_box.h} (100%) rename include/{con4m/datatypes/buffers.h => adts/dt_buffers.h} (100%) rename include/{con4m/datatypes/callbacks.h => adts/dt_callbacks.h} (100%) rename include/{con4m/datatypes/codepoints.h => adts/dt_codepoints.h} (100%) rename include/{con4m/datatypes/flags.h => adts/dt_flags.h} (100%) rename include/{con4m/datatypes/grids.h => adts/dt_grids.h} (100%) rename include/{con4m/datatypes/lists.h => adts/dt_lists.h} (100%) rename include/{con4m/datatypes/mixed.h => adts/dt_mixed.h} (100%) rename include/{con4m/datatypes/streams.h => adts/dt_streams.h} (100%) rename include/{con4m/datatypes/strings.h => adts/dt_strings.h} (100%) rename include/{con4m/datatypes/trees.h => adts/dt_trees.h} (100%) rename include/{con4m/datatypes/tuples.h => adts/dt_tuples.h} (100%) rename include/{con4m => adts}/flags.h (100%) rename include/{con4m => adts}/grid.h (100%) rename include/{con4m => adts}/list.h (100%) rename include/{con4m => adts}/mixed.h (100%) rename include/{con4m => adts}/set.h (100%) rename include/{con4m => adts}/stream.h (100%) rename include/{con4m => adts}/string.h (100%) rename include/{con4m => adts}/tree.h (100%) rename include/{con4m => adts}/tuple.h (100%) rename include/compiler/{datatypes/cfg.h => dt_cfgs.h} (100%) rename include/compiler/{datatypes/compile.h => dt_compile.h} (100%) rename include/compiler/{datatypes/error.h => dt_errors.h} (100%) rename include/compiler/{datatypes/file.h => dt_files.h} (100%) rename include/compiler/{datatypes/lex.h => dt_lex.h} (100%) rename include/compiler/{datatypes/nodeinfo.h => dt_nodeinfo.h} (100%) rename include/compiler/{datatypes/parse.h => dt_parse.h} (100%) rename include/compiler/{datatypes/scope.h => dt_scopes.h} (100%) rename include/compiler/{datatypes/spec.h => dt_specs.h} (100%) create mode 100644 include/con4m/config.h rename include/{con4m/datatypes/memory.h => core/dt_alloc.h} (94%) rename include/{con4m/datatypes/exceptions.h => core/dt_exceptions.h} (100%) rename include/{con4m/datatypes/ffi.h => core/dt_ffi.h} (100%) rename include/{con4m/datatypes/kargs.h => core/dt_kargs.h} (100%) rename include/{con4m/datatypes/literals.h => core/dt_literals.h} (100%) rename include/{con4m/datatypes/objects.h => core/dt_objects.h} (100%) rename include/{con4m/datatypes/types.h => core/dt_types.h} (100%) rename include/{con4m/datatypes/ufi.h => core/dt_ufi.h} (100%) rename include/{con4m/datatypes/vm.h => core/dt_vm.h} (98%) rename include/{con4m => core}/exception.h (99%) rename include/{con4m => core}/ffi.h (100%) rename include/{con4m => core}/gc.h (87%) rename include/{con4m => core}/init.h (100%) rename include/{con4m => core}/kargs.h (100%) rename include/{con4m => core}/literal.h (100%) rename include/{con4m => core}/marshal.h (100%) rename include/{con4m => core}/object.h (100%) rename include/{con4m => core}/refcount.h (90%) rename include/{con4m => core}/type.h (99%) rename include/{con4m => core}/typestore.h (100%) rename include/{con4m => core}/vm.h (100%) rename include/{con4m/datatypes/crypto.h => crypto/dt_crypto.h} (100%) rename include/{con4m => io}/ansi.h (100%) rename include/{con4m/datatypes/io.h => io/dt_io.h} (100%) rename include/{con4m => io}/subproc.h (100%) rename include/{con4m => io}/switchboard.h (100%) rename include/{con4m => io}/term.h (100%) rename include/{con4m => util}/breaks.h (100%) rename include/{con4m => util}/cbacktrace.h (89%) rename include/{con4m => util}/color.h (100%) rename include/{con4m => util}/conststr.h (100%) rename include/{con4m/datatypes/colors.h => util/dt_colors.h} (100%) rename include/{con4m/datatypes/format.h => util/dt_format.h} (100%) rename include/{con4m/datatypes/styles.h => util/dt_styles.h} (100%) rename include/{con4m/datatypes/tree_pattern.h => util/dt_tree_patterns.h} (100%) rename include/{con4m => util}/format.h (100%) rename include/{con4m => util}/fp.h (100%) rename include/{con4m => util}/hex.h (100%) rename include/{con4m => util}/macros.h (100%) rename include/{con4m => util}/math.h (100%) rename include/{con4m => util}/path.h (100%) rename include/{con4m => util}/random.h (100%) rename include/{con4m => util}/style.h (100%) rename include/{con4m => util}/styledb.h (100%) rename include/{con4m => util}/tree_pattern.h (100%) rename include/{con4m => util}/watch.h (91%) rename include/{con4m => util}/wrappers.h (100%) create mode 100644 src/README.md create mode 100644 src/adts/README.md rename src/{con4m => adts}/box.c (100%) rename src/{con4m => adts}/buffer.c (100%) rename src/{con4m => adts}/callback.c (100%) rename src/{con4m => adts}/dict.c (100%) rename src/{con4m => adts}/flags.c (100%) rename src/{con4m => adts}/grid.c (100%) rename src/{con4m => adts}/hatlists.c (100%) rename src/{con4m => adts}/ipaddr.c (100%) rename src/{con4m => adts}/list.c (100%) rename src/{con4m => adts}/mixed.c (100%) rename src/{con4m => adts}/numbers.c (100%) rename src/{con4m => adts}/set.c (100%) rename src/{con4m => adts}/streams.c (100%) rename src/{con4m => adts}/string.c (100%) rename src/{con4m => adts}/tree.c (100%) rename src/{con4m => adts}/tuple.c (100%) rename src/{con4m => }/compiler/ast_utils.c (100%) rename src/{con4m => }/compiler/cfg.c (100%) rename src/{con4m => }/compiler/cfg_build.c (100%) rename src/{con4m => }/compiler/check_pass.c (100%) rename src/{con4m => }/compiler/codegen.c (100%) rename src/{con4m => }/compiler/compile.c (100%) rename src/{con4m => }/compiler/decl_pass.c (100%) rename src/{con4m => }/compiler/disasm.c (99%) rename src/{con4m => }/compiler/errors.c (100%) rename src/{con4m => }/compiler/lex.c (100%) rename src/{con4m => }/compiler/memory_layout.c (100%) rename src/{con4m => }/compiler/objgen.c (100%) rename src/{con4m => }/compiler/parse.c (100%) rename src/{con4m => }/compiler/scope.c (100%) rename src/{con4m => }/compiler/specs.c (100%) rename src/{con4m => core}/attrstore.c (100%) rename src/{con4m => core}/collect.c (98%) rename src/{con4m => core}/exceptions.c (100%) rename src/{con4m => core}/ffi.c (100%) rename src/{con4m => core}/gcbase.c (97%) rename src/{con4m => core}/init.c (100%) rename src/{con4m => core}/kargs.c (94%) rename src/{con4m => core}/literals.c (100%) rename src/{con4m => core}/marshal.c (100%) rename src/{con4m => core}/object.c (99%) rename src/{con4m => core}/types.c (100%) rename src/{con4m => core}/typestore.c (100%) rename src/{con4m => core}/vm.c (99%) rename src/{con4m => core}/vmmarshal.c (100%) create mode 100644 src/crypto/README.md rename src/{con4m => }/crypto/sha.c (100%) rename src/{con4m => io}/ansi.c (100%) rename src/{con4m => io}/subproc.c (100%) rename src/{con4m => io}/switchboard.c (100%) rename src/{con4m => io}/term.c (100%) rename src/{con4m => util}/breaks.c (100%) rename src/{con4m => util}/colors.c (100%) rename src/{con4m => util}/conststr.c (100%) rename src/{con4m => util}/ctrace.c (99%) rename src/{con4m => util}/format.c (100%) rename src/{con4m => util}/fptostr.c (100%) rename src/{con4m => util}/hex.c (100%) rename src/{con4m => util}/path.c (99%) rename src/{con4m => util}/richlit.c (100%) rename src/{con4m => util}/static/colors.c (100%) rename src/{con4m => util}/static/richlit.c (100%) create mode 100644 src/util/static_config.c rename src/{con4m => util}/style.c (100%) rename src/{con4m => util}/styledb.c (99%) rename src/{con4m => util}/tree_pattern.c (100%) rename src/{con4m => util}/watch.c (100%) rename src/{con4m => util}/wrappers.c (100%) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e8ba300c..5e819992 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -77,8 +77,11 @@ jobs: if: runner.os == 'macOS' run: brew install meson ninja + - name: Setup + run: ./dev profile test + - name: Build - run: ./dev testbuild + run: ./dev compile - name: Run run: ./dev run diff --git a/dev b/dev index 089bd354..674447fb 100755 --- a/dev +++ b/dev @@ -1,6 +1,13 @@ #!/bin/bash -export LIBRARY_PATH=${HOME}/.local/c0/libs/ +C4M_DEV_CFG="--buildtype=debug -Duse_memcheck=on -Ddev_mode=true" +C4M_RELEASE_CFG="--buildtype=release" +C4M_DEBUG_EXTRA="-Duse_ubsan=enabled -Duse_asan=enabled -Dshow_preprocessor_config=enabled" +C4M_TEST_CFG=${C4M_DEV_CFG} + + +C4M_MESON_STATE_FILE=.meson_last +C4M_TEST_EXE=c4test function color { case $1 in @@ -32,32 +39,33 @@ function log { echo $(color blue "[-- libcon4m --]" $@) } -function meson_init_target { - echo ${1} > .meson_last - rm deps/local 2>/dev/null - ln -s ${PWD}/deps/${OS}-${ARCH} ${PWD}/deps/local +function ensure_env_setup { + export LIBRARY_PATH=${PWD}/deps/${OS}-${ARCH}/:${HOME}/.local/c0/libs/:${HOME}/: + log "OS="$(color green ${OS}) + log "ARCH="$(color green ${ARCH}) + log "LIBRARY_PATH="$(color green ${LIBRARY_PATH}) +} +function cur_exe_loc { + echo ${C4M_BUILD_DIR}/${C4M_TEST_EXE} +} + +function meson_hatrack { if [[ ! -d ${1} ]]; then if [[ -f ${1} ]]; then rm -rf ${1} fi log Creating meson target ${1} - log meson setup ${@} - meson setup ${@} + meson setup -Dbuild_hatrack=enable ${1} fi -} - -function meson_build { - meson_init_target ${@} cd ${1} log Compiling meson target ${1} if [[ ${OS} = "Darwin" ]] ; then - meson compile - dsymutil c4test + meson compile hash else - CC=musl-gcc meson compile + CC=musl-gcc meson compile hash fi CODE=$? @@ -77,140 +85,267 @@ function meson_build { fi } -function meson_hatrack { - if [[ ! -d ${1} ]]; then - if [[ -f ${1} ]]; then - rm -rf ${1} +function libcon4m_dev_usage { + echo $(color YELLOW "Usage: ./dev [ profile | build | run | debug | rebuild | clean | hash ]") + echo $(color CYAN " profile [arg]") " Sets the current profile, or shows without arguments." + echo " Valid profiles are: " $(color blue "dev debug release test") + echo $(color CYAN " build [meson_options]") " Builds the current profile, passing any additional options to" $(color blue "meson setup") "if provided." + echo $(color CYAN " run") " Ensures the current profile is built, and if so, runs the test suite. " + echo " If not, attempts to compile it first." + echo $(color CYAN " debug") " Runs the current profile's test binary in the debugger." + echo $(color CYAN " rebuild [meson_options]") "Same as " $(color blue "build") "except it forces a rebuild." + echo $(color CYAN " clean [all | profile]") " Completely wipes the specified profile(s), or the current profile if no argument." + echo $(color CYAN " hash") " Does a build of libhatrack only." + + exit 1 +} + +function ensure_directory { + + if [[ ! -d ${C4M_BUILD_DIR} ]]; then + mkdir ${C4M_BUILD_DIR} + fi +} + +function ensure_project { + # Return 1 if the project was just setup, 0 if not. + meson introspect ${C4M_BUILD_DIR} > /dev/null + + if [[ $? -ne 0 ]] ; then + shift + log Setting up target: $(color green ${C4M_BUILD_TARGET}) + meson setup ${C4M_BUILD_DIR} ${C4M_MESON_CONF} ${C4M_PASTHROUGH_ARGS} + if [[ $? -ne 0 ]] ; then + log Setup for target ${C4M_BUILD_TARGET} $(color FAILED.) + exit -1 fi - log Creating meson target ${1} - meson setup ${1} + log Setup for target ${C4M_BUILD_TARGET}: $(color GREEN SUCCESS) fi - cd ${1} +} - log Compiling meson target ${1} +function configure_target { + meson configure ${C4M_BUILD_DIR} ${C4M_PASSTHROUGH_ARGS} +} - if [[ ${OS} = "Darwin" ]] ; then - meson compile hash +function build_target { + meson compile ${C4M_BUILD_DIR} +} + +function rebuild_target { + meson compile --clean +} + +function set_profile { + if [[ $# -eq 0 ]] ; then + if [[ -f ${C4M_MESON_STATE_FILE} ]]; then + WRITE_TARGET_FILE=0 + export C4M_BUILD_TARGET=$(cat ${C4M_MESON_STATE_FILE}) + else + WRITE_TARGET_FILE=1 + export C4M_BUILD_TARGET=dev + fi else - CC=musl-gcc meson compile hash + WRITE_TARGET_FILE=1 + export C4M_BUILD_TARGET=${1} + shift + export C4M_PASSTHROUGH_ARGS=${@} fi - CODE=$? - if [[ $CODE -eq 0 ]] ; then - log "Done!" + + case ${C4M_BUILD_TARGET} in + dev) + export C4M_MESON_CONF="${C4M_DEV_CFG}" + ;; + debug) + export C4M_MESON_CONF="${C4M_DEV_CFG} ${C4M_DEBUG_EXTRA}" + ;; + release) + export C4M_MESON_CONF="${C4M_RELEASE_CFG}" + ;; + test) + export C4M_MESON_CONF="${C4M_TEST_CFG}" + ;; + *) + echo $(color RED "[-- libcon4m --] ") Invalid profile: $(color RED ${C4M_BUILD_TARGET}) + echo $(color blue "Valid targets are: dev, debug, release, test") + return -1 + ;; + esac + + if [[ ${WRITE_TARGET_FILE} -eq 1 ]]; then + log "Setting the current profile to:" $(color green ${C4M_BUILD_TARGET}) + echo ${C4M_BUILD_TARGET} > ${C4M_MESON_STATE_FILE} else - log "Build FAILED" + log "Current profile is: " $(color YELLOW ${C4M_BUILD_TARGET}) fi - cd .. - if [[ ${1} != "debug" ]]; then - exit $CODE + export C4M_BUILD_DIR="build_${C4M_BUILD_TARGET}" + log "Current meson build directory is:" $(color YELLOW ${C4M_BUILD_DIR}) + + return 0 + +} + +function clean_one_target { + TARGET=build_${1} + if [[ -d ${TARGET} ]] ; then + log Cleaning: ${1} + rm -rf ${TARGET} + else + log Nothing to clean for ${1} fi +} - if [[ $CODE -ne 0 ]]; then - exit $CODE +function libcon4m_clean { + if [[ "$1" == "all" ]] ; then + for TARGET in dev debug release test ; do + clean_one_target ${TARGET} + done + if [[ -f ${C4M_MESON_STATE_FILE} ]]; then + rm ${C4M_MESON_STATE_FILE} + fi + else + if [[ $# -ne 0 ]]; then + for arg in $@ ; do + set_profile ${arg} + if [[ $? -eq 0 ]] ; then + clean_one_target ${C4M_BUILD_TARGET} + fi + done + else + set_profile + clean_one_target ${C4M_BUILD_TARGET} + fi fi } -function libcon4m_dev_usage { - echo "Usage: ./dev [build | run | release | debug | testbuild | clean]" - exit 1 +function libcon4m_set_profile { + if [[ $# -gt 1 ]]; then + libcon4m_dev_usage + fi + + set_profile $@ + + if [[ $? -ne 0 ]]; then + exit -1 + fi + + log "Current profile is: " $(cat $C4M_MESON_STATE_FILE) + + ensure_directory } -function debug_it { - meson_build debug --buildtype=debug - DEBUGGER=$(which gdb) - DEBUGGER=${DEBUGGER:-$(which lldb)} - log "Running debugger:v${DEBUGGER}" - ${DEBUGGER} debug/c4test +function libcon4m_prebuild { + if [[ $# -ne 0 ]]; then + case ${1} in + dev | debug | release | test) + set_profile $@ + shift + ;; + *) + set_profile + export C4M_PASSTHROUGH_ARGS=$@ + ;; + esac + else + set_profile + fi + + ensure_directory + ensure_project } -function libcon4m_run_tests { - shift +function libcon4m_compile { + log "Compiling target: " $(color green ${C4M_BUILD_TARGET}) + which musl-gcc > /dev/null - TARGET=$(cat .meson_last) + if [[ $? -eq 0 ]]; then + CC=musl-gcc meson compile -C ${C4M_BUILD_DIR} + else + meson compile -C ${C4M_BUILD_DIR} + fi - log Running test binary for target: $(color green '[==' $TARGET '==]') + if [[ $? -ne 0 ]] ; then + log Compilation of target ${C4M_BUILD_TARGET} $(color RED "FAILED.") + exit -1 + fi - $TARGET/c4test $@ + if [[ ${OS} = "Darwin" ]] ; then + dsymutil $(cur_exe_loc) + fi +} + +function libcon4m_run_tests { + log Running test exe for target: $(color yellow '[==' $C4M_BUILD_TARGET '==]') in directory: $(color YELLOW ${C4M_BUILD_DIR}) + + $(cur_exe_loc) ${C4M_PASSTHROUGH_ARGS} EXIT=$? log "Exit status: ${EXIT}" - if [[ ${EXIT} -gt 0 ]] && [[ ${EXIT} -lt 128 ]] && [[ $@ == "" ]] ; then - log "Test runner crashed; rerunning tests individually to isolate." - HERE=`pwd` - cd ../tests - for ITEM in `ls basic[0-9]*`; do - log Running test: $(color green '[==' $ITEM '==]') - ${HERE}/c4test $ITEM - if [[ $? -ne 0 ]] ; then - echo - echo $(color CYAN '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') - echo $(color CYAN '!! Test case ' $ITEM ' failed !!') - echo $(color CYAN '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') - echo - fi - done - exit 127 + exit ${EXIT} +} + +function libcon4m_run { + libcon4m_prebuild $@ + + libcon4m_compile + + set -e + libcon4m_run_tests $@ + CODE=$? + if [[ $CODE -eq 0 ]] ; then + log "CI/CD tests passed." + else + log "CI/CD Tests " $(color RED "FAILED.") + exit $CODE fi } -function libcon4m_dev_clean { - for item in build debug release cicd; do - if [[ -d ${item} ]]; then - log Cleaning ${item} - cd ${item} - meson compile --clean - cd .. - fi - done +function debug_project { + libcon4m_prebuild $@ + CUR_EXE=$(cur_exe_loc) + + libcon4m_compile + + + DEBUGGER=$(which gdb) + DEBUGGER=${DEBUGGER:-$(which lldb)} + DEBUGGER=${DEBUGGER:-1} - if [[ -f .meson_last ]]; then - rm .meson_last + if [[ ${DEBUGGER} -eq 1 ]] ; then + echo $(color RED ERROR: ) "no debugger found in your path." + exit -1 fi + log "Running debugger: ${DEBUGGER} for target:" $(color green '[==' $C4M_BUILD_TARGET '==]') - log "Done!" + ${DEBUGGER} ${CUR_EXE} ${C4M_PASSTHROUGH_ARGS} } +ensure_env_setup -if [[ ${#} -eq 0 ]]; then - meson_build build -fi - -case $1 in - clean) libcon4m_dev_clean +case ${1} in + clean) shift + libcon4m_clean $@ ;; - build) meson_build build --buildtype=plain -Duse_memcheck=true + build | compile) shift + libcon4m_prebuild $@ + libcon4m_compile ;; - debug) meson_init_target debug --buildtype=debug - meson configure debug -Duse_memcheck=true - meson_build debug - debug_it + rebuild) shift + libcon4m_prebuild $@ + libcon4m_compile --clean ;; - testbuild) meson_init_target cicd --buildtype=debug - meson configure cicd -Duse_memcheck=true - meson_build cicd - ;; - sanitizers) meson_init_target sanitizers - meson configure sanitizers -Duse_ubsan=true -Duse_asan=true - meson build sanitizers - ;; - - release) meson_build release --buildtype=release + profile) shift + libcon4m_set_profile $@ ;; - run) - set -e - libcon4m_run_tests $@ - CODE=$? - if [[ $CODE -eq 0 ]] ; then - log "CI/CD tests passed." - else - log "CI/CD Tests FAILED." - exit $CODE - fi - + debug) shift + debug_project $@ + ;; + run) shift + libcon4m_run $@ ;; - hash) meson_hatrack hash + hash) shift + meson_hatrack hash $@ ;; *) libcon4m_dev_usage diff --git a/doc/reference.md b/doc/reference.md index 62259a77..032e1774 100644 --- a/doc/reference.md +++ b/doc/reference.md @@ -347,7 +347,7 @@ bodyItem ::= lockAttr | ifStmt | forStmt | whileStmt | typeOfStmt | body ::= '{' docString? (bodyItem? EOS)* '}' optionalBody ::= body | -enumStmt ::= "enum" enumItem (',' enumItem)* EOS +enumStmt ::= "enum" ID? '{' enumItem (',' enumItem)* '}' enumItem ::= ID (('=' | ':') expression)? lockAttr ::= '~' (assign | memberExpr) ifStmt ::= "if" expression body ("elif" expression body)* ("else" body)? diff --git a/include/con4m/box.h b/include/adts/box.h similarity index 100% rename from include/con4m/box.h rename to include/adts/box.h diff --git a/include/con4m/buffer.h b/include/adts/buffer.h similarity index 85% rename from include/con4m/buffer.h rename to include/adts/buffer.h index 5a764f57..0571cce6 100644 --- a/include/con4m/buffer.h +++ b/include/adts/buffer.h @@ -1,9 +1,6 @@ #pragma once #include "con4m.h" -#ifndef C4M_EMPTY_BUFFER_ALLOC -#define C4M_EMPTY_BUFFER_ALLOC 128 -#endif extern c4m_buf_t *c4m_buffer_add(c4m_buf_t *, c4m_buf_t *); extern c4m_buf_t *c4m_buffer_join(c4m_list_t *, c4m_buf_t *); diff --git a/include/con4m/codepoint.h b/include/adts/codepoint.h similarity index 100% rename from include/con4m/codepoint.h rename to include/adts/codepoint.h diff --git a/include/con4m/dict.h b/include/adts/dict.h similarity index 100% rename from include/con4m/dict.h rename to include/adts/dict.h diff --git a/include/con4m/datatypes/box.h b/include/adts/dt_box.h similarity index 100% rename from include/con4m/datatypes/box.h rename to include/adts/dt_box.h diff --git a/include/con4m/datatypes/buffers.h b/include/adts/dt_buffers.h similarity index 100% rename from include/con4m/datatypes/buffers.h rename to include/adts/dt_buffers.h diff --git a/include/con4m/datatypes/callbacks.h b/include/adts/dt_callbacks.h similarity index 100% rename from include/con4m/datatypes/callbacks.h rename to include/adts/dt_callbacks.h diff --git a/include/con4m/datatypes/codepoints.h b/include/adts/dt_codepoints.h similarity index 100% rename from include/con4m/datatypes/codepoints.h rename to include/adts/dt_codepoints.h diff --git a/include/con4m/datatypes/flags.h b/include/adts/dt_flags.h similarity index 100% rename from include/con4m/datatypes/flags.h rename to include/adts/dt_flags.h diff --git a/include/con4m/datatypes/grids.h b/include/adts/dt_grids.h similarity index 100% rename from include/con4m/datatypes/grids.h rename to include/adts/dt_grids.h diff --git a/include/con4m/datatypes/lists.h b/include/adts/dt_lists.h similarity index 100% rename from include/con4m/datatypes/lists.h rename to include/adts/dt_lists.h diff --git a/include/con4m/datatypes/mixed.h b/include/adts/dt_mixed.h similarity index 100% rename from include/con4m/datatypes/mixed.h rename to include/adts/dt_mixed.h diff --git a/include/con4m/datatypes/streams.h b/include/adts/dt_streams.h similarity index 100% rename from include/con4m/datatypes/streams.h rename to include/adts/dt_streams.h diff --git a/include/con4m/datatypes/strings.h b/include/adts/dt_strings.h similarity index 100% rename from include/con4m/datatypes/strings.h rename to include/adts/dt_strings.h diff --git a/include/con4m/datatypes/trees.h b/include/adts/dt_trees.h similarity index 100% rename from include/con4m/datatypes/trees.h rename to include/adts/dt_trees.h diff --git a/include/con4m/datatypes/tuples.h b/include/adts/dt_tuples.h similarity index 100% rename from include/con4m/datatypes/tuples.h rename to include/adts/dt_tuples.h diff --git a/include/con4m/flags.h b/include/adts/flags.h similarity index 100% rename from include/con4m/flags.h rename to include/adts/flags.h diff --git a/include/con4m/grid.h b/include/adts/grid.h similarity index 100% rename from include/con4m/grid.h rename to include/adts/grid.h diff --git a/include/con4m/list.h b/include/adts/list.h similarity index 100% rename from include/con4m/list.h rename to include/adts/list.h diff --git a/include/con4m/mixed.h b/include/adts/mixed.h similarity index 100% rename from include/con4m/mixed.h rename to include/adts/mixed.h diff --git a/include/con4m/set.h b/include/adts/set.h similarity index 100% rename from include/con4m/set.h rename to include/adts/set.h diff --git a/include/con4m/stream.h b/include/adts/stream.h similarity index 100% rename from include/con4m/stream.h rename to include/adts/stream.h diff --git a/include/con4m/string.h b/include/adts/string.h similarity index 100% rename from include/con4m/string.h rename to include/adts/string.h diff --git a/include/con4m/tree.h b/include/adts/tree.h similarity index 100% rename from include/con4m/tree.h rename to include/adts/tree.h diff --git a/include/con4m/tuple.h b/include/adts/tuple.h similarity index 100% rename from include/con4m/tuple.h rename to include/adts/tuple.h diff --git a/include/compiler/datatypes/cfg.h b/include/compiler/dt_cfgs.h similarity index 100% rename from include/compiler/datatypes/cfg.h rename to include/compiler/dt_cfgs.h diff --git a/include/compiler/datatypes/compile.h b/include/compiler/dt_compile.h similarity index 100% rename from include/compiler/datatypes/compile.h rename to include/compiler/dt_compile.h diff --git a/include/compiler/datatypes/error.h b/include/compiler/dt_errors.h similarity index 100% rename from include/compiler/datatypes/error.h rename to include/compiler/dt_errors.h diff --git a/include/compiler/datatypes/file.h b/include/compiler/dt_files.h similarity index 100% rename from include/compiler/datatypes/file.h rename to include/compiler/dt_files.h diff --git a/include/compiler/datatypes/lex.h b/include/compiler/dt_lex.h similarity index 100% rename from include/compiler/datatypes/lex.h rename to include/compiler/dt_lex.h diff --git a/include/compiler/datatypes/nodeinfo.h b/include/compiler/dt_nodeinfo.h similarity index 100% rename from include/compiler/datatypes/nodeinfo.h rename to include/compiler/dt_nodeinfo.h diff --git a/include/compiler/datatypes/parse.h b/include/compiler/dt_parse.h similarity index 100% rename from include/compiler/datatypes/parse.h rename to include/compiler/dt_parse.h diff --git a/include/compiler/datatypes/scope.h b/include/compiler/dt_scopes.h similarity index 100% rename from include/compiler/datatypes/scope.h rename to include/compiler/dt_scopes.h diff --git a/include/compiler/datatypes/spec.h b/include/compiler/dt_specs.h similarity index 100% rename from include/compiler/datatypes/spec.h rename to include/compiler/dt_specs.h diff --git a/include/con4m.h b/include/con4m.h index 5c3e023a..bf7ad88d 100644 --- a/include/con4m.h +++ b/include/con4m.h @@ -1,83 +1,6 @@ #pragma once -#define C4M_DEBUG // Get backtrace on exceptions. - -// #define C4M_FULL_MEMCHECK -// #define C4M_STRICT_MEMCHECK -// #define C4M_TRACE_GC - -// #define C4M_GC_SHOW_COLLECT_STACK_TRACES -#define C4M_USE_FRAME_INTRINSIC -// #define C4M_GCT_MOVE 1 -// #define C4M_GCT_PTR_TO_MOVE 1 - -// #define C4M_GC_ALL_OFF -// #define C4M_GC_ALL_ON -// #define C4M_TYPE_LOG - -// When this is on, the `debug` instruction will run. -// Note that the debug instruction is not even generated unless -// C4M_DEV is on. - -// #define C4M_VM_DEBUG -// #define C4M_VM_DEBUG_DEFAULT true - -// This won't work on systems that require aligned pointers. -// #define C4M_PARANOID_STACK_SCAN -// #define C4M_PARSE_DEBUG - -// UBSan hates our underflow check. -// #define C4M_OMIT_UNDERFLOW_CHECKS -// -// If you want to identify zero-length allocs while FULL_MEMCHECK is on... -// But -// #define C4M_WARN_ON_ZERO_ALLOCS - -// #define C4M_DEBUG_PATTERNS - -#ifdef C4M_NO_DEV_MODE -#undef C4M_DEV -#undef C4M_PARSE_DEBUG -#else -#ifdef C4M_PARSE_DEBUG -#define C4M_DEV -#endif -#define C4M_DEV -#endif - -#if defined(C4M_VM_DEBUG) -#if !defined(C4M_DEV) -#error "Cannot debug VM when C4M_DEV_MODE is set." -#endif -#if !defined(C4M_VM_DEBUG_DEFAULT) -#define C4M_VM_DEBUG_DEFAULT false -#endif -#endif - -#if !defined(HATRACK_PER_INSTANCE_AUX) -#error "HATRACK_PER_INSTANCE_AUX must be defined for con4m to compile." -#endif - -#if defined(C4M_TRACE_GC) || defined(HATRACK_ALLOC_PASS_LOCATION) -#ifndef C4M_GC_STATS -#define C4M_GC_STATS -#endif -#endif - -#if defined(C4M_TRACE_GC) -#ifndef C4M_GC_FULL_TRACE -#define C4M_GC_FULL_TRACE -#endif - -#else // C4M_TRACE_GC -#undef C4M_GC_FULL_TRACE -#undef C4M_TRACE_GC -#endif - -#ifndef C4M_MIN_RENDER_WIDTH -#define C4M_MIN_RENDER_WIDTH 80 -#endif - +#include "con4m/config.h" // Useful options (mainly for dev) are commented out here. // The logic below (and into the relevent header files) sets up defaults. // @@ -85,96 +8,98 @@ // due to interdependencies, though they can always be solved via // prototyping. #include "con4m/base.h" -#include "con4m/init.h" -#include "con4m/macros.h" // Helper macros, mostly 3rd party stuff. -#include "con4m/kargs.h" // Keyword arguments. -#include "con4m/random.h" +#include "core/init.h" +#include "util/macros.h" // Helper macros +#include "core/kargs.h" // Keyword arguments. +#include "util/random.h" // Memory management -#include "con4m/refcount.h" -#include "con4m/gc.h" -#include "con4m/object.h" -#include "con4m/color.h" +#include "core/refcount.h" +#include "core/gc.h" + +// Core object. +#include "core/object.h" + +#include "util/color.h" // Basic "exclusive" (i.e., single threaded) list. -#include "con4m/list.h" +#include "adts/list.h" // Type system API. -#include "con4m/typestore.h" -#include "con4m/type.h" +#include "core/typestore.h" +#include "core/type.h" -#include "con4m/box.h" +#include "adts/box.h" // Extra data structure stuff. -#include "con4m/tree.h" -#include "con4m/tree_pattern.h" -#include "con4m/buffer.h" -#include "con4m/tuple.h" +#include "adts/tree.h" +#include "util/tree_pattern.h" +#include "adts/buffer.h" +#include "adts/tuple.h" // Basic string handling. -#include "con4m/codepoint.h" -#include "con4m/string.h" -#include "con4m/breaks.h" -#include "con4m/ansi.h" -#include "con4m/hex.h" +#include "adts/codepoint.h" +#include "adts/string.h" +#include "util/breaks.h" +#include "io/ansi.h" +#include "util/hex.h" -#include "con4m/style.h" -#include "con4m/styledb.h" +#include "util/style.h" +#include "util/styledb.h" // Our grid API. -#include "con4m/grid.h" +#include "adts/grid.h" // IO primitives. -#include "con4m/term.h" -#include "con4m/switchboard.h" -#include "con4m/subproc.h" +#include "io/term.h" +#include "io/switchboard.h" +#include "io/subproc.h" // Basic exception handling support. -#include "con4m/exception.h" +#include "core/exception.h" // Stream IO API. -#include "con4m/stream.h" +#include "adts/stream.h" // Helper functions for object marshal implementations to // marshal primitive values. -#include "con4m/marshal.h" +#include "core/marshal.h" // Mixed data type API. -#include "con4m/mixed.h" +#include "adts/mixed.h" // Basic internal API to cache and access common string constants. -#include "con4m/conststr.h" +#include "util/conststr.h" // Boxes for ordinal types -#include "con4m/box.h" +#include "adts/box.h" // A few prototypes for literal handling. -#include "con4m/literal.h" +#include "core/literal.h" // Format string API -#include "con4m/format.h" - -#include "con4m/fp.h" +#include "util/format.h" +#include "util/fp.h" // Path handling utilities. -#include "con4m/path.h" +#include "util/path.h" // Yes we use cryptographic hashes internally for type IDing. #include "crypto/sha.h" // Virtual machine for running con4m code -#include "con4m/vm.h" +#include "core/vm.h" // Bitfields. -#include "con4m/flags.h" +#include "adts/flags.h" // Really int log2 only right now. -#include "con4m/math.h" +#include "util/math.h" // For functions we need to wrap to use through the FFI. -#include "con4m/wrappers.h" +#include "util/wrappers.h" -#include "con4m/cbacktrace.h" +#include "util/cbacktrace.h" // The compiler. #include "compiler/ast_utils.h" @@ -187,8 +112,8 @@ #include "compiler/cfgs.h" #include "compiler/codegen.h" -#include "con4m/dict.h" -#include "con4m/set.h" +#include "adts/dict.h" +#include "adts/set.h" -#include "con4m/ffi.h" -#include "con4m/watch.h" +#include "core/ffi.h" +#include "util/watch.h" diff --git a/include/con4m/config.h b/include/con4m/config.h new file mode 100644 index 00000000..ec8e710b --- /dev/null +++ b/include/con4m/config.h @@ -0,0 +1,220 @@ +#pragma once + +// Home of anything remotely configurable. Don't change this file; +// update the meson config. +// +// If it's not in the meson options, then I'd discourage you from even +// considering changing the value. + +#if defined(__has_feature) +#if __has_feature(address_sanitizer) +#define __c4m_have_asan__ +#endif // address_sanitizer +#elif defined(__SANITIZE_ADDRESS__) +#define __c4m_have_asan__ +#endif // __has_feature + +#define C4M_FORCED_ALIGNMENT 16 + +#ifdef C4M_DEBUG_PATTERNS +#undef C4M_DEBUG_PATTERNS +#endif + +#ifdef C4M_PARSE_DEBUG +#undef C4M_PARSE_DEBUG +#endif + +#ifdef C4M_ADD_ALLOC_LOC_INFO +#undef C4M_ADD_ALLOC_LOC_INFO +#endif + +#ifdef C4M_DEBUG_KARGS +#undef C4M_DEBUG_KARGS +#endif + +#ifdef C4M_TYPE_LOG +#undef C4M_TYPE_LOG +#endif + +#ifdef C4M_SB_DEBUG +#undef C4M_SB_DEBUG +#endif + +#ifdef C4M_SB_TEST +#undef C4M_SB_TEST +#endif + +#if !defined(C4M_DEV) +#ifdef C4M_DEBUG +#error "C4M_DEBUG requires C4M_DEV" +#endif +#ifdef C4M_GC_STATS +#error "C4M_GC_STATS requires C4M_DEV" +#endif +#ifdef C4M_FULL_MEMCHECK +#error "C4M_FULL_MEMCHECK requires C4M_DEV" +#endif +#ifdef C4M_VM_DEBUG +#error "C4M_VM_DEBUG requires C4M_DEV" +#endif +#ifdef C4M_VM_WARN_ON_ZERO_ALLOCS +#error "C4M_VM_WARN_ON_ZERO_ALLOCS requires C4M_DEV" +#endif + +#endif + +#if !defined(HATRACK_PER_INSTANCE_AUX) +#error "HATRACK_PER_INSTANCE_AUX must be defined for con4m to compile." +#endif + +#if defined(C4M_GC_FULL_TRACE) && !defined(C4M_GC_STATS) +#define C4M_GC_STATS +#endif + +#if defined(C4M_FULL_MEMCHECK) && !defined(C4M_GC_STATS) +#define C4M_GC_STATS +#endif + +#if defined(HATRACK_ALLOC_PASS_LOCATION) +#define C4M_ADD_ALLOC_LOC_INFO +#else +#if defined(C4M_GC_STATS) +#error "C4M_GC_STATS cannot be enabled without HATRACK_ALLOC_PASS_LOCATION" +#endif // C4M_GC_STATS + +#endif // HATRACK_ALLOC_PASS_LOCATION + +#if defined(C4M_VM_DEBUG) && !defined(C4M_VM_DEBUG_DEFAULT) +#define C4M_VM_DEBUG_DEFAULT false +#endif + +#if defined(C4M_GC_FULL_TRACE) && !defined(C4M_GC_FULL_TRACE_DEFAULT) +#define C4M_GC_FULL_TRACE_DEFAULT 1 +#endif + +#ifndef C4M_MIN_RENDER_WIDTH +#define C4M_MIN_RENDER_WIDTH 80 +#endif + +#ifndef C4M_DEBUG +#if defined(C4M_WATCH_SLOTS) || defined(C4M_WATCH_LOG_SZ) +#warning "Watchpoint compile parameters set, but watchpoints are disabeld" +#endif // either set +#else +#ifndef C4M_WATCH_SLOTS +#define C4M_WATCH_SLOTS 30 +#endif + +#ifndef C4M_WATCH_LOG_SZ +#define C4M_WATCH_LOG_SZ (1 << 14) +#endif +#endif // C4M_DEBUG + +#ifndef C4M_MAX_KARGS_NESTING_DEPTH +// Must be a power of two, and probably shouldn't be lower. +#define C4M_MAX_KARGS_NESTING_DEPTH 32 +#endif + +// More accurately, max # of supported keywords. +#ifndef C4M_MAX_KEYWORD_SIZE +#define C4M_MAX_KEYWORD_SIZE 32 +#endif + +#if defined(C4M_FULL_MEMCHECK) +// #define C4M_SHOW_NEXT_ALLOCS 1000 +#ifndef C4M_MEMCHECK_RING_SZ +// Must be a power of 2. +#define C4M_MEMCHECK_RING_SZ 128 +#endif // RING_SZ + +#if C4M_MEMCHECK_RING_SZ != 0 +#define C4M_USE_RING +#else +#undef C4M_USE_RING +#endif // C4M_MEMCHECK_RING_SZ +#endif // C4M_FULL_MEMCHECK + +#ifndef C4M_EMPTY_BUFFER_ALLOC +#define C4M_EMPTY_BUFFER_ALLOC 128 +#endif + +#ifndef C4M_DEFAULT_ARENA_SIZE +// This is the size any test case that prints a thing grows to awfully fast. +#define C4M_DEFAULT_ARENA_SIZE (1 << 26) +#endif + +#ifndef C4M_STACK_SIZE +#define C4M_STACK_SIZE (1 << 17) +#endif + +#ifndef C4M_MAX_CALL_DEPTH +#define C4M_MAX_CALL_DEPTH 100 +#endif + +#if defined(C4M_GC_STATS) && !defined(C4M_SHOW_GC_DEFAULT) +#define C4M_SHOW_GC_DEFAULT 0 +#endif + +#ifdef C4M_GC_ALL_ON +#define C4M_GC_DEFAULT_ON 1 +#define C4M_GC_DEFAULT_OFF 1 +#elif defined(C4M_GC_ALL_OFF) +#define C4M_GC_DEFAULT_ON 0 +#define C4M_GC_DEFAULT_OFF 0 +#else +#define C4M_GC_DEFAULT_ON 1 +#define C4M_GC_DEFAULT_OFF 0 +#endif + +#if defined(C4M_DEBUG) && !defined(C4M_BACKTRACE_SUPPORTED) +#warning "Cannot add debug stack traces to exceptions: libbacktrace not supported" +#endif + +#ifndef C4M_GCT_INIT +#define C4M_GCT_INIT C4M_GC_DEFAULT_ON +#endif +#ifndef C4M_GCT_MMAP +#define C4M_GCT_MMAP C4M_GC_DEFAULT_ON +#endif +#ifndef C4M_GCT_MUNMAP +#define C4M_GCT_MUNMAP C4M_GC_DEFAULT_ON +#endif +#ifndef C4M_GCT_SCAN +#define C4M_GCT_SCAN C4M_GC_DEFAULT_ON +#endif +#ifndef C4M_GCT_OBJ +#define C4M_GCT_OBJ C4M_GC_DEFAULT_OFF +#endif +#ifndef C4M_GCT_SCAN_PTR +#define C4M_GCT_SCAN_PTR C4M_GC_DEFAULT_OFF +#endif +#ifndef C4M_GCT_PTR_TEST +#define C4M_GCT_PTR_TEST C4M_GC_DEFAULT_OFF +#endif +#ifndef C4M_GCT_PTR_TO_MOVE +#define C4M_GCT_PTR_TO_MOVE C4M_GC_DEFAULT_OFF +#endif +#ifndef C4M_GCT_MOVE +#define C4M_GCT_MOVE C4M_GC_DEFAULT_OFF +#endif +#ifndef C4M_GCT_ALLOC_FOUND +#define C4M_GCT_ALLOC_FOUND C4M_GC_DEFAULT_OFF +#endif +#ifndef C4M_GCT_PTR_THREAD +#define C4M_GCT_PTR_THREAD C4M_GC_DEFAULT_OFF +#endif +#ifndef C4M_GCT_MOVED +#define C4M_GCT_MOVED C4M_GC_DEFAULT_OFF +#endif +#ifndef C4M_GCT_COLLECT +#define C4M_GCT_COLLECT C4M_GC_DEFAULT_ON +#endif +#ifndef C4M_GCT_REGISTER +#define C4M_GCT_REGISTER C4M_GC_DEFAULT_ON +#endif +#ifndef C4M_GCT_ALLOC +#define C4M_GCT_ALLOC C4M_GC_DEFAULT_OFF +#endif +#ifndef C4M_MAX_GC_ROOTS +#define C4M_MAX_GC_ROOTS (1 << 15) +#endif diff --git a/include/con4m/datatypes.h b/include/con4m/datatypes.h index 996569c3..8b3f7109 100644 --- a/include/con4m/datatypes.h +++ b/include/con4m/datatypes.h @@ -2,42 +2,42 @@ typedef struct hatrack_set_st c4m_set_t; -#include "con4m/datatypes/box.h" -#include "con4m/datatypes/memory.h" -#include "con4m/datatypes/kargs.h" -#include "con4m/datatypes/objects.h" -#include "con4m/datatypes/literals.h" -#include "con4m/datatypes/colors.h" -#include "con4m/datatypes/codepoints.h" -#include "con4m/datatypes/styles.h" -#include "con4m/datatypes/strings.h" -#include "con4m/datatypes/flags.h" -#include "con4m/datatypes/lists.h" -#include "con4m/datatypes/trees.h" -#include "con4m/datatypes/tree_pattern.h" -#include "con4m/datatypes/types.h" -#include "con4m/datatypes/grids.h" -#include "con4m/datatypes/buffers.h" -#include "con4m/datatypes/io.h" -#include "con4m/datatypes/crypto.h" -#include "con4m/datatypes/exceptions.h" -#include "con4m/datatypes/mixed.h" -#include "con4m/datatypes/tuples.h" -#include "con4m/datatypes/streams.h" -#include "con4m/datatypes/format.h" -#include "compiler/datatypes/lex.h" -#include "compiler/datatypes/error.h" -#include "compiler/datatypes/parse.h" -#include "compiler/datatypes/scope.h" -#include "con4m/datatypes/ffi.h" -#include "con4m/datatypes/ufi.h" -#include "con4m/datatypes/vm.h" -#include "con4m/datatypes/callbacks.h" -#include "compiler/datatypes/nodeinfo.h" -#include "compiler/datatypes/spec.h" -#include "compiler/datatypes/cfg.h" -#include "compiler/datatypes/file.h" -#include "compiler/datatypes/compile.h" +#include "adts/dt_box.h" +#include "core/dt_alloc.h" +#include "core/dt_kargs.h" +#include "core/dt_objects.h" +#include "core/dt_literals.h" +#include "util/dt_colors.h" +#include "adts/dt_codepoints.h" +#include "util/dt_styles.h" +#include "adts/dt_strings.h" +#include "adts/dt_flags.h" +#include "adts/dt_lists.h" +#include "adts/dt_trees.h" +#include "util/dt_tree_patterns.h" +#include "core/dt_types.h" +#include "adts/dt_grids.h" +#include "adts/dt_buffers.h" +#include "io/dt_io.h" +#include "crypto/dt_crypto.h" +#include "core/dt_exceptions.h" +#include "adts/dt_mixed.h" +#include "adts/dt_tuples.h" +#include "adts/dt_streams.h" +#include "util/dt_format.h" +#include "compiler/dt_lex.h" +#include "compiler/dt_errors.h" +#include "compiler/dt_parse.h" +#include "compiler/dt_scopes.h" +#include "core/dt_ffi.h" +#include "core/dt_ufi.h" +#include "core/dt_vm.h" +#include "adts/dt_callbacks.h" +#include "compiler/dt_nodeinfo.h" +#include "compiler/dt_specs.h" +#include "compiler/dt_cfgs.h" +#include "compiler/dt_files.h" +#include "compiler/dt_compile.h" typedef c4m_str_t *(*c4m_repr_fn)(c4m_obj_t); typedef void (*c4m_marshal_fn)(c4m_obj_t, diff --git a/include/con4m/datatypes/memory.h b/include/core/dt_alloc.h similarity index 94% rename from include/con4m/datatypes/memory.h rename to include/core/dt_alloc.h index 32576c53..3d051eac 100644 --- a/include/con4m/datatypes/memory.h +++ b/include/core/dt_alloc.h @@ -1,12 +1,6 @@ #pragma once #include "con4m.h" -#if defined(C4M_FULL_MEMCHECK) && !defined(C4M_GC_STATS) -#define C4M_GC_STATS -#endif - -#define C4M_FORCED_ALIGNMENT 16 - typedef void (*c4m_mem_scan_fn)(uint64_t *, void *); typedef struct c4m_alloc_hdr { @@ -56,15 +50,15 @@ typedef struct c4m_alloc_hdr { // bits that correspond to words with pointers should be set. c4m_mem_scan_fn scan_fn; -#if defined(C4M_GC_STATS) || defined(C4M_DEBUG) - char *alloc_file; - int alloc_line; -#endif - #ifdef C4M_FULL_MEMCHECK uint64_t *end_guard_loc; #endif +#if defined(C4M_ADD_ALLOC_LOC_INFO) + char *alloc_file; + int alloc_line; +#endif + // Set to 'true' if this object requires finalization. This is // necessary, even though the arena tracks allocations needing // finalization, because resizes could move the pointer. @@ -103,16 +97,12 @@ typedef struct c4m_shadow_alloc_t { typedef struct { void *ptr; uint64_t num_items; -#ifdef C4M_GC_STATS +#ifdef C4M_ADD_ALLOC_LOC_INFO char *file; int line; #endif } c4m_gc_root_info_t; -#ifndef C4M_MAX_GC_ROOTS -#define C4M_MAX_GC_ROOTS (1 << 15) -#endif - typedef struct c4m_arena_t { #ifdef C4M_FULL_MEMCHECK c4m_shadow_alloc_t *shadow_start; diff --git a/include/con4m/datatypes/exceptions.h b/include/core/dt_exceptions.h similarity index 100% rename from include/con4m/datatypes/exceptions.h rename to include/core/dt_exceptions.h diff --git a/include/con4m/datatypes/ffi.h b/include/core/dt_ffi.h similarity index 100% rename from include/con4m/datatypes/ffi.h rename to include/core/dt_ffi.h diff --git a/include/con4m/datatypes/kargs.h b/include/core/dt_kargs.h similarity index 100% rename from include/con4m/datatypes/kargs.h rename to include/core/dt_kargs.h diff --git a/include/con4m/datatypes/literals.h b/include/core/dt_literals.h similarity index 100% rename from include/con4m/datatypes/literals.h rename to include/core/dt_literals.h diff --git a/include/con4m/datatypes/objects.h b/include/core/dt_objects.h similarity index 100% rename from include/con4m/datatypes/objects.h rename to include/core/dt_objects.h diff --git a/include/con4m/datatypes/types.h b/include/core/dt_types.h similarity index 100% rename from include/con4m/datatypes/types.h rename to include/core/dt_types.h diff --git a/include/con4m/datatypes/ufi.h b/include/core/dt_ufi.h similarity index 100% rename from include/con4m/datatypes/ufi.h rename to include/core/dt_ufi.h diff --git a/include/con4m/datatypes/vm.h b/include/core/dt_vm.h similarity index 98% rename from include/con4m/datatypes/vm.h rename to include/core/dt_vm.h index 841db31d..0513e111 100644 --- a/include/con4m/datatypes/vm.h +++ b/include/core/dt_vm.h @@ -63,18 +63,6 @@ // caller must push the return register onto the stack if it's interested in // its value. -#ifndef C4M_STACK_SIZE -#define STACK_SIZE (1 << 17) -#else -#define STACK_SIZE C4M_STACK_SIZE -#endif - -#ifndef C4M_MAX_CALL_DEPTH -#define MAX_CALL_DEPTH 200 -#else -#define MAX_CALL_DEPTH C4M_MAX_CALL_DEPTH -#endif - typedef enum : uint8_t { // Push from const storage onto the stack. // Const values that are not reference objects can be pushed as immediates @@ -563,11 +551,11 @@ typedef struct { c4m_arena_t *thread_arena; // frame_stack is the base address of the call stack - c4m_vmframe_t frame_stack[MAX_CALL_DEPTH]; + c4m_vmframe_t frame_stack[C4M_MAX_CALL_DEPTH]; // stack is the base address of the stack for this thread of execution. // the stack grows down, so the stack bottom is &stack[STACK_SIZE] - c4m_stack_value_t stack[STACK_SIZE]; + c4m_stack_value_t stack[C4M_STACK_SIZE]; // General purpose registers. // R0 should generally only be used for passing return values. diff --git a/include/con4m/exception.h b/include/core/exception.h similarity index 99% rename from include/con4m/exception.h rename to include/core/exception.h index 814671cb..1aaf32d9 100644 --- a/include/con4m/exception.h +++ b/include/core/exception.h @@ -131,7 +131,7 @@ #define C4M_FINALLY C4M_LFINALLY(default_label) #define C4M_TRY_END C4M_LTRY_END(default_label) -#if defined(C4M_DEBUG) && defined(BACKTRACE_SUPPORTED) +#if defined(C4M_DEBUG) && defined(C4M_BACKTRACE_SUPPORTED) extern void c4m_print_c_backtrace(); #define c4m_trace() c4m_print_c_backtrace() #else diff --git a/include/con4m/ffi.h b/include/core/ffi.h similarity index 100% rename from include/con4m/ffi.h rename to include/core/ffi.h diff --git a/include/con4m/gc.h b/include/core/gc.h similarity index 87% rename from include/con4m/gc.h rename to include/core/gc.h index df31bb13..3398ce78 100644 --- a/include/con4m/gc.h +++ b/include/core/gc.h @@ -64,73 +64,6 @@ * generated by the compiler. */ -#if defined(C4M_GC_FULL_TRACE) && !defined(C4M_GC_STATS) -#define C4M_GC_STATS -#endif - -#ifdef C4M_GC_ALL_ON -#define DEFAULT_ON 1 -#define DEFAULT_OFF 1 -#elif defined(C4M_GC_ALL_OFF) -#define DEFAULT_ON 0 -#define DEFAULT_OFF 0 -#else -#define DEFAULT_ON 1 -#define DEFAULT_OFF 0 -#endif - -#ifndef C4M_GCT_INIT -#define C4M_GCT_INIT DEFAULT_ON -#endif -#ifndef C4M_GCT_MMAP -#define C4M_GCT_MMAP DEFAULT_ON -#endif -#ifndef C4M_GCT_MUNMAP -#define C4M_GCT_MUNMAP DEFAULT_ON -#endif -#ifndef C4M_GCT_SCAN -#define C4M_GCT_SCAN DEFAULT_ON -#endif -#ifndef C4M_GCT_OBJ -#define C4M_GCT_OBJ DEFAULT_OFF -#endif -#ifndef C4M_GCT_SCAN_PTR -#define C4M_GCT_SCAN_PTR DEFAULT_OFF -#endif -#ifndef C4M_GCT_PTR_TEST -#define C4M_GCT_PTR_TEST DEFAULT_OFF -#endif -#ifndef C4M_GCT_PTR_TO_MOVE -#define C4M_GCT_PTR_TO_MOVE DEFAULT_OFF -#endif -#ifndef C4M_GCT_MOVE -#define C4M_GCT_MOVE DEFAULT_OFF -#endif -#ifndef C4M_GCT_ALLOC_FOUND -#define C4M_GCT_ALLOC_FOUND DEFAULT_OFF -#endif -#ifndef C4M_GCT_PTR_THREAD -#define C4M_GCT_PTR_THREAD DEFAULT_OFF -#endif -#ifndef C4M_GCT_MOVED -#define C4M_GCT_MOVED DEFAULT_OFF -#endif -#ifndef C4M_GCT_COLLECT -#define C4M_GCT_COLLECT DEFAULT_ON -#endif -#ifndef C4M_GCT_REGISTER -#define C4M_GCT_REGISTER DEFAULT_ON -#endif -#ifndef C4M_GCT_ALLOC -#define C4M_GCT_ALLOC DEFAULT_OFF -#endif - -#ifndef C4M_DEFAULT_ARENA_SIZE - -// This is the size any test case that prints a thing grows to awfully fast. -#define C4M_DEFAULT_ARENA_SIZE (1 << 26) -#endif - // In the future, we would expect that a writer seeing the // 'collecting' field will attempt to help migration to minimize // time spent waiting, but for the time being, any cross-thread @@ -164,7 +97,7 @@ extern void c4m_gc_thread_collect(); extern bool c4m_is_read_only_memory(volatile void *); extern void c4m_gc_set_finalize_callback(c4m_system_finalizer_fn); -#ifdef C4M_GC_STATS +#ifdef C4M_ADD_ALLOC_LOC_INFO extern void _c4m_arena_register_root(c4m_arena_t *, void *, uint64_t, @@ -188,7 +121,7 @@ extern void _c4m_gc_register_root(void *, uint64_t); void c4m_arena_remove_root(c4m_arena_t *arena, void *ptr); void c4m_gc_remove_root(void *ptr); -#if defined(C4M_GC_STATS) || defined(C4M_DEBUG) +#ifdef C4M_ADD_ALLOC_LOC_INFO extern void *_c4m_gc_raw_alloc(size_t, c4m_mem_scan_fn, char *, int); extern void *_c4m_gc_raw_alloc_with_finalizer(size_t, c4m_mem_scan_fn, @@ -221,12 +154,9 @@ extern void *c4m_alloc_from_arena(c4m_arena_t **, bool); #endif -#ifdef C4M_GC_STATS -#ifndef C4M_SHOW_GC_DEFAULT -#define C4M_SHOW_GC_DEFAULT 0 -#endif extern int c4m_gc_show_heap_stats_on; +#ifdef C4M_GC_STATS #define c4m_gc_show_heap_stats_on() c4m_gc_show_heap_stats_on = 1 #define c4m_gc_show_heap_stats_off() c4m_gc_show_heap_stats_on = 0 #else @@ -336,13 +266,7 @@ void _c4m_memcheck_object(c4m_obj_t, char *, int); #define c4m_memcheck_object(x) #endif -#if defined(__has_feature) -#if __has_feature(address_sanitizer) -#define __SANITIZE_ADDRESS__ -#endif -#endif - -#if defined(__SANITIZE_ADDRESS__) +#if defined(__c4m_have_asan__) void __asan_poison_memory_region(void const volatile *addr, size_t size); void __asan_unpoison_memory_region(void const volatile *addr, size_t size); diff --git a/include/con4m/init.h b/include/core/init.h similarity index 100% rename from include/con4m/init.h rename to include/core/init.h diff --git a/include/con4m/kargs.h b/include/core/kargs.h similarity index 100% rename from include/con4m/kargs.h rename to include/core/kargs.h diff --git a/include/con4m/literal.h b/include/core/literal.h similarity index 100% rename from include/con4m/literal.h rename to include/core/literal.h diff --git a/include/con4m/marshal.h b/include/core/marshal.h similarity index 100% rename from include/con4m/marshal.h rename to include/core/marshal.h diff --git a/include/con4m/object.h b/include/core/object.h similarity index 100% rename from include/con4m/object.h rename to include/core/object.h diff --git a/include/con4m/refcount.h b/include/core/refcount.h similarity index 90% rename from include/con4m/refcount.h rename to include/core/refcount.h index 75d44ff8..577d02a7 100644 --- a/include/con4m/refcount.h +++ b/include/core/refcount.h @@ -17,7 +17,7 @@ typedef struct { _Atomic int64_t refcount; - char data[]; + alignas(C4M_FORCED_ALIGNMENT) char data[]; } refcount_alloc_t; static inline void * @@ -25,7 +25,10 @@ c4m_rc_alloc(size_t len) { refcount_alloc_t *raw; - raw = (refcount_alloc_t *)calloc(sizeof(refcount_alloc_t) + len, 1); + len += sizeof(refcount_alloc_t); + + assert(!posix_memalign((void **)&raw, C4M_FORCED_ALIGNMENT, len)); + bzero(raw, len); atomic_store(&(raw->refcount), 1); return (void *)raw->data; diff --git a/include/con4m/type.h b/include/core/type.h similarity index 99% rename from include/con4m/type.h rename to include/core/type.h index ad503b91..25247a75 100644 --- a/include/con4m/type.h +++ b/include/core/type.h @@ -138,7 +138,12 @@ c4m_type_unlock(c4m_type_t *t) static inline c4m_type_t * c4m_type_get_param(c4m_type_t *t, int i) { - return c4m_list_get(t->details->items, i, NULL); + if (t && t->details) { + return c4m_list_get(t->details->items, i, NULL); + } + else { + return NULL; + } } static inline c4m_type_t * diff --git a/include/con4m/typestore.h b/include/core/typestore.h similarity index 100% rename from include/con4m/typestore.h rename to include/core/typestore.h diff --git a/include/con4m/vm.h b/include/core/vm.h similarity index 100% rename from include/con4m/vm.h rename to include/core/vm.h diff --git a/include/con4m/datatypes/crypto.h b/include/crypto/dt_crypto.h similarity index 100% rename from include/con4m/datatypes/crypto.h rename to include/crypto/dt_crypto.h diff --git a/include/hatrack/crown.h b/include/hatrack/crown.h index 9b313f7b..534b8747 100644 --- a/include/hatrack/crown.h +++ b/include/hatrack/crown.h @@ -31,7 +31,7 @@ #include "mmm.h" typedef struct { - alignas(8) void *item; + void *item; uint64_t info; } crown_record_t; diff --git a/include/hatrack/dict.h b/include/hatrack/dict.h index 7a9569b2..13acb290 100644 --- a/include/hatrack/dict.h +++ b/include/hatrack/dict.h @@ -71,7 +71,7 @@ struct hatrack_dict_t { hatrack_mem_hook_t key_return_hook; hatrack_mem_hook_t val_return_hook; #ifdef HATRACK_PER_INSTANCE_AUX - alignas(8) void *bucket_aux; + void *bucket_aux; #endif }; diff --git a/include/con4m/ansi.h b/include/io/ansi.h similarity index 100% rename from include/con4m/ansi.h rename to include/io/ansi.h diff --git a/include/con4m/datatypes/io.h b/include/io/dt_io.h similarity index 100% rename from include/con4m/datatypes/io.h rename to include/io/dt_io.h diff --git a/include/con4m/subproc.h b/include/io/subproc.h similarity index 100% rename from include/con4m/subproc.h rename to include/io/subproc.h diff --git a/include/con4m/switchboard.h b/include/io/switchboard.h similarity index 100% rename from include/con4m/switchboard.h rename to include/io/switchboard.h diff --git a/include/con4m/term.h b/include/io/term.h similarity index 100% rename from include/con4m/term.h rename to include/io/term.h diff --git a/include/con4m/breaks.h b/include/util/breaks.h similarity index 100% rename from include/con4m/breaks.h rename to include/util/breaks.h diff --git a/include/con4m/cbacktrace.h b/include/util/cbacktrace.h similarity index 89% rename from include/con4m/cbacktrace.h rename to include/util/cbacktrace.h index abcd3cf5..99409c76 100644 --- a/include/con4m/cbacktrace.h +++ b/include/util/cbacktrace.h @@ -1,7 +1,7 @@ #pragma once #include "con4m.h" -#ifdef BACKTRACE_SUPPORTED +#ifdef C4M_BACKTRACE_SUPPORTED extern void c4m_backtrace_init(char *); extern void c4m_print_c_backtrace(); #else diff --git a/include/con4m/color.h b/include/util/color.h similarity index 100% rename from include/con4m/color.h rename to include/util/color.h diff --git a/include/con4m/conststr.h b/include/util/conststr.h similarity index 100% rename from include/con4m/conststr.h rename to include/util/conststr.h diff --git a/include/con4m/datatypes/colors.h b/include/util/dt_colors.h similarity index 100% rename from include/con4m/datatypes/colors.h rename to include/util/dt_colors.h diff --git a/include/con4m/datatypes/format.h b/include/util/dt_format.h similarity index 100% rename from include/con4m/datatypes/format.h rename to include/util/dt_format.h diff --git a/include/con4m/datatypes/styles.h b/include/util/dt_styles.h similarity index 100% rename from include/con4m/datatypes/styles.h rename to include/util/dt_styles.h diff --git a/include/con4m/datatypes/tree_pattern.h b/include/util/dt_tree_patterns.h similarity index 100% rename from include/con4m/datatypes/tree_pattern.h rename to include/util/dt_tree_patterns.h diff --git a/include/con4m/format.h b/include/util/format.h similarity index 100% rename from include/con4m/format.h rename to include/util/format.h diff --git a/include/con4m/fp.h b/include/util/fp.h similarity index 100% rename from include/con4m/fp.h rename to include/util/fp.h diff --git a/include/con4m/hex.h b/include/util/hex.h similarity index 100% rename from include/con4m/hex.h rename to include/util/hex.h diff --git a/include/con4m/macros.h b/include/util/macros.h similarity index 100% rename from include/con4m/macros.h rename to include/util/macros.h diff --git a/include/con4m/math.h b/include/util/math.h similarity index 100% rename from include/con4m/math.h rename to include/util/math.h diff --git a/include/con4m/path.h b/include/util/path.h similarity index 100% rename from include/con4m/path.h rename to include/util/path.h diff --git a/include/con4m/random.h b/include/util/random.h similarity index 100% rename from include/con4m/random.h rename to include/util/random.h diff --git a/include/con4m/style.h b/include/util/style.h similarity index 100% rename from include/con4m/style.h rename to include/util/style.h diff --git a/include/con4m/styledb.h b/include/util/styledb.h similarity index 100% rename from include/con4m/styledb.h rename to include/util/styledb.h diff --git a/include/con4m/tree_pattern.h b/include/util/tree_pattern.h similarity index 100% rename from include/con4m/tree_pattern.h rename to include/util/tree_pattern.h diff --git a/include/con4m/watch.h b/include/util/watch.h similarity index 91% rename from include/con4m/watch.h rename to include/util/watch.h index 2b4eaba6..b38b8d06 100644 --- a/include/con4m/watch.h +++ b/include/util/watch.h @@ -8,14 +8,6 @@ // memory writes. For now, it's just a prototype to help me hunt down // a Heisenbug that is afraid of debuggers. -#ifndef C4M_WATCH_SLOTS -#define C4M_WATCH_SLOTS 30 -#endif - -#ifndef C4M_WATCH_LOG_SZ -#define C4M_WATCH_LOG_SZ (1 << 14) -#endif - typedef enum : int8_t { c4m_wa_ignore, c4m_wa_log, diff --git a/include/con4m/wrappers.h b/include/util/wrappers.h similarity index 100% rename from include/con4m/wrappers.h rename to include/util/wrappers.h diff --git a/meson.build b/meson.build index 60dd9347..15374853 100644 --- a/meson.build +++ b/meson.build @@ -1,14 +1,15 @@ -project('libcon4m', 'c', - default_options: ['c_std=c2x', - 'default_library=static' - ], - version : '0.1.0', - license: 'MIT') +project( + 'libcon4m', + 'c', + default_options: ['c_std=c2x', 'default_library=static'], + version: '0.1.0', + license: 'MIT', +) -cc = meson.get_compiler('c') -incdir = include_directories('include') -using_osx = false +cc = meson.get_compiler('c') +incdir = include_directories('include') +using_osx = false glibc_check = ''' #include @@ -17,42 +18,54 @@ glibc_check = ''' #endif ''' if cc.compiles(glibc_check) - using_glibc = true + using_glibc = true else - using_glibc = false + using_glibc = false endif -c_args = ['-Wextra', - '-g', - '-Wno-unused-parameter', - '-Wno-cast-function-type', - '-fno-omit-frame-pointer', - '-DHATRACK_PER_INSTANCE_AUX', - ] +render_width = get_option('minimum_render_width').to_string() + +c_args = [ + '-Wextra', + '-g', + '-Wno-unused-parameter', + '-Wno-cast-function-type', + '-fno-omit-frame-pointer', + '-DHATRACK_PER_INSTANCE_AUX', + '-DC4M_MIN_RENDER_WIDTH=' + render_width, +] if (host_machine.cpu_family() == 'x86_64' and cc.get_id() == 'clang') - c_args = c_args + ['-Wno-atomic-alignment'] + c_args = c_args + ['-Wno-atomic-alignment'] endif if (host_machine.system() == 'darwin') - using_osx = true - link_args = ['-target', - 'arm64-apple-macos14', - '-framework', - 'Security', - ] + using_osx = true + link_args = ['-target', 'arm64-apple-macos14', '-framework', 'Security'] + + if not get_option('use_frame_intrinsic').disabled() + c_args = c_args + ['-DC4M_USE_FRAME_INTRINSIC'] + endif else - using_osx = false - link_args = [] - c_args = c_args + ['-D_GNU_SOURCE'] + using_osx = false + link_args = [] + c_args = c_args + ['-D_GNU_SOURCE'] + + # This doesn't seem to always work right on Linux so don't use it by default. + if get_option('use_frame_intrinsic').enabled() + c_args = c_args + ['-DC4M_USE_FRAME_INTRINSIC'] + endif endif -backtrace = cc.find_library('backtrace', - required: false) +backtrace = cc.find_library('backtrace', required: false) if backtrace.found() -c_args = c_args + ['-DBACKTRACE_SUPPORTED'] -endif + c_args = c_args + ['-DC4M_BACKTRACE_SUPPORTED'] +endif + +if get_option('show_preprocessor_config').enabled() + c_args = c_args + ['-DC4M_SHOW_PREPROC_CONFIG'] +endif fpty_code = ''' #include @@ -62,218 +75,301 @@ int main(void) { forkpty(NULL, NULL, NULL, NULL); return 0; } ''' if cc.links(fpty_code, name: 'forkpty_check') - add_project_arguments('-DHAVE_PTY_H', language: 'c') + add_project_arguments('-DHAVE_PTY_H', language: 'c') endif -if (get_option('buildtype') == 'release') - c_args = c_args + [ '-Ofast', '-flto' ] - link_args = link_args + ['-flto'] +if get_option('buildtype') == 'release' + c_args = c_args + ['-Ofast', '-flto'] + link_args = link_args + ['-flto'] endif -if (get_option('use_asan') == true) - c_args = c_args + ['-fsanitize=address', - '-fsanitize-recover=all' - ] - link_args = link_args + ['-fsanitize=address', - '-fsanitize-recover=all' - ] +if not get_option('use_gc_ptr_hooks').disabled() + c_args = c_args + ['-DC4M_USE_GC_HOOKS'] endif -if (get_option('use_ubsan') == true) - c_args = c_args + ['-fsanitize=undefined', - '-fno-sanitize=function', - '-fsanitize-recover=all' - ] -link_args = link_args + ['-fsanitize=undefined', - '-fsanitize-recover=all' - ] -endif +if get_option('keep_alloc_locations') == true and get_option('dev_mode') == false + c_args = c_args + ['-DHATRACK_ALLOC_PASS_LOCATION'] -if (get_option('use_memcheck') == true) - c_args = c_args + ['-DC4M_FULL_MEMCHECK'] endif -if (get_option('show_gc_stats') == true) - c_args = c_args + ['-DC4M_GC_STATS', '-DHATRACK_ALLOC_PASS_LOCATION'] -endif +if get_option('dev_mode') == true + c_args = c_args + ['-DC4M_DEV'] + + if not get_option('exception_traces').disabled() + c_args = c_args + ['-DC4M_DEBUG'] + endif + + if get_option('use_asan').enabled() + c_args = c_args + ['-fsanitize=address', '-fsanitize-recover=all'] + link_args = link_args + ['-fsanitize=address', '-fsanitize-recover=all'] + endif + + if get_option('use_ubsan').enabled() + c_args = c_args + [ + '-fsanitize=undefined', + '-fno-sanitize=function', + '-fsanitize-recover=all', + ] + link_args = link_args + [ + '-fsanitize=undefined', + '-fsanitize-recover=all', + ] + endif + + memcheck = get_option('use_memcheck') + if not (memcheck == 'off') + c_args = c_args + [ + '-DC4M_FULL_MEMCHECK', + '-DHATRACK_ALLOC_PASS_LOCATION', + ] + + if memcheck == 'strict' + c_args = c_args + ['-DC4M_STRICT_MEMCHECK'] + endif + endif + + if get_option('show_gc_stats').enabled() + c_args = c_args + ['-DC4M_GC_STATS', '-DHATRACK_ALLOC_PASS_LOCATION'] + endif + + vm_debug = get_option('vm_debug') + + if vm_debug != 'always off' + c_args = c_args + ['-DC4M_VM_DEBUG'] + endif + + if vm_debug == 'default on' + c_args = c_args + ['-DC4M_VM_DEBUG_DEFAULT=true'] + endif + + if get_option('warn_on_zero_allocs') == true + c_args = c_args + ['-DC4M_WARN_ON_ZERO_ALLOCS'] + endif + gctrace = get_option('gc_tracing') + + if gctrace != 'off' + c_args = c_args + ['-DC4M_GC_FULL_TRACE'] + endif + + if gctrace == 'full' + c_args = c_args + ['-DC4M_GC_FULL_TRACE', '-DC4M_GC_ALL_ON'] + endif + +endif + exe_link_args = link_args + ['-flto', '-w'] -exe_c_args = c_args + ['-flto', '-DHATRACK_REFERENCE_ALGORITHMS'] +exe_c_args = c_args + ['-flto', '-DHATRACK_REFERENCE_ALGORITHMS'] c4m_c_args = c_args -c4m_src = ['src/con4m/style.c', - 'src/con4m/colors.c', - 'src/con4m/breaks.c', - 'src/con4m/string.c', - 'src/con4m/buffer.c', - 'src/con4m/ansi.c', - 'src/con4m/hex.c', - 'src/con4m/switchboard.c', - 'src/con4m/subproc.c', - 'src/con4m/gcbase.c', - 'src/con4m/collect.c', - 'src/con4m/term.c', - 'src/con4m/kargs.c', - 'src/con4m/object.c', - 'src/con4m/dict.c', - 'src/con4m/set.c', - 'src/con4m/hatlists.c', - 'src/con4m/list.c', - 'src/con4m/grid.c', - 'src/con4m/styledb.c', - 'src/con4m/exceptions.c', - 'src/con4m/marshal.c', - 'src/con4m/typestore.c', - 'src/con4m/types.c', - 'src/con4m/tree.c', - 'src/con4m/tree_pattern.c', - 'src/con4m/numbers.c', - 'src/con4m/mixed.c', - 'src/con4m/conststr.c', - 'src/con4m/tuple.c', - 'src/con4m/ipaddr.c', - 'src/con4m/callback.c', - 'src/con4m/streams.c', - 'src/con4m/richlit.c', - 'src/con4m/literals.c', - 'src/con4m/init.c', - 'src/con4m/attrstore.c', - 'src/con4m/vm.c', - 'src/con4m/vmmarshal.c', - 'src/con4m/format.c', - 'src/con4m/fptostr.c', - 'src/con4m/path.c', - 'src/con4m/flags.c', - 'src/con4m/box.c', - 'src/con4m/ffi.c', - 'src/con4m/watch.c', - 'src/con4m/wrappers.c', - 'src/con4m/ctrace.c', - 'src/con4m/crypto/sha.c', - 'src/con4m/compiler/compile.c', - 'src/con4m/compiler/lex.c', - 'src/con4m/compiler/parse.c', - 'src/con4m/compiler/errors.c', - 'src/con4m/compiler/scope.c', - 'src/con4m/compiler/specs.c', - 'src/con4m/compiler/cfg_build.c', - 'src/con4m/compiler/cfg.c', - 'src/con4m/compiler/ast_utils.c', - 'src/con4m/compiler/decl_pass.c', - 'src/con4m/compiler/check_pass.c', - 'src/con4m/compiler/memory_layout.c', - 'src/con4m/compiler/codegen.c', - 'src/con4m/compiler/disasm.c', - 'src/con4m/compiler/objgen.c', - ] - -hat_primary = ['src/hatrack/support/hatrack_common.c', - 'src/hatrack/support/mmm.c', - 'src/hatrack/support/counters.c', - 'src/hatrack/support/malloc.c', - 'src/hatrack/hash/crown.c', - 'src/hatrack/hash/dict.c', - 'src/hatrack/hash/xxhash.c', - 'src/hatrack/hash/set.c', - 'src/hatrack/hash/woolhat.c', - 'src/hatrack/array/flexarray.c', - 'src/hatrack/array/zeroarray.c', - 'src/hatrack/queue/queue.c', - 'src/hatrack/queue/hatring.c', - 'src/hatrack/queue/stack.c', - 'src/hatrack/queue/debug.c', - 'src/hatrack/queue/logring.c', - ] - -hat_hashref = ['src/hatrack/hash/ballcap.c', - 'src/hatrack/hash/duncecap.c', - 'src/hatrack/hash/hihat-a.c', - 'src/hatrack/hash/hihat.c', - 'src/hatrack/hash/lohat-a.c', - 'src/hatrack/hash/lohat.c', - 'src/hatrack/hash/newshat.c', - 'src/hatrack/hash/oldhat.c', - 'src/hatrack/hash/refhat.c', - 'src/hatrack/hash/swimcap.c', - 'src/hatrack/hash/tiara.c', - 'src/hatrack/hash/tophat.c', - 'src/hatrack/hash/witchhat.c' +c4m_core = [ + 'src/core/init.c', + 'src/core/gcbase.c', + 'src/core/collect.c', + 'src/core/kargs.c', + 'src/core/exceptions.c', + 'src/core/types.c', + 'src/core/typestore.c', + 'src/core/marshal.c', + 'src/core/literals.c', + 'src/core/attrstore.c', + 'src/core/vm.c', + 'src/core/vmmarshal.c', + 'src/core/ffi.c', + 'src/core/object.c', +] +c4m_adts = [ + 'src/adts/string.c', + 'src/adts/buffer.c', + 'src/adts/dict.c', + 'src/adts/set.c', + 'src/adts/hatlists.c', + 'src/adts/list.c', + 'src/adts/grid.c', + 'src/adts/tree.c', + 'src/adts/numbers.c', + 'src/adts/mixed.c', + 'src/adts/tuple.c', + 'src/adts/ipaddr.c', + 'src/adts/callback.c', + 'src/adts/streams.c', + 'src/adts/flags.c', + 'src/adts/box.c', +] + +c4m_io = [ + 'src/io/ansi.c', + 'src/io/switchboard.c', + 'src/io/subproc.c', + 'src/io/term.c', +] + +c4m_compiler = [ + 'src/compiler/compile.c', + 'src/compiler/lex.c', + 'src/compiler/parse.c', + 'src/compiler/errors.c', + 'src/compiler/scope.c', + 'src/compiler/specs.c', + 'src/compiler/cfg_build.c', + 'src/compiler/cfg.c', + 'src/compiler/ast_utils.c', + 'src/compiler/decl_pass.c', + 'src/compiler/check_pass.c', + 'src/compiler/memory_layout.c', + 'src/compiler/codegen.c', + 'src/compiler/disasm.c', + 'src/compiler/objgen.c', +] + +c4m_util = [ + 'src/util/style.c', + 'src/util/styledb.c', + 'src/util/colors.c', + 'src/util/breaks.c', + 'src/util/hex.c', + 'src/util/tree_pattern.c', + 'src/util/conststr.c', + 'src/util/richlit.c', + 'src/util/format.c', + 'src/util/fptostr.c', + 'src/util/path.c', + 'src/util/watch.c', + 'src/util/wrappers.c', + 'src/util/ctrace.c', + 'src/util/static_config.c', +] + +c4m_crypto = ['src/crypto/sha.c'] + +c4m_src = c4m_core + c4m_adts + c4m_io + c4m_compiler + c4m_util + c4m_crypto + + +hat_primary = [ + 'src/hatrack/support/hatrack_common.c', + 'src/hatrack/support/mmm.c', + 'src/hatrack/support/counters.c', + 'src/hatrack/support/malloc.c', + 'src/hatrack/hash/crown.c', + 'src/hatrack/hash/dict.c', + 'src/hatrack/hash/xxhash.c', + 'src/hatrack/hash/set.c', + 'src/hatrack/hash/woolhat.c', + 'src/hatrack/array/flexarray.c', + 'src/hatrack/array/zeroarray.c', + 'src/hatrack/queue/queue.c', + 'src/hatrack/queue/hatring.c', + 'src/hatrack/queue/stack.c', + 'src/hatrack/queue/debug.c', + 'src/hatrack/queue/logring.c', +] + +hat_hashref = [ + 'src/hatrack/hash/ballcap.c', + 'src/hatrack/hash/duncecap.c', + 'src/hatrack/hash/hihat-a.c', + 'src/hatrack/hash/hihat.c', + 'src/hatrack/hash/lohat-a.c', + 'src/hatrack/hash/lohat.c', + 'src/hatrack/hash/newshat.c', + 'src/hatrack/hash/oldhat.c', + 'src/hatrack/hash/refhat.c', + 'src/hatrack/hash/swimcap.c', + 'src/hatrack/hash/tiara.c', + 'src/hatrack/hash/tophat.c', + 'src/hatrack/hash/witchhat.c', ] hash_test_src = hat_hashref + [ - 'src/tests/hash/test.c', - 'src/tests/hash/default.c', - 'src/tests/hash/performance.c', - 'src/tests/hash/config.c', - 'src/tests/hash/functional.c', - 'src/tests/hash/rand.c', - 'src/tests/hash/testhat.c'] + 'src/tests/hash/test.c', + 'src/tests/hash/default.c', + 'src/tests/hash/performance.c', + 'src/tests/hash/config.c', + 'src/tests/hash/functional.c', + 'src/tests/hash/rand.c', + 'src/tests/hash/testhat.c', +] if not using_osx and not using_glibc - target = build_machine.cpu_family() - quark_files = ['src/quark/quark.c', 'src/quark' / target + '.s'] - hat_primary = hat_primary + quark_files + target = build_machine.cpu_family() + quark_files = ['src/quark/quark.c', 'src/quark' / target + '.s'] + hat_primary = hat_primary + quark_files endif lib_src = c4m_src + hat_primary test_src = ['src/tests/test.c'] -threads = dependency('threads') -math = cc.find_library('m', required : false) -ffi = cc.find_library('ffi', required : true, dirs: meson.current_source_dir() + '/deps/local/') +threads = dependency('threads') +math = cc.find_library('m', required: false) +ffi = cc.find_library( + 'ffi', + required: true +) -crypto = cc.find_library('crypto') -ssl = cc.find_library('ssl') +crypto = cc.find_library('crypto') +ssl = cc.find_library('ssl') unibreak = dependency('libunibreak') utf8proc = dependency('libutf8proc') -deps = [unibreak, utf8proc, threads, ffi, ssl, crypto, backtrace] -opts = [math] +deps = [unibreak, utf8proc, threads, ffi, ssl, crypto, backtrace] +opts = [math] if using_glibc - opts = opts + [cc.find_library('atomic')] + opts = opts + [cc.find_library('atomic')] endif all_deps = deps + opts -libc4m = static_library('con4m', - lib_src, - include_directories : incdir, - dependencies : all_deps, - c_args : c4m_c_args, - link_args: link_args) - - -if get_option('build_con4m_dll') == true - library('con4m-dll', - lib_src, - include_directories : incdir, - dependencies : all_deps, - c_args : c4m_c_args, - link_args: link_args) +libc4m = static_library( + 'con4m', + lib_src, + include_directories: incdir, + dependencies: all_deps, + c_args: c4m_c_args, + link_args: link_args, +) + + +if get_option('build_con4m_dll').enabled() + library( + 'con4m-dll', + lib_src, + include_directories: incdir, + dependencies: all_deps, + c_args: c4m_c_args, + link_args: link_args, + ) endif -executable('c4test', test_src, - include_directories : incdir, - dependencies : [all_deps], - c_args : c_args, - link_args : exe_link_args, - link_with : libc4m) - -if get_option('build_hatrack') == true - libhat = static_library('hatrack', - lib_src, - include_directories : incdir, - c_args : c_args, - link_args : link_args) - - executable('hash', hash_test_src, - include_directories : incdir, - dependencies : all_deps, - link_args : exe_link_args, - link_with : libhat, - c_args : exe_c_args) +executable( + 'c4test', + test_src, + include_directories: incdir, + dependencies: [all_deps], + c_args: c_args, + link_args: exe_link_args, + link_with: libc4m, +) + +if get_option('build_hatrack').enabled() + libhat = static_library( + 'hatrack', + lib_src, + include_directories: incdir, + c_args: c_args, + link_args: link_args, + ) + + executable( + 'hash', + hash_test_src, + include_directories: incdir, + dependencies: all_deps, + link_args: exe_link_args, + link_with: libhat, + c_args: exe_c_args, + ) endif diff --git a/meson.options b/meson.options index a396b227..ae0ca68f 100644 --- a/meson.options +++ b/meson.options @@ -1,6 +1,115 @@ -option('use_asan', type: 'boolean', value: false) -option('use_ubsan', type: 'boolean', value: false) -option('build_hatrack', type: 'boolean', value: false) -option('use_memcheck', type: 'boolean', value: false) -option('build_con4m_dll', type: 'boolean', value: false) -option('show_gc_stats', type: 'boolean', value: true) +option( + 'minimum_render_width', + type: 'integer', + min: 20, + value: 80, + description: 'Render width if not available from terminal', +) + +option( + 'keep_alloc_locations', + type: 'boolean', + value: 'false', + description: 'Allocs keep source file/line info', +) + +option( + 'use_frame_intrinsic', + type: 'feature', + value: 'auto', + description: 'Exposed due to linux issues', +) + +option( + 'build_hatrack', + type: 'feature', + value: 'auto', + description: 'Build the optional libhatrack.a', +) + +option( + 'build_con4m_dll', + type: 'feature', + value: 'auto', + description: 'Build the optional libcon4m.a', +) + +option( + 'use_gc_ptr_hooks', + type: 'feature', + value: 'auto', + description: 'Turn off to scan all memory for pointers, not just likely pointer locations', +) + +option( + 'show_preprocessor_config', + type: 'feature', + value: 'auto', + description: 'Show key compile flags set during compilation.', +) + +option( + 'dev_mode', + type: 'boolean', + value: true, + description: 'Enable (below) debugging options', +) + +option( + 'exception_traces', + type: 'feature', + value: 'auto', + description: 'Enable C stack traces on internal exceptions if possible', +) + +option( + 'show_gc_stats', + type: 'feature', + value: 'auto', + description: 'Print stats after collections', +) + +option( + 'use_memcheck', + type: 'combo', + choices: ['off', 'on', 'strict'], + value: 'off', + description: 'Enable internal lightweight heap checks', +) + +option( + 'gc_tracing', + type: 'combo', + choices: ['off', 'minimal', 'full'], + value: 'off', + description: 'Print GC disagnostics to console', +) + +option( + 'warn_on_zero_allocs', + type: 'boolean', + value: false, + description: 'Give console warning to see 0-length allocs', +) + +option( + 'vm_debug', + type: 'combo', + choices: ['default on', 'default off', 'always off'], + value: 'always off', + description: 'At runtime, show instructions and stack', +) + +option( + 'use_asan', + type: 'feature', + value: 'auto', + description: 'Use address sanitizer', +) + +option( + 'use_ubsan', + type: 'feature', + value: 'auto', + description: 'Use undefined behavior sanitizer', +) diff --git a/src/README.md b/src/README.md new file mode 100644 index 00000000..bfc02ccb --- /dev/null +++ b/src/README.md @@ -0,0 +1,21 @@ +# Con4m Source directory + +Currently, this directory is all C code. Con4m code lives in `/sys` or +`/test`. + +Directories under this one: + +- `compiler` Is the Con4m compiler. +- `core` Is the core runtime, including the the type system, + the garbage collector and the VM. +- `adts` Contains the base data types used throughout; most of them + are exported to the language. +- `io` is the home of terminal and network code. +- `util` contains misc utilities used by the implementation. +- `hatrack` is a library of lock-free data structures, primarily hash + tables. This is core to Con4m's dictionary and set implementations, + and eventually more of the data types there will get integrated. +- `quark` is a tiny shim for providing core atomic ops in environments + where the linked standard library won't have them (this is really + just MUSL right now). +- `tests` is where all tests go, for both Con4m and Hatrack. diff --git a/src/adts/README.md b/src/adts/README.md new file mode 100644 index 00000000..3d109cd7 --- /dev/null +++ b/src/adts/README.md @@ -0,0 +1,46 @@ +# ADTs-- Abstract Data Types + +This directory contains C implementations for data types provided by +Con4m. A few things primarily live in Hatrack-- the set implementation +and the dictionary implementation. What's in this directory is minor +con4m-specific stuff, like integration with the garbage collector. + +Current status of data types: + +1. Strings. Con4m strings are meant to be non-mutable. The API +supports both UTF-8 and UTF-32 encodings (I'm considering having +strings hang on to both representations if the string is used in a way +that requires a conversion). Additionally, strings carry style +information out-of-band, that is applied when rendering (generally via +the ascii module in the io directory). These are available through +Con4m itself. + +The core of the implementation is in `strings.c`, but a bunch of +related code lives in the `util` subdirectory, like code to support +'rich' text literals (available using a variety of lit modifiers). + +2. Grids. Grids build on top of strings to make it easy to do things +like tables, flows, etc. These are meant to be first class citizens in +Con4m, and currently have some functionaility exposed. + +3. A buffer type, available from Con4m. + +4. A stream type, not yet exposed (but will be). + +5. A `callback` type, which probably doesn't work yet, but should be +exposed. + +6. A tuple type, exposed to the language. + +7. A tree type, not yet exposed. + +8. Standard numeric types. Currently, we lack 16 bit and 128 bit +types. `char` in Con4m is a 32 bit int. + +9. A bitfield, not yet exposed. + +10. An internal `box` type. Eventually, the `mixed` type will be +exposed, but it's not close to done. + +11. Some light hatrack wrappers. `set` and `dict` are well exposed, +but things like `rings` are not. diff --git a/src/con4m/box.c b/src/adts/box.c similarity index 100% rename from src/con4m/box.c rename to src/adts/box.c diff --git a/src/con4m/buffer.c b/src/adts/buffer.c similarity index 100% rename from src/con4m/buffer.c rename to src/adts/buffer.c diff --git a/src/con4m/callback.c b/src/adts/callback.c similarity index 100% rename from src/con4m/callback.c rename to src/adts/callback.c diff --git a/src/con4m/dict.c b/src/adts/dict.c similarity index 100% rename from src/con4m/dict.c rename to src/adts/dict.c diff --git a/src/con4m/flags.c b/src/adts/flags.c similarity index 100% rename from src/con4m/flags.c rename to src/adts/flags.c diff --git a/src/con4m/grid.c b/src/adts/grid.c similarity index 100% rename from src/con4m/grid.c rename to src/adts/grid.c diff --git a/src/con4m/hatlists.c b/src/adts/hatlists.c similarity index 100% rename from src/con4m/hatlists.c rename to src/adts/hatlists.c diff --git a/src/con4m/ipaddr.c b/src/adts/ipaddr.c similarity index 100% rename from src/con4m/ipaddr.c rename to src/adts/ipaddr.c diff --git a/src/con4m/list.c b/src/adts/list.c similarity index 100% rename from src/con4m/list.c rename to src/adts/list.c diff --git a/src/con4m/mixed.c b/src/adts/mixed.c similarity index 100% rename from src/con4m/mixed.c rename to src/adts/mixed.c diff --git a/src/con4m/numbers.c b/src/adts/numbers.c similarity index 100% rename from src/con4m/numbers.c rename to src/adts/numbers.c diff --git a/src/con4m/set.c b/src/adts/set.c similarity index 100% rename from src/con4m/set.c rename to src/adts/set.c diff --git a/src/con4m/streams.c b/src/adts/streams.c similarity index 100% rename from src/con4m/streams.c rename to src/adts/streams.c diff --git a/src/con4m/string.c b/src/adts/string.c similarity index 100% rename from src/con4m/string.c rename to src/adts/string.c diff --git a/src/con4m/tree.c b/src/adts/tree.c similarity index 100% rename from src/con4m/tree.c rename to src/adts/tree.c diff --git a/src/con4m/tuple.c b/src/adts/tuple.c similarity index 100% rename from src/con4m/tuple.c rename to src/adts/tuple.c diff --git a/src/con4m/compiler/ast_utils.c b/src/compiler/ast_utils.c similarity index 100% rename from src/con4m/compiler/ast_utils.c rename to src/compiler/ast_utils.c diff --git a/src/con4m/compiler/cfg.c b/src/compiler/cfg.c similarity index 100% rename from src/con4m/compiler/cfg.c rename to src/compiler/cfg.c diff --git a/src/con4m/compiler/cfg_build.c b/src/compiler/cfg_build.c similarity index 100% rename from src/con4m/compiler/cfg_build.c rename to src/compiler/cfg_build.c diff --git a/src/con4m/compiler/check_pass.c b/src/compiler/check_pass.c similarity index 100% rename from src/con4m/compiler/check_pass.c rename to src/compiler/check_pass.c diff --git a/src/con4m/compiler/codegen.c b/src/compiler/codegen.c similarity index 100% rename from src/con4m/compiler/codegen.c rename to src/compiler/codegen.c diff --git a/src/con4m/compiler/compile.c b/src/compiler/compile.c similarity index 100% rename from src/con4m/compiler/compile.c rename to src/compiler/compile.c diff --git a/src/con4m/compiler/decl_pass.c b/src/compiler/decl_pass.c similarity index 100% rename from src/con4m/compiler/decl_pass.c rename to src/compiler/decl_pass.c diff --git a/src/con4m/compiler/disasm.c b/src/compiler/disasm.c similarity index 99% rename from src/con4m/compiler/disasm.c rename to src/compiler/disasm.c index 949df24d..50a5e2b7 100644 --- a/src/con4m/compiler/disasm.c +++ b/src/compiler/disasm.c @@ -53,8 +53,10 @@ get_bool_label(c4m_zop_t op) return c4m_new_utf8("currently unused"); case C4M_ZLoadFromView: return c4m_new_utf8("load kv pair"); +#ifdef C4M_VM_DEBUG case C4M_ZDebug: return c4m_new_utf8("set debug"); +#endif default: c4m_unreachable(); } diff --git a/src/con4m/compiler/errors.c b/src/compiler/errors.c similarity index 100% rename from src/con4m/compiler/errors.c rename to src/compiler/errors.c diff --git a/src/con4m/compiler/lex.c b/src/compiler/lex.c similarity index 100% rename from src/con4m/compiler/lex.c rename to src/compiler/lex.c diff --git a/src/con4m/compiler/memory_layout.c b/src/compiler/memory_layout.c similarity index 100% rename from src/con4m/compiler/memory_layout.c rename to src/compiler/memory_layout.c diff --git a/src/con4m/compiler/objgen.c b/src/compiler/objgen.c similarity index 100% rename from src/con4m/compiler/objgen.c rename to src/compiler/objgen.c diff --git a/src/con4m/compiler/parse.c b/src/compiler/parse.c similarity index 100% rename from src/con4m/compiler/parse.c rename to src/compiler/parse.c diff --git a/src/con4m/compiler/scope.c b/src/compiler/scope.c similarity index 100% rename from src/con4m/compiler/scope.c rename to src/compiler/scope.c diff --git a/src/con4m/compiler/specs.c b/src/compiler/specs.c similarity index 100% rename from src/con4m/compiler/specs.c rename to src/compiler/specs.c diff --git a/src/con4m/attrstore.c b/src/core/attrstore.c similarity index 100% rename from src/con4m/attrstore.c rename to src/core/attrstore.c diff --git a/src/con4m/collect.c b/src/core/collect.c similarity index 98% rename from src/con4m/collect.c rename to src/core/collect.c index 2b547543..786fcfc9 100644 --- a/src/con4m/collect.c +++ b/src/core/collect.c @@ -32,9 +32,10 @@ static void process_worklist(c4m_collection_ctx *); static worklist_t * c4m_alloc_collection_worklist(c4m_arena_t *fromspace) { - int num_records = 1 << 14; - int alloc_len = num_records * sizeof(worklist_item) + sizeof(worklist_t); - alloc_len = c4m_round_up_to_given_power_of_2(getpagesize(), + int n = (1 << (64 - __builtin_clzll(fromspace->largest_alloc))); + + int alloc_len = n * sizeof(worklist_item) + sizeof(worklist_t); + alloc_len = c4m_round_up_to_given_power_of_2(getpagesize(), alloc_len); worklist_t *result = mmap(NULL, @@ -45,8 +46,8 @@ c4m_alloc_collection_worklist(c4m_arena_t *fromspace) 0); result->write_ix = 0; result->read_ix = 0; - result->ring_size = num_records; - result->mod = num_records - 1; + result->ring_size = n; + result->mod = n - 1; result->alloc_len = alloc_len; return result; @@ -117,7 +118,7 @@ c4m_get_alloc_counter() #endif #ifdef C4M_GC_FULL_TRACE -int c4m_gc_trace_on = 1; +int c4m_gc_trace_on = C4M_GC_FULL_TRACE_DEFAULT; #endif #ifdef C4M_FULL_MEMCHECK @@ -142,12 +143,13 @@ c4m_get_stack_scan_region(uint64_t *top, uint64_t *bottom) pthread_getattr_np(self, &attrs); + size_t size; + + pthread_attr_getstack(&attrs, (void **)&addr, &size); + #ifdef C4M_USE_FRAME_INTRINSIC - pthread_attr_getstackaddr(&attrs, (void **)&addr); *bottom = (uint64_t)__builtin_frame_address(0); #else - size_t size; - pthread_attr_getstack(&attrs, (void **)&addr, &size); *bottom = (uint64_t)addr + size; #endif @@ -203,7 +205,7 @@ prep_allocation(c4m_alloc_hdr *old, c4m_arena_t *new_arena) c4m_alloc_hdr *res; c4m_arena_t *arena = new_arena; -#if defined(C4M_GC_STATS) || defined(C4M_DEBUG) +#if defined(C4M_ADD_ALLOC_LOC_INFO) #define TRACE_DEBUG_ARGS , debug_file, debug_ln char *debug_file = old->alloc_file; @@ -309,7 +311,7 @@ get_header(c4m_collection_ctx *ctx, void *ptr) c4m_alloc_hdr *result = (c4m_alloc_hdr *)p; -#if defined(C4M_GC_STATS) && (C4M_GCT_OBJ != 0) +#if defined(C4M_ADD_ALLOC_LOC_INFO) && (C4M_GCT_OBJ != 0) if (result->con4m_obj) { c4m_base_obj_t *obj = (c4m_base_obj_t *)result->data; @@ -382,7 +384,11 @@ scan_allocation(c4m_collection_ctx *ctx, c4m_alloc_hdr *hdr) c4m_mem_scan_fn scanner = hdr->scan_fn; void *contents; +#ifdef C4M_USE_GC_HOOKS if ((void *)scanner == C4M_GC_SCAN_ALL) { +#else + if ((void *)scanner != C4M_GC_SCAN_NONE) { +#endif while (p < end) { ASAN_UNPOISON_MEMORY_REGION(p, 8); contents = *p; @@ -628,7 +634,6 @@ raw_trace(c4m_collection_ctx *ctx) (((char *)ctx->to_space->heap_end) - (char *)ctx->to_space->data)); ctx->worklist = c4m_alloc_collection_worklist(cur); - c4m_get_stack_scan_region((uint64_t *)&stack_top, (uint64_t *)&stack_bottom); diff --git a/src/con4m/exceptions.c b/src/core/exceptions.c similarity index 100% rename from src/con4m/exceptions.c rename to src/core/exceptions.c diff --git a/src/con4m/ffi.c b/src/core/ffi.c similarity index 100% rename from src/con4m/ffi.c rename to src/core/ffi.c diff --git a/src/con4m/gcbase.c b/src/core/gcbase.c similarity index 97% rename from src/con4m/gcbase.c rename to src/core/gcbase.c index 02fbc792..790123e5 100644 --- a/src/con4m/gcbase.c +++ b/src/core/gcbase.c @@ -12,17 +12,6 @@ thread_local uint64_t c4m_total_alloced = 0; thread_local uint32_t c4m_total_allocs = 0; #endif -#ifdef C4M_FULL_MEMCHECK -#ifndef C4M_MEMCHECK_RING_SZ -// Must be a power of 2. -#define C4M_MEMCHECK_RING_SZ 128 -#endif -#if C4M_MEMCHECK_RING_SZ != 0 -#define C4M_USE_RING -#else -#undef C4M_USE_RING -#endif - uint64_t c4m_end_guard; #ifdef C4M_USE_RING @@ -33,8 +22,6 @@ static thread_local unsigned int ring_head = 0; static thread_local unsigned int ring_tail = 0; #endif -#endif // C4M_FULL_MEMCHECK - static c4m_set_t *external_holds = NULL; static pthread_key_t c4m_thread_key; @@ -101,7 +88,7 @@ c4m_gc_heap_stats(uint64_t *used, uint64_t *available, uint64_t *total) } } -#ifdef HATRACK_ALLOC_PASS_LOCATION +#ifdef C4M_ADD_ALLOC_LOC_INFO void * c4m_gc_malloc_wrapper(size_t size, void *arg, char *file, int line) { @@ -370,7 +357,7 @@ c4m_new_arena(size_t num_words, hatrack_zarray_t *roots) return new_arena; } -#if defined(C4M_GC_STATS) || defined(C4M_DEBUG) +#if defined(C4M_ADD_ALLOC_LOC_INFO) #define TRACE_DEBUG_ARGS , debug_file, debug_ln void * @@ -393,7 +380,7 @@ _c4m_gc_raw_alloc(size_t len, c4m_mem_scan_fn scan_fn) false TRACE_DEBUG_ARGS); } -#if defined(C4M_GC_STATS) || defined(C4M_DEBUG) +#if defined(C4M_ADD_ALLOC_LOC_INFO) void * _c4m_gc_raw_alloc_with_finalizer(size_t len, c4m_mem_scan_fn scan_fn, @@ -423,7 +410,7 @@ c4m_gc_resize(void *ptr, size_t len) assert(hdr->guard = c4m_gc_guard); -#if defined(C4M_GC_STATS) || defined(C4M_DEBUG) +#if defined(C4M_ADD_ALLOC_LOC_INFO) char *debug_file = hdr->alloc_file; int debug_ln = hdr->alloc_line; #endif @@ -480,7 +467,7 @@ c4m_delete_arena(c4m_arena_t *arena) return; } -#ifdef C4M_GC_STATS +#ifdef C4M_ADD_ALLOC_LOC_INFO void _c4m_arena_register_root(c4m_arena_t *arena, void *ptr, @@ -532,7 +519,7 @@ c4m_find_alloc(void *ptr) return NULL; } -#if defined(C4M_GC_STATS) || defined(C4M_DEBUG) +#if defined(C4M_ADD_ALLOC_LOC_INFO) c4m_utf8_t * c4m_gc_alloc_info(void *addr, int *line) { @@ -551,9 +538,7 @@ c4m_gc_alloc_info(void *addr, int *line) return c4m_new_utf8(h->alloc_file); } -#endif -#ifdef C4M_GC_STATS void _c4m_gc_register_root(void *ptr, uint64_t num_words, char *f, int l) { @@ -614,7 +599,7 @@ memcheck_process_ring() } #endif -#if defined(C4M_GC_STATS) || defined(C4M_DEBUG) +#if defined(C4M_ADD_ALLOC_LOC_INFO) void * c4m_alloc_from_arena(c4m_arena_t **arena_ptr, size_t len, @@ -636,7 +621,7 @@ c4m_alloc_from_arena(c4m_arena_t **arena_ptr, len += sizeof(c4m_alloc_hdr); -#ifdef C4M_DEBUG +#if defined(C4M_DEBUG) && defined(C4M_ADD_ALLOC_LOC_INFO) _c4m_watch_scan(file, line); #endif @@ -660,7 +645,7 @@ c4m_alloc_from_arena(c4m_arena_t **arena_ptr, next = (c4m_alloc_hdr *)&(raw->data[wordlen]); if (((uint64_t *)next) > arena->heap_end) { arena->grow_next = true; -#if defined(C4M_GC_STATS) || defined(C4M_DEBUG) +#if defined(C4M_ADD_ALLOC_LOC_INFO) return c4m_alloc_from_arena(arena_ptr, len, scan_fn, diff --git a/src/con4m/init.c b/src/core/init.c similarity index 100% rename from src/con4m/init.c rename to src/core/init.c diff --git a/src/con4m/kargs.c b/src/core/kargs.c similarity index 94% rename from src/con4m/kargs.c rename to src/core/kargs.c index bf5e0b2c..521afbb2 100644 --- a/src/con4m/kargs.c +++ b/src/core/kargs.c @@ -10,15 +10,6 @@ #include "con4m.h" -#ifndef C4M_MAX_KARGS_NESTING_DEPTH -// Must be a power of two. -#define C4M_MAX_KARGS_NESTING_DEPTH 32 -#endif - -#ifndef C4M_MAX_KEYWORD_SIZE -#define C4M_MAX_KEYWORD_SIZE 32 -#endif - static thread_local c4m_karg_info_t *kcache[C4M_MAX_KARGS_NESTING_DEPTH]; static thread_local int kargs_next_entry = -1; diff --git a/src/con4m/literals.c b/src/core/literals.c similarity index 100% rename from src/con4m/literals.c rename to src/core/literals.c diff --git a/src/con4m/marshal.c b/src/core/marshal.c similarity index 100% rename from src/con4m/marshal.c rename to src/core/marshal.c diff --git a/src/con4m/object.c b/src/core/object.c similarity index 99% rename from src/con4m/object.c rename to src/core/object.c index bc53c360..3fcf17e4 100644 --- a/src/con4m/object.c +++ b/src/core/object.c @@ -433,7 +433,7 @@ _c4m_new(c4m_type_t *type, ...) c4m_vtable_entry init_fn = tinfo->vtable->methods[C4M_BI_CONSTRUCTOR]; c4m_vtable_entry scan_fn = tinfo->vtable->methods[C4M_BI_GC_MAP]; -#if defined(C4M_GC_STATS) || defined(C4M_DEBUG) +#if defined(C4M_ADD_ALLOC_LOC_INFO) if (tinfo->vtable->methods[C4M_BI_FINALIZER] == NULL) { obj = _c4m_gc_raw_alloc(alloc_len, (c4m_mem_scan_fn)scan_fn, diff --git a/src/con4m/types.c b/src/core/types.c similarity index 100% rename from src/con4m/types.c rename to src/core/types.c diff --git a/src/con4m/typestore.c b/src/core/typestore.c similarity index 100% rename from src/con4m/typestore.c rename to src/core/typestore.c diff --git a/src/con4m/vm.c b/src/core/vm.c similarity index 99% rename from src/con4m/vm.c rename to src/core/vm.c index cc5ea498..306c934c 100644 --- a/src/con4m/vm.c +++ b/src/core/vm.c @@ -154,9 +154,9 @@ c4m_vm_exception(c4m_vmthread_t *tstate, c4m_exception_t *exc) #ifdef C4M_OMIT_UNDERFLOW_CHECKS #define STACK_REQUIRE_VALUES(_n) #else -#define STACK_REQUIRE_VALUES(_n) \ - if (tstate->sp > &tstate->stack[STACK_SIZE - (_n)]) { \ - C4M_CRAISE("stack underflow"); \ +#define STACK_REQUIRE_VALUES(_n) \ + if (tstate->sp > &tstate->stack[C4M_STACK_SIZE - (_n)]) { \ + C4M_CRAISE("stack underflow"); \ } #endif @@ -283,7 +283,7 @@ c4m_vmframe_push(c4m_vmthread_t *tstate, c4m_zfn_info_t *target_func, int32_t target_lineno) { - if (MAX_CALL_DEPTH == tstate->num_frames) { + if (C4M_MAX_CALL_DEPTH == tstate->num_frames) { C4M_CRAISE("maximum call depth reached"); } @@ -839,7 +839,7 @@ c4m_vm_runloop(c4m_vmthread_t *tstate_arg) "FP@{:x}; a = {}; i = {}; m = {})"; if (debug_on && i->op != C4M_ZNop) { - int num_stack_items = &tstate->stack[STACK_SIZE] - tstate->sp; + int num_stack_items = &tstate->stack[C4M_STACK_SIZE] - tstate->sp; printf("stack has %d items on it: ", num_stack_items); for (int i = 0; i < num_stack_items; i++) { if (&tstate->sp[i] == tstate->fp) { @@ -1738,7 +1738,7 @@ c4m_vmthread_new(c4m_vm_t *vm) void c4m_vmthread_reset(c4m_vmthread_t *tstate) { - tstate->sp = &tstate->stack[STACK_SIZE]; + tstate->sp = &tstate->stack[C4M_STACK_SIZE]; tstate->fp = tstate->sp; tstate->pc = 0; tstate->num_frames = 1; diff --git a/src/con4m/vmmarshal.c b/src/core/vmmarshal.c similarity index 100% rename from src/con4m/vmmarshal.c rename to src/core/vmmarshal.c diff --git a/src/crypto/README.md b/src/crypto/README.md new file mode 100644 index 00000000..0d71695f --- /dev/null +++ b/src/crypto/README.md @@ -0,0 +1,4 @@ +# Cryptography + +There's not much here yet; we use SHA-256 as a building block in +places. Requires OpenSSL. \ No newline at end of file diff --git a/src/con4m/crypto/sha.c b/src/crypto/sha.c similarity index 100% rename from src/con4m/crypto/sha.c rename to src/crypto/sha.c diff --git a/src/con4m/ansi.c b/src/io/ansi.c similarity index 100% rename from src/con4m/ansi.c rename to src/io/ansi.c diff --git a/src/con4m/subproc.c b/src/io/subproc.c similarity index 100% rename from src/con4m/subproc.c rename to src/io/subproc.c diff --git a/src/con4m/switchboard.c b/src/io/switchboard.c similarity index 100% rename from src/con4m/switchboard.c rename to src/io/switchboard.c diff --git a/src/con4m/term.c b/src/io/term.c similarity index 100% rename from src/con4m/term.c rename to src/io/term.c diff --git a/src/con4m/breaks.c b/src/util/breaks.c similarity index 100% rename from src/con4m/breaks.c rename to src/util/breaks.c diff --git a/src/con4m/colors.c b/src/util/colors.c similarity index 100% rename from src/con4m/colors.c rename to src/util/colors.c diff --git a/src/con4m/conststr.c b/src/util/conststr.c similarity index 100% rename from src/con4m/conststr.c rename to src/util/conststr.c diff --git a/src/con4m/ctrace.c b/src/util/ctrace.c similarity index 99% rename from src/con4m/ctrace.c rename to src/util/ctrace.c index baa749cb..2958305e 100644 --- a/src/con4m/ctrace.c +++ b/src/util/ctrace.c @@ -1,6 +1,6 @@ #include "con4m.h" -#ifdef BACKTRACE_SUPPORTED +#ifdef C4M_BACKTRACE_SUPPORTED static void c4m_bt_err(void *data, const char *msg, int errnum) diff --git a/src/con4m/format.c b/src/util/format.c similarity index 100% rename from src/con4m/format.c rename to src/util/format.c diff --git a/src/con4m/fptostr.c b/src/util/fptostr.c similarity index 100% rename from src/con4m/fptostr.c rename to src/util/fptostr.c diff --git a/src/con4m/hex.c b/src/util/hex.c similarity index 100% rename from src/con4m/hex.c rename to src/util/hex.c diff --git a/src/con4m/path.c b/src/util/path.c similarity index 99% rename from src/con4m/path.c rename to src/util/path.c index 9f765eb2..4a3d8a87 100644 --- a/src/con4m/path.c +++ b/src/util/path.c @@ -461,7 +461,7 @@ c4m_app_path() snprintf(proc_path, PATH_MAX, "/proc/%d/exe", getpid()); readlink(proc_path, buf, PATH_MAX); - return c4m_new_utf8(proc_path); + return c4m_new_utf8(buf); } #elif defined(__MACH__) c4m_utf8_t * diff --git a/src/con4m/richlit.c b/src/util/richlit.c similarity index 100% rename from src/con4m/richlit.c rename to src/util/richlit.c diff --git a/src/con4m/static/colors.c b/src/util/static/colors.c similarity index 100% rename from src/con4m/static/colors.c rename to src/util/static/colors.c diff --git a/src/con4m/static/richlit.c b/src/util/static/richlit.c similarity index 100% rename from src/con4m/static/richlit.c rename to src/util/static/richlit.c diff --git a/src/util/static_config.c b/src/util/static_config.c new file mode 100644 index 00000000..3627162e --- /dev/null +++ b/src/util/static_config.c @@ -0,0 +1,140 @@ +#include "con4m.h" + +#ifdef C4M_SHOW_PREPROC_CONFIG + +#ifdef C4M_DEV +#warning "C4M_DEV is ON (development mode)" +#else +#warning "C4M_DEV is OFF (no development mode; required for all tests)" +#endif + +#ifdef C4M_DEBUG +#warning "C4M_DEBUG is ON (C stack traces on thrown exceptions, watchpoints, etc)" +#else +#warning "C4M_DEBUG is OFF (no C stack traces on thrown exceptions)" +#ifndef C4M_DEV +#warning "enabling requires C4M_DEV" +#endif +#endif + +// Adds c4m_end_guard field. +#ifdef C4M_FULL_MEMCHECK +#warning "C4M_FULL_MEMCHECK is ON (memory guards around each allocation checked at GC collect)" + +#ifdef C4M_STRICT_MEMCHECK +#warning "C4M_STRICT_MEMCHECK is ON (abort on any memcheck error)" +#else +#warning "C4M_STRICT_MEMCHECK is OFF (don't abort on any memcheck error)" +#endif +#else +#warning "C4M_FULL_MEMCHECK is OFF (no memory guards around each allocation)" +#ifndef C4M_DEV +#warning "enabling requires C4M_DEV" +#endif +#endif + +#ifdef C4M_TRACE_GC +#warning "C4M_TRACE_GC is ON (garbage collection tracing is enabled)" +#else +#warning "C4M_TRACE_GC is OFF (garbage collection tracing is disabled)" +#ifndef C4M_DEV +#warning "enabling requires C4M_DEV" +#endif +#endif + +#ifdef C4M_USE_FRAME_INTRINSIC +#warning "C4M_USE_FRAME_INSTRINSIC is ON" +#else +#warning "C4M_USE_FRAME_INSTRINSIC is OFF" +#endif + +#ifdef C4M_VM_DEBUG +#warning "C4M_VM_DEBUG is ON (virtual machine debugging is enabled)" + +#if defined(C4M_VM_DEBUG_DEFAULT) +#if C4M_VM_DEBUG_DEFAULT == true +#define __vm_debug_default +#endif +#endif + +#ifdef __vm_debug_default +#warning "C4M_VM_DEBUG_DEFAULT is true (VM debugging on by default)" +#else +#warning "VM debugging is off unless a debug instruction turns it on." +#endif + +#else +#warning "C4M_VM_DEBUG is ON (virtual machine debugging is disabled)" +#ifndef C4M_DEV +#warning "enabling requires C4M_DEV" +#endif +#endif + +#if defined(__has_feature) +#if __has_feature(address_sanitizer) +#define __c4m_have_asan__ +#endif +#else +#ifdef HAS_ADDRESS_SANITIZER +#define __c4m_have_asan__ +#endif +#endif + +#ifdef __c4m_have_asan__ +#warning "ADDRESS_SANTITIZER is ON (llvm memory checking enabled)" +#else +#warning "ADDRESS_SANTITIZER is OFF (llvm memory checking disabled)" +#ifndef C4M_DEV +#warning "enabling requires C4M_DEV" +#endif +#endif + +#ifdef C4M_OMIT_UNDERFLOW_CHECKS +#warning "C4M_OMIT_UNDERFLOW_CHECKS is ON (Avoid some UBSAN falses)" +#else +#warning "C4M_OMIT_UNDERFLOW_CHECKS is OFF (Will see some UBSAN falses)" +#endif + +#ifdef C4M_WARN_ON_ZERO_ALLOCS +#warning "C4M_WARN_ON_ZERO_ALLOCS is ON (Identify zero-length allocations)" +#else +#warning "C4M_WARN_ON_ZERO_ALLOCS is OFF (No spam about 0-length allocs)" +#ifndef C4M_DEV +#warning "enabling requires C4M_DEV" +#endif +#endif + +#ifdef C4M_GC_SHOW_COLLECT_STACK_TRACES +#warning "C4M_GC_SHOW_COLLECT_STACK_TRACES is ON (Show C stack traces at every garbage collection invocation." +#else +#warning "C4M_GC_SHOW_COLLECT_STACK_TRACES is OFF (no C stack traces for GC collections)" +#ifndef C4M_DEV +#warning "enabling requires C4M_DEV" +#endif +#endif + +#ifdef C4M_PARANOID_STACK_SCAN +#warning "C4M_PARANOID_STACK_SCAN is ON (Find slow, unaligned pointers)" +#else +#warning "C4M_PARANOID_STACK_SCAN is OFF (Does not look for unaligned pointers; this is slow and meant for debugging)" +#endif + +#ifdef C4M_MIN_RENDER_WIDTH +#warning "C4M_MIN_RENDER_WIDTH is: " #C4M_MIN_RENDER_WIDTH +#else +#warning "C4M_MIN_RENDER_WIDTH is not set." +#endif + +#ifdef _GNU_SOURCE +#warning "_GNU_SOURCE is ON (gnu stdlib)" +#else +#warning "_GNU_SOURCE is OFF (not a gnu stdlib)." +#endif + +#ifdef HAVE_PTY_H +#warning "HAVE_PTY_H is ON (forkpty is available)" +#else +#warning "HAVE_PTY_H is OFF (forkpty is NOT available)" +#endif + +#endif diff --git a/src/con4m/style.c b/src/util/style.c similarity index 100% rename from src/con4m/style.c rename to src/util/style.c diff --git a/src/con4m/styledb.c b/src/util/styledb.c similarity index 99% rename from src/con4m/styledb.c rename to src/util/styledb.c index 7257559f..468d2336 100644 --- a/src/con4m/styledb.c +++ b/src/util/styledb.c @@ -552,6 +552,9 @@ void c4m_layer_styles(const c4m_render_style_t *base, c4m_render_style_t *cur) { // Anything not explicitly set in 'cur' will get set from base. + if (!cur || !base) { + return; + } if (!(cur->base_style & C4M_STY_FG) && base->base_style & C4M_STY_FG) { c4m_set_render_style_fg_color(cur, base->base_style & ~C4M_STY_CLEAR_FG); diff --git a/src/con4m/tree_pattern.c b/src/util/tree_pattern.c similarity index 100% rename from src/con4m/tree_pattern.c rename to src/util/tree_pattern.c diff --git a/src/con4m/watch.c b/src/util/watch.c similarity index 100% rename from src/con4m/watch.c rename to src/util/watch.c diff --git a/src/con4m/wrappers.c b/src/util/wrappers.c similarity index 100% rename from src/con4m/wrappers.c rename to src/util/wrappers.c