├── .gitignore ├── LICENSE ├── README.md ├── build.zig ├── deps ├── github.com │ └── ivmai │ │ └── bdwgc │ │ ├── .appveyor.yml │ │ ├── .gitattributes │ │ ├── .gitignore │ │ ├── .travis.yml │ │ ├── AUTHORS │ │ ├── CMakeLists.txt │ │ ├── ChangeLog │ │ ├── Config.cmake.in │ │ ├── LICENSE │ │ ├── Makefile.am │ │ ├── Makefile.direct │ │ ├── NT_MAKEFILE │ │ ├── README.md │ │ ├── WCC_MAKEFILE │ │ ├── allchblk.c │ │ ├── alloc.c │ │ ├── autogen.sh │ │ ├── backgraph.c │ │ ├── bdw-gc.pc.in │ │ ├── blacklst.c │ │ ├── checksums.c │ │ ├── configure.ac │ │ ├── cord │ │ ├── cord.am │ │ ├── cordbscs.c │ │ ├── cordprnt.c │ │ ├── cordxtra.c │ │ └── tests │ │ │ ├── cordtest.c │ │ │ ├── de.c │ │ │ ├── de_cmds.h │ │ │ ├── de_win.c │ │ │ ├── de_win.h │ │ │ └── de_win.rc │ │ ├── darwin_stop_world.c │ │ ├── dbg_mlc.c │ │ ├── digimars.mak │ │ ├── docs │ │ ├── README.autoconf │ │ ├── README.cmake │ │ ├── README.cords │ │ ├── README.environment │ │ ├── README.macros │ │ ├── debugging.md │ │ ├── faq.md │ │ ├── finalization.md │ │ ├── gcdescr.md │ │ ├── gcinterface.md │ │ ├── leak.md │ │ ├── overview.md │ │ ├── platforms │ │ │ ├── README.aix │ │ │ ├── README.amiga │ │ │ ├── README.arm_cross │ │ │ ├── README.darwin │ │ │ ├── README.dgux386 │ │ │ ├── README.emscripten │ │ │ ├── README.ews4800 │ │ │ ├── README.hp │ │ │ ├── README.linux │ │ │ ├── README.mac │ │ │ ├── README.os2 │ │ │ ├── README.sgi │ │ │ ├── README.solaris2 │ │ │ ├── README.symbian │ │ │ ├── README.uts │ │ │ ├── README.win32 │ │ │ └── README.win64 │ │ ├── porting.md │ │ ├── scale.md │ │ ├── simple_example.md │ │ └── tree.md │ │ ├── dyn_load.c │ │ ├── extra │ │ ├── AmigaOS.c │ │ ├── MacOS.c │ │ ├── Mac_files │ │ │ ├── MacOS_config.h │ │ │ ├── dataend.c │ │ │ └── datastart.c │ │ ├── gc.c │ │ ├── msvc_dbg.c │ │ ├── pcr_interface.c │ │ ├── real_malloc.c │ │ ├── symbian.cpp │ │ └── symbian │ │ │ ├── global_end.cpp │ │ │ ├── global_start.cpp │ │ │ └── init_global_static_roots.cpp │ │ ├── finalize.c │ │ ├── fnlz_mlc.c │ │ ├── gc.man │ │ ├── gc_badalc.cc │ │ ├── gc_badalc.cpp │ │ ├── gc_cpp.cc │ │ ├── gc_cpp.cpp │ │ ├── gc_dlopen.c │ │ ├── gcj_mlc.c │ │ ├── headers.c │ │ ├── ia64_save_regs_in_stack.s │ │ ├── include │ │ ├── gc.h │ │ ├── gc │ │ │ ├── cord.h │ │ │ ├── cord_pos.h │ │ │ ├── ec.h │ │ │ ├── gc.h │ │ │ ├── gc_allocator.h │ │ │ ├── gc_backptr.h │ │ │ ├── gc_config_macros.h │ │ │ ├── gc_cpp.h │ │ │ ├── gc_disclaim.h │ │ │ ├── gc_gcj.h │ │ │ ├── gc_inline.h │ │ │ ├── gc_mark.h │ │ │ ├── gc_pthread_redirects.h │ │ │ ├── gc_tiny_fl.h │ │ │ ├── gc_typed.h │ │ │ ├── gc_version.h │ │ │ ├── javaxfc.h │ │ │ └── leak_detector.h │ │ ├── gc_cpp.h │ │ ├── include.am │ │ └── private │ │ │ ├── darwin_semaphore.h │ │ │ ├── dbg_mlc.h │ │ │ ├── gc_alloc_ptrs.h │ │ │ ├── gc_atomic_ops.h │ │ │ ├── gc_hdrs.h │ │ │ ├── gc_locks.h │ │ │ ├── gc_pmark.h │ │ │ ├── gc_priv.h │ │ │ ├── gcconfig.h │ │ │ ├── pthread_support.h │ │ │ ├── specific.h │ │ │ └── thread_local_alloc.h │ │ ├── m4 │ │ └── gc_set_version.m4 │ │ ├── mach_dep.c │ │ ├── malloc.c │ │ ├── mallocx.c │ │ ├── mark.c │ │ ├── mark_rts.c │ │ ├── misc.c │ │ ├── new_hblk.c │ │ ├── obj_map.c │ │ ├── os_dep.c │ │ ├── pthread_start.c │ │ ├── pthread_stop_world.c │ │ ├── pthread_support.c │ │ ├── ptr_chck.c │ │ ├── reclaim.c │ │ ├── sparc_mach_dep.S │ │ ├── sparc_netbsd_mach_dep.s │ │ ├── specific.c │ │ ├── tests │ │ ├── atomicops.c │ │ ├── cpp.cc │ │ ├── disclaim.c │ │ ├── disclaim_bench.c │ │ ├── gctest.c │ │ ├── huge.c │ │ ├── initfromthread.c │ │ ├── leak.c │ │ ├── middle.c │ │ ├── realloc.c │ │ ├── smash.c │ │ ├── staticroots.c │ │ ├── staticroots_lib.c │ │ ├── subthreadcreate.c │ │ ├── tests.am │ │ ├── threadkey.c │ │ ├── threadleak.c │ │ ├── trace.c │ │ └── weakmap.c │ │ ├── thread_local_alloc.c │ │ ├── tools │ │ ├── callprocs.sh │ │ ├── if_mach.c │ │ ├── if_not_there.c │ │ ├── setjmp_t.c │ │ └── threadlibs.c │ │ ├── typd_mlc.c │ │ └── win32_threads.c ├── linenoise.c └── linenoise.h ├── examples ├── albums.lisp ├── fizzbuzz-cond.lisp ├── fizzbuzz-if.lisp ├── hello.lisp ├── mod-pos.lisp ├── quine.lisp ├── random.lisp └── triangles.lisp ├── src ├── ast.zig ├── boehm.zig ├── interpreter.zig ├── intrinsics.zig ├── linereader.zig ├── main.zig ├── tests.zig └── util.zig ├── std.lisp └── test.lisp /.gitignore: -------------------------------------------------------------------------------- 1 | zig-* 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2021-2023 cryptocode@zolo.io 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /build.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn build(b: *std.Build) void { 4 | const target = b.standardTargetOptions(.{}); 5 | const optimize = b.standardOptimizeOption(.{}); 6 | 7 | // Boehm GC 8 | const gc = b.addStaticLibrary(.{ 9 | .name = "gc", 10 | .target = target, 11 | .optimize = optimize, 12 | }); 13 | { 14 | const cflags = [_][]const u8{"-DNO_EXECUTE_PERMISSION"}; 15 | const libgc_srcs = [_][]const u8{ 16 | "alloc.c", "reclaim.c", "allchblk.c", "misc.c", "mach_dep.c", "os_dep.c", 17 | "mark_rts.c", "headers.c", "mark.c", "obj_map.c", "blacklst.c", "finalize.c", 18 | "new_hblk.c", "dbg_mlc.c", "malloc.c", "dyn_load.c", "typd_mlc.c", "ptr_chck.c", 19 | "mallocx.c", 20 | }; 21 | 22 | gc.linkLibC(); 23 | if (target.result.isDarwin()) { 24 | gc.linkFramework("CoreServices"); 25 | } 26 | gc.addIncludePath(b.path("deps/github.com/ivmai/bdwgc/include")); 27 | inline for (libgc_srcs) |src| { 28 | gc.addCSourceFile(.{ .file = b.path("deps/github.com/ivmai/bdwgc/" ++ src), .flags = &cflags }); 29 | } 30 | 31 | const gc_step = b.step("libgc", "build libgc"); 32 | gc_step.dependOn(&gc.step); 33 | } 34 | 35 | const exe = b.addExecutable(.{ 36 | .name = "bio", 37 | .root_source_file = b.path("src/main.zig"), 38 | .target = target, 39 | .optimize = optimize, 40 | }); 41 | exe.addIncludePath(b.path("deps/github.com/ivmai/bdwgc/include")); 42 | exe.linkLibC(); 43 | exe.linkLibrary(gc); 44 | 45 | if (target.result.os.tag != .windows) { 46 | exe.addCSourceFile(.{ .file = b.path("deps/linenoise.c"), .flags = &[_][]const u8{ "-std=c99", "-Wno-everything" } }); 47 | exe.addIncludePath(b.path("deps")); 48 | } 49 | 50 | var inst = b.addInstallArtifact(exe, .{}); 51 | b.getInstallStep().dependOn(&inst.step); 52 | 53 | const run_cmd = b.addRunArtifact(exe); 54 | run_cmd.step.dependOn(b.getInstallStep()); 55 | if (b.args) |args| { 56 | run_cmd.addArgs(args); 57 | } 58 | 59 | const run_step = b.step("run", "Run the app"); 60 | run_step.dependOn(&run_cmd.step); 61 | 62 | var tests = b.addTest(.{ 63 | .root_source_file = b.path("src/tests.zig"), 64 | .target = target, 65 | .optimize = optimize, 66 | }); 67 | tests.addIncludePath(b.path("deps/github.com/ivmai/bdwgc/include")); 68 | tests.linkLibC(); 69 | tests.linkLibrary(gc); 70 | 71 | const run_tests = b.addRunArtifact(tests); 72 | const test_step = b.step("test", "Run tests"); 73 | test_step.dependOn(&run_tests.step); 74 | } 75 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/.gitattributes: -------------------------------------------------------------------------------- 1 | # Git repo attributes. 2 | 3 | # Ensure shell and configure-related files have LF enforced. 4 | *.ac text eol=lf 5 | *.am text eol=lf 6 | *.m4 text eol=lf 7 | *.sh text eol=lf 8 | 9 | # Ensure all text files have normalized line endings in the repository. 10 | * text=auto 11 | 12 | # These files should use CR/LF line ending: 13 | /digimars.mak -text 14 | 15 | # Note: "core.eol" configuration variable controls which line endings to use 16 | # for the normalized files in the working directory (the default is native). 17 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignored files in bdwgc Git repo. 2 | 3 | # Binary files (in root dir, cord, tests): 4 | *.dll 5 | *.exe 6 | *.gcda 7 | *.gch 8 | *.gcno 9 | *.la 10 | *.lib 11 | *.lo 12 | *.o 13 | *.obj 14 | 15 | *.gc.log 16 | .dirstamp 17 | /*.a 18 | /*_bench.log 19 | /*_bench.trs 20 | /*_test 21 | /*test.log 22 | /*test.trs 23 | /.libs/ 24 | /Makefile 25 | /add_gc_prefix 26 | /atomicopstest 27 | /base_lib 28 | /bdw-gc.pc 29 | /c++ 30 | /config.cache 31 | /config.log 32 | /config.status 33 | /cord/cordtest 34 | /cord/de 35 | /cord/de_win.rbj 36 | /cord/de_win.res 37 | /cord/tests/de_win.rbj 38 | /cord/tests/de_win.res 39 | /cords 40 | /cordtest 41 | /core 42 | /cpptest 43 | /de 44 | /de.dir/ 45 | /disclaim_bench 46 | /disclaimtest 47 | /dont_ar_1 48 | /dont_ar_3 49 | /dont_ar_4 50 | /gc-* 51 | /gc.log 52 | /gcname 53 | /gctest 54 | /gctest_dyn_link 55 | /gctest_irix_dyn_link 56 | /hugetest 57 | /if_mach 58 | /if_not_there 59 | /initfromthreadtest 60 | /leaktest 61 | /lib*.so 62 | /libtool 63 | /middletest 64 | /realloctest 65 | /smashtest 66 | /staticrootstest 67 | /subthreadcreatetest 68 | /sunos5gc.so 69 | /test-suite.log 70 | /test_atomic_ops 71 | /test_atomic_ops.log 72 | /test_atomic_ops.trs 73 | /test_cpp 74 | /test_cpp.cpp 75 | /test_cpp.log 76 | /test_cpp.trs 77 | /threadkeytest 78 | /threadleaktest 79 | /threadlibs 80 | /tracetest 81 | /weakmaptest 82 | 83 | /out/ 84 | 85 | # Config, dependency and stamp files generated by configure: 86 | .deps/ 87 | /include/config.h 88 | config.h.in~ 89 | stamp-h1 90 | 91 | # External library (without trailing slash to allow symlinks): 92 | /libatomic_ops* 93 | /pthreads-w32* 94 | 95 | # These files are generated by autoreconf: 96 | /Makefile.in 97 | /aclocal.m4 98 | /autom4te.cache/ 99 | /compile 100 | /config.guess 101 | /config.sub 102 | /configure 103 | /configure~ 104 | /depcomp 105 | /include/config.h.in 106 | /install-sh 107 | /ltmain.sh 108 | /m4/libtool.m4 109 | /m4/ltoptions.m4 110 | /m4/ltsugar.m4 111 | /m4/ltversion.m4 112 | /m4/lt~obsolete.m4 113 | /missing 114 | /mkinstalldirs 115 | /test-driver 116 | 117 | # These files are generated by CMake: 118 | *.tlog 119 | /*.vcxproj 120 | /*.vcxproj.filters 121 | /CMakeCache.txt 122 | /CMakeFiles/ 123 | /DartConfiguration.tcl 124 | /Testing/Temporary/ 125 | /cord/CMakeFiles/ 126 | /cord/Makefile 127 | /gc.sln 128 | /tests/*.vcxproj 129 | /tests/*.vcxproj.filters 130 | /tests/*test 131 | /tests/CMakeFiles/ 132 | /tests/Makefile 133 | /tests/test_cpp 134 | CTestTestfile.cmake 135 | cmake_install.cmake 136 | 137 | # Rarely generated files (mostly by some Win/DOS compilers): 138 | /*.copied.c 139 | /*.csm 140 | /*.err 141 | /*.i 142 | /*.lb1 143 | /*.lnk 144 | /*.map 145 | /*.out 146 | /*.rbj 147 | /*.res 148 | /*.stackdump 149 | /*.sym 150 | /*.tmp 151 | *.bsc 152 | *.dll.manifest 153 | *.exp 154 | *.idb 155 | *.ilk 156 | *.pdb 157 | *.sbr 158 | *.tds 159 | gc.def 160 | 161 | # Stuff from VS build system and IDE 162 | *.vcproj.*.user 163 | .vs/ 164 | 165 | # Code analysis tools: 166 | *.c.gcov 167 | *.cc.gcov 168 | *.h.gcov 169 | *.sancov 170 | /.sv*-dir 171 | /cov-int 172 | /coverage.info 173 | /pvs-project.log 174 | /pvs-project.tasks 175 | /strace_out 176 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/Config.cmake.in: -------------------------------------------------------------------------------- 1 | # The BDWgc CMake configuration file. 2 | 3 | @PACKAGE_INIT@ 4 | include("${CMAKE_CURRENT_LIST_DIR}/BDWgcTargets.cmake") 5 | check_required_components(gc) 6 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/LICENSE: -------------------------------------------------------------------------------- 1 | MIT-style License 2 | 3 | Copyright (c) 1988-1989 Hans-J. Boehm, Alan J. Demers 4 | Copyright (c) 1991-1996 by Xerox Corporation. All rights reserved. 5 | Copyright (c) 1996-1999 by Silicon Graphics. All rights reserved. 6 | Copyright (c) 1998 by Fergus Henderson. All rights reserved. 7 | Copyright (c) 1999-2001 by Red Hat, Inc. All rights reserved. 8 | Copyright (c) 1999-2011 Hewlett-Packard Development Company, L.P. 9 | Copyright (c) 2004-2005 Andrei Polushin 10 | Copyright (c) 2007 Free Software Foundation, Inc. 11 | Copyright (c) 2008-2022 Ivan Maidanski 12 | Copyright (c) 2011 Ludovic Courtes 13 | Copyright (c) 2018 Petter A. Urkedal 14 | 15 | 16 | THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 17 | OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 18 | 19 | Permission is hereby granted to use or copy this program 20 | for any purpose, provided the above notices are retained on all copies. 21 | Permission to modify the code and to distribute modified code is granted, 22 | provided the above notices are retained, and a notice that the code was 23 | modified is included with the above copyright notice. 24 | 25 | 26 | Several files (gc/gc_allocator.h, extra/msvc_dbg.c) come with slightly 27 | different licenses, though they are all similar in spirit (the exact 28 | licensing terms are given at the beginning of the corresponding source file). 29 | 30 | A few of the files needed to use the GNU-style build procedure come with 31 | a modified GPL license that appears not to significantly restrict use of 32 | the collector, though use of those files for a purpose other than building 33 | the collector may require the resulting code to be covered by the GPL. 34 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # This script creates (or regenerates) configure (as well as aclocal.m4, 5 | # config.h.in, Makefile.in, etc.) missing in the source repository. 6 | # 7 | # If you compile from a distribution tarball, you can skip this. Otherwise, 8 | # make sure that you have Autoconf, Automake and Libtool installed 9 | # on your system, and that the corresponding *.m4 files are visible 10 | # to the aclocal. The latter can be achieved by using packages shipped by 11 | # your OS, or by installing custom versions of all four packages to the same 12 | # prefix. Otherwise, you may need to invoke autoreconf with the appropriate 13 | # -I options to locate the required *.m4 files. 14 | 15 | autoreconf -i 16 | 17 | echo 18 | echo "Ready to run './configure'." 19 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/bdw-gc.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: Boehm-Demers-Weiser Conservative Garbage Collector 7 | Description: A garbage collector for C and C++ 8 | Version: @PACKAGE_VERSION@ 9 | Libs: -L${libdir} @ATOMIC_OPS_LIBS@ -lgc @THREADDLLIBS@ 10 | Cflags: -I${includedir} 11 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/cord/cord.am: -------------------------------------------------------------------------------- 1 | ## This file is processed with automake. 2 | 3 | # Info (current:revision:age) for the Libtool versioning system. 4 | # These numbers should be updated at most once just before the release, 5 | # and, optionally, at most once during the development (after the release). 6 | LIBCORD_VER_INFO = 6:0:5 7 | 8 | lib_LTLIBRARIES += libcord.la 9 | 10 | libcord_la_LIBADD = libgc.la 11 | libcord_la_LDFLAGS = -version-info $(LIBCORD_VER_INFO) -no-undefined 12 | libcord_la_CPPFLAGS = $(AM_CPPFLAGS) 13 | 14 | libcord_la_SOURCES = \ 15 | cord/cordbscs.c \ 16 | cord/cordprnt.c \ 17 | cord/cordxtra.c 18 | 19 | TESTS += cordtest$(EXEEXT) 20 | check_PROGRAMS += cordtest 21 | cordtest_SOURCES = cord/tests/cordtest.c 22 | cordtest_LDADD = $(top_builddir)/libcord.la 23 | 24 | ## In case of static libraries build, libgc.a is already referenced in 25 | ## dependency_libs attribute of libcord.la file. 26 | if ENABLE_SHARED 27 | cordtest_LDADD += $(top_builddir)/libgc.la 28 | endif 29 | 30 | EXTRA_DIST += \ 31 | cord/tests/de.c \ 32 | cord/tests/de_cmds.h \ 33 | cord/tests/de_win.c \ 34 | cord/tests/de_win.h \ 35 | cord/tests/de_win.rc 36 | 37 | pkginclude_HEADERS += \ 38 | include/gc/cord.h \ 39 | include/gc/cord_pos.h \ 40 | include/gc/ec.h 41 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/cord/tests/de_cmds.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to use or copy this program 8 | * for any purpose, provided the above notices are retained on all copies. 9 | * Permission to modify the code and to distribute modified code is granted, 10 | * provided the above notices are retained, and a notice that the code was 11 | * modified is included with the above copyright notice. 12 | */ 13 | 14 | #ifndef DE_CMDS_H 15 | 16 | # define DE_CMDS_H 17 | 18 | # define UP 16 /* ^P */ 19 | # define DOWN 14 /* ^N */ 20 | # define LEFT 2 /* ^B */ 21 | # define RIGHT 6 /* ^F */ 22 | # define DEL 127 /* ^? */ 23 | # define BS 8 /* ^H */ 24 | # define UNDO 21 /* ^U */ 25 | # define WRITE 23 /* ^W */ 26 | # define QUIT 4 /* ^D */ 27 | # define REPEAT 18 /* ^R */ 28 | # define LOCATE 12 /* ^L */ 29 | # define TOP 20 /* ^T */ 30 | 31 | void do_command(int); 32 | /* Execute an editor command. */ 33 | /* The argument is a command character */ 34 | /* or one of the IDM_ commands. */ 35 | 36 | void generic_init(void); 37 | /* OS independent initialization. */ 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/cord/tests/de_win.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to use or copy this program 8 | * for any purpose, provided the above notices are retained on all copies. 9 | * Permission to modify the code and to distribute modified code is granted, 10 | * provided the above notices are retained, and a notice that the code was 11 | * modified is included with the above copyright notice. 12 | */ 13 | 14 | /* cord.h, de_cmds.h, and windows.h should be included before this. */ 15 | 16 | # define OTHER_FLAG 0x100 17 | # define EDIT_CMD_FLAG 0x200 18 | # define REPEAT_FLAG 0x400 19 | 20 | # define CHAR_CMD(i) ((i) & 0xff) 21 | 22 | /* MENU: DE */ 23 | #define IDM_FILESAVE (EDIT_CMD_FLAG + WRITE) 24 | #define IDM_FILEEXIT (OTHER_FLAG + 1) 25 | #define IDM_HELPABOUT (OTHER_FLAG + 2) 26 | #define IDM_HELPCONTENTS (OTHER_FLAG + 3) 27 | 28 | #define IDM_EDITPDOWN (REPEAT_FLAG + EDIT_CMD_FLAG + DOWN) 29 | #define IDM_EDITPUP (REPEAT_FLAG + EDIT_CMD_FLAG + UP) 30 | #define IDM_EDITUNDO (EDIT_CMD_FLAG + UNDO) 31 | #define IDM_EDITLOCATE (EDIT_CMD_FLAG + LOCATE) 32 | #define IDM_EDITDOWN (EDIT_CMD_FLAG + DOWN) 33 | #define IDM_EDITUP (EDIT_CMD_FLAG + UP) 34 | #define IDM_EDITLEFT (EDIT_CMD_FLAG + LEFT) 35 | #define IDM_EDITRIGHT (EDIT_CMD_FLAG + RIGHT) 36 | #define IDM_EDITBS (EDIT_CMD_FLAG + BS) 37 | #define IDM_EDITDEL (EDIT_CMD_FLAG + DEL) 38 | #define IDM_EDITREPEAT (EDIT_CMD_FLAG + REPEAT) 39 | #define IDM_EDITTOP (EDIT_CMD_FLAG + TOP) 40 | 41 | /* Screen dimensions. Maintained by de_win.c. */ 42 | extern int LINES; 43 | extern int COLS; 44 | 45 | /* File being edited. */ 46 | extern char * arg_file_name; 47 | 48 | /* 49 | * Calls from de_win.c to de.c 50 | */ 51 | 52 | CORD retrieve_screen_line(int i); 53 | /* Get the contents of i'th screen line. */ 54 | /* Relies on COLS. */ 55 | 56 | void set_position(int x, int y); 57 | /* Set column, row. Upper left of window = (0,0). */ 58 | 59 | /* 60 | * Calls from de.c to de_win.c 61 | */ 62 | 63 | void move_cursor(int column, int line); 64 | /* Physically move the cursor on the display, */ 65 | /* so that it appears at (column, line). */ 66 | 67 | void invalidate_line(int line); 68 | /* Invalidate line i on the screen. */ 69 | 70 | void de_error(const char *s); 71 | /* Display error message. */ 72 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/cord/tests/de_win.rc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to use or copy this program 8 | * for any purpose, provided the above notices are retained on all copies. 9 | * Permission to modify the code and to distribute modified code is granted, 10 | * provided the above notices are retained, and a notice that the code was 11 | * modified is included with the above copyright notice. 12 | */ 13 | 14 | #include "windows.h" 15 | #include "de_cmds.h" 16 | #include "de_win.h" 17 | 18 | ABOUTBOX DIALOG 19, 21, 163, 47 19 | STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU 20 | CAPTION "About Demonstration Text Editor" 21 | BEGIN 22 | LTEXT "Demonstration Text Editor", -1, 44, 8, 118, 8, WS_CHILD | WS_VISIBLE | WS_GROUP 23 | PUSHBUTTON "OK", IDOK, 118, 27, 24, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP 24 | END 25 | 26 | DE MENU 27 | BEGIN 28 | POPUP "&File" 29 | BEGIN 30 | MENUITEM "&Save\t^W", IDM_FILESAVE 31 | MENUITEM "E&xit\t^D", IDM_FILEEXIT 32 | END 33 | 34 | POPUP "&Edit" 35 | BEGIN 36 | MENUITEM "Page &Down\t^R^N", IDM_EDITPDOWN 37 | MENUITEM "Page &Up\t^R^P", IDM_EDITPUP 38 | MENUITEM "U&ndo\t^U", IDM_EDITUNDO 39 | MENUITEM "&Locate\t^L ... ^L", IDM_EDITLOCATE 40 | MENUITEM "D&own\t^N", IDM_EDITDOWN 41 | MENUITEM "U&p\t^P", IDM_EDITUP 42 | MENUITEM "Le&ft\t^B", IDM_EDITLEFT 43 | MENUITEM "&Right\t^F", IDM_EDITRIGHT 44 | MENUITEM "Delete &Backward\tBS", IDM_EDITBS 45 | MENUITEM "Delete F&orward\tDEL", IDM_EDITDEL 46 | MENUITEM "&Top\t^T", IDM_EDITTOP 47 | END 48 | 49 | POPUP "&Help" 50 | BEGIN 51 | MENUITEM "&Contents", IDM_HELPCONTENTS 52 | MENUITEM "&About...", IDM_HELPABOUT 53 | END 54 | 55 | MENUITEM "Page_&Down", IDM_EDITPDOWN 56 | MENUITEM "Page_&Up", IDM_EDITPUP 57 | END 58 | 59 | DE ACCELERATORS 60 | BEGIN 61 | "^R", IDM_EDITREPEAT 62 | "^N", IDM_EDITDOWN 63 | "^P", IDM_EDITUP 64 | "^L", IDM_EDITLOCATE 65 | "^B", IDM_EDITLEFT 66 | "^F", IDM_EDITRIGHT 67 | "^T", IDM_EDITTOP 68 | VK_DELETE, IDM_EDITDEL, VIRTKEY 69 | VK_BACK, IDM_EDITBS, VIRTKEY 70 | END 71 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/digimars.mak: -------------------------------------------------------------------------------- 1 | # Makefile to build Hans Boehm garbage collector using the Digital Mars 2 | # compiler from www.digitalmars.com 3 | # Written by Walter Bright 4 | 5 | CFLAGS_EXTRA= 6 | DEFINES=-D_WINDOWS -DGC_DLL -DGC_THREADS -DGC_DISCOVER_TASK_THREADS \ 7 | -DALL_INTERIOR_POINTERS -DENABLE_DISCLAIM -DGC_ATOMIC_UNCOLLECTABLE \ 8 | -DGC_GCJ_SUPPORT -DJAVA_FINALIZATION -DNO_EXECUTE_PERMISSION \ 9 | -DGC_REQUIRE_WCSDUP -DUSE_MUNMAP 10 | CFLAGS=-Iinclude -Ilibatomic_ops\src $(DEFINES) -g $(CFLAGS_EXTRA) 11 | LFLAGS=/ma/implib/co 12 | CC=sc 13 | 14 | # Must precede other goals. 15 | all: gc.dll gc.lib 16 | 17 | gc.obj: extra\gc.c 18 | $(CC) -c $(CFLAGS) extra\gc.c -ogc.obj 19 | 20 | .cpp.obj: 21 | $(CC) -c $(CFLAGS) -Aa $* 22 | 23 | OBJS= gc.obj gc_badalc.obj gc_cpp.obj 24 | 25 | check: gctest.exe cpptest.exe 26 | gctest.exe 27 | cpptest.exe 28 | 29 | gc.lib: gc.dll 30 | 31 | gc.dll: $(OBJS) gc.def digimars.mak 32 | $(CC) -ogc.dll $(OBJS) -L$(LFLAGS) gc.def kernel32.lib user32.lib 33 | 34 | gc.def: digimars.mak 35 | echo LIBRARY GC >gc.def 36 | echo DESCRIPTION "Boehm-Demers-Weiser Garbage Collector" >>gc.def 37 | echo EXETYPE NT >>gc.def 38 | echo EXPORTS >>gc.def 39 | echo GC_is_visible_print_proc >>gc.def 40 | echo GC_is_valid_displacement_print_proc >>gc.def 41 | 42 | clean: 43 | del *.log gc.def gc.dll gc.lib gc.map gctest.map cpptest.map 44 | del tests\gctest.obj gctest.exe tests\cpptest.obj cpptest.exe 45 | del $(OBJS) 46 | 47 | gctest.exe: gc.lib tests\gctest.obj 48 | $(CC) -ogctest.exe tests\gctest.obj gc.lib 49 | 50 | tests\gctest.obj: tests\gctest.c 51 | $(CC) -c $(CFLAGS) tests\gctest.c -otests\gctest.obj 52 | 53 | cpptest.exe: gc.lib tests\cpptest.obj 54 | $(CC) -ocpptest.exe tests\cpptest.obj gc.lib 55 | 56 | tests\cpptest.obj: tests\cpp.cc 57 | $(CC) -c $(CFLAGS) -cpp tests\cpp.cc -otests\cpptest.obj 58 | 59 | gc_badalc.obj: gc_badalc.cc gc_badalc.cpp 60 | gc_cpp.obj: gc_cpp.cc gc_cpp.cpp 61 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/docs/README.autoconf: -------------------------------------------------------------------------------- 1 | We support GNU-style builds based on automake, autoconf and libtool. 2 | This is based almost entirely on Tom Tromey's work with gcj. 3 | 4 | To build and install libraries use 5 | 6 | configure; make; make install 7 | 8 | The advantages of this process are: 9 | 10 | 1) It should eventually do a better job of automatically determining the 11 | right compiler to use, etc. It probably already does in some cases. 12 | 13 | 2) It tries to automatically set a good set of default GC parameters for 14 | the platform (e.g. thread support). It provides an easier way to configure 15 | some of the others. 16 | 17 | 3) It integrates better with other projects using a GNU-style build process. 18 | 19 | 4) It builds both dynamic and static libraries. 20 | 21 | The known disadvantages are: 22 | 23 | 1) The build scripts are much more complex and harder to debug (though largely 24 | standard). I don't understand them all, and there's probably lots of redundant 25 | stuff. 26 | 27 | 2) It probably doesn't work on all Un*x-like platforms yet. It probably will 28 | never work on the rest. 29 | 30 | 3) The scripts are not yet complete. Some of the standard GNU targets don't 31 | yet work. (Corrections/additions are very welcome.) 32 | 33 | The distribution should contain all files needed to run "configure" and "make", 34 | as well as the sources needed to regenerate the derived files. (If I missed 35 | some, please let me know.) 36 | 37 | Note that the distribution comes without "Makefile" which is generated by 38 | "configure". The distribution also contains "Makefile.direct" which is not 39 | always equivalent to the generated one. 40 | 41 | Important options to configure: 42 | 43 | --prefix=PREFIX install architecture-independent files in PREFIX 44 | [/usr/local] 45 | --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX 46 | [same as prefix] 47 | --enable-threads=TYPE choose threading package 48 | --disable-parallel-mark do not parallelize marking and free list 49 | construction 50 | --enable-gc-debug include full support for pointer back-tracing, etc. 51 | 52 | 53 | Unless --prefix is set (or --exec-prefix or one of the more obscure options), 54 | "make install" will install libgc.a and libgc.so in /usr/local/lib and 55 | /usr/local/bin, respectively, which would typically require the "make install" 56 | to be run as root. 57 | 58 | It is not recommended to turn off parallel marking for multiprocessors unless 59 | a poor support of the feature on the platform. 60 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/docs/README.cmake: -------------------------------------------------------------------------------- 1 | 2 | CMAKE 3 | ----- 4 | 5 | Unix and Win32 binaries (both 32- and 64-bit) can be built using CMake. 6 | CMake is an open-source tool like automake - it generates makefiles. 7 | 8 | CMake (as of v3.14.5) is able to generate: 9 | Borland Makefiles 10 | MSYS Makefiles 11 | MinGW Makefiles 12 | NMake Makefiles 13 | Unix Makefiles 14 | Visual Studio 16 2019 15 | Visual Studio 15 2017 16 | Visual Studio 14 2015 17 | Visual Studio 12 2013 18 | Visual Studio 11 2012 19 | Visual Studio 10 2010 20 | Visual Studio 9 2008 21 | Watcom WMake 22 | 23 | 24 | BUILD PROCESS 25 | ------------- 26 | 27 | The steps are: 28 | . install cmake (cmake.org) 29 | . add directory containing cmake.exe to %PATH% 30 | . run cmake from the bdwgc root directory, passing the target with -G: 31 | e.g., 32 | > cmake -G "Visual Studio 9 2008" . 33 | > use the gc.sln file generated by cmake to build gc 34 | 35 | Notes: 36 | . specify -Denable_cplusplus=ON option to build gccpp, gctba (GC C++ support) 37 | . specify -Dbuild_tests=ON option to the tests (and run them by "ctest -V") 38 | . you can also run cmake from a build directory to build outside of 39 | the source tree; just specify the path to the source tree: 40 | e.g., 41 | > mkdir out 42 | > cd out 43 | > cmake -G "Visual Studio 9 2008" -Dbuild_tests=ON .. 44 | > cmake --build . --config Release 45 | > ctest --build-config Release -V 46 | 47 | Here's a sample for Linux (build, test and install, w/o C++ support): 48 | > mkdir out 49 | > cd out 50 | > cmake -Dbuild_tests=ON .. 51 | > cmake --build . 52 | > ctest 53 | > make install 54 | 55 | 56 | INPUT 57 | ----- 58 | 59 | The main input to cmake is CMakeLists.txt file in the GC root directory. For 60 | help, go to cmake.org. 61 | 62 | 63 | HOW TO IMPORT BDWGC 64 | ------------------- 65 | 66 | Another project could add bdwgc as one of its dependencies with something like 67 | this in their CMakeLists.txt: 68 | 69 | find_package(BDWgc 8.2.0 REQUIRED) 70 | add_executable(Foo foo.c) 71 | target_link_libraries(Foo BDWgc::gc) 72 | 73 | Other exported libraries are: cord, gccpp, gctba. 74 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/docs/README.cords: -------------------------------------------------------------------------------- 1 | 2 | This is a string packages that uses a tree-based representation. 3 | See cord.h for a description of the functions provided. Ec.h describes 4 | "extensible cords", which are essentially output streams that write 5 | to a cord. These allow for efficient construction of cords without 6 | requiring a bound on the size of a cord. 7 | 8 | The cord library is built by default in case of the GNU autoconf-based build 9 | and the CMake-based one (unless "-Dbuild_cord=OFF" option is given to cmake). 10 | If you wish to build the library with the stand-alone Makefile.direct, type 11 | "make -f Makefile.direct cords". 12 | 13 | More details on the data structure can be found in: 14 | 15 | Boehm, Atkinson, and Plass, "Ropes: An Alternative to Strings", 16 | Software Practice and Experience 25, 12, December 1995, pp. 1315-1330. 17 | 18 | A fundamentally similar "rope" data structure is also part of SGI's standard 19 | template library implementation, and its descendants, which include the 20 | GNU C++ library. That uses reference counting by default. 21 | There is a short description of that data structure at 22 | http://www.sgi.com/tech/stl/ropeimpl.html . 23 | 24 | All of these are descendants of the "ropes" in Xerox Cedar. 25 | 26 | cord/tests/de.c is a very dumb text editor that illustrates the use of cords. 27 | It maintains a list of file versions. Each version is simply a 28 | cord representing the file contents. Nonetheless, standard 29 | editing operations are efficient, even on very large files. 30 | (Its 3 line "user manual" can be obtained by invoking it without 31 | arguments. Note that ^R^N and ^R^P move the cursor by 32 | almost a screen. It does not understand tabs, which will show 33 | up as highlighted "I"s. Use the UNIX "expand" program first.) 34 | To build the editor, type "make de" in the gc directory. 35 | 36 | Note that CORD_printf and friends use C functions with variable numbers 37 | of arguments in non-standard-conforming ways. This code is known to 38 | break on some platforms, notably PowerPC. It should be possible to 39 | build the remainder of the library (everything but cordprnt.c) on 40 | any platform that supports the collector. 41 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/docs/faq.md: -------------------------------------------------------------------------------- 1 | # FAQ: A garbage collector for C and C++ 2 | 3 | This is the beginning of a "frequently asked questions" file for what has 4 | become known as the "Boehm-Demers-Weiser" garbage collector. Some of these 5 | are likely to apply to any garbage collector whatsoever. 6 | 7 | ## Questions and Answers 8 | 9 | ### I wrote a test program which allocates objects and registers finalizers for them. Only a few (or no) objects are finalized. What's wrong? 10 | 11 | Probably nothing. Finalizers are only executed if all of the following happen 12 | before the process exits: 13 | 14 | * A garbage collection runs. This normally happens only after a significant 15 | amount of allocation. 16 | * The objects in question appear inaccessible at the time of the collection. 17 | It is common for a handful of objects to appear accessible even though they 18 | should not be, e.g. because temporary pointers to them haven't yet been 19 | overwritten. Also note that by default only the first item in a chain of 20 | finalizable objects will be finalized in a collection. 21 | * Another GC_ call notices that there are finalizers waiting to be run and 22 | does so. 23 | 24 | Small test programs typically don't run long enough for this to happen. 25 | 26 | ### Does this mean that the collector might leak memory? 27 | 28 | In the short term yes. But it is unlikely, though not impossible, that this 29 | will result in a leak that grows over time. Under normal circumstances, short 30 | term, or one time leaks are a minor issue. Memory leaks in explicitly managed 31 | programs are feared because they almost always continue to grow over time. 32 | 33 | For (a lot) more details see: 34 | 35 | * "Bounding Space Usage of Conservative Garbage Collectors", Proceedings of 36 | the 2002 ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, 37 | Jan. 2002, pp. 93-100 38 | ([official version](https://dl.acm.org/doi/10.1145/565816.503282), 39 | [Technical report](http://www.hpl.hp.com/techreports/2001/HPL-2001-251.html)). 40 | 41 | ### How can I get more of the finalizers to run to convince myself that the GC is working? 42 | 43 | Invoke GC_gcollect a couple of times just before process exit. 44 | 45 | ### I want to ensure that all my objects are finalized and reclaimed before process exit. How can I do that? 46 | 47 | You can't, and you do not really want that. This would require finalizing 48 | _reachable_ objects. Finalizers run later would have to be able to handle 49 | this, and would have to be able to run with randomly broken libraries, because 50 | the objects they rely on where previously finalized. In most environments, 51 | you would also be replacing the operating systems mechanism for very 52 | efficiently reclaiming process memory at process exit with a significantly 53 | slower mechanism. 54 | 55 | You do sometimes want to ensure that certain particular resources are 56 | explicitly reclaimed before process exit, whether or not they become 57 | unreachable. Programming techniques for ensuring this are discussed in 58 | 59 | * "Destructors, Finalizers, and Synchronization", Proceedings of the 2003 ACM 60 | SIGPLAN-SIGACT Symposium on Principles of Programming Languages, Jan. 2003, 61 | pp. 262-272 62 | ([official version](https://dl.acm.org/doi/10.1145/604131.604153), 63 | [Technical report](http://www.hpl.hp.com/techreports/2002/HPL-2002-335.html), 64 | [slides](http://www.hboehm.info/popl03/slides.pdf)). 65 | 66 | ### I wrote a memory allocation loop, and it runs much slower with the garbage collector than when I use malloc/free memory management. Why? 67 | 68 | Odds are your loop allocates very large objects and never initializes them. 69 | Real programs generally don't behave that way. Garbage collectors generally 70 | perform appreciably worse for large object allocations, and they generally 71 | initialize objects, even if you don't. 72 | 73 | ### What can I do to maximize allocation performance? 74 | 75 | Here are some hints: 76 | 77 | * Use `GC_MALLOC_ATOMIC` where possible. 78 | * For a multi-threaded application, ensure the GC library is compiled with 79 | `THREAD_LOCAL_ALLOC` macro defined (this is the default behavior) to avoid 80 | locking on each allocation. 81 | * If you use large statically allocated arrays or mapped files, consider 82 | `GC_exclude_static_roots`. 83 | 84 | ### If my heap uses 2 GB on a 32-bit machine, won't every other integer or other random data be misinterpreted as a pointer by the collector? Thus won't way too much memory be retained? 85 | 86 | Maybe. Probably, if the collector is used purely conservatively, with no 87 | pointer layout information (such as use of `GC_MALLOC_ATOMIC`). 88 | 89 | With a gigabyte heap, you are clearly much better off on a 64-bit machine. 90 | Empirical evidence seems to suggest that some such applications work on 91 | a 32-bit machine, and others don't perform acceptably. 92 | 93 | Simple probability calculations for pointer misidentifications are generally 94 | incorrect. The probability of misinterpreting an integer is typically reduced 95 | significantly by a number of collector features and fortunate accidents. Most 96 | integers are small, and small integers can generally not be heap addresses. 97 | The collector black-listing mechanism avoids allocating areas that are prone 98 | to be targets of misinterpreted references. The collector can be told to 99 | ignore some or all pointers to object interiors. 100 | 101 | ### I have a different question that is not answered here, nor in the other GC documentation. Where else can I go? 102 | 103 | If you can't find the answer in the [GC overview](overview.md) and the linked 104 | files, please see "Feedback, Contribution, Questions and Notifications" section of 105 | the main [README](../README.md). 106 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/docs/platforms/README.aix: -------------------------------------------------------------------------------- 1 | We have so far failed to find a good way to determine the stack base. 2 | It is highly recommended that GC_stackbottom be set explicitly on program 3 | startup. The supplied value sometimes causes failure under AIX 4.1, though 4 | it appears to work under 3.X. HEURISTIC2 seems to work under 4.1, but 5 | involves a substantial performance penalty, and will fail if there is 6 | no limit on stack size. 7 | 8 | There is no thread support. (I assume recent versions of AIX provide 9 | pthreads? I no longer have access to a machine ...) 10 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/docs/platforms/README.arm_cross: -------------------------------------------------------------------------------- 1 | From: Margaret Fleck 2 | 3 | Here's the key details of what worked for me, in case anyone else needs them. 4 | There may well be better ways to do some of this, but .... 5 | -- Margaret 6 | 7 | 8 | The badge4 has a StrongArm-1110 processor and a StrongArm-1111 coprocessor. 9 | 10 | Assume that the garbage collector distribution is unpacked into /home/arm/gc, 11 | which is visible to both the ARM machine and a linux desktop (e.g. via NFS mounting). 12 | 13 | Assume that you have a file /home/arm/config.site with contents something like the 14 | example attached below. Notice that our local ARM toolchain lives in 15 | /skiff/local. 16 | 17 | Go to /home/arm/gc directory. Do 18 | CONFIG_SITE=/home/arm/config.site ./configure --target=arm-linux 19 | --prefix=/home/arm/gc 20 | 21 | On your desktop, do: 22 | make 23 | make install 24 | The main garbage collector library should now be in ../gc/lib/libgc.so. 25 | 26 | To test the garbage collector, first do the following on your desktop 27 | make gctest 28 | ./gctest 29 | Then do the following on the ARM machine 30 | cd .libs 31 | ./lt-gctest 32 | 33 | Do not try to do "make check" (the usual way of running the test 34 | program). This does not work and seems to erase some of the important 35 | files. 36 | 37 | The gctest program claims to have succeeded. Haven't run any further tests 38 | with it, though I'll be doing so in the near future. 39 | 40 | ------------------------------- 41 | # config.site for configure 42 | 43 | HOSTCC=gcc 44 | 45 | # Names of the cross-compilers 46 | CC=/skiff/local/bin/arm-linux-gcc 47 | CXX=/skiff/local/bin/arm-linux-gcc 48 | 49 | # The cross compiler specific options 50 | CFLAGS="-O2 -fno-exceptions" 51 | CXXFLAGS="-O2 -fno-exceptions" 52 | CPPFLAGS="-O2 -fno-exceptions" 53 | LDFLAGS="" 54 | 55 | # Some other programs 56 | AR=/skiff/local/bin/arm-linux-ar 57 | RANLIB=/skiff/local/bin/arm-linux-ranlib 58 | NM=/skiff/local/bin/arm-linux-nm 59 | ac_cv_path_NM=/skiff/local/bin/arm-linux-nm 60 | ac_cv_func_setpgrp_void=yes 61 | x_includes=/skiff/local/arm-linux/include/X11 62 | x_libraries=/skiff/local/arm-linux/lib/X11 63 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/docs/platforms/README.darwin: -------------------------------------------------------------------------------- 1 | Darwin/MacOSX Support - December 16, 2003 2 | 3 | == Build Notes == 4 | 5 | Building can be done with autoconf as normal. If you want to build 6 | a Universal library using autoconf, you need to disable dependency 7 | tracking and specify your desired architectures in CFLAGS: 8 | 9 | CFLAGS="-arch ppc -arch i386 -arch x86_64" ./configure --disable-dependency-tracking 10 | 11 | 12 | == Important Usage Notes == 13 | 14 | GC_INIT() MUST be called before calling any other GC functions. This 15 | is necessary to properly register segments in dynamic libraries. This 16 | call is required even if you code does not use dynamic libraries as the 17 | dyld code handles registering all data segments. 18 | 19 | When your use of the garbage collector is confined to dylibs and you 20 | cannot call GC_INIT() before your libraries' static initializers have 21 | run and perhaps called GC_malloc(), create an initialization routine 22 | for each library to call GC_INIT(), e.g.: 23 | 24 | #include "gc.h" 25 | extern "C" void my_library_init() { GC_INIT(); } 26 | 27 | Compile this code into a my_library_init.o, and link it into your 28 | dylib. When you link the dylib, pass the -init argument with 29 | _my_library_init (e.g. gcc -dynamiclib -o my_library.dylib a.o b.o c.o 30 | my_library_init.o -init _my_library_init). This causes 31 | my_library_init() to be called before any static initializers, and 32 | will initialize the garbage collector properly. 33 | 34 | Note: It doesn't hurt to call GC_INIT() more than once, so it's best, 35 | if you have an application or set of libraries that all use the 36 | garbage collector, to create an initialization routine for each of 37 | them that calls GC_INIT(). Better safe than sorry. 38 | 39 | Thread-local GC allocation will not work with threads that are not 40 | created using the GC-provided override of pthread_create(). Threads 41 | created without the GC-provided pthread_create() do not have the 42 | necessary data structures in the GC to store this data. 43 | 44 | 45 | == Implementation Information == 46 | 47 | Darwin/MacOSX support is nearly complete. Thread support is reliable on 48 | Darwin 6.x (MacOSX 10.2) and there have been reports of success on older 49 | Darwin versions (MacOSX 10.1). Shared library support had also been 50 | added and the gc can be run from a shared library. 51 | 52 | Thread support is implemented in terms of mach thread_suspend and 53 | thread_resume calls. These provide a very clean interface to thread 54 | suspension. This implementation doesn't rely on pthread_kill so the 55 | code works on Darwin < 6.0 (MacOSX 10.1). All the code to stop and 56 | start the world is located in darwin_stop_world.c. 57 | 58 | Since not all uses of the GC enable clients to override pthread_create() 59 | before threads have been created, the code for stopping the world has 60 | been rewritten to look for threads using Mach kernel calls. Each 61 | thread identified in this way is suspended and resumed as above. In 62 | addition, since Mach kernel threads do not contain pointers to their 63 | stacks, a stack-walking function has been written to find the stack 64 | limits. Given an initial stack pointer (for the current thread, a 65 | pointer to a stack-allocated local variable will do; for a non-active 66 | thread, we grab the value of register 1 (on PowerPC)), it 67 | will walk the PPC Mach-O-ABI compliant stack chain until it reaches the 68 | top of the stack. This appears to work correctly for GCC-compiled C, 69 | C++, Objective-C, and Objective-C++ code, as well as for Java 70 | programs that use JNI. If you run code that does not follow the stack 71 | layout or stack pointer conventions laid out in the PPC Mach-O ABI, 72 | then this will likely crash the garbage collector. 73 | 74 | Mach has a very clean interface to exception handing. So, the current 75 | implementation of the incremental collection uses Mach's exception handling. 76 | 77 | Much thanks goes to Andrew Stone, Dietmar Planitzer, Andrew Begel, 78 | Jeff Sturm, and Jesse Rosenstock for all their work on the 79 | Darwin/OS X port. 80 | 81 | -Brian Alliet 82 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/docs/platforms/README.dgux386: -------------------------------------------------------------------------------- 1 | Garbage Collector (parallel version) for x86 DG/UX Release R4.20MU07 2 | 3 | 4 | *READ* the file README.md first. 5 | 6 | You need the GCC-3.0.3 rev (DG/UX) compiler to build this tree. 7 | This compiler has the new "dgux386" threads package implemented. 8 | It also supports the switch "-pthread" needed to link correctly 9 | the DG/UX's -lrte -lthread with -lgcc and the system's -lc. 10 | Finally, we support parallel mark for the SMP DG/UX machines. 11 | To build the garbage collector do: 12 | 13 | ./configure 14 | make 15 | make gctest 16 | 17 | Before you run "gctest" you need to set your LD_LIBRARY_PATH 18 | correctly so that "gctest" can find the shared library libgc. 19 | Alternatively you can do a configuration 20 | 21 | ./configure --disable-shared 22 | 23 | to build only the static version of libgc. 24 | 25 | To enable debugging messages please do: 26 | 1) Add the "--enable-gc-debug" flag during configuration. 27 | 2) Pass "CFLAGS=-DDEBUG_THREADS" to "make". 28 | 29 | In a machine with 4 CPUs (my own machine), parallel mark makes 30 | a BIG difference. 31 | 32 | Takis Psarogiannakopoulos 33 | 34 | Note (HB): 35 | The integration of this patch is currently not complete. 36 | The following patches against 6.1alpha3 where hard to move 37 | to alpha4, and are not integrated. There may also be minor 38 | problems with stylistic corrections made by me. 39 | [The diff for ltconfig and ltmain.sh was removed from this file on 2011-08-22] 40 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/docs/platforms/README.emscripten: -------------------------------------------------------------------------------- 1 | 2 | The build system (at least autotools-based) should detect and configure 3 | emscripten correctly. 4 | 5 | As of now, gctest almost passes, except for the tests that involve a_get(). 6 | 7 | No thread support for now. No idea how to stop other threads (perhaps we need 8 | support from JS side). 9 | 10 | How to build: 11 | 12 | # source EMSDK first 13 | emconfigure ./configure 14 | emmake make gctest.html 15 | # point your browser at .libs/gctest.html 16 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/docs/platforms/README.ews4800: -------------------------------------------------------------------------------- 1 | GC on EWS4800 2 | ------------- 3 | 4 | 1. About EWS4800 5 | 6 | EWS4800 is a 32/64-bit workstation. 7 | 8 | Vendor: NEC Corporation 9 | OS: UX/4800 R9.* - R13.* (SystemV R4.2) 10 | CPU: R4000, R4400, R10000 (MIPS) 11 | 12 | 2. Compiler 13 | 14 | 32-bit: 15 | Use ANSI C compiler. 16 | CC = /usr/abiccs/bin/cc 17 | 18 | 64-bit: 19 | Use the 64-bit ANSI C compiler. 20 | CC = /usr/ccs64/bin/cc 21 | AR = /usr/ccs64/bin/ar 22 | 23 | 3. ELF file format 24 | *** Caution: The following information is empirical. *** 25 | 26 | 32-bit: 27 | ELF file has a unique format. (See a.out(4) and end(3C).) 28 | 29 | &_start 30 | : text segment 31 | &etext 32 | DATASTART 33 | : data segment (initialized) 34 | &edata 35 | DATASTART2 36 | : data segment (uninitialized) 37 | &end 38 | 39 | Here, DATASTART and DATASTART2 are macros of GC, and are defined as 40 | the following equations. (See include/private/gcconfig.h.) 41 | The algorithm for DATASTART is similar with the function 42 | GC_SysVGetDataStart() in os_dep.c. 43 | 44 | DATASTART = ((&etext + 0x3ffff) & ~0x3ffff) + (&etext & 0xffff) 45 | 46 | Dynamically linked: 47 | DATASTART2 = (&_gp + 0x8000 + 0x3ffff) & ~0x3ffff 48 | 49 | Statically linked: 50 | DATASTART2 = &edata 51 | 52 | GC has to check addresses both between DATASTART and &edata, and 53 | between DATASTART2 and &end. If a program accesses between &etext 54 | and DATASTART, or between &edata and DATASTART2, the segmentation 55 | error occurs and the program stops. 56 | 57 | If a program is statically linked, there is not a gap between 58 | &edata and DATASTART2. The global symbol &_DYNAMIC_LINKING is used 59 | for the detection. 60 | 61 | 64-bit: 62 | ELF file has a simple format. (See end(3C).) 63 | 64 | _ftext 65 | : text segment 66 | _etext 67 | _fdata = DATASTART 68 | : data segment (initialized) 69 | _edata 70 | _fbss 71 | : data segment (uninitialized) 72 | _end = DATAEND 73 | 74 | -- 75 | Hironori SAKAMOTO 76 | 77 | 78 | When using the new "configure; make" build process, please 79 | run configure with the --disable-shared option. "Make check" does not 80 | yet pass with dynamic libraries. The reasons for that are not yet 81 | understood. (HB, paraphrasing message from Hironori SAKAMOTO.) 82 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/docs/platforms/README.hp: -------------------------------------------------------------------------------- 1 | Dynamic loading support requires that executables be linked with -ldld. 2 | The alternative is to build the collector without defining DYNAMIC_LOADING 3 | in gcconfig.h and ensuring that all garbage collectible objects are 4 | accessible without considering statically allocated variables in dynamic 5 | libraries. 6 | 7 | The collector should compile with either plain cc or cc -Ae. Cc -Aa 8 | fails to define _HPUX_SOURCE and thus will not configure the collector 9 | correctly. 10 | 11 | Incremental collection support was added recently, and should now work. 12 | 13 | In spite of past claims, pthread support under HP/UX 11 should now work. 14 | Define GC_THREADS macro for the build. Incremental collection still does not 15 | work in combination with it. 16 | 17 | The stack finding code can be confused by putenv calls before collector 18 | initialization. Call GC_malloc() or GC_INIT() before any putenv() calls. 19 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/docs/platforms/README.linux: -------------------------------------------------------------------------------- 1 | See README.alpha for Linux on DEC AXP info. 2 | 3 | This file applies mostly to Linux/Intel IA-32. Ports to Linux on an M68K, 4 | IA-64, SPARC, MIPS, Alpha and PowerPC are integrated too. They should behave 5 | similarly, except that the PowerPC port lacks incremental GC support, and 6 | it is unknown to what extent the Linux threads code is functional. 7 | See below for M68K specific notes. 8 | 9 | Incremental GC is generally supported. 10 | 11 | Dynamic libraries are supported on an ELF system. 12 | 13 | The collector appears to work reliably with Linux threads, but beware 14 | of older versions of glibc and gdb. 15 | 16 | The garbage collector uses SIGPWR and SIGXCPU if it is used with 17 | Linux threads. These should not be touched by the client program. 18 | 19 | To use threads, you need to abide by the following requirements: 20 | 21 | 1) You need to use LinuxThreads or NPTL (which are included in libc6). 22 | 23 | The collector relies on some implementation details of the LinuxThreads 24 | package. This code may not work on other 25 | pthread implementations (in particular it will *not* work with 26 | MIT pthreads). 27 | 28 | 2) You must compile the collector with "-DGC_THREADS -D_REENTRANT" specified 29 | in the Makefile.direct file. 30 | 31 | 3a) Every file that makes thread calls should define GC_THREADS, and then 32 | include gc.h. The latter redefines some of the pthread primitives as 33 | macros which also provide the collector with information it requires. 34 | 35 | 3b) A new alternative to (3a) is to build the collector and compile GC clients 36 | with -DGC_USE_LD_WRAP, and to link the final program with 37 | 38 | (for ld) --wrap dlopen --wrap pthread_create \ 39 | --wrap pthread_join --wrap pthread_detach \ 40 | --wrap pthread_sigmask --wrap pthread_exit --wrap pthread_cancel 41 | 42 | (for gcc) -Wl,--wrap -Wl,dlopen -Wl,--wrap -Wl,pthread_create \ 43 | -Wl,--wrap -Wl,pthread_join -Wl,--wrap -Wl,pthread_detach \ 44 | -Wl,--wrap -Wl,pthread_sigmask -Wl,--wrap -Wl,pthread_exit \ 45 | -Wl,--wrap -Wl,pthread_cancel 46 | 47 | In any case, _REENTRANT should be defined during compilation. 48 | 49 | 4) Dlopen() disables collection during its execution. (It can't run 50 | concurrently with the collector, since the collector looks at its 51 | data structures. It can't acquire the allocator lock, since arbitrary 52 | user startup code may run as part of dlopen().) Under unusual 53 | conditions, this may cause unexpected heap growth. 54 | 55 | 5) The combination of GC_THREADS, REDIRECT_MALLOC, and incremental 56 | collection is probably not fully reliable, though it now seems to work 57 | in simple cases. 58 | 59 | 6) Thread local storage may not be viewed as part of the root set by the 60 | collector. This probably depends on the linuxthreads version. For the 61 | time being, any collectible memory referenced by thread local storage 62 | should also be referenced from elsewhere, or be allocated as uncollectible. 63 | (This is really a bug that should be fixed somehow. Actually, the 64 | collector probably gets things right, on Linux at least, if there are not 65 | too many tls locations and if dlopen is not used.) 66 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/docs/platforms/README.os2: -------------------------------------------------------------------------------- 1 | The code assumes static linking, and a single thread. The editor de has 2 | not been ported; the cord test program has. The supplied WCC_MAKEFILE should 3 | work for OS/2 but was not tested on. 4 | 5 | Since we haven't figured out how to do partial linking or to build static 6 | libraries, clients currently need to link against a long list of executables. 7 | 8 | Notes: 9 | * adding dynamic linking support seems easy, but was not done; 10 | * adding thread support may be nontrivial, since we have not yet figured out 11 | how to look at another thread's registers; 12 | * setjmp_test may yield overly optimistic results when compiled without 13 | optimization. 14 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/docs/platforms/README.sgi: -------------------------------------------------------------------------------- 1 | Performance of the incremental collector can be greatly enhanced with 2 | -DNO_EXECUTE_PERMISSION. 3 | 4 | The collector should run with all of the -32, -n32 and -64 ABIs. Remember to 5 | define the AS macro in the Makefile.direct to be "as -64", or "as -n32". 6 | 7 | If you use -DREDIRECT_MALLOC=GC_malloc with C++ code, your code should make 8 | at least one explicit call to malloc instead of new to ensure that the proper 9 | version of malloc is linked in. 10 | 11 | Sproc threads are not supported. 12 | 13 | Pthreads support is provided. This requires that: 14 | 15 | 1) You compile the collector with -DGC_THREADS specified in Makefile.direct. 16 | 17 | 2) You have the latest pthreads patches installed. 18 | 19 | (Though the collector makes only documented pthread calls, 20 | it relies on signal/threads interactions working just right in ways 21 | that are not required by the standard. It is unlikely that this code 22 | will run on other pthreads platforms. But please tell me if it does.) 23 | 24 | 3) Every file that makes thread calls should define GC_THREADS and then 25 | include gc.h. Gc.h redefines some of the pthread primitives as macros which 26 | also provide the collector with information it requires. 27 | 28 | 4) pthread_cond_wait and pthread_cond_timedwait should be prepared for 29 | premature wakeups. (I believe the pthreads and related standards require this 30 | anyway. Irix pthreads often terminate a wait if a signal arrives. 31 | The garbage collector uses signals to stop threads.) 32 | 33 | 5) It is expensive to stop a thread waiting in IO at the time the request is 34 | initiated. Applications with many such threads may not exhibit acceptable 35 | performance with the collector. (Increasing the heap size may help.) 36 | 37 | 6) The collector should not be compiled with -DREDIRECT_MALLOC. This 38 | confuses some library calls made by the pthreads implementation, which 39 | expect the standard malloc. 40 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/docs/platforms/README.solaris2: -------------------------------------------------------------------------------- 1 | The collector supports both incremental collection and threads under 2 | Solaris 2. The incremental collector normally retrieves page dirty information 3 | through the appropriate /proc calls. But it can also be configured 4 | (by defining MPROTECT_VDB instead of PROC_VDB in gcconfig.h) to use mprotect 5 | and signals. This may result in shorter pause times, but it is no longer 6 | safe to issue arbitrary system calls that write to the heap. 7 | 8 | Under other UNIX versions, 9 | the collector normally obtains memory through sbrk. There is some reason 10 | to expect that this is not safe if the client program also calls the system 11 | malloc, or especially realloc. The sbrk man page strongly suggests this is 12 | not safe: "Many library routines use malloc() internally, so use brk() 13 | and sbrk() only when you know that malloc() definitely will not be used by 14 | any library routine." This doesn't make a lot of sense to me, since there 15 | seems to be no documentation as to which routines can transitively call malloc. 16 | Nonetheless, under Solaris2, the collector now allocates 17 | memory using mmap by default. (It defines USE_MMAP in gcconfig.h.) 18 | You may want to reverse this decisions if you use -DREDIRECT_MALLOC=... 19 | 20 | Note: 21 | Before you run "make check", you need to set your LD_LIBRARY_PATH correctly 22 | (e.g., to "/usr/local/lib") so that tests can find the shared library 23 | libgcc_s.so.1. Alternatively, you can configure with --disable-shared. 24 | 25 | SOLARIS THREADS: 26 | 27 | Unless --disable-threads option is given, threads support is on by default in 28 | configure. This causes the collector to be compiled with -D GC_THREADS 29 | ensuring thread safety. This assumes use of the pthread_ interface; old-style 30 | Solaris threads are no longer supported. Thread-local allocation is on by 31 | default. Parallel marking is on by default (it could be disabled manually 32 | by configure --disable-parallel-mark option). 33 | 34 | It is also essential that gc.h be included in files that call pthread_create, 35 | pthread_join, pthread_detach, or dlopen. gc.h macro defines these to also do 36 | GC bookkeeping, etc. gc.h must be included with GC_THREADS macro defined 37 | first, otherwise these replacements are not visible. A collector built in 38 | this way may only be used by programs that are linked with the threads library. 39 | 40 | Unless USE_PROC_FOR_LIBRARIES is defined, dlopen disables collection 41 | temporarily. In some unlikely cases, this can result in unpleasant heap 42 | growth. But it seems better than the race/deadlock issues we had before. 43 | 44 | If threads are used on an x86 processor with malloc redirected to 45 | GC_malloc, it is necessary to call GC_INIT explicitly before forking the 46 | first thread. (This avoids a deadlock arising from calling GC_thr_init 47 | with the allocation lock held.) 48 | 49 | There could be an issue when using gc_cpp.h in conjunction with Solaris 50 | threads and Sun's C++ runtime. Apparently the overloaded new operator 51 | may be invoked by some iostream initialization code before threads are 52 | correctly initialized. This may cause a SIGSEGV during initialization 53 | of the garbage collector. Currently the only known workaround is to not 54 | invoke the garbage collector from a user defined global operator new, or to 55 | have it invoke the garbage-collector's allocators only after main has started. 56 | (Note that the latter requires a moderately expensive test in operator 57 | delete.) 58 | 59 | I encountered "symbol : offset .... is non-aligned" errors. These 60 | appear to be traceable to the use of the GNU assembler with the Sun linker. 61 | The former appears to generate a relocation not understood by the latter. 62 | The fix appears to be to use a consistent toolchain. (As a non-Solaris-expert 63 | my solution involved hacking the libtool script, but I'm sure you can 64 | do something less ugly.) 65 | 66 | Hans-J. Boehm 67 | (The above contains my personal opinions, which are probably not shared 68 | by anyone else.) 69 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/docs/platforms/README.symbian: -------------------------------------------------------------------------------- 1 | Instructions for Symbian: 2 | 1. Build: use libgc.mmp (the sample for s60v3 is provided below) 3 | 2. Limitations 4 | 2.1. No multi-threaded support yet 5 | 2.2. Be careful with limitation that emulator introduces: Static roots are not 6 | dynamically accessible (there are Symbian APIs for this purpose but are just 7 | stubs, returning irrelevant values). 8 | Consequently, on emulator, you can only use dlls or exe, and retrieve static 9 | roots by calling global_init_static_root per dll (or exe). 10 | On target, only libs are supported, because static roots are retrieved by 11 | linker flags, by calling global_init_static_root in main exe. 12 | 13 | 14 | bld.inf sample contents: 15 | 16 | PRJ_PLATFORMS 17 | default armv5 18 | 19 | PRJ_MMPFILES 20 | libgc.mmp 21 | 22 | 23 | libgc.mmp sample contents: 24 | 25 | TARGET libgc.dll 26 | 27 | TARGETTYPE dll 28 | UID 0x1000008d 0x200107C2 // check uid 29 | 30 | EXPORTUNFROZEN 31 | EPOCALLOWDLLDATA 32 | 33 | CAPABILITY PowerMgmt ReadDeviceData ReadUserData WriteDeviceData WriteUserData SwEvent LocalServices NetworkServices UserEnvironment 34 | 35 | MACRO ALL_INTERIOR_POINTERS 36 | MACRO NO_EXECUTE_PERMISSION 37 | MACRO USE_MMAP 38 | MACRO GC_ATOMIC_UNCOLLECTABLE 39 | MACRO GC_DONT_REGISTER_MAIN_STATIC_DATA 40 | MACRO GC_DLL 41 | MACRO JAVA_FINALIZATION 42 | MACRO SYMBIAN 43 | MACRO ENABLE_DISCLAIM 44 | 45 | USERINCLUDE .\include 46 | USERINCLUDE .\include\private 47 | 48 | SYSTEMINCLUDE \epoc32\include 49 | SYSTEMINCLUDE \epoc32\include\stdapis 50 | 51 | SOURCEPATH . 52 | 53 | SOURCE extra/gc.c 54 | SOURCE extra/symbian.cpp 55 | 56 | SOURCE extra/symbian/global_end.cpp 57 | SOURCE extra/symbian/global_start.cpp 58 | SOURCE extra/symbian/init_global_static_roots.cpp 59 | 60 | STATICLIBRARY libcrt0.lib 61 | LIBRARY libc.lib 62 | LIBRARY euser.lib 63 | LIBRARY efsrv.lib 64 | LIBRARY avkon.lib 65 | LIBRARY eikcore.lib 66 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/docs/platforms/README.uts: -------------------------------------------------------------------------------- 1 | Alistair Crooks supplied the port. He used Lexa C version 2.1.3 with 2 | -Xa to compile. 3 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/docs/platforms/README.win64: -------------------------------------------------------------------------------- 1 | 64-bit Windows on AMD64/Intel EM64T (x64) is supported. A collector can be 2 | built with Microsoft Visual C++ 2005 or with mingw-w64 gcc. 3 | 4 | NT_MAKEFILE has been used in this environment. Type 5 | "nmake -f NT_MAKEFILE cpu=AMD64 nodebug=1" in a Visual C++ command line 6 | window to build the release variant of the dynamic library with threads 7 | support. 8 | To verify that the collector is at least somewhat functional, 9 | type "nmake -f NT_MAKEFILE cpu=AMD64 check" to build and run the usual test 10 | programs. This should create gctest.gc.log after a few seconds. 11 | 12 | cpptest.exe might not run correctly in case of dynamic GC linking. (It seems 13 | that we're getting wrong instances of operator new/delete in some cases.) 14 | 15 | This process is completely analogous to NT_MAKEFILE usage 16 | for the 32-bit library version. 17 | 18 | A similar procedure using NT_MAKEFILE is applicable to build the static 19 | library - just pass "enable_static=1" as an extra argument to nmake. 20 | If needed, it is also possible to build the library without threads 21 | support - this could be done by passing "disable_threads=1" argument to nmake. 22 | 23 | Note that some warnings have been explicitly turned off in the makefile. 24 | 25 | VC++ note: to suppress warnings -D_CRT_SECURE_NO_DEPRECATE is used. 26 | 27 | gcc note: -fno-strict-aliasing should be used if optimizing. 28 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/extra/MacOS.c: -------------------------------------------------------------------------------- 1 | /* 2 | MacOS.c 3 | 4 | Some routines for the Macintosh OS port of the Hans-J. Boehm, Alan J. Demers 5 | garbage collector. 6 | 7 | 8 | 9 | 11/22/94 pcb StripAddress the temporary memory handle for 24-bit mode. 10 | 11/30/94 pcb Tracking all memory usage so we can deallocate it all at once. 11 | 02/10/96 pcb Added routine to perform a final collection when 12 | unloading shared library. 13 | 14 | by Patrick C. Beard. 15 | */ 16 | /* Boehm, February 15, 1996 2:55 pm PST */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #define GC_BUILD 26 | #include "gc.h" 27 | #include "private/gc_priv.h" 28 | 29 | /* use 'CODE' resource 0 to get exact location of the beginning of global space. */ 30 | 31 | typedef struct { 32 | unsigned long aboveA5; 33 | unsigned long belowA5; 34 | unsigned long JTSize; 35 | unsigned long JTOffset; 36 | } *CodeZeroPtr, **CodeZeroHandle; 37 | 38 | void* GC_MacGetDataStart(void) 39 | { 40 | CodeZeroHandle code0 = (CodeZeroHandle)GetResource('CODE', 0); 41 | if (code0) { 42 | long belowA5Size = (**code0).belowA5; 43 | ReleaseResource((Handle)code0); 44 | return (LMGetCurrentA5() - belowA5Size); 45 | } 46 | fprintf(stderr, "Couldn't load the jump table."); 47 | exit(-1); 48 | # if !defined(CPPCHECK) 49 | return 0; /* to avoid compiler complain about missing return */ 50 | # endif 51 | } 52 | 53 | #ifdef USE_TEMPORARY_MEMORY 54 | 55 | /* track the use of temporary memory so it can be freed all at once. */ 56 | 57 | typedef struct TemporaryMemoryBlock TemporaryMemoryBlock, **TemporaryMemoryHandle; 58 | 59 | struct TemporaryMemoryBlock { 60 | TemporaryMemoryHandle nextBlock; 61 | char data[]; 62 | }; 63 | 64 | static TemporaryMemoryHandle theTemporaryMemory = NULL; 65 | 66 | void GC_MacFreeTemporaryMemory(void); 67 | 68 | Ptr GC_MacTemporaryNewPtr(size_t size, Boolean clearMemory) 69 | { 70 | # if !defined(SHARED_LIBRARY_BUILD) 71 | static Boolean firstTime = true; 72 | # endif 73 | OSErr result; 74 | TemporaryMemoryHandle tempMemBlock; 75 | Ptr tempPtr = nil; 76 | 77 | tempMemBlock = (TemporaryMemoryHandle)TempNewHandle(size + sizeof(TemporaryMemoryBlock), &result); 78 | if (tempMemBlock && result == noErr) { 79 | HLockHi((Handle)tempMemBlock); 80 | tempPtr = (**tempMemBlock).data; 81 | if (clearMemory) memset(tempPtr, 0, size); 82 | tempPtr = StripAddress(tempPtr); 83 | 84 | /* keep track of the allocated blocks. */ 85 | (**tempMemBlock).nextBlock = theTemporaryMemory; 86 | theTemporaryMemory = tempMemBlock; 87 | } 88 | 89 | # if !defined(SHARED_LIBRARY_BUILD) 90 | /* install an exit routine to clean up the memory used at the end. */ 91 | if (firstTime) { 92 | atexit(&GC_MacFreeTemporaryMemory); 93 | firstTime = false; 94 | } 95 | # endif 96 | 97 | return tempPtr; 98 | } 99 | 100 | static void perform_final_collection(void) 101 | { 102 | unsigned i; 103 | word last_fo_entries = 0; 104 | 105 | /* adjust the stack bottom, because CFM calls us from another stack 106 | location. */ 107 | GC_stackbottom = (ptr_t)&i; 108 | 109 | /* try to collect and finalize everything in sight */ 110 | for (i = 0; i < 2 || GC_fo_entries < last_fo_entries; i++) { 111 | last_fo_entries = GC_fo_entries; 112 | GC_gcollect(); 113 | } 114 | } 115 | 116 | 117 | void GC_MacFreeTemporaryMemory(void) 118 | { 119 | # if defined(SHARED_LIBRARY_BUILD) 120 | /* if possible, collect all memory, and invoke all finalizers. */ 121 | perform_final_collection(); 122 | # endif 123 | 124 | if (theTemporaryMemory != NULL) { 125 | TemporaryMemoryHandle tempMemBlock = theTemporaryMemory; 126 | while (tempMemBlock /* != NULL */) { 127 | TemporaryMemoryHandle nextBlock = (**tempMemBlock).nextBlock; 128 | DisposeHandle((Handle)tempMemBlock); 129 | tempMemBlock = nextBlock; 130 | } 131 | theTemporaryMemory = NULL; 132 | } 133 | } 134 | 135 | #endif /* USE_TEMPORARY_MEMORY */ 136 | 137 | #if __option(far_data) 138 | 139 | void* GC_MacGetDataEnd(void) 140 | { 141 | CodeZeroHandle code0 = (CodeZeroHandle)GetResource('CODE', 0); 142 | if (code0) { 143 | long aboveA5Size = (**code0).aboveA5; 144 | ReleaseResource((Handle)code0); 145 | return (LMGetCurrentA5() + aboveA5Size); 146 | } 147 | fprintf(stderr, "Couldn't load the jump table."); 148 | exit(-1); 149 | # if !defined(CPPCHECK) 150 | return 0; 151 | # endif 152 | } 153 | 154 | #endif /* __option(far_data) */ 155 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/extra/Mac_files/MacOS_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | MacOS_config.h 3 | 4 | Configuration flags for Macintosh development systems. 5 | 6 | 7 | 8 | 11/16/95 pcb Updated compilation flags to reflect latest 4.6 Makefile. 9 | 10 | by Patrick C. Beard. 11 | */ 12 | /* Boehm, November 17, 1995 12:10 pm PST */ 13 | 14 | #ifdef __MWERKS__ 15 | /* for CodeWarrior Pro with Metrowerks Standard Library (MSL). */ 16 | /* #define MSL_USE_PRECOMPILED_HEADERS 0 */ 17 | #include 18 | #endif /* __MWERKS__ */ 19 | 20 | /* these are defined again in gc_priv.h. */ 21 | #undef TRUE 22 | #undef FALSE 23 | 24 | #define ALL_INTERIOR_POINTERS /* follows interior pointers. */ 25 | /* #define DONT_ADD_BYTE_AT_END */ /* no padding. */ 26 | /* #define SMALL_CONFIG */ /* whether to use a smaller heap. */ 27 | #define USE_TEMPORARY_MEMORY /* use Macintosh temporary memory. */ 28 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/extra/Mac_files/dataend.c: -------------------------------------------------------------------------------- 1 | /* 2 | dataend.c 3 | 4 | A hack to get the extent of global data for the Macintosh. 5 | 6 | by Patrick C. Beard. 7 | */ 8 | 9 | long __dataend; 10 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/extra/Mac_files/datastart.c: -------------------------------------------------------------------------------- 1 | /* 2 | datastart.c 3 | 4 | A hack to get the extent of global data for the Macintosh. 5 | 6 | by Patrick C. Beard. 7 | */ 8 | 9 | long __datastart; 10 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/extra/gc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | * Copyright (c) 1996 by Silicon Graphics. All rights reserved. 4 | * Copyright (c) 1998 by Fergus Henderson. All rights reserved. 5 | * Copyright (c) 2000-2009 by Hewlett-Packard Development Company. 6 | * All rights reserved. 7 | * Copyright (c) 2009-2018 Ivan Maidanski 8 | * 9 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 10 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 11 | * 12 | * Permission is hereby granted to use or copy this program 13 | * for any purpose, provided the above notices are retained on all copies. 14 | * Permission to modify the code and to distribute modified code is granted, 15 | * provided the above notices are retained, and a notice that the code was 16 | * modified is included with the above copyright notice. 17 | */ 18 | 19 | /* This file could be used for the following purposes: */ 20 | /* - get the complete GC as a single link object file (module); */ 21 | /* - enable more compiler optimizations. */ 22 | 23 | /* Tip: to get the highest level of compiler optimizations, the typical */ 24 | /* compiler options (GCC) to use are: */ 25 | /* -O3 -fno-strict-aliasing -march=native -Wall -fprofile-generate/use */ 26 | 27 | /* Warning: GCC for Linux (for C++ clients only): Use -fexceptions both */ 28 | /* for GC and the client otherwise GC_thread_exit_proc() is not */ 29 | /* guaranteed to be invoked (see the comments in pthread_start.c). */ 30 | 31 | #ifndef __cplusplus 32 | /* static is desirable here for more efficient linkage. */ 33 | /* TODO: Enable this in case of the compilation as C++ code. */ 34 | # define GC_INNER STATIC 35 | # define GC_EXTERN GC_INNER 36 | /* STATIC is defined in gcconfig.h. */ 37 | #endif 38 | 39 | /* Small files go first... */ 40 | #include "../backgraph.c" 41 | #include "../blacklst.c" 42 | #include "../checksums.c" 43 | #include "../gcj_mlc.c" 44 | #include "../headers.c" 45 | #include "../new_hblk.c" 46 | #include "../obj_map.c" 47 | #include "../ptr_chck.c" 48 | 49 | #include "../allchblk.c" 50 | #include "../alloc.c" 51 | #include "../dbg_mlc.c" 52 | #include "../finalize.c" 53 | #include "../fnlz_mlc.c" 54 | #include "../malloc.c" 55 | #include "../mallocx.c" 56 | #include "../mark.c" 57 | #include "../mark_rts.c" 58 | #include "../reclaim.c" 59 | #include "../typd_mlc.c" 60 | 61 | #include "../misc.c" 62 | #include "../os_dep.c" 63 | #include "../thread_local_alloc.c" 64 | 65 | /* Most platform-specific files go here... */ 66 | #include "../darwin_stop_world.c" 67 | #include "../dyn_load.c" 68 | #include "../gc_dlopen.c" 69 | #if !defined(PLATFORM_MACH_DEP) 70 | # include "../mach_dep.c" 71 | #endif 72 | #if !defined(PLATFORM_STOP_WORLD) 73 | # include "../pthread_stop_world.c" 74 | #endif 75 | #include "../pthread_support.c" 76 | #include "../specific.c" 77 | #include "../win32_threads.c" 78 | 79 | #ifndef GC_PTHREAD_START_STANDALONE 80 | # include "../pthread_start.c" 81 | #endif 82 | 83 | /* Restore pthread calls redirection (if altered in */ 84 | /* pthread_stop_world.c, pthread_support.c or win32_threads.c). */ 85 | /* This is only useful if directly included from application */ 86 | /* (instead of linking gc). */ 87 | #ifndef GC_NO_THREAD_REDIRECTS 88 | # define GC_PTHREAD_REDIRECTS_ONLY 89 | # include "gc/gc_pthread_redirects.h" 90 | #endif 91 | 92 | /* The files from "extra" folder are not included. */ 93 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/extra/pcr_interface.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to use or copy this program 8 | * for any purpose, provided the above notices are retained on all copies. 9 | * Permission to modify the code and to distribute modified code is granted, 10 | * provided the above notices are retained, and a notice that the code was 11 | * modified is included with the above copyright notice. 12 | */ 13 | # include "private/gc_priv.h" 14 | 15 | # ifdef PCR 16 | /* 17 | * We wrap all of the allocator functions to avoid questions of 18 | * compatibility between the prototyped and nonprototyped versions of the f 19 | */ 20 | # include "config/PCR_StdTypes.h" 21 | # include "mm/PCR_MM.h" 22 | # include 23 | 24 | # define MY_MAGIC 17L 25 | # define MY_DEBUGMAGIC 42L 26 | 27 | void * GC_AllocProc(size_t size, PCR_Bool ptrFree, PCR_Bool clear ) 28 | { 29 | if (ptrFree) { 30 | void * result = (void *)GC_malloc_atomic(size); 31 | if (clear && result != 0) BZERO(result, size); 32 | return(result); 33 | } else { 34 | return((void *)GC_malloc(size)); 35 | } 36 | } 37 | 38 | void * GC_DebugAllocProc(size_t size, PCR_Bool ptrFree, PCR_Bool clear ) 39 | { 40 | if (ptrFree) { 41 | void * result = (void *)GC_debug_malloc_atomic(size, __FILE__, 42 | __LINE__); 43 | if (clear && result != 0) BZERO(result, size); 44 | return(result); 45 | } else { 46 | return((void *)GC_debug_malloc(size, __FILE__, __LINE__)); 47 | } 48 | } 49 | 50 | # define GC_ReallocProc GC_realloc 51 | void * GC_DebugReallocProc(void * old_object, size_t new_size_in_bytes) 52 | { 53 | return(GC_debug_realloc(old_object, new_size_in_bytes, __FILE__, __LINE__)); 54 | } 55 | 56 | # define GC_FreeProc GC_free 57 | # define GC_DebugFreeProc GC_debug_free 58 | 59 | typedef struct { 60 | PCR_ERes (*ed_proc)(void *p, size_t size, PCR_Any data); 61 | GC_bool ed_pointerfree; 62 | PCR_ERes ed_fail_code; 63 | PCR_Any ed_client_data; 64 | } enumerate_data; 65 | 66 | void GC_enumerate_block(struct hblk *h, enumerate_data * ed) 67 | { 68 | hdr * hhdr; 69 | size_t sz; 70 | ptr_t p; 71 | ptr_t lim; 72 | word descr; 73 | 74 | # if !defined(CPPCHECK) 75 | # error This code was updated without testing. 76 | # error and its precursor was clearly broken. 77 | # endif 78 | hhdr = HDR(h); 79 | descr = hhdr -> hb_descr; 80 | sz = (size_t)hhdr->hb_sz; 81 | if (descr != 0 && ed -> ed_pointerfree 82 | || descr == 0 && !(ed -> ed_pointerfree)) return; 83 | lim = (ptr_t)(h+1) - sz; 84 | p = (ptr_t)h; 85 | do { 86 | if (PCR_ERes_IsErr(ed -> ed_fail_code)) return; 87 | ed -> ed_fail_code = 88 | (*(ed -> ed_proc))(p, sz, ed -> ed_client_data); 89 | p+= sz; 90 | } while ((word)p <= (word)lim); 91 | } 92 | 93 | struct PCR_MM_ProcsRep * GC_old_allocator = 0; 94 | 95 | PCR_ERes GC_EnumerateProc( 96 | PCR_Bool ptrFree, 97 | PCR_ERes (*proc)(void *p, size_t size, PCR_Any data), 98 | PCR_Any data 99 | ) 100 | { 101 | enumerate_data ed; 102 | 103 | ed.ed_proc = proc; 104 | ed.ed_pointerfree = ptrFree; 105 | ed.ed_fail_code = PCR_ERes_okay; 106 | ed.ed_client_data = data; 107 | GC_apply_to_all_blocks(GC_enumerate_block, &ed); 108 | if (ed.ed_fail_code != PCR_ERes_okay) { 109 | return(ed.ed_fail_code); 110 | } else { 111 | /* Also enumerate objects allocated by my predecessors */ 112 | return((*(GC_old_allocator->mmp_enumerate))(ptrFree, proc, data)); 113 | } 114 | } 115 | 116 | void GC_DummyFreeProc(void *p) {} 117 | 118 | void GC_DummyShutdownProc(void) {} 119 | 120 | struct PCR_MM_ProcsRep GC_Rep = { 121 | MY_MAGIC, 122 | GC_AllocProc, 123 | GC_ReallocProc, 124 | GC_DummyFreeProc, /* mmp_free */ 125 | GC_FreeProc, /* mmp_unsafeFree */ 126 | GC_EnumerateProc, 127 | GC_DummyShutdownProc /* mmp_shutdown */ 128 | }; 129 | 130 | struct PCR_MM_ProcsRep GC_DebugRep = { 131 | MY_DEBUGMAGIC, 132 | GC_DebugAllocProc, 133 | GC_DebugReallocProc, 134 | GC_DummyFreeProc, /* mmp_free */ 135 | GC_DebugFreeProc, /* mmp_unsafeFree */ 136 | GC_EnumerateProc, 137 | GC_DummyShutdownProc /* mmp_shutdown */ 138 | }; 139 | 140 | GC_bool GC_use_debug = 0; 141 | 142 | void GC_pcr_install() 143 | { 144 | PCR_MM_Install((GC_use_debug? &GC_DebugRep : &GC_Rep), &GC_old_allocator); 145 | } 146 | 147 | PCR_ERes 148 | PCR_GC_Setup(void) 149 | { 150 | return PCR_ERes_okay; 151 | } 152 | 153 | extern GC_bool GC_quiet; 154 | 155 | PCR_ERes 156 | PCR_GC_Run(void) 157 | { 158 | 159 | if( !PCR_Base_TestPCRArg("-nogc") ) { 160 | GC_quiet = ( PCR_Base_TestPCRArg("-gctrace") ? 0 : 1 ); 161 | GC_use_debug = (GC_bool)PCR_Base_TestPCRArg("-debug_alloc"); 162 | GC_init(); 163 | if( !PCR_Base_TestPCRArg("-nogc_incremental") ) { 164 | /* 165 | * awful hack to test whether VD is implemented ... 166 | */ 167 | if( PCR_VD_Start( 0, NIL, 0) != PCR_ERes_FromErr(ENOSYS) ) { 168 | GC_enable_incremental(); 169 | } 170 | } 171 | } 172 | return PCR_ERes_okay; 173 | } 174 | 175 | void GC_push_thread_structures(void) 176 | { 177 | /* PCR doesn't work unless static roots are pushed. Can't get here. */ 178 | ABORT("In GC_push_thread_structures()"); 179 | } 180 | 181 | # endif 182 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/extra/real_malloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers 3 | * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. 4 | * 5 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 6 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 7 | * 8 | * Permission is hereby granted to use or copy this program 9 | * for any purpose, provided the above notices are retained on all copies. 10 | * Permission to modify the code and to distribute modified code is granted, 11 | * provided the above notices are retained, and a notice that the code was 12 | * modified is included with the above copyright notice. 13 | */ 14 | 15 | # ifdef HAVE_CONFIG_H 16 | # include "config.h" 17 | # endif 18 | 19 | # ifdef PCR 20 | /* 21 | * This definition should go in its own file that includes no other 22 | * header files. Otherwise, we risk not getting the underlying system 23 | * malloc. 24 | */ 25 | # define PCR_NO_RENAME 26 | # include 27 | 28 | void * real_malloc(size_t size) 29 | { 30 | return malloc(size); 31 | } 32 | 33 | # else 34 | 35 | extern int GC_quiet; 36 | /* ANSI C doesn't allow translation units to be empty. */ 37 | /* So we guarantee this one is nonempty. */ 38 | 39 | #endif /* PCR */ 40 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/extra/symbian.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | extern "C" { 10 | 11 | int GC_get_main_symbian_stack_base() 12 | { 13 | TThreadStackInfo aInfo; 14 | TInt err = RThread().StackInfo(aInfo); 15 | if ( !err ) 16 | { 17 | return aInfo.iBase; 18 | } 19 | else 20 | { 21 | return 0; 22 | } 23 | } 24 | 25 | char* GC_get_private_path_and_zero_file() 26 | { 27 | // always on c: drive 28 | RFs fs; 29 | fs.Connect(); 30 | fs.CreatePrivatePath( EDriveC ); 31 | TFileName path; 32 | fs.PrivatePath( path ); 33 | fs.Close(); 34 | _LIT( KCDrive, "c:" ); 35 | path.Insert( 0, KCDrive ); 36 | 37 | 38 | //convert to char*, assume ascii 39 | TBuf8 path8; 40 | path8.Copy( path ); 41 | _LIT8( KZero8, "zero" ); 42 | path8.Append( KZero8 ); 43 | 44 | size_t size = path8.Length() + 1; 45 | char* copyChar = (char*) malloc( size ); 46 | if (copyChar) 47 | memcpy( copyChar, path8.PtrZ(), size ); 48 | 49 | return copyChar; // ownership passed 50 | } 51 | 52 | } /* extern "C" */ 53 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/extra/symbian/global_end.cpp: -------------------------------------------------------------------------------- 1 | // Symbian-specific file. 2 | 3 | // INCLUDE FILES 4 | #include "private/gcconfig.h" 5 | 6 | extern "C" { 7 | 8 | int winscw_data_end; 9 | 10 | } /* extern "C" */ 11 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/extra/symbian/global_start.cpp: -------------------------------------------------------------------------------- 1 | // Symbian-specific file. 2 | 3 | // INCLUDE FILES 4 | #include "private/gcconfig.h" 5 | 6 | extern "C" { 7 | 8 | int winscw_data_start; 9 | 10 | } /* extern "C" */ 11 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/extra/symbian/init_global_static_roots.cpp: -------------------------------------------------------------------------------- 1 | // Symbian-specific file. 2 | 3 | // INCLUDE FILES 4 | #include 5 | 6 | #include "private/gcconfig.h" 7 | #include "gc.h" 8 | 9 | extern "C" { 10 | 11 | void GC_init_global_static_roots() 12 | { 13 | ptr_t dataStart = NULL; 14 | ptr_t dataEnd = NULL; 15 | # if defined (__WINS__) 16 | extern int winscw_data_start, winscw_data_end; 17 | dataStart = ((ptr_t)&winscw_data_start); 18 | dataEnd = ((ptr_t)&winscw_data_end); 19 | # else 20 | extern int Image$$RW$$Limit[], Image$$RW$$Base[]; 21 | dataStart = ((ptr_t)Image$$RW$$Base); 22 | dataEnd = ((ptr_t)Image$$RW$$Limit); 23 | # endif 24 | 25 | GC_add_roots(dataStart, dataEnd); 26 | } 27 | 28 | } /* extern "C" */ 29 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/fnlz_mlc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011 by Hewlett-Packard Company. All rights reserved. 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to use or copy this program 8 | * for any purpose, provided the above notices are retained on all copies. 9 | * Permission to modify the code and to distribute modified code is granted, 10 | * provided the above notices are retained, and a notice that the code was 11 | * modified is included with the above copyright notice. 12 | * 13 | */ 14 | 15 | #include "private/gc_priv.h" 16 | 17 | #ifdef ENABLE_DISCLAIM 18 | 19 | #include "gc/gc_disclaim.h" 20 | #include "private/dbg_mlc.h" /* for oh type */ 21 | 22 | #if defined(KEEP_BACK_PTRS) || defined(MAKE_BACK_GRAPH) 23 | /* The first bit is already used for a debug purpose. */ 24 | # define FINALIZER_CLOSURE_FLAG 0x2 25 | #else 26 | # define FINALIZER_CLOSURE_FLAG 0x1 27 | #endif 28 | 29 | STATIC int GC_CALLBACK GC_finalized_disclaim(void *obj) 30 | { 31 | # ifdef AO_HAVE_load 32 | word fc_word = (word)AO_load((volatile AO_t *)obj); 33 | # else 34 | word fc_word = *(word *)obj; 35 | # endif 36 | 37 | if ((fc_word & FINALIZER_CLOSURE_FLAG) != 0) { 38 | /* The disclaim function may be passed fragments from the */ 39 | /* free-list, on which it should not run finalization. */ 40 | /* To recognize this case, we use the fact that the first word */ 41 | /* on such fragments is always multiple of 4 (a link to the next */ 42 | /* fragment, or NULL). If it is desirable to have a finalizer */ 43 | /* which does not use the first word for storing finalization */ 44 | /* info, GC_disclaim_and_reclaim() must be extended to clear */ 45 | /* fragments so that the assumption holds for the selected word. */ 46 | const struct GC_finalizer_closure *fc 47 | = (struct GC_finalizer_closure *)(fc_word 48 | & ~(word)FINALIZER_CLOSURE_FLAG); 49 | GC_ASSERT(!GC_find_leak); 50 | (*fc->proc)((word *)obj + 1, fc->cd); 51 | } 52 | return 0; 53 | } 54 | 55 | STATIC void GC_register_disclaim_proc_inner(unsigned kind, 56 | GC_disclaim_proc proc, 57 | GC_bool mark_unconditionally) 58 | { 59 | GC_ASSERT(kind < MAXOBJKINDS); 60 | if (EXPECT(GC_find_leak, FALSE)) return; 61 | 62 | GC_obj_kinds[kind].ok_disclaim_proc = proc; 63 | GC_obj_kinds[kind].ok_mark_unconditionally = mark_unconditionally; 64 | } 65 | 66 | GC_API void GC_CALL GC_init_finalized_malloc(void) 67 | { 68 | GC_init(); /* In case it's not already done. */ 69 | LOCK(); 70 | if (GC_finalized_kind != 0) { 71 | UNLOCK(); 72 | return; 73 | } 74 | 75 | /* The finalizer closure is placed in the first word in order to */ 76 | /* use the lower bits to distinguish live objects from objects on */ 77 | /* the free list. The downside of this is that we need one-word */ 78 | /* offset interior pointers, and that GC_base does not return the */ 79 | /* start of the user region. */ 80 | GC_register_displacement_inner(sizeof(word)); 81 | 82 | /* And, the pointer to the finalizer closure object itself is */ 83 | /* displaced due to baking in this indicator. */ 84 | GC_register_displacement_inner(FINALIZER_CLOSURE_FLAG); 85 | GC_register_displacement_inner(sizeof(oh) + FINALIZER_CLOSURE_FLAG); 86 | 87 | GC_finalized_kind = GC_new_kind_inner(GC_new_free_list_inner(), 88 | GC_DS_LENGTH, TRUE, TRUE); 89 | GC_ASSERT(GC_finalized_kind != 0); 90 | GC_register_disclaim_proc_inner(GC_finalized_kind, GC_finalized_disclaim, 91 | TRUE); 92 | UNLOCK(); 93 | } 94 | 95 | GC_API void GC_CALL GC_register_disclaim_proc(int kind, GC_disclaim_proc proc, 96 | int mark_unconditionally) 97 | { 98 | LOCK(); 99 | GC_register_disclaim_proc_inner((unsigned)kind, proc, 100 | (GC_bool)mark_unconditionally); 101 | UNLOCK(); 102 | } 103 | 104 | GC_API GC_ATTR_MALLOC void * GC_CALL GC_finalized_malloc(size_t lb, 105 | const struct GC_finalizer_closure *fclos) 106 | { 107 | void *op; 108 | 109 | GC_ASSERT(GC_finalized_kind != 0); 110 | GC_ASSERT(NONNULL_ARG_NOT_NULL(fclos)); 111 | GC_ASSERT(((word)fclos & FINALIZER_CLOSURE_FLAG) == 0); 112 | op = GC_malloc_kind(SIZET_SAT_ADD(lb, sizeof(word)), 113 | (int)GC_finalized_kind); 114 | if (EXPECT(NULL == op, FALSE)) 115 | return NULL; 116 | # ifdef AO_HAVE_store 117 | AO_store((volatile AO_t *)op, (AO_t)fclos | FINALIZER_CLOSURE_FLAG); 118 | # else 119 | *(word *)op = (word)fclos | FINALIZER_CLOSURE_FLAG; 120 | # endif 121 | GC_dirty(op); 122 | REACHABLE_AFTER_DIRTY(fclos); 123 | return (word *)op + 1; 124 | } 125 | 126 | #endif /* ENABLE_DISCLAIM */ 127 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/gc_badalc.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018-2020 Ivan Maidanski 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to use or copy this program 8 | * for any purpose, provided the above notices are retained on all copies. 9 | * Permission to modify the code and to distribute modified code is granted, 10 | * provided the above notices are retained, and a notice that the code was 11 | * modified is included with the above copyright notice. 12 | * 13 | */ 14 | 15 | // This file provides the implementation of GC_throw_bad_alloc() which 16 | // is invoked by GC operator "new" in case of an out-of-memory event. 17 | 18 | #ifdef HAVE_CONFIG_H 19 | # include "config.h" 20 | #endif 21 | 22 | #ifndef GC_BUILD 23 | # define GC_BUILD 24 | #endif 25 | 26 | #define GC_DONT_INCL_WINDOWS_H 27 | #include "gc/gc.h" 28 | 29 | #include // for bad_alloc, precedes include of gc_cpp.h 30 | 31 | #if defined(GC_NEW_ABORTS_ON_OOM) || defined(_LIBCPP_NO_EXCEPTIONS) 32 | # define GC_ALLOCATOR_THROW_OR_ABORT() GC_abort_on_oom() 33 | #else 34 | # define GC_ALLOCATOR_THROW_OR_ABORT() throw std::bad_alloc() 35 | #endif 36 | 37 | GC_API void GC_CALL GC_throw_bad_alloc() { 38 | GC_ALLOCATOR_THROW_OR_ABORT(); 39 | } 40 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/gc_badalc.cpp: -------------------------------------------------------------------------------- 1 | // Visual C++ seems to prefer a .cpp extension to .cc one. 2 | #include "gc_badalc.cc" 3 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/gc_cpp.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to use or copy this program 8 | * for any purpose, provided the above notices are retained on all copies. 9 | * Permission to modify the code and to distribute modified code is granted, 10 | * provided the above notices are retained, and a notice that the code was 11 | * modified is included with the above copyright notice. 12 | */ 13 | 14 | /************************************************************************* 15 | This implementation module for gc_cpp.h provides an implementation of 16 | the global operators "new" and "delete" that calls the Boehm 17 | allocator. All objects allocated by this implementation will be 18 | uncollectible but part of the root set of the collector. 19 | 20 | You should ensure (using implementation-dependent techniques) that the 21 | linker finds this module before the library that defines the default 22 | built-in "new" and "delete". 23 | **************************************************************************/ 24 | 25 | #ifdef HAVE_CONFIG_H 26 | # include "config.h" 27 | #endif 28 | 29 | #ifndef GC_BUILD 30 | # define GC_BUILD 31 | #endif 32 | 33 | #define GC_DONT_INCL_WINDOWS_H 34 | #include "gc/gc.h" 35 | 36 | #ifndef GC_INCLUDE_NEW 37 | # define GC_INCLUDE_NEW 38 | #endif 39 | #include "gc/gc_cpp.h" 40 | 41 | #if (!defined(_MSC_VER) && !defined(__DMC__) \ 42 | || defined(GC_NO_INLINE_STD_NEW)) && !defined(GC_INLINE_STD_NEW) 43 | 44 | # if defined(GC_NEW_ABORTS_ON_OOM) || defined(_LIBCPP_NO_EXCEPTIONS) 45 | # define GC_ALLOCATOR_THROW_OR_ABORT() GC_abort_on_oom() 46 | # else 47 | // Use bad_alloc() directly instead of GC_throw_bad_alloc() call. 48 | # define GC_ALLOCATOR_THROW_OR_ABORT() throw std::bad_alloc() 49 | # endif 50 | 51 | void* operator new(GC_SIZE_T size) GC_DECL_NEW_THROW 52 | { 53 | void* obj = GC_MALLOC_UNCOLLECTABLE(size); 54 | if (0 == obj) 55 | GC_ALLOCATOR_THROW_OR_ABORT(); 56 | return obj; 57 | } 58 | 59 | # ifdef _MSC_VER 60 | // This new operator is used by VC++ in case of Debug builds. 61 | void* operator new(GC_SIZE_T size, int /* nBlockUse */, 62 | const char* szFileName, int nLine) 63 | { 64 | # ifdef GC_DEBUG 65 | void* obj = GC_debug_malloc_uncollectable(size, szFileName, nLine); 66 | # else 67 | void* obj = GC_MALLOC_UNCOLLECTABLE(size); 68 | (void)szFileName; (void)nLine; 69 | # endif 70 | if (0 == obj) 71 | GC_ALLOCATOR_THROW_OR_ABORT(); 72 | return obj; 73 | } 74 | # endif // _MSC_VER 75 | 76 | void operator delete(void* obj) GC_NOEXCEPT 77 | { 78 | GC_FREE(obj); 79 | } 80 | 81 | # ifdef GC_OPERATOR_NEW_NOTHROW 82 | void* operator new(GC_SIZE_T size, const std::nothrow_t&) GC_NOEXCEPT 83 | { 84 | return GC_MALLOC_UNCOLLECTABLE(size); 85 | } 86 | 87 | void operator delete(void* obj, const std::nothrow_t&) GC_NOEXCEPT 88 | { 89 | GC_FREE(obj); 90 | } 91 | # endif // GC_OPERATOR_NEW_NOTHROW 92 | 93 | # if defined(GC_OPERATOR_NEW_ARRAY) && !defined(CPPCHECK) 94 | void* operator new[](GC_SIZE_T size) GC_DECL_NEW_THROW 95 | { 96 | void* obj = GC_MALLOC_UNCOLLECTABLE(size); 97 | if (0 == obj) 98 | GC_ALLOCATOR_THROW_OR_ABORT(); 99 | return obj; 100 | } 101 | 102 | # ifdef _MSC_VER 103 | // This new operator is used by VC++ 7+ in Debug builds. 104 | void* operator new[](GC_SIZE_T size, int nBlockUse, 105 | const char* szFileName, int nLine) 106 | { 107 | return operator new(size, nBlockUse, szFileName, nLine); 108 | } 109 | # endif // _MSC_VER 110 | 111 | void operator delete[](void* obj) GC_NOEXCEPT 112 | { 113 | GC_FREE(obj); 114 | } 115 | 116 | # ifdef GC_OPERATOR_NEW_NOTHROW 117 | void* operator new[](GC_SIZE_T size, const std::nothrow_t&) GC_NOEXCEPT 118 | { 119 | return GC_MALLOC_UNCOLLECTABLE(size); 120 | } 121 | 122 | void operator delete[](void* obj, const std::nothrow_t&) GC_NOEXCEPT 123 | { 124 | GC_FREE(obj); 125 | } 126 | # endif // GC_OPERATOR_NEW_NOTHROW 127 | # endif // GC_OPERATOR_NEW_ARRAY 128 | 129 | # ifdef GC_OPERATOR_SIZED_DELETE 130 | void operator delete(void* obj, GC_SIZE_T) GC_NOEXCEPT 131 | { 132 | GC_FREE(obj); 133 | } 134 | 135 | # if defined(GC_OPERATOR_NEW_ARRAY) && !defined(CPPCHECK) 136 | void operator delete[](void* obj, GC_SIZE_T) GC_NOEXCEPT 137 | { 138 | GC_FREE(obj); 139 | } 140 | # endif 141 | # endif // GC_OPERATOR_SIZED_DELETE 142 | 143 | #endif // !_MSC_VER && !__DMC__ || GC_NO_INLINE_STD_NEW 144 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/gc_cpp.cpp: -------------------------------------------------------------------------------- 1 | // Visual C++ seems to prefer a .cpp extension to .cc 2 | #include "gc_cpp.cc" 3 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/gc_dlopen.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. 3 | * Copyright (c) 1997 by Silicon Graphics. All rights reserved. 4 | * Copyright (c) 2000 by Hewlett-Packard Company. All rights reserved. 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | */ 15 | 16 | #include "private/gc_priv.h" 17 | 18 | /* This used to be in dyn_load.c. It was extracted into a separate */ 19 | /* file to avoid having to link against libdl.{a,so} if the client */ 20 | /* doesn't call dlopen. Of course this fails if the collector is in */ 21 | /* a dynamic library. -HB */ 22 | #if defined(GC_PTHREADS) && !defined(GC_NO_DLOPEN) 23 | 24 | #undef GC_MUST_RESTORE_REDEFINED_DLOPEN 25 | #if defined(dlopen) && !defined(GC_USE_LD_WRAP) 26 | /* To support various threads pkgs, gc.h interposes on dlopen by */ 27 | /* defining "dlopen" to be "GC_dlopen", which is implemented below. */ 28 | /* However, both GC_FirstDLOpenedLinkMap() and GC_dlopen() use the */ 29 | /* real system dlopen() in their implementation. We first remove */ 30 | /* gc.h's dlopen definition and restore it later, after GC_dlopen(). */ 31 | # undef dlopen 32 | # define GC_MUST_RESTORE_REDEFINED_DLOPEN 33 | #endif 34 | 35 | /* Make sure we're not in the middle of a collection, and make sure we */ 36 | /* don't start any. This is invoked prior to a dlopen call to avoid */ 37 | /* synchronization issues. We can't just acquire the allocation lock, */ 38 | /* since startup code in dlopen may try to allocate. This solution */ 39 | /* risks heap growth (or, even, heap overflow) in the presence of many */ 40 | /* dlopen calls in either a multi-threaded environment, or if the */ 41 | /* library initialization code allocates substantial amounts of GC'ed */ 42 | /* memory. */ 43 | #ifndef USE_PROC_FOR_LIBRARIES 44 | static void disable_gc_for_dlopen(void) 45 | { 46 | LOCK(); 47 | while (GC_incremental && GC_collection_in_progress()) { 48 | ENTER_GC(); 49 | GC_collect_a_little_inner(1000); 50 | EXIT_GC(); 51 | } 52 | ++GC_dont_gc; 53 | UNLOCK(); 54 | } 55 | #endif 56 | 57 | /* Redefine dlopen to guarantee mutual exclusion with */ 58 | /* GC_register_dynamic_libraries. Should probably happen for */ 59 | /* other operating systems, too. */ 60 | 61 | /* This is similar to WRAP/REAL_FUNC() in pthread_support.c. */ 62 | #ifdef GC_USE_LD_WRAP 63 | # define WRAP_DLFUNC(f) __wrap_##f 64 | # define REAL_DLFUNC(f) __real_##f 65 | void * REAL_DLFUNC(dlopen)(const char *, int); 66 | #else 67 | # define WRAP_DLFUNC(f) GC_##f 68 | # define REAL_DLFUNC(f) f 69 | #endif 70 | 71 | GC_API void * WRAP_DLFUNC(dlopen)(const char *path, int mode) 72 | { 73 | void * result; 74 | 75 | # ifndef USE_PROC_FOR_LIBRARIES 76 | /* Disable collections. This solution risks heap growth (or, */ 77 | /* even, heap overflow) but there seems no better solutions. */ 78 | disable_gc_for_dlopen(); 79 | # endif 80 | result = REAL_DLFUNC(dlopen)(path, mode); 81 | # ifndef USE_PROC_FOR_LIBRARIES 82 | GC_enable(); /* undoes disable_gc_for_dlopen */ 83 | # endif 84 | return result; 85 | } 86 | 87 | #ifdef GC_USE_LD_WRAP 88 | /* Define GC_ function as an alias for the plain one, which will be */ 89 | /* intercepted. This allows files which include gc.h, and hence */ 90 | /* generate references to the GC_ symbol, to see the right symbol. */ 91 | GC_API void *GC_dlopen(const char *path, int mode) 92 | { 93 | return dlopen(path, mode); 94 | } 95 | #endif /* GC_USE_LD_WRAP */ 96 | 97 | #ifdef GC_MUST_RESTORE_REDEFINED_DLOPEN 98 | # define dlopen GC_dlopen 99 | #endif 100 | 101 | #endif /* GC_PTHREADS && !GC_NO_DLOPEN */ 102 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/ia64_save_regs_in_stack.s: -------------------------------------------------------------------------------- 1 | .text 2 | .align 16 3 | .global GC_save_regs_in_stack 4 | .proc GC_save_regs_in_stack 5 | GC_save_regs_in_stack: 6 | .body 7 | flushrs 8 | ;; 9 | mov r8=ar.bsp 10 | br.ret.sptk.few rp 11 | .endp GC_save_regs_in_stack 12 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/include/gc.h: -------------------------------------------------------------------------------- 1 | /* This file is installed for backward compatibility. */ 2 | #include "gc/gc.h" 3 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/include/gc/cord_pos.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1993-1994 by Xerox Corporation. All rights reserved. 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to use or copy this program 8 | * for any purpose, provided the above notices are retained on all copies. 9 | * Permission to modify the code and to distribute modified code is granted, 10 | * provided the above notices are retained, and a notice that the code was 11 | * modified is included with the above copyright notice. 12 | */ 13 | 14 | /* This should never be included directly; included only from cord.h. */ 15 | #if !defined(CORD_POSITION_H) && defined(CORD_H) 16 | #define CORD_POSITION_H 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | /* The representation of CORD_position. This is private to the */ 23 | /* implementation, but the size is known to clients. Also */ 24 | /* the implementation of some exported macros relies on it. */ 25 | /* Don't use anything defined here and not in cord.h. */ 26 | 27 | # define MAX_DEPTH 48 28 | /* The maximum depth of a balanced cord + 1. */ 29 | /* We don't let cords get deeper than MAX_DEPTH. */ 30 | 31 | struct CORD_pe { 32 | CORD pe_cord; 33 | size_t pe_start_pos; 34 | }; 35 | 36 | /* A structure describing an entry on the path from the root */ 37 | /* to current position. */ 38 | typedef struct CORD_Pos { 39 | size_t cur_pos; 40 | int path_len; 41 | # define CORD_POS_INVALID (0x55555555) 42 | /* path_len == INVALID <==> position invalid */ 43 | const char *cur_leaf; /* Current leaf, if it is a string. */ 44 | /* If the current leaf is a function, */ 45 | /* then this may point to function_buf */ 46 | /* containing the next few characters. */ 47 | /* Always points to a valid string */ 48 | /* containing the current character */ 49 | /* unless cur_end is 0. */ 50 | size_t cur_start; /* Start position of cur_leaf. */ 51 | size_t cur_end; /* Ending position of cur_leaf; */ 52 | /* 0 if cur_leaf is invalid. */ 53 | struct CORD_pe path[MAX_DEPTH + 1]; 54 | /* path[path_len] is the leaf corresponding to cur_pos */ 55 | /* path[0].pe_cord is the cord we point to. */ 56 | # define FUNCTION_BUF_SZ 8 57 | char function_buf[FUNCTION_BUF_SZ]; /* Space for next few chars */ 58 | /* from function node. */ 59 | } CORD_pos[1]; 60 | 61 | /* Extract the cord from a position: */ 62 | CORD_API CORD CORD_pos_to_cord(CORD_pos p); 63 | 64 | /* Extract the current index from a position: */ 65 | CORD_API size_t CORD_pos_to_index(CORD_pos p); 66 | 67 | /* Fetch the character located at the given position: */ 68 | CORD_API char CORD_pos_fetch(CORD_pos p); 69 | 70 | /* Initialize the position to refer to the give cord and index. */ 71 | /* Note that this is the most expensive function on positions: */ 72 | CORD_API void CORD_set_pos(CORD_pos p, CORD x, size_t i); 73 | 74 | /* Advance the position to the next character. */ 75 | /* P must be initialized and valid. */ 76 | /* Invalidates p if past end: */ 77 | CORD_API void CORD_next(CORD_pos p); 78 | 79 | /* Move the position to the preceding character. */ 80 | /* P must be initialized and valid. */ 81 | /* Invalidates p if past beginning: */ 82 | CORD_API void CORD_prev(CORD_pos p); 83 | 84 | /* Is the position valid, i.e. inside the cord? */ 85 | CORD_API int CORD_pos_valid(CORD_pos p); 86 | 87 | CORD_API char CORD__pos_fetch(CORD_pos); 88 | CORD_API void CORD__next(CORD_pos); 89 | CORD_API void CORD__prev(CORD_pos); 90 | 91 | #define CORD_pos_fetch(p) \ 92 | ((p)[0].cur_end != 0 ? \ 93 | (p)[0].cur_leaf[(p)[0].cur_pos - (p)[0].cur_start] \ 94 | : CORD__pos_fetch(p)) 95 | 96 | #define CORD_next(p) \ 97 | ((p)[0].cur_pos + 1 < (p)[0].cur_end ? \ 98 | (p)[0].cur_pos++ \ 99 | : (CORD__next(p), 0U)) 100 | 101 | #define CORD_prev(p) \ 102 | ((p)[0].cur_end != 0 && (p)[0].cur_pos > (p)[0].cur_start ? \ 103 | (p)[0].cur_pos-- \ 104 | : (CORD__prev(p), 0U)) 105 | 106 | #define CORD_pos_to_index(p) ((p)[0].cur_pos) 107 | 108 | #define CORD_pos_to_cord(p) ((p)[0].path[0].pe_cord) 109 | 110 | #define CORD_pos_valid(p) ((p)[0].path_len != CORD_POS_INVALID) 111 | 112 | /* Some grubby stuff for performance-critical friends: */ 113 | #define CORD_pos_chars_left(p) ((long)(p)[0].cur_end - (long)(p)[0].cur_pos) 114 | /* Number of characters in cache. <= 0 ==> none */ 115 | 116 | #define CORD_pos_advance(p,n) ((p)[0].cur_pos += (n) - 1, CORD_next(p)) 117 | /* Advance position by n characters; */ 118 | /* 0 < n < CORD_pos_chars_left(p). */ 119 | 120 | #define CORD_pos_cur_char_addr(p) \ 121 | ((p)[0].cur_leaf + ((p)[0].cur_pos - (p)[0].cur_start)) 122 | /* Address of the current character in cache. */ 123 | 124 | #ifdef __cplusplus 125 | } /* extern "C" */ 126 | #endif 127 | 128 | #endif 129 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/include/gc/ec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1993-1994 by Xerox Corporation. All rights reserved. 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to use or copy this program 8 | * for any purpose, provided the above notices are retained on all copies. 9 | * Permission to modify the code and to distribute modified code is granted, 10 | * provided the above notices are retained, and a notice that the code was 11 | * modified is included with the above copyright notice. 12 | */ 13 | 14 | #ifndef EC_H 15 | #define EC_H 16 | 17 | #ifndef CORD_H 18 | # include "cord.h" 19 | #endif 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | /* Extensible cords are strings that may be destructively appended to. */ 26 | /* They allow fast construction of cords from characters that are */ 27 | /* being read from a stream. */ 28 | /* 29 | * A client might look like: 30 | * 31 | * { 32 | * CORD_ec x; 33 | * CORD result; 34 | * char c; 35 | * FILE *f; 36 | * 37 | * ... 38 | * CORD_ec_init(x); 39 | * while (...) { 40 | * c = getc(f); 41 | * ... 42 | * CORD_ec_append(x, c); 43 | * } 44 | * result = CORD_balance(CORD_ec_to_cord(x)); 45 | * 46 | * If a C string is desired as the final result, the call to CORD_balance 47 | * may be replaced by a call to CORD_to_char_star. 48 | */ 49 | 50 | # ifndef CORD_BUFSZ 51 | # define CORD_BUFSZ 128 52 | # endif 53 | 54 | /* This structure represents the concatenation of ec_cord with */ 55 | /* ec_buf[0 .. ec_bufptr-ec_buf-1]. */ 56 | typedef struct CORD_ec_struct { 57 | CORD ec_cord; 58 | char * ec_bufptr; 59 | char ec_buf[CORD_BUFSZ+1]; 60 | } CORD_ec[1]; 61 | 62 | /* Flush the buffer part of the extended cord into ec_cord. */ 63 | void CORD_ec_flush_buf(CORD_ec x); 64 | 65 | /* Convert an extensible cord to a cord. */ 66 | # define CORD_ec_to_cord(x) (CORD_ec_flush_buf(x), (x)[0].ec_cord) 67 | 68 | /* Initialize an extensible cord. */ 69 | #define CORD_ec_init(x) \ 70 | ((x)[0].ec_cord = 0, (void)((x)[0].ec_bufptr = (x)[0].ec_buf)) 71 | 72 | /* Append a character to an extensible cord. */ 73 | #define CORD_ec_append(x, c) \ 74 | ((void)((x)[0].ec_bufptr == (x)[0].ec_buf + CORD_BUFSZ \ 75 | ? (CORD_ec_flush_buf(x), 0) : 0), \ 76 | (void)(*(x)[0].ec_bufptr++ = (c))) 77 | 78 | /* Append a cord to an extensible cord. Structure remains shared with */ 79 | /* original. */ 80 | void CORD_ec_append_cord(CORD_ec x, CORD s); 81 | 82 | #ifdef __cplusplus 83 | } /* extern "C" */ 84 | #endif 85 | 86 | #endif /* EC_H */ 87 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/include/gc/gc_backptr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | * Copyright (c) 1996 by Silicon Graphics. All rights reserved. 4 | * Copyright (c) 1998 by Fergus Henderson. All rights reserved. 5 | * Copyright (c) 2000-2009 by Hewlett-Packard Development Company. 6 | * All rights reserved. 7 | * 8 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 9 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 10 | * 11 | * Permission is hereby granted to use or copy this program 12 | * for any purpose, provided the above notices are retained on all copies. 13 | * Permission to modify the code and to distribute modified code is granted, 14 | * provided the above notices are retained, and a notice that the code was 15 | * modified is included with the above copyright notice. 16 | */ 17 | 18 | /* 19 | * This is a simple API to implement pointer back tracing, i.e. 20 | * to answer questions such as "who is pointing to this" or 21 | * "why is this object being retained by the collector" 22 | * 23 | * Most of these calls yield useful information on only after 24 | * a garbage collection. Usually the client will first force 25 | * a full collection and then gather information, preferably 26 | * before much intervening allocation. 27 | * 28 | * The implementation of the interface is only about 99.9999% 29 | * correct. It is intended to be good enough for profiling, 30 | * but is not intended to be used with production code. 31 | * 32 | * Results are likely to be much more useful if all allocation is 33 | * accomplished through the debugging allocators. 34 | * 35 | * The implementation idea is due to A. Demers. 36 | */ 37 | 38 | #ifndef GC_BACKPTR_H 39 | #define GC_BACKPTR_H 40 | 41 | #ifndef GC_H 42 | # include "gc.h" 43 | #endif 44 | 45 | #ifdef __cplusplus 46 | extern "C" { 47 | #endif 48 | 49 | /* Store information about the object referencing dest in *base_p */ 50 | /* and *offset_p. */ 51 | /* If multiple objects or roots point to dest, the one reported */ 52 | /* will be the last on used by the garbage collector to trace the */ 53 | /* object. */ 54 | /* source is root ==> *base_p = address, *offset_p = 0 */ 55 | /* source is heap object ==> *base_p != 0, *offset_p = offset */ 56 | /* Returns 1 on success, 0 if source couldn't be determined. */ 57 | /* Dest can be any address within a heap object. */ 58 | typedef enum { 59 | GC_UNREFERENCED, /* No reference info available. */ 60 | GC_NO_SPACE, /* Dest not allocated with debug alloc. */ 61 | GC_REFD_FROM_ROOT, /* Referenced directly by root *base_p. */ 62 | GC_REFD_FROM_REG, /* Referenced from a register, i.e. */ 63 | /* a root without an address. */ 64 | GC_REFD_FROM_HEAP, /* Referenced from another heap obj. */ 65 | GC_FINALIZER_REFD /* Finalizable and hence accessible. */ 66 | } GC_ref_kind; 67 | 68 | GC_API GC_ref_kind GC_CALL GC_get_back_ptr_info(void * /* dest */, 69 | void ** /* base_p */, size_t * /* offset_p */) 70 | GC_ATTR_NONNULL(1); 71 | 72 | /* Generate a random heap address. The resulting address is */ 73 | /* in the heap, but not necessarily inside a valid object. */ 74 | /* The caller should hold the allocation lock. */ 75 | GC_API void * GC_CALL GC_generate_random_heap_address(void); 76 | 77 | /* Generate a random address inside a valid marked heap object. */ 78 | /* The caller should hold the allocation lock. */ 79 | GC_API void * GC_CALL GC_generate_random_valid_address(void); 80 | 81 | /* Force a garbage collection and generate a backtrace from a */ 82 | /* random heap address. */ 83 | /* This uses the GC logging mechanism (GC_printf) to produce */ 84 | /* output. It can often be called from a debugger. */ 85 | GC_API void GC_CALL GC_generate_random_backtrace(void); 86 | 87 | /* Print a backtrace from a specific address. Used by the */ 88 | /* above. The client should call GC_gcollect() immediately */ 89 | /* before invocation. */ 90 | GC_API void GC_CALL GC_print_backtrace(void *) GC_ATTR_NONNULL(1); 91 | 92 | #ifdef __cplusplus 93 | } /* extern "C" */ 94 | #endif 95 | 96 | #endif /* GC_BACKPTR_H */ 97 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/include/gc/gc_disclaim.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007-2011 by Hewlett-Packard Company. All rights reserved. 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to use or copy this program 8 | * for any purpose, provided the above notices are retained on all copies. 9 | * Permission to modify the code and to distribute modified code is granted, 10 | * provided the above notices are retained, and a notice that the code was 11 | * modified is included with the above copyright notice. 12 | */ 13 | 14 | #ifndef GC_DISCLAIM_H 15 | #define GC_DISCLAIM_H 16 | 17 | #include "gc.h" 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | /* This API is defined only if the library has been suitably compiled */ 24 | /* (i.e. with ENABLE_DISCLAIM defined). */ 25 | 26 | /* Prepare the object kind used by GC_finalized_malloc. Call it from */ 27 | /* your initialization code or, at least, at some point before using */ 28 | /* finalized allocations. The function is thread-safe. */ 29 | GC_API void GC_CALL GC_init_finalized_malloc(void); 30 | 31 | /* Type of a disclaim call-back. Called with the allocation lock held. */ 32 | typedef int (GC_CALLBACK * GC_disclaim_proc)(void * /* obj */); 33 | 34 | /* Register proc to be called on each object (of given kind) ready to */ 35 | /* be reclaimed. If proc() returns non-zero, the collector will not */ 36 | /* reclaim the object on this GC cycle (proc() should not try to */ 37 | /* resurrect the object otherwise); objects reachable from proc() */ 38 | /* (including the referred closure object) will be protected from */ 39 | /* collection if mark_from_all is non-zero, but at the expense that */ 40 | /* long chains of objects will take many cycles to reclaim. Any call */ 41 | /* to GC_free() deallocates the object (pointed by the argument) */ 42 | /* without inquiring proc(). Acquires the allocation lock. */ 43 | /* No-op in the leak-finding mode. */ 44 | GC_API void GC_CALL GC_register_disclaim_proc(int /* kind */, 45 | GC_disclaim_proc /* proc */, 46 | int /* mark_from_all */); 47 | 48 | /* The finalizer closure used by GC_finalized_malloc. */ 49 | struct GC_finalizer_closure { 50 | GC_finalization_proc proc; 51 | void *cd; 52 | }; 53 | 54 | /* Allocate an object which is to be finalized by the given closure. */ 55 | /* This uses a dedicated object kind with a disclaim procedure, and is */ 56 | /* more efficient than GC_register_finalizer and friends. */ 57 | /* GC_init_finalized_malloc must be called before using this. */ 58 | /* The collector will reclaim the object during this GC cycle (thus, */ 59 | /* fc->proc() should not try to resurrect the object). The other */ 60 | /* objects reachable from fc->proc (including the closure object in */ 61 | /* case it is a heap-allocated one) will be protected from collection. */ 62 | /* Note that GC_size (applied to such allocated object) returns a value */ 63 | /* slightly bigger than the specified allocation size, and that GC_base */ 64 | /* result points to a word prior to the start of the allocated object. */ 65 | /* The disclaim procedure is not invoked in the leak-finding mode. */ 66 | /* There is no debugging version of this allocation API. */ 67 | GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL 68 | GC_finalized_malloc(size_t /* size */, 69 | const struct GC_finalizer_closure * /* fc */) GC_ATTR_NONNULL(2); 70 | 71 | #ifdef __cplusplus 72 | } /* extern "C" */ 73 | #endif 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/include/gc/gc_pthread_redirects.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | * Copyright (c) 1996 by Silicon Graphics. All rights reserved. 4 | * Copyright (c) 1998 by Fergus Henderson. All rights reserved. 5 | * Copyright (c) 2000-2010 by Hewlett-Packard Development Company. 6 | * All rights reserved. 7 | * 8 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 9 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 10 | * 11 | * Permission is hereby granted to use or copy this program 12 | * for any purpose, provided the above notices are retained on all copies. 13 | * Permission to modify the code and to distribute modified code is granted, 14 | * provided the above notices are retained, and a notice that the code was 15 | * modified is included with the above copyright notice. 16 | */ 17 | 18 | /* Our pthread support normally needs to intercept a number of thread */ 19 | /* calls. We arrange to do that here, if appropriate. */ 20 | 21 | #ifndef GC_PTHREAD_REDIRECTS_H 22 | #define GC_PTHREAD_REDIRECTS_H 23 | 24 | /* Included from gc.h only. Included only if GC_PTHREADS. */ 25 | #if defined(GC_H) && defined(GC_PTHREADS) 26 | 27 | /* We need to intercept calls to many of the threads primitives, so */ 28 | /* that we can locate thread stacks and stop the world. */ 29 | /* Note also that the collector cannot always see thread specific data. */ 30 | /* Thread specific data should generally consist of pointers to */ 31 | /* uncollectible objects (allocated with GC_malloc_uncollectable, */ 32 | /* not the system malloc), which are deallocated using the destructor */ 33 | /* facility in thr_keycreate. Alternatively, keep a redundant pointer */ 34 | /* to thread specific data on the thread stack. */ 35 | 36 | #ifndef GC_PTHREAD_REDIRECTS_ONLY 37 | 38 | # include 39 | # ifndef GC_NO_DLOPEN 40 | # include 41 | # endif 42 | # ifndef GC_NO_PTHREAD_SIGMASK 43 | # include /* needed anyway for proper redirection */ 44 | # endif 45 | 46 | # ifdef __cplusplus 47 | extern "C" { 48 | # endif 49 | 50 | # ifndef GC_SUSPEND_THREAD_ID 51 | # define GC_SUSPEND_THREAD_ID pthread_t 52 | # endif 53 | 54 | # ifndef GC_NO_DLOPEN 55 | GC_API void *GC_dlopen(const char * /* path */, int /* mode */); 56 | # endif /* !GC_NO_DLOPEN */ 57 | 58 | # ifndef GC_NO_PTHREAD_SIGMASK 59 | # if defined(GC_PTHREAD_SIGMASK_NEEDED) \ 60 | || defined(_BSD_SOURCE) || defined(_GNU_SOURCE) \ 61 | || (_POSIX_C_SOURCE >= 199506L) || (_XOPEN_SOURCE >= 500) 62 | GC_API int GC_pthread_sigmask(int /* how */, const sigset_t *, 63 | sigset_t * /* oset */); 64 | # else 65 | # define GC_NO_PTHREAD_SIGMASK 66 | # endif 67 | # endif /* !GC_NO_PTHREAD_SIGMASK */ 68 | 69 | # ifndef GC_PTHREAD_CREATE_CONST 70 | /* This is used for pthread_create() only. */ 71 | # define GC_PTHREAD_CREATE_CONST const 72 | # endif 73 | 74 | GC_API int GC_pthread_create(pthread_t *, 75 | GC_PTHREAD_CREATE_CONST pthread_attr_t *, 76 | void *(*)(void *), void * /* arg */); 77 | GC_API int GC_pthread_join(pthread_t, void ** /* retval */); 78 | GC_API int GC_pthread_detach(pthread_t); 79 | 80 | # ifndef GC_NO_PTHREAD_CANCEL 81 | GC_API int GC_pthread_cancel(pthread_t); 82 | # endif 83 | 84 | # if defined(GC_HAVE_PTHREAD_EXIT) && !defined(GC_PTHREAD_EXIT_DECLARED) 85 | # define GC_PTHREAD_EXIT_DECLARED 86 | GC_API void GC_pthread_exit(void *) GC_PTHREAD_EXIT_ATTRIBUTE; 87 | # endif 88 | 89 | # ifdef __cplusplus 90 | } /* extern "C" */ 91 | # endif 92 | 93 | #endif /* !GC_PTHREAD_REDIRECTS_ONLY */ 94 | 95 | #if !defined(GC_NO_THREAD_REDIRECTS) && !defined(GC_USE_LD_WRAP) 96 | /* Unless the compiler supports #pragma extern_prefix, the Tru64 */ 97 | /* UNIX pthread.h redefines some POSIX thread functions to use */ 98 | /* mangled names. Anyway, it's safe to undef them before redefining. */ 99 | # undef pthread_create 100 | # undef pthread_join 101 | # undef pthread_detach 102 | # define pthread_create GC_pthread_create 103 | # define pthread_join GC_pthread_join 104 | # define pthread_detach GC_pthread_detach 105 | 106 | # ifndef GC_NO_PTHREAD_SIGMASK 107 | # undef pthread_sigmask 108 | # define pthread_sigmask GC_pthread_sigmask 109 | # endif 110 | # ifndef GC_NO_DLOPEN 111 | # undef dlopen 112 | # define dlopen GC_dlopen 113 | # endif 114 | # ifndef GC_NO_PTHREAD_CANCEL 115 | # undef pthread_cancel 116 | # define pthread_cancel GC_pthread_cancel 117 | # endif 118 | # ifdef GC_HAVE_PTHREAD_EXIT 119 | # undef pthread_exit 120 | # define pthread_exit GC_pthread_exit 121 | # endif 122 | #endif /* !GC_NO_THREAD_REDIRECTS */ 123 | 124 | #endif /* GC_PTHREADS */ 125 | 126 | #endif /* GC_PTHREAD_REDIRECTS_H */ 127 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/include/gc/gc_tiny_fl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2005 Hewlett-Packard Development Company, L.P. 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to use or copy this program 8 | * for any purpose, provided the above notices are retained on all copies. 9 | * Permission to modify the code and to distribute modified code is granted, 10 | * provided the above notices are retained, and a notice that the code was 11 | * modified is included with the above copyright notice. 12 | */ 13 | 14 | #ifndef GC_TINY_FL_H 15 | #define GC_TINY_FL_H 16 | /* 17 | * Constants and data structures for "tiny" free lists. 18 | * These are used for thread-local allocation or in-lined allocators. 19 | * Each global free list also essentially starts with one of these. 20 | * However, global free lists are known to the GC. "Tiny" free lists 21 | * are basically private to the client. Their contents are viewed as 22 | * "in use" and marked accordingly by the core of the GC. 23 | * 24 | * Note that inlined code might know about the layout of these and the constants 25 | * involved. Thus any change here may invalidate clients, and such changes should 26 | * be avoided. Hence we keep this as simple as possible. 27 | */ 28 | 29 | /* 30 | * We always set GC_GRANULE_BYTES to twice the length of a pointer. 31 | * This means that all allocation requests are rounded up to the next 32 | * multiple of 16 on 64-bit architectures or 8 on 32-bit architectures. 33 | * This appears to be a reasonable compromise between fragmentation overhead 34 | * and space usage for mark bits (usually mark bytes). 35 | * On many 64-bit architectures some memory references require 16-byte 36 | * alignment, making this necessary anyway. 37 | * For a few 32-bit architecture (e.g. x86), we may also need 16-byte alignment 38 | * for certain memory references. But currently that does not seem to be the 39 | * default for all conventional malloc implementations, so we ignore that 40 | * problem. 41 | * It would always be safe, and often useful, to be able to allocate very 42 | * small objects with smaller alignment. But that would cost us mark bit 43 | * space, so we no longer do so. 44 | */ 45 | #ifndef GC_GRANULE_BYTES 46 | /* GC_GRANULE_BYTES should not be overridden in any instances of the GC */ 47 | /* library that may be shared between applications, since it affects */ 48 | /* the binary interface to the library. */ 49 | # if defined(__LP64__) || defined (_LP64) || defined(_WIN64) \ 50 | || defined(__s390x__) \ 51 | || (defined(__x86_64__) && !defined(__ILP32__)) \ 52 | || defined(__alpha__) || defined(__powerpc64__) \ 53 | || defined(__arch64__) 54 | # define GC_GRANULE_BYTES 16 55 | # define GC_GRANULE_WORDS 2 56 | # else 57 | # define GC_GRANULE_BYTES 8 58 | # define GC_GRANULE_WORDS 2 59 | # endif 60 | #endif /* !GC_GRANULE_BYTES */ 61 | 62 | #if GC_GRANULE_WORDS == 2 63 | # define GC_WORDS_TO_GRANULES(n) ((n)>>1) 64 | #else 65 | # define GC_WORDS_TO_GRANULES(n) ((n)*sizeof(void *)/GC_GRANULE_BYTES) 66 | #endif 67 | 68 | /* A "tiny" free list header contains TINY_FREELISTS pointers to */ 69 | /* singly linked lists of objects of different sizes, the ith one */ 70 | /* containing objects i granules in size. Note that there is a list */ 71 | /* of size zero objects. */ 72 | #ifndef GC_TINY_FREELISTS 73 | # if GC_GRANULE_BYTES == 16 74 | # define GC_TINY_FREELISTS 25 75 | # else 76 | # define GC_TINY_FREELISTS 33 /* Up to and including 256 bytes */ 77 | # endif 78 | #endif /* !GC_TINY_FREELISTS */ 79 | 80 | /* The ith free list corresponds to size i*GC_GRANULE_BYTES */ 81 | /* Internally to the collector, the index can be computed with */ 82 | /* ALLOC_REQUEST_GRANS(). Externally, we don't know whether */ 83 | /* DONT_ADD_BYTE_AT_END is set, but the client should know. */ 84 | 85 | /* Convert a free list index to the actual size of objects */ 86 | /* on that list, including extra space we added. Not an */ 87 | /* inverse of the above. */ 88 | #define GC_RAW_BYTES_FROM_INDEX(i) ((i) * GC_GRANULE_BYTES) 89 | 90 | #endif /* GC_TINY_FL_H */ 91 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/include/gc/gc_version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | * Copyright (c) 1996 by Silicon Graphics. All rights reserved. 4 | * Copyright (c) 1998 by Fergus Henderson. All rights reserved. 5 | * Copyright (c) 2000-2009 by Hewlett-Packard Development Company. 6 | * All rights reserved. 7 | * 8 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 9 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 10 | * 11 | * Permission is hereby granted to use or copy this program 12 | * for any purpose, provided the above notices are retained on all copies. 13 | * Permission to modify the code and to distribute modified code is granted, 14 | * provided the above notices are retained, and a notice that the code was 15 | * modified is included with the above copyright notice. 16 | */ 17 | 18 | /* This should never be included directly; it is included only from gc.h. */ 19 | #if defined(GC_H) 20 | 21 | /* The policy regarding version numbers: development code has odd */ 22 | /* "minor" number (and "micro" part is 0); when development is finished */ 23 | /* and a release is prepared, "minor" number is incremented (keeping */ 24 | /* "micro" number still zero), whenever a defect is fixed a new release */ 25 | /* is prepared incrementing "micro" part to odd value (the most stable */ 26 | /* release has the biggest "micro" number). */ 27 | 28 | /* The version here should match that in configure/configure.ac */ 29 | /* Eventually this one may become unnecessary. For now we need */ 30 | /* it to keep the old-style build process working. */ 31 | #define GC_TMP_VERSION_MAJOR 8 32 | #define GC_TMP_VERSION_MINOR 3 33 | #define GC_TMP_VERSION_MICRO 0 /* 8.3.0 */ 34 | 35 | #ifdef GC_VERSION_MAJOR 36 | # if GC_TMP_VERSION_MAJOR != GC_VERSION_MAJOR \ 37 | || GC_TMP_VERSION_MINOR != GC_VERSION_MINOR \ 38 | || GC_TMP_VERSION_MICRO != GC_VERSION_MICRO 39 | # error Inconsistent version info. Check README.md, include/gc_version.h and configure.ac. 40 | # endif 41 | #else 42 | # define GC_VERSION_MAJOR GC_TMP_VERSION_MAJOR 43 | # define GC_VERSION_MINOR GC_TMP_VERSION_MINOR 44 | # define GC_VERSION_MICRO GC_TMP_VERSION_MICRO 45 | #endif /* !GC_VERSION_MAJOR */ 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/include/gc/javaxfc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | * Copyright (c) 1996 by Silicon Graphics. All rights reserved. 4 | * Copyright (c) 1998 by Fergus Henderson. All rights reserved. 5 | * Copyright (c) 2000-2009 by Hewlett-Packard Development Company. 6 | * All rights reserved. 7 | * 8 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 9 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 10 | * 11 | * Permission is hereby granted to use or copy this program 12 | * for any purpose, provided the above notices are retained on all copies. 13 | * Permission to modify the code and to distribute modified code is granted, 14 | * provided the above notices are retained, and a notice that the code was 15 | * modified is included with the above copyright notice. 16 | */ 17 | 18 | #ifndef GC_JAVAXFC_H 19 | #define GC_JAVAXFC_H 20 | 21 | #ifndef GC_H 22 | # include "gc.h" 23 | #endif 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | /* 30 | * Invoke all remaining finalizers that haven't yet been run. (Since the 31 | * notifier is not called, this should be called from a separate thread.) 32 | * This function is needed for strict compliance with the Java standard, 33 | * which can make the runtime guarantee that all finalizers are run. 34 | * This is problematic for several reasons: 35 | * 1) It means that finalizers, and all methods called by them, 36 | * must be prepared to deal with objects that have been finalized in 37 | * spite of the fact that they are still referenced by statically 38 | * allocated pointer variables. 39 | * 2) It may mean that we get stuck in an infinite loop running 40 | * finalizers which create new finalizable objects, though that's 41 | * probably unlikely. 42 | * Thus this is not recommended for general use. 43 | * Acquire the allocation lock (to enqueue all finalizers). 44 | */ 45 | GC_API void GC_CALL GC_finalize_all(void); 46 | 47 | #ifdef GC_THREADS 48 | /* External thread suspension support. No thread suspension count */ 49 | /* (so a thread which has been suspended numerous times will be */ 50 | /* resumed with the very first call to GC_resume_thread). */ 51 | /* Acquire the allocation lock. Thread should be registered in GC */ 52 | /* (otherwise no-op, GC_is_thread_suspended returns false). */ 53 | /* Unimplemented on some platforms. Not recommended for general use. */ 54 | # ifndef GC_SUSPEND_THREAD_ID 55 | # define GC_SUSPEND_THREAD_ID void* 56 | # endif 57 | GC_API void GC_CALL GC_suspend_thread(GC_SUSPEND_THREAD_ID); 58 | GC_API void GC_CALL GC_resume_thread(GC_SUSPEND_THREAD_ID); 59 | GC_API int GC_CALL GC_is_thread_suspended(GC_SUSPEND_THREAD_ID); 60 | #endif /* GC_THREADS */ 61 | 62 | #ifdef __cplusplus 63 | } /* extern "C" */ 64 | #endif 65 | 66 | #endif /* GC_JAVAXFC_H */ 67 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/include/gc/leak_detector.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000-2011 by Hewlett-Packard Development Company. 3 | * All rights reserved. 4 | * 5 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 6 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 7 | * 8 | * Permission is hereby granted to use or copy this program 9 | * for any purpose, provided the above notices are retained on all copies. 10 | * Permission to modify the code and to distribute modified code is granted, 11 | * provided the above notices are retained, and a notice that the code was 12 | * modified is included with the above copyright notice. 13 | */ 14 | 15 | #ifndef GC_LEAK_DETECTOR_H 16 | #define GC_LEAK_DETECTOR_H 17 | 18 | /* Include this header file (e.g., via gcc --include directive) */ 19 | /* to turn libgc into a leak detector. */ 20 | 21 | #ifndef GC_DEBUG 22 | # define GC_DEBUG 23 | #endif 24 | #include "gc.h" 25 | 26 | #ifndef GC_DONT_INCLUDE_STDLIB 27 | /* We ensure stdlib.h and string.h are included before */ 28 | /* redirecting malloc() and the accompanying functions. */ 29 | # include 30 | # include 31 | #endif 32 | 33 | #undef malloc 34 | #define malloc(n) GC_MALLOC(n) 35 | #undef calloc 36 | #define calloc(m,n) GC_MALLOC((m)*(n)) 37 | #undef free 38 | #define free(p) GC_FREE(p) 39 | #undef realloc 40 | #define realloc(p,n) GC_REALLOC(p,n) 41 | #undef reallocarray 42 | #define reallocarray(p,m,n) GC_REALLOC(p,(m)*(n)) 43 | 44 | #undef strdup 45 | #define strdup(s) GC_STRDUP(s) 46 | #undef strndup 47 | #define strndup(s,n) GC_STRNDUP(s,n) 48 | 49 | #ifdef GC_REQUIRE_WCSDUP 50 | /* The collector should be built with GC_REQUIRE_WCSDUP */ 51 | /* defined as well to redirect wcsdup(). */ 52 | # include 53 | # undef wcsdup 54 | # define wcsdup(s) GC_WCSDUP(s) 55 | #endif 56 | 57 | /* The following routines for the aligned objects allocation */ 58 | /* (aligned_alloc, valloc, etc.) do not have their debugging */ 59 | /* counterparts. Note that free() called for such objects */ 60 | /* may output a warning that the pointer has no debugging info. */ 61 | 62 | #undef aligned_alloc 63 | #define aligned_alloc(a,n) GC_memalign(a,n) /* identical to memalign */ 64 | #undef memalign 65 | #define memalign(a,n) GC_memalign(a,n) 66 | #undef posix_memalign 67 | #define posix_memalign(p,a,n) GC_posix_memalign(p,a,n) 68 | 69 | #undef _aligned_malloc 70 | #define _aligned_malloc(n,a) GC_memalign(a,n) /* reverse args order */ 71 | #undef _aligned_free 72 | #define _aligned_free(p) GC_free(GC_base(p)) /* non-debug */ 73 | 74 | #ifndef GC_NO_VALLOC 75 | # undef valloc 76 | # define valloc(n) GC_valloc(n) 77 | # undef pvalloc 78 | # define pvalloc(n) GC_pvalloc(n) /* obsolete */ 79 | #endif /* !GC_NO_VALLOC */ 80 | 81 | #ifndef CHECK_LEAKS 82 | # define CHECK_LEAKS() GC_gcollect() 83 | /* Note 1: CHECK_LEAKS does not have GC prefix (preserved for */ 84 | /* backward compatibility). */ 85 | /* Note 2: GC_gcollect() is also called automatically in the */ 86 | /* leak-finding mode at program exit. */ 87 | #endif 88 | 89 | #endif /* GC_LEAK_DETECTOR_H */ 90 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/include/gc_cpp.h: -------------------------------------------------------------------------------- 1 | /* This file is installed for backward compatibility. */ 2 | #include "gc/gc_cpp.h" 3 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/include/include.am: -------------------------------------------------------------------------------- 1 | # 2 | # THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 3 | # OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 4 | # 5 | # Permission is hereby granted to use or copy this program 6 | # for any purpose, provided the above notices are retained on all copies. 7 | # Permission to modify the code and to distribute modified code is granted, 8 | # provided the above notices are retained, and a notice that the code was 9 | # modified is included with the above copyright notice. 10 | 11 | ## Process this file with automake to produce part of Makefile.in. 12 | 13 | # installed headers 14 | # 15 | pkginclude_HEADERS += \ 16 | include/gc/gc.h \ 17 | include/gc/gc_backptr.h \ 18 | include/gc/gc_config_macros.h \ 19 | include/gc/gc_inline.h \ 20 | include/gc/gc_mark.h \ 21 | include/gc/gc_tiny_fl.h \ 22 | include/gc/gc_typed.h \ 23 | include/gc/gc_version.h \ 24 | include/gc/javaxfc.h \ 25 | include/gc/leak_detector.h 26 | 27 | if ENABLE_DISCLAIM 28 | pkginclude_HEADERS += include/gc/gc_disclaim.h 29 | endif 30 | 31 | if ENABLE_GCJ_SUPPORT 32 | pkginclude_HEADERS += include/gc/gc_gcj.h 33 | endif 34 | 35 | if PTHREADS 36 | pkginclude_HEADERS += include/gc/gc_pthread_redirects.h 37 | endif 38 | 39 | if CPLUSPLUS 40 | pkginclude_HEADERS += \ 41 | include/gc/gc_allocator.h \ 42 | include/gc/gc_cpp.h 43 | 44 | include_HEADERS += include/gc_cpp.h 45 | endif 46 | 47 | # headers which are not installed 48 | # 49 | dist_noinst_HEADERS += \ 50 | include/private/darwin_semaphore.h \ 51 | include/private/dbg_mlc.h \ 52 | include/private/gc_alloc_ptrs.h \ 53 | include/private/gc_atomic_ops.h \ 54 | include/private/gc_hdrs.h \ 55 | include/private/gc_locks.h \ 56 | include/private/gc_pmark.h \ 57 | include/private/gc_priv.h \ 58 | include/private/gcconfig.h \ 59 | include/private/pthread_support.h \ 60 | include/private/specific.h \ 61 | include/private/thread_local_alloc.h 62 | 63 | # unprefixed header 64 | include_HEADERS += \ 65 | include/gc.h 66 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/include/private/darwin_semaphore.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | * Copyright (c) 1996 by Silicon Graphics. All rights reserved. 4 | * Copyright (c) 1998 by Fergus Henderson. All rights reserved. 5 | * Copyright (c) 2000-2009 by Hewlett-Packard Development Company. 6 | * All rights reserved. 7 | * 8 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 9 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 10 | * 11 | * Permission is hereby granted to use or copy this program 12 | * for any purpose, provided the above notices are retained on all copies. 13 | * Permission to modify the code and to distribute modified code is granted, 14 | * provided the above notices are retained, and a notice that the code was 15 | * modified is included with the above copyright notice. 16 | */ 17 | 18 | #ifndef GC_DARWIN_SEMAPHORE_H 19 | #define GC_DARWIN_SEMAPHORE_H 20 | 21 | #if !defined(GC_DARWIN_THREADS) && !defined(GC_WIN32_THREADS) 22 | # error darwin_semaphore.h included for improper target 23 | #endif 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | /* This is a very simple semaphore implementation based on pthreads. */ 30 | /* It is not async-signal safe. But this is not a problem because */ 31 | /* signals are not used to suspend threads on the target. */ 32 | 33 | typedef struct { 34 | pthread_mutex_t mutex; 35 | pthread_cond_t cond; 36 | int value; 37 | } sem_t; 38 | 39 | GC_INLINE int sem_init(sem_t *sem, int pshared, int value) { 40 | if (pshared != 0) { 41 | errno = EPERM; /* unsupported */ 42 | return -1; 43 | } 44 | sem->value = value; 45 | if (pthread_mutex_init(&sem->mutex, NULL) != 0) 46 | return -1; 47 | if (pthread_cond_init(&sem->cond, NULL) != 0) { 48 | (void)pthread_mutex_destroy(&sem->mutex); 49 | return -1; 50 | } 51 | return 0; 52 | } 53 | 54 | GC_INLINE int sem_post(sem_t *sem) { 55 | if (pthread_mutex_lock(&sem->mutex) != 0) 56 | return -1; 57 | sem->value++; 58 | if (pthread_cond_signal(&sem->cond) != 0) { 59 | (void)pthread_mutex_unlock(&sem->mutex); 60 | return -1; 61 | } 62 | return pthread_mutex_unlock(&sem->mutex) != 0 ? -1 : 0; 63 | } 64 | 65 | GC_INLINE int sem_wait(sem_t *sem) { 66 | if (pthread_mutex_lock(&sem->mutex) != 0) 67 | return -1; 68 | while (sem->value == 0) { 69 | if (pthread_cond_wait(&sem->cond, &sem->mutex) != 0) { 70 | (void)pthread_mutex_unlock(&sem->mutex); 71 | return -1; 72 | } 73 | } 74 | sem->value--; 75 | return pthread_mutex_unlock(&sem->mutex) != 0 ? -1 : 0; 76 | } 77 | 78 | GC_INLINE int sem_destroy(sem_t *sem) { 79 | return pthread_cond_destroy(&sem->cond) != 0 80 | || pthread_mutex_destroy(&sem->mutex) != 0 ? -1 : 0; 81 | } 82 | 83 | #ifdef __cplusplus 84 | } /* extern "C" */ 85 | #endif 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/include/private/gc_alloc_ptrs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996-1998 by Silicon Graphics. All rights reserved. 3 | * Copyright (c) 2018-2021 Ivan Maidanski 4 | * 5 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 6 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 7 | * 8 | * Permission is hereby granted to use or copy this program 9 | * for any purpose, provided the above notices are retained on all copies. 10 | * Permission to modify the code and to distribute modified code is granted, 11 | * provided the above notices are retained, and a notice that the code was 12 | * modified is included with the above copyright notice. 13 | */ 14 | 15 | /* This file is kept for a binary compatibility purpose only. */ 16 | 17 | #ifndef GC_ALLOC_PTRS_H 18 | #define GC_ALLOC_PTRS_H 19 | 20 | #include "gc/gc.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | #ifndef GC_API_PRIV 27 | # define GC_API_PRIV GC_API 28 | #endif 29 | 30 | /* Some compilers do not accept "const" together with the dllimport */ 31 | /* attribute, so the symbols below are exported as non-constant ones. */ 32 | #ifndef GC_APIVAR_CONST 33 | # if defined(GC_BUILD) || !defined(GC_DLL) 34 | # define GC_APIVAR_CONST const 35 | # else 36 | # define GC_APIVAR_CONST /* empty */ 37 | # endif 38 | #endif 39 | 40 | GC_API_PRIV void ** GC_APIVAR_CONST GC_objfreelist_ptr; 41 | GC_API_PRIV void ** GC_APIVAR_CONST GC_aobjfreelist_ptr; 42 | GC_API_PRIV void ** GC_APIVAR_CONST GC_uobjfreelist_ptr; 43 | 44 | #ifdef GC_ATOMIC_UNCOLLECTABLE 45 | GC_API_PRIV void ** GC_APIVAR_CONST GC_auobjfreelist_ptr; 46 | #endif 47 | 48 | /* Manually update the number of bytes allocated during the current */ 49 | /* collection cycle and the number of explicitly deallocated bytes of */ 50 | /* memory since the last collection, respectively. Both functions are */ 51 | /* unsynchronized, GC_call_with_alloc_lock() should be used to avoid */ 52 | /* data races. */ 53 | GC_API_PRIV void GC_CALL GC_incr_bytes_allocd(size_t /* bytes */); 54 | GC_API_PRIV void GC_CALL GC_incr_bytes_freed(size_t /* bytes */); 55 | 56 | #ifdef __cplusplus 57 | } /* extern "C" */ 58 | #endif 59 | 60 | #endif /* GC_ALLOC_PTRS_H */ 61 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/include/private/gc_atomic_ops.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 Ivan Maidanski 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to use or copy this program 8 | * for any purpose, provided the above notices are retained on all copies. 9 | * Permission to modify the code and to distribute modified code is granted, 10 | * provided the above notices are retained, and a notice that the code was 11 | * modified is included with the above copyright notice. 12 | */ 13 | 14 | /* This is a private GC header which provides an implementation of */ 15 | /* libatomic_ops subset primitives sufficient for GC assuming that GCC */ 16 | /* atomic intrinsics are available (and have correct implementation). */ 17 | /* This is enabled by defining GC_BUILTIN_ATOMIC macro. Otherwise, */ 18 | /* libatomic_ops library is used to define the primitives. */ 19 | 20 | #ifndef GC_ATOMIC_OPS_H 21 | #define GC_ATOMIC_OPS_H 22 | 23 | #ifdef GC_BUILTIN_ATOMIC 24 | 25 | # include "gc/gc.h" /* for GC_word */ 26 | 27 | # ifdef __cplusplus 28 | extern "C" { 29 | # endif 30 | 31 | typedef GC_word AO_t; 32 | 33 | # ifdef GC_PRIVATE_H /* have GC_INLINE */ 34 | # define AO_INLINE GC_INLINE 35 | # else 36 | # define AO_INLINE static __inline 37 | # endif 38 | 39 | # if !defined(THREAD_SANITIZER) && !defined(GC_PRIVATE_H) 40 | /* Similar to that in gcconfig.h. */ 41 | # if defined(__has_feature) 42 | # if __has_feature(thread_sanitizer) 43 | # define THREAD_SANITIZER 44 | # endif 45 | # elif defined(__SANITIZE_THREAD__) 46 | # define THREAD_SANITIZER 47 | # endif 48 | # endif /* !THREAD_SANITIZER && !GC_PRIVATE_H */ 49 | 50 | typedef unsigned char AO_TS_t; 51 | # define AO_TS_CLEAR 0 52 | # define AO_TS_INITIALIZER (AO_TS_t)AO_TS_CLEAR 53 | # if defined(__GCC_ATOMIC_TEST_AND_SET_TRUEVAL) && !defined(CPPCHECK) 54 | # define AO_TS_SET __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 55 | # else 56 | # define AO_TS_SET (AO_TS_t)1 /* true */ 57 | # endif 58 | # define AO_CLEAR(p) __atomic_clear(p, __ATOMIC_RELEASE) 59 | # define AO_test_and_set_acquire(p) \ 60 | (__atomic_test_and_set(p, __ATOMIC_ACQUIRE) ? AO_TS_SET : AO_TS_CLEAR) 61 | # define AO_HAVE_test_and_set_acquire 62 | 63 | # define AO_compiler_barrier() __atomic_signal_fence(__ATOMIC_SEQ_CST) 64 | 65 | # if defined(THREAD_SANITIZER) && !defined(AO_USE_ATOMIC_THREAD_FENCE) 66 | /* Workaround a compiler warning (reported by gcc-11, at least) */ 67 | /* that atomic_thread_fence is unsupported with thread sanitizer. */ 68 | AO_INLINE void 69 | AO_nop_full(void) 70 | { 71 | volatile AO_TS_t dummy = AO_TS_INITIALIZER; 72 | (void)__atomic_test_and_set(&dummy, __ATOMIC_SEQ_CST); 73 | } 74 | # else 75 | # define AO_nop_full() __atomic_thread_fence(__ATOMIC_SEQ_CST) 76 | # endif 77 | # define AO_HAVE_nop_full 78 | 79 | # define AO_fetch_and_add(p, v) __atomic_fetch_add(p, v, __ATOMIC_RELAXED) 80 | # define AO_HAVE_fetch_and_add 81 | # define AO_fetch_and_add1(p) AO_fetch_and_add(p, 1) 82 | # define AO_HAVE_fetch_and_add1 83 | 84 | # define AO_or(p, v) (void)__atomic_or_fetch(p, v, __ATOMIC_RELAXED) 85 | # define AO_HAVE_or 86 | 87 | # define AO_load(p) __atomic_load_n(p, __ATOMIC_RELAXED) 88 | # define AO_HAVE_load 89 | # define AO_load_acquire(p) __atomic_load_n(p, __ATOMIC_ACQUIRE) 90 | # define AO_HAVE_load_acquire 91 | # define AO_load_acquire_read(p) AO_load_acquire(p) 92 | # define AO_HAVE_load_acquire_read 93 | 94 | # define AO_store(p, v) __atomic_store_n(p, v, __ATOMIC_RELAXED) 95 | # define AO_HAVE_store 96 | # define AO_store_release(p, v) __atomic_store_n(p, v, __ATOMIC_RELEASE) 97 | # define AO_HAVE_store_release 98 | # define AO_store_release_write(p, v) AO_store_release(p, v) 99 | # define AO_HAVE_store_release_write 100 | 101 | # define AO_char_load(p) __atomic_load_n(p, __ATOMIC_RELAXED) 102 | # define AO_HAVE_char_load 103 | # define AO_char_store(p, v) __atomic_store_n(p, v, __ATOMIC_RELAXED) 104 | # define AO_HAVE_char_store 105 | 106 | # ifdef AO_REQUIRE_CAS 107 | AO_INLINE int 108 | AO_compare_and_swap(volatile AO_t *p, AO_t ov, AO_t nv) 109 | { 110 | return (int)__atomic_compare_exchange_n(p, &ov, nv, 0, 111 | __ATOMIC_RELAXED, __ATOMIC_RELAXED); 112 | } 113 | 114 | AO_INLINE int 115 | AO_compare_and_swap_release(volatile AO_t *p, AO_t ov, AO_t nv) 116 | { 117 | return (int)__atomic_compare_exchange_n(p, &ov, nv, 0, 118 | __ATOMIC_RELEASE, __ATOMIC_RELAXED); 119 | } 120 | # define AO_HAVE_compare_and_swap_release 121 | # endif 122 | 123 | # ifdef __cplusplus 124 | } /* extern "C" */ 125 | # endif 126 | 127 | # ifndef NO_LOCKFREE_AO_OR 128 | /* __atomic_or_fetch is assumed to be lock-free. */ 129 | # define HAVE_LOCKFREE_AO_OR 1 130 | # endif 131 | 132 | #else 133 | /* Fallback to libatomic_ops. */ 134 | # include "atomic_ops.h" 135 | 136 | /* AO_compiler_barrier, AO_load and AO_store should be defined for */ 137 | /* all targets; the rest of the primitives are guaranteed to exist */ 138 | /* only if AO_REQUIRE_CAS is defined (or if the corresponding */ 139 | /* AO_HAVE_x macro is defined). x86/x64 targets have AO_nop_full, */ 140 | /* AO_load_acquire, AO_store_release, at least. */ 141 | # if (!defined(AO_HAVE_load) || !defined(AO_HAVE_store)) && !defined(CPPCHECK) 142 | # error AO_load or AO_store is missing; probably old version of atomic_ops 143 | # endif 144 | 145 | #endif /* !GC_BUILTIN_ATOMIC */ 146 | 147 | #endif /* GC_ATOMIC_OPS_H */ 148 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/m4/gc_set_version.m4: -------------------------------------------------------------------------------- 1 | # 2 | # THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 3 | # OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 4 | # 5 | # Permission is hereby granted to use or copy this program 6 | # for any purpose, provided the above notices are retained on all copies. 7 | # Permission to modify the code and to distribute modified code is granted, 8 | # provided the above notices are retained, and a notice that the code was 9 | # modified is included with the above copyright notice. 10 | 11 | # GC_SET_VERSION 12 | # sets and AC_DEFINEs GC_VERSION_MAJOR, GC_VERSION_MINOR and GC_VERSION_MICRO 13 | # based on the contents of PACKAGE_VERSION; PACKAGE_VERSION must conform to 14 | # [0-9]+[.][0-9]+[.][0-9]+ 15 | # 16 | AC_DEFUN([GC_SET_VERSION], [ 17 | AC_MSG_CHECKING(GC version numbers) 18 | GC_VERSION_MAJOR=`echo $PACKAGE_VERSION | sed 's/^\([[0-9]][[0-9]]*\)[[.]].*$/\1/g'` 19 | GC_VERSION_MINOR=`echo $PACKAGE_VERSION | sed 's/^[[^.]]*[[.]]\([[0-9]][[0-9]]*\).*$/\1/g'` 20 | GC_VERSION_MICRO=`echo $PACKAGE_VERSION | sed 's/^[[^.]]*[[.]][[^.]]*[[.]]\([[0-9]][[0-9]]*\)$/\1/g'` 21 | 22 | if test :$GC_VERSION_MAJOR: = :: \ 23 | -o :$GC_VERSION_MINOR: = :: \ 24 | -o :$GC_VERSION_MICRO: = :: ; 25 | then 26 | AC_MSG_RESULT(invalid) 27 | AC_MSG_ERROR([nonconforming PACKAGE_VERSION='$PACKAGE_VERSION']) 28 | fi 29 | 30 | AC_DEFINE_UNQUOTED([GC_VERSION_MAJOR], $GC_VERSION_MAJOR, 31 | [The major version number of this GC release.]) 32 | AC_DEFINE_UNQUOTED([GC_VERSION_MINOR], $GC_VERSION_MINOR, 33 | [The minor version number of this GC release.]) 34 | AC_DEFINE_UNQUOTED([GC_VERSION_MICRO], $GC_VERSION_MICRO, 35 | [The micro version number of this GC release.]) 36 | AC_MSG_RESULT(major=$GC_VERSION_MAJOR minor=$GC_VERSION_MINOR \ 37 | micro=$GC_VERSION_MICRO) 38 | ]) 39 | 40 | sinclude(libtool.m4) 41 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/obj_map.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers 3 | * Copyright (c) 1991, 1992 by Xerox Corporation. All rights reserved. 4 | * Copyright (c) 1999-2001 by Hewlett-Packard Company. All rights reserved. 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | */ 15 | 16 | #include "private/gc_priv.h" 17 | 18 | /* Routines for maintaining maps describing heap block 19 | * layouts for various object sizes. Allows fast pointer validity checks 20 | * and fast location of object start locations on machines (such as SPARC) 21 | * with slow division. 22 | */ 23 | 24 | /* Consider pointers that are offset bytes displaced from the beginning */ 25 | /* of an object to be valid. */ 26 | 27 | GC_API void GC_CALL GC_register_displacement(size_t offset) 28 | { 29 | LOCK(); 30 | GC_register_displacement_inner(offset); 31 | UNLOCK(); 32 | } 33 | 34 | GC_INNER void GC_register_displacement_inner(size_t offset) 35 | { 36 | GC_ASSERT(I_HOLD_LOCK()); 37 | if (offset >= VALID_OFFSET_SZ) { 38 | ABORT("Bad argument to GC_register_displacement"); 39 | } 40 | if (!GC_valid_offsets[offset]) { 41 | GC_valid_offsets[offset] = TRUE; 42 | GC_modws_valid_offsets[offset % sizeof(word)] = TRUE; 43 | } 44 | } 45 | 46 | #ifdef MARK_BIT_PER_GRANULE 47 | /* Add a heap block map for objects of size granules to obj_map. */ 48 | /* A size of 0 is used for large objects. Return FALSE on failure. */ 49 | GC_INNER GC_bool GC_add_map_entry(size_t granules) 50 | { 51 | unsigned displ; 52 | unsigned short * new_map; 53 | 54 | GC_ASSERT(I_HOLD_LOCK()); 55 | if (granules > BYTES_TO_GRANULES(MAXOBJBYTES)) granules = 0; 56 | if (GC_obj_map[granules] != 0) return TRUE; 57 | 58 | new_map = (unsigned short *)GC_scratch_alloc(OBJ_MAP_LEN * sizeof(short)); 59 | if (EXPECT(NULL == new_map, FALSE)) return FALSE; 60 | 61 | GC_COND_LOG_PRINTF( 62 | "Adding block map for size of %u granules (%u bytes)\n", 63 | (unsigned)granules, (unsigned)GRANULES_TO_BYTES(granules)); 64 | if (granules == 0) { 65 | for (displ = 0; displ < OBJ_MAP_LEN; displ++) { 66 | new_map[displ] = 1; /* Nonzero to get us out of marker fast path. */ 67 | } 68 | } else { 69 | for (displ = 0; displ < OBJ_MAP_LEN; displ++) { 70 | new_map[displ] = (unsigned short)(displ % granules); 71 | } 72 | } 73 | GC_obj_map[granules] = new_map; 74 | return TRUE; 75 | } 76 | #endif /* MARK_BIT_PER_GRANULE */ 77 | 78 | GC_INNER void GC_initialize_offsets(void) 79 | { 80 | unsigned i; 81 | if (GC_all_interior_pointers) { 82 | for (i = 0; i < VALID_OFFSET_SZ; ++i) 83 | GC_valid_offsets[i] = TRUE; 84 | } else { 85 | BZERO(GC_valid_offsets, sizeof(GC_valid_offsets)); 86 | for (i = 0; i < sizeof(word); ++i) 87 | GC_modws_valid_offsets[i] = FALSE; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/pthread_start.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | * Copyright (c) 1996 by Silicon Graphics. All rights reserved. 4 | * Copyright (c) 1998 by Fergus Henderson. All rights reserved. 5 | * Copyright (c) 2000-2010 by Hewlett-Packard Development Company. 6 | * All rights reserved. 7 | * 8 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 9 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 10 | * 11 | * Permission is hereby granted to use or copy this program 12 | * for any purpose, provided the above notices are retained on all copies. 13 | * Permission to modify the code and to distribute modified code is granted, 14 | * provided the above notices are retained, and a notice that the code was 15 | * modified is included with the above copyright notice. 16 | */ 17 | 18 | /* We want to make sure that GC_thread_exit_proc() is unconditionally */ 19 | /* invoked, even if the client is not compiled with -fexceptions, but */ 20 | /* the GC is. The workaround is to put GC_pthread_start_inner() in its */ 21 | /* own file (pthread_start.c), and undefine __EXCEPTIONS in the GCC */ 22 | /* case at the top of the file. FIXME: it's still unclear whether this */ 23 | /* will actually cause the exit handler to be invoked last when */ 24 | /* thread_exit is called (and if -fexceptions is used). */ 25 | #if !defined(DONT_UNDEF_EXCEPTIONS) && defined(__GNUC__) && defined(__linux__) 26 | /* We undefine __EXCEPTIONS to avoid using GCC __cleanup__ attribute. */ 27 | /* The current NPTL implementation of pthread_cleanup_push uses */ 28 | /* __cleanup__ attribute when __EXCEPTIONS is defined (-fexceptions). */ 29 | /* The stack unwinding and cleanup with __cleanup__ attributes work */ 30 | /* correctly when everything is compiled with -fexceptions, but it is */ 31 | /* not the requirement for this library clients to use -fexceptions */ 32 | /* everywhere. With __EXCEPTIONS undefined, the cleanup routines are */ 33 | /* registered with __pthread_register_cancel thus should work anyway. */ 34 | # undef __EXCEPTIONS 35 | #endif 36 | 37 | #include "private/pthread_support.h" 38 | 39 | #if defined(GC_PTHREADS) \ 40 | && !defined(SN_TARGET_ORBIS) && !defined(SN_TARGET_PSP2) 41 | 42 | /* Invoked from GC_pthread_start. */ 43 | GC_INNER_PTHRSTART void *GC_CALLBACK GC_pthread_start_inner( 44 | struct GC_stack_base *sb, void *arg) 45 | { 46 | void * (*start)(void *); 47 | void * start_arg; 48 | void * result; 49 | volatile GC_thread me = 50 | GC_start_rtn_prepare_thread(&start, &start_arg, sb, arg); 51 | 52 | # ifndef NACL 53 | pthread_cleanup_push(GC_thread_exit_proc, (void *)me); 54 | # endif 55 | result = (*start)(start_arg); 56 | # if defined(DEBUG_THREADS) && !defined(GC_PTHREAD_START_STANDALONE) 57 | GC_log_printf("Finishing thread %p\n", 58 | (void *)GC_PTHREAD_PTRVAL(pthread_self())); 59 | # endif 60 | me -> status = result; 61 | GC_end_stubborn_change(me); /* cannot use GC_dirty */ 62 | /* Cleanup acquires lock, ensuring that we can't exit while */ 63 | /* a collection that thinks we're alive is trying to stop us. */ 64 | # ifdef NACL 65 | GC_thread_exit_proc((void *)me); 66 | # else 67 | pthread_cleanup_pop(1); 68 | # endif 69 | return result; 70 | } 71 | 72 | #endif /* GC_PTHREADS */ 73 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/sparc_mach_dep.S: -------------------------------------------------------------------------------- 1 | ! SPARCompiler 3.0 and later apparently no longer handles 2 | ! asm outside functions. So we need a separate .s file 3 | ! This is only set up for SunOS 5, not SunOS 4. 4 | ! Assumes this is called before the stack contents are 5 | ! examined. 6 | 7 | .seg "text" 8 | .globl GC_save_regs_in_stack 9 | GC_save_regs_in_stack: 10 | #if defined(__arch64__) || defined(__sparcv9) 11 | save %sp,-128,%sp 12 | flushw 13 | ret 14 | restore %sp,2047+128,%o0 15 | #else /* 32 bit SPARC */ 16 | ta 0x3 ! ST_FLUSH_WINDOWS 17 | mov %sp,%o0 18 | retl 19 | nop 20 | #endif /* 32 bit SPARC */ 21 | .GC_save_regs_in_stack_end: 22 | .size GC_save_regs_in_stack,.GC_save_regs_in_stack_end-GC_save_regs_in_stack 23 | 24 | ! GC_clear_stack_inner(arg, limit) clears stack area up to limit and 25 | ! returns arg. Stack clearing is crucial on SPARC, so we supply 26 | ! an assembly version that s more careful. Assumes limit is hotter 27 | ! than sp, and limit is 8 byte aligned. 28 | .globl GC_clear_stack_inner 29 | GC_clear_stack_inner: 30 | #if defined(__arch64__) || defined(__sparcv9) 31 | mov %sp,%o2 ! Save sp 32 | add %sp,2047-8,%o3 ! p = sp+bias-8 33 | add %o1,-2047-192,%sp ! Move sp out of the way, 34 | ! so that traps still work. 35 | ! Includes some extra words 36 | ! so we can be sloppy below. 37 | loop: 38 | stx %g0,[%o3] ! *(long *)p = 0 39 | cmp %o3,%o1 40 | bgu,pt %xcc, loop ! if (p > limit) goto loop 41 | add %o3,-8,%o3 ! p -= 8 (delay slot) 42 | retl 43 | mov %o2,%sp ! Restore sp., delay slot 44 | #else /* 32 bit SPARC */ 45 | mov %sp,%o2 ! Save sp 46 | add %sp,-8,%o3 ! p = sp-8 47 | clr %g1 ! [g0,g1] = 0 48 | add %o1,-0x60,%sp ! Move sp out of the way, 49 | ! so that traps still work. 50 | ! Includes some extra words 51 | ! so we can be sloppy below. 52 | loop: 53 | std %g0,[%o3] ! *(long long *)p = 0 54 | cmp %o3,%o1 55 | bgu loop ! if (p > limit) goto loop 56 | add %o3,-8,%o3 ! p -= 8 (delay slot) 57 | retl 58 | mov %o2,%sp ! Restore sp., delay slot 59 | #endif /* 32 bit SPARC */ 60 | .GC_clear_stack_inner_end: 61 | .size GC_clear_stack_inner,.GC_clear_stack_inner_end-GC_clear_stack_inner 62 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/sparc_netbsd_mach_dep.s: -------------------------------------------------------------------------------- 1 | ! SPARCompiler 3.0 and later apparently no longer handles 2 | ! asm outside functions. So we need a separate .s file 3 | ! This is only set up for SunOS 4. 4 | ! Assumes this is called before the stack contents are 5 | ! examined. 6 | 7 | #include "machine/asm.h" 8 | 9 | .seg "text" 10 | .globl _C_LABEL(GC_save_regs_in_stack) 11 | .globl _C_LABEL(GC_push_regs) 12 | _C_LABEL(GC_save_regs_in_stack): 13 | _C_LABEL(GC_push_regs): 14 | ta 0x3 ! ST_FLUSH_WINDOWS 15 | mov %sp,%o0 16 | retl 17 | nop 18 | 19 | .globl _C_LABEL(GC_clear_stack_inner) 20 | _C_LABEL(GC_clear_stack_inner): 21 | mov %sp,%o2 ! Save sp 22 | add %sp,-8,%o3 ! p = sp-8 23 | clr %g1 ! [g0,g1] = 0 24 | add %o1,-0x60,%sp ! Move sp out of the way, 25 | ! so that traps still work. 26 | ! Includes some extra words 27 | ! so we can be sloppy below. 28 | loop: 29 | std %g0,[%o3] ! *(long long *)p = 0 30 | cmp %o3,%o1 31 | bgu loop ! if (p > limit) goto loop 32 | add %o3,-8,%o3 ! p -= 8 (delay slot) 33 | retl 34 | mov %o2,%sp ! Restore sp., delay slot 35 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/tests/atomicops.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 Ivan Maidanski 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to use or copy this program 8 | * for any purpose, provided the above notices are retained on all copies. 9 | * Permission to modify the code and to distribute modified code is granted, 10 | * provided the above notices are retained, and a notice that the code was 11 | * modified is included with the above copyright notice. 12 | */ 13 | 14 | /* Minimal testing of atomic operations used by the BDWGC. Primary use */ 15 | /* is to determine whether compiler atomic intrinsics can be relied on. */ 16 | 17 | #ifdef HAVE_CONFIG_H 18 | # include "config.h" 19 | #endif 20 | 21 | #include 22 | 23 | #if defined(GC_BUILTIN_ATOMIC) || defined(GC_THREADS) 24 | 25 | # include 26 | 27 | # ifdef PARALLEL_MARK 28 | # define AO_REQUIRE_CAS 29 | # endif 30 | 31 | # include "private/gc_atomic_ops.h" 32 | 33 | # define TA_assert(e) \ 34 | if (!(e)) { \ 35 | fprintf(stderr, "Assertion failure, line %d: " #e "\n", __LINE__); \ 36 | exit(-1); \ 37 | } 38 | 39 | int main(void) { 40 | AO_t x = 13; 41 | # if defined(AO_HAVE_char_load) || defined(AO_HAVE_char_store) 42 | unsigned char c = 117; 43 | # endif 44 | # ifdef AO_HAVE_test_and_set_acquire 45 | AO_TS_t z = AO_TS_INITIALIZER; 46 | 47 | TA_assert(AO_test_and_set_acquire(&z) == AO_TS_CLEAR); 48 | TA_assert(AO_test_and_set_acquire(&z) == AO_TS_SET); 49 | AO_CLEAR(&z); 50 | # endif 51 | AO_compiler_barrier(); 52 | # ifdef AO_HAVE_nop_full 53 | AO_nop_full(); 54 | # endif 55 | # ifdef AO_HAVE_char_load 56 | TA_assert(AO_char_load(&c) == 117); 57 | # endif 58 | # ifdef AO_HAVE_char_store 59 | AO_char_store(&c, 119); 60 | TA_assert(c == 119); 61 | # endif 62 | # ifdef AO_HAVE_load_acquire 63 | TA_assert(AO_load_acquire(&x) == 13); 64 | # endif 65 | # if defined(AO_HAVE_fetch_and_add) && defined(AO_HAVE_fetch_and_add1) 66 | TA_assert(AO_fetch_and_add(&x, 42) == 13); 67 | TA_assert(AO_fetch_and_add(&x, (AO_t)(-43)) == 55); 68 | TA_assert(AO_fetch_and_add1(&x) == 12); 69 | # endif 70 | # ifdef AO_HAVE_compare_and_swap_release 71 | TA_assert(!AO_compare_and_swap(&x, 14, 42)); 72 | TA_assert(x == 13); 73 | TA_assert(AO_compare_and_swap_release(&x, 13, 42)); 74 | TA_assert(x == 42); 75 | # else 76 | if (*(volatile AO_t *)&x == 13) 77 | *(volatile AO_t *)&x = 42; 78 | # endif 79 | # ifdef AO_HAVE_or 80 | AO_or(&x, 66); 81 | TA_assert(x == 106); 82 | # endif 83 | # ifdef AO_HAVE_store_release 84 | AO_store_release(&x, 113); 85 | TA_assert(x == 113); 86 | # endif 87 | return 0; 88 | } 89 | 90 | #else 91 | 92 | int main(void) 93 | { 94 | printf("test skipped\n"); 95 | return 0; 96 | } 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/tests/disclaim_bench.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011 by Hewlett-Packard Company. All rights reserved. 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to use or copy this program 8 | * for any purpose, provided the above notices are retained on all copies. 9 | * Permission to modify the code and to distribute modified code is granted, 10 | * provided the above notices are retained, and a notice that the code was 11 | * modified is included with the above copyright notice. 12 | * 13 | */ 14 | 15 | #include 16 | 17 | #ifdef HAVE_CONFIG_H 18 | # include "config.h" 19 | #endif 20 | 21 | #include "gc/gc_disclaim.h" 22 | 23 | #define NOT_GCBUILD 24 | #include "private/gc_priv.h" 25 | 26 | #undef rand 27 | static GC_RAND_STATE_T seed; 28 | #define rand() GC_RAND_NEXT(&seed) 29 | 30 | #define my_assert(e) \ 31 | if (!(e)) { \ 32 | fprintf(stderr, "Assertion failure, line %d: " #e "\n", __LINE__); \ 33 | exit(-1); \ 34 | } 35 | 36 | static int free_count = 0; 37 | 38 | struct testobj_s { 39 | struct testobj_s *keep_link; 40 | int i; 41 | }; 42 | 43 | typedef struct testobj_s *testobj_t; 44 | 45 | static void GC_CALLBACK testobj_finalize(void *obj, void *carg) 46 | { 47 | ++*(int *)carg; 48 | my_assert(((testobj_t)obj)->i == 109); 49 | ((testobj_t)obj)->i = 110; 50 | } 51 | 52 | static const struct GC_finalizer_closure fclos = { 53 | testobj_finalize, 54 | &free_count 55 | }; 56 | 57 | static testobj_t testobj_new(int model) 58 | { 59 | testobj_t obj; 60 | switch (model) { 61 | # ifndef GC_NO_FINALIZATION 62 | case 0: 63 | obj = (struct testobj_s *)GC_malloc(sizeof(struct testobj_s)); 64 | if (obj != NULL) 65 | GC_register_finalizer_no_order(obj, testobj_finalize, 66 | &free_count, NULL, NULL); 67 | break; 68 | # endif 69 | case 1: 70 | obj = (testobj_t)GC_finalized_malloc(sizeof(struct testobj_s), 71 | &fclos); 72 | break; 73 | case 2: 74 | obj = (struct testobj_s *)GC_malloc(sizeof(struct testobj_s)); 75 | break; 76 | default: 77 | exit(-1); 78 | } 79 | if (obj == NULL) { 80 | fprintf(stderr, "Out of memory!\n"); 81 | exit(3); 82 | } 83 | my_assert(obj->i == 0 && obj->keep_link == NULL); 84 | obj->i = 109; 85 | return obj; 86 | } 87 | 88 | #define ALLOC_CNT (2*1024*1024) 89 | #define KEEP_CNT (32*1024) 90 | 91 | static char const *model_str[3] = { 92 | "regular finalization", 93 | "finalize on reclaim", 94 | "no finalization" 95 | }; 96 | 97 | int main(int argc, char **argv) 98 | { 99 | int i; 100 | int model, model_min, model_max; 101 | testobj_t *keep_arr; 102 | 103 | GC_INIT(); 104 | GC_init_finalized_malloc(); 105 | if (argc == 2 && strcmp(argv[1], "--help") == 0) { 106 | fprintf(stderr, 107 | "Usage: %s [FINALIZATION_MODEL]\n" 108 | "\t0 -- original finalization\n" 109 | "\t1 -- finalization on reclaim\n" 110 | "\t2 -- no finalization\n", argv[0]); 111 | return 1; 112 | } 113 | if (argc == 2) { 114 | model_min = model_max = (int)COVERT_DATAFLOW(atoi(argv[1])); 115 | if (model_min < 0 || model_max > 2) 116 | exit(2); 117 | } else { 118 | # ifndef GC_NO_FINALIZATION 119 | model_min = 0; 120 | # else 121 | model_min = 1; 122 | # endif 123 | model_max = 2; 124 | } 125 | if (GC_get_find_leak()) 126 | printf("This test program is not designed for leak detection mode\n"); 127 | 128 | keep_arr = (testobj_t *)GC_malloc(sizeof(void *) * KEEP_CNT); 129 | if (NULL == keep_arr) { 130 | fprintf(stderr, "Out of memory!\n"); 131 | exit(3); 132 | } 133 | 134 | printf("\t\t\tfin. ratio time/s time/fin.\n"); 135 | for (model = model_min; model <= model_max; ++model) { 136 | double t = 0.0; 137 | # ifndef NO_CLOCK 138 | CLOCK_TYPE tI, tF; 139 | 140 | GET_TIME(tI); 141 | # endif 142 | free_count = 0; 143 | for (i = 0; i < ALLOC_CNT; ++i) { 144 | int k = rand() % KEEP_CNT; 145 | keep_arr[k] = testobj_new(model); 146 | } 147 | GC_gcollect(); 148 | # ifndef NO_CLOCK 149 | GET_TIME(tF); 150 | t = (double)MS_TIME_DIFF(tF, tI) * 1e-3; 151 | # endif 152 | 153 | # ifdef EMBOX 154 | /* Workaround some issue with %g processing in Embox libc. */ 155 | # define PRINTF_SPEC_12g "%12f" 156 | # else 157 | # define PRINTF_SPEC_12g "%12g" 158 | # endif 159 | if (model < 2 && free_count > 0) { 160 | printf("%20s: %12.4f " PRINTF_SPEC_12g " " PRINTF_SPEC_12g "\n", 161 | model_str[model], free_count / (double)ALLOC_CNT, 162 | t, t / free_count); 163 | } else { 164 | printf("%20s: %12.4f " PRINTF_SPEC_12g " %12s\n", 165 | model_str[model], 0.0, t, "N/A"); 166 | } 167 | } 168 | return 0; 169 | } 170 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/tests/huge.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | #ifndef GC_IGNORE_WARN 7 | /* Ignore misleading "Out of Memory!" warning (which is printed on */ 8 | /* every GC_MALLOC call below) by defining this macro before "gc.h" */ 9 | /* inclusion. */ 10 | # define GC_IGNORE_WARN 11 | #endif 12 | 13 | #ifndef GC_MAXIMUM_HEAP_SIZE 14 | # define GC_MAXIMUM_HEAP_SIZE 100 * 1024 * 1024 15 | # define GC_INITIAL_HEAP_SIZE GC_MAXIMUM_HEAP_SIZE / 20 16 | /* Otherwise heap expansion aborts when deallocating large block. */ 17 | /* That's OK. We test this corner case mostly to make sure that */ 18 | /* it fails predictably. */ 19 | #endif 20 | 21 | #ifndef GC_ATTR_ALLOC_SIZE 22 | /* Omit alloc_size attribute to avoid compiler warnings about */ 23 | /* exceeding maximum object size when values close to GC_SWORD_MAX */ 24 | /* are passed to GC_MALLOC. */ 25 | # define GC_ATTR_ALLOC_SIZE(argnum) /* empty */ 26 | #endif 27 | 28 | #include "gc.h" 29 | 30 | /* 31 | * Check that very large allocation requests fail. "Success" would usually 32 | * indicate that the size was somehow converted to a negative 33 | * number. Clients shouldn't do this, but we should fail in the 34 | * expected manner. 35 | */ 36 | 37 | #define CHECK_ALLOC_FAILED(r, sz_str) \ 38 | do { \ 39 | if (NULL != (r)) { \ 40 | fprintf(stderr, \ 41 | "Size " sz_str " allocation unexpectedly succeeded\n"); \ 42 | exit(1); \ 43 | } \ 44 | } while (0) 45 | 46 | #define GC_WORD_MAX ((GC_word)-1) 47 | #define GC_SWORD_MAX ((GC_signed_word)(GC_WORD_MAX >> 1)) 48 | 49 | int main(void) 50 | { 51 | GC_INIT(); 52 | 53 | CHECK_ALLOC_FAILED(GC_MALLOC(GC_SWORD_MAX - 1024), "SWORD_MAX-1024"); 54 | CHECK_ALLOC_FAILED(GC_MALLOC(GC_SWORD_MAX), "SWORD_MAX"); 55 | /* Skip other checks to avoid "exceeds maximum object size" gcc warning. */ 56 | # if !defined(_FORTIFY_SOURCE) 57 | CHECK_ALLOC_FAILED(GC_MALLOC((GC_word)GC_SWORD_MAX + 1), "SWORD_MAX+1"); 58 | CHECK_ALLOC_FAILED(GC_MALLOC((GC_word)GC_SWORD_MAX + 1024), 59 | "SWORD_MAX+1024"); 60 | CHECK_ALLOC_FAILED(GC_MALLOC(GC_WORD_MAX - 1024), "WORD_MAX-1024"); 61 | CHECK_ALLOC_FAILED(GC_MALLOC(GC_WORD_MAX - 16), "WORD_MAX-16"); 62 | CHECK_ALLOC_FAILED(GC_MALLOC(GC_WORD_MAX - 8), "WORD_MAX-8"); 63 | CHECK_ALLOC_FAILED(GC_MALLOC(GC_WORD_MAX - 4), "WORD_MAX-4"); 64 | CHECK_ALLOC_FAILED(GC_MALLOC(GC_WORD_MAX), "WORD_MAX"); 65 | # endif 66 | printf("SUCCEEDED\n"); 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/tests/initfromthread.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011 Ludovic Courtes 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to use or copy this program 8 | * for any purpose, provided the above notices are retained on all copies. 9 | * Permission to modify the code and to distribute modified code is granted, 10 | * provided the above notices are retained, and a notice that the code was 11 | * modified is included with the above copyright notice. 12 | */ 13 | 14 | /* Make sure 'GC_INIT' can be called from threads other than the initial 15 | * thread. 16 | */ 17 | 18 | #ifdef HAVE_CONFIG_H 19 | # include "config.h" 20 | #endif 21 | 22 | #ifndef GC_THREADS 23 | # define GC_THREADS 24 | #endif 25 | 26 | #define GC_NO_THREAD_REDIRECTS 1 27 | /* Do not redirect thread creation and join calls. */ 28 | 29 | #include "gc.h" 30 | 31 | #ifdef GC_PTHREADS 32 | # include 33 | # include 34 | #else 35 | # ifndef WIN32_LEAN_AND_MEAN 36 | # define WIN32_LEAN_AND_MEAN 1 37 | # endif 38 | # define NOSERVICE 39 | # include 40 | #endif /* !GC_PTHREADS */ 41 | 42 | #include 43 | #include 44 | 45 | #ifdef GC_PTHREADS 46 | static void *thread(void *arg) 47 | #else 48 | static DWORD WINAPI thread(LPVOID arg) 49 | #endif 50 | { 51 | GC_INIT(); 52 | (void)GC_MALLOC(123); 53 | (void)GC_MALLOC(12345); 54 | # ifdef GC_PTHREADS 55 | return arg; 56 | # else 57 | return (DWORD)(GC_word)arg; 58 | # endif 59 | } 60 | 61 | #include "private/gcconfig.h" 62 | 63 | int main(void) 64 | { 65 | # ifdef GC_PTHREADS 66 | int code; 67 | pthread_t t; 68 | 69 | # ifdef LINT2 70 | t = pthread_self(); /* explicitly initialize to some value */ 71 | # endif 72 | # else 73 | HANDLE t; 74 | DWORD thread_id; 75 | # endif 76 | # if !(defined(BEOS) || defined(ANY_MSWIN) \ 77 | || (defined(DARWIN) && !defined(NO_PTHREAD_GET_STACKADDR_NP)) \ 78 | || ((defined(FREEBSD) || defined(LINUX) || defined(NETBSD) \ 79 | || defined(HOST_ANDROID)) && !defined(NO_PTHREAD_GETATTR_NP) \ 80 | && !defined(NO_PTHREAD_ATTR_GET_NP)) \ 81 | || (defined(GC_SOLARIS_THREADS) && !defined(_STRICT_STDC)) \ 82 | || (!defined(STACKBOTTOM) && (defined(HEURISTIC1) \ 83 | || (!defined(LINUX_STACKBOTTOM) && !defined(FREEBSD_STACKBOTTOM))))) 84 | /* GC_INIT() must be called from main thread only. */ 85 | GC_INIT(); 86 | # endif 87 | (void)GC_get_suspend_signal(); /* linking fails if no threads support */ 88 | if (GC_get_find_leak()) 89 | printf("This test program is not designed for leak detection mode\n"); 90 | # ifdef GC_PTHREADS 91 | if ((code = pthread_create (&t, NULL, thread, NULL)) != 0) { 92 | fprintf(stderr, "Thread #0 creation failed: %s\n", strerror(code)); 93 | return 1; 94 | } 95 | if ((code = pthread_join (t, NULL)) != 0) { 96 | fprintf(stderr, "Thread #0 join failed: %s\n", strerror(code)); 97 | return 1; 98 | } 99 | # else 100 | t = CreateThread(NULL, 0, thread, 0, 0, &thread_id); 101 | if (t == NULL) { 102 | fprintf(stderr, "Thread #0 creation failed, errcode= %d\n", 103 | (int)GetLastError()); 104 | return 1; 105 | } 106 | if (WaitForSingleObject(t, INFINITE) != WAIT_OBJECT_0) { 107 | fprintf(stderr, "Thread #0 join failed, errcode= %d\n", 108 | (int)GetLastError()); 109 | CloseHandle(t); 110 | return 1; 111 | } 112 | CloseHandle(t); 113 | # endif 114 | printf("SUCCEEDED\n"); 115 | return 0; 116 | } 117 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/tests/leak.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include "gc/leak_detector.h" 5 | 6 | #define N_TESTS 100 7 | 8 | int main(void) { 9 | char *p[N_TESTS]; 10 | unsigned i; 11 | 12 | GC_set_find_leak(1); /* for new collect versions not compiled */ 13 | /* with -DFIND_LEAK. */ 14 | 15 | GC_INIT(); /* Needed if thread-local allocation is enabled. */ 16 | /* FIXME: This is not ideal. */ 17 | 18 | p[0] = (char *)_aligned_malloc(70 /* size */, 16); 19 | if (!p[0]) { 20 | fprintf(stderr, "Aligned allocation failed\n"); 21 | return 1; 22 | } 23 | _aligned_free(p[0]); 24 | 25 | for (i = 0; i < N_TESTS; ++i) { 26 | p[i] = i > 0 ? (char*)malloc(sizeof(int) + i) 27 | : strdup("abc"); 28 | } 29 | CHECK_LEAKS(); 30 | for (i = 3; i < N_TESTS / 2; ++i) { 31 | p[i] = (char*)((i & 1) != 0 ? reallocarray(p[i], i, 43) 32 | : realloc(p[i], i * 16 + 1)); 33 | } 34 | CHECK_LEAKS(); 35 | for (i = 2; i < N_TESTS; ++i) { 36 | free(p[i]); 37 | } 38 | for (i = 0; i < N_TESTS / 8; ++i) { 39 | p[i] = i < 3 || i > 6 ? (char*)malloc(sizeof(int) + i) 40 | : strndup("abcd", i); 41 | } 42 | CHECK_LEAKS(); 43 | CHECK_LEAKS(); 44 | CHECK_LEAKS(); 45 | printf("SUCCEEDED\n"); 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/tests/middle.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Test at the boundary between small and large objects. 3 | * Inspired by a test case from Zoltan Varga. 4 | */ 5 | #include "gc.h" 6 | #include 7 | 8 | #define N_TESTS 40000 9 | #define ALLOC_SZ 4096 /* typical page size */ 10 | 11 | int main (void) 12 | { 13 | int i; 14 | 15 | GC_set_all_interior_pointers(0); 16 | GC_INIT(); 17 | if (GC_get_find_leak()) 18 | printf("This test program is not designed for leak detection mode\n"); 19 | 20 | for (i = 0; i < N_TESTS; ++i) { 21 | (void)GC_malloc_atomic(ALLOC_SZ); 22 | (void)GC_malloc(ALLOC_SZ); 23 | } 24 | 25 | /* Test delayed start of marker threads, if they are enabled. */ 26 | GC_start_mark_threads(); 27 | 28 | for (i = 0; i < N_TESTS; ++i) { 29 | (void)GC_malloc_atomic(ALLOC_SZ/2); 30 | (void)GC_malloc(ALLOC_SZ/2); 31 | } 32 | printf("Final heap size is %lu\n", (unsigned long)GC_get_heap_size()); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/tests/realloc.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include "gc.h" 5 | 6 | #define COUNT 10000000 7 | 8 | int main(void) { 9 | int i; 10 | unsigned long last_heap_size = 0; 11 | 12 | GC_INIT(); 13 | if (GC_get_find_leak()) 14 | printf("This test program is not designed for leak detection mode\n"); 15 | 16 | for (i = 0; i < COUNT; i++) { 17 | int **p = GC_NEW(int *); 18 | int *q = (int*)GC_MALLOC_ATOMIC(sizeof(int)); 19 | 20 | if (p == 0 || *p != 0) { 21 | fprintf(stderr, "GC_malloc returned garbage (or NULL)\n"); 22 | exit(1); 23 | } 24 | 25 | *p = (int*)GC_REALLOC(q, 2 * sizeof(int)); 26 | 27 | if (i % 10 == 0) { 28 | unsigned long heap_size = (unsigned long)GC_get_heap_size(); 29 | if (heap_size != last_heap_size) { 30 | printf("Heap size: %lu\n", heap_size); 31 | last_heap_size = heap_size; 32 | } 33 | } 34 | } 35 | printf("SUCCEEDED\n"); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/tests/smash.c: -------------------------------------------------------------------------------- 1 | /* Test that overwrite error detection works reasonably. */ 2 | 3 | #ifndef GC_DEBUG 4 | # define GC_DEBUG 5 | #endif 6 | 7 | #include "gc.h" 8 | 9 | #include 10 | 11 | #define COUNT 7000 12 | #define SIZE 40 13 | 14 | char * A[COUNT]; 15 | 16 | char * volatile q; 17 | 18 | int main(void) 19 | { 20 | int i; 21 | char *p; 22 | 23 | GC_INIT(); 24 | 25 | for (i = 0; i < COUNT; ++i) { 26 | A[i] = p = (char*)GC_MALLOC(SIZE); 27 | 28 | if (i%3000 == 0) { 29 | q = NULL; 30 | GC_gcollect(); 31 | } else if (i%5678 == 0 && p != 0) { 32 | /* Write a byte past the end of the allocated object */ 33 | /* but not beyond the last word of the object's memory. */ 34 | /* A volatile intermediate pointer variable is used to */ 35 | /* avoid a compiler complain of out-of-bounds access. */ 36 | q = &p[(SIZE + i/2000) /* 42 */]; 37 | *q = 42; 38 | } 39 | } 40 | printf("SUCCEEDED\n"); 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/tests/staticroots.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #ifndef GC_DEBUG 6 | # define GC_DEBUG 7 | #endif 8 | 9 | #include "gc.h" 10 | #include "gc/gc_backptr.h" 11 | 12 | #ifndef GC_TEST_IMPORT_API 13 | # define GC_TEST_IMPORT_API extern 14 | #endif 15 | 16 | /* Should match that in staticroots_lib.c. */ 17 | struct treenode { 18 | struct treenode *x; 19 | struct treenode *y; 20 | }; 21 | 22 | struct treenode *root[10] = { NULL }; 23 | 24 | /* Same as "root" variable but initialized to some non-zero value (to */ 25 | /* be placed to .data section instead of .bss). */ 26 | struct treenode *root_nz[10] = { (struct treenode *)(GC_word)1 }; 27 | 28 | static char *staticroot; /* intentionally static */ 29 | 30 | GC_TEST_IMPORT_API struct treenode * libsrl_mktree(int i); 31 | GC_TEST_IMPORT_API void * libsrl_init(void); 32 | GC_TEST_IMPORT_API struct treenode ** libsrl_getpelem(int i, int j); 33 | 34 | GC_TEST_IMPORT_API struct treenode ** libsrl_getpelem2(int i, int j); 35 | 36 | static void init_staticroot(void) 37 | { 38 | /* Intentionally put staticroot initialization in a function other */ 39 | /* than main to prevent CSA warning that staticroot variable can be */ 40 | /* changed to be a local one). */ 41 | staticroot = (char *)libsrl_init(); 42 | } 43 | 44 | int main(void) 45 | { 46 | int i, j; 47 | 48 | # ifdef STATICROOTSLIB_INIT_IN_MAIN 49 | GC_INIT(); 50 | # endif 51 | init_staticroot(); 52 | if (GC_get_find_leak()) 53 | printf("This test program is not designed for leak detection mode\n"); 54 | if (NULL == staticroot) { 55 | fprintf(stderr, "GC_malloc returned NULL\n"); 56 | return 2; 57 | } 58 | memset(staticroot, 0x42, sizeof(struct treenode)); 59 | GC_gcollect(); 60 | for (j = 0; j < 4; j++) { 61 | for (i = 0; i < (int)(sizeof(root) / sizeof(root[0])); ++i) { 62 | # ifdef STATICROOTSLIB2 63 | *libsrl_getpelem2(i, j) = libsrl_mktree(12); 64 | # endif 65 | *libsrl_getpelem(i, j) = libsrl_mktree(12); 66 | ((j & 1) != 0 ? root_nz : root)[i] = libsrl_mktree(12); 67 | GC_gcollect(); 68 | } 69 | for (i = 0; i < (int)sizeof(struct treenode); ++i) { 70 | if (staticroot[i] != 0x42) { 71 | fprintf(stderr, "Memory check failed\n"); 72 | return 1; 73 | } 74 | } 75 | } 76 | printf("SUCCEEDED\n"); 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/tests/staticroots_lib.c: -------------------------------------------------------------------------------- 1 | 2 | /* This test file is intended to be compiled into a DLL. */ 3 | 4 | #ifndef GC_DEBUG 5 | # define GC_DEBUG 6 | #endif 7 | 8 | #include "gc.h" 9 | 10 | #ifndef GC_TEST_EXPORT_API 11 | # if defined(GC_VISIBILITY_HIDDEN_SET) \ 12 | && !defined(__CEGCC__) && !defined(__CYGWIN__) && !defined(__MINGW32__) 13 | # define GC_TEST_EXPORT_API \ 14 | extern __attribute__((__visibility__("default"))) 15 | # else 16 | # define GC_TEST_EXPORT_API extern 17 | # endif 18 | #endif 19 | 20 | struct treenode { 21 | struct treenode *x; 22 | struct treenode *y; 23 | }; 24 | 25 | static struct treenode *root[10] = { 0 }; 26 | static struct treenode *root_nz[10] = { (struct treenode *)(GC_word)2 }; 27 | 28 | /* Declare it to avoid "no previous prototype" clang warning. */ 29 | GC_TEST_EXPORT_API struct treenode ** libsrl_getpelem(int i, int j); 30 | 31 | #ifdef STATICROOTSLIB2 32 | # define libsrl_getpelem libsrl_getpelem2 33 | #else 34 | 35 | GC_TEST_EXPORT_API struct treenode * libsrl_mktree(int i); 36 | GC_TEST_EXPORT_API void * libsrl_init(void); 37 | 38 | GC_TEST_EXPORT_API struct treenode * libsrl_mktree(int i) 39 | { 40 | struct treenode * r = GC_NEW(struct treenode); 41 | if (0 == i) 42 | return 0; 43 | if (1 == i) 44 | r = (struct treenode *)GC_MALLOC_ATOMIC(sizeof(struct treenode)); 45 | if (r) { 46 | struct treenode *x = libsrl_mktree(i - 1); 47 | struct treenode *y = libsrl_mktree(i - 1); 48 | r -> x = x; 49 | r -> y = y; 50 | if (i != 1) { 51 | GC_END_STUBBORN_CHANGE(r); 52 | GC_reachable_here(x); 53 | GC_reachable_here(y); 54 | } 55 | } 56 | return r; 57 | } 58 | 59 | GC_TEST_EXPORT_API void * libsrl_init(void) 60 | { 61 | # ifdef TEST_MANUAL_VDB 62 | GC_set_manual_vdb_allowed(1); 63 | # endif 64 | # ifndef STATICROOTSLIB_INIT_IN_MAIN 65 | GC_INIT(); 66 | # endif 67 | # ifndef NO_INCREMENTAL 68 | GC_enable_incremental(); 69 | # endif 70 | return GC_MALLOC(sizeof(struct treenode)); 71 | } 72 | 73 | #endif /* !STATICROOTSLIB2 */ 74 | 75 | GC_TEST_EXPORT_API struct treenode ** libsrl_getpelem(int i, int j) 76 | { 77 | # if defined(CPPCHECK) 78 | struct treenode node = { 0, 0 }; 79 | GC_noop1((GC_word)node.x | (GC_word)node.y); 80 | # endif 81 | return &((j & 1) != 0 ? root_nz : root)[i]; 82 | } 83 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/tests/subthreadcreate.c: -------------------------------------------------------------------------------- 1 | 2 | #ifdef HAVE_CONFIG_H 3 | /* For GC_THREADS and PARALLEL_MARK */ 4 | # include "config.h" 5 | #endif 6 | 7 | #ifdef GC_THREADS 8 | # undef GC_NO_THREAD_REDIRECTS 9 | # include "gc.h" 10 | 11 | # ifdef PARALLEL_MARK 12 | # define AO_REQUIRE_CAS 13 | # endif 14 | # include "private/gc_atomic_ops.h" 15 | #endif /* GC_THREADS */ 16 | 17 | #include 18 | 19 | #ifdef AO_HAVE_fetch_and_add1 20 | 21 | #ifdef GC_PTHREADS 22 | # include /* for EAGAIN */ 23 | # include 24 | # include 25 | #else 26 | # ifndef WIN32_LEAN_AND_MEAN 27 | # define WIN32_LEAN_AND_MEAN 1 28 | # endif 29 | # define NOSERVICE 30 | # include 31 | #endif /* !GC_PTHREADS */ 32 | 33 | #if defined(__HAIKU__) 34 | # include 35 | #endif 36 | 37 | #include 38 | 39 | #ifndef NTHREADS 40 | # define NTHREADS 5 41 | #endif 42 | 43 | #define NTHREADS_INNER (NTHREADS * 6) /* number of threads to create */ 44 | 45 | #ifndef MAX_SUBTHREAD_DEPTH 46 | # define MAX_ALIVE_THREAD_COUNT 55 47 | # define MAX_SUBTHREAD_DEPTH 7 48 | # define MAX_SUBTHREAD_COUNT 200 49 | #endif 50 | 51 | #ifndef DECAY_NUMER 52 | # define DECAY_NUMER 15 53 | # define DECAY_DENOM 16 54 | #endif 55 | 56 | volatile AO_t thread_created_cnt = 0; 57 | volatile AO_t thread_ended_cnt = 0; 58 | 59 | #ifdef GC_PTHREADS 60 | static void *entry(void *arg) 61 | #else 62 | static DWORD WINAPI entry(LPVOID arg) 63 | #endif 64 | { 65 | int thread_num = (int)AO_fetch_and_add1(&thread_created_cnt); 66 | GC_word my_depth = (GC_word)arg + 1; 67 | 68 | if (my_depth <= MAX_SUBTHREAD_DEPTH 69 | && thread_num < MAX_SUBTHREAD_COUNT 70 | && (thread_num % DECAY_DENOM) < DECAY_NUMER 71 | && thread_num - (int)AO_load(&thread_ended_cnt) 72 | <= MAX_ALIVE_THREAD_COUNT) { 73 | # ifdef GC_PTHREADS 74 | int err; 75 | pthread_t th; 76 | 77 | err = pthread_create(&th, NULL, entry, (void *)my_depth); 78 | if (err != 0) { 79 | fprintf(stderr, 80 | "Thread #%d creation failed from other thread: %s\n", 81 | thread_num, strerror(err)); 82 | if (err != EAGAIN) 83 | exit(2); 84 | } else { 85 | err = pthread_detach(th); 86 | if (err != 0) { 87 | fprintf(stderr, "Thread #%d detach failed: %s\n", 88 | thread_num, strerror(err)); 89 | exit(2); 90 | } 91 | } 92 | # else 93 | HANDLE th; 94 | DWORD thread_id; 95 | 96 | th = CreateThread(NULL, 0, entry, (LPVOID)my_depth, 0, &thread_id); 97 | if (th == NULL) { 98 | fprintf(stderr, "Thread #%d creation failed, errcode= %d\n", 99 | thread_num, (int)GetLastError()); 100 | exit(2); 101 | } 102 | CloseHandle(th); 103 | # endif 104 | } 105 | 106 | (void)AO_fetch_and_add1(&thread_ended_cnt); 107 | return 0; 108 | } 109 | 110 | int main(void) 111 | { 112 | #if NTHREADS > 0 113 | int i, n; 114 | # ifdef GC_PTHREADS 115 | int err; 116 | pthread_t th[NTHREADS_INNER]; 117 | # else 118 | HANDLE th[NTHREADS_INNER]; 119 | # endif 120 | int th_nums[NTHREADS_INNER]; 121 | 122 | GC_INIT(); 123 | for (i = 0; i < NTHREADS_INNER; ++i) { 124 | th_nums[i] = (int)AO_fetch_and_add1(&thread_created_cnt); 125 | # ifdef GC_PTHREADS 126 | err = pthread_create(&th[i], NULL, entry, 0); 127 | if (err) { 128 | fprintf(stderr, "Thread #%d creation failed: %s\n", 129 | th_nums[i], strerror(err)); 130 | if (i > 0 && EAGAIN == err) break; 131 | exit(1); 132 | } 133 | # else 134 | DWORD thread_id; 135 | th[i] = CreateThread(NULL, 0, entry, 0, 0, &thread_id); 136 | if (th[i] == NULL) { 137 | fprintf(stderr, "Thread #%d creation failed, errcode= %d\n", 138 | th_nums[i], (int)GetLastError()); 139 | exit(1); 140 | } 141 | # endif 142 | } 143 | n = i; 144 | for (i = 0; i < n; ++i) { 145 | # ifdef GC_PTHREADS 146 | void *res; 147 | err = pthread_join(th[i], &res); 148 | if (err) { 149 | fprintf(stderr, "Thread #%d join failed: %s\n", 150 | th_nums[i], strerror(err)); 151 | # if defined(__HAIKU__) 152 | /* The error is just ignored (and the test is ended) to */ 153 | /* workaround some bug in Haiku pthread_join. */ 154 | /* TODO: The thread is not deleted from GC_threads. */ 155 | if (ESRCH == err) break; 156 | # endif 157 | exit(1); 158 | } 159 | # else 160 | if (WaitForSingleObject(th[i], INFINITE) != WAIT_OBJECT_0) { 161 | fprintf(stderr, "Thread #%d join failed, errcode= %d\n", 162 | th_nums[i], (int)GetLastError()); 163 | CloseHandle(th[i]); 164 | exit(1); 165 | } 166 | CloseHandle(th[i]); 167 | # endif 168 | } 169 | #else 170 | (void)entry(NULL); 171 | #endif 172 | printf("Created %d threads (%d ended)\n", 173 | (int)AO_load(&thread_created_cnt), (int)AO_load(&thread_ended_cnt)); 174 | return 0; 175 | } 176 | 177 | #else 178 | 179 | int main(void) 180 | { 181 | printf("test skipped\n"); 182 | return 0; 183 | } 184 | 185 | #endif /* !AO_HAVE_fetch_and_add1 */ 186 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/tests/threadkey.c: -------------------------------------------------------------------------------- 1 | 2 | #ifdef HAVE_CONFIG_H 3 | # include "config.h" 4 | #endif 5 | 6 | #ifndef GC_THREADS 7 | # define GC_THREADS 8 | #endif 9 | 10 | #define GC_NO_THREAD_REDIRECTS 1 11 | 12 | #include "gc.h" 13 | 14 | #include 15 | #include 16 | 17 | #if (!defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS) \ 18 | || defined(__native_client__)) && !defined(SKIP_THREADKEY_TEST) 19 | /* FIXME: Skip this test on Solaris for now. The test may fail on */ 20 | /* other targets as well. Currently, tested only on Linux, Cygwin */ 21 | /* and Darwin. */ 22 | # define SKIP_THREADKEY_TEST 23 | #endif 24 | 25 | #ifdef SKIP_THREADKEY_TEST 26 | 27 | int main(void) 28 | { 29 | printf("test skipped\n"); 30 | return 0; 31 | } 32 | 33 | #else 34 | 35 | #include /* for EAGAIN */ 36 | #include 37 | #include 38 | 39 | pthread_key_t key; 40 | 41 | #ifdef GC_SOLARIS_THREADS 42 | /* pthread_once_t key_once = { PTHREAD_ONCE_INIT }; */ 43 | #else 44 | pthread_once_t key_once = PTHREAD_ONCE_INIT; 45 | #endif 46 | 47 | static void * entry(void *arg) 48 | { 49 | pthread_setspecific(key, 50 | (void *)GC_HIDE_POINTER(GC_STRDUP("hello, world"))); 51 | return arg; 52 | } 53 | 54 | static void * GC_CALLBACK on_thread_exit_inner(struct GC_stack_base * sb, 55 | void * arg) 56 | { 57 | int res = GC_register_my_thread (sb); 58 | pthread_t t; 59 | int creation_res; /* Used to suppress a warning about */ 60 | /* unchecked pthread_create() result. */ 61 | pthread_attr_t attr; 62 | 63 | if (pthread_attr_init(&attr) != 0 64 | || pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0) { 65 | fprintf(stderr, "Thread attribute init or setdetachstate failed\n"); 66 | exit(2); 67 | } 68 | creation_res = GC_pthread_create(&t, &attr, entry, NULL); 69 | (void)pthread_attr_destroy(&attr); 70 | if (res == GC_SUCCESS) 71 | GC_unregister_my_thread (); 72 | 73 | return arg ? (void*)(GC_word)creation_res : 0; 74 | } 75 | 76 | static void on_thread_exit(void *v) 77 | { 78 | GC_call_with_stack_base (on_thread_exit_inner, v); 79 | } 80 | 81 | static void make_key(void) 82 | { 83 | pthread_key_create (&key, on_thread_exit); 84 | } 85 | 86 | #ifndef NTHREADS 87 | # define NTHREADS 5 88 | #endif 89 | 90 | #define NTHREADS_INNER (NTHREADS * 6) /* number of threads to create */ 91 | 92 | int main(void) 93 | { 94 | int i; 95 | 96 | GC_INIT(); 97 | if (GC_get_find_leak()) 98 | printf("This test program is not designed for leak detection mode\n"); 99 | # ifdef GC_SOLARIS_THREADS 100 | pthread_key_create (&key, on_thread_exit); 101 | # else 102 | pthread_once (&key_once, make_key); 103 | # endif 104 | for (i = 0; i < NTHREADS_INNER; i++) { 105 | pthread_t t; 106 | void *res; 107 | int code = GC_pthread_create(&t, NULL, entry, NULL); 108 | 109 | if (code != 0) { 110 | fprintf(stderr, "Thread #%d creation failed: %s\n", i, strerror(code)); 111 | if (i > 0 && EAGAIN == code) break; 112 | exit(2); 113 | } 114 | 115 | if ((i & 1) != 0) { 116 | code = GC_pthread_join(t, &res); 117 | if (code != 0) { 118 | fprintf(stderr, "Thread #%d join failed: %s\n", i, strerror(code)); 119 | exit(2); 120 | } 121 | } else { 122 | code = GC_pthread_detach(t); 123 | if (code != 0) { 124 | fprintf(stderr, "Thread #%d detach failed: %s\n", i, strerror(code)); 125 | exit(2); 126 | } 127 | } 128 | } 129 | printf("SUCCEEDED\n"); 130 | return 0; 131 | } 132 | 133 | #endif /* !SKIP_THREADKEY_TEST */ 134 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/tests/threadleak.c: -------------------------------------------------------------------------------- 1 | 2 | #ifdef HAVE_CONFIG_H 3 | # include "config.h" 4 | #endif 5 | 6 | #ifndef GC_THREADS 7 | # define GC_THREADS 8 | #endif 9 | 10 | #undef GC_NO_THREAD_REDIRECTS 11 | #include "gc/leak_detector.h" 12 | 13 | #ifdef GC_PTHREADS 14 | # include /* for EAGAIN */ 15 | # include 16 | # include 17 | #else 18 | # ifndef WIN32_LEAN_AND_MEAN 19 | # define WIN32_LEAN_AND_MEAN 1 20 | # endif 21 | # define NOSERVICE 22 | # include 23 | #endif /* !GC_PTHREADS */ 24 | 25 | #include 26 | 27 | #define N_TESTS 100 28 | 29 | #ifdef GC_PTHREADS 30 | static void * test(void * arg) 31 | #else 32 | static DWORD WINAPI test(LPVOID arg) 33 | #endif 34 | { 35 | int *p[N_TESTS]; 36 | int i; 37 | for (i = 0; i < N_TESTS; ++i) { 38 | p[i] = (int *)malloc(sizeof(int) + i); 39 | } 40 | CHECK_LEAKS(); 41 | for (i = 1; i < N_TESTS; ++i) { 42 | free(p[i]); 43 | } 44 | # ifdef GC_PTHREADS 45 | return arg; 46 | # else 47 | return (DWORD)(GC_word)arg; 48 | # endif 49 | } 50 | 51 | #ifndef NTHREADS 52 | # define NTHREADS 5 53 | #endif 54 | 55 | int main(void) { 56 | # if NTHREADS > 0 57 | int i, n; 58 | # ifdef GC_PTHREADS 59 | pthread_t t[NTHREADS]; 60 | # else 61 | HANDLE t[NTHREADS]; 62 | # endif 63 | # endif 64 | 65 | GC_set_find_leak(1); /* for new collect versions not compiled */ 66 | /* with -DFIND_LEAK. */ 67 | GC_INIT(); 68 | 69 | GC_allow_register_threads(); /* optional if pthread_create redirected */ 70 | 71 | # if NTHREADS > 0 72 | for (i = 0; i < NTHREADS; ++i) { 73 | # ifdef GC_PTHREADS 74 | int code = pthread_create(t + i, 0, test, 0); 75 | 76 | if (code != 0) { 77 | fprintf(stderr, "Thread #%d creation failed: %s\n", 78 | i, strerror(code)); 79 | if (i > 1 && EAGAIN == code) break; 80 | exit(2); 81 | } 82 | # else 83 | DWORD thread_id; 84 | 85 | t[i] = CreateThread(NULL, 0, test, 0, 0, &thread_id); 86 | if (NULL == t[i]) { 87 | fprintf(stderr, "Thread #%d creation failed, errcode= %d\n", 88 | i, (int)GetLastError()); 89 | exit(2); 90 | } 91 | # endif 92 | } 93 | n = i; 94 | for (i = 0; i < n; ++i) { 95 | int code; 96 | 97 | # ifdef GC_PTHREADS 98 | code = pthread_join(t[i], 0); 99 | # else 100 | code = WaitForSingleObject(t[i], INFINITE) == WAIT_OBJECT_0 ? 0 : 101 | (int)GetLastError(); 102 | # endif 103 | if (code != 0) { 104 | fprintf(stderr, "Thread #%d join failed, errcode= %d\n", 105 | i, code); 106 | exit(2); 107 | } 108 | } 109 | # else 110 | (void)test(NULL); 111 | # endif 112 | 113 | CHECK_LEAKS(); 114 | CHECK_LEAKS(); 115 | CHECK_LEAKS(); 116 | printf("SUCCEEDED\n"); 117 | return 0; 118 | } 119 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/tests/trace.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #ifndef GC_DEBUG 6 | # define GC_DEBUG 7 | #endif 8 | 9 | #include "gc.h" 10 | #include "gc/gc_backptr.h" 11 | 12 | struct treenode { 13 | struct treenode *x; 14 | struct treenode *y; 15 | } * root[10]; 16 | 17 | static struct treenode * mktree(int i) { 18 | struct treenode * r = GC_NEW(struct treenode); 19 | struct treenode *x, *y; 20 | if (0 == i) 21 | return 0; 22 | if (1 == i) 23 | r = (struct treenode *)GC_MALLOC_ATOMIC(sizeof(struct treenode)); 24 | if (r == NULL) { 25 | fprintf(stderr, "Out of memory\n"); 26 | exit(1); 27 | } 28 | x = mktree(i - 1); 29 | y = mktree(i - 1); 30 | r -> x = x; 31 | r -> y = y; 32 | if (i != 1) { 33 | GC_END_STUBBORN_CHANGE(r); 34 | GC_reachable_here(x); 35 | GC_reachable_here(y); 36 | } 37 | return r; 38 | } 39 | 40 | int main(void) 41 | { 42 | int i; 43 | 44 | GC_INIT(); 45 | if (GC_get_find_leak()) 46 | printf("This test program is not designed for leak detection mode\n"); 47 | for (i = 0; i < 10; ++i) { 48 | root[i] = mktree(12); 49 | } 50 | GC_generate_random_backtrace(); 51 | GC_generate_random_backtrace(); 52 | GC_generate_random_backtrace(); 53 | GC_generate_random_backtrace(); 54 | printf("SUCCEEDED\n"); 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/tools/callprocs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | GC_DEBUG=1 3 | export GC_DEBUG 4 | $* 2>&1 | awk '{print "0x3e=c\""$0"\""};/^\t##PC##=/ {if ($2 != 0) {print $2"?i"}}' | adb $1 | sed "s/^ >/>/" 5 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/tools/if_mach.c: -------------------------------------------------------------------------------- 1 | /* Conditionally execute a command based on machine and OS from gcconfig.h */ 2 | 3 | # include "private/gc_priv.h" 4 | # include 5 | # include 6 | # include 7 | 8 | #ifdef __cplusplus 9 | # define EXECV_ARGV_T char** 10 | #else 11 | /* The 2nd argument of execvp() prototype may be either char**, or */ 12 | /* char* const*, or const char* const*. */ 13 | # define EXECV_ARGV_T void* 14 | #endif 15 | 16 | int main(int argc, char **argv) 17 | { 18 | if (argc < 4) goto Usage; 19 | if (strcmp(MACH_TYPE, argv[1]) != 0) return 0; 20 | if (strlen(OS_TYPE) > 0 && strlen(argv[2]) > 0 21 | && strcmp(OS_TYPE, argv[2]) != 0) return 0; 22 | fprintf(stderr, "^^^^Starting command^^^^\n"); 23 | fflush(stdout); 24 | execvp(TRUSTED_STRING(argv[3]), (EXECV_ARGV_T)(argv + 3)); 25 | perror("Couldn't execute"); 26 | 27 | Usage: 28 | fprintf(stderr, "Usage: %s mach_type os_type command\n", argv[0]); 29 | fprintf(stderr, "Currently mach_type = %s, os_type = %s\n", 30 | MACH_TYPE, OS_TYPE); 31 | return 1; 32 | } 33 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/tools/if_not_there.c: -------------------------------------------------------------------------------- 1 | /* Conditionally execute the command argv[2] based if the file argv[1] */ 2 | /* does not exist. If the command is omitted (and the file does not */ 3 | /* exist) then just exit with a non-zero code. */ 4 | 5 | # include "private/gc_priv.h" 6 | # include 7 | # include 8 | # include 9 | #ifdef __DJGPP__ 10 | #include 11 | #endif /* __DJGPP__ */ 12 | 13 | #ifdef __cplusplus 14 | # define EXECV_ARGV_T char** 15 | #else 16 | # define EXECV_ARGV_T void* /* see the comment in if_mach.c */ 17 | #endif 18 | 19 | int main(int argc, char **argv) 20 | { 21 | FILE * f; 22 | #ifdef __DJGPP__ 23 | DIR * d; 24 | #endif /* __DJGPP__ */ 25 | char *fname; 26 | 27 | if (argc < 2 || argc > 3) 28 | goto Usage; 29 | 30 | fname = TRUSTED_STRING(argv[1]); 31 | f = fopen(fname, "rb"); 32 | if (f != NULL) { 33 | fclose(f); 34 | return 0; 35 | } 36 | f = fopen(fname, "r"); 37 | if (f != NULL) { 38 | fclose(f); 39 | return 0; 40 | } 41 | #ifdef __DJGPP__ 42 | if ((d = opendir(fname)) != 0) { 43 | closedir(d); 44 | return 0; 45 | } 46 | #endif 47 | printf("^^^^Starting command^^^^\n"); 48 | fflush(stdout); 49 | if (argc == 2) 50 | return 2; /* the file does not exist but no command is given */ 51 | 52 | execvp(TRUSTED_STRING(argv[2]), (EXECV_ARGV_T)(argv + 2)); 53 | exit(1); 54 | 55 | Usage: 56 | fprintf(stderr, "Usage: %s file_name [command]\n", argv[0]); 57 | return 1; 58 | } 59 | -------------------------------------------------------------------------------- /deps/github.com/ivmai/bdwgc/tools/threadlibs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | * Copyright (c) 1996 by Silicon Graphics. All rights reserved. 4 | * Copyright (c) 1998 by Fergus Henderson. All rights reserved. 5 | * Copyright (c) 2000-2010 by Hewlett-Packard Development Company. 6 | * All rights reserved. 7 | * 8 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 9 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 10 | * 11 | * Permission is hereby granted to use or copy this program 12 | * for any purpose, provided the above notices are retained on all copies. 13 | * Permission to modify the code and to distribute modified code is granted, 14 | * provided the above notices are retained, and a notice that the code was 15 | * modified is included with the above copyright notice. 16 | */ 17 | 18 | # include "private/gc_priv.h" 19 | 20 | # include 21 | 22 | int main(void) 23 | { 24 | # if defined(GC_USE_LD_WRAP) 25 | printf("-Wl,--wrap -Wl,dlopen " 26 | "-Wl,--wrap -Wl,pthread_create -Wl,--wrap -Wl,pthread_join " 27 | "-Wl,--wrap -Wl,pthread_detach -Wl,--wrap -Wl,pthread_sigmask " 28 | "-Wl,--wrap -Wl,pthread_exit -Wl,--wrap -Wl,pthread_cancel\n"); 29 | # endif 30 | # if (defined(GC_LINUX_THREADS) && !defined(HOST_ANDROID)) \ 31 | || defined(GC_IRIX_THREADS) || defined(GC_DARWIN_THREADS) \ 32 | || defined(GC_AIX_THREADS) || (defined(HURD) && defined(GC_THREADS)) 33 | # ifdef GC_USE_DLOPEN_WRAP 34 | printf("-ldl "); 35 | # endif 36 | printf("-lpthread\n"); 37 | # endif 38 | # if defined(GC_OPENBSD_THREADS) 39 | printf("-pthread\n"); 40 | # endif 41 | # if defined(GC_FREEBSD_THREADS) 42 | # ifdef GC_USE_DLOPEN_WRAP 43 | printf("-ldl "); 44 | # endif 45 | # if (__FREEBSD_version < 500000) 46 | printf("-pthread\n"); 47 | # else /* __FREEBSD__ || __DragonFly__ */ 48 | printf("-lpthread\n"); 49 | # endif 50 | # endif 51 | # if defined(GC_NETBSD_THREADS) 52 | printf("-lpthread -lrt\n"); 53 | # endif 54 | 55 | # if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) 56 | printf("-lpthread -lrt\n"); 57 | # endif 58 | # if defined(GC_SOLARIS_THREADS) 59 | printf("-lthread -lposix4\n"); 60 | /* Is this right for recent versions? */ 61 | # endif 62 | # if defined(GC_WIN32_THREADS) && defined(CYGWIN32) 63 | printf("-lpthread\n"); 64 | # endif 65 | # if defined(GC_WIN32_PTHREADS) 66 | # ifdef PTW32_STATIC_LIB 67 | /* assume suffix s for static version of the pthreads-win32 library */ 68 | printf("-lpthreadGC2s -lws2_32\n"); 69 | # else 70 | printf("-lpthreadGC2\n"); 71 | # endif 72 | # endif 73 | # if defined(GC_OSF1_THREADS) 74 | printf("-pthread -lrt\n"); /* DOB: must be -pthread, not -lpthread */ 75 | # endif 76 | /* You need GCC 3.0.3 to build this one! */ 77 | /* DG/UX native gcc doesn't know what "-pthread" is */ 78 | # if defined(GC_DGUX386_THREADS) 79 | printf("-ldl -pthread\n"); 80 | # endif 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /deps/linenoise.h: -------------------------------------------------------------------------------- 1 | /* linenoise.h -- VERSION 1.0 2 | * 3 | * Guerrilla line editing library against the idea that a line editing lib 4 | * needs to be 20,000 lines of C code. 5 | * 6 | * See linenoise.c for more information. 7 | * 8 | * ------------------------------------------------------------------------ 9 | * 10 | * Copyright (c) 2010-2014, Salvatore Sanfilippo 11 | * Copyright (c) 2010-2013, Pieter Noordhuis 12 | * 13 | * All rights reserved. 14 | * 15 | * Redistribution and use in source and binary forms, with or without 16 | * modification, are permitted provided that the following conditions are 17 | * met: 18 | * 19 | * * Redistributions of source code must retain the above copyright 20 | * notice, this list of conditions and the following disclaimer. 21 | * 22 | * * Redistributions in binary form must reproduce the above copyright 23 | * notice, this list of conditions and the following disclaimer in the 24 | * documentation and/or other materials provided with the distribution. 25 | * 26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | */ 38 | 39 | #ifndef __LINENOISE_H 40 | #define __LINENOISE_H 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | typedef struct linenoiseCompletions { 47 | size_t len; 48 | char **cvec; 49 | } linenoiseCompletions; 50 | 51 | typedef void(linenoiseCompletionCallback)(const char *, linenoiseCompletions *); 52 | typedef char*(linenoiseHintsCallback)(const char *, int *color, int *bold); 53 | typedef void(linenoiseFreeHintsCallback)(void *); 54 | void linenoiseSetCompletionCallback(linenoiseCompletionCallback *); 55 | void linenoiseSetHintsCallback(linenoiseHintsCallback *); 56 | void linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback *); 57 | void linenoiseAddCompletion(linenoiseCompletions *, const char *); 58 | 59 | char *linenoise(const char *prompt); 60 | void linenoiseFree(void *ptr); 61 | int linenoiseHistoryAdd(const char *line); 62 | int linenoiseHistorySetMaxLen(int len); 63 | int linenoiseHistorySave(const char *filename); 64 | int linenoiseHistoryLoad(const char *filename); 65 | void linenoiseClearScreen(void); 66 | void linenoiseSetMultiLine(int ml); 67 | void linenoisePrintKeyCodes(void); 68 | void linenoiseMaskModeEnable(void); 69 | void linenoiseMaskModeDisable(void); 70 | 71 | #ifdef __cplusplus 72 | } 73 | #endif 74 | 75 | #endif /* __LINENOISE_H */ -------------------------------------------------------------------------------- /examples/albums.lisp: -------------------------------------------------------------------------------- 1 | ; This example is a simple interactive persistent album database. The database is a 2 | ; list where each entry is a ("name" rating) pair. These are serialized to file as 3 | ; Bio expressions, and then replayed on startup. 4 | (var albums '()) 5 | 6 | (var print-menu (lambda () 7 | (print "1: Add 2: Find by name 3: List all 4: Exit\n") 8 | )) 9 | 10 | (var print-heading (lambda (heading) 11 | (print "\n------------------------------------\n") 12 | (print heading "\n") 13 | (print "------------------------------------\n") 14 | )) 15 | 16 | ; Add new album to database 17 | (var album.add (lambda () 18 | (print "\nName of album: ") 19 | (var album-name (io.read-line)) 20 | 21 | (print "Rating: ") 22 | (var rating (as number (io.read-line))) 23 | 24 | (set! albums (append albums (list (list album-name rating)))) 25 | (print "\nAlbum was added!\n") 26 | 27 | ; Append to album database file 28 | (var dat (io.open-file "albums.dat")) 29 | (io.write-line dat (string `(set! albums (append albums (list (list ,(double-quote album-name) ,rating)))))) 30 | (io.close-file dat) 31 | )) 32 | 33 | ; List all albums 34 | (var album.list (lambda () 35 | (if (> (len albums) 0) 36 | (begin 37 | (print-heading "All albums") 38 | (var sorted-album-list (quicksort albums (lambda (first second) 39 | ; Compare album names 40 | (< (car first) (car second)) 41 | ))) 42 | (each sorted-album-list (lambda (album) 43 | (album.print-entry album) 44 | )) 45 | ) 46 | (print "\nThere are no albums in the database\n") 47 | ) 48 | (print "\n") 49 | )) 50 | 51 | ; Find an album by name 52 | (var album.find (lambda () 53 | (print "Album name: ") 54 | (var to-find (io.read-line)) 55 | (each albums (lambda (album) 56 | (if (= to-find (car album)) 57 | (begin 58 | (print-heading "Found a matching album:") 59 | (album.print-entry album) 60 | ) 61 | ) 62 | )) 63 | (print "\n") 64 | )) 65 | 66 | (var album.print-entry (lambda (album) 67 | (print "Name : " (car album) "\n") 68 | (print "Rating : " (cadr album) "\n") 69 | (print "------------------------------------\n") 70 | )) 71 | 72 | (print "\nWelcome to the Bio Album Database\n \n") 73 | 74 | ; Read albums from the database file until EOF 75 | (var dat (io.open-file "albums.dat")) 76 | (var keep-reading #t) 77 | (while keep-reading 78 | (try (io.read-line dat) 79 | (eval-string #value) 80 | (set! keep-reading #f) 81 | ) 82 | ) 83 | (io.close-file dat) 84 | 85 | ; Menu loop 86 | (while #t 87 | (print-menu) 88 | (let ((action (io.read-number))) 89 | (if (= action 1) (album.add)) 90 | (if (= action 2) (album.find)) 91 | (if (= action 3) (album.list)) 92 | (if (= action 4) (exit 0)) 93 | ) 94 | ) 95 | -------------------------------------------------------------------------------- /examples/fizzbuzz-cond.lisp: -------------------------------------------------------------------------------- 1 | ; FizzBuzz using cond - see fizzbuzz-if.lisp for an improvement 2 | (var fizzbuzz (lambda (i n) 3 | (if (<= i n) 4 | (let ((x (math.mod i 3)) (y (math.mod i 5))) 5 | (cond 6 | ((and (= 0 x) (= 0 y)) (print "FizzBuzz" "\n")) 7 | ((= 0 x) (print "Fizz" "\n")) 8 | ((= 0 y) (print "Buzz" "\n")) 9 | ((print i "\n")) 10 | ) 11 | (fizzbuzz (+ i 1) n)) 12 | ) 13 | )) 14 | 15 | (fizzbuzz 1 20) 16 | -------------------------------------------------------------------------------- /examples/fizzbuzz-if.lisp: -------------------------------------------------------------------------------- 1 | (var fizzbuzz (lambda (i n) 2 | (if (<= i n) 3 | (let ((x (math.mod i 3)) (y (math.mod i 5))) 4 | (if (= 0 x) (print "Fizz")) 5 | (if (= 0 y) (print "Buzz")) 6 | (if (and (!= 0 x) (!= 0 y)) (print i)) 7 | (print "\n") 8 | (fizzbuzz (+ i 1) n) 9 | ) 10 | ) 11 | )) 12 | 13 | (fizzbuzz 1 20) 14 | -------------------------------------------------------------------------------- /examples/hello.lisp: -------------------------------------------------------------------------------- 1 | (print "How many times to print Hello?\n") 2 | 3 | ; Attempt to read a number from stdin. If io.read-number fails, the error messages 4 | ; is available in #!, which we print. 5 | (try (var count (io.read-number)) 6 | (n-times count 7 | (print "Hello\n") 8 | ) 9 | (print "Could not read number of times:" #! "\n") 10 | ) 11 | -------------------------------------------------------------------------------- /examples/mod-pos.lisp: -------------------------------------------------------------------------------- 1 | ; You can test this module from the REPL with: 2 | ; 3 | ; (var Point (import "examples/mod-pos.lisp")) 4 | ; 5 | ; and then calling the modules' test function: 6 | ; 7 | ; (Point (test)) 8 | ; 9 | ; which should print: 10 | ; 11 | ; New York : 40.7554351° N 73.9981619° W 12 | ; Bejing : 39.9390731° N 116.1172802° E 13 | ; Buenos Aires : 34.5777632° S 58.409201° W 14 | ; Sidney : 33.8568285° S 151.2130914° E 15 | ; Sidney zeroed: 0° N 0° E 16 | ; 17 | ; Making a new point can be done with: 18 | ; (var pt (Point (new-point 2 5.4))) 19 | ; 20 | ; To access a member: 21 | ; (pt y) 22 | ; 5.4 23 | ; 24 | ; Two ways to call member functions: 25 | ; ((pt as-string)) 26 | ; 2 5.4 27 | ; (pt (as-string)) 28 | ; 2 5.4 29 | 30 | ((lambda () 31 | 32 | ; Both point types adopt this as their "update" function, but each 33 | ; point type have their own implementation of the "as-string" function. 34 | ; This is a macro, so x and y is expected to be available in the callee environment. 35 | (var generic-update (macro (new-x new-y) 36 | (set! x new-x) 37 | (set! y new-y) 38 | nil 39 | )) 40 | 41 | ; A point datatype with regular formatting 42 | (var new-point (lambda (x y) 43 | (var update generic-update) 44 | (var as-string (lambda () 45 | (string x " " y) 46 | )) 47 | (self) 48 | )) 49 | 50 | ; A version with longitude and latitude formatting 51 | (var new-location (lambda (x y) 52 | (var update generic-update) 53 | (var as-string (lambda () 54 | (string 55 | (math.abs x) (if (< x 0) "° S" "° N") 56 | " " 57 | (math.abs y) (if (< y 0) "° W" "° E")) 58 | )) 59 | (self) 60 | )) 61 | 62 | (var test (lambda () 63 | (var new-york (new-location 40.7554351 -73.9981619)) 64 | (var bejing (new-location 39.9390731 116.1172802)) 65 | (var buenos-aires (new-location -34.5777632 -58.409201)) 66 | (var sidney (new-location -33.8568285 151.2130914)) 67 | 68 | (assert (= ((new-york as-string)) "40.7554351° N 73.9981619° W")) 69 | (assert (= ((bejing as-string)) "39.9390731° N 116.1172802° E")) 70 | (assert (= ((buenos-aires as-string)) "34.5777632° S 58.409201° W")) 71 | (assert (= ((sidney as-string)) "33.8568285° S 151.2130914° E")) 72 | 73 | (print "New York :" ((new-york as-string)) "\n") 74 | (print "Bejing :" ((bejing as-string)) "\n") 75 | (print "Buenos Aires :" ((buenos-aires as-string)) "\n") 76 | (print "Sidney :" ((sidney as-string)) "\n") 77 | 78 | (sidney (update 0 0)) 79 | (print "Sidney zeroed:" ((sidney as-string)) "\n") 80 | )) 81 | 82 | (var module-name "Position Module") 83 | (var module-version '(1 0 0)) 84 | (self) 85 | )) 86 | -------------------------------------------------------------------------------- /examples/quine.lisp: -------------------------------------------------------------------------------- 1 | ((lambda (q) (quasiquote ((unquote q) (quote (unquote q))))) (quote (lambda (q) (quasiquote ((unquote q) (quote (unquote q))))))) -------------------------------------------------------------------------------- /examples/random.lisp: -------------------------------------------------------------------------------- 1 | ; Prints a list of random numbers, using current epoch milliseconds as seed 2 | (var math (Math)) 3 | (var count 100) 4 | (print (math (random-list (math (make-random-generator (std-time-now))) count)) "\n") 5 | -------------------------------------------------------------------------------- /examples/triangles.lisp: -------------------------------------------------------------------------------- 1 | (var sierpinski (lambda (n) 2 | (var generator (lambda (acc spaces n) 3 | (if (= 0 n) 4 | acc 5 | (generator 6 | (append 7 | (map (lambda (x) (append spaces x spaces)) acc) 8 | (map (lambda (x) (append x (list " ") x)) acc)) 9 | (append spaces spaces) 10 | (- n 1) 11 | ) 12 | ) 13 | )) 14 | 15 | (map 16 | (lambda (x) (print (as symbol x) "\n")) 17 | (generator (list "^") (list " ") n) 18 | ) 19 | )) 20 | 21 | ; Prints a Sierpinksi Triangle of size 5; change size at your leisure 22 | (sierpinski 5) 23 | -------------------------------------------------------------------------------- /src/boehm.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const assert = std.debug.assert; 3 | const testing = std.testing; 4 | const mem = std.mem; 5 | const Allocator = std.mem.Allocator; 6 | 7 | const gc = @cImport({ 8 | @cInclude("gc.h"); 9 | }); 10 | 11 | /// Returns the Zig allocator interface to BoehmGC 12 | pub fn allocator() Allocator { 13 | if (gc.GC_is_init_called() == 0) { 14 | // Make sure interior pointers are handled. It's recommended to call this before GC_init. 15 | gc.GC_set_all_interior_pointers(1); 16 | gc.GC_init(); 17 | } 18 | 19 | return Allocator{ 20 | .ptr = undefined, 21 | .vtable = &gc_allocator_vtable, 22 | }; 23 | } 24 | 25 | /// Kind of garbage collection to run 26 | pub const GCKind = enum { 27 | nul, 28 | /// Short collection burst (typically a page worth of allocations) 29 | short, 30 | /// Regular collection 31 | normal, 32 | /// This is a full collection, only use when system is running low on memory 33 | aggressive, 34 | }; 35 | 36 | /// Run garbage collector where `kind` is the type of collection to run; normally you want .short or .normal. 37 | /// Returns true if collection is completed. It's possible to call this in a loop until it returns true (only useful for .short) 38 | pub fn collect(kind: GCKind) bool { 39 | switch (kind) { 40 | .short => { 41 | if (gc.GC_collect_a_little() != 0) return false; 42 | }, 43 | .normal => gc.GC_gcollect(), 44 | .aggressive => gc.GC_gcollect_and_unmap(), 45 | else => {}, 46 | } 47 | 48 | return true; 49 | } 50 | 51 | pub fn setMaxHeap(max_size: usize) void { 52 | gc.GC_set_max_heap_size(max_size); 53 | } 54 | 55 | pub fn memUsage() usize { 56 | return gc.GC_get_memory_use(); 57 | } 58 | 59 | pub fn heapSize() u64 { 60 | return gc.GC_get_heap_size(); 61 | } 62 | 63 | pub fn collectionCount() usize { 64 | return gc.GC_get_gc_no(); 65 | } 66 | 67 | pub fn enable() void { 68 | gc.GC_enable(); 69 | } 70 | 71 | pub fn disable() void { 72 | gc.GC_disable(); 73 | } 74 | 75 | pub fn setLeakDetection(enabled: bool) void { 76 | return gc.GC_set_find_leak(@intFromBool(enabled)); 77 | } 78 | 79 | /// Zig allocator using Boehm GC 80 | pub const BoehmGcAllocator = struct { 81 | fn alloc(_: *anyopaque, len: usize, log2_align: u8, return_address: usize) ?[*]u8 { 82 | _ = return_address; 83 | assert(len > 0); 84 | const alignment = @as(usize, 1) << @as(Allocator.Log2Align, @intCast(log2_align)); 85 | const raw = gc.GC_memalign(alignment, len); 86 | return @as([*]u8, @ptrCast(raw)); 87 | } 88 | 89 | fn resize(_: *anyopaque, buf: []u8, log2_buf_align: u8, new_len: usize, return_address: usize) bool { 90 | _ = .{ log2_buf_align, return_address, buf, new_len }; 91 | return false; 92 | } 93 | 94 | fn free(_: *anyopaque, buf: []u8, log2_buf_align: u8, return_address: usize) void { 95 | _ = .{ buf, log2_buf_align, return_address }; 96 | } 97 | }; 98 | 99 | const gc_allocator_vtable = Allocator.VTable{ 100 | .alloc = BoehmGcAllocator.alloc, 101 | .resize = BoehmGcAllocator.resize, 102 | .free = BoehmGcAllocator.free, 103 | }; 104 | -------------------------------------------------------------------------------- /src/linereader.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const builtin = @import("builtin"); 3 | const target = @import("builtin").target; 4 | const gc = @import("boehm.zig"); 5 | 6 | const is_windows = target.os.tag == .windows; 7 | const linenoise = @cImport({ 8 | if (!is_windows) { 9 | @cInclude("stddef.h"); 10 | @cInclude("linenoise.h"); 11 | } 12 | }); 13 | 14 | /// Linenoise wrapper with a Reader interface 15 | const Linenoise = struct { 16 | line: ?[:0]u8 = null, 17 | index: usize = 0, 18 | remaining: usize = 0, 19 | eof_next: bool = false, 20 | prompt: []const u8 = "", 21 | 22 | fn init() Linenoise { 23 | return .{}; 24 | } 25 | 26 | pub fn hidePrompt(self: *Linenoise) void { 27 | self.prompt = ""; 28 | } 29 | 30 | /// Prints the REPL prompt. On nix* systems this is done by linenoise in readFn. 31 | pub fn printPrompt(self: *Linenoise, prompt: []const u8) !void { 32 | self.prompt = prompt; 33 | if (is_windows and self.prompt.len > 0) { 34 | try std.io.getStdOut().writer().print("{s}", .{self.prompt}); 35 | } 36 | } 37 | 38 | /// Add the given entry to the REPL history 39 | pub fn addToHistory(_: *Linenoise, entry: []const u8) !void { 40 | if (!is_windows and entry.len > 0) { 41 | const duped = try gc.allocator().dupeZ(u8, entry); 42 | // Linenoise takes a copy 43 | _ = linenoise.linenoiseHistoryAdd(duped.ptr); 44 | } 45 | } 46 | 47 | /// This satisfies the Reader interface. The first call will cause 48 | /// linenoise to be invoked with an optional prompt. The returned line 49 | /// is then consumed, after which EndOfStream is returned. Rinse and 50 | /// repeat. For Windows, we simply delegate to stdin. 51 | fn readFn(self: *@This(), dest: []u8) anyerror!usize { 52 | var copy_count: usize = 0; 53 | if (!is_windows) { 54 | if (self.eof_next) { 55 | self.eof_next = false; 56 | return error.EndOfStream; 57 | } 58 | 59 | if (self.remaining == 0) { 60 | // This gives us a [*c]u8... 61 | const c_line = linenoise.linenoise(self.prompt.ptr); 62 | if (c_line == null) { 63 | return error.EndOfStream; 64 | } 65 | 66 | // ...which we convert to a [:0]u8 67 | self.line = std.mem.span(c_line); 68 | self.remaining = self.line.?.len; 69 | self.index = 0; 70 | } 71 | 72 | copy_count = @min(self.remaining, dest.len); 73 | if (copy_count > 0) @memcpy(dest, self.line.?[self.index .. self.index + copy_count]); 74 | self.remaining -= copy_count; 75 | self.index += copy_count; 76 | 77 | if (self.remaining == 0) { 78 | self.eof_next = true; 79 | //std.heap.c_allocator.free(self.line.?); 80 | } 81 | return copy_count; 82 | } else { 83 | return std.io.getStdIn().reader().read(dest); 84 | } 85 | } 86 | 87 | pub const Reader = std.io.Reader(*@This(), anyerror, readFn); 88 | pub fn reader(self: *@This()) Reader { 89 | return .{ .context = self }; 90 | } 91 | }; 92 | 93 | pub var linenoise_wrapper = Linenoise.init(); 94 | pub var linenoise_reader = linenoise_wrapper.reader(); 95 | -------------------------------------------------------------------------------- /src/main.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const ast = @import("ast.zig"); 3 | const gc = @import("boehm.zig"); 4 | const Interpreter = @import("interpreter.zig").Interpreter; 5 | const intrinsics = @import("intrinsics.zig"); 6 | 7 | /// Interpreter driver program 8 | pub fn main() !void { 9 | var interpreter = try Interpreter.init(); 10 | defer interpreter.deinit(); 11 | 12 | const allocator = gc.allocator(); 13 | 14 | // Load the standard library 15 | { 16 | var args = std.ArrayList(*ast.Expr).init(allocator); 17 | defer args.deinit(); 18 | 19 | // Use current directory for standard library path 20 | const cwd_absolute = try std.fs.cwd().realpathAlloc(allocator, "."); 21 | const stdpath = try std.fs.path.join(allocator, &[_][]const u8{ cwd_absolute, "std.lisp" }); 22 | 23 | const stdlib = try ast.makeListExpr(&.{ ast.getIntrinsic(.quote), try ast.makeAtomByDuplicating(stdpath) }); 24 | try args.append(stdlib); 25 | _ = try intrinsics.import(interpreter, interpreter.env, args.items); 26 | } 27 | 28 | // Check if "run " was passed 29 | { 30 | const process_args = try std.process.argsAlloc(allocator); 31 | if (process_args.len > 1) { 32 | if (std.mem.eql(u8, process_args[1], "run") and process_args.len > 2) { 33 | const load_expr = try std.fmt.allocPrint(allocator, "(import \"{s}\")", .{process_args[2]}); 34 | 35 | _ = try interpreter.eval(interpreter.env, try ast.Parser.parseSingleExpression(load_expr)); 36 | return; 37 | } 38 | } 39 | } 40 | 41 | // Start REPL 42 | interpreter.readEvalPrint() catch |err| { 43 | try interpreter.printError(err); 44 | }; 45 | } 46 | 47 | // This invokes a test suite written in Bio. The tests will assert on error, which is why we check the exit code. 48 | test "Evaluate standard library and test.lisp" { 49 | var interpreter = try Interpreter.init(); 50 | defer interpreter.deinit(); 51 | _ = try interpreter.eval(interpreter.env, try interpreter.parse("(begin (import \"std.lisp\") (import \"test.lisp\"))")); 52 | try std.testing.expectEqual(interpreter.exit_code, null); 53 | } 54 | -------------------------------------------------------------------------------- /src/tests.zig: -------------------------------------------------------------------------------- 1 | test "ast" { 2 | _ = @import("ast.zig"); 3 | } 4 | -------------------------------------------------------------------------------- /src/util.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const ast = @import("ast.zig"); 3 | const interpreter = @import("interpreter.zig"); 4 | 5 | const Expr = ast.Expr; 6 | const ExprType = ast.ExprType; 7 | const ExprErrors = ast.ExprErrors; 8 | 9 | pub fn isEmptyList(expr: *Expr) bool { 10 | return (expr.val == ExprType.lst and expr.val.lst.items.len == 0); 11 | } 12 | 13 | pub fn isError(expr: *Expr) bool { 14 | return expr.val == ExprType.err; 15 | } 16 | 17 | pub fn isFalsy(expr: *Expr) bool { 18 | return expr.isIntrinsic(.@"#f") or expr.isIntrinsic(.nil) or isEmptyList(expr) or isError(expr); 19 | } 20 | 21 | pub fn isNil(expr: *Expr) bool { 22 | return expr.isIntrinsic(.nil); 23 | } 24 | 25 | pub fn isNotNil(expr: *Expr) bool { 26 | return !expr.isIntrinsic(.nil); 27 | } 28 | 29 | pub fn requireExactArgCount(args_required: usize, args: []const *Expr) !void { 30 | if (args.len != args_required) { 31 | return ExprErrors.InvalidArgumentCount; 32 | } 33 | } 34 | 35 | pub fn requireMinimumArgCount(args_required: usize, args: []const *Expr) !void { 36 | if (args.len < args_required) { 37 | return ExprErrors.InvalidArgumentCount; 38 | } 39 | } 40 | 41 | pub fn requireMaximumArgCount(max_arg_count: usize, args: []const *Expr) !void { 42 | if (args.len > max_arg_count) { 43 | return ExprErrors.InvalidArgumentCount; 44 | } 45 | } 46 | 47 | pub fn requireType(ev: *interpreter.Interpreter, expr: *Expr, etype: ExprType) !void { 48 | if (expr.val != etype) { 49 | const str = try expr.toStringAlloc(); 50 | try ev.printErrorFmt(expr, "Expected {s}, got {s} with value: {s}", .{ ast.typeString(etype), ast.typeString(std.meta.activeTag(expr.val)), str }); 51 | return ExprErrors.AlreadyReported; 52 | } 53 | } 54 | 55 | // Copy bytes from a reader to a writer, until EOF 56 | pub fn copyBytes(reader: anytype, writer: anytype) !void { 57 | var buffered_reader = std.io.bufferedReader(reader); 58 | var instream = buffered_reader.reader(); 59 | read_loop: while (true) { 60 | const byte = instream.readByte() catch |err| switch (err) { 61 | error.EndOfStream => break :read_loop, 62 | else => return err, 63 | }; 64 | try writer.writeByte(byte); 65 | } 66 | } 67 | --------------------------------------------------------------------------------