Duktape - embeddable Javascript engine with a focus on portability and compact footprint

Duktape

Build status Test status

⚠️ Master branch is undergoing incompatible changes for Duktape 3.x. To track Duktape 2.x, follow the v2-maintenance branch.

Introduction

Duktape is an embeddable Javascript engine, with a focus on portability and compact footprint.

Duktape is easy to integrate into a C/C++ project: add duktape.c, duktape.h, and duk_config.h to your build, and use the Duktape API to call ECMAScript functions from C code and vice versa.

Main features:

  • Embeddable, portable, compact
  • ECMAScript E5/E5.1 compliant, with some semantics updated from ES2015+
  • Partial support for ECMAScript 2015 (E6) and ECMAScript 2016 (E7), Post-ES5 feature status, kangax/compat-table
  • ES2015 TypedArray and Node.js Buffer bindings
  • WHATWG Encoding API living standard
  • Built-in debugger
  • Built-in regular expression engine
  • Built-in Unicode support
  • Minimal platform dependencies
  • Combined reference counting and mark-and-sweep garbage collection with finalization
  • Custom features like coroutines
  • Property virtualization using a subset of ECMAScript ES2015 Proxy object
  • Bytecode dump/load for caching compiled functions
  • Distributable includes an optional logging framework, CommonJS-based module loading implementations, CBOR bindings, etc
  • Liberal MIT license (see LICENSE.txt)

See duktape.org for packaged end-user downloads and documentation. The end user downloads are also available from the duktape-releases repo as both binaries and in unpacked form as git tags.

Have fun!

Support

About this repository

This repository is intended for Duktape developers only, and contains Duktape internals: test cases, internal documentation, sources for the duktape.org web site, etc.

Getting started: end user

When embedding Duktape in your application you should use the packaged source distributables available from duktape.org/download.html. See duktape.org/guide.html#gettingstarted for the basics.

The distributable src/ directory contains a duk_config.h configuration header and amalgamated sources for Duktape default configuration. If necessary, use python tools/configure.py to create header and sources for customized configuration options, see http://wiki.duktape.org/Configuring.html. For example, to enable fastint support (example for Linux):

$ tar xvfJ duktape-2.0.0.tar.xz
$ cd duktape-2.0.0
$ rm -rf src-custom
$ python tools/configure.py \
      --source-directory src-input \
      --output-directory src-custom \
      --config-metadata config \
      -DDUK_USE_FASTINT

# src-custom/ will now contain: duktape.c, duktape.h, duk_config.h.

You can download and install Duktape using the vcpkg dependency manager:

$ git clone https://github.com/Microsoft/vcpkg.git
$ cd vcpkg
$ ./bootstrap-vcpkg.sh
$ ./vcpkg integrate install
$ vcpkg install duktape

The Duktape port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please create an issue or pull request on the vcpkg repository.

You can also clone this repository, make modifications, and build a source distributable on Linux, macOS, and Windows using python util/dist.py. You'll need Python 2 and Python YAML binding.

Getting started: modifying and rebuilding the distributable

If you intend to change Duktape internals and want to rebuild the source distributable in Linux, macOS, or Windows:

# Linux; can often install from packages or using 'pip'
# Install Node.js >= 14.x
$ sudo apt-get install python python-yaml
$ python util/dist.py

# macOS
# Install Python 2.7.x
# Install Node.js >= 14.x
$ pip install PyYAML
$ python util/dist.py

# Windows
; Install Python 2.7.x from python.org, and add it to PATH
; Install Node.js >= 14.x
> pip install PyYAML
> python util\dist.py

The source distributable directory will be in dist/.

For platform specific notes see http://wiki.duktape.org/DevelopmentSetup.html.

Getting started: other development (Linux only)

Other development stuff, such as building the website and running test cases, is based on a Makefile supported for Linux x86-64 only.

There are some Docker images which can simplify the development setup and also document the needed packages. These are also supported for Linux x86-64 only. For example:

# Build Docker images.  This takes a long time.
$ make docker-images

# Equivalent of 'make dist-source', but runs inside a container.
$ make docker-dist-source-wd

# Run a shell with /work/duktape containing a disposable master snapshot.
$ make docker-shell-master

# Run a shell with /work/duktape mounted from current directory.
# This allows editing, building, testing, etc with an interactive
# shell running in the container.
$ make docker-shell-wdmount

# For non-native images you may need:
# https://github.com/multiarch/qemu-user-static

There is limited support for developing on macOS via Docker. On Apple M1:

$ make docker-images-arm64
$ DOCKER_ARCH=arm64 make docker-shell-wdmount

Branch policy

  • The master branch is used for active development. Even though pull requests are tested before merging, master may still be broken from time to time. When development on a new major release starts, master will also get API incompatible changes without warning. For these reasons you should generally not depend on the master branch for building your project; use a release tag (e.g. v2.4.0) or a release maintenance branch (e.g. v2.4-maintenance or v2-maintenance) instead.

  • Pull requests and their related branches are frequently rebased so you should not fork off them. Pull requests may be open for a while for testing and discussion.

  • Release tags like v1.4.1 are used for releases and match the released distributables. These are stable once the release is complete.

  • Maintenance branches are used for backporting fixes and features for maintenance releases. Documentation changes go to master for maintenance releases too. For example, v1.5-maintenance was created for the 1.5.0 release and is used for 1.5.x maintenance releases.

  • A maintenance branch is also created for a major release when master moves on to active development of the next major release. For example, v1-maintenance was created when 1.5.0 was released (last planned 1.x release) and development of 2.0.0 (with API incompatible changes) started on master. The 1.6.0 and 1.7.0 releases were made from v1-maintenance for example.

Versioning

Duktape uses Semantic Versioning for official releases. Builds from Duktape repo are not official releases and don't follow strict semver, mainly because DUK_VERSION needs to have some compromise value that won't be strictly semver conforming. Because Duktape tracks the latest ECMAScript specification versions, compliance fixes are made in minor versions even when they are technically not backwards compatible. See Versioning for details.

Reporting bugs

See CONTRIBUTING.md.

Security critical GitHub issues (for example anything leading to a segfault) are tagged security.

Contributing

See CONTRIBUTING.md.

Copyright and license

See AUTHORS.rst and LICENSE.txt.

Duktape Wiki is part of Duktape documentation and under the same copyright and license.

Comments
  • Strange assert, unmoved heapptr was selected for finalization

    Strange assert, unmoved heapptr was selected for finalization

    Were there any major changes to garbage collection?

    Take this with a grain of salt since usually the bugs I present is some weird thing I messed up in my side, but this was a strange one.

    In my app I have certain indices in the stash reserved for some object pools. The pools get allocated at the beginning as arrays, and they are left there. I simply grab the heapptr and add/remove objects to that array. I haven't had any issues with it ever, suddenly today I got an assert triggered when I pushed the stashed pool's heapptr:

    /* One particular problem case is where an object has been
    		 * queued for finalization but the finalizer hasn't been
    		 * executed.
    		 */
    		duk_heaphdr *curr;
    		for (curr = thr->heap->finalize_list;
    		     curr != NULL;
    		     curr = DUK_HEAPHDR_GET_NEXT(thr->heap, curr)) {
    			DUK_ASSERT(curr != (duk_heaphdr *) ptr);
    		}
    

    Again, I might have corrupted something somewhere, who knows, just looking for some info in case there were some changes that might have caused this? This portion of my code (with the pool) hasn't been touched in a very long time...

    The heapptr which is an array inside an array inside the heap stash is only ever grabbed from the stash index once at the beginning, the pushed into the stack only 3 places in the code. The stash is not messed with again other than in initializing those arrays at the beginning.

    If it helps, the objects that are stored in that pool (the heapptr that caused the assert) are revived when being finalized. That is, the pool is full of preallocated Ecmascirpt objects that I grab from the pool return them when I need one, then nullify that object's index. When the object get's finalized I keep it alive by storing it back in the pool.

  • Add support for debugger heap walking

    Add support for debugger heap walking

    Add support for safe debugger heap walking:

    • Add a primitive to inspect an object and its properties and flags without side effects. This allows the debug client to enumerate properties, look up the prototype chain, walk referenced objects, etc.
    • Add a mechanism for some kind of heap locking to avoid garbage collection while walking the heap.

    Tasks:

    • [x] Add a new debugger command for inspecting an object
    • [x] Add new debugger commands to "lock" the heap for walking (see discussion in #358) => For now, uses automatic locking during paused state; future work is to add an explicit GC during paused state if that is necessary for some reason
    • [x] Add sizeof(void *) to BasicInfo
    • [x] Add optional heapptr target to GetBytecode?
    • [ ] Debugger protocol documentation
    • [ ] Wiki page for debugger heap walking with more verbose discussion and example command sequences - https://github.com/svaarala/duktape-wiki/pull/81
    • [ ] Some minimal implementation in the web UI
    • [ ] Document garbage collection behavior during paused state into debugger documentation; refzero cases go through mark-and-sweep now
    • [ ] Read through debugger.rst and update design notes and future work re: inspect
    • [ ] Releases

    Low level issues to resolve:

    • [x] What to do about virtual properties - i.e. properties logically part of the object and visible to Ecmascript code, but not concretely part of the object's internal property table? For comparison, enumeration code needs to "fake" these properties. => For now, virtual properties are not returned in inspection; future work.
    • [ ] Make the InspectHeapObject command optional because of the relatively high footprint.
    • [ ] Should property keys be object references to heap strings? If yes, what to do about artificial keys? If no, how would user code be able to dump all heap strings? Should there be a LookupString command to find an interned string?

    Consider overlaps with existing commands:

    • [ ] InspectHeapObject and DumpHeap: Could DumpHeap simply provide a list of heap pointers which the debug client would then inspect using InspectHeapObject so that there'd be no formatting overlap?
    • [ ] InspectHeapObject and GetBytecode: GetBytecode could be replaced by simply getting a reference to the currently executing function and then adding the bytecode, constants, and inner functions into the InspectHeapObject result. There's a small issue in representing structured values there; temporary objects may need to be created to hold the constants, etc.
  • Implement debugger halt-on-throw

    Implement debugger halt-on-throw

    When the debugger is attached and an error is thrown with no active catch site, either a runtime error thrown by Duktape or directly by Ecmascript code, the debug client is notified and execution is paused at the error site to allow the developer to view program state. This is useful, as this information will be lost once the stack is unwound.

    Implementation checklist:

    • [x] Implement the basic logic for debugger error intercept.
    • [x] Add a Throw notification to alert the client to the error.
    • [x] Ensure yield/resume awareness to avoid spurious pauses.
    • [x] Fix C stack overflow when an error is thrown at max recursion (double error pileup).
    • [x] Fix crashes when intercepting errors originating from the compiler (fixed by not intercepting them).
    • [x] Fix an assert failure when execution is stopped inside a Duktape/C call.
    • [x] Finalize changes and ensure consistency with Duktape codebase.
  • Improve opcode dispatch further by using a local curr_pc in executor

    Improve opcode dispatch further by using a local curr_pc in executor

    With #265 bytecode dispatch uses a cached thr->curr_pc pointer which is copied back into the topmost activation act->curr_pc whenever activation states may change or an up-to-date activation state is needed (e.g. for line numbers in the debugger).

    This can probably be improved a bit further:

    • Use a local variable in the bytecode executor for curr_pc. Make that variable volatile so that it is always stored back into the stack frame after a dispatch.
    • Store a pointer to the stack frame location which holds curr_pc (i.e. a duk_instr_t ** with &curr_pc as its value) in thr->ptr_curr_pc.
    • Wherever thr->curr_pc was copied back into act->curr_pc after #265, copy the value from *thr->ptr_curr_pc instead.

    This is faster because thr is sometimes spilled but the stack frame pointer is not.

    Preliminary testing suggests this is roughly 5% faster than #265 (to be verified with more careful testing).

    Changes:

    • [x] Main source changes to implement the change
    • [x] Perhaps simplify management of thr->ptr_curr_pc: bytecode executor can establish it, and restore it before exiting (it always has a setjmp catchpoint so it can do this reliably)
    • [x] Check volatile declarations
    • [x] Verify performance difference
    • [x] Update doc/execution.rst
    • [x] Testcases (apitest, qecmatest, test262)
    • [x] Test debugger manually
  • Add initial ES6 symbol support

    Add initial ES6 symbol support

    This is a prototype for an implementation approach where Symbols are duk_hstrings with a specific byte prefix which cannot occur for valid (extended) UTF-8 strings. The existing internal string concept is essentially taken a step further to support ES6 Symbols. There's no new internal type for Symbols as such, and the C API sees Symbols as just strings.

    • [x] Code change for symbol support
    • [x] Fix compiler warnings
    • [x] Fix Reflect.keys()
    • [x] Testcase support
    • [x] Fix perftest coercion issues
    • [x] Check key coercion for duk_def_prop() and other property calls
    • [x] Wiki pull for symbols howto (should cover the C API aspects especially) - https://github.com/svaarala/duktape-wiki/pull/152
    • [x] 2.x migration notes
    • [x] Releases entry
    • [x] Read through pull comments and add cleanup issues to #1120
  • Fix debugger re-entry while detaching

    Fix debugger re-entry while detaching

    Fixes #597. Possibly related to debugger read callback re-entry issue described in #591.

    Tasks:

    • [x] Fix debugger re-entry when dbg_processing was set to zero during detach1()
    • [x] Fix Duktape never doing detach2() if detach1() occurred outside of debugger message loop
    • [x] Fix write_cb NULLing for duk_debug_write_byte()
    • [x] Any way to repeat @harold-b's issue with repeated read calls not resetting callbacks to NULL? => Could not reproduce.
    • [x] Add fix backport notes for earlier releases where appropriate
    • [x] Releases
  • Implement application-defined debugger command support

    Implement application-defined debugger command support

    This adds application-defined message support to the debug protocol. When Duktape receives a request message beginning with the code for AppRequest (currently 0x22), it pushes all the remaining dvalues in the message to the valstack and calls heap->dbg_request_cb. That callback can push its own values to the stack, and these are sent back to the client as a REP, or optionally return -1 to send the value on the stack top as an ERR response.

    It is also possible for the target to send application-defined notifys (AppNotify, 0x07) to the client by calling duk_debugger_notify().

    This branch is merge-ready.

  • Add a Node.js-like module loader extra

    Add a Node.js-like module loader extra

    A module loading framework and require() implementation based on Node.js. Semantics match Node.js wherever possible and most features of the Node module system are provided.

    https://nodejs.org/api/modules.html

    Features:

    • Application provides callbacks to perform module resolution and loading
    • Module caching based on resolved module ID
    • Tolerates circular require() chains
    • Supports module.exports, module.loaded, and module.require
    • Supports require.cache
    • Supports __filename (but not __dirname)

    Checklist:

    • [x] Expose duk__push_require_function() to calling code? => duk_module_node_init() registers a global require, so not needed
    • [x] Manual tests to ensure correctness of all features such as module.loaded, require.cache, etc.
    • [x] Full documentation, in particular for callbacks
    • [x] More/better sanity checks/guards around callback invocations? => callbacks are now Duktape/C functions
    • [x] Rename extra to module-node
    • [x] Match Node.js module ID semantics (module.id === module.filename)
  • Implement WHATWG Encoding API support

    Implement WHATWG Encoding API support

    Implements #961.

    Add TextEncoder and TextDecoder built-ins as described by the WHATWG Encoding specification. For this pull, only UTF-8/CESU-8 support is implemented. UTF-16 and all legacy encodings are left as future work.

    Specification: https://encoding.spec.whatwg.org/#api

    Checklist:

    • [x] Implement the WHATWG Encoding API: TextEncoder and TextDecoder
    • [x] Config option - DUK_USE_ENCODING_BUILTINS
    • [x] Support Encoding API with bufferobjects disabled? Bindings could then work with plain buffers instead of Uint8Arrays (out of spec).
    • [x] Node.js Buffer .toString() can share code with TextDecoder? => Save for later
    • [x] Test cases for both encode and decode
    • [x] Website note (Encoding API listed in features)
    • [x] RELEASES entry
  • Error thrown in try/finally with no catch causes internal error

    Error thrown in try/finally with no catch causes internal error

    try { throw new Error("A pig ate everyone at 8:12"); }
    finally { print("*munch*"); }
    

    The finally runs, but leads to "internal error in bytecode executor longjmp handler". What's odd is that I can't always reproduce it. Depending on the surrounding lines, it sometimes works correctly.

  • Avoid finalizer rerun unless object is rescued

    Avoid finalizer rerun unless object is rescued

    Change duk_hobject_run_finalizer() so that:

    • If DUK_HEAPHDR_FLAG_FINALIZED is already set, do nothing.
    • Set DUK_HEAPHDR_FLAG_FINALIZED just before running finalizer.

    This should guarantee the semantics described in #109 (= at most one finalizer call per rescue cycle) because:

    • The only place where a finalizer is called is duk_hobject_run_finalizer().
    • The FINALIZED flag is only cleared by an explicit rescue, detected by either mark-and-sweep or refcounting.

    Other changes:

    • Heap destruction finalizer behavior changes: allow finalizers to create new finalizable objects whose finalizers are also executed, sanity limit.
    • Explicit Proxy check, don't call finalizer on a Proxy object.

    Tasks:

    • [x] Review changes
    • [x] Try to come up with a repro case for finalizer re-run, most obvious cases are already fixed
    • [x] Test case for runaway finalizer which spawns 1 or 2 new objects per finalization
    • [x] Test case for new finalizer argument
    • [x] Ensure "mark-and-sweep running" is checked even when mark-and-sweep not enabled
    • [x] Website changes for new guarantee
    • [x] Internal doc changes for new guarantee
    • [x] Add second parameter to finalizer indicating if rescue is possible or not (true: heap being destroyed, can't rescue; false: normal rescue possible)
    • [x] Finalizer documentation changes for new 2nd argument
    • [x] Run heap destruction finalizers in a loop to allow any new finalizable objects created by previous finalizers to also be finalized
    • [x] Add a sanity limit to the finalization loop
    • [x] Releases
    • [x] Assert run with mark-and-sweep + refcounting
    • [x] Assert run with mark-and-sweep only
    • [x] Assert run with refcounting only

    Fixes #109. See #108.

  • add OpenRCT2 to

    add OpenRCT2 to "Projects using Duktape"

    used for the plugins system

    https://openrct2.io/

    https://github.com/OpenRCT2/OpenRCT2

    many plugins here https://openrct2plugins.org/

    I'm referring to this list https://wiki.duktape.org/projectsusingduktape

  • website: incorrect MuJS license

    website: incorrect MuJS license

  • What's comming in 3.0?

    What's comming in 3.0?

    Is there any place where I can read info about the planned changes for Duktape 3.0? Also, any idea of the kind of timeline for the new version to hit beta?

  • Can't use for loops.

    Can't use for loops.

    Hello there, when I try to use a simple for loop, I get "SyntaxError: parse error (line 2)" I can use while loops, but any for loops seems to cause parse errors.

    Here is the really simple code that doesn't work: (Uses a custom print function bound via C)

    const arr = [3, 5, 7];
    for (let i of arr) {
       print(i); // logs 3, 5, 7
    }
    

    Here is the really simple code that does work:

    const arr = [3, 5, 7];
    const counter = arr.length;
    const index = 0;
    while (index < counter)
    {
    	print(arr[index])
    	index++;
    }
    
  • How to avoid parsing of nested json

    How to avoid parsing of nested json

    Hi @svaarala,

    I have json string which looks like '{"a":0,"b":1,"c":{"c1":10,"c2":20}}. Note c is nested. Currently I am using JSON.parse() to parse above.

    Is it possible avoid parsing value of attribute c and keeps it's value as a string only? In other terms, i wish to parse only simple values and not keys have nested json (i.e. parsing depth = 1).

    I have a use case where c is a large json value and parsing the same is not needed. This could help me massively improve the performance.

    Requesting your help on the same. Thanks

  • Cannot parse complex functions

    Cannot parse complex functions

    ((o) Duktape 2.7.0 (03d4d72-dirty)
    duk> function x() { for (i=0; i-10; i++) { try { if (i == 5) throw i} catch {return 10} finally {break} }; return 42 }; x()
    SyntaxError: parse error (line 1)
        at [anon] (input:1) internal
        at [anon] (duk_js_compiler.c:511) internal
    duk> function x() { var a; return a?.qq; }; x();
    SyntaxError: parse error (line 1)
        at [anon] (input:1) internal
        at [anon] (duk_js_compiler.c:3797) internal
    duk> function f(){return 0 ?? 42;}; f();
    SyntaxError: parse error (line 1)
        at [anon] (input:1) internal
        at [anon] (duk_js_compiler.c:3797) internal
    

    First result should be 42 second = undefined third = 0

ChakraCore is an open source Javascript engine with a C API.

ChakraCore ChakraCore is a Javascript engine with a C API you can use to add support for Javascript to any C or C compatible project. It can be compil

Nov 19, 2022
Structy is an irresponsibly dumb and simple struct serialization/deserialization library for C, Python, and vanilla JavaScript.

Structy Structy is an irresponsibly dumb and simple struct serialization/deserialization library for C, Python, and vanilla JavaScript. You can think

Sep 13, 2022
:sparkles: Magical headers that make your C++ library accessible from JavaScript :rocket:
:sparkles: Magical headers that make your C++ library accessible from JavaScript :rocket:

Quick start | Requirements | Features | User guide | Contributing | License nbind is a set of headers that make your C++11 library accessible from Jav

Nov 14, 2022
Sol3 (sol2 v3.0) - a C++ <-> Lua API wrapper with advanced features and top notch performance - is here, and it's great! Documentation:

sol2 sol2 is a C++ library binding to Lua. It currently supports all Lua versions 5.1+ (LuaJIT 2.0+ and MoonJIT included). sol2 aims to be easy to use

Nov 25, 2022
Libraries and examples to support Pimoroni Pico add-ons in C++ and MicroPython.

Pimoroni Pico Libraries and Examples Welcome to the brave new world of Pico! This repository contains the C/C++ and MicroPython libraries for our rang

Nov 24, 2022
Tools and libraries to glue C/C++ APIs to high-level languages

CppSharp is a tool and set of libraries which facilitates the usage of native C/C++ code with the .NET ecosystem. It consumes C/C++ header and library

Nov 23, 2022
A tool for generating cross-language type declarations and interface bindings.

Djinni Djinni is a tool for generating cross-language type declarations and interface bindings. It's designed to connect C++ with either Java or Objec

Nov 19, 2022
The missing bridge between Java and native C++

JavaCPP Commercial support: Introduction JavaCPP provides efficient access to native C++ inside Java, not unlike the way some C/C++ compilers interact

Nov 26, 2022
Seamless operability between C++11 and Python
Seamless operability between C++11 and Python

pybind11 — Seamless operability between C++11 and Python Setuptools example • Scikit-build example • CMake example Warning Combining older versions of

Nov 25, 2022
SWIG is a software development tool that connects programs written in C and C++ with a variety of high-level programming languages.

SWIG (Simplified Wrapper and Interface Generator) Version: 4.1.0 (in progress) Tagline: SWIG is a compiler that integrates C and C++ with languages

Nov 25, 2022
A minimalist and mundane scripting language.

Drift Script A minimalist and mundane scripting language. I like all simple things, simple and beautiful, simple and strong. I know that all developme

Nov 14, 2022
Elk is a tiny embeddable JavaScript engine that implements a small but usable subset of ES6
Elk is a tiny embeddable JavaScript engine that implements a small but usable subset of ES6

Elk is a tiny embeddable JavaScript engine that implements a small but usable subset of ES6. It is designed for microcontroller development. Instead of writing firmware code in C/C++, Elk allows to develop in JavaScript. Another use case is providing customers with a secure, protected scripting environment for product customisation.

Nov 25, 2022
Kokkos C++ Performance Portability Programming EcoSystem: The Programming Model - Parallel Execution and Memory Abstraction

Kokkos: Core Libraries Kokkos Core implements a programming model in C++ for writing performance portable applications targeting all major HPC platfor

Nov 16, 2022
A Gen implementation in C. With memory efficiency, portability and speed in mind

A Gen implementation in C. With memory efficiency, portability and speed in mind

Jul 31, 2022
Low dependency(C++11 STL only), good portability, header-only, deep neural networks for embedded
Low dependency(C++11 STL only), good portability, header-only, deep neural networks for embedded

LKYDeepNN LKYDeepNN 可訓練的深度類神經網路 (Deep Neural Network) 函式庫。 輕量,核心部份只依賴 C++11 標準函式庫,低相依性、好移植,方便在嵌入式系統上使用。 Class diagram 附有訓練視覺化 demo 程式 訓練視覺化程式以 OpenCV

Nov 7, 2022
The Atomic Game Engine is a multi-platform 2D and 3D engine with a consistent API in C++, C#, JavaScript, and TypeScript
The Atomic Game Engine is a multi-platform 2D and 3D engine with a consistent API in C++, C#, JavaScript, and TypeScript

The Atomic Game Engine is a multi-platform 2D and 3D engine with a consistent API in C++, C#, JavaScript, and TypeScript

Nov 15, 2022
dqlite is a C library that implements an embeddable and replicated SQL database engine with high-availability and automatic failover

dqlite dqlite is a C library that implements an embeddable and replicated SQL database engine with high-availability and automatic failover. The acron

Nov 23, 2022
Stealthy way to hijack the existing game process handle within the game launcher (currently supports Steam and Battle.net). Achieve external game process read/write with minimum footprint.
Stealthy way to hijack the existing game process handle within the game launcher (currently supports Steam and Battle.net). Achieve external game process read/write with minimum footprint.

Launcher Abuser Stealthy way to hijack the existing game process handle within the game launcher (currently supports Steam and Battle.net). Achieve ex

Nov 23, 2022
32Kb, small memory footprint, single binary that run list of commands in parallel and waits for their termination
32Kb, small memory footprint, single binary that run list of commands in parallel and waits for their termination

await 32K, small memory footprint, single binary that run list of commands in parallel and waits for their termination documentation linux install cur

Oct 2, 2022
Very low footprint JSON parser written in portable ANSI C

Very low footprint JSON parser written in portable ANSI C. BSD licensed with no dependencies (i.e. just drop the C file into your project) Never recur

Nov 15, 2022