├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── bin ├── mpisgcc ├── ops.hpp └── sgcc ├── build.sh ├── build_gc.sh ├── clean_all.sh ├── cstdlib ├── makefile ├── stdlib_macros.c └── time_macros.c ├── docs ├── all.md ├── booleans.md ├── c_standard_library.md ├── cuda_style_kernels.md ├── function_overloading.md ├── generics.md ├── iterators.md ├── modules.md ├── operator_overloading.md ├── sugaryc_standard_library.md ├── type_inference.md └── uniform_function_call_syntax.md ├── examples ├── customtype.sgc ├── helloworld.sgc ├── iterators.sgc ├── makefile ├── memory_safety.sgc ├── optionals.sgc ├── performance_index.sgc ├── performance_vector_list.sgc ├── reduce.sgc ├── strings.sgc ├── strong_typing.sgc └── template_abuse.sgc ├── ext ├── .DS_Store └── bdwgc │ ├── .appveyor.yml │ ├── .gitattributes │ ├── .github │ └── workflows │ │ ├── CodeQL.yml │ │ ├── cmake-build.yml │ │ ├── zig-build.yml │ │ └── zig-cross-compile.yml │ ├── .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 │ ├── build.zig │ ├── 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 ├── include ├── assert.sgh ├── filter_map_reduce.sgh ├── lists.sgh ├── logging.sgh ├── math.sgh ├── mpi.sgh ├── mpi │ ├── openmpi_config.sgh │ └── sgccmpi.sgh ├── np │ └── array.sgh ├── optional.sgh ├── print.sgh ├── range.sgh ├── safe_ptr.sgh ├── stdlib.sgh ├── string.sgh ├── strong_types.sgh ├── time.sgh ├── vector.sgh ├── vector_definition.sgh └── vector_types.sgh ├── libmpisgc ├── makefile └── sources │ ├── comms.sgc │ ├── init.sgc │ └── send_recv.sgc ├── pycparser ├── __init__.py ├── _ast_gen.py ├── _build_tables.py ├── _c_ast.cfg ├── ast_transforms.py ├── c_ast.py ├── c_generator.py ├── c_lexer.py ├── c_parser.py ├── ply │ ├── LICENSE │ ├── __init__.py │ ├── cpp.py │ ├── ctokens.py │ ├── lex.py │ ├── yacc.py │ └── ygen.py └── plyparser.py ├── pysgcc ├── __init__.py ├── find_cxx.py ├── kernel_fixer.py └── preprocessor.py └── stdlib ├── makefile └── sources ├── math.sgc ├── np ├── array.sgc ├── broadcasting.sgc └── math.sgc ├── print.sgc └── string.sgc /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 105 | __pypackages__/ 106 | 107 | # Celery stuff 108 | celerybeat-schedule 109 | celerybeat.pid 110 | 111 | # SageMath parsed files 112 | *.sage.py 113 | 114 | # Environments 115 | .env 116 | .venv 117 | env/ 118 | venv/ 119 | ENV/ 120 | env.bak/ 121 | venv.bak/ 122 | 123 | # Spyder project settings 124 | .spyderproject 125 | .spyproject 126 | 127 | # Rope project settings 128 | .ropeproject 129 | 130 | # mkdocs documentation 131 | /site 132 | 133 | # mypy 134 | .mypy_cache/ 135 | .dmypy.json 136 | dmypy.json 137 | 138 | # Pyre type checker 139 | .pyre/ 140 | 141 | # pytype static type analyzer 142 | .pytype/ 143 | 144 | # Cython debug symbols 145 | cython_debug/ 146 | 147 | # PyCharm 148 | # JetBrains specific template is maintainted in a separate JetBrains.gitignore that can 149 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 150 | # and can be added to the global gitignore or merged into this file. For a more nuclear 151 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 152 | #.idea/ 153 | 154 | **.o 155 | 156 | **.a 157 | 158 | .vscode 159 | 160 | old 161 | 162 | test.c 163 | test.sgc 164 | bin/ref_counter.cpp 165 | cstdlib/*.h 166 | 167 | .DS_Store 168 | 169 | pycparser/lextab.py 170 | pycparser/yacctab.py 171 | reference_counter/ref_counter.cpp 172 | reference_counter/ref_counter.hpp 173 | 174 | a.out -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Humza Qureshi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /bin/mpisgcc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import sys 4 | import os 5 | 6 | if __name__ == "__main__": 7 | mpilib = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..','libmpisgc','libmpisgc.a')) 8 | if ("-c" in " ".join(sys.argv[1:])): 9 | os.system("sgcc -cxx mpicxx -Wno-macro-redefined -Wno-duplicate-decl-specifier " + " ".join(sys.argv[1:])) 10 | else: 11 | os.system("sgcc -cxx mpicxx -Wno-macro-redefined -Wno-duplicate-decl-specifier " + mpilib + " " + " ".join(sys.argv[1:])) -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cd cstdlib 4 | make clean 5 | make all 6 | cd .. 7 | 8 | cd pycparser 9 | rm -rf lextab.py 10 | rm -rf yacctab.py 11 | python3 _build_tables.py 12 | cd .. 13 | 14 | cd stdlib 15 | make clean 16 | make libsgc.a 17 | cd .. 18 | 19 | cd examples 20 | make clean 21 | make 22 | cd .. 23 | -------------------------------------------------------------------------------- /build_gc.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cd ext/bdwgc 4 | make -f makefile.direct clean 5 | make -f makefile.direct 6 | cd .. -------------------------------------------------------------------------------- /clean_all.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cd cstdlib 4 | make clean 5 | cd .. 6 | 7 | cd pycparser 8 | rm -rf lextab.py 9 | rm -rf yacctab.py 10 | cd .. 11 | 12 | cd stdlib 13 | make clean 14 | cd .. 15 | 16 | cd examples 17 | make clean 18 | cd .. 19 | 20 | cd ext/bdwgc 21 | make -f makefile.direct clean 22 | cd .. -------------------------------------------------------------------------------- /cstdlib/makefile: -------------------------------------------------------------------------------- 1 | SOURCES := $(shell find . -name '*.c') 2 | OBJECTS := $(SOURCES:%.c=%.h) 3 | 4 | .PHONY: all 5 | all: $(OBJECTS) 6 | 7 | %.h: %.o 8 | ./$< > $@ 9 | 10 | %.o: %.c 11 | $(CC) $< -o $@ 12 | 13 | clean: 14 | rm -rf *.h 15 | rm -rf *.o -------------------------------------------------------------------------------- /cstdlib/stdlib_macros.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define STRINGIFY(x) #x 5 | #define TOSTRING(x) STRINGIFY(x) 6 | #define GET(x) x 7 | 8 | #define OUTPUT_MACRO_VALUE(name,MACRO_NAME) printf("#define %s %d\n",name,(int)GET(MACRO_NAME)) 9 | 10 | #define OUTPUT_TYPEDEF(t1,t2) printf("typedef %s %s;\n",TOSTRING(t1),TOSTRING(t2)) 11 | 12 | #define error_out(str) printf("%s\n",str);exit(1) 13 | 14 | #define __restrict restrict 15 | 16 | int main(){ 17 | 18 | printf("#ifndef _STDLIB_MACROS_H_\n#define _STDLIB_MACROS_H_\n"); 19 | 20 | switch (sizeof(size_t)){ 21 | case sizeof(unsigned long): 22 | OUTPUT_TYPEDEF(unsigned long,size_t); 23 | break; 24 | case sizeof(unsigned int): 25 | OUTPUT_TYPEDEF(unsigned int,size_t); 26 | break; 27 | default: 28 | error_out("couldn't determine sizeof(size_t)"); 29 | } 30 | printf("#endif\n"); 31 | return 0; 32 | } -------------------------------------------------------------------------------- /cstdlib/time_macros.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define STRINGIFY(x) #x 6 | #define TOSTRING(x) STRINGIFY(x) 7 | #define GET(x) x 8 | 9 | #define OUTPUT_MACRO_VALUE(name,MACRO_NAME) printf("#define %s %d\n",name,(int)GET(MACRO_NAME)) 10 | 11 | #define OUTPUT_TYPEDEF(t1,t2) printf("typedef %s %s;\n",TOSTRING(t1),TOSTRING(t2)) 12 | 13 | #define error_out(str) printf("%s\n",str);exit(1) 14 | 15 | int main(){ 16 | 17 | printf("#ifndef _TIME_MACROS_H_\n#define _TIME_MACROS_H_\n"); 18 | 19 | switch (sizeof(clock_t)){ 20 | case sizeof(unsigned long): 21 | OUTPUT_TYPEDEF(unsigned long,clock_t); 22 | break; 23 | case sizeof(unsigned int): 24 | OUTPUT_TYPEDEF(unsigned int,clock_t); 25 | break; 26 | default: 27 | error_out("couldn't determine sizeof(clock_t)"); 28 | } 29 | 30 | switch (sizeof(time_t)){ 31 | case sizeof(long): 32 | OUTPUT_TYPEDEF(long,time_t); 33 | break; 34 | case sizeof(int): 35 | OUTPUT_TYPEDEF(int,time_t); 36 | break; 37 | default: 38 | error_out("couldn't determine sizeof(time_t)"); 39 | } 40 | 41 | OUTPUT_MACRO_VALUE("CLOCKS_PER_SEC",CLOCKS_PER_SEC); 42 | 43 | printf("#endif\n"); 44 | return 0; 45 | } -------------------------------------------------------------------------------- /docs/booleans.md: -------------------------------------------------------------------------------- 1 | # Booleans 2 | 3 | Use builtin type `bool` and `true/false`. `println` and `print` will format `bool`s correctly. -------------------------------------------------------------------------------- /docs/c_standard_library.md: -------------------------------------------------------------------------------- 1 | # C Standard Library 2 | 3 | WIP. Eventually, all C standard library functions/headers will have corresponding `sgh` equivalents. If something is missing, see `math.sgh` for examples on how to write your own wrappers. For any architecture dependent things, see `stdlib_macros.c` and `time_macros.c` in `cstdlib` for examples on how to deal with that. PRs welcome and would be appreciated! -------------------------------------------------------------------------------- /docs/cuda_style_kernels.md: -------------------------------------------------------------------------------- 1 | # Cuda Style Kernels 2 | 3 | There is some experimental support for cuda style kernels. For example: 4 | ``` 5 | #include 6 | 7 | __global__ void test(int* in, int* out){ 8 | int idx = blockDim.x * blockIdx.x + threadIdx.x; 9 | out[idx] = in[idx]; 10 | } 11 | 12 | int main(){ 13 | return 0; 14 | } 15 | ``` 16 | Currently, these are basically `openmp` `parallel for` constructs, but the goal is to eventually have native GPU support. If you want something a little better, see https://github.com/humz2k/FPC. -------------------------------------------------------------------------------- /docs/function_overloading.md: -------------------------------------------------------------------------------- 1 | # Function Overloading 2 | 3 | This works the same as in C++. Actually, the compiler currently literally generates C++, so the name mangling is identical to C++. This will probably change, so don't count on that being the case. 4 | 5 | Use the `extern` keyword to stop name mangling. For example, the header for `free` in `stdlib.sgh` is 6 | ``` 7 | extern void free(void*); 8 | ``` -------------------------------------------------------------------------------- /docs/generics.md: -------------------------------------------------------------------------------- 1 | # Generics 2 | 3 | I like C++ templates, but they can get kind of confusing and a little too complicated. I also like the simplicity of the C preprocessor (simplicity in terms of understanding what it is doing under the hood). 4 | 5 | Sugaryc implements generics as a souped up preprocessor. Everything is still dumb text substitution, but the new constructs make it (fairly) easy to write generic, reusable code. 6 | 7 | There are two types of generics, `template`s and `generated`s. 8 | 9 | ## Templates 10 | 11 | These are very simple. They let you wrap an area of code, and then will substitute some string with values you provide. For example: 12 | 13 | ``` 14 | template{ 15 | T add2(T a, T b){ 16 | return a + b; 17 | } 18 | } 19 | ``` 20 | 21 | will (literally) be expanded to: 22 | ``` 23 | int add2(int a, int b){ 24 | return a + b; 25 | } 26 | float add2(float a, float b){ 27 | return a + b; 28 | } 29 | ``` 30 | 31 | Note that each template can only take one parameter as input (although this may change). 32 | 33 | Inputs to templates don't need to be types. Its just text substitution, so you can do all kinds of terrible things. You can also multiple things inside one template block. For example: 34 | ``` 35 | template{ 36 | T add2(T a, T b){ 37 | return a + b; 38 | } 39 | 40 | T sub2(T a, T b){ 41 | return a - b; 42 | } 43 | } 44 | ``` 45 | is perfectly valid. You should in theory be able to nest templates, but this can get weird. See `stdlib/np/array.sgc` for an example. 46 | 47 | ## Generateds 48 | 49 | These are a little more complicated, and a little annoying for a few reasons. Essentially, a `generated` will generate some code if the compiler finds some string that we specify. For example: 50 | ``` 51 | generated my_type{ 52 | typedef struct{ 53 | T a; 54 | } my_type; 55 | } 56 | ``` 57 | will generate a `my_type` only if it sees the string `my_type`. You can specify multiple strings to match against. For example: 58 | ``` 59 | generated keyword1,keyword2,keyword3{ 60 | typedef struct{ 61 | T a; 62 | } my_generated_type; 63 | } 64 | ``` 65 | will generate a `my_generated_type` if any of `keyword1`, `keyword2` or `keyword3` show up. Unlike `template`s, `generated`s can take multiple inputs. 66 | 67 | ### Don't nest generated types. It might work, but it depends on the ordering of when things are expanded, and I'll likely change this in the future. Also, don't have a `generated` inside a `template`. Again, it may work, but things get weird. 68 | 69 | One thing to note is that the generated code is placed in the same location as the original code. This is important. For example: 70 | 71 | ``` 72 | generated my_type{ 73 | typedef struct{ 74 | T a; 75 | } my_type; 76 | } 77 | 78 | struct my_struct{ 79 | int a; 80 | }; 81 | 82 | my_type; 83 | ``` 84 | 85 | will be expanded to: 86 | ``` 87 | typedef struct{ 88 | struct my_struct a; 89 | } my_type; 90 | 91 | struct my_struct{ 92 | int a; 93 | }; 94 | 95 | my_type; 96 | ``` 97 | 98 | Because `struct my_struct` is not declared before `my_type`, the compiler will freak out. So for situations where you are including a `generated` (for example from the standard library), note that they need to be included AFTER any relevant declarations. 99 | 100 | I know, this is annoying. But it makes it simple to implement, and also to reason about. 101 | 102 | ## What `thing` actually does 103 | 104 | Like everything else, `thing` just substitutes this with text. So you can really have that anywhere, as another way to mangle names. You can also nest them. 105 | 106 | ## Abuse 107 | 108 | If you want some examples on how to abuse generics, see `filter_map_reduce.sgh` and `strong_types.sgh` in `include`. -------------------------------------------------------------------------------- /docs/iterators.md: -------------------------------------------------------------------------------- 1 | # Iterator 2 | 3 | Sugaryc has the syntax extension: 4 | ``` 5 | foreach(T item in my_iterator){ 6 | do_something_with(item); 7 | } 8 | ``` 9 | 10 | An iterator needs to have some overloaded functions. Imagine I'm implementing a wrapper on an `int*`: 11 | ``` 12 | struct int_ptr_wrapper{ 13 | int* raw; 14 | int len; 15 | }; 16 | ``` 17 | and I want to be able to iterate though the elements with `foreach`. 18 | 19 | I first need to define an `iterator` type: 20 | ``` 21 | struct int_ptr_iter_struct{ 22 | int* raw; 23 | int cur; 24 | int length; 25 | }; 26 | 27 | typedef struct int_ptr_iter_struct* int_ptr_iter; 28 | ``` 29 | 30 | Then I need to overload `__iter__` to take in a `struct int_ptr_wrapper` and return a `int_ptr_iter` (note that the returned iterator needs to be a pointer): 31 | 32 | ``` 33 | int_ptr_iter __iter__(struct int_ptr_wrapper ptr){ 34 | int_ptr_iter out = (int_ptr_iter)GC_malloc(sizeof(struct int_ptr_iter_struct)); 35 | out->raw = ptr.raw; 36 | out->length = ptr.length; 37 | } 38 | ``` 39 | 40 | Then I need to overload some functions on `int_ptr_iter`. Firstly, I need to overload the `__start__` function, which should initialize my iterator, and return the first element. 41 | ``` 42 | int __start__(int_ptr_iter iter){ 43 | iter->cur = 0; 44 | return iter->raw[iter->cur]; 45 | } 46 | ``` 47 | Then I need to overload `__done__`, which should return a bool if we are done iterating: 48 | ``` 49 | bool __done__(int_ptr_iter iter){ 50 | return iter->cur >= iter->length; 51 | } 52 | ``` 53 | And finally, I need to overload `__next__`, which gets the next element: 54 | ``` 55 | int __next__(int_ptr_iter iter){ 56 | iter->cur++; 57 | return iter->raw[iter->cur]; 58 | } 59 | ``` 60 | 61 | Then, I can iterate through my `struct int_ptr_wrapper ptr` using a `foreach` loop: 62 | ``` 63 | struct int_ptr_warpper ptr = ...initialization_stuff...; 64 | foreach(auto i in ptr){ 65 | print(i); 66 | } 67 | ``` 68 | 69 | See `range.sgh` and `lists.sgh` in `include` for examples. -------------------------------------------------------------------------------- /docs/modules.md: -------------------------------------------------------------------------------- 1 | # Modules 2 | 3 | These aren't really modules, just more name mangling. You declare a module with `module module_name;`. Then, anywhere with `module_name.something` will be replaced with something like `module_name__something`. Nothing smarter than that. -------------------------------------------------------------------------------- /docs/operator_overloading.md: -------------------------------------------------------------------------------- 1 | # Operator Overloading 2 | 3 | This works similar to in python. You overload a built in method for specific types. The method names and corresponding operators are: 4 | 5 | ``` 6 | + -> __add__ 7 | - -> __sub__ 8 | * -> __mul__ 9 | / -> __div__ 10 | << -> __shl__ 11 | >> -> __shr__ 12 | % -> __mod__ 13 | | -> __or__ 14 | & -> __and__ 15 | || -> __lor__ 16 | && -> __land__ 17 | ^ -> __xor__ 18 | < -> __lt__ 19 | > -> __gt__ 20 | <= -> __le__ 21 | >= -> __ge__ 22 | == -> __eq__ 23 | != -> __neq__ 24 | ``` 25 | 26 | There is no awfulness like overloading `*` or `&` for pointers. Any memory allocated in an operator should be allocated using `GC_malloc`, rather than `malloc` (you really just shouldn't use `malloc` at all, if you want to free memory use `GC_free`). 27 | 28 | For overloading the index operator, using `__index__`. `__index__` needs to return a pointer to the type that is getting returned (if it needs to be constant, return a `const` pointer). For example, if I am writing an `int` array struct, 29 | ``` 30 | struct int_array{ 31 | int* array; 32 | }; 33 | 34 | int* __index__(struct int_array arr, int idx){ 35 | return arr.array + idx; 36 | } 37 | ``` 38 | For up to `4` dimensions, I can overload: 39 | ``` 40 | T* __index__(my_type,int idx1); 41 | T* __index__(my_type,int idx1, int idx2); 42 | T* __index__(my_type,int idx1, int idx2, int idx3); 43 | T* __index__(my_type,int idx1, int idx2, int idx3, int idx4); 44 | ``` 45 | For `n > 4` dimensions, I can overload: 46 | ``` 47 | T* __index__(my_type, int* idxs, int nidxs); 48 | ``` 49 | BUT, this will allocate `idxs` on the heap, so is probably a bad idea for performance. 50 | 51 | There is no restriction on types used as indexes. If I had a `dictionary` object, it would be valid to have something like: 52 | ``` 53 | T* __index__(dictionary dict, string str); 54 | ``` -------------------------------------------------------------------------------- /docs/sugaryc_standard_library.md: -------------------------------------------------------------------------------- 1 | # Sugaryc Standard Library 2 | 3 | There are some sugaryc-style data structures/algorithms that you can include. 4 | 5 | ## `lists.sgh` 6 | 7 | `std.list` is a 1D dynamic list. It allocates `10` items at a time, and does bounds checking so is slow. `print` and `println` will be correctly formatted. 8 | 9 | ### Initialization 10 | ``` 11 | std.list my_list = std.make_list(); 12 | ``` 13 | ### API 14 | ``` 15 | my_list.append(item) //appends item to the list 16 | my_list.pop() //pops the last item 17 | my_list.pop(idx) //pops the item at index idx 18 | my_list.insert(idx,item) //inserts item at index idx 19 | my_list[idx] //returns item at index idx 20 | len(my_list) //returns the length of the list 21 | my_list.destroy() //optionally manually delete the list 22 | ``` 23 | 24 | You can also iterate through a list with `foreach`: 25 | ``` 26 | foreach(auto i in my_list){ 27 | do_something_with(i); 28 | } 29 | ``` 30 | 31 | `print` and `println` will be correctly formatted. 32 | 33 | ## `vector.sgh` 34 | 35 | `std.vector` is a 1D dynamic array. It is more performant than a `std.list`, but doesn't do bounds checking. It doubles in size on reallocation. `print` and `println` will be correctly formatted. 36 | 37 | ### Initialization 38 | ``` 39 | std.vector my_vec = std.make_vector(); 40 | ``` 41 | 42 | ### API 43 | ``` 44 | my_vec.push_back(item) //appends item to end of vector 45 | my_vec.emplace_back(item) //removes last item 46 | my_vec.pop_back(item) //pops last item 47 | my_vec.reserve(n) //reserves n elements 48 | my_vec.shrink_to_fit() //shrinks size to fit 49 | my_vec.resize(n) //resizes vector to n elements 50 | len(my_vec) //returns the length of the vector 51 | my_vec.destroy() //optionally manually delete the vector 52 | ``` 53 | 54 | ## `optional.sgh` 55 | 56 | `std.optional` is a container for optional values of the type `T`. 57 | 58 | ### Initialization 59 | ``` 60 | std.optional my_opt = std.make_optional(value); 61 | std.optional my_null_opt = std.nullopt(); 62 | ``` 63 | 64 | ### API 65 | ``` 66 | my_opt.value_or(val) //returns value of my_opt if it exists, or val 67 | my_opt.value(val) //returns value of my_opt if it exists, or errors out 68 | my_opt.has_value() //returns true if my_opt has a value, or false if it doesn't 69 | ``` 70 | 71 | ## `np/array.sgh` 72 | 73 | Numpy style ndarrays. Fast rather than safe. Valid types `T` are: `T=float, double, short, int, long, long long, unsigned short, unsigned int, unsigned long, unsigned long long`. `print` and `println` will be correctly formatted. 74 | 75 | 76 | ### Initialization 77 | ``` 78 | np.ndarray arr = np.array(Shape(...)); 79 | np.ndarray arr = np.array(Shape(...)); 80 | ``` 81 | where `Shape(...)` is a list of dimensions, for example `Shape(10)`, `Shape(2,3)`. 82 | 83 | #### Other initializers 84 | ``` 85 | np.ndarray arr0 = np.ones(Shape(...)); 86 | np.ndarray arr1 = np.zeros(Shape(...)); 87 | np.ndarray arr2 = np.arange(start=0,end,step=1); 88 | np.ndarray arr3 = np.linspace(start,end,samples); 89 | ``` 90 | 91 | ### Attributes 92 | ``` 93 | shape_t arr.shape //the shape of the array. 94 | - len(arr.shape) //gives the number of dimensions of the array. 95 | - arr.shape[i] //gives the ith dimension 96 | int size //the number of elements in the array 97 | T* raw //pointer to the raw memory in the array 98 | ``` 99 | 100 | ### API 101 | ``` 102 | arr.as_type() //casts arr to np.ndarray 103 | arr.reshape(Shape(...)) //reshapes arr 104 | arr.reshape(shape) //given a shape_t, reshape arr 105 | arr.flatten() //flattens arr 106 | arr.destroy() //optionally manually delete arr 107 | ``` 108 | 109 | ### Broadcasting 110 | Broadcasting should (!!) work the same as in numpy. For example 111 | ``` 112 | auto arr3 = (arr + 0.5) * arr2 113 | ``` 114 | 115 | ### Math 116 | WIP, but for now: 117 | ``` 118 | np.sin(arr) 119 | np.cos(arr) 120 | np.tan(arr) 121 | np.asin(arr) 122 | np.acos(arr) 123 | np.atan(arr) 124 | ``` -------------------------------------------------------------------------------- /docs/type_inference.md: -------------------------------------------------------------------------------- 1 | # Type Inference 2 | 3 | Exactly like C++, use `auto`. -------------------------------------------------------------------------------- /docs/uniform_function_call_syntax.md: -------------------------------------------------------------------------------- 1 | # Uniform Function Call Syntax (UFCS) 2 | 3 | Imagine I have a type 4 | ``` 5 | struct my_type{ 6 | int a; 7 | ... 8 | }; 9 | 10 | struct my_type obj; 11 | ``` 12 | and a method 13 | ``` 14 | int my_method(struct my_type obj, int b){ 15 | return obj.a + b; 16 | } 17 | ``` 18 | 19 | I can call it like this: 20 | ``` 21 | my_method(obj,1); 22 | ``` 23 | Or, I can call it like this: 24 | ``` 25 | obj.my_method(1); 26 | ``` 27 | 28 | This means I can add \`methods\` wherever I want, and I can even add \`methods\` to built in types: 29 | ``` 30 | int add_1(int x){ 31 | return x+1; 32 | } 33 | ``` 34 | can be called 35 | ``` 36 | int my_x = 0; 37 | my_x.add_1(); 38 | ``` 39 | 40 | It also makes OOP a little less gross. For example, the code 41 | ``` 42 | struct my_struct{ 43 | int a; 44 | }; 45 | 46 | typedef struct my_struct* my_object; 47 | 48 | int get_a(my_object obj){ 49 | return obj->a; 50 | } 51 | 52 | void set_a(my_object obj, int a){ 53 | obj->a = a; 54 | } 55 | ``` 56 | lets you do stuff like this 57 | ``` 58 | my_object obj = (my_object)GC_malloc(sizeof(struct my_struct)); 59 | obj.set_a(10); 60 | obj.get_a(); 61 | ``` -------------------------------------------------------------------------------- /examples/customtype.sgc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct my_struct{ 5 | int a; 6 | }; 7 | 8 | #include //needs to know about relevant types 9 | 10 | typedef std.safe_ptr my_object; 11 | 12 | my_object make_my_object(void){ 13 | my_object out = std.alloc_safe(); 14 | out.get()->a = 0; 15 | return out; 16 | } 17 | 18 | int get_a(my_object obj){ 19 | return obj.get()->a; 20 | } 21 | 22 | void set_a(my_object obj, int a){ 23 | obj.get()->a = a; 24 | } 25 | 26 | string __str__(my_object obj){ 27 | string out = "my_struct{" + to_str(obj.get()->a) + "}"; 28 | return out; 29 | } 30 | 31 | int main(){ 32 | auto obj = make(my_object); 33 | obj.set_a(10); 34 | println("a =",obj.get_a()); 35 | set_a(obj,5); 36 | println("a =",get_a(obj)); 37 | println(obj); 38 | return 0; 39 | } -------------------------------------------------------------------------------- /examples/helloworld.sgc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(){ 5 | println("Hello World!"); 6 | return 0; 7 | } -------------------------------------------------------------------------------- /examples/iterators.sgc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(){ 5 | 6 | foreach(auto i in range(10)){ 7 | print(i); 8 | } 9 | println(); 10 | 11 | foreach(auto i in range(1,10,2)){ 12 | println(i); 13 | foreach(auto j in range(1,i)){ 14 | print(j); 15 | } 16 | } 17 | println(); 18 | 19 | return 0; 20 | } -------------------------------------------------------------------------------- /examples/makefile: -------------------------------------------------------------------------------- 1 | SOURCES := $(shell find . -name '*.sgc') 2 | OBJECTS := $(SOURCES:%.sgc=%.o) 3 | 4 | %.o: %.sgc | $(BUILD_DIR) 5 | sgcc -O3 -o $@ $< 6 | 7 | .PHONY: all 8 | all: $(OBJECTS) 9 | 10 | .PHONY: clean 11 | 12 | clean: 13 | rm *.o 14 | -------------------------------------------------------------------------------- /examples/memory_safety.sgc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(){ 6 | 7 | std.safe_ptr array; 8 | //println(array[0]); //fails at runtime 9 | array = std.alloc_safe(10); 10 | array[0] = 1; 11 | array[1] = 2; 12 | array[2] = 3; 13 | println(array[0],array[1],array[2]); 14 | 15 | //array[11] = 10; //fails at runtime 16 | 17 | return 0; 18 | } -------------------------------------------------------------------------------- /examples/optionals.sgc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | std.optional is_greater_than_5_or_null(int input){ 5 | if (input > 5){ 6 | return std.make_optional(input); 7 | } 8 | return std.nullopt(); 9 | } 10 | 11 | int main(){ 12 | 13 | std.optional i = std.make_optional(10); 14 | println(i.value_or(0)); 15 | 16 | std.optional j = std.nullopt(); 17 | println(j.value_or(0)); 18 | 19 | println(is_greater_than_5_or_null(10)); 20 | println(is_greater_than_5_or_null(5)); 21 | //println(is_greater_than_5_or_null(5).value()); //fails at runtime 22 | 23 | auto ilt5 = is_greater_than_5_or_null(0); 24 | if (ilt5.has_value()){ 25 | println(ilt5.value()); 26 | } 27 | 28 | auto igt5 = is_greater_than_5_or_null(100); 29 | if (igt5.has_value()){ 30 | println(igt5.value()); 31 | } 32 | 33 | return 0; 34 | } -------------------------------------------------------------------------------- /examples/performance_index.sgc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | double ptr_only(int n, int* out){ 6 | 7 | int* arr = (int*)malloc(sizeof(int) * n); 8 | 9 | auto start = CPUTimer(); 10 | 11 | int* iter = arr; 12 | for (int i = 0; i < n; i++){ 13 | *iter++ = i; 14 | } 15 | 16 | int sum = 0; 17 | iter = arr; 18 | for (int i = 0; i < n; i++){ 19 | sum += *iter++; 20 | } 21 | 22 | auto end = CPUTimer(start); 23 | 24 | *out = sum; 25 | 26 | free(arr); 27 | 28 | return end; 29 | 30 | } 31 | 32 | double index_only(int n, int* out){ 33 | int* arr = (int*)malloc(sizeof(int) * n); 34 | 35 | auto start = CPUTimer(); 36 | 37 | for (int i = 0; i < n; i++){ 38 | arr[i] = i; 39 | } 40 | 41 | int sum = 0; 42 | for (int i = 0; i < n; i++){ 43 | sum += arr[i]; 44 | } 45 | 46 | auto end = CPUTimer(start); 47 | 48 | *out = sum; 49 | 50 | free(arr); 51 | 52 | return end; 53 | } 54 | 55 | int main(){ 56 | int sum; 57 | int n = 1000000; 58 | 59 | ptr_only(n,&sum); 60 | index_only(n,&sum); 61 | int tries = 5; 62 | double diff = 0; 63 | for (int i = 0; i < tries; i++){ 64 | double a = ptr_only(n,&sum); 65 | double b = index_only(n,&sum); 66 | diff += b - a; 67 | } 68 | 69 | println("raw diff:",diff); 70 | println("avg:",diff/((double)(n*tries))); 71 | 72 | return 0; 73 | } -------------------------------------------------------------------------------- /examples/performance_vector_list.sgc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | double malloc_many(int n){ 7 | 8 | auto start = CPUTimer(); 9 | 10 | int* arr = (int*)malloc(sizeof(int) * n); 11 | int* iter = arr; 12 | for (int i = 0; i < n; i++){ 13 | *iter++ = i; 14 | } 15 | 16 | auto end = CPUTimer(start); 17 | 18 | free(arr); 19 | 20 | return end; 21 | } 22 | 23 | double push_back_many(int n){ 24 | std.vector my_vec = std.make_vector(); 25 | 26 | auto start = CPUTimer(); 27 | 28 | for (int i = 0; i < n; i++){ 29 | my_vec.push_back(i); 30 | } 31 | 32 | auto end = CPUTimer(start); 33 | 34 | my_vec.destroy(); 35 | 36 | return end; 37 | 38 | } 39 | 40 | double append_many(int n){ 41 | std.list my_list = std.make_list(); 42 | 43 | auto start = CPUTimer(); 44 | 45 | for (int i = 0; i < n; i++){ 46 | my_list.append(i); 47 | } 48 | 49 | auto end = CPUTimer(start); 50 | 51 | my_list.destroy(); 52 | 53 | return end; 54 | } 55 | 56 | double push_back_many_reserve(int n){ 57 | std.vector my_vec = std.make_vector(); 58 | 59 | auto start = CPUTimer(); 60 | 61 | my_vec.reserve(n); 62 | 63 | for (int i = 0; i < n; i++){ 64 | my_vec.push_back(i); 65 | } 66 | 67 | auto end = CPUTimer(start); 68 | 69 | my_vec.destroy(); 70 | 71 | return end; 72 | } 73 | 74 | int main(){ 75 | for (int n = 10; n < 100; n += 1){ 76 | push_back_many_reserve(n); 77 | push_back_many(n); 78 | append_many(n); 79 | malloc_many(n); 80 | 81 | int avg_of = 10; 82 | 83 | double push_back_many_reserve_time = 0; 84 | double push_back_many_time = 0; 85 | double append_many_time = 0; 86 | double malloc_many_time = 0; 87 | 88 | for (int i = 0; i < avg_of; i++){ 89 | push_back_many_reserve_time += push_back_many_reserve(n); 90 | push_back_many_time += push_back_many(n); 91 | append_many_time += append_many(n); 92 | malloc_many_time += malloc_many(n); 93 | } 94 | push_back_many_reserve_time /= (double)avg_of; 95 | push_back_many_time /= (double)avg_of; 96 | append_many_time /= (double)avg_of; 97 | malloc_many_time /= (double)avg_of; 98 | println("n =",n); 99 | println(" push_back_many:",push_back_many_time); 100 | println(" push_back_many_reserve:",push_back_many_reserve_time); 101 | println(" append_many:",append_many_time); 102 | println(" malloc_many:",malloc_many_time); 103 | } 104 | 105 | return 0; 106 | } -------------------------------------------------------------------------------- /examples/reduce.sgc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | //a really inefficient way to sum [0,n] 6 | int sum_n(int n){ 7 | return std.reduce,val+last,int>(range(n+1).to_list(),0); 8 | } 9 | 10 | int main(){ 11 | println(sum_n(100)); 12 | return 0; 13 | } -------------------------------------------------------------------------------- /examples/strings.sgc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(){ 5 | string a = "This is a string"; 6 | auto b = "this is another string!"; 7 | println(a + ", and " + b); 8 | println("The length of b is",len(b)); 9 | println("The length of a is",a.len()); 10 | return 0; 11 | } -------------------------------------------------------------------------------- /examples/strong_typing.sgc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | template { 5 | 6 | typedef std.strong_type even; 7 | typedef std.strong_type odd; 8 | 9 | static inline even make_even(T val){ 10 | return std.make_strong(val); 11 | } 12 | 13 | static inline odd make_odd(T val){ 14 | return std.make_strong(val); 15 | } 16 | 17 | static inline odd increment(even val){ 18 | return make_odd(val.get() + 1); 19 | } 20 | 21 | static inline even increment(odd val){ 22 | return make_even(val.get() + 1); 23 | } 24 | 25 | } 26 | 27 | int main(){ 28 | 29 | even my_even_int = make_even(2); 30 | //even my_incorrect_even_int = make_even(3); //fails at runtime 31 | //even my_odd_int = make_odd(3); //fails at compile time 32 | //even my_odd_int = increment(my_even_int); //fails at compile time 33 | odd my_odd_int = increment(my_even_int); 34 | auto my_auto_int = increment(my_odd_int); 35 | //odd my_bad_odd_int = my_auto_int; //fails at compile time 36 | println("even:",my_even_int.get()); 37 | println("odd:",my_odd_int); 38 | return 0; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /examples/template_abuse.sgc: -------------------------------------------------------------------------------- 1 | generated op { 2 | T3 op (T1 l, T2 r){ 3 | return l o r; 4 | } 5 | } 6 | 7 | int main(){ 8 | 9 | float a = op(1,2); 10 | 11 | return 0; 12 | } -------------------------------------------------------------------------------- /ext/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/humz2k/sugaryc/138616c0f2456e3bba0ec0607f592fa8a3c548e1/ext/.DS_Store -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/bdwgc/.github/workflows/CodeQL.yml: -------------------------------------------------------------------------------- 1 | # CodeQL workflow for GitHub code scanning. 2 | name: CodeQL 3 | 4 | on: [ push, pull_request ] 5 | 6 | jobs: 7 | analyze: 8 | name: Analyze 9 | runs-on: ubuntu-latest 10 | permissions: 11 | actions: read 12 | contents: read 13 | security-events: write 14 | 15 | strategy: 16 | fail-fast: false 17 | matrix: 18 | language: [ 'c-cpp' ] 19 | 20 | steps: 21 | - name: Checkout 22 | uses: actions/checkout@v4 23 | 24 | - name: Initialize CodeQL 25 | uses: github/codeql-action/init@v3 26 | with: 27 | languages: ${{ matrix.language }} 28 | 29 | - name: Autobuild 30 | uses: github/codeql-action/autobuild@v3 31 | 32 | - name: Perform CodeQL Analysis 33 | uses: github/codeql-action/analyze@v3 34 | with: 35 | category: "/language:${{ matrix.language }}" 36 | -------------------------------------------------------------------------------- /ext/bdwgc/.github/workflows/zig-build.yml: -------------------------------------------------------------------------------- 1 | # This workflow is for zig-based build/test running on Linux/x86_64. 2 | name: zig build 3 | 4 | on: [push, pull_request] 5 | 6 | jobs: 7 | build: 8 | name: thr:${{ matrix.enable_threads }} rwlock:${{ matrix.enable_rwlock }} redir:${{ matrix.redirect_malloc }} gcdeb:${{ matrix.enable_gc_debug }} munmap:${{ matrix.enable_munmap }} paramark:${{ matrix.parallel_mark }} thrlocal:${{ matrix.thread_local_alloc }} 9 | runs-on: ubuntu-latest 10 | timeout-minutes: 4 11 | 12 | strategy: 13 | fail-fast: false 14 | 15 | matrix: 16 | gc_assertions: [ true ] 17 | large_config: [ false ] 18 | enable_threads: [ false, true ] 19 | disable_handle_fork: [ false ] 20 | enable_rwlock: [ false, true ] 21 | redirect_malloc: [ false, true ] 22 | enable_gc_debug: [ false, true ] 23 | enable_munmap: [ false, true ] 24 | parallel_mark: [ false, true ] 25 | thread_local_alloc: [ false, true ] 26 | shared_libs: [ false ] # FIXME: gctest fail if shared lib 27 | exclude: 28 | - enable_threads: false 29 | disable_handle_fork: true 30 | - enable_threads: false 31 | parallel_mark: true 32 | - enable_threads: false 33 | enable_rwlock: true 34 | - enable_threads: false 35 | thread_local_alloc: true 36 | - enable_gc_debug: true # FIXME: some tests fail if gc_debug+redirect 37 | redirect_malloc: true 38 | 39 | # TODO: move from nightly to zig 0.12 when released. 40 | steps: 41 | - uses: actions/checkout@v4 42 | - name: "Install zig" 43 | run: | 44 | mkdir zig && curl https://ziglang.org/builds/zig-linux-x86_64-0.12.0-dev.1849+bb0f7d55e.tar.xz | tar Jx --directory=zig --strip-components=1 45 | - name: Build 46 | run: > 47 | zig/zig build 48 | -DBUILD_SHARED_LIBS=${{ matrix.shared_libs }} 49 | -Dbuild_tests=true 50 | -Ddisable_handle_fork=${{ matrix.disable_handle_fork }} 51 | -Denable_gc_assertions=${{ matrix.gc_assertions }} 52 | -Denable_gc_debug=${{ matrix.enable_gc_debug }} 53 | -Denable_large_config=${{ matrix.large_config }} 54 | -Denable_munmap=${{ matrix.enable_munmap }} 55 | -Denable_parallel_mark=${{ matrix.parallel_mark }} 56 | -Denable_redirect_malloc=${{ matrix.redirect_malloc }} 57 | -Denable_rwlock=${{ matrix.enable_rwlock }} 58 | -Denable_thread_local_alloc=${{ matrix.thread_local_alloc }} 59 | -Denable_threads=${{ matrix.enable_threads }} 60 | -Denable_werror=true 61 | test 62 | -------------------------------------------------------------------------------- /ext/bdwgc/.github/workflows/zig-cross-compile.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses Zig and its excellent cross-compilation support to test 2 | # compiling for multiple platforms. No tests are actually run since it would 3 | # require emulation. 4 | name: zig cross-compile 5 | 6 | on: [ push, pull_request ] 7 | 8 | jobs: 9 | build: 10 | name: ${{ matrix.ttriple }} thr:${{ matrix.enable_threads }} dll:${{ matrix.shared_libs }} 11 | runs-on: ubuntu-latest 12 | 13 | strategy: 14 | fail-fast: false 15 | matrix: 16 | # Some of the triples are commented out just to speedup this workflow. 17 | ttriple: [ 18 | aarch64-linux-gnu, 19 | #aarch64-linux-musl, 20 | aarch64-windows-gnu, 21 | #aarch64_be-linux-gnu, 22 | aarch64_be-linux-musl, 23 | #arm-linux-gnueabi, 24 | arm-linux-gnueabihf, 25 | arm-linux-musleabi, 26 | #arm-linux-musleabihf, 27 | armeb-linux-gnueabi, 28 | #armeb-linux-gnueabihf, 29 | #armeb-linux-musleabi, 30 | armeb-linux-musleabihf, 31 | #mips-linux-gnueabi, 32 | #mips-linux-gnueabihf, 33 | mips-linux-musl, 34 | mips64-linux-gnuabi64, 35 | #mips64-linux-gnuabin32, 36 | mips64-linux-musl, 37 | #mips64el-linux-gnuabi64, 38 | mips64el-linux-gnuabin32, 39 | mips64el-linux-musl, 40 | mipsel-linux-gnueabi, 41 | #mipsel-linux-gnueabihf, 42 | mipsel-linux-musl, 43 | #powerpc-linux-gnueabi, 44 | powerpc-linux-gnueabihf, 45 | #powerpc-linux-musl, 46 | powerpc64-linux-gnu, 47 | #powerpc64-linux-musl, 48 | #powerpc64le-linux-gnu, 49 | powerpc64le-linux-musl, 50 | riscv64-linux-musl, 51 | sparc64-linux-gnu, 52 | thumb-linux-gnueabi, 53 | #thumb-linux-gnueabihf, 54 | #thumb-linux-musleabi, 55 | thumb-linux-musleabihf, 56 | wasm32-wasi-musl, 57 | #x86-linux-gnu, 58 | x86-linux-musl, 59 | x86-windows-gnu, 60 | x86_64-linux-gnu.2.27, # with a glibc version 61 | x86_64-linux-gnux32, 62 | #x86_64-linux-musl, 63 | x86_64-windows-gnu, 64 | ] 65 | enable_threads: [ false, true ] 66 | shared_libs: [ false, true ] 67 | exclude: 68 | - enable_threads: true 69 | ttriple: wasm32-wasi-musl 70 | # The following ones have some zig link issue. 71 | - shared_libs: true 72 | ttriple: aarch64_be-linux-gnu 73 | - shared_libs: true 74 | ttriple: aarch64_be-linux-musl 75 | - shared_libs: true 76 | ttriple: armeb-linux-gnueabi 77 | - shared_libs: true 78 | ttriple: armeb-linux-gnueabihf 79 | - shared_libs: true 80 | ttriple: armeb-linux-musleabi 81 | - shared_libs: true 82 | ttriple: armeb-linux-musleabihf 83 | - shared_libs: true 84 | ttriple: mips64-linux-gnuabin32 85 | - shared_libs: true 86 | ttriple: mips64el-linux-gnuabin32 87 | - shared_libs: true 88 | ttriple: powerpc-linux-gnueabi 89 | - shared_libs: true 90 | ttriple: powerpc-linux-gnueabihf 91 | - shared_libs: true 92 | ttriple: sparc64-linux-gnu # FIXME: recompile with -fPIC 93 | - shared_libs: true 94 | ttriple: thumb-linux-gnueabi 95 | - shared_libs: true 96 | ttriple: thumb-linux-gnueabihf 97 | - shared_libs: true 98 | ttriple: x86_64-linux-gnux32 # FIXME: recompile with -fPIC 99 | 100 | # TODO: move from nightly to zig 0.12 when released. 101 | steps: 102 | - uses: actions/checkout@v4 103 | - name: "Install zig" 104 | run: | 105 | mkdir zig && curl https://ziglang.org/builds/zig-linux-x86_64-0.12.0-dev.1849+bb0f7d55e.tar.xz | tar Jx --directory=zig --strip-components=1 106 | - name: Build 107 | run: > 108 | zig/zig build -Dtarget=${{ matrix.ttriple }} 109 | -DBUILD_SHARED_LIBS=${{ matrix.shared_libs }} 110 | -Denable_threads=${{ matrix.enable_threads }} 111 | -------------------------------------------------------------------------------- /ext/bdwgc/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignored files in bdwgc Git repo. 2 | 3 | # Binary files (in root dir, cord, tests): 4 | *.a 5 | *.dll 6 | *.dylib 7 | *.exe 8 | *.gcda 9 | *.gch 10 | *.gcno 11 | *.la 12 | *.lib 13 | *.lo 14 | *.o 15 | *.obj 16 | lib*.so 17 | 18 | *.gc.log 19 | .dirstamp 20 | /*_bench.log 21 | /*_bench.trs 22 | /*_test 23 | /*test.log 24 | /*test.trs 25 | /.libs/ 26 | /Makefile 27 | /add_gc_prefix 28 | /atomicopstest 29 | /base_lib 30 | /bdw-gc.pc 31 | /c++ 32 | /config.cache 33 | /config.log 34 | /config.status 35 | /cord/cordtest 36 | /cord/de 37 | /cord/de_win.rbj 38 | /cord/de_win.res 39 | /cord/tests/de_win.rbj 40 | /cord/tests/de_win.res 41 | /cords 42 | /cordtest 43 | /core 44 | /cpptest 45 | /de 46 | /de.dir/ 47 | /disclaim_bench 48 | /disclaimtest 49 | /dont_ar_1 50 | /dont_ar_3 51 | /dont_ar_4 52 | /gc-* 53 | /gc.log 54 | /gcname 55 | /gctest 56 | /gctest_dyn_link 57 | /gctest_irix_dyn_link 58 | /hugetest 59 | /if_mach 60 | /if_not_there 61 | /initfromthreadtest 62 | /leaktest 63 | /libtool 64 | /middletest 65 | /realloctest 66 | /smashtest 67 | /staticrootstest 68 | /subthreadcreatetest 69 | /sunos5gc.so 70 | /test-suite.log 71 | /test_atomic_ops 72 | /test_atomic_ops.log 73 | /test_atomic_ops.trs 74 | /test_cpp 75 | /test_cpp.cpp 76 | /test_cpp.log 77 | /test_cpp.trs 78 | /threadkeytest 79 | /threadleaktest 80 | /threadlibs 81 | /tracetest 82 | /weakmaptest 83 | 84 | /build/ 85 | /out/ 86 | 87 | # Config, dependency and stamp files generated by configure: 88 | .deps/ 89 | /include/config.h 90 | config.h.in~ 91 | stamp-h1 92 | 93 | # External library (without trailing slash to allow symlinks): 94 | /libatomic_ops* 95 | /pthreads-w32* 96 | 97 | # These files are generated by autoreconf: 98 | /Makefile.in 99 | /aclocal.m4 100 | /autom4te.cache/ 101 | /compile 102 | /config.guess 103 | /config.sub 104 | /configure 105 | /configure~ 106 | /depcomp 107 | /include/config.h.in 108 | /install-sh 109 | /ltmain.sh 110 | /m4/libtool.m4 111 | /m4/ltoptions.m4 112 | /m4/ltsugar.m4 113 | /m4/ltversion.m4 114 | /m4/lt~obsolete.m4 115 | /missing 116 | /mkinstalldirs 117 | /test-driver 118 | 119 | # These files are generated by CMake: 120 | *.tlog 121 | /*.vcxproj 122 | /*.vcxproj.filters 123 | /CMakeCache.txt 124 | /CMakeFiles/ 125 | /DartConfiguration.tcl 126 | /Testing/Temporary/ 127 | /cord/CMakeFiles/ 128 | /cord/Makefile 129 | /gc.sln 130 | /tests/*.vcxproj 131 | /tests/*.vcxproj.filters 132 | /tests/*test 133 | /tests/CMakeFiles/ 134 | /tests/Makefile 135 | /tests/test_cpp 136 | CTestTestfile.cmake 137 | cmake_install.cmake 138 | 139 | # These ones are generated by Zig: 140 | /zig-cache/ 141 | /zig-out/ 142 | 143 | # Rarely generated files (mostly by some Win/DOS compilers): 144 | /*.copied.c 145 | /*.csm 146 | /*.err 147 | /*.i 148 | /*.lb1 149 | /*.lnk 150 | /*.map 151 | /*.out 152 | /*.rbj 153 | /*.res 154 | /*.stackdump 155 | /*.sym 156 | /*.tmp 157 | *.bsc 158 | *.dll.manifest 159 | *.exp 160 | *.idb 161 | *.ilk 162 | *.pdb 163 | *.sbr 164 | *.tds 165 | gc.def 166 | 167 | # Stuff from VS build system and IDE 168 | *.vcproj.*.user 169 | .vs/ 170 | 171 | # Code analysis tools: 172 | *.c.gcov 173 | *.cc.gcov 174 | *.h.gcov 175 | *.sancov 176 | /.sv*-dir 177 | /cov-int 178 | /coverage.info 179 | /pvs-project.log 180 | /pvs-project.tasks 181 | /strace_out 182 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | #define DE_CMDS_H 16 | 17 | # define UP 16 /* ^P */ 18 | # define DOWN 14 /* ^N */ 19 | # define LEFT 2 /* ^B */ 20 | # define RIGHT 6 /* ^F */ 21 | # define DEL 127 /* ^? */ 22 | # define BS 8 /* ^H */ 23 | # define UNDO 21 /* ^U */ 24 | # define WRITE 23 /* ^W */ 25 | # define QUIT 4 /* ^D */ 26 | # define REPEAT 18 /* ^R */ 27 | # define LOCATE 12 /* ^L */ 28 | # define TOP 20 /* ^T */ 29 | 30 | void do_command(int); 31 | /* Execute an editor command. */ 32 | /* The argument is a command character */ 33 | /* or one of the IDM_ commands. */ 34 | 35 | void generic_init(void); 36 | /* OS independent initialization. */ 37 | 38 | #endif /* DE_CMDS_H */ 39 | -------------------------------------------------------------------------------- /ext/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 | #ifndef DE_WIN_H 15 | #define DE_WIN_H 16 | 17 | #include "de_cmds.h" 18 | 19 | #define OTHER_FLAG 0x100 20 | #define EDIT_CMD_FLAG 0x200 21 | #define REPEAT_FLAG 0x400 22 | 23 | #define CHAR_CMD(i) ((i) & 0xff) 24 | 25 | /* MENU: DE */ 26 | #define IDM_FILESAVE (EDIT_CMD_FLAG + WRITE) 27 | #define IDM_FILEEXIT (OTHER_FLAG + 1) 28 | #define IDM_HELPABOUT (OTHER_FLAG + 2) 29 | #define IDM_HELPCONTENTS (OTHER_FLAG + 3) 30 | 31 | #define IDM_EDITPDOWN (REPEAT_FLAG + EDIT_CMD_FLAG + DOWN) 32 | #define IDM_EDITPUP (REPEAT_FLAG + EDIT_CMD_FLAG + UP) 33 | #define IDM_EDITUNDO (EDIT_CMD_FLAG + UNDO) 34 | #define IDM_EDITLOCATE (EDIT_CMD_FLAG + LOCATE) 35 | #define IDM_EDITDOWN (EDIT_CMD_FLAG + DOWN) 36 | #define IDM_EDITUP (EDIT_CMD_FLAG + UP) 37 | #define IDM_EDITLEFT (EDIT_CMD_FLAG + LEFT) 38 | #define IDM_EDITRIGHT (EDIT_CMD_FLAG + RIGHT) 39 | #define IDM_EDITBS (EDIT_CMD_FLAG + BS) 40 | #define IDM_EDITDEL (EDIT_CMD_FLAG + DEL) 41 | #define IDM_EDITREPEAT (EDIT_CMD_FLAG + REPEAT) 42 | #define IDM_EDITTOP (EDIT_CMD_FLAG + TOP) 43 | 44 | /* Screen dimensions. Maintained by de_win.c. */ 45 | extern int LINES; 46 | extern int COLS; 47 | 48 | /* File being edited. */ 49 | extern char * arg_file_name; 50 | 51 | /* Calls from de_win.c to de.c. */ 52 | 53 | const void *retrieve_screen_line(int i); 54 | /* Get the contents (CORD) of i-th screen line. */ 55 | /* Relies on COLS. */ 56 | 57 | void set_position(int x, int y); 58 | /* Set column, row. Upper left of window = (0,0). */ 59 | 60 | /* 61 | * Calls from de.c to de_win.c 62 | */ 63 | 64 | void move_cursor(int column, int line); 65 | /* Physically move the cursor on the display, */ 66 | /* so that it appears at (column, line). */ 67 | 68 | void invalidate_line(int line); 69 | /* Invalidate line i on the screen. */ 70 | 71 | void de_error(const char *s); 72 | /* Display error message. */ 73 | 74 | #endif /* DE_WIN_H */ 75 | -------------------------------------------------------------------------------- /ext/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_win.h" 16 | 17 | ABOUTBOX DIALOG 19, 21, 163, 47 18 | STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU 19 | CAPTION "About Demonstration Text Editor" 20 | BEGIN 21 | LTEXT "Demonstration Text Editor", -1, 44, 8, 118, 8, WS_CHILD | WS_VISIBLE | WS_GROUP 22 | PUSHBUTTON "OK", IDOK, 118, 27, 24, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP 23 | END 24 | 25 | DE MENU 26 | BEGIN 27 | POPUP "&File" 28 | BEGIN 29 | MENUITEM "&Save\t^W", IDM_FILESAVE 30 | MENUITEM "E&xit\t^D", IDM_FILEEXIT 31 | END 32 | 33 | POPUP "&Edit" 34 | BEGIN 35 | MENUITEM "Page &Down\t^R^N", IDM_EDITPDOWN 36 | MENUITEM "Page &Up\t^R^P", IDM_EDITPUP 37 | MENUITEM "U&ndo\t^U", IDM_EDITUNDO 38 | MENUITEM "&Locate\t^L ... ^L", IDM_EDITLOCATE 39 | MENUITEM "D&own\t^N", IDM_EDITDOWN 40 | MENUITEM "U&p\t^P", IDM_EDITUP 41 | MENUITEM "Le&ft\t^B", IDM_EDITLEFT 42 | MENUITEM "&Right\t^F", IDM_EDITRIGHT 43 | MENUITEM "Delete &Backward\tBS", IDM_EDITBS 44 | MENUITEM "Delete F&orward\tDEL", IDM_EDITDEL 45 | MENUITEM "&Top\t^T", IDM_EDITTOP 46 | END 47 | 48 | POPUP "&Help" 49 | BEGIN 50 | MENUITEM "&Contents", IDM_HELPCONTENTS 51 | MENUITEM "&About...", IDM_HELPABOUT 52 | END 53 | 54 | MENUITEM "Page_&Down", IDM_EDITPDOWN 55 | MENUITEM "Page_&Up", IDM_EDITPUP 56 | END 57 | 58 | DE ACCELERATORS 59 | BEGIN 60 | "^R", IDM_EDITREPEAT 61 | "^N", IDM_EDITDOWN 62 | "^P", IDM_EDITUP 63 | "^L", IDM_EDITLOCATE 64 | "^B", IDM_EDITLEFT 65 | "^F", IDM_EDITRIGHT 66 | "^T", IDM_EDITTOP 67 | VK_DELETE, IDM_EDITDEL, VIRTKEY 68 | VK_BACK, IDM_EDITBS, VIRTKEY 69 | END 70 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 allocator 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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/bdwgc/extra/symbian/global_end.cpp: -------------------------------------------------------------------------------- 1 | // Symbian-specific file. 2 | 3 | extern "C" { 4 | 5 | int winscw_data_end; 6 | 7 | } /* extern "C" */ 8 | -------------------------------------------------------------------------------- /ext/bdwgc/extra/symbian/global_start.cpp: -------------------------------------------------------------------------------- 1 | // Symbian-specific file. 2 | 3 | extern "C" { 4 | 5 | int winscw_data_start; 6 | 7 | } /* extern "C" */ 8 | -------------------------------------------------------------------------------- /ext/bdwgc/extra/symbian/init_global_static_roots.cpp: -------------------------------------------------------------------------------- 1 | // Symbian-specific file. 2 | 3 | #include 4 | 5 | #include "gc.h" 6 | 7 | extern "C" { 8 | 9 | #if defined(__WINS__) 10 | extern int winscw_data_start, winscw_data_end; 11 | #else 12 | extern int Image$$RW$$Limit[], Image$$RW$$Base[]; 13 | #endif 14 | 15 | void GC_init_global_static_roots() 16 | { 17 | void *dataStart; 18 | void *dataEnd; 19 | 20 | # if defined(__WINS__) 21 | dataStart = &winscw_data_start; 22 | dataEnd = &winscw_data_end; 23 | # else 24 | dataStart = (void *)Image$$RW$$Base; 25 | dataEnd = (void *)Image$$RW$$Limit; 26 | # endif 27 | GC_add_roots(dataStart, dataEnd); 28 | } 29 | 30 | } /* extern "C" */ 31 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/bdwgc/gc_badalc.cpp: -------------------------------------------------------------------------------- 1 | // Visual C++ seems to prefer a .cpp extension to .cc one. 2 | #include "gc_badalc.cc" 3 | -------------------------------------------------------------------------------- /ext/bdwgc/gc_cpp.cpp: -------------------------------------------------------------------------------- 1 | // Visual C++ seems to prefer a .cpp extension to .cc 2 | #include "gc_cpp.cc" 3 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/bdwgc/include/gc.h: -------------------------------------------------------------------------------- 1 | /* This file is installed for backward compatibility. */ 2 | #include "gc/gc.h" 3 | -------------------------------------------------------------------------------- /ext/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 | CORD_API void CORD_ec_flush_buf(CORD_ec); 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 | CORD_API void CORD_ec_append_cord(CORD_ec, CORD); 81 | 82 | #ifdef __cplusplus 83 | } /* extern "C" */ 84 | #endif 85 | 86 | #endif /* EC_H */ 87 | -------------------------------------------------------------------------------- /ext/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 callback. Called with the allocator 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 allocator lock. No-op in */ 43 | /* 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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | * Acquires the allocator 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 | /* Acquires the allocator lock. Thread should be registered in GC. */ 52 | /* Unimplemented on some platforms. Not recommended for general use. */ 53 | # ifndef GC_SUSPEND_THREAD_ID 54 | # define GC_SUSPEND_THREAD_ID void* 55 | # endif 56 | GC_API void GC_CALL GC_suspend_thread(GC_SUSPEND_THREAD_ID); 57 | GC_API void GC_CALL GC_resume_thread(GC_SUSPEND_THREAD_ID); 58 | 59 | /* Is the given thread suspended externally? The result is either */ 60 | /* 1 (true) or 0. Acquires the allocator lock in the reader mode. */ 61 | /* Note: returns false if the thread is not registered in GC. */ 62 | /* Unimplemented on some platforms (same as GC_suspend_thread). */ 63 | GC_API int GC_CALL GC_is_thread_suspended(GC_SUSPEND_THREAD_ID); 64 | #endif /* GC_THREADS */ 65 | 66 | #ifdef __cplusplus 67 | } /* extern "C" */ 68 | #endif 69 | 70 | #endif /* GC_JAVAXFC_H */ 71 | -------------------------------------------------------------------------------- /ext/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(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 | -------------------------------------------------------------------------------- /ext/bdwgc/include/gc_cpp.h: -------------------------------------------------------------------------------- 1 | /* This file is installed for backward compatibility. */ 2 | #include "gc/gc_cpp.h" 3 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | #include "gc_priv.h" 22 | 23 | #if !defined(GC_DARWIN_THREADS) && !defined(GC_WIN32_THREADS) 24 | # error darwin_semaphore.h included for improper target 25 | #endif 26 | 27 | #include 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | /* This is a very simple semaphore implementation based on pthreads. */ 34 | /* It is not async-signal safe. But this is not a problem because */ 35 | /* signals are not used to suspend threads on the target. */ 36 | 37 | typedef struct { 38 | pthread_mutex_t mutex; 39 | pthread_cond_t cond; 40 | int value; 41 | } sem_t; 42 | 43 | GC_INLINE int sem_init(sem_t *sem, int pshared, int value) { 44 | if (pshared != 0) { 45 | errno = EPERM; /* unsupported */ 46 | return -1; 47 | } 48 | sem->value = value; 49 | if (pthread_mutex_init(&sem->mutex, NULL) != 0) 50 | return -1; 51 | if (pthread_cond_init(&sem->cond, NULL) != 0) { 52 | (void)pthread_mutex_destroy(&sem->mutex); 53 | return -1; 54 | } 55 | return 0; 56 | } 57 | 58 | GC_INLINE int sem_post(sem_t *sem) { 59 | if (pthread_mutex_lock(&sem->mutex) != 0) 60 | return -1; 61 | sem->value++; 62 | if (pthread_cond_signal(&sem->cond) != 0) { 63 | (void)pthread_mutex_unlock(&sem->mutex); 64 | return -1; 65 | } 66 | return pthread_mutex_unlock(&sem->mutex) != 0 ? -1 : 0; 67 | } 68 | 69 | GC_INLINE int sem_wait(sem_t *sem) { 70 | if (pthread_mutex_lock(&sem->mutex) != 0) 71 | return -1; 72 | while (sem->value == 0) { 73 | if (pthread_cond_wait(&sem->cond, &sem->mutex) != 0) { 74 | (void)pthread_mutex_unlock(&sem->mutex); 75 | return -1; 76 | } 77 | } 78 | sem->value--; 79 | return pthread_mutex_unlock(&sem->mutex) != 0 ? -1 : 0; 80 | } 81 | 82 | GC_INLINE int sem_destroy(sem_t *sem) { 83 | return pthread_cond_destroy(&sem->cond) != 0 84 | || pthread_mutex_destroy(&sem->mutex) != 0 ? -1 : 0; 85 | } 86 | 87 | #ifdef __cplusplus 88 | } /* extern "C" */ 89 | #endif 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /ext/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 race. */ 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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | #ifndef MARK_BIT_PER_OBJ 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_OBJ */ 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 | -------------------------------------------------------------------------------- /ext/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 the allocator lock, ensuring that we cannot exit */ 63 | /* while a collection that thinks we are 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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | && defined(AO_HAVE_fetch_and_sub1) 67 | TA_assert(AO_fetch_and_add(&x, 42) == 13); 68 | TA_assert(AO_fetch_and_add(&x, (AO_t)(-43)) == 55); 69 | TA_assert(AO_fetch_and_add1(&x) == 12); 70 | TA_assert(AO_fetch_and_sub1(&x) == 13); 71 | TA_assert(AO_fetch_and_add1(&x) == 12); /* 2nd call */ 72 | # endif 73 | # ifdef AO_HAVE_compare_and_swap_release 74 | TA_assert(!AO_compare_and_swap(&x, 14, 42)); 75 | TA_assert(x == 13); 76 | TA_assert(AO_compare_and_swap_release(&x, 13, 42)); 77 | TA_assert(x == 42); 78 | # else 79 | if (*(volatile AO_t *)&x == 13) 80 | *(volatile AO_t *)&x = 42; 81 | # endif 82 | # ifdef AO_HAVE_or 83 | AO_or(&x, 66); 84 | TA_assert(x == 106); 85 | # endif 86 | # ifdef AO_HAVE_store_release 87 | AO_store_release(&x, 113); 88 | TA_assert(x == 113); 89 | # endif 90 | return 0; 91 | } 92 | 93 | #else 94 | 95 | int main(void) 96 | { 97 | printf("test skipped\n"); 98 | return 0; 99 | } 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | #define CHECK_OUT_OF_MEMORY(p) \ 46 | do { \ 47 | if (NULL == (p)) { \ 48 | fprintf(stderr, "Out of memory\n"); \ 49 | exit(69); \ 50 | } \ 51 | } while (0) 52 | 53 | #ifdef GC_PTHREADS 54 | static void *thread(void *arg) 55 | #else 56 | static DWORD WINAPI thread(LPVOID arg) 57 | #endif 58 | { 59 | GC_INIT(); 60 | CHECK_OUT_OF_MEMORY(GC_MALLOC(123)); 61 | CHECK_OUT_OF_MEMORY(GC_MALLOC(12345)); 62 | # ifdef GC_PTHREADS 63 | return arg; 64 | # else 65 | return (DWORD)(GC_word)arg; 66 | # endif 67 | } 68 | 69 | #include "private/gcconfig.h" 70 | 71 | int main(void) 72 | { 73 | # ifdef GC_PTHREADS 74 | int code; 75 | pthread_t t; 76 | 77 | # ifdef LINT2 78 | t = pthread_self(); /* explicitly initialize to some value */ 79 | # endif 80 | # else 81 | HANDLE t; 82 | DWORD thread_id; 83 | # endif 84 | # if !(defined(BEOS) || defined(ANY_MSWIN) \ 85 | || (defined(DARWIN) && !defined(NO_PTHREAD_GET_STACKADDR_NP)) \ 86 | || ((defined(FREEBSD) || defined(LINUX) || defined(NETBSD) \ 87 | || defined(HOST_ANDROID)) && !defined(NO_PTHREAD_GETATTR_NP) \ 88 | && !defined(NO_PTHREAD_ATTR_GET_NP)) \ 89 | || (defined(GC_SOLARIS_THREADS) && !defined(_STRICT_STDC)) \ 90 | || (!defined(STACKBOTTOM) && (defined(HEURISTIC1) \ 91 | || (!defined(LINUX_STACKBOTTOM) && !defined(FREEBSD_STACKBOTTOM))))) 92 | /* GC_INIT() must be called from main thread only. */ 93 | GC_INIT(); 94 | # endif 95 | (void)GC_get_suspend_signal(); /* linking fails if no threads support */ 96 | if (GC_get_find_leak()) 97 | printf("This test program is not designed for leak detection mode\n"); 98 | # ifdef GC_PTHREADS 99 | if ((code = pthread_create(&t, NULL, thread, NULL)) != 0) { 100 | fprintf(stderr, "Thread #0 creation failed: %s\n", strerror(code)); 101 | return 1; 102 | } 103 | if ((code = pthread_join(t, NULL)) != 0) { 104 | fprintf(stderr, "Thread #0 join failed: %s\n", strerror(code)); 105 | return 1; 106 | } 107 | # else 108 | t = CreateThread(NULL, 0, thread, 0, 0, &thread_id); 109 | if (t == NULL) { 110 | fprintf(stderr, "Thread #0 creation failed, errcode= %d\n", 111 | (int)GetLastError()); 112 | return 1; 113 | } 114 | if (WaitForSingleObject(t, INFINITE) != WAIT_OBJECT_0) { 115 | fprintf(stderr, "Thread #0 join failed, errcode= %d\n", 116 | (int)GetLastError()); 117 | CloseHandle(t); 118 | return 1; 119 | } 120 | CloseHandle(t); 121 | # endif 122 | printf("SUCCEEDED\n"); 123 | return 0; 124 | } 125 | -------------------------------------------------------------------------------- /ext/bdwgc/tests/leak.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #include "gc/leak_detector.h" 6 | 7 | #define N_TESTS 100 8 | 9 | #define CHECK_OUT_OF_MEMORY(p) \ 10 | do { \ 11 | if (NULL == (p)) { \ 12 | fprintf(stderr, "Out of memory\n"); \ 13 | exit(69); \ 14 | } \ 15 | } while (0) 16 | 17 | int main(void) { 18 | char *p[N_TESTS]; 19 | unsigned i; 20 | 21 | GC_set_find_leak(1); /* for new collect versions not compiled */ 22 | /* with -DFIND_LEAK. */ 23 | 24 | GC_INIT(); /* Needed if thread-local allocation is enabled. */ 25 | /* FIXME: This is not ideal. */ 26 | 27 | p[0] = (char *)_aligned_malloc(70 /* size */, 16); 28 | if (!p[0]) { 29 | fprintf(stderr, "Aligned allocation failed\n"); 30 | return 1; 31 | } 32 | _aligned_free(p[0]); 33 | 34 | for (i = 0; i < N_TESTS; ++i) { 35 | p[i] = i > 0 ? (char*)malloc(sizeof(int) + i) 36 | : strdup("abc"); 37 | CHECK_OUT_OF_MEMORY(p[i]); 38 | } 39 | CHECK_LEAKS(); 40 | for (i = 3; i < N_TESTS / 2; ++i) { 41 | p[i] = (char*)((i & 1) != 0 ? reallocarray(p[i], i, 43) 42 | : realloc(p[i], i * 16 + 1)); 43 | CHECK_OUT_OF_MEMORY(p[i]); 44 | } 45 | CHECK_LEAKS(); 46 | for (i = 2; i < N_TESTS; ++i) { 47 | free(p[i]); 48 | } 49 | for (i = 0; i < N_TESTS / 8; ++i) { 50 | p[i] = i < 3 || i > 6 ? (char*)malloc(sizeof(int) + i) 51 | : strndup("abcd", i); 52 | CHECK_OUT_OF_MEMORY(p[i]); 53 | } 54 | CHECK_LEAKS(); 55 | CHECK_LEAKS(); 56 | CHECK_LEAKS(); 57 | printf("SUCCEEDED\n"); 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /ext/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 | 6 | #include 7 | #include 8 | 9 | #include "gc.h" 10 | 11 | #define N_TESTS 32000 12 | 13 | #define ALLOC_SZ 4096 /* typical page size */ 14 | 15 | #define CHECK_OUT_OF_MEMORY(p) \ 16 | do { \ 17 | if (NULL == (p)) { \ 18 | fprintf(stderr, "Out of memory\n"); \ 19 | exit(69); \ 20 | } \ 21 | } while (0) 22 | 23 | int main(void) 24 | { 25 | int i; 26 | 27 | GC_set_all_interior_pointers(0); 28 | GC_INIT(); 29 | if (GC_get_find_leak()) 30 | printf("This test program is not designed for leak detection mode\n"); 31 | 32 | for (i = 0; i < N_TESTS; ++i) { 33 | CHECK_OUT_OF_MEMORY(GC_malloc_atomic(ALLOC_SZ)); 34 | CHECK_OUT_OF_MEMORY(GC_malloc(ALLOC_SZ)); 35 | } 36 | 37 | /* Test delayed start of marker threads, if they are enabled. */ 38 | GC_start_mark_threads(); 39 | 40 | for (i = 0; i < N_TESTS; ++i) { 41 | CHECK_OUT_OF_MEMORY(GC_malloc_atomic(ALLOC_SZ / 2)); 42 | CHECK_OUT_OF_MEMORY(GC_malloc(ALLOC_SZ / 2)); 43 | } 44 | 45 | printf("Final heap size is %lu\n", (unsigned long)GC_get_heap_size()); 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /ext/bdwgc/tests/realloc.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #include "gc.h" 6 | 7 | #define COUNT 10000000 8 | 9 | #define CHECK_OUT_OF_MEMORY(p) \ 10 | do { \ 11 | if (NULL == (p)) { \ 12 | fprintf(stderr, "Out of memory\n"); \ 13 | exit(69); \ 14 | } \ 15 | } while (0) 16 | 17 | int main(void) { 18 | int i; 19 | unsigned long last_heap_size = 0; 20 | 21 | GC_INIT(); 22 | if (GC_get_find_leak()) 23 | printf("This test program is not designed for leak detection mode\n"); 24 | 25 | for (i = 0; i < COUNT; i++) { 26 | int **p = GC_NEW(int *); 27 | int *q; 28 | 29 | CHECK_OUT_OF_MEMORY(p); 30 | q = (int *)GC_MALLOC_ATOMIC(sizeof(int)); 31 | CHECK_OUT_OF_MEMORY(q); 32 | if (*p != NULL) { 33 | fprintf(stderr, "GC_malloc returned garbage (or NULL)\n"); 34 | exit(1); 35 | } 36 | 37 | *p = (int *)GC_REALLOC(q, 2 * sizeof(int)); 38 | CHECK_OUT_OF_MEMORY(*p); 39 | 40 | if (i % 10 == 0) { 41 | unsigned long heap_size = (unsigned long)GC_get_heap_size(); 42 | 43 | if (heap_size != last_heap_size) { 44 | printf("Heap size: %lu\n", heap_size); 45 | last_heap_size = heap_size; 46 | } 47 | } 48 | } 49 | printf("SUCCEEDED\n"); 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /ext/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 | #include 11 | 12 | #define COUNT 7000 13 | #define SIZE 40 14 | 15 | #define CHECK_OUT_OF_MEMORY(p) \ 16 | do { \ 17 | if (NULL == (p)) { \ 18 | fprintf(stderr, "Out of memory\n"); \ 19 | exit(69); \ 20 | } \ 21 | } while (0) 22 | 23 | char * A[COUNT]; 24 | 25 | char * volatile q; 26 | 27 | int main(void) 28 | { 29 | int i; 30 | char *p; 31 | 32 | GC_INIT(); 33 | for (i = 0; i < COUNT; ++i) { 34 | A[i] = p = (char *)GC_MALLOC(SIZE); 35 | CHECK_OUT_OF_MEMORY(p); 36 | if (i % 3000 == 0) { 37 | q = NULL; 38 | GC_gcollect(); 39 | } else if (i % 5678 == 0) { 40 | /* Write a byte past the end of the allocated object */ 41 | /* but not beyond the last word of the object's memory. */ 42 | /* A volatile intermediate pointer variable is used to */ 43 | /* avoid a compiler complain of out-of-bounds access. */ 44 | q = &p[(SIZE + i / 2000) /* 42 */]; 45 | *q = 42; 46 | } 47 | } 48 | printf("SUCCEEDED\n"); 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/bdwgc/tests/staticroots_lib.c: -------------------------------------------------------------------------------- 1 | 2 | /* This test file is intended to be compiled into a DLL. */ 3 | 4 | #include 5 | #include 6 | 7 | #ifndef GC_DEBUG 8 | # define GC_DEBUG 9 | #endif 10 | 11 | #include "gc.h" 12 | 13 | #ifndef GC_TEST_EXPORT_API 14 | # if defined(GC_VISIBILITY_HIDDEN_SET) \ 15 | && !defined(__CEGCC__) && !defined(__CYGWIN__) && !defined(__MINGW32__) 16 | # define GC_TEST_EXPORT_API \ 17 | extern __attribute__((__visibility__("default"))) 18 | # else 19 | # define GC_TEST_EXPORT_API extern 20 | # endif 21 | #endif 22 | 23 | #define CHECK_OUT_OF_MEMORY(p) \ 24 | do { \ 25 | if (NULL == (p)) { \ 26 | fprintf(stderr, "Out of memory\n"); \ 27 | exit(69); \ 28 | } \ 29 | } while (0) 30 | 31 | struct treenode { 32 | struct treenode *x; 33 | struct treenode *y; 34 | }; 35 | 36 | static struct treenode *root[10] = { 0 }; 37 | static struct treenode *root_nz[10] = { (struct treenode *)(GC_word)2 }; 38 | 39 | /* Declare it to avoid "no previous prototype" clang warning. */ 40 | GC_TEST_EXPORT_API struct treenode ** libsrl_getpelem(int i, int j); 41 | 42 | #ifdef STATICROOTSLIB2 43 | # define libsrl_getpelem libsrl_getpelem2 44 | #else 45 | 46 | GC_TEST_EXPORT_API struct treenode * libsrl_mktree(int i); 47 | GC_TEST_EXPORT_API void * libsrl_init(void); 48 | 49 | GC_TEST_EXPORT_API struct treenode * libsrl_mktree(int i) 50 | { 51 | struct treenode *r = GC_NEW(struct treenode); 52 | struct treenode *x, *y; 53 | 54 | CHECK_OUT_OF_MEMORY(r); 55 | if (0 == i) 56 | return 0; 57 | if (1 == i) { 58 | r = (struct treenode *)GC_MALLOC_ATOMIC(sizeof(struct treenode)); 59 | CHECK_OUT_OF_MEMORY(r); 60 | } 61 | x = libsrl_mktree(i - 1); 62 | y = libsrl_mktree(i - 1); 63 | r -> x = x; 64 | r -> y = y; 65 | if (i != 1) { 66 | GC_END_STUBBORN_CHANGE(r); 67 | GC_reachable_here(x); 68 | GC_reachable_here(y); 69 | } 70 | return r; 71 | } 72 | 73 | GC_TEST_EXPORT_API void * libsrl_init(void) 74 | { 75 | # ifdef TEST_MANUAL_VDB 76 | GC_set_manual_vdb_allowed(1); 77 | # endif 78 | # ifndef STATICROOTSLIB_INIT_IN_MAIN 79 | GC_INIT(); 80 | # endif 81 | # ifndef NO_INCREMENTAL 82 | GC_enable_incremental(); 83 | # endif 84 | return GC_MALLOC(sizeof(struct treenode)); 85 | } 86 | 87 | #endif /* !STATICROOTSLIB2 */ 88 | 89 | GC_TEST_EXPORT_API struct treenode ** libsrl_getpelem(int i, int j) 90 | { 91 | # if defined(CPPCHECK) 92 | struct treenode node = { 0, 0 }; 93 | GC_noop1((GC_word)node.x | (GC_word)node.y); 94 | # endif 95 | return &((j & 1) != 0 ? root_nz : root)[i]; 96 | } 97 | -------------------------------------------------------------------------------- /ext/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_NZ_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 | make_key(); 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 | -------------------------------------------------------------------------------- /ext/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 | #include 27 | 28 | #define N_TESTS 100 29 | 30 | #define CHECK_OUT_OF_MEMORY(p) \ 31 | do { \ 32 | if (NULL == (p)) { \ 33 | fprintf(stderr, "Out of memory\n"); \ 34 | exit(69); \ 35 | } \ 36 | } while (0) 37 | 38 | #ifdef GC_PTHREADS 39 | static void *test(void *arg) 40 | #else 41 | static DWORD WINAPI test(LPVOID arg) 42 | #endif 43 | { 44 | int *p[N_TESTS]; 45 | int i; 46 | for (i = 0; i < N_TESTS; ++i) { 47 | p[i] = (int *)malloc(sizeof(int) + i); 48 | CHECK_OUT_OF_MEMORY(p[i]); 49 | } 50 | CHECK_LEAKS(); 51 | for (i = 1; i < N_TESTS; ++i) { 52 | free(p[i]); 53 | } 54 | # ifdef GC_PTHREADS 55 | return arg; 56 | # else 57 | return (DWORD)(GC_word)arg; 58 | # endif 59 | } 60 | 61 | #ifndef NTHREADS 62 | # define NTHREADS 5 63 | #endif 64 | 65 | int main(void) { 66 | # if NTHREADS > 0 67 | int i, n; 68 | # ifdef GC_PTHREADS 69 | pthread_t t[NTHREADS]; 70 | # else 71 | HANDLE t[NTHREADS]; 72 | # endif 73 | # endif 74 | 75 | GC_set_find_leak(1); /* for new collect versions not compiled */ 76 | /* with -DFIND_LEAK. */ 77 | GC_INIT(); 78 | 79 | GC_allow_register_threads(); /* optional if pthread_create redirected */ 80 | 81 | # if NTHREADS > 0 82 | for (i = 0; i < NTHREADS; ++i) { 83 | # ifdef GC_PTHREADS 84 | int code = pthread_create(t + i, 0, test, 0); 85 | 86 | if (code != 0) { 87 | fprintf(stderr, "Thread #%d creation failed: %s\n", 88 | i, strerror(code)); 89 | if (i > 1 && EAGAIN == code) break; 90 | exit(2); 91 | } 92 | # else 93 | DWORD thread_id; 94 | 95 | t[i] = CreateThread(NULL, 0, test, 0, 0, &thread_id); 96 | if (NULL == t[i]) { 97 | fprintf(stderr, "Thread #%d creation failed, errcode= %d\n", 98 | i, (int)GetLastError()); 99 | exit(2); 100 | } 101 | # endif 102 | } 103 | n = i; 104 | for (i = 0; i < n; ++i) { 105 | int code; 106 | 107 | # ifdef GC_PTHREADS 108 | code = pthread_join(t[i], 0); 109 | # else 110 | code = WaitForSingleObject(t[i], INFINITE) == WAIT_OBJECT_0 ? 0 : 111 | (int)GetLastError(); 112 | # endif 113 | if (code != 0) { 114 | fprintf(stderr, "Thread #%d join failed, errcode= %d\n", 115 | i, code); 116 | exit(2); 117 | } 118 | } 119 | # else 120 | (void)test(NULL); 121 | # endif 122 | 123 | CHECK_LEAKS(); 124 | CHECK_LEAKS(); 125 | CHECK_LEAKS(); 126 | printf("SUCCEEDED\n"); 127 | return 0; 128 | } 129 | -------------------------------------------------------------------------------- /ext/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 | #define CHECK_OUT_OF_MEMORY(p) \ 13 | do { \ 14 | if (NULL == (p)) { \ 15 | fprintf(stderr, "Out of memory\n"); \ 16 | exit(69); \ 17 | } \ 18 | } while (0) 19 | 20 | struct treenode { 21 | struct treenode *x; 22 | struct treenode *y; 23 | } *root[10]; 24 | 25 | static struct treenode *mktree(int i) { 26 | struct treenode *r = GC_NEW(struct treenode); 27 | struct treenode *x, *y; 28 | 29 | CHECK_OUT_OF_MEMORY(r); 30 | if (0 == i) 31 | return NULL; 32 | if (1 == i) { 33 | r = (struct treenode *)GC_MALLOC_ATOMIC(sizeof(struct treenode)); 34 | CHECK_OUT_OF_MEMORY(r); 35 | } 36 | x = mktree(i - 1); 37 | y = mktree(i - 1); 38 | r -> x = x; 39 | r -> y = y; 40 | if (i != 1) { 41 | GC_END_STUBBORN_CHANGE(r); 42 | GC_reachable_here(x); 43 | GC_reachable_here(y); 44 | } 45 | return r; 46 | } 47 | 48 | int main(void) 49 | { 50 | int i; 51 | 52 | GC_INIT(); 53 | if (GC_get_find_leak()) 54 | printf("This test program is not designed for leak detection mode\n"); 55 | for (i = 0; i < 10; ++i) { 56 | root[i] = mktree(12); 57 | } 58 | GC_generate_random_backtrace(); 59 | GC_generate_random_backtrace(); 60 | GC_generate_random_backtrace(); 61 | GC_generate_random_backtrace(); 62 | printf("SUCCEEDED\n"); 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /ext/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 | -------------------------------------------------------------------------------- /ext/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 | 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 | -------------------------------------------------------------------------------- /ext/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 | 7 | #include 8 | 9 | #ifdef __DJGPP__ 10 | # include 11 | #endif 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 | -------------------------------------------------------------------------------- /ext/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 | int main(void) 21 | { 22 | # if defined(GC_USE_LD_WRAP) 23 | printf("-Wl,--wrap -Wl,dlopen " 24 | "-Wl,--wrap -Wl,pthread_create -Wl,--wrap -Wl,pthread_join " 25 | "-Wl,--wrap -Wl,pthread_detach -Wl,--wrap -Wl,pthread_sigmask " 26 | "-Wl,--wrap -Wl,pthread_exit -Wl,--wrap -Wl,pthread_cancel\n"); 27 | # endif 28 | # if (defined(GC_LINUX_THREADS) && !defined(HOST_ANDROID)) \ 29 | || defined(GC_IRIX_THREADS) || defined(GC_DARWIN_THREADS) \ 30 | || defined(GC_AIX_THREADS) || (defined(HURD) && defined(GC_THREADS)) 31 | # ifdef GC_USE_DLOPEN_WRAP 32 | printf("-ldl "); 33 | # endif 34 | printf("-lpthread\n"); 35 | # endif 36 | # if defined(GC_OPENBSD_THREADS) 37 | printf("-pthread\n"); 38 | # endif 39 | # if defined(GC_FREEBSD_THREADS) 40 | # ifdef GC_USE_DLOPEN_WRAP 41 | printf("-ldl "); 42 | # endif 43 | # if (__FREEBSD_version < 500000) 44 | printf("-pthread\n"); 45 | # else /* __FREEBSD__ || __DragonFly__ */ 46 | printf("-lpthread\n"); 47 | # endif 48 | # endif 49 | # if defined(GC_NETBSD_THREADS) 50 | printf("-lpthread -lrt\n"); 51 | # endif 52 | 53 | # if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) 54 | printf("-lpthread -lrt\n"); 55 | # endif 56 | # if defined(GC_SOLARIS_THREADS) 57 | printf("-lthread -lposix4\n"); 58 | /* Is this right for recent versions? */ 59 | # endif 60 | # if defined(GC_WIN32_THREADS) && defined(CYGWIN32) 61 | printf("-lpthread\n"); 62 | # endif 63 | # if defined(GC_WIN32_PTHREADS) 64 | # ifdef PTW32_STATIC_LIB 65 | /* assume suffix s for static version of the pthreads-win32 library */ 66 | printf("-lpthreadGC2s -lws2_32\n"); 67 | # else 68 | printf("-lpthreadGC2\n"); 69 | # endif 70 | # endif 71 | # if defined(GC_OSF1_THREADS) 72 | printf("-pthread -lrt\n"); /* DOB: must be -pthread, not -lpthread */ 73 | # endif 74 | /* You need GCC 3.0.3 to build this one! */ 75 | /* DG/UX native gcc doesn't know what "-pthread" is */ 76 | # if defined(GC_DGUX386_THREADS) 77 | printf("-ldl -pthread\n"); 78 | # endif 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /include/assert.sgh: -------------------------------------------------------------------------------- 1 | #define assert(cond) if (!(cond)){printf("%s: FAILED\n",#cond); exit(1);} -------------------------------------------------------------------------------- /include/filter_map_reduce.sgh: -------------------------------------------------------------------------------- 1 | #ifndef _FILTER_MAP_REDUCE_SGH_ 2 | #define _FILTER_MAP_REDUCE_SGH_ 3 | 4 | module std; 5 | 6 | generated std.filter{ 7 | static inline T std.filter(T lst){ 8 | T out = __init__(); 9 | int length = len(lst); 10 | for (int i = 0; i < length; i++){ 11 | auto val = lst[i]; 12 | if (cond){ 13 | out.__append__(val); 14 | } 15 | } 16 | return out; 17 | } 18 | } 19 | 20 | generated std.map{ 21 | static inline T std.map(T lst){ 22 | T out = __init__(); 23 | int length = len(lst); 24 | for (int i = 0; i < length; i++){ 25 | auto val = lst[i]; 26 | out.__append__(func); 27 | } 28 | return out; 29 | } 30 | } 31 | 32 | generated std.reduce{ 33 | static inline Tout std.reduce(Tin lst, Tout initial){ 34 | Tout last = initial; 35 | int length = len(lst); 36 | for (int i = 0; i < length; i++){ 37 | auto val = lst[i]; 38 | last = func; 39 | } 40 | return last; 41 | } 42 | } 43 | 44 | #endif -------------------------------------------------------------------------------- /include/logging.sgh: -------------------------------------------------------------------------------- 1 | #ifndef _LOGGING_SGH_ 2 | #define _LOGGING_SGH_ 3 | 4 | #include 5 | 6 | #define set static int 7 | 8 | static inline void log_base(string log_str){ 9 | 10 | generated turn_on_debug_mode{ 11 | println(log_str); 12 | } 13 | 14 | }; 15 | 16 | #define logs_on turn_on_debug_mode 17 | 18 | static inline void log(string log_str){ 19 | log_base("\033[1;0mINFO: \033[0;0m" + log_str); 20 | } 21 | 22 | static inline void log(string log_str){ 23 | log_base("\033[1;33mWARNING: \033[0;33m" + log_str + "\033[0;0m"); 24 | } 25 | 26 | static inline void log(string log_str){ 27 | log_base("\033[1;31mERROR: \033[0;31m" + log_str + "\033[0;0m"); 28 | 29 | generated turn_off_log_exit_mode{ 30 | log("not exiting (dont_exit_on_log_error set)"); 31 | return; 32 | } 33 | exit(1); 34 | } 35 | 36 | #define dont_exit_on_log_error turn_off_log_exit_mode 37 | 38 | #endif -------------------------------------------------------------------------------- /include/mpi.sgh: -------------------------------------------------------------------------------- 1 | #include "mpi/sgccmpi.sgh" -------------------------------------------------------------------------------- /include/mpi/sgccmpi.sgh: -------------------------------------------------------------------------------- 1 | #ifndef _SGCCMPI_H_ 2 | #define _SGCCMPI_H_ 3 | #include 4 | #include "openmpi_config.sgh" 5 | #include 6 | #include 7 | 8 | module mpi; 9 | 10 | typedef struct{ 11 | MPI_Comm raw_comm; 12 | int rank; 13 | int size; 14 | } mpi.comm; 15 | 16 | int comm_rank(mpi.comm comm); 17 | 18 | int comm_size(mpi.comm comm); 19 | 20 | int mpi.comm_rank(mpi.comm comm); 21 | 22 | int mpi.comm_size(mpi.comm comm); 23 | 24 | mpi.comm mpi.get_comm_world(void); 25 | 26 | extern mpi.comm mpi.comm_world; 27 | 28 | int mpi.init(int* argc, char*** argv); 29 | 30 | int mpi.init(); 31 | 32 | int mpi.finalize(); 33 | 34 | template { 35 | 36 | int mpi.send(np.ndarray arr, int dest, int tag, mpi.comm comm); 37 | 38 | int send(np.ndarray arr, int dest, int tag, mpi.comm comm); 39 | 40 | int mpi.recv(np.ndarray arr, int source, int tag, mpi.comm comm); 41 | 42 | int recv(np.ndarray arr, int source, int tag, mpi.comm comm); 43 | 44 | int mpi.sendrecv(np.ndarray sendbuf, int dest, int sendtag, np.ndarray recvbuf, int source, int recvtag, mpi.comm comm); 45 | 46 | } 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /include/optional.sgh: -------------------------------------------------------------------------------- 1 | #ifndef _STD_OPTIONAL_H_ 2 | #define _STD_OPTIONAL_H_ 3 | 4 | #include 5 | #include 6 | 7 | module std; 8 | 9 | generated std.optional, std.make_optional, std.nullopt { 10 | 11 | typedef struct{ 12 | T raw; 13 | bool exists; 14 | } std.optional; 15 | 16 | static inline std.optional std.make_optional (T in){ 17 | std.optional out; 18 | out.raw = in; 19 | out.exists = true; 20 | return out; 21 | } 22 | 23 | static inline std.optional std.nullopt(void){ 24 | std.optional out; 25 | out.exists = false; 26 | return out; 27 | } 28 | 29 | static inline T value_or(std.optional opt, T val){ 30 | if (opt.exists)return opt.raw; 31 | return val; 32 | } 33 | 34 | static inline T value(std.optional opt){ 35 | if (!opt.exists){ 36 | printf("optional_failed\n");exit(1); 37 | } 38 | return opt.raw; 39 | } 40 | 41 | static inline string __str__(std.optional opt){ 42 | if (opt.exists){ 43 | return to_str(opt.raw); 44 | } 45 | return "nullopt"; 46 | } 47 | 48 | static inline bool has_value(std.optional opt){ 49 | return opt.exists; 50 | } 51 | 52 | } 53 | 54 | #endif -------------------------------------------------------------------------------- /include/print.sgh: -------------------------------------------------------------------------------- 1 | #ifndef _PRINT_SGH_ 2 | #define _PRINT_SGH_ 3 | 4 | const char* __str__(const char* s); 5 | 6 | const char* __str__(float f); 7 | const char* __str__(double f); 8 | 9 | const char* __str__(short a); 10 | 11 | const char* __str__(int a); 12 | 13 | const char* __str__(long int a); 14 | 15 | const char* __str__(long long int a); 16 | 17 | #endif -------------------------------------------------------------------------------- /include/range.sgh: -------------------------------------------------------------------------------- 1 | #ifndef _FOREACH_SGH_ 2 | #define _FOREACH_SGH_ 3 | 4 | typedef struct { 5 | int start; 6 | int stop; 7 | int step; 8 | int cur; 9 | } range_t; 10 | 11 | typedef range_t* range_obj; 12 | 13 | static inline range_obj __iter__(range_obj r){ 14 | return r; 15 | } 16 | 17 | static inline int __start__(range_obj r){ 18 | r->cur = r->start; 19 | return r->cur; 20 | } 21 | 22 | static inline bool __done__(range_obj r){ 23 | return r->cur >= r->stop; 24 | } 25 | 26 | static inline int __next__(range_obj r){ 27 | r->cur += r->step; 28 | return r->cur; 29 | } 30 | 31 | static inline range_obj range(int stop){ 32 | range_obj out = (range_obj)GC_malloc(sizeof(range_t)); 33 | out->start = 0; 34 | out->stop = stop; 35 | out->step = 1; 36 | return out; 37 | } 38 | static inline range_obj range(int start, int stop){ 39 | range_obj out = (range_obj)GC_malloc(sizeof(range_t)); 40 | out->start = start; 41 | out->stop = stop; 42 | out->step = 1; 43 | return out; 44 | } 45 | static inline range_obj range(int start, int stop, int step){ 46 | range_obj out = (range_obj)GC_malloc(sizeof(range_t)); 47 | out->start = start; 48 | out->stop = stop; 49 | out->step = step; 50 | return out; 51 | } 52 | 53 | #endif -------------------------------------------------------------------------------- /include/safe_ptr.sgh: -------------------------------------------------------------------------------- 1 | #ifndef _STD_SAFE_PTR_SGH_ 2 | #define _STD_SAFE_PTR_SGH_ 3 | 4 | #include 5 | #include 6 | 7 | module std; 8 | 9 | generated std.safe_ptr, std.alloc_safe { 10 | 11 | typedef struct{ 12 | std.strong_type raw; 13 | unsigned int sz; 14 | } std.safe_ptr; 15 | 16 | static inline std.safe_ptr std.alloc_safe(unsigned int sz){ 17 | T* tmp = (T*)GC_malloc(sz * sizeof(T)); 18 | std.safe_ptr out; 19 | out.raw = std.make_strong(tmp); 20 | out.sz = sz; 21 | return out; 22 | } 23 | 24 | static inline std.safe_ptr std.alloc_safe(void){ 25 | return std.alloc_safe(1); 26 | } 27 | 28 | /*static inline T* __index__(std.safe_ptr ptr, int* idxs, int n){ 29 | assert(n == 1); 30 | T* raw = ptr.raw.get(); 31 | int idx = idxs[0]; 32 | assert(idx < (ptr.sz)); 33 | return &raw[idx]; 34 | }*/ 35 | 36 | static inline T* __index__(std.safe_ptr ptr, int idx){ 37 | T* raw = ptr.raw.get(); 38 | assert(idx < (ptr.sz)); 39 | return &raw[idx]; 40 | } 41 | 42 | static inline T* get(std.safe_ptr ptr){ 43 | return ptr.raw.get(); 44 | } 45 | 46 | } 47 | 48 | #endif -------------------------------------------------------------------------------- /include/stdlib.sgh: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _STDLIB_SGH_ 3 | #define _STDLIB_SGH_ 4 | 5 | #include "../cstdlib/stdlib_macros.h" 6 | 7 | extern void* malloc(long unsigned int); 8 | 9 | extern void free(void*); 10 | 11 | #define _COMBINE(a,b) a ## b 12 | #define _combine(a, b) _COMBINE(a, b) 13 | #define make(typ,...) _combine(make_,typ)(__VA_ARGS__) 14 | 15 | //#define NULL ((void*)0) 16 | #ifndef NULL 17 | #define NULL nullptr 18 | #endif 19 | 20 | #include 21 | 22 | #include 23 | 24 | #define __device__ 25 | 26 | #endif -------------------------------------------------------------------------------- /include/string.sgh: -------------------------------------------------------------------------------- 1 | #ifndef _STRING_SGH_ 2 | #define _STRING_SGH_ 3 | 4 | typedef const char* string; 5 | 6 | string __add__(string left, string right); 7 | 8 | string __mul__(string left, int right); 9 | 10 | string __mul__(int left, string right); 11 | 12 | int __eq__(string left, string right); 13 | 14 | int __neq__(string left, string right); 15 | 16 | int len(string str); 17 | 18 | #endif -------------------------------------------------------------------------------- /include/strong_types.sgh: -------------------------------------------------------------------------------- 1 | #ifndef _STD_STRONG_TYPES_SGH_ 2 | #define _STD_STRONG_TYPES_SGH_ 3 | 4 | #include 5 | #include 6 | 7 | module std; 8 | 9 | generated std.strong_type, std.make_strong { 10 | typedef struct{ 11 | T raw; 12 | unsigned int magic; 13 | } std.strong_type; 14 | 15 | static inline std.strong_type std.make_strong(T val){ 16 | assert(cond); 17 | std.strong_type out; 18 | out.raw = val; 19 | out.magic = 0x23148201; 20 | return out; 21 | } 22 | 23 | static inline T get(std.strong_type input){ 24 | T val = input.raw; 25 | assert(input.magic == 0x23148201); 26 | assert(cond); 27 | return val; 28 | } 29 | 30 | static inline string __str__(std.strong_type input){ 31 | return to_str(input.get()); 32 | } 33 | } 34 | 35 | #endif -------------------------------------------------------------------------------- /include/time.sgh: -------------------------------------------------------------------------------- 1 | #ifndef _TIME_SGH_ 2 | #define _TIME_SGH_ 3 | 4 | #include "../cstdlib/time_macros.h" 5 | #include 6 | 7 | #define USECPSEC 1000000ULL 8 | 9 | struct tm { 10 | int tm_sec; /* seconds after the minute [0-60] */ 11 | int tm_min; /* minutes after the hour [0-59] */ 12 | int tm_hour; /* hours since midnight [0-23] */ 13 | int tm_mday; /* day of the month [1-31] */ 14 | int tm_mon; /* months since January [0-11] */ 15 | int tm_year; /* years since 1900 */ 16 | int tm_wday; /* days since Sunday [0-6] */ 17 | int tm_yday; /* days since January 1 [0-365] */ 18 | int tm_isdst; /* Daylight Savings Time flag */ 19 | long tm_gmtoff; /* offset from UTC in seconds */ 20 | char *tm_zone; /* timezone abbreviation */ 21 | }; 22 | 23 | extern char *asctime(const struct tm *); 24 | extern clock_t clock(void); 25 | extern char *ctime(const time_t *); 26 | extern double difftime(time_t, time_t); 27 | extern struct tm *getdate(const char *); 28 | extern struct tm *gmtime(const time_t *); 29 | extern struct tm *localtime(const time_t *); 30 | extern time_t mktime(struct tm *); 31 | extern size_t strftime(char * __restrict, size_t, const char * __restrict, const struct tm * __restrict); 32 | extern char *strptime(const char * __restrict, const char * __restrict, struct tm * __restrict); 33 | extern time_t time(time_t *); 34 | 35 | static inline double CPUTimer(void){ 36 | return clock()/CLOCKS_PER_SEC; 37 | } 38 | static inline double CPUTimer(double start){ 39 | return (clock() - start)/CLOCKS_PER_SEC; 40 | } 41 | 42 | #endif -------------------------------------------------------------------------------- /include/vector.sgh: -------------------------------------------------------------------------------- 1 | #ifndef _VECTOR_SGH_ 2 | #define _VECTOR_SGH_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #define INITIAL_VEC_LEN 4 9 | 10 | module std; 11 | 12 | generated std.vector, std.make_vector { 13 | 14 | struct std.vector_struct { 15 | T* raw; 16 | int length; 17 | int allocated; 18 | }; 19 | 20 | typedef struct std.vector_struct* std.vector; 21 | 22 | static inline int len(std.vector vec){ 23 | return vec->length; 24 | } 25 | 26 | static inline std.vector std.make_vector(void){ 27 | std.vector out = (std.vector)GC_malloc(sizeof(struct std.vector_struct)); 28 | out->raw = (T*)GC_malloc(sizeof(T) * INITIAL_VEC_LEN); 29 | out->length = 0; 30 | out->allocated = INITIAL_VEC_LEN; 31 | return out; 32 | } 33 | 34 | static inline void double_capacity(std.vector vec){ 35 | int allocated = vec->allocated; 36 | int new_allocated = allocated*2; 37 | vec->raw = (T*)GC_realloc(vec->raw, sizeof(T) * new_allocated); 38 | vec->allocated = new_allocated; 39 | } 40 | 41 | /*static inline T* __index__(std.vector vec, int* idxs, int n){ 42 | int idx = idxs[0]; 43 | return vec->raw + idx; 44 | }*/ 45 | 46 | static inline T* __index__(std.vector vec, int idx){ 47 | return vec->raw + idx; 48 | } 49 | 50 | static inline void push_back(std.vector vec, T val){ 51 | if (vec->length >= vec->allocated){ 52 | double_capacity(vec); 53 | } 54 | vec->raw[vec->length] = val; 55 | vec->length++; 56 | return; 57 | } 58 | 59 | static inline void __append__(std.vector lst, T val){ 60 | push_back(lst,val); 61 | } 62 | 63 | static inline std.vector __init__>(void){ 64 | return std.make_vector(); 65 | } 66 | 67 | static inline void emplace_back(std.vector vec){ 68 | vec->length--; 69 | int allocated = vec->allocated/2; 70 | if (allocated > vec->length){ 71 | vec->raw = (T*)GC_realloc(vec->raw, sizeof(T) * allocated); 72 | vec->allocated = allocated; 73 | } 74 | } 75 | 76 | static inline T pop_back(std.vector vec){ 77 | T out = vec->raw[vec->length-1]; 78 | emplace_back(vec); 79 | return out; 80 | } 81 | 82 | static inline void reserve(std.vector vec, int length){ 83 | int allocated = vec->allocated; 84 | while (length > allocated){ 85 | allocated *= 2; 86 | } 87 | vec->raw = (T*)GC_realloc(vec->raw, sizeof(T) * allocated); 88 | vec->allocated = allocated; 89 | } 90 | 91 | static inline void shrink_to_fit(std.vector vec){ 92 | int allocated = vec->allocated; 93 | int length = vec->length; 94 | while (length < allocated){ 95 | allocated /= 2; 96 | } 97 | allocated *= 2; 98 | vec->raw = (T*)GC_realloc(vec->raw, sizeof(T) * allocated); 99 | vec->allocated = allocated; 100 | } 101 | 102 | static inline void resize(std.vector vec, int length){ 103 | int allocated = INITIAL_VEC_LEN; 104 | while (length > allocated){ 105 | allocated *= 2; 106 | } 107 | vec->raw = (T*)GC_realloc(vec->raw, sizeof(T) * allocated); 108 | vec->allocated = allocated; 109 | vec->length = length; 110 | } 111 | 112 | static inline string __str__(std.vector vec){ 113 | string out = "["; 114 | int length = vec->length; 115 | for (int i = 0; i < (length-1); i++){ 116 | out += to_str(vec[i]) + ", "; 117 | } 118 | if (length > 0){ 119 | out += to_str(vec[length-1]); 120 | } 121 | out += "]"; 122 | return out; 123 | } 124 | 125 | static inline void destroy(std.vector vec){ 126 | GC_free(vec->raw); 127 | GC_free(vec); 128 | } 129 | 130 | } 131 | 132 | #endif -------------------------------------------------------------------------------- /include/vector_definition.sgh: -------------------------------------------------------------------------------- 1 | #ifndef vector_t 2 | #define vector_t float 3 | #endif 4 | 5 | #include 6 | 7 | #define _COMBINE(a,b) a ## b 8 | #define _combine(a, b) _COMBINE(a, b) 9 | 10 | #define vector2 _combine(vector_t,2) 11 | #define make_vector2 _combine(make_,vector2) 12 | #define vector3 _combine(vector_t,3) 13 | #define make_vector3 _combine(make_,vector3) 14 | #define vector4 _combine(vector_t,4) 15 | #define make_vector4 _combine(make_,vector4) 16 | 17 | #define STRINGIFY(x) #x 18 | #define TOSTRING(x) STRINGIFY(x) 19 | 20 | typedef struct { 21 | vector_t x; 22 | vector_t y; 23 | } vector2; 24 | 25 | static inline vector2 make_vector2(vector_t x, vector_t y){ 26 | vector2 out; 27 | out.x = x; 28 | out.y = y; 29 | return out; 30 | } 31 | 32 | static inline string __str__(vector2 vec){ 33 | string out = TOSTRING(vector2) + "{" + to_str(vec.x) + ", " + to_str(vec.y) + "}"; 34 | return out; 35 | } 36 | 37 | typedef struct { 38 | vector_t x; 39 | vector_t y; 40 | vector_t z; 41 | } vector3; 42 | 43 | static inline vector3 make_vector3(vector_t x, vector_t y, vector_t z){ 44 | vector3 out; 45 | out.x = x; 46 | out.y = y; 47 | out.z = z; 48 | return out; 49 | } 50 | 51 | static inline string __str__(vector3 vec){ 52 | string out = TOSTRING(vector3) + "{" + to_str(vec.x) + ", " + to_str(vec.y) + ", " + to_str(vec.z) + "}"; 53 | return out; 54 | } 55 | 56 | typedef struct { 57 | vector_t x; 58 | vector_t y; 59 | vector_t z; 60 | vector_t w; 61 | } vector4; 62 | 63 | static inline vector4 make_vector4(vector_t x, vector_t y, vector_t z, vector_t w){ 64 | vector4 out; 65 | out.x = x; 66 | out.y = y; 67 | out.z = z; 68 | out.w = w; 69 | return out; 70 | } 71 | 72 | static inline string __str__(vector4 vec){ 73 | string out = TOSTRING(vector4) + "{" + to_str(vec.x) + ", " + to_str(vec.y) + ", " + to_str(vec.z) + ", " + to_str(vec.w) + "}"; 74 | return out; 75 | } 76 | 77 | #undef vector2 78 | #undef vector3 79 | #undef vector4 80 | #undef make_vector2 81 | #undef make_vector3 82 | #undef make_vector4 -------------------------------------------------------------------------------- /include/vector_types.sgh: -------------------------------------------------------------------------------- 1 | #ifndef _VECTOR_TYPES_SGH_ 2 | #define _VECTOR_TYPES_SGH_ 3 | 4 | #define vector_t float 5 | #include "vector_definition.sgh" 6 | #undef vector_t 7 | 8 | #define vector_t double 9 | #include "vector_definition.sgh" 10 | #undef vector_t 11 | 12 | #define vector_t short 13 | #include "vector_definition.sgh" 14 | #undef vector_t 15 | 16 | #define vector_t int 17 | #include "vector_definition.sgh" 18 | #undef vector_t 19 | 20 | #define vector_t long 21 | #include "vector_definition.sgh" 22 | #undef vector_t 23 | 24 | #endif -------------------------------------------------------------------------------- /libmpisgc/makefile: -------------------------------------------------------------------------------- 1 | SOURCEDIR ?= sources 2 | BUILD_DIR ?= build 3 | 4 | SOURCES := $(shell find $(SOURCEDIR) -name '*.sgc') $(shell find $(SOURCEDIR) -name '*.c') $(shell find $(SOURCEDIR) -name '*.cpp') 5 | OBJECTS_0 := $(SOURCES:%.sgc=%.o) 6 | OBJECTS_1 := $(OBJECTS_0:%.cpp=%.o) 7 | OBJECTS := $(OBJECTS_1:%.c=%.o) 8 | OUTPUTS := $(OBJECTS:sources%=build%) 9 | 10 | libmpisgc.a: $(OUTPUTS) 11 | echo $(OUTPUTS) 12 | ar -cr $@ $^ 13 | 14 | $(BUILD_DIR)/%.o: $(SOURCEDIR)/%.sgc | $(BUILD_DIR) 15 | mpisgcc -O3 -o $@ $< -c 16 | 17 | $(BUILD_DIR)/%.o: $(SOURCEDIR)/%.c | $(BUILD_DIR) 18 | mpicc -O3 -o $@ $< -c 19 | 20 | $(BUILD_DIR)/%.o: $(SOURCEDIR)/%.cpp | $(BUILD_DIR) 21 | mpicxx -O3 -o $@ $< -c 22 | 23 | $(BUILD_DIR): 24 | mkdir -p $(BUILD_DIR) 25 | 26 | .PHONY: clean 27 | 28 | clean: 29 | rm -rf $(BUILD_DIR) 30 | rm libmpisgc.a 31 | -------------------------------------------------------------------------------- /libmpisgc/sources/comms.sgc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int comm_rank(mpi.comm comm){ 4 | int out; MPI_Comm_rank(comm.raw_comm,&out); 5 | return out; 6 | } 7 | 8 | int comm_size(mpi.comm comm){ 9 | int out; MPI_Comm_size(comm.raw_comm,&out); 10 | return out; 11 | } 12 | 13 | int mpi.comm_rank(mpi.comm comm){ 14 | return comm.comm_rank(); 15 | } 16 | 17 | int mpi.comm_size(mpi.comm comm){ 18 | return comm.comm_size(); 19 | } 20 | 21 | mpi.comm mpi.get_comm_world(void){ 22 | mpi.comm out; 23 | out.raw_comm = MPI_COMM_WORLD; 24 | MPI_Comm_rank(out.raw_comm,&out.rank); 25 | MPI_Comm_size(out.raw_comm,&out.size); 26 | return out; 27 | } 28 | 29 | mpi.comm mpi.comm_world; -------------------------------------------------------------------------------- /libmpisgc/sources/init.sgc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int mpi.init(int* argc, char*** argv){ 4 | int out = MPI_Init(argc,argv); 5 | mpi.comm_world = mpi.get_comm_world(); 6 | return out; 7 | } 8 | 9 | int mpi.init(){ 10 | return mpi.init(NULL,NULL); 11 | } 12 | 13 | int mpi.finalize(){ 14 | return MPI_Finalize(); 15 | } -------------------------------------------------------------------------------- /libmpisgc/sources/send_recv.sgc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | template { 4 | 5 | int mpi.send(np.ndarray arr, int dest, int tag, mpi.comm comm){ 6 | return MPI_Send(arr.raw,arr.size * sizeof(T),MPI_BYTE,dest,tag,comm.raw_comm); 7 | } 8 | 9 | int send(np.ndarray arr, int dest, int tag, mpi.comm comm){ 10 | return mpi.send(arr,dest,tag,comm); 11 | } 12 | 13 | int mpi.recv(np.ndarray arr, int source, int tag, mpi.comm comm){ 14 | return MPI_Recv(arr.raw,arr.size * sizeof(T),MPI_BYTE,source,tag,comm.raw_comm,MPI_STATUS_IGNORE); 15 | } 16 | 17 | int recv(np.ndarray arr, int source, int tag, mpi.comm comm){ 18 | return mpi.recv(arr,source,tag,comm); 19 | } 20 | 21 | int mpi.sendrecv(np.ndarray sendbuf, int dest, int sendtag, np.ndarray recvbuf, int source, int recvtag, mpi.comm comm){ 22 | return MPI_Sendrecv(sendbuf.raw,sendbuf.size*sizeof(T),MPI_BYTE,dest,sendtag,recvbuf.raw,recvbuf.size*sizeof(T),MPI_BYTE,source,recvtag,comm.raw_comm,MPI_STATUS_IGNORE); 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /pycparser/__init__.py: -------------------------------------------------------------------------------- 1 | #----------------------------------------------------------------- 2 | # pycparser: __init__.py 3 | # 4 | # This package file exports some convenience functions for 5 | # interacting with pycparser 6 | # 7 | # Eli Bendersky [https://eli.thegreenplace.net/] 8 | # License: BSD 9 | #----------------------------------------------------------------- 10 | __all__ = ['c_lexer', 'c_parser', 'c_ast'] 11 | __version__ = '2.21' 12 | 13 | import io 14 | from subprocess import check_output 15 | from .c_parser import CParser, ParseError 16 | 17 | 18 | def preprocess_file(filename, cpp_path='cpp', cpp_args=''): 19 | """ Preprocess a file using cpp. 20 | 21 | filename: 22 | Name of the file you want to preprocess. 23 | 24 | cpp_path: 25 | cpp_args: 26 | Refer to the documentation of parse_file for the meaning of these 27 | arguments. 28 | 29 | When successful, returns the preprocessed file's contents. 30 | Errors from cpp will be printed out. 31 | """ 32 | path_list = [cpp_path] 33 | if isinstance(cpp_args, list): 34 | path_list += cpp_args 35 | elif cpp_args != '': 36 | path_list += [cpp_args] 37 | path_list += [filename] 38 | 39 | try: 40 | # Note the use of universal_newlines to treat all newlines 41 | # as \n for Python's purpose 42 | text = check_output(path_list, universal_newlines=True) 43 | except OSError as e: 44 | raise RuntimeError("Unable to invoke 'cpp'. " + 45 | 'Make sure its path was passed correctly\n' + 46 | ('Original error: %s' % e)) 47 | 48 | return text 49 | 50 | 51 | def parse_file(filename, use_cpp=False, cpp_path='cpp', cpp_args='', 52 | parser=None, encoding=None): 53 | """ Parse a C file using pycparser. 54 | 55 | filename: 56 | Name of the file you want to parse. 57 | 58 | use_cpp: 59 | Set to True if you want to execute the C pre-processor 60 | on the file prior to parsing it. 61 | 62 | cpp_path: 63 | If use_cpp is True, this is the path to 'cpp' on your 64 | system. If no path is provided, it attempts to just 65 | execute 'cpp', so it must be in your PATH. 66 | 67 | cpp_args: 68 | If use_cpp is True, set this to the command line arguments strings 69 | to cpp. Be careful with quotes - it's best to pass a raw string 70 | (r'') here. For example: 71 | r'-I../utils/fake_libc_include' 72 | If several arguments are required, pass a list of strings. 73 | 74 | encoding: 75 | Encoding to use for the file to parse 76 | 77 | parser: 78 | Optional parser object to be used instead of the default CParser 79 | 80 | When successful, an AST is returned. ParseError can be 81 | thrown if the file doesn't parse successfully. 82 | 83 | Errors from cpp will be printed out. 84 | """ 85 | if use_cpp: 86 | text = preprocess_file(filename, cpp_path, cpp_args) 87 | else: 88 | with io.open(filename, encoding=encoding) as f: 89 | text = f.read() 90 | 91 | if parser is None: 92 | parser = CParser() 93 | return parser.parse(text, filename) 94 | -------------------------------------------------------------------------------- /pycparser/_build_tables.py: -------------------------------------------------------------------------------- 1 | #----------------------------------------------------------------- 2 | # pycparser: _build_tables.py 3 | # 4 | # A dummy for generating the lexing/parsing tables and and 5 | # compiling them into .pyc for faster execution in optimized mode. 6 | # Also generates AST code from the configuration file. 7 | # Should be called from the pycparser directory. 8 | # 9 | # Eli Bendersky [https://eli.thegreenplace.net/] 10 | # License: BSD 11 | #----------------------------------------------------------------- 12 | 13 | # Insert '.' and '..' as first entries to the search path for modules. 14 | # Restricted environments like embeddable python do not include the 15 | # current working directory on startup. 16 | import importlib 17 | import sys 18 | sys.path[0:0] = ['.', '..'] 19 | 20 | # Generate c_ast.py 21 | from _ast_gen import ASTCodeGenerator 22 | ast_gen = ASTCodeGenerator('_c_ast.cfg') 23 | ast_gen.generate(open('c_ast.py', 'w')) 24 | 25 | from pycparser import c_parser 26 | 27 | # Generates the tables 28 | # 29 | c_parser.CParser( 30 | lex_optimize=True, 31 | yacc_debug=False, 32 | yacc_optimize=True) 33 | 34 | # Load to compile into .pyc 35 | # 36 | importlib.invalidate_caches() 37 | 38 | import lextab 39 | import yacctab 40 | import c_ast 41 | -------------------------------------------------------------------------------- /pycparser/ply/LICENSE: -------------------------------------------------------------------------------- 1 | PLY (Python Lex-Yacc) Version 3.10 2 | 3 | Copyright (C) 2001-2017 4 | David M. Beazley (Dabeaz LLC) 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are 9 | met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, 12 | this list of conditions and the following disclaimer. 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | * Neither the name of the David Beazley or Dabeaz LLC may be used to 17 | endorse or promote products derived from this software without 18 | specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | More information about PLY can be obtained on the PLY webpage at: 33 | 34 | http://www.dabeaz.com/ply 35 | -------------------------------------------------------------------------------- /pycparser/ply/__init__.py: -------------------------------------------------------------------------------- 1 | # PLY package 2 | # Author: David Beazley (dave@dabeaz.com) 3 | 4 | __version__ = '3.9' 5 | __all__ = ['lex','yacc'] 6 | -------------------------------------------------------------------------------- /pycparser/ply/ctokens.py: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------------- 2 | # ctokens.py 3 | # 4 | # Token specifications for symbols in ANSI C and C++. This file is 5 | # meant to be used as a library in other tokenizers. 6 | # ---------------------------------------------------------------------- 7 | 8 | # Reserved words 9 | 10 | tokens = [ 11 | # Literals (identifier, integer constant, float constant, string constant, char const) 12 | 'ID', 'TYPEID', 'INTEGER', 'FLOAT', 'STRING', 'CHARACTER', 13 | 14 | # Operators (+,-,*,/,%,|,&,~,^,<<,>>, ||, &&, !, <, <=, >, >=, ==, !=) 15 | 'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'MODULO', 16 | 'OR', 'AND', 'NOT', 'XOR', 'LSHIFT', 'RSHIFT', 17 | 'LOR', 'LAND', 'LNOT', 18 | 'LT', 'LE', 'GT', 'GE', 'EQ', 'NE', 19 | 20 | # Assignment (=, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=) 21 | 'EQUALS', 'TIMESEQUAL', 'DIVEQUAL', 'MODEQUAL', 'PLUSEQUAL', 'MINUSEQUAL', 22 | 'LSHIFTEQUAL','RSHIFTEQUAL', 'ANDEQUAL', 'XOREQUAL', 'OREQUAL', 23 | 24 | # Increment/decrement (++,--) 25 | 'INCREMENT', 'DECREMENT', 26 | 27 | # Structure dereference (->) 28 | 'ARROW', 29 | 30 | # Ternary operator (?) 31 | 'TERNARY', 32 | 33 | # Delimeters ( ) [ ] { } , . ; : 34 | 'LPAREN', 'RPAREN', 35 | 'LBRACKET', 'RBRACKET', 36 | 'LBRACE', 'RBRACE', 37 | 'COMMA', 'PERIOD', 'SEMI', 'COLON', 38 | 39 | # Ellipsis (...) 40 | 'ELLIPSIS', 41 | ] 42 | 43 | # Operators 44 | t_PLUS = r'\+' 45 | t_MINUS = r'-' 46 | t_TIMES = r'\*' 47 | t_DIVIDE = r'/' 48 | t_MODULO = r'%' 49 | t_OR = r'\|' 50 | t_AND = r'&' 51 | t_NOT = r'~' 52 | t_XOR = r'\^' 53 | t_LSHIFT = r'<<' 54 | t_RSHIFT = r'>>' 55 | t_LOR = r'\|\|' 56 | t_LAND = r'&&' 57 | t_LNOT = r'!' 58 | t_LT = r'<' 59 | t_GT = r'>' 60 | t_LE = r'<=' 61 | t_GE = r'>=' 62 | t_EQ = r'==' 63 | t_NE = r'!=' 64 | 65 | # Assignment operators 66 | 67 | t_EQUALS = r'=' 68 | t_TIMESEQUAL = r'\*=' 69 | t_DIVEQUAL = r'/=' 70 | t_MODEQUAL = r'%=' 71 | t_PLUSEQUAL = r'\+=' 72 | t_MINUSEQUAL = r'-=' 73 | t_LSHIFTEQUAL = r'<<=' 74 | t_RSHIFTEQUAL = r'>>=' 75 | t_ANDEQUAL = r'&=' 76 | t_OREQUAL = r'\|=' 77 | t_XOREQUAL = r'\^=' 78 | 79 | # Increment/decrement 80 | t_INCREMENT = r'\+\+' 81 | t_DECREMENT = r'--' 82 | 83 | # -> 84 | t_ARROW = r'->' 85 | 86 | # ? 87 | t_TERNARY = r'\?' 88 | 89 | # Delimeters 90 | t_LPAREN = r'\(' 91 | t_RPAREN = r'\)' 92 | t_LBRACKET = r'\[' 93 | t_RBRACKET = r'\]' 94 | t_LBRACE = r'\{' 95 | t_RBRACE = r'\}' 96 | t_COMMA = r',' 97 | t_PERIOD = r'\.' 98 | t_SEMI = r';' 99 | t_COLON = r':' 100 | t_ELLIPSIS = r'\.\.\.' 101 | 102 | # Identifiers 103 | t_ID = r'[A-Za-z_][A-Za-z0-9_]*' 104 | 105 | # Integer literal 106 | t_INTEGER = r'\d+([uU]|[lL]|[uU][lL]|[lL][uU])?' 107 | 108 | # Floating literal 109 | t_FLOAT = r'((\d+)(\.\d+)(e(\+|-)?(\d+))? | (\d+)e(\+|-)?(\d+))([lL]|[fF])?' 110 | 111 | # String literal 112 | t_STRING = r'\"([^\\\n]|(\\.))*?\"' 113 | 114 | # Character constant 'c' or L'c' 115 | t_CHARACTER = r'(L)?\'([^\\\n]|(\\.))*?\'' 116 | 117 | # Comment (C-Style) 118 | def t_COMMENT(t): 119 | r'/\*(.|\n)*?\*/' 120 | t.lexer.lineno += t.value.count('\n') 121 | return t 122 | 123 | # Comment (C++-Style) 124 | def t_CPPCOMMENT(t): 125 | r'//.*\n' 126 | t.lexer.lineno += 1 127 | return t 128 | 129 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /pycparser/ply/ygen.py: -------------------------------------------------------------------------------- 1 | # ply: ygen.py 2 | # 3 | # This is a support program that auto-generates different versions of the YACC parsing 4 | # function with different features removed for the purposes of performance. 5 | # 6 | # Users should edit the method LParser.parsedebug() in yacc.py. The source code 7 | # for that method is then used to create the other methods. See the comments in 8 | # yacc.py for further details. 9 | 10 | import os.path 11 | import shutil 12 | 13 | def get_source_range(lines, tag): 14 | srclines = enumerate(lines) 15 | start_tag = '#--! %s-start' % tag 16 | end_tag = '#--! %s-end' % tag 17 | 18 | for start_index, line in srclines: 19 | if line.strip().startswith(start_tag): 20 | break 21 | 22 | for end_index, line in srclines: 23 | if line.strip().endswith(end_tag): 24 | break 25 | 26 | return (start_index + 1, end_index) 27 | 28 | def filter_section(lines, tag): 29 | filtered_lines = [] 30 | include = True 31 | tag_text = '#--! %s' % tag 32 | for line in lines: 33 | if line.strip().startswith(tag_text): 34 | include = not include 35 | elif include: 36 | filtered_lines.append(line) 37 | return filtered_lines 38 | 39 | def main(): 40 | dirname = os.path.dirname(__file__) 41 | shutil.copy2(os.path.join(dirname, 'yacc.py'), os.path.join(dirname, 'yacc.py.bak')) 42 | with open(os.path.join(dirname, 'yacc.py'), 'r') as f: 43 | lines = f.readlines() 44 | 45 | parse_start, parse_end = get_source_range(lines, 'parsedebug') 46 | parseopt_start, parseopt_end = get_source_range(lines, 'parseopt') 47 | parseopt_notrack_start, parseopt_notrack_end = get_source_range(lines, 'parseopt-notrack') 48 | 49 | # Get the original source 50 | orig_lines = lines[parse_start:parse_end] 51 | 52 | # Filter the DEBUG sections out 53 | parseopt_lines = filter_section(orig_lines, 'DEBUG') 54 | 55 | # Filter the TRACKING sections out 56 | parseopt_notrack_lines = filter_section(parseopt_lines, 'TRACKING') 57 | 58 | # Replace the parser source sections with updated versions 59 | lines[parseopt_notrack_start:parseopt_notrack_end] = parseopt_notrack_lines 60 | lines[parseopt_start:parseopt_end] = parseopt_lines 61 | 62 | lines = [line.rstrip()+'\n' for line in lines] 63 | with open(os.path.join(dirname, 'yacc.py'), 'w') as f: 64 | f.writelines(lines) 65 | 66 | print('Updated yacc.py') 67 | 68 | if __name__ == '__main__': 69 | main() 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /pysgcc/__init__.py: -------------------------------------------------------------------------------- 1 | from .kernel_fixer import * 2 | from .preprocessor import * 3 | from .find_cxx import find_compiler -------------------------------------------------------------------------------- /pysgcc/find_cxx.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | import subprocess 4 | sys.path = [os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..'))] + sys.path 5 | 6 | def print_log(log,msg): 7 | if log: 8 | print(msg) 9 | 10 | def find_compiler(log=False): 11 | # Prefered compiler 12 | preferred_compiler = 'g++' 13 | 14 | # Check if the user has set an environment variable 15 | compiler_env = os.getenv('SGCC_CXX') 16 | if compiler_env: 17 | print_log(log,"SGCC_CXX set to " + compiler_env) 18 | return compiler_env 19 | 20 | # List of compilers to check 21 | compilers = ['g++', 'clang++', 'c++'] 22 | 23 | # Check each compiler to see if it's available 24 | for compiler in compilers: 25 | try: 26 | # Check if compiler is in PATH and get its version 27 | subprocess.run([compiler, '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True) 28 | print_log(log,f"Found compiler: {compiler}") 29 | return compiler 30 | except (subprocess.CalledProcessError, FileNotFoundError): 31 | continue 32 | 33 | print("No C++ compiler found. Please install a C++ compiler (preferable g++).") 34 | exit() 35 | return None -------------------------------------------------------------------------------- /pysgcc/kernel_fixer.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | sys.path = [os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..'))] + sys.path 4 | from pycparser import c_generator, parse_file, c_ast, ParseError 5 | import argparse 6 | import re 7 | 8 | class KernelFixer(c_ast.NodeVisitor): 9 | def visit_Decl(self, node : c_ast.Decl): 10 | if (not "__global__" in node.quals): 11 | return 12 | if not isinstance(node.type,c_ast.FuncDecl): 13 | return 14 | 15 | typ = node.type 16 | 17 | if not typ.args: 18 | typ.args = c_ast.ParamList(params = []) 19 | 20 | new_inps = [] 21 | for v in ["blockIdx","blockDim","threadIdx"]: 22 | ty = c_ast.TypeDecl(declname=v, quals=[], align=[], type=c_ast.IdentifierType(['int3'])) 23 | newdecl = c_ast.Decl(name=v,quals=[],align=[],storage=[],funcspec=[],type=ty,init=None,bitsize=None,coord=node.coord) 24 | new_inps.append(newdecl) 25 | typ.args.params = new_inps + typ.args.params 26 | 27 | node.type = typ -------------------------------------------------------------------------------- /stdlib/makefile: -------------------------------------------------------------------------------- 1 | SOURCEDIR ?= sources 2 | BUILD_DIR ?= build 3 | 4 | SOURCES := $(shell find $(SOURCEDIR) -name '*.sgc') $(shell find $(SOURCEDIR) -name '*.c') $(shell find $(SOURCEDIR) -name '*.cpp') 5 | OBJECTS_0 := $(SOURCES:%.sgc=%.o) 6 | OBJECTS_1 := $(OBJECTS_0:%.cpp=%.o) 7 | OBJECTS := $(OBJECTS_1:%.c=%.o) 8 | OUTPUTS := $(OBJECTS:sources%=build%) 9 | 10 | libsgc.a: $(OUTPUTS) 11 | echo $(OUTPUTS) 12 | ar -cr $@ $^ 13 | 14 | $(BUILD_DIR)/%.o: $(SOURCEDIR)/%.sgc | $(BUILD_DIR) 15 | sgcc -O3 -o $@ $< -c 16 | 17 | $(BUILD_DIR)/%.o: $(SOURCEDIR)/%.c | $(BUILD_DIR) 18 | gcc -O3 -o $@ $< -c 19 | 20 | $(BUILD_DIR)/%.o: $(SOURCEDIR)/%.cpp | $(BUILD_DIR) 21 | g++ -O3 -o $@ $< -c 22 | 23 | $(BUILD_DIR): 24 | mkdir -p $(BUILD_DIR) 25 | mkdir -p $(BUILD_DIR)/np 26 | 27 | .PHONY: clean 28 | 29 | clean: 30 | rm -rf $(BUILD_DIR) 31 | rm libsgc.a 32 | -------------------------------------------------------------------------------- /stdlib/sources/math.sgc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | float sin(float x) { 4 | return sinf(x); 5 | } 6 | 7 | float cos(float x) { 8 | return cosf(x); 9 | } 10 | 11 | float tan(float x) { 12 | return tanf(x); 13 | } 14 | 15 | float asin(float x) { 16 | return asinf(x); 17 | } 18 | 19 | float acos(float x) { 20 | return acosf(x); 21 | } 22 | 23 | float atan(float x) { 24 | return atanf(x); 25 | } 26 | 27 | float atan2(float y, float x) { 28 | return atan2f(y, x); 29 | } 30 | 31 | float sinh(float x) { 32 | return sinhf(x); 33 | } 34 | 35 | float cosh(float x) { 36 | return coshf(x); 37 | } 38 | 39 | float tanh(float x) { 40 | return tanhf(x); 41 | } 42 | 43 | float exp(float x) { 44 | return expf(x); 45 | } 46 | 47 | float log(float x) { 48 | return logf(x); 49 | } 50 | 51 | float log10(float x) { 52 | return log10f(x); 53 | } 54 | 55 | float pow(float x, float y) { 56 | return powf(x, y); 57 | } 58 | 59 | float sqrt(float x) { 60 | return sqrtf(x); 61 | } 62 | 63 | float cbrt(float x) { 64 | return cbrtf(x); 65 | } 66 | 67 | float ceil(float x) { 68 | return ceilf(x); 69 | } 70 | 71 | float floor(float x) { 72 | return floorf(x); 73 | } 74 | 75 | float fmod(float x, float y) { 76 | return fmodf(x, y); 77 | } 78 | 79 | float fabs(float x) { 80 | return fabsf(x); 81 | } -------------------------------------------------------------------------------- /stdlib/sources/np/math.sgc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | module np; 8 | 9 | generated npmath { 10 | 11 | np.ndarray npmath(np.ndarray arr){ 12 | np.ndarray out = np.array(arr.shape); 13 | for (int i = 0; i < out.size; i++){ 14 | out.raw[i] = func((T2)arr.raw[i]); 15 | } 16 | return out; 17 | } 18 | 19 | } 20 | 21 | template{ 22 | np.ndarray np.sin(np.ndarray arr){ 23 | return npmath(arr); 24 | } 25 | 26 | np.ndarray np.cos(np.ndarray arr){ 27 | return npmath(arr); 28 | } 29 | 30 | np.ndarray np.tan(np.ndarray arr){ 31 | return npmath(arr); 32 | } 33 | 34 | np.ndarray np.asin(np.ndarray arr){ 35 | return npmath(arr); 36 | } 37 | 38 | np.ndarray np.acos(np.ndarray arr){ 39 | return npmath(arr); 40 | } 41 | 42 | np.ndarray np.atan(np.ndarray arr){ 43 | return npmath(arr); 44 | } 45 | 46 | T np.sin(T in){ 47 | return sin(in); 48 | } 49 | 50 | T np.cos(T in){ 51 | return cos(in); 52 | } 53 | 54 | T np.tan(T in){ 55 | return tan(in); 56 | } 57 | 58 | T np.asin(T in){ 59 | return asin(in); 60 | } 61 | 62 | T np.acos(T in){ 63 | return acos(in); 64 | } 65 | 66 | T np.atan(T in){ 67 | return atan(in); 68 | } 69 | } 70 | 71 | template{ 72 | np.ndarray np.sin(np.ndarray arr){ 73 | return npmath(arr); 74 | } 75 | 76 | np.ndarray np.cos(np.ndarray arr){ 77 | return npmath(arr); 78 | } 79 | 80 | np.ndarray np.tan(np.ndarray arr){ 81 | return npmath(arr); 82 | } 83 | 84 | np.ndarray np.asin(np.ndarray arr){ 85 | return npmath(arr); 86 | } 87 | 88 | np.ndarray np.acos(np.ndarray arr){ 89 | return npmath(arr); 90 | } 91 | 92 | np.ndarray np.atan(np.ndarray arr){ 93 | return npmath(arr); 94 | } 95 | 96 | double np.sin(T in){ 97 | return sin((double)in); 98 | } 99 | 100 | double np.cos(T in){ 101 | return cos((double)in); 102 | } 103 | 104 | double np.tan(T in){ 105 | return tan((double)in); 106 | } 107 | 108 | double np.asin(T in){ 109 | return asin((double)in); 110 | } 111 | 112 | double np.acos(T in){ 113 | return acos((double)in); 114 | } 115 | 116 | double np.atan(T in){ 117 | return atan((double)in); 118 | } 119 | } -------------------------------------------------------------------------------- /stdlib/sources/print.sgc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | extern int sprintf(char *str, const char *format, ...); 5 | 6 | const char* __str__(const char* s){ 7 | return s; 8 | } 9 | 10 | const char* __str__(float f){ 11 | char* buffer = (char*)GC_malloc(sizeof(char) * 11); 12 | sprintf(buffer, "%10.4g", f); 13 | while (buffer[0] == ' '){ 14 | buffer = &buffer[1]; 15 | } 16 | return buffer; 17 | } 18 | 19 | const char* __str__(double f){ 20 | char* buffer = (char*)GC_malloc(sizeof(char) * 11); 21 | sprintf(buffer, "%10.4g", f); 22 | while (buffer[0] == ' '){ 23 | buffer = &buffer[1]; 24 | } 25 | return buffer; 26 | } 27 | 28 | const char* __str__(int a){ 29 | int sz = (a / 10) + 2; 30 | char* buffer = (char*)GC_malloc(sizeof(char) * sz); 31 | sprintf(buffer, "%d", a); 32 | return buffer; 33 | } 34 | 35 | const char* __str__(long int a){ 36 | int sz = (a / 10) + 2; 37 | char* buffer = (char*)GC_malloc(sizeof(char) * sz); 38 | sprintf(buffer, "%ld", a); 39 | return buffer; 40 | } 41 | 42 | const char* __str__(long long int a){ 43 | int sz = (a / 10) + 2; 44 | char* buffer = (char*)GC_malloc(sizeof(char) * sz); 45 | sprintf(buffer, "%lld", a); 46 | return buffer; 47 | } 48 | 49 | const char* __str__(short a){ 50 | int sz = (a / 10) + 2; 51 | char* buffer = (char*)GC_malloc(sizeof(char) * sz); 52 | sprintf(buffer, "%d", a); 53 | return buffer; 54 | } -------------------------------------------------------------------------------- /stdlib/sources/string.sgc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | extern char *strcat(char *destination, const char *source); 5 | extern char *strcpy(char *dest, const char *src); 6 | extern long unsigned int strlen(const char *str); 7 | extern int strcmp (const char* str1, const char* str2); 8 | 9 | string __add__(string left, string right){ 10 | int sz = strlen(left) + strlen(right) + 1; 11 | char* out = (char*)GC_malloc(sizeof(char) * sz); 12 | strcpy(out,left); 13 | strcat(out,right); 14 | return out; 15 | } 16 | 17 | string __mul__(string left, int right){ 18 | string out = ""; 19 | for (int i = 0; i < right; i++){ 20 | out += left; 21 | } 22 | return out; 23 | } 24 | 25 | string __mul__(int left, string right){ 26 | return right * left; 27 | } 28 | 29 | int __eq__(string left, string right){ 30 | return strcmp(left,right) == 0; 31 | } 32 | 33 | int __neq__(string left, string right){ 34 | return strcmp(left,right) != 0; 35 | } 36 | 37 | int len(string str){ 38 | return strlen(str); 39 | } --------------------------------------------------------------------------------