├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── bin └── secureworker-create ├── binding.gyp ├── duk_enclave ├── duk_enclave.config.xml ├── duk_enclave.cpp ├── duk_enclave.edl ├── duk_enclave.vcxproj └── duk_enclave.vcxproj.filters ├── duktape-1.4.0 ├── AUTHORS.rst ├── LICENSE.txt ├── Makefile.cmdline ├── Makefile.codepage ├── Makefile.coffee ├── Makefile.dukdebug ├── Makefile.eval ├── Makefile.eventloop ├── Makefile.hello ├── Makefile.jxpretty ├── Makefile.sandbox ├── Makefile.sharedlibrary ├── README.rst ├── config │ ├── README.rst │ ├── duk_config.h-modular-dll │ ├── duk_config.h-modular-static │ ├── genconfig.py │ └── genconfig_metadata.tar.gz ├── debugger │ ├── Makefile │ ├── README.rst │ ├── duk_classnames.yaml │ ├── duk_debug.js │ ├── duk_debugcommands.yaml │ ├── duk_opcodes.yaml │ ├── package.json │ └── static │ │ ├── index.html │ │ ├── style.css │ │ └── webui.js ├── duk_build_meta.json ├── duktape.vcxproj ├── duktape.vcxproj.filters ├── examples │ ├── README.rst │ ├── alloc-hybrid │ │ ├── README.rst │ │ ├── duk_alloc_hybrid.c │ │ └── duk_alloc_hybrid.h │ ├── alloc-logging │ │ ├── README.rst │ │ ├── duk_alloc_logging.c │ │ ├── duk_alloc_logging.h │ │ └── log2gnuplot.py │ ├── alloc-torture │ │ ├── README.rst │ │ ├── duk_alloc_torture.c │ │ └── duk_alloc_torture.h │ ├── cmdline │ │ ├── README.rst │ │ ├── duk_cmdline.c │ │ └── duk_cmdline_ajduk.c │ ├── codepage-conv │ │ ├── README.rst │ │ ├── duk_codepage_conv.c │ │ ├── duk_codepage_conv.h │ │ └── test.c │ ├── coffee │ │ ├── README.rst │ │ ├── globals.coffee │ │ ├── hello.coffee │ │ └── mandel.coffee │ ├── cpp-exceptions │ │ ├── README.rst │ │ └── cpp_exceptions.cpp │ ├── debug-trans-dvalue │ │ ├── Makefile │ │ ├── README.rst │ │ ├── duk_trans_dvalue.c │ │ ├── duk_trans_dvalue.h │ │ └── test.c │ ├── debug-trans-socket │ │ ├── README.rst │ │ ├── duk_trans_socket.c │ │ └── duk_trans_socket.h │ ├── dummy-date-provider │ │ ├── README.rst │ │ └── dummy_date_provider.c │ ├── eval │ │ ├── README.rst │ │ └── eval.c │ ├── eventloop │ │ ├── README.rst │ │ ├── basic-test.js │ │ ├── c_eventloop.c │ │ ├── c_eventloop.js │ │ ├── client-socket-test.js │ │ ├── curses-timers.js │ │ ├── ecma_eventloop.js │ │ ├── fileio.c │ │ ├── main.c │ │ ├── ncurses.c │ │ ├── poll.c │ │ ├── server-socket-test.js │ │ └── socket.c │ ├── guide │ │ ├── README.rst │ │ ├── fib.js │ │ ├── prime.js │ │ ├── primecheck.c │ │ ├── process.js │ │ ├── processlines.c │ │ └── uppercase.c │ ├── hello │ │ ├── README.rst │ │ └── hello.c │ ├── jxpretty │ │ ├── README.rst │ │ └── jxpretty.c │ └── sandbox │ │ ├── README.rst │ │ └── sandbox.c ├── extras │ └── README.rst ├── license.spdx ├── licenses │ ├── commonjs.txt │ ├── lua.txt │ └── murmurhash2.txt ├── mandel.js ├── polyfills │ ├── console-minimal.js │ ├── duktape-error-setter-nonwritable.js │ ├── duktape-error-setter-writable.js │ ├── duktape-isfastint.js │ ├── object-assign.js │ ├── object-prototype-definegetter.js │ ├── object-prototype-definesetter.js │ └── performance-now.js ├── src-noline │ ├── duk_config.h │ ├── duktape.c │ ├── duktape.h │ └── metadata.json ├── src-separate │ ├── duk_alloc_default.c │ ├── duk_api_buffer.c │ ├── duk_api_bytecode.c │ ├── duk_api_call.c │ ├── duk_api_codec.c │ ├── duk_api_compile.c │ ├── duk_api_debug.c │ ├── duk_api_heap.c │ ├── duk_api_internal.h │ ├── duk_api_logging.c │ ├── duk_api_memory.c │ ├── duk_api_object.c │ ├── duk_api_stack.c │ ├── duk_api_string.c │ ├── duk_api_var.c │ ├── duk_bi_array.c │ ├── duk_bi_boolean.c │ ├── duk_bi_buffer.c │ ├── duk_bi_date.c │ ├── duk_bi_date_sgx.c │ ├── duk_bi_date_unix.c │ ├── duk_bi_date_windows.c │ ├── duk_bi_duktape.c │ ├── duk_bi_error.c │ ├── duk_bi_function.c │ ├── duk_bi_global.c │ ├── duk_bi_json.c │ ├── duk_bi_logger.c │ ├── duk_bi_math.c │ ├── duk_bi_number.c │ ├── duk_bi_object.c │ ├── duk_bi_pointer.c │ ├── duk_bi_protos.h │ ├── duk_bi_proxy.c │ ├── duk_bi_regexp.c │ ├── duk_bi_string.c │ ├── duk_bi_thread.c │ ├── duk_bi_thrower.c │ ├── duk_builtins.c │ ├── duk_builtins.h │ ├── duk_config.h │ ├── duk_debug.h │ ├── duk_debug_fixedbuffer.c │ ├── duk_debug_heap.c │ ├── duk_debug_macros.c │ ├── duk_debug_vsnprintf.c │ ├── duk_debugger.c │ ├── duk_debugger.h │ ├── duk_error.h │ ├── duk_error_augment.c │ ├── duk_error_longjmp.c │ ├── duk_error_macros.c │ ├── duk_error_misc.c │ ├── duk_error_throw.c │ ├── duk_exception.h │ ├── duk_forwdecl.h │ ├── duk_hbuffer.h │ ├── duk_hbuffer_alloc.c │ ├── duk_hbuffer_ops.c │ ├── duk_hbufferobject.h │ ├── duk_hbufferobject_misc.c │ ├── duk_hcompiledfunction.h │ ├── duk_heap.h │ ├── duk_heap_alloc.c │ ├── duk_heap_hashstring.c │ ├── duk_heap_markandsweep.c │ ├── duk_heap_memory.c │ ├── duk_heap_misc.c │ ├── duk_heap_refcount.c │ ├── duk_heap_stringcache.c │ ├── duk_heap_stringtable.c │ ├── duk_heaphdr.h │ ├── duk_hnativefunction.h │ ├── duk_hobject.h │ ├── duk_hobject_alloc.c │ ├── duk_hobject_class.c │ ├── duk_hobject_enum.c │ ├── duk_hobject_finalizer.c │ ├── duk_hobject_misc.c │ ├── duk_hobject_pc2line.c │ ├── duk_hobject_props.c │ ├── duk_hstring.h │ ├── duk_hstring_misc.c │ ├── duk_hthread.h │ ├── duk_hthread_alloc.c │ ├── duk_hthread_builtins.c │ ├── duk_hthread_misc.c │ ├── duk_hthread_stacks.c │ ├── duk_initjs_min.js │ ├── duk_internal.h │ ├── duk_jmpbuf.h │ ├── duk_js.h │ ├── duk_js_bytecode.h │ ├── duk_js_call.c │ ├── duk_js_compiler.c │ ├── duk_js_compiler.h │ ├── duk_js_executor.c │ ├── duk_js_ops.c │ ├── duk_js_var.c │ ├── duk_json.h │ ├── duk_lexer.c │ ├── duk_lexer.h │ ├── duk_numconv.c │ ├── duk_numconv.h │ ├── duk_regexp.h │ ├── duk_regexp_compiler.c │ ├── duk_regexp_executor.c │ ├── duk_replacements.c │ ├── duk_replacements.h │ ├── duk_selftest.c │ ├── duk_selftest.h │ ├── duk_strings.c │ ├── duk_strings.h │ ├── duk_tval.c │ ├── duk_tval.h │ ├── duk_unicode.h │ ├── duk_unicode_support.c │ ├── duk_unicode_tables.c │ ├── duk_util.h │ ├── duk_util_bitdecoder.c │ ├── duk_util_bitencoder.c │ ├── duk_util_bufwriter.c │ ├── duk_util_hashbytes.c │ ├── duk_util_hashprime.c │ ├── duk_util_misc.c │ ├── duk_util_tinyrandom.c │ └── duktape.h └── src │ ├── duk_config.h │ ├── duktape.c │ ├── duktape.h │ └── metadata.json ├── duktape.sln ├── enclave-autoexec └── index.js ├── lib ├── index.js ├── message-port.js ├── mock.js └── real.js ├── node-secureworker-internal ├── node-secureworker-internal.vcxproj ├── node-secureworker-internal.vcxproj.filters └── secureworker-internal.cc ├── package-lock.json ├── package.json ├── scripts ├── generate-scripts-data.sh ├── generate-scripts-table.sh ├── scripts.h ├── scripts.vcxproj └── scripts.vcxproj.filters ├── secureworker-logo.png └── tests ├── run.js ├── test-commands.js └── test.js /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019, Evervault Limited. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of the PeerLibrary Project nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /bin/secureworker-create: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var child_process = require('child_process'); 4 | var path = require('path'); 5 | 6 | var argv = require('yargs') 7 | .usage('Usage: $0 [options] \n\nIncludes specified JavaScript scripts into a signed enclave .so file.') 8 | 9 | .help('help', false) 10 | .alias('h', 'help') 11 | 12 | .describe('output', "Output path for signed enclave object") 13 | .string('output') 14 | .default('output', 'enclave.so') 15 | .demandOption('output') 16 | .alias('o', 'output') 17 | 18 | .describe('key', "Path to the key for enclave signing (will be created if missing)") 19 | .default('key', 'key.pem') 20 | .string('key') 21 | .alias('k', 'key') 22 | 23 | .describe('config', "Path to the config for enclave signing (will be created with defaults if missing)") 24 | .default('config', 'enclave.config.xml') 25 | .string('config') 26 | .alias('c', 'config') 27 | 28 | .demandCommand(1, "Scripts missing. At least one script to include in the enclave has to be specified.") 29 | 30 | .argv; 31 | 32 | var base = path.normalize(path.join(path.dirname(require.resolve('../lib/index.js')), '..')); 33 | 34 | child_process.execFileSync('make', [ 35 | 'enclave', 36 | 'SCRIPTS=' + argv._.map(function (script) {return path.resolve(script);}).join(' '), 37 | 'ENCLAVE_KEY=' + path.resolve(argv.key), 38 | 'ENCLAVE_CONFIG=' + path.resolve(argv.config), 39 | 'ENCLAVE_OUTPUT=' + path.resolve(argv.output) 40 | ], { 41 | cwd: base, 42 | stdio: 'inherit', 43 | encoding: 'utf8' 44 | }); -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | "targets": [ 3 | { 4 | "target_name": "secureworker_internal", 5 | "sources": [ 6 | "node-secureworker-internal/secureworker-internal.cc", 7 | "../duk_enclave/duk_enclave_u.o", 8 | ], 9 | "cflags": [ 10 | "-std=c++11", 11 | "-g", 12 | ], 13 | "cflags_cc!": [ 14 | "-fno-exceptions", 15 | ], 16 | "include_dirs": [ 17 | "$(SGX_SDK)/include", 18 | "duk_enclave", 19 | " 2 | 0 3 | 0 4 | 0x40000 5 | 0x100000 6 | 1 7 | 1 8 | 0 9 | 0 10 | 0xFFFFFFFF 11 | 12 | -------------------------------------------------------------------------------- /duk_enclave/duk_enclave.edl: -------------------------------------------------------------------------------- 1 | enclave { 2 | from "sgx_tkey_exchange.edl" import *; 3 | include "sgx_key_exchange.h" 4 | include "sgx_report.h" 5 | include "sgx_tseal.h" 6 | 7 | trusted { 8 | /* define ECALLs here. */ 9 | public void duk_enclave_init([in, string] const char *key); 10 | public void duk_enclave_close(); 11 | public void duk_enclave_emit_message([in, string] const char *message); 12 | public void duk_enclave_init_ra([out] sgx_ra_context_t *ra_context, int pse); 13 | public void duk_enclave_bootstrap_ra( 14 | sgx_ra_context_t ra_context, 15 | [out, size=out_size] sgx_sealed_data_t *out, size_t out_size, 16 | [in, size=iv_size] const uint8_t *iv, size_t iv_size, 17 | [in, size=additional_data_size] const uint8_t *additional_data, size_t additional_data_size, 18 | [in, size=data_size] const uint8_t *data, size_t data_size, 19 | [in] sgx_aes_gcm_128bit_key_t *tag 20 | ); 21 | public void duk_enclave_bootstrap_mock( 22 | [out, size=out_size] sgx_sealed_data_t *out, size_t out_size, 23 | [in, size=additional_data_size] const uint8_t *additional_data, size_t additional_data_size, 24 | [in, size=data_size] const uint8_t *clear, size_t data_size 25 | ); 26 | }; 27 | 28 | untrusted { 29 | /* define OCALLs here. */ 30 | void duk_enclave_post_message([in, string] const char *message); 31 | sgx_status_t duk_enclave_init_quote([out] sgx_target_info_t *target_info, [out] sgx_epid_group_id_t *gid); 32 | void duk_enclave_debug([in, string] const char *message); 33 | }; 34 | }; 35 | -------------------------------------------------------------------------------- /duk_enclave/duk_enclave.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {ba37224a-f176-4fde-86e2-f1cfe0488f5d} 6 | 7 | 8 | {07318645-d360-49b5-a399-1cb9627090fd} 9 | cpp;c;edl;def; .. and other options 10 | 11 | 12 | {c4a1f197-0396-456e-ab1a-5af9765a1e68} 13 | h;hpp; .. and other options 14 | 15 | 16 | {ddd4f6a8-a3fa-4173-9df9-9eb364936d62} 17 | rc;xml;pem; .. and other options 18 | 19 | 20 | 21 | 22 | Generated Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | 29 | 30 | Generated Files 31 | 32 | 33 | 34 | 35 | Resource Files 36 | 37 | 38 | 39 | 40 | Resource Files 41 | 42 | 43 | 44 | 45 | Source Files 46 | 47 | 48 | -------------------------------------------------------------------------------- /duktape-1.4.0/AUTHORS.rst: -------------------------------------------------------------------------------- 1 | =============== 2 | Duktape authors 3 | =============== 4 | 5 | Copyright 6 | ========= 7 | 8 | Duktape copyrights are held by its authors. Each author has a copyright 9 | to their contribution, and agrees to irrevocably license the contribution 10 | under the Duktape ``LICENSE.txt``. 11 | 12 | Authors 13 | ======= 14 | 15 | Please include an e-mail address, a link to your GitHub profile, or something 16 | similar to allow your contribution to be identified accurately. 17 | 18 | The following people have contributed code, website contents, or Wiki contents, 19 | and agreed to irrevocably license their contributions under the Duktape 20 | ``LICENSE.txt`` (in order of appearance): 21 | 22 | * Sami Vaarala 23 | * Niki Dobrev 24 | * Andreas Öman 25 | * László Langó 26 | * Legimet 27 | * Karl Skomski 28 | * Bruce Pascoe 29 | * René Hollander 30 | 31 | Other contributions 32 | =================== 33 | 34 | The following people have contributed something other than code (e.g. reported 35 | bugs, provided ideas, etc; roughly in order of appearance): 36 | 37 | * Greg Burns 38 | * Anthony Rabine 39 | * Carlos Costa 40 | * Aurélien Bouilland 41 | * Preet Desai (Pris Matic) 42 | * judofyr (http://www.reddit.com/user/judofyr) 43 | * Jason Woofenden 44 | * Michał Przybyś 45 | * Anthony Howe 46 | * Conrad Pankoff 47 | * Jim Schimpf 48 | * Rajaran Gaunker (https://github.com/zimbabao) 49 | * Andreas Öman 50 | * Doug Sanden 51 | * Josh Engebretson (https://github.com/JoshEngebretson) 52 | * Remo Eichenberger (https://github.com/remoe) 53 | * Mamod Mehyar (https://github.com/mamod) 54 | * David Demelier (https://github.com/markand) 55 | * Tim Caswell (https://github.com/creationix) 56 | * Mitchell Blank Jr (https://github.com/mitchblank) 57 | * https://github.com/yushli 58 | * Seo Sanghyeon (https://github.com/sanxiyn) 59 | * Han ChoongWoo (https://github.com/tunz) 60 | * Joshua Peek (https://github.com/josh) 61 | * Bruce E. Pascoe (https://github.com/fatcerberus) 62 | * https://github.com/Kelledin 63 | * https://github.com/sstruchtrup 64 | * Michael Drake (https://github.com/tlsa) 65 | * https://github.com/chris-y 66 | * Laurent Zubiaur (https://github.com/lzubiaur) 67 | 68 | If you are accidentally missing from this list, send me an e-mail 69 | (``sami.vaarala@iki.fi``) and I'll fix the omission. 70 | -------------------------------------------------------------------------------- /duktape-1.4.0/LICENSE.txt: -------------------------------------------------------------------------------- 1 | =============== 2 | Duktape license 3 | =============== 4 | 5 | (http://opensource.org/licenses/MIT) 6 | 7 | Copyright (c) 2013-2016 by Duktape authors (see AUTHORS.rst) 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in 17 | all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /duktape-1.4.0/Makefile.cmdline: -------------------------------------------------------------------------------- 1 | # 2 | # Example Makefile for building a program with embedded Duktape. 3 | # The example program here is the Duktape command line tool. 4 | # 5 | 6 | DUKTAPE_SOURCES = src/duktape.c 7 | 8 | DUKTAPE_CMDLINE_SOURCES = \ 9 | examples/cmdline/duk_cmdline.c 10 | 11 | CC = gcc 12 | CCOPTS = -Os -pedantic -std=c99 -Wall -fstrict-aliasing -fomit-frame-pointer 13 | CCOPTS += -I./src # duktape.h and duk_config.h must be in include path 14 | CCLIBS = -lm 15 | 16 | # If you have readline, you may want to enable these. On some platforms 17 | # -lreadline also requires -lncurses (e.g. RHEL), so it is added by default 18 | # (you may be able to remove it) 19 | #CCOPTS += -DDUK_CMDLINE_FANCY 20 | #CCLIBS += -lreadline 21 | #CCLIBS += -lncurses 22 | 23 | # Optional feature defines, see: http://duktape.org/guide.html#compiling 24 | CCOPTS += -DDUK_OPT_SELF_TESTS 25 | #CCOPTS += -DDUK_OPT_DEBUG 26 | #CCOPTS += -DDUK_OPT_DPRINT 27 | # ... 28 | 29 | duk: $(DUKTAPE_SOURCES) $(DUKTAPE_CMDLINE_SOURCES) 30 | $(CC) -o $@ $(DEFINES) $(CCOPTS) $(DUKTAPE_SOURCES) $(DUKTAPE_CMDLINE_SOURCES) $(CCLIBS) 31 | -------------------------------------------------------------------------------- /duktape-1.4.0/Makefile.codepage: -------------------------------------------------------------------------------- 1 | codepage: 2 | gcc -o $@ -std=c99 -O2 -Wall -Wextra -Isrc/ \ 3 | src/duktape.c examples/codepage-conv/duk_codepage_conv.c \ 4 | examples/codepage-conv/test.c -lm 5 | -------------------------------------------------------------------------------- /duktape-1.4.0/Makefile.coffee: -------------------------------------------------------------------------------- 1 | dummy: 2 | coffee -c examples/coffee/globals.coffee 3 | coffee -c examples/coffee/hello.coffee 4 | coffee -c examples/coffee/mandel.coffee 5 | -------------------------------------------------------------------------------- /duktape-1.4.0/Makefile.dukdebug: -------------------------------------------------------------------------------- 1 | # 2 | # Duktape command line tool with debugger support. 3 | # 4 | 5 | DUKTAPE_SOURCES = src/duktape.c 6 | 7 | DUKTAPE_CMDLINE_SOURCES = \ 8 | examples/cmdline/duk_cmdline.c \ 9 | examples/debug-trans-socket/duk_trans_socket.c 10 | 11 | CC = gcc 12 | CCOPTS = -Os -pedantic -std=c99 -Wall -fstrict-aliasing -fomit-frame-pointer 13 | CCOPTS += -I./src -I./examples/debug-trans-socket 14 | CCOPTS += -DDUK_CMDLINE_DEBUGGER_SUPPORT # enable --debugger in ./duk 15 | CCOPTS += -DDUK_OPT_DEBUGGER_SUPPORT # enable debugger support in Duktape 16 | CCOPTS += -DDUK_OPT_INTERRUPT_COUNTER # prerequisite for debugging 17 | CCOPTS += -DDUK_OPT_DEBUGGER_FWD_PRINTALERT # optional debugger features 18 | CCOPTS += -DDUK_OPT_DEBUGGER_FWD_LOGGING 19 | CCOPTS += -DDUK_OPT_DEBUGGER_DUMPHEAP 20 | CCLIBS = -lm 21 | 22 | duk: $(DUKTAPE_SOURCES) $(DUKTAPE_CMDLINE_SOURCES) 23 | $(CC) -o $@ $(DEFINES) $(CCOPTS) $(DUKTAPE_SOURCES) $(DUKTAPE_CMDLINE_SOURCES) $(CCLIBS) 24 | -------------------------------------------------------------------------------- /duktape-1.4.0/Makefile.eval: -------------------------------------------------------------------------------- 1 | # 2 | # Example Makefile for building the eval example 3 | # 4 | 5 | eval: 6 | gcc -o $@ -std=c99 -O2 -Wall -Wextra -Isrc/ \ 7 | src/duktape.c examples/eval/eval.c -lm 8 | -------------------------------------------------------------------------------- /duktape-1.4.0/Makefile.eventloop: -------------------------------------------------------------------------------- 1 | # 2 | # Example Makefile for building the eventloop example 3 | # 4 | 5 | evloop: 6 | @echo "NOTE: The eventloop is example is intended to be used on Linux" 7 | @echo " or other common UNIX variants. It is not fully portable." 8 | @echo "" 9 | 10 | gcc -o $@ -std=c99 -Wall -Wextra -O2 -Isrc \ 11 | examples/eventloop/main.c \ 12 | examples/eventloop/c_eventloop.c \ 13 | examples/eventloop/poll.c \ 14 | examples/eventloop/socket.c \ 15 | examples/eventloop/fileio.c \ 16 | examples/eventloop/ncurses.c \ 17 | src/duktape.c \ 18 | -lm -lncurses 19 | 20 | @echo "" 21 | @echo "NOTE: You must 'cd examples/eventloop' before you execute the" 22 | @echo " eventloop binary: it relies on finding .js files in CWD" 23 | -------------------------------------------------------------------------------- /duktape-1.4.0/Makefile.hello: -------------------------------------------------------------------------------- 1 | # 2 | # Example Makefile for building a program with embedded Duktape. 3 | # 4 | # There are two source sets in the distribution: (1) combined sources where 5 | # you only need duktape.c, duktape.h, and duk_config.h, and (2) separate 6 | # sources where you have a bunch of source and header files. Whichever 7 | # you use, simply include the relevant sources into your C project. This 8 | # Makefile uses the combined source file. 9 | # 10 | 11 | DUKTAPE_SOURCES = src/duktape.c 12 | 13 | # Compiler options are quite flexible. GCC versions have a significant impact 14 | # on the size of -Os code, e.g. gcc-4.6 is much worse than gcc-4.5. 15 | 16 | CC = gcc 17 | CCOPTS = -Os -pedantic -std=c99 -Wall -fstrict-aliasing -fomit-frame-pointer 18 | CCOPTS += -I./src # for combined sources 19 | CCLIBS = -lm 20 | DEFINES = 21 | 22 | # If you want a 32-bit build on a 64-bit host 23 | #CCOPTS += -m32 24 | 25 | # Optional feature defines, see: http://duktape.org/guide.html#compiling 26 | DEFINES += -DDUK_OPT_SELF_TESTS 27 | #DEFINES += -DDUK_OPT_DEBUG 28 | #DEFINES += -DDUK_OPT_DPRINT 29 | #DEFINES += -DDUK_OPT_NO_TRACEBACKS 30 | # ... 31 | 32 | # For debugging, use -O0 -g -ggdb, and don't add -fomit-frame-pointer 33 | 34 | hello: $(DUKTAPE_SOURCES) examples/hello/hello.c 35 | $(CC) -o $@ $(DEFINES) $(CCOPTS) $(DUKTAPE_SOURCES) examples/hello/hello.c $(CCLIBS) 36 | -------------------------------------------------------------------------------- /duktape-1.4.0/Makefile.jxpretty: -------------------------------------------------------------------------------- 1 | # 2 | # Example Makefile for building the jxpretty example 3 | # 4 | 5 | jxpretty: 6 | gcc -o $@ -std=c99 -Wall -Wextra -O2 -Isrc \ 7 | src/duktape.c examples/jxpretty/jxpretty.c \ 8 | -lm 9 | -------------------------------------------------------------------------------- /duktape-1.4.0/Makefile.sandbox: -------------------------------------------------------------------------------- 1 | # 2 | # Example Makefile for building the sandbox example 3 | # 4 | 5 | sandbox: 6 | gcc -o $@ -std=c99 -O2 -Wall -Wextra -Isrc/ \ 7 | src/duktape.c examples/sandbox/sandbox.c -lm 8 | -------------------------------------------------------------------------------- /duktape-1.4.0/Makefile.sharedlibrary: -------------------------------------------------------------------------------- 1 | # 2 | # Example of how to build and install locally as a shared library 3 | # 4 | # Usage: 5 | # 6 | # $ make -f Makefile.sharedlibrary 7 | # $ sudo make -f Makefile.sharedlibrary install 8 | # $ make -f Makefile.sharedlibrary duk # --> example 'duk' linked to shared libduktape 9 | # 10 | # $ ls -l duk 11 | # -rwxrwxr-x 1 duktape duktape 19407 Nov 30 15:48 duk 12 | # 13 | # $ ldd ./duk 14 | # linux-vdso.so.1 => (0x00007ffd5ed3c000) 15 | # libduktape.so.104 => /usr/local/lib/libduktape.so.104 (0x00007fb2f9753000) 16 | # libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fb2f944d000) 17 | # libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb2f9088000) 18 | # /lib64/ld-linux-x86-64.so.2 (0x00007fb2f9991000) 19 | # 20 | # Based on: http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html 21 | 22 | # Soname version must be bumped whenever a binary compatibility change occurs 23 | # (and should not be bumped when the library is compatible). A simple Duktape 24 | # convention is to set soname version to (100*MAJOR + MINOR), e.g. 104 for 25 | # Duktape 1.4.x, so that it gets automatically bumped for major and minor 26 | # releases (potentially binary incompatible), but not for patch releases. 27 | DUK_VERSION=10400 28 | SONAME_VERSION=104 29 | REAL_VERSION=$(SONAME_VERSION).$(DUK_VERSION) 30 | 31 | # Change to actual path for actual distribution packaging. 32 | INSTALL_PREFIX=/usr/local 33 | 34 | # The 'noline' variant may be more appropriate for some distributions; it 35 | # doesn't have #line directives in the combined source. 36 | DUKTAPE_SRCDIR=./src 37 | #DUKTAPE_SRCDIR=./src-noline 38 | 39 | .PHONY: all 40 | all: libduktape.so.$(REAL_VERSION) libduktaped.so.$(REAL_VERSION) 41 | 42 | # If the default duk_config.h is not suitable for the distribution, modify it 43 | # before compiling the shared library and copy the same, edited duk_config.h 44 | # to $INSTALL_PREFIX/include on installation. 45 | 46 | libduktape.so.$(REAL_VERSION): 47 | gcc -shared -fPIC -Wall -Wextra -Os -Wl,-soname,libduktape.so.$(SONAME_VERSION) \ 48 | -o $@ $(DUKTAPE_SRCDIR)/duktape.c 49 | 50 | libduktaped.so.$(REAL_VERSION): 51 | gcc -shared -fPIC -g -Wall -Wextra -Os -Wl,-soname,libduktaped.so.$(SONAME_VERSION) \ 52 | -o $@ $(DUKTAPE_SRCDIR)/duktape.c 53 | 54 | # Symlinks depend on platform conventions. 55 | .PHONY: install 56 | install: libduktape.so.$(REAL_VERSION) libduktaped.so.$(REAL_VERSION) 57 | cp $+ $(INSTALL_PREFIX)/lib/ 58 | rm -f $(INSTALL_PREFIX)/lib/libduktape.so $(INSTALL_PREFIX)/lib/libduktape.so.$(SONAME_VERSION) 59 | ln -s libduktape.so.$(REAL_VERSION) $(INSTALL_PREFIX)/lib/libduktape.so 60 | ln -s libduktape.so.$(REAL_VERSION) $(INSTALL_PREFIX)/lib/libduktape.so.$(SONAME_VERSION) 61 | rm -f $(INSTALL_PREFIX)/lib/libduktaped.so $(INSTALL_PREFIX)/lib/libduktaped.so.$(SONAME_VERSION) 62 | ln -s libduktaped.so.$(REAL_VERSION) $(INSTALL_PREFIX)/lib/libduktaped.so 63 | ln -s libduktaped.so.$(REAL_VERSION) $(INSTALL_PREFIX)/lib/libduktaped.so.$(SONAME_VERSION) 64 | cp $(DUKTAPE_SRCDIR)/duktape.h $(DUKTAPE_SRCDIR)/duk_config.h $(INSTALL_PREFIX)/include/ 65 | 66 | # Note: assumes /usr/local/include/ and /usr/local/lib/ are in include/link 67 | # path which may not be the case for all distributions. 68 | #CCOPTS=-I/usr/local/include -L/usr/local/lib 69 | CCOPTS= 70 | duk: 71 | gcc $(CCOPTS) -Wall -Wextra -Os -o $@ ./examples/cmdline/duk_cmdline.c -lduktape -lm 72 | -------------------------------------------------------------------------------- /duktape-1.4.0/README.rst: -------------------------------------------------------------------------------- 1 | ======= 2 | Duktape 3 | ======= 4 | 5 | Duktape is a small and portable Ecmascript E5/E5.1 implementation. It is 6 | intended to be easily embeddable into C programs, with a C API similar in 7 | spirit to Lua's. 8 | 9 | Duktape supports the full E5/E5.1 feature set including errors, Unicode 10 | strings, and regular expressions, a subset of E6 features (e.g. Proxy 11 | objects), Khronos/ES6 ArrayBuffer/TypedView, and Node.js Buffer bindings. 12 | 13 | Duktape also provides a number of custom features such as error tracebacks, 14 | additional data types for better C integration, combined reference counting 15 | and mark-and sweep garbage collector, object finalizers, co-operative 16 | threads a.k.a. coroutines, tail calls, built-in logging and module frameworks, 17 | a built-in debugger protocol, function bytecode dump/load, and so on. 18 | 19 | You can browse Duktape programmer's API and other documentation at: 20 | 21 | * http://duktape.org/ 22 | 23 | In particular, you should read the getting started section: 24 | 25 | * http://duktape.org/guide.html#gettingstarted 26 | 27 | More examples and how-to articles are in the Duktape Wiki: 28 | 29 | * http://wiki.duktape.org/ 30 | 31 | Building and integrating Duktape into your project is very straightforward: 32 | 33 | * http://duktape.org/guide.html#compiling 34 | 35 | See Makefile.hello for a concrete example:: 36 | 37 | $ cd 38 | $ make -f Makefile.hello 39 | [...] 40 | $ ./hello 41 | Hello world! 42 | 2+3=5 43 | 44 | To build an example command line tool, use the following:: 45 | 46 | $ cd 47 | $ make -f Makefile.cmdline 48 | [...] 49 | 50 | $ ./duk 51 | ((o) Duktape 52 | duk> print('Hello world!'); 53 | Hello world! 54 | = undefined 55 | 56 | $ ./duk mandel.js 57 | [...] 58 | 59 | This distributable contains: 60 | 61 | * ``src/``: main Duktape library in a "single source file" format (duktape.c, 62 | duktape.h, and duk_config.h). 63 | 64 | * ``src-noline/``: contains a variant of ``src/duktape.c`` with no ``#line`` 65 | directives which is preferable for some users. See discussion in 66 | https://github.com/svaarala/duktape/pull/363. 67 | 68 | * ``src-separate/``: main Duktape library in multiple files format. 69 | 70 | * ``config/``: genconfig utility for creating duk_config.h configuration 71 | files, see: http://wiki.duktape.org/Configuring.html. 72 | 73 | * ``examples/``: further examples for using Duktape. Although Duktape 74 | itself is widely portable, some of the examples are Linux only. 75 | For instance the ``eventloop`` example illustrates how ``setTimeout()`` 76 | and other standard timer functions could be implemented on Unix/Linux. 77 | 78 | * ``extras/``: utilities and modules which don't comfortably fit into the 79 | main Duktape library because of footprint or portability concerns. 80 | Extras are maintained and bug fixed code, but don't have the same version 81 | guarantees as the main Duktape library. 82 | 83 | * ``polyfills/``: a few replacement suggestions for non-standard Javascript 84 | functions provided by other implementations. 85 | 86 | * ``debugger/``: a debugger with a web UI, see ``debugger/README.rst`` and 87 | https://github.com/svaarala/duktape/blob/master/doc/debugger.rst for 88 | details on Duktape debugger support. 89 | 90 | * ``licenses/``: licensing information. 91 | 92 | You can find release notes at: 93 | 94 | * https://github.com/svaarala/duktape/blob/master/RELEASES.rst 95 | 96 | This distributable contains Duktape version 1.4.0, created from git 97 | commit cad6f595382a0cc1a7e4207794ade5be11b3e397 (v1.4.0). 98 | 99 | Duktape is copyrighted by its authors (see ``AUTHORS.rst``) and licensed 100 | under the MIT license (see ``LICENSE.txt``). String hashing algorithms are 101 | based on the algorithm from Lua (MIT license), djb2 hash, and Murmurhash2 102 | (MIT license). Duktape module loader is based on the CommonJS module 103 | loading specification (without sharing any code), CommonJS is under the 104 | MIT license. 105 | 106 | Have fun! 107 | 108 | Sami Vaarala (sami.vaarala@iki.fi) 109 | -------------------------------------------------------------------------------- /duktape-1.4.0/config/README.rst: -------------------------------------------------------------------------------- 1 | ================= 2 | Duktape genconfig 3 | ================= 4 | 5 | Overview 6 | ======== 7 | 8 | ``genconfig`` is a helper script for coming up with a ``duk_config.h`` for 9 | compiling Duktape for your platform. 10 | 11 | To support this: 12 | 13 | * It creates a Duktape 1.2.x compatible ``duk_config.h`` with automatic 14 | platform detection and ``DUK_OPT_xxx`` feature options. 15 | 16 | * It helps to create a ``duk_config.h`` for your platform/compiler 17 | combination. You can give a base configuration and then force certain 18 | values manually based on a YAML configuration file. 19 | 20 | * It autogenerates documentation for config options (and Duktape 1.2.x 21 | feature options) based on option metadata files written in YAML. 22 | 23 | Usage 24 | ===== 25 | 26 | To create an autodetect duk_config.h header (compatible with Duktape 1.2.x):: 27 | 28 | $ python config/genconfig.py --metadata config --output /tmp/duk_config.h \ 29 | autodetect-header 30 | 31 | To create a barebones duk_config.h header for a specific platform (easier to 32 | edit manually):: 33 | 34 | $ python config/genconfig.py --metadata config --output /tmp/duk_config.h \ 35 | --platform linux --compiler gcc --architecture x64 \ 36 | barebones-header 37 | 38 | There are further commands to e.g. autogenerate config option documentation; 39 | see ``genconfig.py`` for details. 40 | -------------------------------------------------------------------------------- /duktape-1.4.0/config/genconfig_metadata.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evervault/node-secureworker/5b7a4579bc056c0f8bb2a9987512579cc76d7517/duktape-1.4.0/config/genconfig_metadata.tar.gz -------------------------------------------------------------------------------- /duktape-1.4.0/debugger/Makefile: -------------------------------------------------------------------------------- 1 | NODE:=$(shell which nodejs node | head -1) 2 | 3 | # Try to get a useful default --source-dirs which works both in the Duktape 4 | # repo and in the distributable. We don't want to add '..' because it would 5 | # scan a lot of undesired files in the Duktape repo (e.g. test262 testcases). 6 | ifeq ($(wildcard ../tests/ecmascript/*.js),) 7 | SOURCEDIRS:=../ 8 | else 9 | SOURCEDIRS:=../tests/ecmascript 10 | endif 11 | 12 | .PHONY: all 13 | all: run 14 | 15 | .PHONY: run 16 | run: node_modules static/socket.io-1.2.0.js static/jquery-1.11.1.min.js static/reset.css static/jquery-ui.min.js static/jquery-ui.min.css static/images 17 | $(NODE) duk_debug.js --source-dirs=$(SOURCEDIRS) 18 | 19 | rundebug: node_modules static/socket.io-1.2.0.js static/jquery-1.11.1.min.js static/reset.css static/jquery-ui.min.js static/jquery-ui.min.css static/images 20 | $(NODE) duk_debug.js --source-dirs=$(SOURCEDIRS) --verbose --log-messages /tmp/dukdebug-messages --dump-debug-pretty /tmp/dukdebug-pretty 21 | 22 | .PHONY: runproxy 23 | runproxy: node_modules static/socket.io-1.2.0.js static/jquery-1.11.1.min.js static/reset.css static/jquery-ui.min.js static/jquery-ui.min.css static/images 24 | $(NODE) duk_debug.js --json-proxy 25 | 26 | .PHONY: clean 27 | clean: 28 | @rm -f static/socket.io-1.2.0.js 29 | @rm -f static/jquery-1.11.1.min.js 30 | @rm -f static/jquery.syntaxhighlighter.min.js 31 | @rm -f static/jquery.snippet.min.js 32 | @rm -f static/jquery.snippet.min.css 33 | @rm -f static/prefixfree.min.js 34 | @rm -f static/reset.css 35 | @rm -f static/jquery-ui.min.js 36 | @rm -f static/jquery-ui.min.css 37 | @rm -rf static/images 38 | @rm -f jquery-ui-1.11.2.zip 39 | @rm -rf jquery-ui-1.11.2 40 | @rm -rf node_modules 41 | 42 | node_modules: 43 | npm install 44 | 45 | static/socket.io-1.2.0.js: 46 | wget -O $@ https://cdn.socket.io/socket.io-1.2.0.js 47 | 48 | static/jquery-1.11.1.min.js: 49 | wget -O $@ http://code.jquery.com/jquery-1.11.1.min.js 50 | 51 | # http://balupton.github.io/jquery-syntaxhighlighter/demo/ 52 | static/jquery.syntaxhighlighter.min.js: 53 | wget -O $@ http://balupton.github.com/jquery-syntaxhighlighter/scripts/jquery.syntaxhighlighter.min.js 54 | 55 | # http://steamdev.com/snippet/ 56 | static/jquery.snippet.min.js: 57 | wget -O $@ http://steamdev.com/snippet/js/jquery.snippet.min.js 58 | static/jquery.snippet.min.css: 59 | wget -O $@ http://steamdev.com/snippet/css/jquery.snippet.min.css 60 | 61 | # http://prismjs.com/ 62 | # http://prismjs.com/plugins/line-highlight/ 63 | # 64 | # XXX: prism download manually? 65 | 66 | # https://raw.github.com/LeaVerou/prefixfree/gh-pages/prefixfree.min.js 67 | static/prefixfree.min.js: 68 | wget -O $@ https://raw.github.com/LeaVerou/prefixfree/gh-pages/prefixfree.min.js 69 | 70 | # http://meyerweb.com/eric/tools/css/reset/ 71 | static/reset.css: 72 | wget -O $@ http://meyerweb.com/eric/tools/css/reset/reset.css 73 | 74 | jquery-ui-1.11.2.zip: 75 | wget -O $@ http://jqueryui.com/resources/download/jquery-ui-1.11.2.zip 76 | jquery-ui-1.11.2: jquery-ui-1.11.2.zip 77 | unzip $< 78 | static/jquery-ui.min.js: jquery-ui-1.11.2 79 | cp jquery-ui-1.11.2/jquery-ui.min.js $@ 80 | static/jquery-ui.min.css: jquery-ui-1.11.2 81 | cp jquery-ui-1.11.2/jquery-ui.min.css $@ 82 | static/images: jquery-ui-1.11.2 83 | cp -r jquery-ui-1.11.2/images static/ 84 | -------------------------------------------------------------------------------- /duktape-1.4.0/debugger/duk_classnames.yaml: -------------------------------------------------------------------------------- 1 | # Must match C header 2 | - unused 3 | - Arguments 4 | - Array 5 | - Boolean 6 | - Date 7 | - Error 8 | - Function 9 | - JSON 10 | - Math 11 | - Number 12 | - Object 13 | - RegExp 14 | - String 15 | - global 16 | - ObjEnv 17 | - DecEnv 18 | - Buffer 19 | - Pointer 20 | - Thread 21 | - ArrayBuffer 22 | - DataView 23 | - Int8Array 24 | - Uint8Array 25 | - Uint8ClampedArray 26 | - Int16Array 27 | - Uint16Array 28 | - Int32Array 29 | - Uint32Array 30 | - Float32Array 31 | - Float64Array 32 | -------------------------------------------------------------------------------- /duktape-1.4.0/debugger/duk_debugcommands.yaml: -------------------------------------------------------------------------------- 1 | # Debug command names. A single map works for now because command names 2 | # provided by client/target don't overlap. 3 | - Reserved_0 4 | - Status 5 | - Print 6 | - Alert 7 | - Log 8 | - Throw 9 | - Detaching 10 | - Reserved_7 11 | - Reserved_8 12 | - Reserved_9 13 | - Reserved_10 14 | - Reserved_11 15 | - Reserved_12 16 | - Reserved_13 17 | - Reserved_14 18 | - Reserved_15 19 | - BasicInfo 20 | - TriggerStatus 21 | - Pause 22 | - Resume 23 | - StepInto 24 | - StepOver 25 | - StepOut 26 | - ListBreak 27 | - AddBreak 28 | - DelBreak 29 | - GetVar 30 | - PutVar 31 | - GetCallStack 32 | - GetLocals 33 | - Eval 34 | - Detach 35 | - DumpHeap 36 | - GetBytecode 37 | -------------------------------------------------------------------------------- /duktape-1.4.0/debugger/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "duk-debug", 3 | "version": "0.1.0", 4 | "description": "Duktape debugger", 5 | "author": { 6 | "name": "Sami Vaarala", 7 | "email": "sami.vaarala@iki.fi" 8 | }, 9 | "dependencies": { 10 | "bluebird": "~2.6.4", 11 | "minimist": "~1.1.0", 12 | "express": "~4.10.1", 13 | "body-parser": "~1.9.3", 14 | "socket.io": "~1.2.1", 15 | "utf8": "~2.0.0", 16 | "wrench": "~1.5.8", 17 | "sprintf": "~0.1.5", 18 | "events": "~1.0.2", 19 | "stream": "0.0.2", 20 | "readline": "0.0.5", 21 | "util": "~0.10.3", 22 | "http": "0.0.0", 23 | "yamljs": "~0.2.1", 24 | "byline": "~4.2.1" 25 | }, 26 | "main": "duk_debug.js" 27 | } 28 | -------------------------------------------------------------------------------- /duktape-1.4.0/debugger/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Duktape debugger 9 | 10 | 11 | 12 |
13 | ((o) Duktape debugger 14 |
15 | 16 |
17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 |
25 |
26 |
27 |
28 | 29 | 30 | 31 | 32 | 33 |
34 | 35 |
36 |

37 | // No source loaded
38 | 
39 |
40 |
41 | 42 |
43 |
44 |
?
45 |
?
?
46 |
47 |
48 |
(output from script, print() and alert() calls)
49 |
50 |
51 | 52 |
53 |
54 |
(callstack)
55 |
56 |
57 |
(locals)
58 |
59 |
60 |
(breakpoints)
61 |
62 |
63 |  watch (eval on pause) 64 |
65 | 66 |
67 |
68 |
69 | 70 |
71 | 72 | 79 | 80 |
81 |

Duktape debugger is a web UI for debugging Ecmascript on a target device.

82 |

This web UI talks to a NodeJS debug server using socket.io. 83 | The debug server talks to the target device using the Duktape debug protocol 84 | (see debugger.rst).

85 |
86 | 87 |
88 |

89 | 
90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/README.rst: -------------------------------------------------------------------------------- 1 | ================ 2 | Duktape examples 3 | ================ 4 | 5 | Examples for using Duktape. These support user documentation and are 6 | intended as informative illustrations only. 7 | 8 | Examples are unmaintained and are not production quality code. Bugs are 9 | not not necessarily fixed, unless the bug makes the example misleading 10 | as documentation. 11 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/alloc-hybrid/README.rst: -------------------------------------------------------------------------------- 1 | ===================== 2 | Hybrid pool allocator 3 | ===================== 4 | 5 | Example allocator that tries to satisfy memory allocations for small sizes 6 | from a set of fixed pools, but always falls back to malloc/realloc/free if 7 | a larger size is requested or the pools have been exhausted. 8 | 9 | This may be useful to reduce memory churn when the platform allocator does 10 | not handle allocations for a lot of small memory areas efficiently. 11 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/alloc-hybrid/duk_alloc_hybrid.h: -------------------------------------------------------------------------------- 1 | #ifndef DUK_ALLOC_HYBRID_H_INCLUDED 2 | #define DUK_ALLOC_HYBRID_H_INCLUDED 3 | 4 | #include "duktape.h" 5 | 6 | void *duk_alloc_hybrid_init(void); 7 | void *duk_alloc_hybrid(void *udata, duk_size_t size); 8 | void *duk_realloc_hybrid(void *udata, void *ptr, duk_size_t size); 9 | void duk_free_hybrid(void *udata, void *ptr); 10 | 11 | #endif /* DUK_ALLOC_HYBRID_H_INCLUDED */ 12 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/alloc-logging/README.rst: -------------------------------------------------------------------------------- 1 | ====================== 2 | Allocator with logging 3 | ====================== 4 | 5 | Example allocator that writes all memory alloc/realloc/free calls into a 6 | log file so that memory usage can replayed later. This is useful to e.g. 7 | optimize pool sizes. 8 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/alloc-logging/duk_alloc_logging.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Example memory allocator with machine parseable logging. 3 | * 4 | * Also sizes for reallocs and frees are logged so that the memory 5 | * behavior can be essentially replayed to accurately determine e.g. 6 | * optimal pool sizes for a pooled allocator. 7 | * 8 | * Allocation structure: 9 | * 10 | * [ alloc_hdr | user area ] 11 | * 12 | * ^ ^ 13 | * | `--- pointer returned to Duktape 14 | * `--- underlying malloc ptr 15 | */ 16 | 17 | #include "duktape.h" 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #define ALLOC_LOG_FILE "/tmp/duk-alloc-log.txt" 24 | 25 | typedef struct { 26 | /* The double value in the union is there to ensure alignment is 27 | * good for IEEE doubles too. In many 32-bit environments 4 bytes 28 | * would be sufficiently aligned and the double value is unnecessary. 29 | */ 30 | union { 31 | size_t sz; 32 | double d; 33 | } u; 34 | } alloc_hdr; 35 | 36 | static FILE *log_file = NULL; 37 | 38 | static void write_log(const char *fmt, ...) { 39 | va_list ap; 40 | 41 | if (!log_file) { 42 | log_file = fopen(ALLOC_LOG_FILE, "wb"); 43 | if (!log_file) { 44 | return; 45 | } 46 | } 47 | 48 | va_start(ap, fmt); 49 | vfprintf(log_file, fmt, ap); 50 | va_end(ap); 51 | } 52 | 53 | void *duk_alloc_logging(void *udata, duk_size_t size) { 54 | alloc_hdr *hdr; 55 | void *ret; 56 | 57 | (void) udata; /* Suppress warning. */ 58 | 59 | if (size == 0) { 60 | write_log("A NULL %ld\n", (long) size); 61 | return NULL; 62 | } 63 | 64 | hdr = (alloc_hdr *) malloc(size + sizeof(alloc_hdr)); 65 | if (!hdr) { 66 | write_log("A FAIL %ld\n", (long) size); 67 | return NULL; 68 | } 69 | hdr->u.sz = size; 70 | ret = (void *) (hdr + 1); 71 | write_log("A %p %ld\n", ret, (long) size); 72 | return ret; 73 | } 74 | 75 | void *duk_realloc_logging(void *udata, void *ptr, duk_size_t size) { 76 | alloc_hdr *hdr; 77 | size_t old_size; 78 | void *t; 79 | void *ret; 80 | 81 | (void) udata; /* Suppress warning. */ 82 | 83 | /* Handle the ptr-NULL vs. size-zero cases explicitly to minimize 84 | * platform assumptions. You can get away with much less in specific 85 | * well-behaving environments. 86 | */ 87 | 88 | if (ptr) { 89 | hdr = (alloc_hdr *) (void *) ((unsigned char *) ptr - sizeof(alloc_hdr)); 90 | old_size = hdr->u.sz; 91 | 92 | if (size == 0) { 93 | free((void *) hdr); 94 | write_log("R %p %ld NULL 0\n", ptr, (long) old_size); 95 | return NULL; 96 | } else { 97 | t = realloc((void *) hdr, size + sizeof(alloc_hdr)); 98 | if (!t) { 99 | write_log("R %p %ld FAIL %ld\n", ptr, (long) old_size, (long) size); 100 | return NULL; 101 | } 102 | hdr = (alloc_hdr *) t; 103 | hdr->u.sz = size; 104 | ret = (void *) (hdr + 1); 105 | write_log("R %p %ld %p %ld\n", ptr, (long) old_size, ret, (long) size); 106 | return ret; 107 | } 108 | } else { 109 | if (size == 0) { 110 | write_log("R NULL 0 NULL 0\n"); 111 | return NULL; 112 | } else { 113 | hdr = (alloc_hdr *) malloc(size + sizeof(alloc_hdr)); 114 | if (!hdr) { 115 | write_log("R NULL 0 FAIL %ld\n", (long) size); 116 | return NULL; 117 | } 118 | hdr->u.sz = size; 119 | ret = (void *) (hdr + 1); 120 | write_log("R NULL 0 %p %ld\n", ret, (long) size); 121 | return ret; 122 | } 123 | } 124 | } 125 | 126 | void duk_free_logging(void *udata, void *ptr) { 127 | alloc_hdr *hdr; 128 | 129 | (void) udata; /* Suppress warning. */ 130 | 131 | if (!ptr) { 132 | write_log("F NULL 0\n"); 133 | return; 134 | } 135 | hdr = (alloc_hdr *) (void *) ((unsigned char *) ptr - sizeof(alloc_hdr)); 136 | write_log("F %p %ld\n", ptr, (long) hdr->u.sz); 137 | free((void *) hdr); 138 | } 139 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/alloc-logging/duk_alloc_logging.h: -------------------------------------------------------------------------------- 1 | #ifndef DUK_ALLOC_LOGGING_H_INCLUDED 2 | #define DUK_ALLOC_LOGGING_H_INCLUDED 3 | 4 | #include "duktape.h" 5 | 6 | void *duk_alloc_logging(void *udata, duk_size_t size); 7 | void *duk_realloc_logging(void *udata, void *ptr, duk_size_t size); 8 | void duk_free_logging(void *udata, void *ptr); 9 | 10 | #endif /* DUK_ALLOC_LOGGING_H_INCLUDED */ 11 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/alloc-logging/log2gnuplot.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # 3 | # Analyze allocator logs and write total-bytes-in-use after every 4 | # operation to stdout. The output can be gnuplotted as: 5 | # 6 | # $ python log2gnuplot.py /tmp/output.txt 7 | # $ gnuplot 8 | # > plot "output.txt" with lines 9 | # 10 | 11 | import os 12 | import sys 13 | 14 | def main(): 15 | allocated = 0 16 | 17 | for line in sys.stdin: 18 | line = line.strip() 19 | parts = line.split(' ') 20 | 21 | # A ptr/NULL/FAIL size 22 | # F ptr/NULL size 23 | # R ptr/NULL oldsize ptr/NULL/FAIL newsize 24 | 25 | # Note: ajduk doesn't log oldsize (uses -1 instead) 26 | 27 | if parts[0] == 'A': 28 | if parts[1] != 'NULL' and parts[1] != 'FAIL': 29 | allocated += long(parts[2]) 30 | elif parts[0] == 'F': 31 | allocated -= long(parts[2]) 32 | elif parts[0] == 'R': 33 | allocated -= long(parts[2]) 34 | if parts[3] != 'NULL' and parts[3] != 'FAIL': 35 | allocated += long(parts[4]) 36 | print(allocated) 37 | 38 | print(allocated) 39 | 40 | if __name__ == '__main__': 41 | main() 42 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/alloc-torture/README.rst: -------------------------------------------------------------------------------- 1 | ========================================== 2 | Allocator with memory wiping and red zones 3 | ========================================== 4 | 5 | Example allocator that wipes memory on free and checks that no out-of-bounds 6 | writes have been made to bytes just before and after the allocated area. 7 | 8 | Valgrind is a better tool for detecting these memory issues, but it's not 9 | available for all targets so you can use something like this to detect 10 | memory lifecycle or out-of-bounds issues. 11 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/alloc-torture/duk_alloc_torture.h: -------------------------------------------------------------------------------- 1 | #ifndef DUK_ALLOC_TORTURE_H_INCLUDED 2 | #define DUK_ALLOC_TORTURE_H_INCLUDED 3 | 4 | #include "duktape.h" 5 | 6 | void *duk_alloc_torture(void *udata, duk_size_t size); 7 | void *duk_realloc_torture(void *udata, void *ptr, duk_size_t size); 8 | void duk_free_torture(void *udata, void *ptr); 9 | 10 | #endif /* DUK_ALLOC_TORTURE_H_INCLUDED */ 11 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/cmdline/README.rst: -------------------------------------------------------------------------------- 1 | ==================== 2 | Duktape command line 3 | ==================== 4 | 5 | Ecmascript command line execution tool, useful for running Ecmascript code 6 | from a file, stdin, or interactively. Also used by automatic testing. 7 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/codepage-conv/README.rst: -------------------------------------------------------------------------------- 1 | Codepage conversion example 2 | =========================== 3 | 4 | Example of how to convert an 8-bit input string (e.g. ISO-8859-1 or Windows 5 | codepage 1252) into CESU-8 without using an external library like iconv. 6 | 7 | This is useful e.g. when compiling non-UTF-8 source code which cannot be 8 | converted to UTF-8 (CESU-8) at build time. 9 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/codepage-conv/duk_codepage_conv.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Convert an 8-bit input string (e.g. ISO-8859-1) into CESU-8. 3 | * Calling code supplies the "code page" as a 256-entry array of 4 | * codepoints for the conversion. 5 | * 6 | * This is useful when input data is in non-UTF-8 format and must 7 | * be converted at runtime, e.g. when compiling non-UTF-8 source 8 | * code. Another alternative is to use e.g. iconv. 9 | */ 10 | 11 | #include "duktape.h" 12 | 13 | /* Decode an 8-bit string using 'codepage' into Unicode codepoints and 14 | * re-encode into CESU-8. Codepage argument must point to a 256-entry 15 | * table. Only supports BMP (codepoints U+0000 to U+FFFF). 16 | */ 17 | void duk_decode_string_codepage(duk_context *ctx, const char *str, size_t len, unsigned int *codepage) { 18 | unsigned char *tmp; 19 | size_t tmplen, i; 20 | unsigned char *p; 21 | unsigned int cp; 22 | 23 | tmplen = 3 * len; /* max expansion is 1 input byte -> 3 output bytes */ 24 | if (tmplen / 3 != len) { 25 | /* Temporary buffer length wraps. */ 26 | duk_error(ctx, DUK_ERR_RANGE_ERROR, "input string too long"); 27 | return; 28 | } 29 | 30 | tmp = (unsigned char *) duk_push_fixed_buffer(ctx, tmplen); 31 | 32 | for (i = 0, p = tmp; i < len; i++) { 33 | cp = codepage[((unsigned char *) str)[i]] & 0xffffUL; 34 | if (cp < 0x80UL) { 35 | *p++ = (unsigned char) cp; 36 | } else if (cp < 0x800UL) { 37 | *p++ = (unsigned char) (0xc0 + ((cp >> 6) & 0x1f)); 38 | *p++ = (unsigned char) (0x80 + (cp & 0x3f)); 39 | } else { 40 | /* In CESU-8 all codepoints in [0x0000,0xFFFF] are 41 | * allowed, including surrogates. 42 | */ 43 | *p++ = (unsigned char) (0xe0 + ((cp >> 12) & 0x0f)); 44 | *p++ = (unsigned char) (0x80 + ((cp >> 6) & 0x3f)); 45 | *p++ = (unsigned char) (0x80 + (cp & 0x3f)); 46 | } 47 | } 48 | 49 | duk_push_lstring(ctx, (const char *) tmp, (duk_size_t) (p - tmp)); 50 | 51 | /* [ ... tmp res ] */ 52 | 53 | duk_remove(ctx, -2); 54 | } 55 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/codepage-conv/duk_codepage_conv.h: -------------------------------------------------------------------------------- 1 | #ifndef DUK_CODEPAGE_CONV_H_INCLUDED 2 | #define DUK_CODEPAGE_CONV_H_INCLUDED 3 | 4 | #include "duktape.h" 5 | 6 | void duk_decode_string_codepage(duk_context *ctx, const char *str, size_t len, unsigned int *codepage); 7 | 8 | #endif /* DUK_CODEPAGE_CONV_H_INCLUDED */ 9 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/coffee/README.rst: -------------------------------------------------------------------------------- 1 | ===================== 2 | Coffeescript examples 3 | ===================== 4 | 5 | A few tests to see how CoffeeScript works with Duktape. Just convert the 6 | Coffeescript files to Javascript with the ``Makefile.coffee`` in the 7 | distributable, or manually:: 8 | 9 | $ coffee -c hello.coffee 10 | $ cat hello.js 11 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/coffee/globals.coffee: -------------------------------------------------------------------------------- 1 | 2 | print '*** All globals' 3 | print(name) for name in Object.getOwnPropertyNames(this) 4 | 5 | print '*** Globals with a short name (<= 8 chars)' 6 | print(name) for name in Object.getOwnPropertyNames(this) when name.length <= 8 7 | 8 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/coffee/hello.coffee: -------------------------------------------------------------------------------- 1 | print 'Hello world!' 2 | print 'version: ' + Duktape.version 3 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/coffee/mandel.coffee: -------------------------------------------------------------------------------- 1 | mandel = (x0, y0, x1, y1, w, h, maxiter) -> 2 | [dx, dy] = [(x1 - x0) / w, (y1 - y0) / h] 3 | res = [] 4 | 5 | y = y0 6 | for yc in [0..h-1] 7 | x = x0 8 | for xc in [0..w-1] 9 | [xx, yy] = [x, y] 10 | c = '*' 11 | for i in [0..maxiter-1] 12 | # (xx+i*yy)^2 + (x+i*y) = xx^2 + i*2*xx*yy - yy^2 + x + i*y 13 | # = (xx^2 - yy^2 + x) + i*(2*xx*yy + y) 14 | [xx2, yy2] = [xx*xx, yy*yy] 15 | if xx2 + yy2 >= 4.0 16 | c = '.' 17 | break 18 | [xx, yy] = [xx2 - yy2 + x, 2*xx*yy + y] 19 | res.push(c) 20 | x += dx 21 | res.push('\n') 22 | y += dy 23 | 24 | print(res.join('')) 25 | return 26 | 27 | mandel(-2, 2, 2, -2, 200, 100, 1000) 28 | 29 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/cpp-exceptions/README.rst: -------------------------------------------------------------------------------- 1 | ========================================= 2 | C++ exceptions for long control transfers 3 | ========================================= 4 | 5 | Normally Duktape uses ``setjmp()`` / ``longjmp()`` or their variants for 6 | internal long control transfers. One downside of these functions is that 7 | C++ automatic destructors (scope-based resource management, SBRM, a special 8 | case of RAII) in Duktape/C functions won't be executed which is awkward for 9 | C++ programmers. 10 | 11 | When ``DUK_USE_CPP_EXCEPTIONS`` (``DUK_OPT_CPP_EXCEPTIONS``) is defined, and 12 | both Duktape and application code is compiled using a C++ compiler, Duktape 13 | uses C++ ``try-catch`` and ``throw`` for internal long control transfers. 14 | This allows automatic destructors to run as expected. The config option is 15 | not enabled by default because C++ exceptions are sometimes disabled even 16 | when a C++ compiler is used (e.g. for performance reasons). 17 | 18 | The ``cpp_exceptions.cpp`` example illustrates how C++ exceptions can be 19 | used in Duktape/C functions at the moment: 20 | 21 | * Duktape uses C++ try/catch/throw internally; this is not visible to user 22 | code directly. 23 | 24 | * Automatic destructors (scope-based resource management) work as expected. 25 | 26 | * C++ exceptions can be used in Duktape/C functions normally, but user 27 | exceptions must be caught before they reach Duktape. If this is not 28 | done, such exceptions are caught by Duktape and converted to API errors 29 | (in other words, they won't propagate "through" Duktape at the moment). 30 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/debug-trans-dvalue/Makefile: -------------------------------------------------------------------------------- 1 | # Set DUKTAPE_SRC to 'src' dir of Duktape distributable. 2 | # The default is for the dist environment. 3 | DUKTAPE_SRC=../../src 4 | DUKTAPE_OPTS= 5 | DUKTAPE_OPTS+=-DDUK_OPT_ASSERTIONS 6 | DUKTAPE_OPTS+=-DDUK_OPT_DEBUGGER_SUPPORT -DDUK_OPT_INTERRUPT_COUNTER 7 | DUKTAPE_OPTS+=-DDUK_OPT_DEBUGGER_FWD_PRINTALERT 8 | DUKTAPE_OPTS+=-DDUK_OPT_DEBUGGER_DUMPHEAP 9 | #DUKTAPE_OPTS+=-DDUK_OPT_DEBUGGER_TRANSPORT_TORTURE 10 | TRANS_OPTS= 11 | #TRANS_OPTS+=-DDEBUG_PRINTS 12 | 13 | test: test.c duk_trans_dvalue.c duk_trans_dvalue.h 14 | echo $(DUKTAPE_SRC) 15 | gcc -O0 -g -ggdb -Wall -Wextra -std=c99 -o test -I$(DUKTAPE_SRC) -I. \ 16 | $(DUKTAPE_OPTS) $(TRANS_OPTS) \ 17 | $(DUKTAPE_SRC)/duktape.c duk_trans_dvalue.c test.c -lm 18 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/debug-trans-dvalue/README.rst: -------------------------------------------------------------------------------- 1 | =========================================================== 2 | Debug transport with local debug protocol encoding/decoding 3 | =========================================================== 4 | 5 | This example implements a debug transport which decodes/encodes the Duktape 6 | debug protocol locally into a more easy to use C interface, which is useful 7 | for debug clients implemented locally on the target. The example also 8 | demonstrates how to trial parse dvalues in C. 9 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/debug-trans-socket/README.rst: -------------------------------------------------------------------------------- 1 | ================================================ 2 | Debug transport using a simple socket connection 3 | ================================================ 4 | 5 | This example implements an example debug transport which uses a Linux server 6 | socket on the debug target. 7 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/debug-trans-socket/duk_trans_socket.h: -------------------------------------------------------------------------------- 1 | #ifndef DUK_TRANS_SOCKET_H_INCLUDED 2 | #define DUK_TRANS_SOCKET_H_INCLUDED 3 | 4 | #include "duktape.h" 5 | 6 | void duk_trans_socket_init(void); 7 | void duk_trans_socket_finish(void); 8 | void duk_trans_socket_waitconn(void); 9 | duk_size_t duk_trans_socket_read_cb(void *udata, char *buffer, duk_size_t length); 10 | duk_size_t duk_trans_socket_write_cb(void *udata, const char *buffer, duk_size_t length); 11 | duk_size_t duk_trans_socket_peek_cb(void *udata); 12 | void duk_trans_socket_read_flush_cb(void *udata); 13 | void duk_trans_socket_write_flush_cb(void *udata); 14 | 15 | #endif /* DUK_TRANS_SOCKET_H_INCLUDED */ 16 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/dummy-date-provider/README.rst: -------------------------------------------------------------------------------- 1 | ==================================== 2 | Dummy external Date provider example 3 | ==================================== 4 | 5 | This example implements a dummy, minimal external Date provider. 6 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/dummy-date-provider/dummy_date_provider.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Dummy Date provider 3 | * 4 | * There are two minimally required macros which you must provide in 5 | * duk_config.h: 6 | * 7 | * extern duk_double_t dummy_get_now(void); 8 | * 9 | * #define DUK_USE_DATE_GET_NOW(ctx) dummy_get_now() 10 | * #define DUK_USE_DATE_GET_LOCAL_TZOFFSET(d) 0 11 | * 12 | * Note that since the providers are macros, you don't need to use 13 | * all arguments. Similarly, you can "return" fixed values as 14 | * constants. Above, local timezone offset is always zero i.e. 15 | * we're always in UTC. 16 | * 17 | * You can also provide optional macros to parse and format timestamps 18 | * in a platform specific format. If not provided, Duktape will use 19 | * ISO 8601 only (which is often good enough). 20 | */ 21 | 22 | #include "duktape.h" 23 | 24 | duk_double_t dummy_get_now(void) { 25 | /* Return a fixed time here as a dummy example. */ 26 | return -11504520000.0; 27 | } 28 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/eval/README.rst: -------------------------------------------------------------------------------- 1 | ============ 2 | Eval example 3 | ============ 4 | 5 | Evaluate expressions from command line. 6 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/eval/eval.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Very simple example program for evaluating expressions from 3 | * command line 4 | */ 5 | 6 | #include "duktape.h" 7 | #include 8 | 9 | static int eval_raw(duk_context *ctx) { 10 | duk_eval(ctx); 11 | return 1; 12 | } 13 | 14 | static int tostring_raw(duk_context *ctx) { 15 | duk_to_string(ctx, -1); 16 | return 1; 17 | } 18 | 19 | static void usage_exit(void) { 20 | fprintf(stderr, "Usage: eval [] ...\n"); 21 | fflush(stderr); 22 | exit(1); 23 | } 24 | 25 | int main(int argc, char *argv[]) { 26 | duk_context *ctx; 27 | int i; 28 | const char *res; 29 | 30 | if (argc < 2) { 31 | usage_exit(); 32 | } 33 | 34 | ctx = duk_create_heap_default(); 35 | for (i = 1; i < argc; i++) { 36 | printf("=== eval: '%s' ===\n", argv[i]); 37 | duk_push_string(ctx, argv[i]); 38 | duk_safe_call(ctx, eval_raw, 1 /*nargs*/, 1 /*nrets*/); 39 | duk_safe_call(ctx, tostring_raw, 1 /*nargs*/, 1 /*nrets*/); 40 | res = duk_get_string(ctx, -1); 41 | printf("%s\n", res ? res : "null"); 42 | duk_pop(ctx); 43 | } 44 | 45 | duk_destroy_heap(ctx); 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/eventloop/README.rst: -------------------------------------------------------------------------------- 1 | ================== 2 | Eventloop examples 3 | ================== 4 | 5 | Overview and usage 6 | ================== 7 | 8 | A few examples on how an event loop can be implemented with Duktape, mainly 9 | illlustrating how the Duktape interface works (not how event loops should be 10 | built otherwise). 11 | 12 | To test (Linux only, perhaps other Unix):: 13 | 14 | $ make 15 | $ ./evloop curses-timers.js # run with Ecmascript eventloop 16 | $ ./evloop -c curses-timers.js # run with C eventloop 17 | 18 | Implementation approaches 19 | ========================= 20 | 21 | There are several approaches to implementation timers. Here we demonstrate 22 | two main approaches: 23 | 24 | 1. Using a C eventloop which calls into Javascript. All the event loop state 25 | like timers, sockets, etc, is held in C structures. 26 | (See ``c_eventloop.c`` and ``c_eventloop.js``.) 27 | 28 | 2. Using an Ecmascript eventloop which never returns. All the event loop state 29 | can be managed with Ecmascript code instead of C structures. The Ecmascript 30 | eventloop calls a Duktape/C helper to do the lowest level poll() call. 31 | (See ``ecma_eventloop.js``.) 32 | 33 | Services provided 34 | ================= 35 | 36 | The event loop API provided by both examples is the same, and includes: 37 | 38 | * Timers: setTimeout, clearTimeout, setInterval, clearInterval 39 | 40 | * Sockets: simple network sockets 41 | 42 | In addition there are a few synchronous API bindings which are not event loop 43 | related: 44 | 45 | * File I/O 46 | 47 | * Curses, for doing beautiful character graphics 48 | 49 | Limitations 50 | =========== 51 | 52 | This is **not** a production quality event loop. This is on purpose, to 53 | keep the example somewhat simple. Some shortcomings include: 54 | 55 | * A production quality event loop would track its internal state (active 56 | timers and sockets) much more efficiently. In general memory usage and 57 | code footprint can be reduced. 58 | 59 | * Buffer churn caused by allocating a new buffer for every socket read 60 | should be eliminated by reusing buffers where appropriate. Although 61 | churn doesn't increase memory footprint with reference counting, it 62 | is slower than reusing buffers and might increase memory fragmentation. 63 | 64 | * There is no way to suspend reading or writing in the example. Adding 65 | them is straightforward: the poll set needs to be managed dynamically. 66 | 67 | * The example uses poll() while one should use epoll() on Linux, kqueue() 68 | on BSD systems, etc. 69 | 70 | * Timers are not very accurate, e.g. setInterval() does not try to guarantee 71 | a steady schedule. Instead, the next interval is scheduled after the 72 | current callback has finished. This is not the best behavior for some 73 | environments, but avoids bunching callbacks. 74 | 75 | * Error handling is mostly missing. Debug prints don't interact well 76 | with curses. 77 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/eventloop/basic-test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * A few basic tests 3 | */ 4 | 5 | var count = 0; 6 | var intervalId; 7 | 8 | setTimeout(function (x) { print('timer 1', x); }, 1234, 'foo'); 9 | setTimeout('print("timer 2");', 4321); 10 | setTimeout(function () { print('timer 3'); }, 2345); 11 | intervalId = setInterval(function (x, y) { 12 | print('interval', ++count, x, y); 13 | if (count >= 10) { 14 | clearInterval(intervalId); 15 | } 16 | }, 400, 'foo', 'bar'); 17 | 18 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/eventloop/client-socket-test.js: -------------------------------------------------------------------------------- 1 | 2 | var HOST = 'localhost'; 3 | var PORT = 80; 4 | var EXIT_TIMEOUT = 300e3; 5 | 6 | print('automatic exit after ' + (EXIT_TIMEOUT / 1e3) + ' seconds'); 7 | setTimeout(function () { 8 | print('exit timer'); 9 | EventLoop.requestExit(); 10 | }, EXIT_TIMEOUT); 11 | 12 | EventLoop.connect(HOST, PORT, function (fd) { 13 | print('connected to ' + HOST + ':' + PORT + ', fd', fd); 14 | EventLoop.setReader(fd, function (fd, data) { 15 | print('read from fd', fd); 16 | print(data); 17 | EventLoop.close(fd); 18 | }); 19 | EventLoop.write(fd, "GET / HTTP/1.1\r\n" + 20 | "Host: " + HOST + "\r\n" + 21 | "User-Agent: client-socket-test.js\r\n" + 22 | "\r\n"); 23 | }); 24 | 25 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/eventloop/curses-timers.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Test using timers and intervals with curses. 3 | */ 4 | 5 | if (typeof Ncurses !== 'object') { 6 | throw new Error('Ncurses required'); 7 | } 8 | 9 | function fillScreen(ch) { 10 | var size, w, h; 11 | var i, j; 12 | 13 | size = Ncurses.getmaxyx(); 14 | h = size[0]; 15 | w = size[1]; 16 | 17 | for (i = 0; i < h; i++) { 18 | for (j = 0; j < w; j++) { 19 | Ncurses.mvprintw(i, j, ch); 20 | } 21 | } 22 | Ncurses.refresh(); 23 | } 24 | 25 | function main() { 26 | var i, j; 27 | var counters = []; 28 | var size, w, h; 29 | 30 | Ncurses.initscr(); 31 | size = Ncurses.getmaxyx(); 32 | h = size[0]; 33 | w = size[1]; 34 | 35 | fillScreen('.'); 36 | 37 | setInterval(function () { 38 | Ncurses.mvprintw(1, 4, new Date().toISOString()); 39 | Ncurses.refresh(); 40 | }, 1000); 41 | 42 | function addCounter(row, index, interval) { 43 | counters[index] = 0; 44 | setInterval(function () { 45 | counters[index]++; 46 | Ncurses.mvprintw(row, 4, '' + Date.now() + ' ' + counters[index]); 47 | Ncurses.refresh(); 48 | }, interval); 49 | } 50 | 51 | function addRandomChar(row, col, interval) { 52 | setTimeout(function () { 53 | Ncurses.mvprintw(row, col, String.fromCharCode(Math.random() * 64 + 0x20)); 54 | Ncurses.refresh(); 55 | }, interval); 56 | } 57 | 58 | for (i = 0; i < h - 5; i++) { 59 | addCounter(3 + i, i, 363 * i + 400); 60 | } 61 | 62 | /* Here the inserts take a lot of time because the underlying timer manager 63 | * data structure has O(n) insertion performance. 64 | */ 65 | for (i = 0; i < h - 5; i++) { 66 | for (j = 0; j < w - 50; j++) { 67 | // Math.exp(0)...Math.exp(8) is an uneven distribution between 1...~2980. 68 | addRandomChar(3 + i, 28 + j, 58000 - Math.exp(Math.random() * 8) * 20); 69 | } 70 | } 71 | 72 | setTimeout(function () { 73 | Ncurses.endwin(); 74 | Ncurses.delscreen(); 75 | requestEventLoopExit(); 76 | }, 120e3); 77 | } 78 | 79 | main(); 80 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/eventloop/fileio.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File I/O binding example. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include "duktape.h" 10 | 11 | static int fileio_readfile(duk_context *ctx) { 12 | const char *filename = duk_to_string(ctx, 0); 13 | FILE *f = NULL; 14 | long len; 15 | void *buf; 16 | size_t got; 17 | 18 | if (!filename) { 19 | goto error; 20 | } 21 | 22 | f = fopen(filename, "rb"); 23 | if (!f) { 24 | goto error; 25 | } 26 | 27 | if (fseek(f, 0, SEEK_END) != 0) { 28 | goto error; 29 | } 30 | 31 | len = ftell(f); 32 | 33 | if (fseek(f, 0, SEEK_SET) != 0) { 34 | goto error; 35 | } 36 | 37 | buf = duk_push_fixed_buffer(ctx, (size_t) len); 38 | 39 | got = fread(buf, 1, len, f); 40 | if (got != (size_t) len) { 41 | goto error; 42 | } 43 | 44 | fclose(f); 45 | f = NULL; 46 | 47 | return 1; 48 | 49 | error: 50 | if (f) { 51 | fclose(f); 52 | } 53 | 54 | return DUK_RET_ERROR; 55 | } 56 | 57 | static duk_function_list_entry fileio_funcs[] = { 58 | { "readfile", fileio_readfile, 1 }, 59 | { NULL, NULL, 0 } 60 | }; 61 | 62 | void fileio_register(duk_context *ctx) { 63 | /* Set global 'FileIo'. */ 64 | duk_push_global_object(ctx); 65 | duk_push_object(ctx); 66 | duk_put_function_list(ctx, -1, fileio_funcs); 67 | duk_put_prop_string(ctx, -2, "FileIo"); 68 | duk_pop(ctx); 69 | } 70 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/eventloop/ncurses.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Ncurses bindings example. 3 | * 4 | * VALGRIND NOTE: when you use ncurses, there seems to be no way to get a 5 | * clean valgrind run. Even if ncurses state is properly shut down, there 6 | * will still be some residual leaks. 7 | * 8 | * Debian: install libncurses5-dev 9 | */ 10 | 11 | #include 12 | #include "duktape.h" 13 | 14 | static int ncurses_initscr(duk_context *ctx) { 15 | WINDOW *win; 16 | 17 | win = initscr(); 18 | duk_push_pointer(ctx, (void *) win); 19 | return 1; 20 | } 21 | 22 | static int ncurses_endwin(duk_context *ctx) { 23 | int rc; 24 | 25 | rc = endwin(); 26 | duk_push_int(ctx, rc); 27 | return 1; 28 | } 29 | 30 | static int ncurses_delscreen(duk_context *ctx) { 31 | /* XXX: no screen management now */ 32 | (void) ctx; 33 | return 0; 34 | } 35 | 36 | static int ncurses_getmaxyx(duk_context *ctx) { 37 | int row, col; 38 | 39 | getmaxyx(stdscr, row, col); 40 | 41 | duk_push_array(ctx); 42 | duk_push_int(ctx, row); 43 | duk_put_prop_index(ctx, -2, 0); 44 | duk_push_int(ctx, col); 45 | duk_put_prop_index(ctx, -2, 1); 46 | return 1; 47 | } 48 | 49 | static int ncurses_printw(duk_context *ctx) { 50 | int rc; 51 | const char *str; 52 | 53 | str = duk_to_string(ctx, 0); 54 | rc = printw("%s", str); 55 | duk_push_int(ctx, rc); 56 | return 1; 57 | } 58 | 59 | static int ncurses_mvprintw(duk_context *ctx) { 60 | int y = duk_to_int(ctx, 0); 61 | int x = duk_to_int(ctx, 1); 62 | const char *str = duk_to_string(ctx, 2); 63 | int rc; 64 | 65 | rc = mvprintw(y, x, "%s", str); 66 | duk_push_int(ctx, rc); 67 | return 1; 68 | } 69 | 70 | static int ncurses_refresh(duk_context *ctx) { 71 | int rc; 72 | 73 | rc = refresh(); 74 | duk_push_int(ctx, rc); 75 | return 1; 76 | } 77 | 78 | static int ncurses_getch(duk_context *ctx) { 79 | int rc; 80 | 81 | rc = getch(); 82 | duk_push_int(ctx, rc); 83 | return 1; 84 | } 85 | 86 | static duk_function_list_entry ncurses_funcs[] = { 87 | { "initscr", ncurses_initscr, 0 }, 88 | { "endwin", ncurses_endwin, 0 }, 89 | { "delscreen", ncurses_delscreen, 0 }, 90 | { "getmaxyx", ncurses_getmaxyx, 0 }, 91 | { "printw", ncurses_printw, 1 }, 92 | { "mvprintw", ncurses_mvprintw, 3 }, 93 | { "refresh", ncurses_refresh, 0 }, 94 | { "getch", ncurses_getch, 0 }, 95 | { NULL, NULL, 0 } 96 | }; 97 | 98 | void ncurses_register(duk_context *ctx) { 99 | /* Set global 'Ncurses'. */ 100 | duk_push_global_object(ctx); 101 | duk_push_object(ctx); 102 | duk_put_function_list(ctx, -1, ncurses_funcs); 103 | duk_put_prop_string(ctx, -2, "Ncurses"); 104 | duk_pop(ctx); 105 | } 106 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/eventloop/poll.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C wrapper for poll(). 3 | */ 4 | 5 | #define _GNU_SOURCE 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "duktape.h" 13 | 14 | static int poll_poll(duk_context *ctx) { 15 | int timeout = duk_to_int(ctx, 1); 16 | int i, n, nchanged; 17 | int fd, rc; 18 | struct pollfd fds[20]; 19 | struct timespec ts; 20 | 21 | memset(fds, 0, sizeof(fds)); 22 | 23 | n = 0; 24 | duk_enum(ctx, 0, 0 /*enum_flags*/); 25 | while (duk_next(ctx, -1, 0)) { 26 | if ((size_t) n >= sizeof(fds) / sizeof(struct pollfd)) { 27 | return -1; 28 | } 29 | 30 | /* [... enum key] */ 31 | duk_dup_top(ctx); /* -> [... enum key key] */ 32 | duk_get_prop(ctx, 0); /* -> [... enum key val] */ 33 | fd = duk_to_int(ctx, -2); 34 | 35 | duk_push_string(ctx, "events"); 36 | duk_get_prop(ctx, -2); /* -> [... enum key val events] */ 37 | 38 | fds[n].fd = fd; 39 | fds[n].events = duk_to_int(ctx, -1); 40 | fds[n].revents = 0; 41 | 42 | duk_pop_n(ctx, 3); /* -> [... enum] */ 43 | 44 | n++; 45 | } 46 | /* leave enum on stack */ 47 | 48 | memset(&ts, 0, sizeof(ts)); 49 | ts.tv_nsec = (timeout % 1000) * 1000000; 50 | ts.tv_sec = timeout / 1000; 51 | 52 | /*rc = ppoll(fds, n, &ts, NULL);*/ 53 | rc = poll(fds, n, timeout); 54 | if (rc < 0) { 55 | duk_error(ctx, DUK_ERR_ERROR, "%s (errno=%d)", strerror(errno), errno); 56 | } 57 | 58 | duk_push_array(ctx); 59 | nchanged = 0; 60 | for (i = 0; i < n; i++) { 61 | /* update revents */ 62 | 63 | if (fds[i].revents) { 64 | duk_push_int(ctx, fds[i].fd); /* -> [... retarr fd] */ 65 | duk_put_prop_index(ctx, -2, nchanged); 66 | nchanged++; 67 | } 68 | 69 | duk_push_int(ctx, fds[i].fd); /* -> [... retarr key] */ 70 | duk_get_prop(ctx, 0); /* -> [... retarr val] */ 71 | duk_push_string(ctx, "revents"); 72 | duk_push_int(ctx, fds[i].revents); /* -> [... retarr val "revents" fds[i].revents] */ 73 | duk_put_prop(ctx, -3); /* -> [... retarr val] */ 74 | duk_pop(ctx); 75 | } 76 | 77 | /* [retarr] */ 78 | 79 | return 1; 80 | } 81 | 82 | static duk_function_list_entry poll_funcs[] = { 83 | { "poll", poll_poll, 2 }, 84 | { NULL, NULL, 0 } 85 | }; 86 | 87 | static duk_number_list_entry poll_consts[] = { 88 | { "POLLIN", (double) POLLIN }, 89 | { "POLLPRI", (double) POLLPRI }, 90 | { "POLLOUT", (double) POLLOUT }, 91 | #if 0 92 | /* Linux 2.6.17 and upwards, requires _GNU_SOURCE etc, not added 93 | * now because we don't use it. 94 | */ 95 | { "POLLRDHUP", (double) POLLRDHUP }, 96 | #endif 97 | { "POLLERR", (double) POLLERR }, 98 | { "POLLHUP", (double) POLLHUP }, 99 | { "POLLNVAL", (double) POLLNVAL }, 100 | { NULL, 0.0 } 101 | }; 102 | 103 | void poll_register(duk_context *ctx) { 104 | /* Set global 'Poll' with functions and constants. */ 105 | duk_push_global_object(ctx); 106 | duk_push_object(ctx); 107 | duk_put_function_list(ctx, -1, poll_funcs); 108 | duk_put_number_list(ctx, -1, poll_consts); 109 | duk_put_prop_string(ctx, -2, "Poll"); 110 | duk_pop(ctx); 111 | } 112 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/eventloop/server-socket-test.js: -------------------------------------------------------------------------------- 1 | 2 | var HOST = 'localhost' 3 | var PORT = 12345; 4 | var EXIT_TIMEOUT = 300e3; 5 | 6 | print('automatic exit after ' + (EXIT_TIMEOUT / 1e3) + ' seconds'); 7 | setTimeout(function () { 8 | print('exit timer'); 9 | EventLoop.requestExit(); 10 | }, EXIT_TIMEOUT); 11 | 12 | print('listen on ' + HOST + ':' + PORT); 13 | EventLoop.server(HOST, PORT, function (fd, addr, port) { 14 | print('new connection on fd ' + fd + ' from ' + addr + ':' + port); 15 | EventLoop.setReader(fd, function (fd, data) { 16 | var b, i, n, x; 17 | 18 | // Handle socket data carefully: if you convert it to a string, 19 | // it may not be valid UTF-8 etc. Here we operate on the data 20 | // directly in the buffer. 21 | 22 | b = data.valueOf(); // ensure we get a plain buffer 23 | n = b.length; 24 | for (i = 0; i < n; i++) { 25 | x = b[i]; 26 | if (x >= 0x61 && x <= 0x7a) { 27 | b[i] = x - 0x20; // uppercase 28 | } 29 | } 30 | 31 | print('read data on fd ' + fd + ', length ' + data.length); 32 | EventLoop.write(fd, data); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/guide/README.rst: -------------------------------------------------------------------------------- 1 | =========================== 2 | Duktape guide example files 3 | =========================== 4 | 5 | Examples used in the Duktape guide. 6 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/guide/fib.js: -------------------------------------------------------------------------------- 1 | // fib.js 2 | function fib(n) { 3 | if (n == 0) { return 0; } 4 | if (n == 1) { return 1; } 5 | return fib(n-1) + fib(n-2); 6 | } 7 | 8 | function test() { 9 | var res = []; 10 | for (i = 0; i < 20; i++) { 11 | res.push(fib(i)); 12 | } 13 | print(res.join(' ')); 14 | } 15 | 16 | test(); 17 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/guide/prime.js: -------------------------------------------------------------------------------- 1 | // prime.js 2 | 3 | // Pure Ecmascript version of low level helper 4 | function primeCheckEcmascript(val, limit) { 5 | for (var i = 2; i <= limit; i++) { 6 | if ((val % i) == 0) { return false; } 7 | } 8 | return true; 9 | } 10 | 11 | // Select available helper at load time 12 | var primeCheckHelper = (this.primeCheckNative || primeCheckEcmascript); 13 | 14 | // Check 'val' for primality 15 | function primeCheck(val) { 16 | if (val == 1 || val == 2) { return true; } 17 | var limit = Math.ceil(Math.sqrt(val)); 18 | while (limit * limit < val) { limit += 1; } 19 | return primeCheckHelper(val, limit); 20 | } 21 | 22 | // Find primes below one million ending in '9999'. 23 | function primeTest() { 24 | var res = []; 25 | 26 | print('Have native helper: ' + (primeCheckHelper !== primeCheckEcmascript)); 27 | for (var i = 1; i < 1000000; i++) { 28 | if (primeCheck(i) && (i % 10000) == 9999) { res.push(i); } 29 | } 30 | print(res.join(' ')); 31 | } 32 | 33 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/guide/primecheck.c: -------------------------------------------------------------------------------- 1 | /* primecheck.c */ 2 | #include 3 | #include 4 | #include 5 | #include "duktape.h" 6 | 7 | static duk_ret_t native_prime_check(duk_context *ctx) { 8 | int val = duk_require_int(ctx, 0); 9 | int lim = duk_require_int(ctx, 1); 10 | int i; 11 | 12 | for (i = 2; i <= lim; i++) { 13 | if (val % i == 0) { 14 | duk_push_false(ctx); 15 | return 1; 16 | } 17 | } 18 | 19 | duk_push_true(ctx); 20 | return 1; 21 | } 22 | 23 | int main(int argc, const char *argv[]) { 24 | duk_context *ctx = NULL; 25 | 26 | ctx = duk_create_heap_default(); 27 | if (!ctx) { 28 | printf("Failed to create a Duktape heap.\n"); 29 | exit(1); 30 | } 31 | 32 | duk_push_global_object(ctx); 33 | duk_push_c_function(ctx, native_prime_check, 2 /*nargs*/); 34 | duk_put_prop_string(ctx, -2, "primeCheckNative"); 35 | 36 | if (duk_peval_file(ctx, "prime.js") != 0) { 37 | printf("Error: %s\n", duk_safe_to_string(ctx, -1)); 38 | goto finished; 39 | } 40 | duk_pop(ctx); /* ignore result */ 41 | 42 | duk_get_prop_string(ctx, -1, "primeTest"); 43 | if (duk_pcall(ctx, 0) != 0) { 44 | printf("Error: %s\n", duk_safe_to_string(ctx, -1)); 45 | } 46 | duk_pop(ctx); /* ignore result */ 47 | 48 | finished: 49 | duk_destroy_heap(ctx); 50 | 51 | exit(0); 52 | } 53 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/guide/process.js: -------------------------------------------------------------------------------- 1 | // process.js 2 | function processLine(line) { 3 | return line.trim() 4 | .replace(/[<>&"'\u0000-\u001F\u007E-\uFFFF]/g, function(x) { 5 | // escape HTML characters 6 | return '&#' + x.charCodeAt(0) + ';' 7 | }) 8 | .replace(/\*(.*?)\*/g, function(x, m) { 9 | // automatically bold text between stars 10 | return '' + m + ''; 11 | }); 12 | } 13 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/guide/processlines.c: -------------------------------------------------------------------------------- 1 | /* processlines.c */ 2 | #include 3 | #include 4 | #include 5 | #include "duktape.h" 6 | 7 | int main(int argc, const char *argv[]) { 8 | duk_context *ctx = NULL; 9 | char line[4096]; 10 | char idx; 11 | int ch; 12 | 13 | ctx = duk_create_heap_default(); 14 | if (!ctx) { 15 | printf("Failed to create a Duktape heap.\n"); 16 | exit(1); 17 | } 18 | 19 | if (duk_peval_file(ctx, "process.js") != 0) { 20 | printf("Error: %s\n", duk_safe_to_string(ctx, -1)); 21 | goto finished; 22 | } 23 | duk_pop(ctx); /* ignore result */ 24 | 25 | memset(line, 0, sizeof(line)); 26 | idx = 0; 27 | for (;;) { 28 | if (idx >= sizeof(line)) { 29 | printf("Line too long\n"); 30 | exit(1); 31 | } 32 | 33 | ch = fgetc(stdin); 34 | if (ch == 0x0a) { 35 | line[idx++] = '\0'; 36 | 37 | duk_push_global_object(ctx); 38 | duk_get_prop_string(ctx, -1 /*index*/, "processLine"); 39 | duk_push_string(ctx, line); 40 | if (duk_pcall(ctx, 1 /*nargs*/) != 0) { 41 | printf("Error: %s\n", duk_safe_to_string(ctx, -1)); 42 | } else { 43 | printf("%s\n", duk_safe_to_string(ctx, -1)); 44 | } 45 | duk_pop(ctx); /* pop result/error */ 46 | 47 | idx = 0; 48 | } else if (ch == EOF) { 49 | break; 50 | } else { 51 | line[idx++] = (char) ch; 52 | } 53 | } 54 | 55 | finished: 56 | duk_destroy_heap(ctx); 57 | 58 | exit(0); 59 | } 60 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/guide/uppercase.c: -------------------------------------------------------------------------------- 1 | /* uppercase.c */ 2 | #include 3 | #include 4 | #include "duktape.h" 5 | 6 | static int dummy_upper_case(duk_context *ctx) { 7 | size_t sz; 8 | const char *val = duk_require_lstring(ctx, 0, &sz); 9 | size_t i; 10 | 11 | /* We're going to need 'sz' additional entries on the stack. */ 12 | duk_require_stack(ctx, sz); 13 | 14 | for (i = 0; i < sz; i++) { 15 | char ch = val[i]; 16 | if (ch >= 'a' && ch <= 'z') { 17 | ch = ch - 'a' + 'A'; 18 | } 19 | duk_push_lstring(ctx, (const char *) &ch, 1); 20 | } 21 | 22 | duk_concat(ctx, sz); 23 | return 1; 24 | } 25 | 26 | int main(int argc, char *argv[]) { 27 | duk_context *ctx; 28 | 29 | if (argc < 2) { exit(1); } 30 | 31 | ctx = duk_create_heap_default(); 32 | if (!ctx) { exit(1); } 33 | 34 | duk_push_c_function(ctx, dummy_upper_case, 1); 35 | duk_push_string(ctx, argv[1]); 36 | duk_call(ctx, 1); 37 | printf("%s -> %s\n", argv[1], duk_to_string(ctx, -1)); 38 | duk_pop(ctx); 39 | 40 | duk_destroy_heap(ctx); 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/hello/README.rst: -------------------------------------------------------------------------------- 1 | =================== 2 | Hello world example 3 | =================== 4 | 5 | Very simple example, most useful for compilation tests. 6 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/hello/hello.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Very simple example program 3 | */ 4 | 5 | #include "duktape.h" 6 | 7 | int adder(duk_context *ctx) { 8 | int i; 9 | int n = duk_get_top(ctx); /* #args */ 10 | double res = 0.0; 11 | 12 | for (i = 0; i < n; i++) { 13 | res += duk_to_number(ctx, i); 14 | } 15 | 16 | duk_push_number(ctx, res); 17 | return 1; /* one return value */ 18 | } 19 | 20 | int main(int argc, char *argv[]) { 21 | duk_context *ctx = duk_create_heap_default(); 22 | 23 | (void) argc; (void) argv; /* suppress warning */ 24 | 25 | duk_eval_string(ctx, "print('Hello world!');"); 26 | 27 | duk_push_global_object(ctx); 28 | duk_push_c_function(ctx, adder, DUK_VARARGS); 29 | duk_put_prop_string(ctx, -2, "adder"); 30 | duk_pop(ctx); /* pop global */ 31 | 32 | duk_eval_string(ctx, "print('2+3=' + adder(2, 3));"); 33 | duk_pop(ctx); /* pop eval result */ 34 | 35 | duk_destroy_heap(ctx); 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/jxpretty/README.rst: -------------------------------------------------------------------------------- 1 | ================ 2 | Jxpretty example 3 | ================ 4 | 5 | Simple command line utility to pretty print JSON in the JX format. 6 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/jxpretty/jxpretty.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Pretty print JSON from stdin into indented JX. 3 | */ 4 | 5 | #include 6 | #include 7 | #include "duktape.h" 8 | 9 | static duk_ret_t do_jxpretty(duk_context *ctx) { 10 | FILE *f = stdin; 11 | char buf[4096]; 12 | size_t ret; 13 | 14 | for (;;) { 15 | if (ferror(f)) { 16 | duk_error(ctx, DUK_ERR_ERROR, "ferror() on stdin"); 17 | } 18 | if (feof(f)) { 19 | break; 20 | } 21 | 22 | ret = fread(buf, 1, sizeof(buf), f); 23 | #if 0 24 | fprintf(stderr, "Read: %ld\n", (long) ret); 25 | fflush(stderr); 26 | #endif 27 | if (ret == 0) { 28 | break; 29 | } 30 | 31 | duk_require_stack(ctx, 1); 32 | duk_push_lstring(ctx, (const char *) buf, ret); 33 | } 34 | 35 | duk_concat(ctx, duk_get_top(ctx)); 36 | 37 | duk_eval_string(ctx, "(function (v) { print(Duktape.enc('jx', JSON.parse(v), null, 4)); })"); 38 | duk_insert(ctx, -2); 39 | duk_call(ctx, 1); 40 | 41 | return 0; 42 | } 43 | 44 | int main(int argc, char *argv[]) { 45 | duk_context *ctx; 46 | duk_int_t rc; 47 | 48 | /* suppress warnings */ 49 | (void) argc; 50 | (void) argv; 51 | 52 | ctx = duk_create_heap_default(); 53 | 54 | rc = duk_safe_call(ctx, do_jxpretty, 0 /*nargs*/, 1 /*nrets*/); 55 | if (rc) { 56 | fprintf(stderr, "ERROR: %s\n", duk_safe_to_string(ctx, -1)); 57 | fflush(stderr); 58 | } 59 | 60 | duk_destroy_heap(ctx); 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /duktape-1.4.0/examples/sandbox/README.rst: -------------------------------------------------------------------------------- 1 | =============== 2 | Sandbox example 3 | =============== 4 | 5 | Very simple, minimal sandboxing example. 6 | -------------------------------------------------------------------------------- /duktape-1.4.0/extras/README.rst: -------------------------------------------------------------------------------- 1 | ============== 2 | Duktape extras 3 | ============== 4 | 5 | Extra modules and utilities. Extras provide functionality that doesn't 6 | comfortably fit into the main Duktape library, perhaps for footprint or 7 | portability reasons, but are still useful for most users. 8 | 9 | Extras are maintained and will be bug fixed. However, they don't have the 10 | same semantic versioning guarantees like the main Duktape library. Extras 11 | may be dropped without warning as Duktape is versioned. For instance, if 12 | an extra breaks due to Duktape changes and there is no time to fix it, the 13 | missing extra won't block a release and will be dropped. 14 | -------------------------------------------------------------------------------- /duktape-1.4.0/licenses/commonjs.txt: -------------------------------------------------------------------------------- 1 | CommonJS specification snapshots are included in the references/ 2 | directory. CommonJS is under the MIT license: http://www.commonjs.org/. 3 | -------------------------------------------------------------------------------- /duktape-1.4.0/licenses/lua.txt: -------------------------------------------------------------------------------- 1 | Lua is under the MIT license: http://www.lua.org/license.html. 2 | -------------------------------------------------------------------------------- /duktape-1.4.0/licenses/murmurhash2.txt: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /duktape-1.4.0/mandel.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Mandelbrot example: 3 | * 4 | * $ ./duk mandel.js 5 | * [...] 6 | */ 7 | 8 | function mandel() { 9 | var w = 76, h = 28, iter = 100; 10 | var i, j, k, c; 11 | var x0, y0, xx, yy, xx2, yy2; 12 | var line; 13 | 14 | for (i = 0; i < h; i++) { 15 | y0 = (i / h) * 2.5 - 1.25; 16 | 17 | for (j = 0, line = []; j < w; j++) { 18 | x0 = (j / w) * 3.0 - 2.0; 19 | 20 | for (k = 0, xx = 0, yy = 0, c = '#'; k < iter; k++) { 21 | /* z -> z^2 + c 22 | * -> (xx+i*yy)^2 + (x0+i*y0) 23 | * -> xx*xx+i*2*xx*yy-yy*yy + x0 + i*y0 24 | * -> (xx*xx - yy*yy + x0) + i*(2*xx*yy + y0) 25 | */ 26 | 27 | xx2 = xx*xx; yy2 = yy*yy; 28 | 29 | if (xx2 + yy2 < 4.0) { 30 | yy = 2*xx*yy + y0; 31 | xx = xx2 - yy2 + x0; 32 | } else { 33 | /* xx^2 + yy^2 >= 4.0 */ 34 | if (k < 3) { c = '.'; } 35 | else if (k < 5) { c = ','; } 36 | else if (k < 10) { c = '-'; } 37 | else { c = '='; } 38 | break; 39 | } 40 | } 41 | 42 | line.push(c); 43 | } 44 | 45 | print(line.join('')); 46 | } 47 | } 48 | 49 | try { 50 | mandel(); 51 | } catch (e) { 52 | print(e.stack || e); 53 | } 54 | -------------------------------------------------------------------------------- /duktape-1.4.0/polyfills/console-minimal.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Minimal console.log() polyfill 3 | */ 4 | 5 | if (typeof console === 'undefined') { 6 | Object.defineProperty(this, 'console', { 7 | value: {}, writable: true, enumerable: false, configurable: true 8 | }); 9 | } 10 | if (typeof console.log === 'undefined') { 11 | (function () { 12 | var origPrint = print; // capture in closure in case changed later 13 | Object.defineProperty(this.console, 'log', { 14 | value: function () { 15 | var strArgs = Array.prototype.map.call(arguments, function (v) { return String(v); }); 16 | origPrint(Array.prototype.join.call(strArgs, ' ')); 17 | }, writable: true, enumerable: false, configurable: true 18 | }); 19 | })(); 20 | } 21 | -------------------------------------------------------------------------------- /duktape-1.4.0/polyfills/duktape-error-setter-nonwritable.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Ensure Error .fileName, .lineNumber, and .stack are not directly writable, 3 | * but can be written using Object.defineProperty(). This matches Duktape 4 | * 1.3.0 and prior. 5 | * 6 | * See: https://github.com/svaarala/duktape/pull/390. 7 | */ 8 | 9 | (function () { 10 | var err = new Error('test'); 11 | err.fileName = 999; 12 | if (err.fileName !== 999) { return; } // already non-writable 13 | 14 | var fn = new Function(''); // nop 15 | Object.defineProperties(Error.prototype, { 16 | fileName: { set: fn }, 17 | lineNumber: { set: fn }, 18 | stack: { set: fn } 19 | }); 20 | })(); 21 | -------------------------------------------------------------------------------- /duktape-1.4.0/polyfills/duktape-error-setter-writable.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Ensure Error .fileName, .lineNumber, and .stack are directly writable 3 | * without having to use Object.defineProperty(). This matches Duktape 4 | * 1.4.0 behavior. 5 | * 6 | * See: https://github.com/svaarala/duktape/pull/390. 7 | */ 8 | 9 | (function () { 10 | var err = new Error('test'); 11 | err.fileName = 999; 12 | if (err.fileName === 999) { return; } // already writable 13 | 14 | Object.defineProperties(Error.prototype, { 15 | fileName: { set: new Function('v', 'Object.defineProperty(this, "fileName", { value: v, writable: true, enumerable: false, configurable: true });') }, 16 | lineNumber: { set: new Function('v', 'Object.defineProperty(this, "lineNumber", { value: v, writable: true, enumerable: false, configurable: true });') }, 17 | stack: { set: new Function('v', 'Object.defineProperty(this, "stack", { value: v, writable: true, enumerable: false, configurable: true });') }, 18 | }); 19 | })(); 20 | -------------------------------------------------------------------------------- /duktape-1.4.0/polyfills/duktape-isfastint.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Helper to check if a number is internally represented as a fastint: 3 | * 4 | * if (Duktape.isFastint(x)) { 5 | * print('fastint'); 6 | * } else { 7 | * print('not a fastint (or not a number)'); 8 | * } 9 | * 10 | * NOTE: This helper depends on the internal tag numbering (defined in 11 | * duk_tval.h) which is both version specific and depends on whether 12 | * duk_tval is packed or not. 13 | */ 14 | 15 | if (typeof Duktape === 'object') { 16 | if (typeof Duktape.fastintTag === 'undefined') { 17 | Object.defineProperty(Duktape, 'fastintTag', { 18 | /* Tag number depends on duk_tval packing. */ 19 | value: (Duktape.info(true)[1] >= 0xfff0) ? 20 | 0xfff1 /* tag for packed duk_tval */ : 21 | 1 /* tag for unpacked duk_tval */, 22 | writable: false, 23 | enumerable: false, 24 | configurable: true 25 | }); 26 | } 27 | if (typeof Duktape.isFastint === 'undefined') { 28 | Object.defineProperty(Duktape, 'isFastint', { 29 | value: function (v) { 30 | return Duktape.info(v)[0] === 4 && /* public type is DUK_TYPE_NUMBER */ 31 | Duktape.info(v)[1] === Duktape.fastintTag; /* internal tag is fastint */ 32 | }, 33 | writable: false, 34 | enumerable: false, 35 | configurable: true 36 | }); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /duktape-1.4.0/polyfills/object-assign.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Object.assign(), described in E6 Section 19.1.2.1 3 | * 4 | * http://www.ecma-international.org/ecma-262/6.0/index.html#sec-object.assign 5 | */ 6 | 7 | if (typeof Object.assign === 'undefined') { 8 | Object.defineProperty(Object, 'assign', { 9 | value: function (target) { 10 | var i, n, j, m, k; 11 | var source, keys; 12 | var gotError; 13 | var pendingError; 14 | 15 | if (target == null) { 16 | throw new Exception('target null or undefined'); 17 | } 18 | 19 | for (i = 1, n = arguments.length; i < n; i++) { 20 | source = arguments[i]; 21 | if (source == null) { 22 | continue; // null or undefined 23 | } 24 | source = Object(source); 25 | keys = Object.keys(source); // enumerable own keys 26 | 27 | for (j = 0, m = keys.length; j < m; j++) { 28 | k = keys[j]; 29 | try { 30 | target[k] = source[k]; 31 | } catch (e) { 32 | if (!gotError) { 33 | gotError = true; 34 | pendingError = e; 35 | } 36 | } 37 | } 38 | } 39 | 40 | if (gotError) { 41 | throw pendingError; 42 | } 43 | }, writable: true, enumerable: false, configurable: true 44 | }); 45 | } 46 | -------------------------------------------------------------------------------- /duktape-1.4.0/polyfills/object-prototype-definegetter.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Object.prototype.__defineGetter__ polyfill 3 | */ 4 | 5 | if (typeof Object.prototype.__defineGetter__ === 'undefined') { 6 | Object.defineProperty(Object.prototype, '__defineGetter__', { 7 | value: function (n, f) { 8 | Object.defineProperty(this, n, { enumerable: true, configurable: true, get: f }); 9 | }, writable: true, enumerable: false, configurable: true 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /duktape-1.4.0/polyfills/object-prototype-definesetter.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Object.prototype.__defineSetter__ polyfill 3 | */ 4 | 5 | if (typeof Object.prototype.__defineSetter__ === 'undefined') { 6 | Object.defineProperty(Object.prototype, '__defineSetter__', { 7 | value: function (n, f) { 8 | Object.defineProperty(this, n, { enumerable: true, configurable: true, set: f }); 9 | }, writable: true, enumerable: false, configurable: true 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /duktape-1.4.0/polyfills/performance-now.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Performance.now() polyfill 3 | * 4 | * http://www.w3.org/TR/hr-time/#sec-high-resolution-time 5 | * 6 | * Dummy implementation which uses the Date built-in and has no higher 7 | * resolution. If/when Duktape has a built-in high resolution timer 8 | * interface, reimplement this. 9 | */ 10 | 11 | var _perfNowZeroTime = Date.now(); 12 | 13 | if (typeof Performance === 'undefined') { 14 | Object.defineProperty(this, 'Performance', { 15 | value: {}, 16 | writable: true, enumerable: false, configurable: true 17 | }); 18 | } 19 | if (typeof Performance.now === 'undefined') { 20 | Object.defineProperty(Performance, 'now', { 21 | value: function () { 22 | return Date.now() - _perfNowZeroTime; 23 | }, writable: true, enumerable: false, configurable: true 24 | }); 25 | } 26 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_alloc_default.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Default allocation functions. 3 | * 4 | * Assumes behavior such as malloc allowing zero size, yielding 5 | * a NULL or a unique pointer which is a no-op for free. 6 | */ 7 | 8 | #include "duk_internal.h" 9 | 10 | DUK_INTERNAL void *duk_default_alloc_function(void *udata, duk_size_t size) { 11 | void *res; 12 | DUK_UNREF(udata); 13 | res = DUK_ANSI_MALLOC(size); 14 | DUK_DDD(DUK_DDDPRINT("default alloc function: %lu -> %p", 15 | (unsigned long) size, (void *) res)); 16 | return res; 17 | } 18 | 19 | DUK_INTERNAL void *duk_default_realloc_function(void *udata, void *ptr, duk_size_t newsize) { 20 | void *res; 21 | DUK_UNREF(udata); 22 | res = DUK_ANSI_REALLOC(ptr, newsize); 23 | DUK_DDD(DUK_DDDPRINT("default realloc function: %p %lu -> %p", 24 | (void *) ptr, (unsigned long) newsize, (void *) res)); 25 | return res; 26 | } 27 | 28 | DUK_INTERNAL void duk_default_free_function(void *udata, void *ptr) { 29 | DUK_DDD(DUK_DDDPRINT("default free function: %p", (void *) ptr)); 30 | DUK_UNREF(udata); 31 | DUK_ANSI_FREE(ptr); 32 | } 33 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_api_buffer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Buffer 3 | */ 4 | 5 | #include "duk_internal.h" 6 | 7 | DUK_EXTERNAL void *duk_resize_buffer(duk_context *ctx, duk_idx_t index, duk_size_t new_size) { 8 | duk_hthread *thr = (duk_hthread *) ctx; 9 | duk_hbuffer_dynamic *h; 10 | 11 | DUK_ASSERT_CTX_VALID(ctx); 12 | 13 | h = (duk_hbuffer_dynamic *) duk_require_hbuffer(ctx, index); 14 | DUK_ASSERT(h != NULL); 15 | 16 | if (!(DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h))) { 17 | DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, DUK_STR_WRONG_BUFFER_TYPE); 18 | } 19 | 20 | /* maximum size check is handled by callee */ 21 | duk_hbuffer_resize(thr, h, new_size); 22 | 23 | return DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h); 24 | } 25 | 26 | DUK_EXTERNAL void *duk_steal_buffer(duk_context *ctx, duk_idx_t index, duk_size_t *out_size) { 27 | duk_hthread *thr = (duk_hthread *) ctx; 28 | duk_hbuffer_dynamic *h; 29 | void *ptr; 30 | duk_size_t sz; 31 | 32 | DUK_ASSERT(ctx != NULL); 33 | 34 | h = (duk_hbuffer_dynamic *) duk_require_hbuffer(ctx, index); 35 | DUK_ASSERT(h != NULL); 36 | 37 | if (!(DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h))) { 38 | DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, DUK_STR_WRONG_BUFFER_TYPE); 39 | } 40 | 41 | /* Forget the previous allocation, setting size to 0 and alloc to 42 | * NULL. Caller is responsible for freeing the previous allocation. 43 | * Getting the allocation and clearing it is done in the same API 44 | * call to avoid any chance of a realloc. 45 | */ 46 | ptr = DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h); 47 | sz = DUK_HBUFFER_DYNAMIC_GET_SIZE(h); 48 | if (out_size) { 49 | *out_size = sz; 50 | } 51 | DUK_HBUFFER_DYNAMIC_SET_DATA_PTR_NULL(thr->heap, h); 52 | DUK_HBUFFER_DYNAMIC_SET_SIZE(h, 0); 53 | 54 | return ptr; 55 | } 56 | 57 | DUK_EXTERNAL void duk_config_buffer(duk_context *ctx, duk_idx_t index, void *ptr, duk_size_t len) { 58 | duk_hthread *thr = (duk_hthread *) ctx; 59 | duk_hbuffer_external *h; 60 | 61 | DUK_ASSERT(ctx != NULL); 62 | 63 | h = (duk_hbuffer_external *) duk_require_hbuffer(ctx, index); 64 | DUK_ASSERT(h != NULL); 65 | 66 | if (!DUK_HBUFFER_HAS_EXTERNAL(h)) { 67 | DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, DUK_STR_WRONG_BUFFER_TYPE); 68 | } 69 | DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(h)); 70 | 71 | DUK_HBUFFER_EXTERNAL_SET_DATA_PTR(thr->heap, h, ptr); 72 | DUK_HBUFFER_EXTERNAL_SET_SIZE(h, len); 73 | } 74 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_api_heap.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Heap creation and destruction 3 | */ 4 | 5 | #include "duk_internal.h" 6 | 7 | DUK_EXTERNAL 8 | duk_context *duk_create_heap(duk_alloc_function alloc_func, 9 | duk_realloc_function realloc_func, 10 | duk_free_function free_func, 11 | void *heap_udata, 12 | duk_fatal_function fatal_handler) { 13 | duk_heap *heap = NULL; 14 | duk_context *ctx; 15 | 16 | /* Assume that either all memory funcs are NULL or non-NULL, mixed 17 | * cases will now be unsafe. 18 | */ 19 | 20 | /* XXX: just assert non-NULL values here and make caller arguments 21 | * do the defaulting to the default implementations (smaller code)? 22 | */ 23 | 24 | if (!alloc_func) { 25 | DUK_ASSERT(realloc_func == NULL); 26 | DUK_ASSERT(free_func == NULL); 27 | alloc_func = duk_default_alloc_function; 28 | realloc_func = duk_default_realloc_function; 29 | free_func = duk_default_free_function; 30 | } else { 31 | DUK_ASSERT(realloc_func != NULL); 32 | DUK_ASSERT(free_func != NULL); 33 | } 34 | 35 | if (!fatal_handler) { 36 | fatal_handler = duk_default_fatal_handler; 37 | } 38 | 39 | DUK_ASSERT(alloc_func != NULL); 40 | DUK_ASSERT(realloc_func != NULL); 41 | DUK_ASSERT(free_func != NULL); 42 | DUK_ASSERT(fatal_handler != NULL); 43 | 44 | heap = duk_heap_alloc(alloc_func, realloc_func, free_func, heap_udata, fatal_handler); 45 | if (!heap) { 46 | return NULL; 47 | } 48 | ctx = (duk_context *) heap->heap_thread; 49 | DUK_ASSERT(ctx != NULL); 50 | DUK_ASSERT(((duk_hthread *) ctx)->heap != NULL); 51 | return ctx; 52 | } 53 | 54 | DUK_EXTERNAL void duk_destroy_heap(duk_context *ctx) { 55 | duk_hthread *thr = (duk_hthread *) ctx; 56 | duk_heap *heap; 57 | 58 | if (!ctx) { 59 | return; 60 | } 61 | heap = thr->heap; 62 | DUK_ASSERT(heap != NULL); 63 | 64 | duk_heap_free(heap); 65 | } 66 | 67 | /* XXX: better place for this */ 68 | DUK_EXTERNAL void duk_set_global_object(duk_context *ctx) { 69 | duk_hthread *thr = (duk_hthread *) ctx; 70 | duk_hobject *h_glob; 71 | duk_hobject *h_prev_glob; 72 | duk_hobject *h_env; 73 | duk_hobject *h_prev_env; 74 | 75 | DUK_D(DUK_DPRINT("replace global object with: %!T", duk_get_tval(ctx, -1))); 76 | 77 | h_glob = duk_require_hobject(ctx, -1); 78 | DUK_ASSERT(h_glob != NULL); 79 | 80 | /* 81 | * Replace global object. 82 | */ 83 | 84 | h_prev_glob = thr->builtins[DUK_BIDX_GLOBAL]; 85 | DUK_UNREF(h_prev_glob); 86 | thr->builtins[DUK_BIDX_GLOBAL] = h_glob; 87 | DUK_HOBJECT_INCREF(thr, h_glob); 88 | DUK_HOBJECT_DECREF_ALLOWNULL(thr, h_prev_glob); /* side effects, in theory (referenced by global env) */ 89 | 90 | /* 91 | * Replace lexical environment for global scope 92 | * 93 | * Create a new object environment for the global lexical scope. 94 | * We can't just reset the _Target property of the current one, 95 | * because the lexical scope is shared by other threads with the 96 | * same (initial) built-ins. 97 | */ 98 | 99 | (void) duk_push_object_helper(ctx, 100 | DUK_HOBJECT_FLAG_EXTENSIBLE | 101 | DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV), 102 | -1); /* no prototype, updated below */ 103 | 104 | duk_dup(ctx, -2); 105 | duk_dup(ctx, -3); 106 | 107 | /* [ ... new_glob new_env new_glob new_glob ] */ 108 | 109 | duk_xdef_prop_stridx(thr, -3, DUK_STRIDX_INT_TARGET, DUK_PROPDESC_FLAGS_NONE); 110 | duk_xdef_prop_stridx(thr, -2, DUK_STRIDX_INT_THIS, DUK_PROPDESC_FLAGS_NONE); 111 | 112 | /* [ ... new_glob new_env ] */ 113 | 114 | h_env = duk_get_hobject(ctx, -1); 115 | DUK_ASSERT(h_env != NULL); 116 | 117 | h_prev_env = thr->builtins[DUK_BIDX_GLOBAL_ENV]; 118 | thr->builtins[DUK_BIDX_GLOBAL_ENV] = h_env; 119 | DUK_HOBJECT_INCREF(thr, h_env); 120 | DUK_HOBJECT_DECREF_ALLOWNULL(thr, h_prev_env); /* side effects */ 121 | DUK_UNREF(h_env); /* without refcounts */ 122 | DUK_UNREF(h_prev_env); 123 | 124 | /* [ ... new_glob new_env ] */ 125 | 126 | duk_pop_2(ctx); 127 | 128 | /* [ ... ] */ 129 | } 130 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_api_logging.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Logging 3 | * 4 | * Current logging primitive is a sprintf-style log which is convenient 5 | * for most C code. Another useful primitive would be to log N arguments 6 | * from value stack (like the Ecmascript binding does). 7 | */ 8 | 9 | #include "duk_internal.h" 10 | 11 | DUK_EXTERNAL void duk_log_va(duk_context *ctx, duk_int_t level, const char *fmt, va_list ap) { 12 | /* stridx_logfunc[] must be static to allow initializer with old compilers like BCC */ 13 | static const duk_uint16_t stridx_logfunc[6] = { 14 | DUK_STRIDX_LC_TRACE, DUK_STRIDX_LC_DEBUG, DUK_STRIDX_LC_INFO, 15 | DUK_STRIDX_LC_WARN, DUK_STRIDX_LC_ERROR, DUK_STRIDX_LC_FATAL 16 | }; 17 | 18 | DUK_ASSERT_CTX_VALID(ctx); 19 | 20 | if (level < 0) { 21 | level = 0; 22 | } else if (level > (int) (sizeof(stridx_logfunc) / sizeof(duk_uint16_t)) - 1) { 23 | level = (int) (sizeof(stridx_logfunc) / sizeof(duk_uint16_t)) - 1; 24 | } 25 | 26 | duk_push_hobject_bidx(ctx, DUK_BIDX_LOGGER_CONSTRUCTOR); 27 | duk_get_prop_stridx(ctx, -1, DUK_STRIDX_CLOG); 28 | duk_get_prop_stridx(ctx, -1, stridx_logfunc[level]); 29 | duk_dup(ctx, -2); 30 | 31 | /* [ ... Logger clog logfunc clog ] */ 32 | 33 | duk_push_vsprintf(ctx, fmt, ap); 34 | 35 | /* [ ... Logger clog logfunc clog(=this) msg ] */ 36 | 37 | duk_call_method(ctx, 1 /*nargs*/); 38 | 39 | /* [ ... Logger clog res ] */ 40 | 41 | duk_pop_3(ctx); 42 | } 43 | 44 | DUK_EXTERNAL void duk_log(duk_context *ctx, duk_int_t level, const char *fmt, ...) { 45 | va_list ap; 46 | 47 | DUK_ASSERT_CTX_VALID(ctx); 48 | 49 | va_start(ap, fmt); 50 | duk_log_va(ctx, level, fmt, ap); 51 | va_end(ap); 52 | } 53 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_api_memory.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Memory calls. 3 | */ 4 | 5 | #include "duk_internal.h" 6 | 7 | DUK_EXTERNAL void *duk_alloc_raw(duk_context *ctx, duk_size_t size) { 8 | duk_hthread *thr = (duk_hthread *) ctx; 9 | 10 | DUK_ASSERT_CTX_VALID(ctx); 11 | 12 | return DUK_ALLOC_RAW(thr->heap, size); 13 | } 14 | 15 | DUK_EXTERNAL void duk_free_raw(duk_context *ctx, void *ptr) { 16 | duk_hthread *thr = (duk_hthread *) ctx; 17 | 18 | DUK_ASSERT_CTX_VALID(ctx); 19 | 20 | DUK_FREE_RAW(thr->heap, ptr); 21 | } 22 | 23 | DUK_EXTERNAL void *duk_realloc_raw(duk_context *ctx, void *ptr, duk_size_t size) { 24 | duk_hthread *thr = (duk_hthread *) ctx; 25 | 26 | DUK_ASSERT_CTX_VALID(ctx); 27 | 28 | return DUK_REALLOC_RAW(thr->heap, ptr, size); 29 | } 30 | 31 | DUK_EXTERNAL void *duk_alloc(duk_context *ctx, duk_size_t size) { 32 | duk_hthread *thr = (duk_hthread *) ctx; 33 | 34 | DUK_ASSERT_CTX_VALID(ctx); 35 | 36 | return DUK_ALLOC(thr->heap, size); 37 | } 38 | 39 | DUK_EXTERNAL void duk_free(duk_context *ctx, void *ptr) { 40 | duk_hthread *thr = (duk_hthread *) ctx; 41 | 42 | DUK_ASSERT_CTX_VALID(ctx); 43 | 44 | DUK_FREE(thr->heap, ptr); 45 | } 46 | 47 | DUK_EXTERNAL void *duk_realloc(duk_context *ctx, void *ptr, duk_size_t size) { 48 | duk_hthread *thr = (duk_hthread *) ctx; 49 | 50 | DUK_ASSERT_CTX_VALID(ctx); 51 | 52 | /* 53 | * Note: since this is an exposed API call, there should be 54 | * no way a mark-and-sweep could have a side effect on the 55 | * memory allocation behind 'ptr'; the pointer should never 56 | * be something that Duktape wants to change. 57 | * 58 | * Thus, no need to use DUK_REALLOC_INDIRECT (and we don't 59 | * have the storage location here anyway). 60 | */ 61 | 62 | return DUK_REALLOC(thr->heap, ptr, size); 63 | } 64 | 65 | DUK_EXTERNAL void duk_get_memory_functions(duk_context *ctx, duk_memory_functions *out_funcs) { 66 | duk_hthread *thr = (duk_hthread *) ctx; 67 | duk_heap *heap; 68 | 69 | DUK_ASSERT_CTX_VALID(ctx); 70 | DUK_ASSERT(out_funcs != NULL); 71 | DUK_ASSERT(thr != NULL); 72 | DUK_ASSERT(thr->heap != NULL); 73 | 74 | heap = thr->heap; 75 | out_funcs->alloc_func = heap->alloc_func; 76 | out_funcs->realloc_func = heap->realloc_func; 77 | out_funcs->free_func = heap->free_func; 78 | out_funcs->udata = heap->heap_udata; 79 | } 80 | 81 | DUK_EXTERNAL void duk_gc(duk_context *ctx, duk_uint_t flags) { 82 | #ifdef DUK_USE_MARK_AND_SWEEP 83 | duk_hthread *thr = (duk_hthread *) ctx; 84 | duk_heap *heap; 85 | 86 | DUK_UNREF(flags); 87 | 88 | /* NULL accepted */ 89 | if (!ctx) { 90 | return; 91 | } 92 | DUK_ASSERT_CTX_VALID(ctx); 93 | heap = thr->heap; 94 | DUK_ASSERT(heap != NULL); 95 | 96 | DUK_D(DUK_DPRINT("mark-and-sweep requested by application")); 97 | duk_heap_mark_and_sweep(heap, 0); 98 | #else 99 | DUK_D(DUK_DPRINT("mark-and-sweep requested by application but mark-and-sweep not enabled, ignoring")); 100 | DUK_UNREF(ctx); 101 | DUK_UNREF(flags); 102 | #endif 103 | } 104 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_api_var.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Variable access 3 | */ 4 | 5 | #include "duk_internal.h" 6 | 7 | DUK_EXTERNAL void duk_get_var(duk_context *ctx) { 8 | duk_hthread *thr = (duk_hthread *) ctx; 9 | duk_activation *act; 10 | duk_hstring *h_varname; 11 | duk_small_int_t throw_flag = 1; /* always throw ReferenceError for unresolvable */ 12 | 13 | DUK_ASSERT_CTX_VALID(ctx); 14 | 15 | h_varname = duk_require_hstring(ctx, -1); /* XXX: tostring? */ 16 | DUK_ASSERT(h_varname != NULL); 17 | 18 | act = duk_hthread_get_current_activation(thr); 19 | if (act) { 20 | (void) duk_js_getvar_activation(thr, act, h_varname, throw_flag); /* -> [ ... varname val this ] */ 21 | } else { 22 | /* Outside any activation -> look up from global. */ 23 | DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL_ENV] != NULL); 24 | (void) duk_js_getvar_envrec(thr, thr->builtins[DUK_BIDX_GLOBAL_ENV], h_varname, throw_flag); 25 | } 26 | 27 | /* [ ... varname val this ] (because throw_flag == 1, always resolved) */ 28 | 29 | duk_pop(ctx); 30 | duk_remove(ctx, -2); 31 | 32 | /* [ ... val ] */ 33 | 34 | /* Return value would be pointless: because throw_flag==1, we always 35 | * throw if the identifier doesn't resolve. 36 | */ 37 | return; 38 | } 39 | 40 | DUK_EXTERNAL void duk_put_var(duk_context *ctx) { 41 | duk_hthread *thr = (duk_hthread *) ctx; 42 | duk_activation *act; 43 | duk_hstring *h_varname; 44 | duk_tval *tv_val; 45 | duk_small_int_t throw_flag; 46 | 47 | DUK_ASSERT_CTX_VALID(ctx); 48 | 49 | h_varname = duk_require_hstring(ctx, -2); /* XXX: tostring? */ 50 | DUK_ASSERT(h_varname != NULL); 51 | 52 | tv_val = duk_require_tval(ctx, -1); 53 | 54 | throw_flag = duk_is_strict_call(ctx); 55 | 56 | act = duk_hthread_get_current_activation(thr); 57 | if (act) { 58 | duk_js_putvar_activation(thr, act, h_varname, tv_val, throw_flag); /* -> [ ... varname val this ] */ 59 | } else { 60 | /* Outside any activation -> put to global. */ 61 | DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL_ENV] != NULL); 62 | duk_js_putvar_envrec(thr, thr->builtins[DUK_BIDX_GLOBAL_ENV], h_varname, tv_val, throw_flag); 63 | } 64 | 65 | /* [ ... varname val ] */ 66 | 67 | duk_pop_2(ctx); 68 | 69 | /* [ ... ] */ 70 | 71 | return; 72 | } 73 | 74 | DUK_EXTERNAL duk_bool_t duk_del_var(duk_context *ctx) { 75 | DUK_ASSERT_CTX_VALID(ctx); 76 | 77 | DUK_ERROR((duk_hthread *) ctx, DUK_ERR_UNIMPLEMENTED_ERROR, DUK_STR_UNIMPLEMENTED); 78 | return 0; 79 | } 80 | 81 | DUK_EXTERNAL duk_bool_t duk_has_var(duk_context *ctx) { 82 | DUK_ASSERT_CTX_VALID(ctx); 83 | 84 | DUK_ERROR((duk_hthread *) ctx, DUK_ERR_UNIMPLEMENTED_ERROR, DUK_STR_UNIMPLEMENTED); 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_bi_boolean.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Boolean built-ins 3 | */ 4 | 5 | #include "duk_internal.h" 6 | 7 | /* Shared helper to provide toString() and valueOf(). Checks 'this', gets 8 | * the primitive value to stack top, and optionally coerces with ToString(). 9 | */ 10 | DUK_INTERNAL duk_ret_t duk_bi_boolean_prototype_tostring_shared(duk_context *ctx) { 11 | duk_tval *tv; 12 | duk_hobject *h; 13 | duk_small_int_t coerce_tostring = duk_get_current_magic(ctx); 14 | 15 | /* XXX: there is room to use a shared helper here, many built-ins 16 | * check the 'this' type, and if it's an object, check its class, 17 | * then get its internal value, etc. 18 | */ 19 | 20 | duk_push_this(ctx); 21 | tv = duk_get_tval(ctx, -1); 22 | DUK_ASSERT(tv != NULL); 23 | 24 | if (DUK_TVAL_IS_BOOLEAN(tv)) { 25 | goto type_ok; 26 | } else if (DUK_TVAL_IS_OBJECT(tv)) { 27 | h = DUK_TVAL_GET_OBJECT(tv); 28 | DUK_ASSERT(h != NULL); 29 | 30 | if (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_BOOLEAN) { 31 | duk_get_prop_stridx(ctx, -1, DUK_STRIDX_INT_VALUE); 32 | DUK_ASSERT(duk_is_boolean(ctx, -1)); 33 | goto type_ok; 34 | } 35 | } 36 | 37 | return DUK_RET_TYPE_ERROR; 38 | 39 | type_ok: 40 | if (coerce_tostring) { 41 | duk_to_string(ctx, -1); 42 | } 43 | return 1; 44 | } 45 | 46 | DUK_INTERNAL duk_ret_t duk_bi_boolean_constructor(duk_context *ctx) { 47 | duk_hthread *thr = (duk_hthread *) ctx; 48 | duk_hobject *h_this; 49 | 50 | DUK_UNREF(thr); 51 | 52 | duk_to_boolean(ctx, 0); 53 | 54 | if (duk_is_constructor_call(ctx)) { 55 | /* XXX: helper; rely on Boolean.prototype as being non-writable, non-configurable */ 56 | duk_push_this(ctx); 57 | h_this = duk_get_hobject(ctx, -1); 58 | DUK_ASSERT(h_this != NULL); 59 | DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_this) == thr->builtins[DUK_BIDX_BOOLEAN_PROTOTYPE]); 60 | 61 | DUK_HOBJECT_SET_CLASS_NUMBER(h_this, DUK_HOBJECT_CLASS_BOOLEAN); 62 | 63 | duk_dup(ctx, 0); /* -> [ val obj val ] */ 64 | duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE); /* XXX: proper flags? */ 65 | } /* unbalanced stack */ 66 | 67 | return 1; 68 | } 69 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_bi_date_sgx.c: -------------------------------------------------------------------------------- 1 | #include "duk_internal.h" 2 | DUK_INTERNAL duk_double_t duk_bi_date_get_now_sgx(duk_context *ctx) { 3 | // TODO: Implement. 4 | return 0; 5 | } 6 | DUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_sgx(duk_double_t d) { 7 | // TODO: Implement. 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_bi_date_windows.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Windows Date providers 3 | * 4 | * Platform specific links: 5 | * 6 | * - http://msdn.microsoft.com/en-us/library/windows/desktop/ms725473(v=vs.85).aspx 7 | */ 8 | 9 | #include "duk_internal.h" 10 | 11 | /* The necessary #includes are in place in duk_config.h. */ 12 | 13 | #if defined(DUK_USE_DATE_NOW_WINDOWS) || defined(DUK_USE_DATE_TZO_WINDOWS) 14 | /* Shared Windows helpers. */ 15 | DUK_LOCAL void duk__convert_systime_to_ularge(const SYSTEMTIME *st, ULARGE_INTEGER *res) { 16 | FILETIME ft; 17 | if (SystemTimeToFileTime(st, &ft) == 0) { 18 | DUK_D(DUK_DPRINT("SystemTimeToFileTime() failed, returning 0")); 19 | res->QuadPart = 0; 20 | } else { 21 | res->LowPart = ft.dwLowDateTime; 22 | res->HighPart = ft.dwHighDateTime; 23 | } 24 | } 25 | DUK_LOCAL void duk__set_systime_jan1970(SYSTEMTIME *st) { 26 | DUK_MEMZERO((void *) st, sizeof(*st)); 27 | st->wYear = 1970; 28 | st->wMonth = 1; 29 | st->wDayOfWeek = 4; /* not sure whether or not needed; Thursday */ 30 | st->wDay = 1; 31 | DUK_ASSERT(st->wHour == 0); 32 | DUK_ASSERT(st->wMinute == 0); 33 | DUK_ASSERT(st->wSecond == 0); 34 | DUK_ASSERT(st->wMilliseconds == 0); 35 | } 36 | #endif /* defined(DUK_USE_DATE_NOW_WINDOWS) || defined(DUK_USE_DATE_TZO_WINDOWS) */ 37 | 38 | #ifdef DUK_USE_DATE_NOW_WINDOWS 39 | DUK_INTERNAL duk_double_t duk_bi_date_get_now_windows(duk_context *ctx) { 40 | /* Suggested step-by-step method from documentation of RtlTimeToSecondsSince1970: 41 | * http://msdn.microsoft.com/en-us/library/windows/desktop/ms724928(v=vs.85).aspx 42 | */ 43 | SYSTEMTIME st1, st2; 44 | ULARGE_INTEGER tmp1, tmp2; 45 | 46 | DUK_UNREF(ctx); 47 | 48 | GetSystemTime(&st1); 49 | duk__convert_systime_to_ularge((const SYSTEMTIME *) &st1, &tmp1); 50 | 51 | duk__set_systime_jan1970(&st2); 52 | duk__convert_systime_to_ularge((const SYSTEMTIME *) &st2, &tmp2); 53 | 54 | /* Difference is in 100ns units, convert to milliseconds w/o fractions */ 55 | return (duk_double_t) ((tmp1.QuadPart - tmp2.QuadPart) / 10000LL); 56 | } 57 | #endif /* DUK_USE_DATE_NOW_WINDOWS */ 58 | 59 | 60 | #if defined(DUK_USE_DATE_TZO_WINDOWS) 61 | DUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_windows(duk_double_t d) { 62 | SYSTEMTIME st1; 63 | SYSTEMTIME st2; 64 | SYSTEMTIME st3; 65 | ULARGE_INTEGER tmp1; 66 | ULARGE_INTEGER tmp2; 67 | ULARGE_INTEGER tmp3; 68 | FILETIME ft1; 69 | 70 | /* XXX: handling of timestamps outside Windows supported range. 71 | * How does Windows deal with dates before 1600? Does windows 72 | * support all Ecmascript years (like -200000 and +200000)? 73 | * Should equivalent year mapping be used here too? If so, use 74 | * a shared helper (currently integrated into timeval-to-parts). 75 | */ 76 | 77 | /* Use the approach described in "Remarks" of FileTimeToLocalFileTime: 78 | * http://msdn.microsoft.com/en-us/library/windows/desktop/ms724277(v=vs.85).aspx 79 | */ 80 | 81 | duk__set_systime_jan1970(&st1); 82 | duk__convert_systime_to_ularge((const SYSTEMTIME *) &st1, &tmp1); 83 | tmp2.QuadPart = (ULONGLONG) (d * 10000.0); /* millisec -> 100ns units since jan 1, 1970 */ 84 | tmp2.QuadPart += tmp1.QuadPart; /* input 'd' in Windows UTC, 100ns units */ 85 | 86 | ft1.dwLowDateTime = tmp2.LowPart; 87 | ft1.dwHighDateTime = tmp2.HighPart; 88 | FileTimeToSystemTime((const FILETIME *) &ft1, &st2); 89 | if (SystemTimeToTzSpecificLocalTime((LPTIME_ZONE_INFORMATION) NULL, &st2, &st3) == 0) { 90 | DUK_D(DUK_DPRINT("SystemTimeToTzSpecificLocalTime() failed, return tzoffset 0")); 91 | return 0; 92 | } 93 | duk__convert_systime_to_ularge((const SYSTEMTIME *) &st3, &tmp3); 94 | 95 | /* Positive if local time ahead of UTC. */ 96 | return (duk_int_t) (((LONGLONG) tmp3.QuadPart - (LONGLONG) tmp2.QuadPart) / 10000000LL); /* seconds */ 97 | } 98 | #endif /* DUK_USE_DATE_TZO_WINDOWS */ 99 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_bi_pointer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Pointer built-ins 3 | */ 4 | 5 | #include "duk_internal.h" 6 | 7 | /* 8 | * Constructor 9 | */ 10 | 11 | DUK_INTERNAL duk_ret_t duk_bi_pointer_constructor(duk_context *ctx) { 12 | /* XXX: this behavior is quite useless now; it would be nice to be able 13 | * to create pointer values from e.g. numbers or strings. Numbers are 14 | * problematic on 64-bit platforms though. Hex encoded strings? 15 | */ 16 | if (duk_get_top(ctx) == 0) { 17 | duk_push_pointer(ctx, NULL); 18 | } else { 19 | duk_to_pointer(ctx, 0); 20 | } 21 | DUK_ASSERT(duk_is_pointer(ctx, 0)); 22 | duk_set_top(ctx, 1); 23 | 24 | if (duk_is_constructor_call(ctx)) { 25 | duk_push_object_helper(ctx, 26 | DUK_HOBJECT_FLAG_EXTENSIBLE | 27 | DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_POINTER), 28 | DUK_BIDX_POINTER_PROTOTYPE); 29 | 30 | /* Pointer object internal value is immutable */ 31 | duk_dup(ctx, 0); 32 | duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE); 33 | } 34 | /* Note: unbalanced stack on purpose */ 35 | 36 | return 1; 37 | } 38 | 39 | /* 40 | * toString(), valueOf() 41 | */ 42 | 43 | DUK_INTERNAL duk_ret_t duk_bi_pointer_prototype_tostring_shared(duk_context *ctx) { 44 | duk_tval *tv; 45 | duk_small_int_t to_string = duk_get_current_magic(ctx); 46 | 47 | duk_push_this(ctx); 48 | tv = duk_require_tval(ctx, -1); 49 | DUK_ASSERT(tv != NULL); 50 | 51 | if (DUK_TVAL_IS_POINTER(tv)) { 52 | /* nop */ 53 | } else if (DUK_TVAL_IS_OBJECT(tv)) { 54 | duk_hobject *h = DUK_TVAL_GET_OBJECT(tv); 55 | DUK_ASSERT(h != NULL); 56 | 57 | /* Must be a "pointer object", i.e. class "Pointer" */ 58 | if (DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_POINTER) { 59 | goto type_error; 60 | } 61 | 62 | duk_get_prop_stridx(ctx, -1, DUK_STRIDX_INT_VALUE); 63 | } else { 64 | goto type_error; 65 | } 66 | 67 | if (to_string) { 68 | duk_to_string(ctx, -1); 69 | } 70 | return 1; 71 | 72 | type_error: 73 | return DUK_RET_TYPE_ERROR; 74 | } 75 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_bi_proxy.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Proxy built-in (ES6) 3 | */ 4 | 5 | #include "duk_internal.h" 6 | 7 | #if defined(DUK_USE_ES6_PROXY) 8 | DUK_INTERNAL duk_ret_t duk_bi_proxy_constructor(duk_context *ctx) { 9 | duk_hobject *h_target; 10 | duk_hobject *h_handler; 11 | 12 | if (!duk_is_constructor_call(ctx)) { 13 | return DUK_RET_TYPE_ERROR; 14 | } 15 | 16 | /* Reject a proxy object as the target because it would need 17 | * special handler in property lookups. (ES6 has no such restriction) 18 | */ 19 | h_target = duk_require_hobject_or_lfunc_coerce(ctx, 0); 20 | DUK_ASSERT(h_target != NULL); 21 | if (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h_target)) { 22 | return DUK_RET_TYPE_ERROR; 23 | } 24 | 25 | /* Reject a proxy object as the handler because it would cause 26 | * potentially unbounded recursion. (ES6 has no such restriction) 27 | */ 28 | h_handler = duk_require_hobject_or_lfunc_coerce(ctx, 1); 29 | DUK_ASSERT(h_handler != NULL); 30 | if (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h_handler)) { 31 | return DUK_RET_TYPE_ERROR; 32 | } 33 | 34 | /* XXX: the returned value is exotic in ES6, but we use a 35 | * simple object here with no prototype. Without a prototype, 36 | * [[DefaultValue]] coercion fails which is abit confusing. 37 | * No callable check/handling in the current Proxy subset. 38 | */ 39 | (void) duk_push_object_helper_proto(ctx, 40 | DUK_HOBJECT_FLAG_EXTENSIBLE | 41 | DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ | 42 | DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT), 43 | NULL); 44 | DUK_ASSERT_TOP(ctx, 3); 45 | 46 | /* Make _Target and _Handler non-configurable and non-writable. 47 | * They can still be forcibly changed by C code (both user and 48 | * Duktape internal), but not by Ecmascript code. 49 | */ 50 | 51 | /* Proxy target */ 52 | duk_dup(ctx, 0); 53 | duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_INT_TARGET, DUK_PROPDESC_FLAGS_NONE); 54 | 55 | /* Proxy handler */ 56 | duk_dup(ctx, 1); 57 | duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_INT_HANDLER, DUK_PROPDESC_FLAGS_NONE); 58 | 59 | return 1; /* replacement handler */ 60 | } 61 | #else /* DUK_USE_ES6_PROXY */ 62 | DUK_INTERNAL duk_ret_t duk_bi_proxy_constructor(duk_context *ctx) { 63 | DUK_UNREF(ctx); 64 | return DUK_RET_UNSUPPORTED_ERROR; 65 | } 66 | #endif /* DUK_USE_ES6_PROXY */ 67 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_bi_thrower.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Type error thrower, E5 Section 13.2.3. 3 | */ 4 | 5 | #include "duk_internal.h" 6 | 7 | DUK_INTERNAL duk_ret_t duk_bi_type_error_thrower(duk_context *ctx) { 8 | DUK_UNREF(ctx); 9 | return DUK_RET_TYPE_ERROR; 10 | } 11 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_debug_fixedbuffer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Fixed buffer helper useful for debugging, requires no allocation 3 | * which is critical for debugging. 4 | */ 5 | 6 | #include "duk_internal.h" 7 | 8 | #ifdef DUK_USE_DEBUG 9 | 10 | DUK_INTERNAL void duk_fb_put_bytes(duk_fixedbuffer *fb, const duk_uint8_t *buffer, duk_size_t length) { 11 | duk_size_t avail; 12 | duk_size_t copylen; 13 | 14 | avail = (fb->offset >= fb->length ? (duk_size_t) 0 : (duk_size_t) (fb->length - fb->offset)); 15 | if (length > avail) { 16 | copylen = avail; 17 | fb->truncated = 1; 18 | } else { 19 | copylen = length; 20 | } 21 | DUK_MEMCPY(fb->buffer + fb->offset, buffer, copylen); 22 | fb->offset += copylen; 23 | } 24 | 25 | DUK_INTERNAL void duk_fb_put_byte(duk_fixedbuffer *fb, duk_uint8_t x) { 26 | duk_fb_put_bytes(fb, (const duk_uint8_t *) &x, 1); 27 | } 28 | 29 | DUK_INTERNAL void duk_fb_put_cstring(duk_fixedbuffer *fb, const char *x) { 30 | duk_fb_put_bytes(fb, (const duk_uint8_t *) x, (duk_size_t) DUK_STRLEN(x)); 31 | } 32 | 33 | DUK_INTERNAL void duk_fb_sprintf(duk_fixedbuffer *fb, const char *fmt, ...) { 34 | duk_size_t avail; 35 | va_list ap; 36 | 37 | va_start(ap, fmt); 38 | avail = (fb->offset >= fb->length ? (duk_size_t) 0 : (duk_size_t) (fb->length - fb->offset)); 39 | if (avail > 0) { 40 | duk_int_t res = (duk_int_t) DUK_VSNPRINTF((char *) (fb->buffer + fb->offset), avail, fmt, ap); 41 | if (res < 0) { 42 | /* error */ 43 | } else if ((duk_size_t) res >= avail) { 44 | /* (maybe) truncated */ 45 | fb->offset += avail; 46 | if ((duk_size_t) res > avail) { 47 | /* actual chars dropped (not just NUL term) */ 48 | fb->truncated = 1; 49 | } 50 | } else { 51 | /* normal */ 52 | fb->offset += res; 53 | } 54 | } 55 | va_end(ap); 56 | } 57 | 58 | DUK_INTERNAL void duk_fb_put_funcptr(duk_fixedbuffer *fb, duk_uint8_t *fptr, duk_size_t fptr_size) { 59 | char buf[64+1]; 60 | duk_debug_format_funcptr(buf, sizeof(buf), fptr, fptr_size); 61 | buf[sizeof(buf) - 1] = (char) 0; 62 | duk_fb_put_cstring(fb, buf); 63 | } 64 | 65 | DUK_INTERNAL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb) { 66 | return (fb->offset >= fb->length); 67 | } 68 | 69 | #endif /* DUK_USE_DEBUG */ 70 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_debug_macros.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Debugging macro calls. 3 | */ 4 | 5 | #include "duk_internal.h" 6 | 7 | #ifdef DUK_USE_DEBUG 8 | 9 | /* 10 | * Debugging enabled 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #define DUK__DEBUG_BUFSIZE DUK_USE_DEBUG_BUFSIZE 18 | DUK_LOCAL char duk__debug_buf[DUK__DEBUG_BUFSIZE]; 19 | 20 | DUK_LOCAL const char *duk__get_level_string(duk_small_int_t level) { 21 | switch ((int) level) { 22 | case DUK_LEVEL_DEBUG: 23 | return "D"; 24 | case DUK_LEVEL_DDEBUG: 25 | return "DD"; 26 | case DUK_LEVEL_DDDEBUG: 27 | return "DDD"; 28 | } 29 | return "???"; 30 | } 31 | 32 | #ifdef DUK_USE_DPRINT_COLORS 33 | 34 | /* http://en.wikipedia.org/wiki/ANSI_escape_code */ 35 | #define DUK__TERM_REVERSE "\x1b[7m" 36 | #define DUK__TERM_BRIGHT "\x1b[1m" 37 | #define DUK__TERM_RESET "\x1b[0m" 38 | #define DUK__TERM_BLUE "\x1b[34m" 39 | #define DUK__TERM_RED "\x1b[31m" 40 | 41 | DUK_LOCAL const char *duk__get_term_1(duk_small_int_t level) { 42 | DUK_UNREF(level); 43 | return (const char *) DUK__TERM_RED; 44 | } 45 | 46 | DUK_LOCAL const char *duk__get_term_2(duk_small_int_t level) { 47 | switch ((int) level) { 48 | case DUK_LEVEL_DEBUG: 49 | return (const char *) (DUK__TERM_RESET DUK__TERM_BRIGHT); 50 | case DUK_LEVEL_DDEBUG: 51 | return (const char *) (DUK__TERM_RESET); 52 | case DUK_LEVEL_DDDEBUG: 53 | return (const char *) (DUK__TERM_RESET DUK__TERM_BLUE); 54 | } 55 | return (const char *) DUK__TERM_RESET; 56 | } 57 | 58 | DUK_LOCAL const char *duk__get_term_3(duk_small_int_t level) { 59 | DUK_UNREF(level); 60 | return (const char *) DUK__TERM_RESET; 61 | } 62 | 63 | #else 64 | 65 | DUK_LOCAL const char *duk__get_term_1(duk_small_int_t level) { 66 | DUK_UNREF(level); 67 | return (const char *) ""; 68 | } 69 | 70 | DUK_LOCAL const char *duk__get_term_2(duk_small_int_t level) { 71 | DUK_UNREF(level); 72 | return (const char *) ""; 73 | } 74 | 75 | DUK_LOCAL const char *duk__get_term_3(duk_small_int_t level) { 76 | DUK_UNREF(level); 77 | return (const char *) ""; 78 | } 79 | 80 | #endif /* DUK_USE_DPRINT_COLORS */ 81 | 82 | #ifdef DUK_USE_VARIADIC_MACROS 83 | 84 | DUK_INTERNAL void duk_debug_log(duk_small_int_t level, const char *file, duk_int_t line, const char *func, const char *fmt, ...) { 85 | va_list ap; 86 | 87 | va_start(ap, fmt); 88 | 89 | DUK_MEMZERO((void *) duk__debug_buf, (size_t) DUK__DEBUG_BUFSIZE); 90 | duk_debug_vsnprintf(duk__debug_buf, DUK__DEBUG_BUFSIZE - 1, fmt, ap); 91 | 92 | DUK_FPRINTF(DUK_STDERR, "%s[%s] %s:%ld (%s):%s %s%s\n", 93 | (const char *) duk__get_term_1(level), 94 | (const char *) duk__get_level_string(level), 95 | (const char *) file, 96 | (long) line, 97 | (const char *) func, 98 | (const char *) duk__get_term_2(level), 99 | (const char *) duk__debug_buf, 100 | (const char *) duk__get_term_3(level)); 101 | DUK_FFLUSH(DUK_STDERR); 102 | 103 | va_end(ap); 104 | } 105 | 106 | #else /* DUK_USE_VARIADIC_MACROS */ 107 | 108 | DUK_INTERNAL char duk_debug_file_stash[DUK_DEBUG_STASH_SIZE]; 109 | DUK_INTERNAL char duk_debug_line_stash[DUK_DEBUG_STASH_SIZE]; 110 | DUK_INTERNAL char duk_debug_func_stash[DUK_DEBUG_STASH_SIZE]; 111 | DUK_INTERNAL duk_small_int_t duk_debug_level_stash; 112 | 113 | DUK_INTERNAL void duk_debug_log(const char *fmt, ...) { 114 | va_list ap; 115 | duk_small_int_t level = duk_debug_level_stash; 116 | 117 | va_start(ap, fmt); 118 | 119 | DUK_MEMZERO((void *) duk__debug_buf, (size_t) DUK__DEBUG_BUFSIZE); 120 | duk_debug_vsnprintf(duk__debug_buf, DUK__DEBUG_BUFSIZE - 1, fmt, ap); 121 | 122 | DUK_FPRINTF(DUK_STDERR, "%s[%s] %s:%s (%s):%s %s%s\n", 123 | (const char *) duk__get_term_1(level), 124 | (const char *) duk__get_level_string(duk_debug_level_stash), 125 | (const char *) duk_debug_file_stash, 126 | (const char *) duk_debug_line_stash, 127 | (const char *) duk_debug_func_stash, 128 | (const char *) duk__get_term_2(level), 129 | (const char *) duk__debug_buf, 130 | (const char *) duk__get_term_3(level)); 131 | DUK_FFLUSH(DUK_STDERR); 132 | 133 | va_end(ap); 134 | } 135 | 136 | #endif /* DUK_USE_VARIADIC_MACROS */ 137 | 138 | #else /* DUK_USE_DEBUG */ 139 | 140 | /* 141 | * Debugging disabled 142 | */ 143 | 144 | #endif /* DUK_USE_DEBUG */ 145 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_error_longjmp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Do a longjmp call, calling the fatal error handler if no 3 | * catchpoint exists. 4 | */ 5 | 6 | #include "duk_internal.h" 7 | 8 | DUK_INTERNAL void duk_err_longjmp(duk_hthread *thr) { 9 | DUK_ASSERT(thr != NULL); 10 | 11 | #if defined(DUK_USE_CPP_EXCEPTIONS) 12 | /* XXX: detecting uncaught exception case for C++ case; perhaps need 13 | * some marker in heap->lj state that a try-catch is active. For now, 14 | * invokes C++ uncaught exception handling. 15 | */ 16 | #else 17 | if (!thr->heap->lj.jmpbuf_ptr) { 18 | /* 19 | * If we don't have a jmpbuf_ptr, there is little we can do 20 | * except panic. The caller's expectation is that we never 21 | * return. 22 | */ 23 | 24 | DUK_D(DUK_DPRINT("uncaught error: type=%d iserror=%d value1=%!T value2=%!T", 25 | (int) thr->heap->lj.type, (int) thr->heap->lj.iserror, 26 | &thr->heap->lj.value1, &thr->heap->lj.value2)); 27 | 28 | duk_fatal((duk_context *) thr, DUK_ERR_UNCAUGHT_ERROR, "uncaught error"); 29 | DUK_UNREACHABLE(); 30 | } 31 | #endif 32 | 33 | #if defined(DUK_USE_CPP_EXCEPTIONS) 34 | { 35 | duk_internal_exception exc; /* dummy */ 36 | throw exc; 37 | } 38 | #else 39 | DUK_LONGJMP(thr->heap->lj.jmpbuf_ptr->jb); 40 | #endif 41 | DUK_UNREACHABLE(); 42 | } 43 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_error_misc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Error helpers 3 | */ 4 | 5 | #include "duk_internal.h" 6 | 7 | /* 8 | * Helper to walk the thread chain and see if there is an active error 9 | * catcher. Protected calls or finally blocks aren't considered catching. 10 | */ 11 | 12 | #if defined(DUK_USE_DEBUGGER_SUPPORT) && \ 13 | (defined(DUK_USE_DEBUGGER_THROW_NOTIFY) || defined(DUK_USE_DEBUGGER_PAUSE_UNCAUGHT)) 14 | DUK_LOCAL duk_bool_t duk__have_active_catcher(duk_hthread *thr) { 15 | /* 16 | * XXX: As noted above, a protected API call won't be counted as a 17 | * catcher. This is usually convenient, e.g. in the case of a top- 18 | * level duk_pcall(), but may not always be desirable. Perhaps add an 19 | * argument to treat them as catchers? 20 | */ 21 | 22 | duk_size_t i; 23 | 24 | DUK_ASSERT(thr != NULL); 25 | 26 | while (thr != NULL) { 27 | for (i = 0; i < thr->catchstack_top; i++) { 28 | duk_catcher *cat = thr->catchstack + i; 29 | if (DUK_CAT_HAS_CATCH_ENABLED(cat)) { 30 | return 1; /* all we need to know */ 31 | } 32 | } 33 | thr = thr->resumer; 34 | } 35 | return 0; 36 | } 37 | #endif /* DUK_USE_DEBUGGER_SUPPORT && (DUK_USE_DEBUGGER_THROW_NOTIFY || DUK_USE_DEBUGGER_PAUSE_UNCAUGHT) */ 38 | 39 | /* 40 | * Get prototype object for an integer error code. 41 | */ 42 | 43 | DUK_INTERNAL duk_hobject *duk_error_prototype_from_code(duk_hthread *thr, duk_errcode_t code) { 44 | switch (code) { 45 | case DUK_ERR_EVAL_ERROR: 46 | return thr->builtins[DUK_BIDX_EVAL_ERROR_PROTOTYPE]; 47 | case DUK_ERR_RANGE_ERROR: 48 | return thr->builtins[DUK_BIDX_RANGE_ERROR_PROTOTYPE]; 49 | case DUK_ERR_REFERENCE_ERROR: 50 | return thr->builtins[DUK_BIDX_REFERENCE_ERROR_PROTOTYPE]; 51 | case DUK_ERR_SYNTAX_ERROR: 52 | return thr->builtins[DUK_BIDX_SYNTAX_ERROR_PROTOTYPE]; 53 | case DUK_ERR_TYPE_ERROR: 54 | return thr->builtins[DUK_BIDX_TYPE_ERROR_PROTOTYPE]; 55 | case DUK_ERR_URI_ERROR: 56 | return thr->builtins[DUK_BIDX_URI_ERROR_PROTOTYPE]; 57 | 58 | /* XXX: more specific error classes? */ 59 | case DUK_ERR_UNIMPLEMENTED_ERROR: 60 | case DUK_ERR_INTERNAL_ERROR: 61 | case DUK_ERR_ALLOC_ERROR: 62 | case DUK_ERR_ASSERTION_ERROR: 63 | case DUK_ERR_API_ERROR: 64 | case DUK_ERR_ERROR: 65 | default: 66 | return thr->builtins[DUK_BIDX_ERROR_PROTOTYPE]; 67 | } 68 | } 69 | 70 | /* 71 | * Exposed helper for setting up heap longjmp state. 72 | */ 73 | 74 | DUK_INTERNAL void duk_err_setup_heap_ljstate(duk_hthread *thr, duk_small_int_t lj_type) { 75 | #if defined(DUK_USE_DEBUGGER_SUPPORT) 76 | /* If something is thrown with the debugger attached and nobody will 77 | * catch it, execution is paused before the longjmp, turning over 78 | * control to the debug client. This allows local state to be examined 79 | * before the stack is unwound. Errors are not intercepted when debug 80 | * message loop is active (e.g. for Eval). 81 | */ 82 | 83 | /* XXX: Allow customizing the pause and notify behavior at runtime 84 | * using debugger runtime flags. For now the behavior is fixed using 85 | * config options. 86 | */ 87 | #if defined(DUK_USE_DEBUGGER_THROW_NOTIFY) || defined(DUK_USE_DEBUGGER_PAUSE_UNCAUGHT) 88 | if (DUK_HEAP_IS_DEBUGGER_ATTACHED(thr->heap) && 89 | !thr->heap->dbg_processing && 90 | lj_type == DUK_LJ_TYPE_THROW) { 91 | duk_context *ctx = (duk_context *) thr; 92 | duk_bool_t fatal; 93 | duk_hobject *h_obj; 94 | 95 | /* Don't intercept a DoubleError, we may have caused the initial double 96 | * fault and attempting to intercept it will cause us to be called 97 | * recursively and exhaust the C stack. 98 | */ 99 | h_obj = duk_get_hobject(ctx, -1); 100 | if (h_obj == thr->builtins[DUK_BIDX_DOUBLE_ERROR]) { 101 | DUK_D(DUK_DPRINT("built-in DoubleError instance thrown, not intercepting")); 102 | goto skip_throw_intercept; 103 | } 104 | 105 | DUK_D(DUK_DPRINT("throw with debugger attached, report to client")); 106 | 107 | fatal = !duk__have_active_catcher(thr); 108 | 109 | #if defined(DUK_USE_DEBUGGER_THROW_NOTIFY) 110 | /* Report it to the debug client */ 111 | duk_debug_send_throw(thr, fatal); 112 | #endif 113 | 114 | #if defined(DUK_USE_DEBUGGER_PAUSE_UNCAUGHT) 115 | if (fatal) { 116 | DUK_D(DUK_DPRINT("throw will be fatal, halt before longjmp")); 117 | duk_debug_halt_execution(thr, 1 /*use_prev_pc*/); 118 | } 119 | #endif 120 | } 121 | 122 | skip_throw_intercept: 123 | #endif /* DUK_USE_DEBUGGER_THROW_NOTIFY || DUK_USE_DEBUGGER_PAUSE_UNCAUGHT */ 124 | #endif /* DUK_USE_DEBUGGER_SUPPORT */ 125 | 126 | thr->heap->lj.type = lj_type; 127 | 128 | DUK_ASSERT(thr->valstack_top > thr->valstack); 129 | DUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value1, thr->valstack_top - 1); /* side effects */ 130 | 131 | duk_pop((duk_context *) thr); 132 | } 133 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_exception.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Exception for Duktape internal throws when C++ exceptions are used 3 | * for long control transfers. 4 | * 5 | * Doesn't inherit from any exception base class to minimize the chance 6 | * that user code would accidentally catch this exception. 7 | */ 8 | 9 | #ifndef DUK_EXCEPTION_H_INCLUDED 10 | #define DUK_EXCEPTION_H_INCLUDED 11 | 12 | #if defined(DUK_USE_CPP_EXCEPTIONS) 13 | class duk_internal_exception { 14 | /* intentionally empty */ 15 | }; 16 | #endif 17 | 18 | #endif /* DUK_EXCEPTION_H_INCLUDED */ 19 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_forwdecl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Forward declarations for all Duktape structures. 3 | */ 4 | 5 | #ifndef DUK_FORWDECL_H_INCLUDED 6 | #define DUK_FORWDECL_H_INCLUDED 7 | 8 | /* 9 | * Forward declarations 10 | */ 11 | 12 | #if defined(DUK_USE_CPP_EXCEPTIONS) 13 | class duk_internal_exception; 14 | #else 15 | struct duk_jmpbuf; 16 | #endif 17 | 18 | /* duk_tval intentionally skipped */ 19 | struct duk_heaphdr; 20 | struct duk_heaphdr_string; 21 | struct duk_hstring; 22 | struct duk_hstring_external; 23 | struct duk_hobject; 24 | struct duk_hcompiledfunction; 25 | struct duk_hnativefunction; 26 | struct duk_hthread; 27 | struct duk_hbufferobject; 28 | struct duk_hbuffer; 29 | struct duk_hbuffer_fixed; 30 | struct duk_hbuffer_dynamic; 31 | struct duk_hbuffer_external; 32 | 33 | struct duk_propaccessor; 34 | union duk_propvalue; 35 | struct duk_propdesc; 36 | 37 | struct duk_heap; 38 | struct duk_breakpoint; 39 | 40 | struct duk_activation; 41 | struct duk_catcher; 42 | struct duk_strcache; 43 | struct duk_ljstate; 44 | struct duk_strtab_entry; 45 | 46 | #ifdef DUK_USE_DEBUG 47 | struct duk_fixedbuffer; 48 | #endif 49 | 50 | struct duk_bitdecoder_ctx; 51 | struct duk_bitencoder_ctx; 52 | struct duk_bufwriter_ctx; 53 | 54 | struct duk_token; 55 | struct duk_re_token; 56 | struct duk_lexer_point; 57 | struct duk_lexer_ctx; 58 | struct duk_lexer_codepoint; 59 | 60 | struct duk_compiler_instr; 61 | struct duk_compiler_func; 62 | struct duk_compiler_ctx; 63 | 64 | struct duk_re_matcher_ctx; 65 | struct duk_re_compiler_ctx; 66 | 67 | #if defined(DUK_USE_CPP_EXCEPTIONS) 68 | /* no typedef */ 69 | #else 70 | typedef struct duk_jmpbuf duk_jmpbuf; 71 | #endif 72 | 73 | /* duk_tval intentionally skipped */ 74 | typedef struct duk_heaphdr duk_heaphdr; 75 | typedef struct duk_heaphdr_string duk_heaphdr_string; 76 | typedef struct duk_hstring duk_hstring; 77 | typedef struct duk_hstring_external duk_hstring_external; 78 | typedef struct duk_hobject duk_hobject; 79 | typedef struct duk_hcompiledfunction duk_hcompiledfunction; 80 | typedef struct duk_hnativefunction duk_hnativefunction; 81 | typedef struct duk_hbufferobject duk_hbufferobject; 82 | typedef struct duk_hthread duk_hthread; 83 | typedef struct duk_hbuffer duk_hbuffer; 84 | typedef struct duk_hbuffer_fixed duk_hbuffer_fixed; 85 | typedef struct duk_hbuffer_dynamic duk_hbuffer_dynamic; 86 | typedef struct duk_hbuffer_external duk_hbuffer_external; 87 | 88 | typedef struct duk_propaccessor duk_propaccessor; 89 | typedef union duk_propvalue duk_propvalue; 90 | typedef struct duk_propdesc duk_propdesc; 91 | 92 | typedef struct duk_heap duk_heap; 93 | typedef struct duk_breakpoint duk_breakpoint; 94 | 95 | typedef struct duk_activation duk_activation; 96 | typedef struct duk_catcher duk_catcher; 97 | typedef struct duk_strcache duk_strcache; 98 | typedef struct duk_ljstate duk_ljstate; 99 | typedef struct duk_strtab_entry duk_strtab_entry; 100 | 101 | #ifdef DUK_USE_DEBUG 102 | typedef struct duk_fixedbuffer duk_fixedbuffer; 103 | #endif 104 | 105 | typedef struct duk_bitdecoder_ctx duk_bitdecoder_ctx; 106 | typedef struct duk_bitencoder_ctx duk_bitencoder_ctx; 107 | typedef struct duk_bufwriter_ctx duk_bufwriter_ctx; 108 | 109 | typedef struct duk_token duk_token; 110 | typedef struct duk_re_token duk_re_token; 111 | typedef struct duk_lexer_point duk_lexer_point; 112 | typedef struct duk_lexer_ctx duk_lexer_ctx; 113 | typedef struct duk_lexer_codepoint duk_lexer_codepoint; 114 | 115 | typedef struct duk_compiler_instr duk_compiler_instr; 116 | typedef struct duk_compiler_func duk_compiler_func; 117 | typedef struct duk_compiler_ctx duk_compiler_ctx; 118 | 119 | typedef struct duk_re_matcher_ctx duk_re_matcher_ctx; 120 | typedef struct duk_re_compiler_ctx duk_re_compiler_ctx; 121 | 122 | #endif /* DUK_FORWDECL_H_INCLUDED */ 123 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_hbuffer_alloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * duk_hbuffer allocation and freeing. 3 | */ 4 | 5 | #include "duk_internal.h" 6 | 7 | /* Allocate a new duk_hbuffer of a certain type and return a pointer to it 8 | * (NULL on error). Write buffer data pointer to 'out_bufdata' (only if 9 | * allocation successful). 10 | */ 11 | DUK_INTERNAL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap, duk_size_t size, duk_small_uint_t flags, void **out_bufdata) { 12 | duk_hbuffer *res = NULL; 13 | duk_size_t header_size; 14 | duk_size_t alloc_size; 15 | 16 | DUK_ASSERT(heap != NULL); 17 | DUK_ASSERT(out_bufdata != NULL); 18 | 19 | DUK_DDD(DUK_DDDPRINT("allocate hbuffer")); 20 | 21 | /* Size sanity check. Should not be necessary because caller is 22 | * required to check this, but we don't want to cause a segfault 23 | * if the size wraps either in duk_size_t computation or when 24 | * storing the size in a 16-bit field. 25 | */ 26 | if (size > DUK_HBUFFER_MAX_BYTELEN) { 27 | DUK_D(DUK_DPRINT("hbuffer alloc failed: size too large: %ld", (long) size)); 28 | return NULL; /* no need to write 'out_bufdata' */ 29 | } 30 | 31 | if (flags & DUK_BUF_FLAG_EXTERNAL) { 32 | header_size = sizeof(duk_hbuffer_external); 33 | alloc_size = sizeof(duk_hbuffer_external); 34 | } if (flags & DUK_BUF_FLAG_DYNAMIC) { 35 | header_size = sizeof(duk_hbuffer_dynamic); 36 | alloc_size = sizeof(duk_hbuffer_dynamic); 37 | } else { 38 | header_size = sizeof(duk_hbuffer_fixed); 39 | alloc_size = sizeof(duk_hbuffer_fixed) + size; 40 | DUK_ASSERT(alloc_size >= sizeof(duk_hbuffer_fixed)); /* no wrapping */ 41 | } 42 | 43 | res = (duk_hbuffer *) DUK_ALLOC(heap, alloc_size); 44 | if (!res) { 45 | goto error; 46 | } 47 | 48 | /* zero everything unless requested not to do so */ 49 | #if defined(DUK_USE_ZERO_BUFFER_DATA) 50 | DUK_MEMZERO((void *) res, 51 | (flags & DUK_BUF_FLAG_NOZERO) ? header_size : alloc_size); 52 | #else 53 | DUK_MEMZERO((void *) res, header_size); 54 | #endif 55 | 56 | if (flags & DUK_BUF_FLAG_EXTERNAL) { 57 | duk_hbuffer_external *h; 58 | h = (duk_hbuffer_external *) res; 59 | DUK_UNREF(h); 60 | *out_bufdata = NULL; 61 | #if defined(DUK_USE_EXPLICIT_NULL_INIT) 62 | #if defined(DUK_USE_HEAPPTR16) 63 | /* the compressed pointer is zeroed which maps to NULL, so nothing to do. */ 64 | #else 65 | DUK_HBUFFER_EXTERNAL_SET_DATA_PTR(heap, h, NULL); 66 | #endif 67 | #endif 68 | DUK_ASSERT(DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(heap, h) == NULL); 69 | } else if (flags & DUK_BUF_FLAG_DYNAMIC) { 70 | duk_hbuffer_dynamic *h = (duk_hbuffer_dynamic *) res; 71 | void *ptr; 72 | 73 | if (size > 0) { 74 | DUK_ASSERT(!(flags & DUK_BUF_FLAG_EXTERNAL)); /* alloc external with size zero */ 75 | DUK_DDD(DUK_DDDPRINT("dynamic buffer with nonzero size, alloc actual buffer")); 76 | #ifdef DUK_USE_ZERO_BUFFER_DATA 77 | ptr = DUK_ALLOC_ZEROED(heap, size); 78 | #else 79 | ptr = DUK_ALLOC(heap, size); 80 | #endif 81 | if (!ptr) { 82 | /* Because size > 0, NULL check is correct */ 83 | goto error; 84 | } 85 | *out_bufdata = ptr; 86 | 87 | DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap, h, ptr); 88 | } else { 89 | *out_bufdata = NULL; 90 | #if defined(DUK_USE_EXPLICIT_NULL_INIT) 91 | #if defined(DUK_USE_HEAPPTR16) 92 | /* the compressed pointer is zeroed which maps to NULL, so nothing to do. */ 93 | #else 94 | DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap, h, NULL); 95 | #endif 96 | #endif 97 | DUK_ASSERT(DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, h) == NULL); 98 | } 99 | } else { 100 | *out_bufdata = (void *) ((duk_hbuffer_fixed *) res + 1); 101 | } 102 | 103 | DUK_HBUFFER_SET_SIZE(res, size); 104 | 105 | DUK_HEAPHDR_SET_TYPE(&res->hdr, DUK_HTYPE_BUFFER); 106 | if (flags & DUK_BUF_FLAG_DYNAMIC) { 107 | DUK_HBUFFER_SET_DYNAMIC(res); 108 | if (flags & DUK_BUF_FLAG_EXTERNAL) { 109 | DUK_HBUFFER_SET_EXTERNAL(res); 110 | } 111 | } else { 112 | DUK_ASSERT(!(flags & DUK_BUF_FLAG_EXTERNAL)); 113 | } 114 | DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, &res->hdr); 115 | 116 | DUK_DDD(DUK_DDDPRINT("allocated hbuffer: %p", (void *) res)); 117 | return res; 118 | 119 | error: 120 | DUK_DD(DUK_DDPRINT("hbuffer allocation failed")); 121 | 122 | DUK_FREE(heap, res); 123 | return NULL; /* no need to write 'out_bufdata' */ 124 | } 125 | 126 | /* For indirect allocs. */ 127 | 128 | DUK_INTERNAL void *duk_hbuffer_get_dynalloc_ptr(duk_heap *heap, void *ud) { 129 | duk_hbuffer_dynamic *buf = (duk_hbuffer_dynamic *) ud; 130 | DUK_UNREF(heap); 131 | return (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, buf); 132 | } 133 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_hbuffer_ops.c: -------------------------------------------------------------------------------- 1 | /* 2 | * duk_hbuffer operations such as resizing and inserting/appending data to 3 | * a dynamic buffer. 4 | * 5 | * Append operations append to the end of the buffer and they are relatively 6 | * efficient: the buffer is grown with a "spare" part relative to the buffer 7 | * size to minimize reallocations. Insert operations need to move existing 8 | * data forward in the buffer with memmove() and are not very efficient. 9 | * They are used e.g. by the regexp compiler to "backpatch" regexp bytecode. 10 | */ 11 | 12 | #include "duk_internal.h" 13 | 14 | /* 15 | * Resizing 16 | */ 17 | 18 | DUK_INTERNAL void duk_hbuffer_resize(duk_hthread *thr, duk_hbuffer_dynamic *buf, duk_size_t new_size) { 19 | void *res; 20 | duk_size_t prev_size; 21 | 22 | DUK_ASSERT(thr != NULL); 23 | DUK_ASSERT(buf != NULL); 24 | DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(buf)); 25 | DUK_ASSERT(!DUK_HBUFFER_HAS_EXTERNAL(buf)); 26 | 27 | /* 28 | * Maximum size check 29 | */ 30 | 31 | if (new_size > DUK_HBUFFER_MAX_BYTELEN) { 32 | DUK_ERROR(thr, DUK_ERR_RANGE_ERROR, "buffer too long"); 33 | } 34 | 35 | /* 36 | * Note: use indirect realloc variant just in case mark-and-sweep 37 | * (finalizers) might resize this same buffer during garbage 38 | * collection. 39 | */ 40 | 41 | res = DUK_REALLOC_INDIRECT(thr->heap, duk_hbuffer_get_dynalloc_ptr, (void *) buf, new_size); 42 | if (res != NULL || new_size == 0) { 43 | /* 'res' may be NULL if new allocation size is 0. */ 44 | 45 | DUK_DDD(DUK_DDDPRINT("resized dynamic buffer %p:%ld -> %p:%ld", 46 | (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, buf), 47 | (long) DUK_HBUFFER_DYNAMIC_GET_SIZE(buf), 48 | (void *) res, 49 | (long) new_size)); 50 | 51 | /* 52 | * The entire allocated buffer area, regardless of actual used 53 | * size, is kept zeroed in resizes for simplicity. If the buffer 54 | * is grown, zero the new part. 55 | */ 56 | 57 | prev_size = DUK_HBUFFER_DYNAMIC_GET_SIZE(buf); 58 | if (new_size > prev_size) { 59 | DUK_ASSERT(new_size - prev_size > 0); 60 | #ifdef DUK_USE_ZERO_BUFFER_DATA 61 | DUK_MEMZERO((void *) ((char *) res + prev_size), 62 | (duk_size_t) (new_size - prev_size)); 63 | #endif 64 | } 65 | 66 | DUK_HBUFFER_DYNAMIC_SET_SIZE(buf, new_size); 67 | DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(thr->heap, buf, res); 68 | } else { 69 | DUK_ERROR(thr, DUK_ERR_ALLOC_ERROR, "buffer resize failed: %ld to %ld", 70 | (long) DUK_HBUFFER_DYNAMIC_GET_SIZE(buf), 71 | (long) new_size); 72 | } 73 | 74 | DUK_ASSERT(res != NULL || new_size == 0); 75 | } 76 | 77 | DUK_INTERNAL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic *buf) { 78 | DUK_ASSERT(thr != NULL); 79 | DUK_ASSERT(buf != NULL); 80 | DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(buf)); 81 | DUK_ASSERT(!DUK_HBUFFER_HAS_EXTERNAL(buf)); 82 | 83 | duk_hbuffer_resize(thr, buf, 0); 84 | } 85 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_hbufferobject_misc.c: -------------------------------------------------------------------------------- 1 | #include "duk_internal.h" 2 | 3 | #if defined(DUK_USE_BUFFEROBJECT_SUPPORT) 4 | DUK_INTERNAL duk_uint_t duk_hbufferobject_clamp_bytelength(duk_hbufferobject *h_bufobj, duk_uint_t len) { 5 | duk_uint_t buf_size; 6 | duk_uint_t buf_avail; 7 | 8 | DUK_ASSERT(h_bufobj != NULL); 9 | DUK_ASSERT(h_bufobj->buf != NULL); 10 | 11 | buf_size = (duk_uint_t) DUK_HBUFFER_GET_SIZE(h_bufobj->buf); 12 | if (h_bufobj->offset > buf_size) { 13 | /* Slice starting point is beyond current length. */ 14 | return 0; 15 | } 16 | buf_avail = buf_size - h_bufobj->offset; 17 | 18 | return buf_avail >= len ? len : buf_avail; 19 | } 20 | #endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ 21 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_heap_hashstring.c: -------------------------------------------------------------------------------- 1 | /* 2 | * String hash computation (interning). 3 | * 4 | * String hashing is performance critical because a string hash is computed 5 | * for all new strings which are candidates to be added to the string table. 6 | * However, strings actually added to the string table go through a codepoint 7 | * length calculation which dominates performance because it goes through 8 | * every byte of the input string (but only for strings added). 9 | * 10 | * The string hash algorithm should be fast, but on the other hand provide 11 | * good enough hashes to ensure both string table and object property table 12 | * hash tables work reasonably well (i.e., there aren't too many collisions 13 | * with real world inputs). Unless the hash is cryptographic, it's always 14 | * possible to craft inputs with maximal hash collisions. 15 | */ 16 | 17 | #include "duk_internal.h" 18 | 19 | #if defined(DUK_USE_STRHASH_DENSE) 20 | #define DUK__STRHASH_SHORTSTRING 4096L 21 | #define DUK__STRHASH_MEDIUMSTRING (256L * 1024L) 22 | #define DUK__STRHASH_BLOCKSIZE 256L 23 | 24 | DUK_INTERNAL duk_uint32_t duk_heap_hashstring(duk_heap *heap, const duk_uint8_t *str, duk_size_t len) { 25 | duk_uint32_t hash; 26 | 27 | /* Use Murmurhash2 directly for short strings, and use "block skipping" 28 | * for long strings: hash an initial part and then sample the rest of 29 | * the string with reasonably sized chunks. An initial offset for the 30 | * sampling is computed based on a hash of the initial part of the string; 31 | * this is done to (usually) avoid the case where all long strings have 32 | * certain offset ranges which are never sampled. 33 | * 34 | * Skip should depend on length and bound the total time to roughly 35 | * logarithmic. With current values: 36 | * 37 | * 1M string => 256 * 241 = 61696 bytes (0.06M) of hashing 38 | * 1G string => 256 * 16321 = 4178176 bytes (3.98M) of hashing 39 | * 40 | * XXX: It would be better to compute the skip offset more "smoothly" 41 | * instead of having a few boundary values. 42 | */ 43 | 44 | /* note: mixing len into seed improves hashing when skipping */ 45 | duk_uint32_t str_seed = heap->hash_seed ^ ((duk_uint32_t) len); 46 | 47 | if (len <= DUK__STRHASH_SHORTSTRING) { 48 | hash = duk_util_hashbytes(str, len, str_seed); 49 | } else { 50 | duk_size_t off; 51 | duk_size_t skip; 52 | 53 | if (len <= DUK__STRHASH_MEDIUMSTRING) { 54 | skip = (duk_size_t) (16 * DUK__STRHASH_BLOCKSIZE + DUK__STRHASH_BLOCKSIZE); 55 | } else { 56 | skip = (duk_size_t) (256 * DUK__STRHASH_BLOCKSIZE + DUK__STRHASH_BLOCKSIZE); 57 | } 58 | 59 | hash = duk_util_hashbytes(str, (duk_size_t) DUK__STRHASH_SHORTSTRING, str_seed); 60 | off = DUK__STRHASH_SHORTSTRING + (skip * (hash % 256)) / 256; 61 | 62 | /* XXX: inefficient loop */ 63 | while (off < len) { 64 | duk_size_t left = len - off; 65 | duk_size_t now = (duk_size_t) (left > DUK__STRHASH_BLOCKSIZE ? DUK__STRHASH_BLOCKSIZE : left); 66 | hash ^= duk_util_hashbytes(str + off, now, str_seed); 67 | off += skip; 68 | } 69 | } 70 | 71 | #if defined(DUK_USE_STRHASH16) 72 | /* Truncate to 16 bits here, so that a computed hash can be compared 73 | * against a hash stored in a 16-bit field. 74 | */ 75 | hash &= 0x0000ffffUL; 76 | #endif 77 | return hash; 78 | } 79 | 80 | #undef DUK__STRHASH_SHORTSTRING 81 | #undef DUK__STRHASH_MEDIUMSTRING 82 | #undef DUK__STRHASH_BLOCKSIZE 83 | #else /* DUK_USE_STRHASH_DENSE */ 84 | DUK_INTERNAL duk_uint32_t duk_heap_hashstring(duk_heap *heap, const duk_uint8_t *str, duk_size_t len) { 85 | duk_uint32_t hash; 86 | duk_size_t step; 87 | duk_size_t off; 88 | 89 | /* Slightly modified "Bernstein hash" from: 90 | * 91 | * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx 92 | * 93 | * Modifications: string skipping and reverse direction similar to 94 | * Lua 5.1.5, and different hash initializer. 95 | * 96 | * The reverse direction ensures last byte it always included in the 97 | * hash which is a good default as changing parts of the string are 98 | * more often in the suffix than in the prefix. 99 | */ 100 | 101 | hash = heap->hash_seed ^ ((duk_uint32_t) len); /* Bernstein hash init value is normally 5381 */ 102 | step = (len >> DUK_USE_STRHASH_SKIP_SHIFT) + 1; 103 | for (off = len; off >= step; off -= step) { 104 | DUK_ASSERT(off >= 1); /* off >= step, and step >= 1 */ 105 | hash = (hash * 33) + str[off - 1]; 106 | } 107 | 108 | #if defined(DUK_USE_STRHASH16) 109 | /* Truncate to 16 bits here, so that a computed hash can be compared 110 | * against a hash stored in a 16-bit field. 111 | */ 112 | hash &= 0x0000ffffUL; 113 | #endif 114 | return hash; 115 | } 116 | #endif /* DUK_USE_STRHASH_DENSE */ 117 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_heap_misc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Support functions for duk_heap. 3 | */ 4 | 5 | #include "duk_internal.h" 6 | 7 | #if defined(DUK_USE_DOUBLE_LINKED_HEAP) && defined(DUK_USE_REFERENCE_COUNTING) 8 | /* arbitrary remove only works with double linked heap, and is only required by 9 | * reference counting so far. 10 | */ 11 | DUK_INTERNAL void duk_heap_remove_any_from_heap_allocated(duk_heap *heap, duk_heaphdr *hdr) { 12 | DUK_ASSERT(DUK_HEAPHDR_GET_TYPE(hdr) != DUK_HTYPE_STRING); 13 | 14 | if (DUK_HEAPHDR_GET_PREV(heap, hdr)) { 15 | DUK_HEAPHDR_SET_NEXT(heap, DUK_HEAPHDR_GET_PREV(heap, hdr), DUK_HEAPHDR_GET_NEXT(heap, hdr)); 16 | } else { 17 | heap->heap_allocated = DUK_HEAPHDR_GET_NEXT(heap, hdr); 18 | } 19 | if (DUK_HEAPHDR_GET_NEXT(heap, hdr)) { 20 | DUK_HEAPHDR_SET_PREV(heap, DUK_HEAPHDR_GET_NEXT(heap, hdr), DUK_HEAPHDR_GET_PREV(heap, hdr)); 21 | } else { 22 | ; 23 | } 24 | } 25 | #endif 26 | 27 | DUK_INTERNAL void duk_heap_insert_into_heap_allocated(duk_heap *heap, duk_heaphdr *hdr) { 28 | DUK_ASSERT(DUK_HEAPHDR_GET_TYPE(hdr) != DUK_HTYPE_STRING); 29 | 30 | #ifdef DUK_USE_DOUBLE_LINKED_HEAP 31 | if (heap->heap_allocated) { 32 | DUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, heap->heap_allocated) == NULL); 33 | DUK_HEAPHDR_SET_PREV(heap, heap->heap_allocated, hdr); 34 | } 35 | DUK_HEAPHDR_SET_PREV(heap, hdr, NULL); 36 | #endif 37 | DUK_HEAPHDR_SET_NEXT(heap, hdr, heap->heap_allocated); 38 | heap->heap_allocated = hdr; 39 | } 40 | 41 | #ifdef DUK_USE_INTERRUPT_COUNTER 42 | DUK_INTERNAL void duk_heap_switch_thread(duk_heap *heap, duk_hthread *new_thr) { 43 | duk_hthread *curr_thr; 44 | 45 | DUK_ASSERT(heap != NULL); 46 | 47 | if (new_thr != NULL) { 48 | curr_thr = heap->curr_thread; 49 | if (curr_thr == NULL) { 50 | /* For initial entry use default value; zero forces an 51 | * interrupt before executing the first insturction. 52 | */ 53 | DUK_DD(DUK_DDPRINT("switch thread, initial entry, init default interrupt counter")); 54 | new_thr->interrupt_counter = 0; 55 | new_thr->interrupt_init = 0; 56 | } else { 57 | /* Copy interrupt counter/init value state to new thread (if any). 58 | * It's OK for new_thr to be the same as curr_thr. 59 | */ 60 | #if defined(DUK_USE_DEBUG) 61 | if (new_thr != curr_thr) { 62 | DUK_DD(DUK_DDPRINT("switch thread, not initial entry, copy interrupt counter")); 63 | } 64 | #endif 65 | new_thr->interrupt_counter = curr_thr->interrupt_counter; 66 | new_thr->interrupt_init = curr_thr->interrupt_init; 67 | } 68 | } else { 69 | DUK_DD(DUK_DDPRINT("switch thread, new thread is NULL, no interrupt counter changes")); 70 | } 71 | 72 | heap->curr_thread = new_thr; /* may be NULL */ 73 | } 74 | #endif /* DUK_USE_INTERRUPT_COUNTER */ 75 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_hnativefunction.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Heap native function representation. 3 | */ 4 | 5 | #ifndef DUK_HNATIVEFUNCTION_H_INCLUDED 6 | #define DUK_HNATIVEFUNCTION_H_INCLUDED 7 | 8 | #define DUK_HNATIVEFUNCTION_NARGS_VARARGS ((duk_int16_t) -1) 9 | #define DUK_HNATIVEFUNCTION_NARGS_MAX ((duk_int16_t) 0x7fff) 10 | 11 | struct duk_hnativefunction { 12 | /* shared object part */ 13 | duk_hobject obj; 14 | 15 | duk_c_function func; 16 | duk_int16_t nargs; 17 | duk_int16_t magic; 18 | 19 | /* The 'magic' field allows an opaque 16-bit field to be accessed by the 20 | * Duktape/C function. This allows, for instance, the same native function 21 | * to be used for a set of very similar functions, with the 'magic' field 22 | * providing the necessary non-argument flags / values to guide the behavior 23 | * of the native function. The value is signed on purpose: it is easier to 24 | * convert a signed value to unsigned (simply AND with 0xffff) than vice 25 | * versa. 26 | * 27 | * Note: cannot place nargs/magic into the heaphdr flags, because 28 | * duk_hobject takes almost all flags already (and needs the spare). 29 | */ 30 | }; 31 | 32 | #endif /* DUK_HNATIVEFUNCTION_H_INCLUDED */ 33 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_hobject_class.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Hobject Ecmascript [[Class]]. 3 | */ 4 | 5 | #include "duk_internal.h" 6 | 7 | #if (DUK_STRIDX_UC_ARGUMENTS > 255) 8 | #error constant too large 9 | #endif 10 | #if (DUK_STRIDX_ARRAY > 255) 11 | #error constant too large 12 | #endif 13 | #if (DUK_STRIDX_UC_BOOLEAN > 255) 14 | #error constant too large 15 | #endif 16 | #if (DUK_STRIDX_DATE > 255) 17 | #error constant too large 18 | #endif 19 | #if (DUK_STRIDX_UC_ERROR > 255) 20 | #error constant too large 21 | #endif 22 | #if (DUK_STRIDX_UC_FUNCTION > 255) 23 | #error constant too large 24 | #endif 25 | #if (DUK_STRIDX_JSON > 255) 26 | #error constant too large 27 | #endif 28 | #if (DUK_STRIDX_MATH > 255) 29 | #error constant too large 30 | #endif 31 | #if (DUK_STRIDX_UC_NUMBER > 255) 32 | #error constant too large 33 | #endif 34 | #if (DUK_STRIDX_UC_OBJECT > 255) 35 | #error constant too large 36 | #endif 37 | #if (DUK_STRIDX_REG_EXP > 255) 38 | #error constant too large 39 | #endif 40 | #if (DUK_STRIDX_UC_STRING > 255) 41 | #error constant too large 42 | #endif 43 | #if (DUK_STRIDX_GLOBAL > 255) 44 | #error constant too large 45 | #endif 46 | #if (DUK_STRIDX_OBJ_ENV > 255) 47 | #error constant too large 48 | #endif 49 | #if (DUK_STRIDX_DEC_ENV > 255) 50 | #error constant too large 51 | #endif 52 | #if (DUK_STRIDX_UC_BUFFER > 255) 53 | #error constant too large 54 | #endif 55 | #if (DUK_STRIDX_UC_POINTER > 255) 56 | #error constant too large 57 | #endif 58 | #if (DUK_STRIDX_UC_THREAD > 255) 59 | #error constant too large 60 | #endif 61 | #if (DUK_STRIDX_ARRAY_BUFFER > 255) 62 | #error constant too large 63 | #endif 64 | #if (DUK_STRIDX_DATA_VIEW > 255) 65 | #error constant too large 66 | #endif 67 | #if (DUK_STRIDX_INT8_ARRAY > 255) 68 | #error constant too large 69 | #endif 70 | #if (DUK_STRIDX_UINT8_ARRAY > 255) 71 | #error constant too large 72 | #endif 73 | #if (DUK_STRIDX_UINT8_CLAMPED_ARRAY > 255) 74 | #error constant too large 75 | #endif 76 | #if (DUK_STRIDX_INT16_ARRAY > 255) 77 | #error constant too large 78 | #endif 79 | #if (DUK_STRIDX_UINT16_ARRAY > 255) 80 | #error constant too large 81 | #endif 82 | #if (DUK_STRIDX_INT32_ARRAY > 255) 83 | #error constant too large 84 | #endif 85 | #if (DUK_STRIDX_UINT32_ARRAY > 255) 86 | #error constant too large 87 | #endif 88 | #if (DUK_STRIDX_FLOAT32_ARRAY > 255) 89 | #error constant too large 90 | #endif 91 | #if (DUK_STRIDX_FLOAT64_ARRAY > 255) 92 | #error constant too large 93 | #endif 94 | #if (DUK_STRIDX_EMPTY_STRING > 255) 95 | #error constant too large 96 | #endif 97 | 98 | /* Note: assumes that these string indexes are 8-bit, genstrings.py must ensure that */ 99 | DUK_INTERNAL duk_uint8_t duk_class_number_to_stridx[32] = { 100 | DUK_STRIDX_EMPTY_STRING, /* UNUSED, intentionally empty */ 101 | DUK_STRIDX_UC_ARGUMENTS, 102 | DUK_STRIDX_ARRAY, 103 | DUK_STRIDX_UC_BOOLEAN, 104 | DUK_STRIDX_DATE, 105 | DUK_STRIDX_UC_ERROR, 106 | DUK_STRIDX_UC_FUNCTION, 107 | DUK_STRIDX_JSON, 108 | DUK_STRIDX_MATH, 109 | DUK_STRIDX_UC_NUMBER, 110 | DUK_STRIDX_UC_OBJECT, 111 | DUK_STRIDX_REG_EXP, 112 | DUK_STRIDX_UC_STRING, 113 | DUK_STRIDX_GLOBAL, 114 | DUK_STRIDX_OBJ_ENV, 115 | DUK_STRIDX_DEC_ENV, 116 | DUK_STRIDX_UC_BUFFER, 117 | DUK_STRIDX_UC_POINTER, 118 | DUK_STRIDX_UC_THREAD, 119 | DUK_STRIDX_ARRAY_BUFFER, 120 | DUK_STRIDX_DATA_VIEW, 121 | DUK_STRIDX_INT8_ARRAY, 122 | DUK_STRIDX_UINT8_ARRAY, 123 | DUK_STRIDX_UINT8_CLAMPED_ARRAY, 124 | DUK_STRIDX_INT16_ARRAY, 125 | DUK_STRIDX_UINT16_ARRAY, 126 | DUK_STRIDX_INT32_ARRAY, 127 | DUK_STRIDX_UINT32_ARRAY, 128 | DUK_STRIDX_FLOAT32_ARRAY, 129 | DUK_STRIDX_FLOAT64_ARRAY, 130 | DUK_STRIDX_EMPTY_STRING, /* UNUSED, intentionally empty */ 131 | DUK_STRIDX_EMPTY_STRING, /* UNUSED, intentionally empty */ 132 | }; 133 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_hobject_finalizer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Run an duk_hobject finalizer. Used for both reference counting 3 | * and mark-and-sweep algorithms. Must never throw an error. 4 | * 5 | * There is no return value. Any return value or error thrown by 6 | * the finalizer is ignored (although errors are debug logged). 7 | * 8 | * Notes: 9 | * 10 | * - The thread used for calling the finalizer is the same as the 11 | * 'thr' argument. This may need to change later. 12 | * 13 | * - The finalizer thread 'top' assertions are there because it is 14 | * critical that strict stack policy is observed (i.e. no cruft 15 | * left on the finalizer stack). 16 | */ 17 | 18 | #include "duk_internal.h" 19 | 20 | DUK_LOCAL duk_ret_t duk__finalize_helper(duk_context *ctx) { 21 | duk_hthread *thr; 22 | 23 | DUK_ASSERT(ctx != NULL); 24 | thr = (duk_hthread *) ctx; 25 | 26 | DUK_DDD(DUK_DDDPRINT("protected finalization helper running")); 27 | 28 | /* [... obj] */ 29 | 30 | /* XXX: Finalizer lookup should traverse the prototype chain (to allow 31 | * inherited finalizers) but should not invoke accessors or proxy object 32 | * behavior. At the moment this lookup will invoke proxy behavior, so 33 | * caller must ensure that this function is not called if the target is 34 | * a Proxy. 35 | */ 36 | 37 | duk_get_prop_stridx(ctx, -1, DUK_STRIDX_INT_FINALIZER); /* -> [... obj finalizer] */ 38 | if (!duk_is_callable(ctx, -1)) { 39 | DUK_DDD(DUK_DDDPRINT("-> no finalizer or finalizer not callable")); 40 | return 0; 41 | } 42 | duk_dup(ctx, -2); 43 | duk_push_boolean(ctx, DUK_HEAP_HAS_FINALIZER_NORESCUE(thr->heap)); 44 | DUK_DDD(DUK_DDDPRINT("-> finalizer found, calling finalizer")); 45 | duk_call(ctx, 2); /* [ ... obj finalizer obj heapDestruct ] -> [ ... obj retval ] */ 46 | DUK_DDD(DUK_DDDPRINT("finalizer finished successfully")); 47 | return 0; 48 | 49 | /* Note: we rely on duk_safe_call() to fix up the stack for the caller, 50 | * so we don't need to pop stuff here. There is no return value; 51 | * caller determines rescued status based on object refcount. 52 | */ 53 | } 54 | 55 | DUK_INTERNAL void duk_hobject_run_finalizer(duk_hthread *thr, duk_hobject *obj) { 56 | duk_context *ctx = (duk_context *) thr; 57 | duk_ret_t rc; 58 | #ifdef DUK_USE_ASSERTIONS 59 | duk_idx_t entry_top; 60 | #endif 61 | 62 | DUK_DDD(DUK_DDDPRINT("running object finalizer for object: %p", (void *) obj)); 63 | 64 | DUK_ASSERT(thr != NULL); 65 | DUK_ASSERT(ctx != NULL); 66 | DUK_ASSERT(obj != NULL); 67 | DUK_ASSERT_VALSTACK_SPACE(thr, 1); 68 | 69 | #ifdef DUK_USE_ASSERTIONS 70 | entry_top = duk_get_top(ctx); 71 | #endif 72 | /* 73 | * Get and call the finalizer. All of this must be wrapped 74 | * in a protected call, because even getting the finalizer 75 | * may trigger an error (getter may throw one, for instance). 76 | */ 77 | 78 | if (DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) obj)) { 79 | DUK_D(DUK_DPRINT("object already finalized, avoid running finalizer twice: %!O", obj)); 80 | return; 81 | } 82 | DUK_HEAPHDR_SET_FINALIZED((duk_heaphdr *) obj); /* ensure never re-entered until rescue cycle complete */ 83 | if (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(obj)) { 84 | /* This shouldn't happen; call sites should avoid looking up 85 | * _Finalizer "through" a Proxy, but ignore if we come here 86 | * with a Proxy to avoid finalizer re-entry. 87 | */ 88 | DUK_D(DUK_DPRINT("object is a proxy, skip finalizer call")); 89 | return; 90 | } 91 | 92 | /* XXX: use a NULL error handler for the finalizer call? */ 93 | 94 | DUK_DDD(DUK_DDDPRINT("-> finalizer found, calling wrapped finalize helper")); 95 | duk_push_hobject(ctx, obj); /* this also increases refcount by one */ 96 | rc = duk_safe_call(ctx, duk__finalize_helper, 0 /*nargs*/, 1 /*nrets*/); /* -> [... obj retval/error] */ 97 | DUK_ASSERT_TOP(ctx, entry_top + 2); /* duk_safe_call discipline */ 98 | 99 | if (rc != DUK_EXEC_SUCCESS) { 100 | /* Note: we ask for one return value from duk_safe_call to get this 101 | * error debugging here. 102 | */ 103 | DUK_D(DUK_DPRINT("wrapped finalizer call failed for object %p (ignored); error: %!T", 104 | (void *) obj, (duk_tval *) duk_get_tval(ctx, -1))); 105 | } 106 | duk_pop_2(ctx); /* -> [...] */ 107 | 108 | DUK_ASSERT_TOP(ctx, entry_top); 109 | } 110 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_hobject_misc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Misc support functions 3 | */ 4 | 5 | #include "duk_internal.h" 6 | 7 | DUK_INTERNAL duk_bool_t duk_hobject_prototype_chain_contains(duk_hthread *thr, duk_hobject *h, duk_hobject *p, duk_bool_t ignore_loop) { 8 | duk_uint_t sanity; 9 | 10 | DUK_ASSERT(thr != NULL); 11 | DUK_ASSERT(h != NULL); 12 | /* allow 'p' to be NULL; then the result is always false */ 13 | 14 | sanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY; 15 | do { 16 | if (h == p) { 17 | return 1; 18 | } 19 | 20 | if (sanity-- == 0) { 21 | if (ignore_loop) { 22 | break; 23 | } else { 24 | DUK_ERROR(thr, DUK_ERR_INTERNAL_ERROR, DUK_STR_PROTOTYPE_CHAIN_LIMIT); 25 | } 26 | } 27 | h = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h); 28 | } while (h); 29 | 30 | return 0; 31 | } 32 | 33 | DUK_INTERNAL void duk_hobject_set_prototype_updref(duk_hthread *thr, duk_hobject *h, duk_hobject *p) { 34 | #ifdef DUK_USE_REFERENCE_COUNTING 35 | duk_hobject *tmp; 36 | 37 | DUK_ASSERT(h); 38 | tmp = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h); 39 | DUK_HOBJECT_SET_PROTOTYPE(thr->heap, h, p); 40 | DUK_HOBJECT_INCREF_ALLOWNULL(thr, p); /* avoid problems if p == h->prototype */ 41 | DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp); 42 | #else 43 | DUK_ASSERT(h); 44 | DUK_UNREF(thr); 45 | DUK_HOBJECT_SET_PROTOTYPE(thr->heap, h, p); 46 | #endif 47 | } 48 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_hstring_misc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Misc support functions 3 | */ 4 | 5 | #include "duk_internal.h" 6 | 7 | DUK_INTERNAL duk_ucodepoint_t duk_hstring_char_code_at_raw(duk_hthread *thr, duk_hstring *h, duk_uint_t pos) { 8 | duk_uint32_t boff; 9 | const duk_uint8_t *p, *p_start, *p_end; 10 | duk_ucodepoint_t cp; 11 | 12 | /* Caller must check character offset to be inside the string. */ 13 | DUK_ASSERT(thr != NULL); 14 | DUK_ASSERT(h != NULL); 15 | DUK_ASSERT_DISABLE(pos >= 0); /* unsigned */ 16 | DUK_ASSERT(pos < (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h)); 17 | 18 | boff = duk_heap_strcache_offset_char2byte(thr, h, (duk_uint32_t) pos); 19 | DUK_DDD(DUK_DDDPRINT("charCodeAt: pos=%ld -> boff=%ld, str=%!O", 20 | (long) pos, (long) boff, (duk_heaphdr *) h)); 21 | DUK_ASSERT_DISABLE(boff >= 0); 22 | DUK_ASSERT(boff < DUK_HSTRING_GET_BYTELEN(h)); 23 | 24 | p_start = DUK_HSTRING_GET_DATA(h); 25 | p_end = p_start + DUK_HSTRING_GET_BYTELEN(h); 26 | p = p_start + boff; 27 | DUK_DDD(DUK_DDDPRINT("p_start=%p, p_end=%p, p=%p", 28 | (const void *) p_start, (const void *) p_end, 29 | (const void *) p)); 30 | 31 | /* This may throw an error though not for valid E5 strings. */ 32 | cp = duk_unicode_decode_xutf8_checked(thr, &p, p_start, p_end); 33 | return cp; 34 | } 35 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_hthread_alloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * duk_hthread allocation and freeing. 3 | */ 4 | 5 | #include "duk_internal.h" 6 | 7 | /* 8 | * Allocate initial stacks for a thread. Note that 'thr' must be reachable 9 | * as a garbage collection may be triggered by the allocation attempts. 10 | * Returns zero (without leaking memory) if init fails. 11 | */ 12 | 13 | DUK_INTERNAL duk_bool_t duk_hthread_init_stacks(duk_heap *heap, duk_hthread *thr) { 14 | duk_size_t alloc_size; 15 | duk_size_t i; 16 | 17 | DUK_ASSERT(heap != NULL); 18 | DUK_ASSERT(thr != NULL); 19 | DUK_ASSERT(thr->valstack == NULL); 20 | DUK_ASSERT(thr->valstack_end == NULL); 21 | DUK_ASSERT(thr->valstack_bottom == NULL); 22 | DUK_ASSERT(thr->valstack_top == NULL); 23 | DUK_ASSERT(thr->callstack == NULL); 24 | DUK_ASSERT(thr->catchstack == NULL); 25 | 26 | /* valstack */ 27 | alloc_size = sizeof(duk_tval) * DUK_VALSTACK_INITIAL_SIZE; 28 | thr->valstack = (duk_tval *) DUK_ALLOC(heap, alloc_size); 29 | if (!thr->valstack) { 30 | goto fail; 31 | } 32 | DUK_MEMZERO(thr->valstack, alloc_size); 33 | thr->valstack_end = thr->valstack + DUK_VALSTACK_INITIAL_SIZE; 34 | #if !defined(DUK_USE_PREFER_SIZE) 35 | thr->valstack_size = DUK_VALSTACK_INITIAL_SIZE; 36 | #endif 37 | thr->valstack_bottom = thr->valstack; 38 | thr->valstack_top = thr->valstack; 39 | 40 | for (i = 0; i < DUK_VALSTACK_INITIAL_SIZE; i++) { 41 | DUK_TVAL_SET_UNDEFINED(&thr->valstack[i]); 42 | } 43 | 44 | /* callstack */ 45 | alloc_size = sizeof(duk_activation) * DUK_CALLSTACK_INITIAL_SIZE; 46 | thr->callstack = (duk_activation *) DUK_ALLOC(heap, alloc_size); 47 | if (!thr->callstack) { 48 | goto fail; 49 | } 50 | DUK_MEMZERO(thr->callstack, alloc_size); 51 | thr->callstack_size = DUK_CALLSTACK_INITIAL_SIZE; 52 | DUK_ASSERT(thr->callstack_top == 0); 53 | 54 | /* catchstack */ 55 | alloc_size = sizeof(duk_catcher) * DUK_CATCHSTACK_INITIAL_SIZE; 56 | thr->catchstack = (duk_catcher *) DUK_ALLOC(heap, alloc_size); 57 | if (!thr->catchstack) { 58 | goto fail; 59 | } 60 | DUK_MEMZERO(thr->catchstack, alloc_size); 61 | thr->catchstack_size = DUK_CATCHSTACK_INITIAL_SIZE; 62 | DUK_ASSERT(thr->catchstack_top == 0); 63 | 64 | return 1; 65 | 66 | fail: 67 | DUK_FREE(heap, thr->valstack); 68 | DUK_FREE(heap, thr->callstack); 69 | DUK_FREE(heap, thr->catchstack); 70 | 71 | thr->valstack = NULL; 72 | thr->callstack = NULL; 73 | thr->catchstack = NULL; 74 | return 0; 75 | } 76 | 77 | /* For indirect allocs. */ 78 | 79 | DUK_INTERNAL void *duk_hthread_get_valstack_ptr(duk_heap *heap, void *ud) { 80 | duk_hthread *thr = (duk_hthread *) ud; 81 | DUK_UNREF(heap); 82 | return (void *) thr->valstack; 83 | } 84 | 85 | DUK_INTERNAL void *duk_hthread_get_callstack_ptr(duk_heap *heap, void *ud) { 86 | duk_hthread *thr = (duk_hthread *) ud; 87 | DUK_UNREF(heap); 88 | return (void *) thr->callstack; 89 | } 90 | 91 | DUK_INTERNAL void *duk_hthread_get_catchstack_ptr(duk_heap *heap, void *ud) { 92 | duk_hthread *thr = (duk_hthread *) ud; 93 | DUK_UNREF(heap); 94 | return (void *) thr->catchstack; 95 | } 96 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_hthread_misc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Thread support. 3 | */ 4 | 5 | #include "duk_internal.h" 6 | 7 | DUK_INTERNAL void duk_hthread_terminate(duk_hthread *thr) { 8 | DUK_ASSERT(thr != NULL); 9 | 10 | /* Order of unwinding is important */ 11 | 12 | duk_hthread_catchstack_unwind(thr, 0); 13 | 14 | duk_hthread_callstack_unwind(thr, 0); /* side effects, possibly errors */ 15 | 16 | thr->valstack_bottom = thr->valstack; 17 | duk_set_top((duk_context *) thr, 0); /* unwinds valstack, updating refcounts */ 18 | 19 | thr->state = DUK_HTHREAD_STATE_TERMINATED; 20 | 21 | /* Here we could remove references to built-ins, but it may not be 22 | * worth the effort because built-ins are quite likely to be shared 23 | * with another (unterminated) thread, and terminated threads are also 24 | * usually garbage collected quite quickly. Also, doing DECREFs 25 | * could trigger finalization, which would run on the current thread 26 | * and have access to only some of the built-ins. Garbage collection 27 | * deals with this correctly already. 28 | */ 29 | 30 | /* XXX: Shrink the stacks to minimize memory usage? May not 31 | * be worth the effort because terminated threads are usually 32 | * garbage collected quite soon. 33 | */ 34 | } 35 | 36 | DUK_INTERNAL duk_activation *duk_hthread_get_current_activation(duk_hthread *thr) { 37 | DUK_ASSERT(thr != NULL); 38 | 39 | if (thr->callstack_top > 0) { 40 | return thr->callstack + thr->callstack_top - 1; 41 | } else { 42 | return NULL; 43 | } 44 | } 45 | 46 | #if defined(DUK_USE_DEBUGGER_SUPPORT) 47 | DUK_INTERNAL duk_uint_fast32_t duk_hthread_get_act_curr_pc(duk_hthread *thr, duk_activation *act) { 48 | duk_instr_t *bcode; 49 | 50 | DUK_ASSERT(thr != NULL); 51 | DUK_ASSERT(act != NULL); 52 | DUK_UNREF(thr); 53 | 54 | /* XXX: store 'bcode' pointer to activation for faster lookup? */ 55 | if (act->func && DUK_HOBJECT_IS_COMPILEDFUNCTION(act->func)) { 56 | bcode = DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(thr->heap, (duk_hcompiledfunction *) (act->func)); 57 | return (duk_uint_fast32_t) (act->curr_pc - bcode); 58 | } 59 | return 0; 60 | } 61 | #endif /* DUK_USE_DEBUGGER_SUPPORT */ 62 | 63 | DUK_INTERNAL duk_uint_fast32_t duk_hthread_get_act_prev_pc(duk_hthread *thr, duk_activation *act) { 64 | duk_instr_t *bcode; 65 | duk_uint_fast32_t ret; 66 | 67 | DUK_ASSERT(thr != NULL); 68 | DUK_ASSERT(act != NULL); 69 | DUK_UNREF(thr); 70 | 71 | if (act->func && DUK_HOBJECT_IS_COMPILEDFUNCTION(act->func)) { 72 | bcode = DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(thr->heap, (duk_hcompiledfunction *) (act->func)); 73 | ret = (duk_uint_fast32_t) (act->curr_pc - bcode); 74 | if (ret > 0) { 75 | ret--; 76 | } 77 | return ret; 78 | } 79 | return 0; 80 | } 81 | 82 | /* Write bytecode executor's curr_pc back to topmost activation (if any). */ 83 | DUK_INTERNAL void duk_hthread_sync_currpc(duk_hthread *thr) { 84 | duk_activation *act; 85 | 86 | DUK_ASSERT(thr != NULL); 87 | 88 | if (thr->ptr_curr_pc != NULL) { 89 | /* ptr_curr_pc != NULL only when bytecode executor is active. */ 90 | DUK_ASSERT(thr->callstack_top > 0); 91 | act = thr->callstack + thr->callstack_top - 1; 92 | act->curr_pc = *thr->ptr_curr_pc; 93 | } 94 | } 95 | 96 | DUK_INTERNAL void duk_hthread_sync_and_null_currpc(duk_hthread *thr) { 97 | duk_activation *act; 98 | 99 | DUK_ASSERT(thr != NULL); 100 | 101 | if (thr->ptr_curr_pc != NULL) { 102 | /* ptr_curr_pc != NULL only when bytecode executor is active. */ 103 | DUK_ASSERT(thr->callstack_top > 0); 104 | act = thr->callstack + thr->callstack_top - 1; 105 | act->curr_pc = *thr->ptr_curr_pc; 106 | thr->ptr_curr_pc = NULL; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_initjs_min.js: -------------------------------------------------------------------------------- 1 | (function(d,a){function b(a,b,c){Object.defineProperty(a,b,{value:c,writable:!0,enumerable:!1,configurable:!0})}b(a.Logger,"clog",new a.Logger("C"));b(a,"modLoaded",{})})(this,Duktape); 2 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Top-level include file to be used for all (internal) source files. 3 | * 4 | * Source files should not include individual header files, as they 5 | * have not been designed to be individually included. 6 | */ 7 | 8 | #ifndef DUK_INTERNAL_H_INCLUDED 9 | #define DUK_INTERNAL_H_INCLUDED 10 | 11 | /* 12 | * The 'duktape.h' header provides the public API, but also handles all 13 | * compiler and platform specific feature detection, Duktape feature 14 | * resolution, inclusion of system headers, etc. These have been merged 15 | * because the public API is also dependent on e.g. detecting appropriate 16 | * C types which is quite platform/compiler specific especially for a non-C99 17 | * build. The public API is also dependent on the resolved feature set. 18 | * 19 | * Some actions taken by the merged header (such as including system headers) 20 | * are not appropriate for building a user application. The define 21 | * DUK_COMPILING_DUKTAPE allows the merged header to skip/include some 22 | * sections depending on what is being built. 23 | */ 24 | 25 | #define DUK_COMPILING_DUKTAPE 26 | #include "duktape.h" 27 | 28 | /* 29 | * User declarations, e.g. prototypes for user functions used by Duktape 30 | * macros. Concretely, if DUK_USE_PANIC_HANDLER is used and the macro 31 | * value calls a user function, it needs to be declared for Duktape 32 | * compilation to avoid warnings. 33 | */ 34 | 35 | DUK_USE_USER_DECLARE() 36 | 37 | /* 38 | * Duktape includes (other than duk_features.h) 39 | * 40 | * The header files expect to be included in an order which satisfies header 41 | * dependencies correctly (the headers themselves don't include any other 42 | * includes). Forward declarations are used to break circular struct/typedef 43 | * dependencies. 44 | */ 45 | 46 | #include "duk_replacements.h" 47 | #include "duk_jmpbuf.h" 48 | #include "duk_exception.h" 49 | #include "duk_forwdecl.h" 50 | #include "duk_builtins.h" /* autogenerated: strings and built-in object init data */ 51 | 52 | #include "duk_util.h" 53 | #include "duk_strings.h" 54 | #include "duk_js_bytecode.h" 55 | #include "duk_lexer.h" 56 | #include "duk_js_compiler.h" 57 | #include "duk_regexp.h" 58 | #include "duk_tval.h" 59 | #include "duk_heaphdr.h" 60 | #include "duk_api_internal.h" 61 | #include "duk_hstring.h" 62 | #include "duk_hobject.h" 63 | #include "duk_hcompiledfunction.h" 64 | #include "duk_hnativefunction.h" 65 | #include "duk_hbufferobject.h" 66 | #include "duk_hthread.h" 67 | #include "duk_hbuffer.h" 68 | #include "duk_heap.h" 69 | #include "duk_debugger.h" 70 | #include "duk_debug.h" 71 | #include "duk_error.h" 72 | #include "duk_unicode.h" 73 | #include "duk_json.h" 74 | #include "duk_js.h" 75 | #include "duk_numconv.h" 76 | #include "duk_bi_protos.h" 77 | #include "duk_selftest.h" 78 | 79 | #endif /* DUK_INTERNAL_H_INCLUDED */ 80 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_jmpbuf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Wrapper for jmp_buf. 3 | * 4 | * This is used because jmp_buf is an array type for backward compatibility. 5 | * Wrapping jmp_buf in a struct makes pointer references, sizeof, etc, 6 | * behave more intuitively. 7 | * 8 | * http://en.wikipedia.org/wiki/Setjmp.h#Member_types 9 | */ 10 | 11 | #ifndef DUK_JMPBUF_H_INCLUDED 12 | #define DUK_JMPBUF_H_INCLUDED 13 | 14 | #if !defined(DUK_USE_CPP_EXCEPTIONS) 15 | struct duk_jmpbuf { 16 | #if defined(DUK_USE_SETJMP) || defined(DUK_USE_UNDERSCORE_SETJMP) 17 | jmp_buf jb; 18 | #elif defined(DUK_USE_SIGSETJMP) 19 | sigjmp_buf jb; 20 | #else 21 | #error internal error, no long control transfer provider 22 | #endif 23 | }; 24 | #endif 25 | 26 | #endif /* DUK_JMPBUF_H_INCLUDED */ 27 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_json.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Defines for JSON, especially duk_bi_json.c. 3 | */ 4 | 5 | #ifndef DUK_JSON_H_INCLUDED 6 | #define DUK_JSON_H_INCLUDED 7 | 8 | /* Encoding/decoding flags */ 9 | #define DUK_JSON_FLAG_ASCII_ONLY (1 << 0) /* escape any non-ASCII characters */ 10 | #define DUK_JSON_FLAG_AVOID_KEY_QUOTES (1 << 1) /* avoid key quotes when key is an ASCII Identifier */ 11 | #define DUK_JSON_FLAG_EXT_CUSTOM (1 << 2) /* extended types: custom encoding */ 12 | #define DUK_JSON_FLAG_EXT_COMPATIBLE (1 << 3) /* extended types: compatible encoding */ 13 | 14 | /* How much stack to require on entry to object/array encode */ 15 | #define DUK_JSON_ENC_REQSTACK 32 16 | 17 | /* How much stack to require on entry to object/array decode */ 18 | #define DUK_JSON_DEC_REQSTACK 32 19 | 20 | /* How large a loop detection stack to use */ 21 | #define DUK_JSON_ENC_LOOPARRAY 64 22 | 23 | /* Encoding state. Heap object references are all borrowed. */ 24 | typedef struct { 25 | duk_hthread *thr; 26 | duk_bufwriter_ctx bw; /* output bufwriter */ 27 | duk_hobject *h_replacer; /* replacer function */ 28 | duk_hstring *h_gap; /* gap (if empty string, NULL) */ 29 | duk_idx_t idx_proplist; /* explicit PropertyList */ 30 | duk_idx_t idx_loop; /* valstack index of loop detection object */ 31 | duk_small_uint_t flags; 32 | duk_small_uint_t flag_ascii_only; 33 | duk_small_uint_t flag_avoid_key_quotes; 34 | #if defined(DUK_USE_JX) || defined(DUK_USE_JC) 35 | duk_small_uint_t flag_ext_custom; 36 | duk_small_uint_t flag_ext_compatible; 37 | duk_small_uint_t flag_ext_custom_or_compatible; 38 | #endif 39 | duk_int_t recursion_depth; 40 | duk_int_t recursion_limit; 41 | duk_uint_t mask_for_undefined; /* type bit mask: types which certainly produce 'undefined' */ 42 | #if defined(DUK_USE_JX) || defined(DUK_USE_JC) 43 | duk_small_uint_t stridx_custom_undefined; 44 | duk_small_uint_t stridx_custom_nan; 45 | duk_small_uint_t stridx_custom_neginf; 46 | duk_small_uint_t stridx_custom_posinf; 47 | duk_small_uint_t stridx_custom_function; 48 | #endif 49 | duk_hobject *visiting[DUK_JSON_ENC_LOOPARRAY]; /* indexed by recursion_depth */ 50 | } duk_json_enc_ctx; 51 | 52 | typedef struct { 53 | duk_hthread *thr; 54 | const duk_uint8_t *p; 55 | const duk_uint8_t *p_start; 56 | const duk_uint8_t *p_end; 57 | duk_idx_t idx_reviver; 58 | duk_small_uint_t flags; 59 | #if defined(DUK_USE_JX) || defined(DUK_USE_JC) 60 | duk_small_uint_t flag_ext_custom; 61 | duk_small_uint_t flag_ext_compatible; 62 | duk_small_uint_t flag_ext_custom_or_compatible; 63 | #endif 64 | duk_int_t recursion_depth; 65 | duk_int_t recursion_limit; 66 | } duk_json_dec_ctx; 67 | 68 | #endif /* DUK_JSON_H_INCLUDED */ 69 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_numconv.h: -------------------------------------------------------------------------------- 1 | #ifndef DUK_NUMCONV_H_INCLUDED 2 | #define DUK_NUMCONV_H_INCLUDED 3 | 4 | /* 5 | * Number-to-string conversion. The semantics of these is very tightly 6 | * bound with the Ecmascript semantics required for call sites. 7 | */ 8 | 9 | /* Output a specified number of digits instead of using the shortest 10 | * form. Used for toPrecision() and toFixed(). 11 | */ 12 | #define DUK_N2S_FLAG_FIXED_FORMAT (1 << 0) 13 | 14 | /* Force exponential format. Used for toExponential(). */ 15 | #define DUK_N2S_FLAG_FORCE_EXP (1 << 1) 16 | 17 | /* If number would need zero padding (for whole number part), use 18 | * exponential format instead. E.g. if input number is 12300, 3 19 | * digits are generated ("123"), output "1.23e+4" instead of "12300". 20 | * Used for toPrecision(). 21 | */ 22 | #define DUK_N2S_FLAG_NO_ZERO_PAD (1 << 2) 23 | 24 | /* Digit count indicates number of fractions (i.e. an absolute 25 | * digit index instead of a relative one). Used together with 26 | * DUK_N2S_FLAG_FIXED_FORMAT for toFixed(). 27 | */ 28 | #define DUK_N2S_FLAG_FRACTION_DIGITS (1 << 3) 29 | 30 | /* 31 | * String-to-number conversion 32 | */ 33 | 34 | /* Maximum exponent value when parsing numbers. This is not strictly 35 | * compliant as there should be no upper limit, but as we parse the 36 | * exponent without a bigint, impose some limit. 37 | */ 38 | #define DUK_S2N_MAX_EXPONENT 1000000000 39 | 40 | /* Trim white space (= allow leading and trailing whitespace) */ 41 | #define DUK_S2N_FLAG_TRIM_WHITE (1 << 0) 42 | 43 | /* Allow exponent */ 44 | #define DUK_S2N_FLAG_ALLOW_EXP (1 << 1) 45 | 46 | /* Allow trailing garbage (e.g. treat "123foo" as "123) */ 47 | #define DUK_S2N_FLAG_ALLOW_GARBAGE (1 << 2) 48 | 49 | /* Allow leading plus sign */ 50 | #define DUK_S2N_FLAG_ALLOW_PLUS (1 << 3) 51 | 52 | /* Allow leading minus sign */ 53 | #define DUK_S2N_FLAG_ALLOW_MINUS (1 << 4) 54 | 55 | /* Allow 'Infinity' */ 56 | #define DUK_S2N_FLAG_ALLOW_INF (1 << 5) 57 | 58 | /* Allow fraction part */ 59 | #define DUK_S2N_FLAG_ALLOW_FRAC (1 << 6) 60 | 61 | /* Allow naked fraction (e.g. ".123") */ 62 | #define DUK_S2N_FLAG_ALLOW_NAKED_FRAC (1 << 7) 63 | 64 | /* Allow empty fraction (e.g. "123.") */ 65 | #define DUK_S2N_FLAG_ALLOW_EMPTY_FRAC (1 << 8) 66 | 67 | /* Allow empty string to be interpreted as 0 */ 68 | #define DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO (1 << 9) 69 | 70 | /* Allow leading zeroes (e.g. "0123" -> "123") */ 71 | #define DUK_S2N_FLAG_ALLOW_LEADING_ZERO (1 << 10) 72 | 73 | /* Allow automatic detection of hex base ("0x" or "0X" prefix), 74 | * overrides radix argument and forces integer mode. 75 | */ 76 | #define DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT (1 << 11) 77 | 78 | /* Allow automatic detection of octal base, overrides radix 79 | * argument and forces integer mode. 80 | */ 81 | #define DUK_S2N_FLAG_ALLOW_AUTO_OCT_INT (1 << 12) 82 | 83 | /* 84 | * Prototypes 85 | */ 86 | 87 | DUK_INTERNAL_DECL void duk_numconv_stringify(duk_context *ctx, duk_small_int_t radix, duk_small_int_t digits, duk_small_uint_t flags); 88 | DUK_INTERNAL_DECL void duk_numconv_parse(duk_context *ctx, duk_small_int_t radix, duk_small_uint_t flags); 89 | 90 | #endif /* DUK_NUMCONV_H_INCLUDED */ 91 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_regexp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Regular expression structs, constants, and bytecode defines. 3 | */ 4 | 5 | #ifndef DUK_REGEXP_H_INCLUDED 6 | #define DUK_REGEXP_H_INCLUDED 7 | 8 | /* maximum bytecode copies for {n,m} quantifiers */ 9 | #define DUK_RE_MAX_ATOM_COPIES 1000 10 | 11 | /* regexp compilation limits */ 12 | #define DUK_RE_COMPILE_TOKEN_LIMIT 100000000L /* 1e8 */ 13 | 14 | /* regexp execution limits */ 15 | #define DUK_RE_EXECUTE_STEPS_LIMIT 1000000000L /* 1e9 */ 16 | 17 | /* regexp opcodes */ 18 | #define DUK_REOP_MATCH 1 19 | #define DUK_REOP_CHAR 2 20 | #define DUK_REOP_PERIOD 3 21 | #define DUK_REOP_RANGES 4 22 | #define DUK_REOP_INVRANGES 5 23 | #define DUK_REOP_JUMP 6 24 | #define DUK_REOP_SPLIT1 7 25 | #define DUK_REOP_SPLIT2 8 26 | #define DUK_REOP_SQMINIMAL 9 27 | #define DUK_REOP_SQGREEDY 10 28 | #define DUK_REOP_SAVE 11 29 | #define DUK_REOP_WIPERANGE 12 30 | #define DUK_REOP_LOOKPOS 13 31 | #define DUK_REOP_LOOKNEG 14 32 | #define DUK_REOP_BACKREFERENCE 15 33 | #define DUK_REOP_ASSERT_START 16 34 | #define DUK_REOP_ASSERT_END 17 35 | #define DUK_REOP_ASSERT_WORD_BOUNDARY 18 36 | #define DUK_REOP_ASSERT_NOT_WORD_BOUNDARY 19 37 | 38 | /* flags */ 39 | #define DUK_RE_FLAG_GLOBAL (1 << 0) 40 | #define DUK_RE_FLAG_IGNORE_CASE (1 << 1) 41 | #define DUK_RE_FLAG_MULTILINE (1 << 2) 42 | 43 | struct duk_re_matcher_ctx { 44 | duk_hthread *thr; 45 | 46 | duk_uint32_t re_flags; 47 | const duk_uint8_t *input; 48 | const duk_uint8_t *input_end; 49 | const duk_uint8_t *bytecode; 50 | const duk_uint8_t *bytecode_end; 51 | const duk_uint8_t **saved; /* allocated from valstack (fixed buffer) */ 52 | duk_uint32_t nsaved; 53 | duk_uint32_t recursion_depth; 54 | duk_uint32_t recursion_limit; 55 | duk_uint32_t steps_count; 56 | duk_uint32_t steps_limit; 57 | }; 58 | 59 | struct duk_re_compiler_ctx { 60 | duk_hthread *thr; 61 | 62 | duk_uint32_t re_flags; 63 | duk_lexer_ctx lex; 64 | duk_re_token curr_token; 65 | duk_bufwriter_ctx bw; 66 | duk_uint32_t captures; /* highest capture number emitted so far (used as: ++captures) */ 67 | duk_uint32_t highest_backref; 68 | duk_uint32_t recursion_depth; 69 | duk_uint32_t recursion_limit; 70 | duk_uint32_t nranges; /* internal temporary value, used for char classes */ 71 | }; 72 | 73 | /* 74 | * Prototypes 75 | */ 76 | 77 | DUK_INTERNAL_DECL void duk_regexp_compile(duk_hthread *thr); 78 | DUK_INTERNAL_DECL void duk_regexp_create_instance(duk_hthread *thr); 79 | DUK_INTERNAL_DECL void duk_regexp_match(duk_hthread *thr); 80 | DUK_INTERNAL_DECL void duk_regexp_match_force_global(duk_hthread *thr); /* hacky helper for String.prototype.split() */ 81 | 82 | #endif /* DUK_REGEXP_H_INCLUDED */ 83 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_replacements.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Replacements for missing platform functions. 3 | * 4 | * Unlike the originals, fpclassify() and signbit() replacements don't 5 | * work on any floating point types, only doubles. The C typing here 6 | * mimics the standard prototypes. 7 | */ 8 | 9 | #include "duk_internal.h" 10 | 11 | #if defined(DUK_USE_COMPUTED_NAN) 12 | DUK_INTERNAL double duk_computed_nan; 13 | #endif 14 | 15 | #if defined(DUK_USE_COMPUTED_INFINITY) 16 | DUK_INTERNAL double duk_computed_infinity; 17 | #endif 18 | 19 | #if defined(DUK_USE_REPL_FPCLASSIFY) 20 | DUK_INTERNAL int duk_repl_fpclassify(double x) { 21 | duk_double_union u; 22 | duk_uint_fast16_t expt; 23 | duk_small_int_t mzero; 24 | 25 | u.d = x; 26 | expt = (duk_uint_fast16_t) (u.us[DUK_DBL_IDX_US0] & 0x7ff0UL); 27 | if (expt > 0x0000UL && expt < 0x7ff0UL) { 28 | /* expt values [0x001,0x7fe] = normal */ 29 | return DUK_FP_NORMAL; 30 | } 31 | 32 | mzero = (u.ui[DUK_DBL_IDX_UI1] == 0 && (u.ui[DUK_DBL_IDX_UI0] & 0x000fffffUL) == 0); 33 | if (expt == 0x0000UL) { 34 | /* expt 0x000 is zero/subnormal */ 35 | if (mzero) { 36 | return DUK_FP_ZERO; 37 | } else { 38 | return DUK_FP_SUBNORMAL; 39 | } 40 | } else { 41 | /* expt 0xfff is infinite/nan */ 42 | if (mzero) { 43 | return DUK_FP_INFINITE; 44 | } else { 45 | return DUK_FP_NAN; 46 | } 47 | } 48 | } 49 | #endif 50 | 51 | #if defined(DUK_USE_REPL_SIGNBIT) 52 | DUK_INTERNAL int duk_repl_signbit(double x) { 53 | duk_double_union u; 54 | u.d = x; 55 | return (int) (u.uc[DUK_DBL_IDX_UC0] & 0x80UL); 56 | } 57 | #endif 58 | 59 | #if defined(DUK_USE_REPL_ISFINITE) 60 | DUK_INTERNAL int duk_repl_isfinite(double x) { 61 | int c = DUK_FPCLASSIFY(x); 62 | if (c == DUK_FP_NAN || c == DUK_FP_INFINITE) { 63 | return 0; 64 | } else { 65 | return 1; 66 | } 67 | } 68 | #endif 69 | 70 | #if defined(DUK_USE_REPL_ISNAN) 71 | DUK_INTERNAL int duk_repl_isnan(double x) { 72 | int c = DUK_FPCLASSIFY(x); 73 | return (c == DUK_FP_NAN); 74 | } 75 | #endif 76 | 77 | #if defined(DUK_USE_REPL_ISINF) 78 | DUK_INTERNAL int duk_repl_isinf(double x) { 79 | int c = DUK_FPCLASSIFY(x); 80 | return (c == DUK_FP_INFINITE); 81 | } 82 | #endif 83 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_replacements.h: -------------------------------------------------------------------------------- 1 | #ifndef DUK_REPLACEMENTS_H_INCLUDED 2 | #define DUK_REPLACEMENTS_H_INCLUDED 3 | 4 | #if defined(DUK_USE_COMPUTED_INFINITY) 5 | DUK_INTERNAL_DECL double duk_computed_infinity; 6 | #endif 7 | 8 | #if defined(DUK_USE_COMPUTED_NAN) 9 | DUK_INTERNAL_DECL double duk_computed_nan; 10 | #endif 11 | 12 | #if defined(DUK_USE_REPL_FPCLASSIFY) 13 | DUK_INTERNAL_DECL int duk_repl_fpclassify(double x); 14 | #endif 15 | 16 | #if defined(DUK_USE_REPL_SIGNBIT) 17 | DUK_INTERNAL_DECL int duk_repl_signbit(double x); 18 | #endif 19 | 20 | #if defined(DUK_USE_REPL_ISFINITE) 21 | DUK_INTERNAL_DECL int duk_repl_isfinite(double x); 22 | #endif 23 | 24 | #if defined(DUK_USE_REPL_ISNAN) 25 | DUK_INTERNAL_DECL int duk_repl_isnan(double x); 26 | #endif 27 | 28 | #if defined(DUK_USE_REPL_ISINF) 29 | DUK_INTERNAL_DECL int duk_repl_isinf(double x); 30 | #endif 31 | 32 | #endif /* DUK_REPLACEMENTS_H_INCLUDED */ 33 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_selftest.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Selftest code 3 | */ 4 | 5 | #ifndef DUK_SELFTEST_H_INCLUDED 6 | #define DUK_SELFTEST_H_INCLUDED 7 | 8 | #if defined(DUK_USE_SELF_TESTS) 9 | DUK_INTERNAL_DECL void duk_selftest_run_tests(void); 10 | #endif 11 | 12 | #endif /* DUK_SELFTEST_H_INCLUDED */ 13 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_tval.c: -------------------------------------------------------------------------------- 1 | #include "duk_internal.h" 2 | 3 | #if defined(DUK_USE_FASTINT) 4 | 5 | /* 6 | * Manually optimized double-to-fastint downgrade check. 7 | * 8 | * This check has a large impact on performance, especially for fastint 9 | * slow paths, so must be changed carefully. The code should probably be 10 | * optimized for the case where the result does not fit into a fastint, 11 | * to minimize the penalty for "slow path code" dealing with fractions etc. 12 | * 13 | * At least on one tested soft float ARM platform double-to-int64 coercion 14 | * is very slow (and sometimes produces incorrect results, see self tests). 15 | * This algorithm combines a fastint compatibility check and extracting the 16 | * integer value from an IEEE double for setting the tagged fastint. For 17 | * other platforms a more naive approach might be better. 18 | * 19 | * See doc/fastint.rst for details. 20 | */ 21 | 22 | DUK_INTERNAL DUK_ALWAYS_INLINE void duk_tval_set_number_chkfast(duk_tval *tv, duk_double_t x) { 23 | duk_double_union du; 24 | duk_int64_t i; 25 | duk_small_int_t expt; 26 | duk_small_int_t shift; 27 | 28 | /* XXX: optimize for packed duk_tval directly? */ 29 | 30 | du.d = x; 31 | i = (duk_int64_t) DUK_DBLUNION_GET_INT64(&du); 32 | expt = (duk_small_int_t) ((i >> 52) & 0x07ff); 33 | shift = expt - 1023; 34 | 35 | if (shift >= 0 && shift <= 46) { /* exponents 1023 to 1069 */ 36 | duk_int64_t t; 37 | 38 | if (((0x000fffffffffffffLL >> shift) & i) == 0) { 39 | t = i | 0x0010000000000000LL; /* implicit leading one */ 40 | t = t & 0x001fffffffffffffLL; 41 | t = t >> (52 - shift); 42 | if (i < 0) { 43 | t = -t; 44 | } 45 | DUK_TVAL_SET_FASTINT(tv, t); 46 | return; 47 | } 48 | } else if (shift == -1023) { /* exponent 0 */ 49 | if (i >= 0 && (i & 0x000fffffffffffffLL) == 0) { 50 | /* Note: reject negative zero. */ 51 | DUK_TVAL_SET_FASTINT(tv, (duk_int64_t) 0); 52 | return; 53 | } 54 | } else if (shift == 47) { /* exponent 1070 */ 55 | if (i < 0 && (i & 0x000fffffffffffffLL) == 0) { 56 | DUK_TVAL_SET_FASTINT(tv, (duk_int64_t) DUK_FASTINT_MIN); 57 | return; 58 | } 59 | } 60 | 61 | DUK_TVAL_SET_DOUBLE(tv, x); 62 | return; 63 | } 64 | 65 | /* 66 | * Manually optimized number-to-double conversion 67 | */ 68 | 69 | #if defined(DUK_USE_FASTINT) && defined(DUK_USE_PACKED_TVAL) 70 | DUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_tval_get_number_packed(duk_tval *tv) { 71 | duk_double_union du; 72 | duk_uint64_t t; 73 | 74 | t = (duk_uint64_t) DUK_DBLUNION_GET_UINT64(tv); 75 | if ((t >> 48) != DUK_TAG_FASTINT) { 76 | return tv->d; 77 | } else if (t & 0x0000800000000000ULL) { 78 | t = (duk_uint64_t) (-((duk_int64_t) t)); /* avoid unary minus on unsigned */ 79 | t = t & 0x0000ffffffffffffULL; /* negative */ 80 | t |= 0xc330000000000000ULL; 81 | DUK_DBLUNION_SET_UINT64(&du, t); 82 | return du.d + 4503599627370496.0; /* 1 << 52 */ 83 | } else if (t != 0) { 84 | t &= 0x0000ffffffffffffULL; /* positive */ 85 | t |= 0x4330000000000000ULL; 86 | DUK_DBLUNION_SET_UINT64(&du, t); 87 | return du.d - 4503599627370496.0; /* 1 << 52 */ 88 | } else { 89 | return 0.0; /* zero */ 90 | } 91 | } 92 | #endif /* DUK_USE_FASTINT && DUK_USE_PACKED_TVAL */ 93 | 94 | #if 0 /* unused */ 95 | #if defined(DUK_USE_FASTINT) && !defined(DUK_USE_PACKED_TVAL) 96 | DUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_tval_get_number_unpacked(duk_tval *tv) { 97 | duk_double_union du; 98 | duk_uint64_t t; 99 | 100 | DUK_ASSERT(tv->t == DUK__TAG_NUMBER || tv->t == DUK_TAG_FASTINT); 101 | 102 | if (tv->t == DUK_TAG_FASTINT) { 103 | if (tv->v.fi >= 0) { 104 | t = 0x4330000000000000ULL | (duk_uint64_t) tv->v.fi; 105 | DUK_DBLUNION_SET_UINT64(&du, t); 106 | return du.d - 4503599627370496.0; /* 1 << 52 */ 107 | } else { 108 | t = 0xc330000000000000ULL | (duk_uint64_t) (-tv->v.fi); 109 | DUK_DBLUNION_SET_UINT64(&du, t); 110 | return du.d + 4503599627370496.0; /* 1 << 52 */ 111 | } 112 | } else { 113 | return tv->v.d; 114 | } 115 | } 116 | #endif /* DUK_USE_FASTINT && DUK_USE_PACKED_TVAL */ 117 | #endif /* 0 */ 118 | 119 | #if defined(DUK_USE_FASTINT) && !defined(DUK_USE_PACKED_TVAL) 120 | DUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_tval_get_number_unpacked_fastint(duk_tval *tv) { 121 | duk_double_union du; 122 | duk_uint64_t t; 123 | 124 | DUK_ASSERT(tv->t == DUK_TAG_FASTINT); 125 | 126 | if (tv->v.fi >= 0) { 127 | t = 0x4330000000000000ULL | (duk_uint64_t) tv->v.fi; 128 | DUK_DBLUNION_SET_UINT64(&du, t); 129 | return du.d - 4503599627370496.0; /* 1 << 52 */ 130 | } else { 131 | t = 0xc330000000000000ULL | (duk_uint64_t) (-tv->v.fi); 132 | DUK_DBLUNION_SET_UINT64(&du, t); 133 | return du.d + 4503599627370496.0; /* 1 << 52 */ 134 | } 135 | } 136 | #endif /* DUK_USE_FASTINT && DUK_USE_PACKED_TVAL */ 137 | 138 | #endif /* DUK_USE_FASTINT */ 139 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_util_bitdecoder.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Bitstream decoder. 3 | */ 4 | 5 | #include "duk_internal.h" 6 | 7 | /* Decode 'bits' bits from the input stream (bits must be 1...24). 8 | * When reading past bitstream end, zeroes are shifted in. The result 9 | * is signed to match duk_bd_decode_flagged. 10 | */ 11 | DUK_INTERNAL duk_int32_t duk_bd_decode(duk_bitdecoder_ctx *ctx, duk_small_int_t bits) { 12 | duk_small_int_t shift; 13 | duk_uint32_t mask; 14 | duk_uint32_t tmp; 15 | 16 | /* Note: cannot read more than 24 bits without possibly shifting top bits out. 17 | * Fixable, but adds complexity. 18 | */ 19 | DUK_ASSERT(bits >= 1 && bits <= 24); 20 | 21 | while (ctx->currbits < bits) { 22 | #if 0 23 | DUK_DDD(DUK_DDDPRINT("decode_bits: shift more data (bits=%ld, currbits=%ld)", 24 | (long) bits, (long) ctx->currbits)); 25 | #endif 26 | ctx->currval <<= 8; 27 | if (ctx->offset < ctx->length) { 28 | /* If ctx->offset >= ctx->length, we "shift zeroes in" 29 | * instead of croaking. 30 | */ 31 | ctx->currval |= ctx->data[ctx->offset++]; 32 | } 33 | ctx->currbits += 8; 34 | } 35 | #if 0 36 | DUK_DDD(DUK_DDDPRINT("decode_bits: bits=%ld, currbits=%ld, currval=0x%08lx", 37 | (long) bits, (long) ctx->currbits, (unsigned long) ctx->currval)); 38 | #endif 39 | 40 | /* Extract 'top' bits of currval; note that the extracted bits do not need 41 | * to be cleared, we just ignore them on next round. 42 | */ 43 | shift = ctx->currbits - bits; 44 | mask = (1 << bits) - 1; 45 | tmp = (ctx->currval >> shift) & mask; 46 | ctx->currbits = shift; /* remaining */ 47 | 48 | #if 0 49 | DUK_DDD(DUK_DDDPRINT("decode_bits: %ld bits -> 0x%08lx (%ld), currbits=%ld, currval=0x%08lx", 50 | (long) bits, (unsigned long) tmp, (long) tmp, (long) ctx->currbits, (unsigned long) ctx->currval)); 51 | #endif 52 | 53 | return tmp; 54 | } 55 | 56 | DUK_INTERNAL duk_small_int_t duk_bd_decode_flag(duk_bitdecoder_ctx *ctx) { 57 | return (duk_small_int_t) duk_bd_decode(ctx, 1); 58 | } 59 | 60 | /* Decode a one-bit flag, and if set, decode a value of 'bits', otherwise return 61 | * default value. Return value is signed so that negative marker value can be 62 | * used by caller as a "not present" value. 63 | */ 64 | DUK_INTERNAL duk_int32_t duk_bd_decode_flagged(duk_bitdecoder_ctx *ctx, duk_small_int_t bits, duk_int32_t def_value) { 65 | if (duk_bd_decode_flag(ctx)) { 66 | return (duk_int32_t) duk_bd_decode(ctx, bits); 67 | } else { 68 | return def_value; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_util_bitencoder.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Bitstream encoder. 3 | */ 4 | 5 | #include "duk_internal.h" 6 | 7 | DUK_INTERNAL void duk_be_encode(duk_bitencoder_ctx *ctx, duk_uint32_t data, duk_small_int_t bits) { 8 | duk_uint8_t tmp; 9 | 10 | DUK_ASSERT(ctx != NULL); 11 | DUK_ASSERT(ctx->currbits < 8); 12 | 13 | /* This limitation would be fixable but adds unnecessary complexity. */ 14 | DUK_ASSERT(bits >= 1 && bits <= 24); 15 | 16 | ctx->currval = (ctx->currval << bits) | data; 17 | ctx->currbits += bits; 18 | 19 | while (ctx->currbits >= 8) { 20 | if (ctx->offset < ctx->length) { 21 | tmp = (duk_uint8_t) ((ctx->currval >> (ctx->currbits - 8)) & 0xff); 22 | ctx->data[ctx->offset++] = tmp; 23 | } else { 24 | /* If buffer has been exhausted, truncate bitstream */ 25 | ctx->truncated = 1; 26 | } 27 | 28 | ctx->currbits -= 8; 29 | } 30 | } 31 | 32 | DUK_INTERNAL void duk_be_finish(duk_bitencoder_ctx *ctx) { 33 | duk_small_int_t npad; 34 | 35 | DUK_ASSERT(ctx != NULL); 36 | DUK_ASSERT(ctx->currbits < 8); 37 | 38 | npad = (duk_small_int_t) (8 - ctx->currbits); 39 | if (npad > 0) { 40 | duk_be_encode(ctx, 0, npad); 41 | } 42 | DUK_ASSERT(ctx->currbits == 0); 43 | } 44 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_util_hashbytes.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Hash function duk_util_hashbytes(). 3 | * 4 | * Currently, 32-bit MurmurHash2. 5 | * 6 | * Don't rely on specific hash values; hash function may be endianness 7 | * dependent, for instance. 8 | */ 9 | 10 | #include "duk_internal.h" 11 | 12 | #if defined(DUK_USE_STRHASH_DENSE) 13 | /* 'magic' constants for Murmurhash2 */ 14 | #define DUK__MAGIC_M ((duk_uint32_t) 0x5bd1e995UL) 15 | #define DUK__MAGIC_R 24 16 | 17 | DUK_INTERNAL duk_uint32_t duk_util_hashbytes(const duk_uint8_t *data, duk_size_t len, duk_uint32_t seed) { 18 | duk_uint32_t h = seed ^ ((duk_uint32_t) len); 19 | 20 | while (len >= 4) { 21 | /* Portability workaround is required for platforms without 22 | * unaligned access. The replacement code emulates little 23 | * endian access even on big endian architectures, which is 24 | * OK as long as it is consistent for a build. 25 | */ 26 | #ifdef DUK_USE_HASHBYTES_UNALIGNED_U32_ACCESS 27 | duk_uint32_t k = *((const duk_uint32_t *) (const void *) data); 28 | #else 29 | duk_uint32_t k = ((duk_uint32_t) data[0]) | 30 | (((duk_uint32_t) data[1]) << 8) | 31 | (((duk_uint32_t) data[2]) << 16) | 32 | (((duk_uint32_t) data[3]) << 24); 33 | #endif 34 | 35 | k *= DUK__MAGIC_M; 36 | k ^= k >> DUK__MAGIC_R; 37 | k *= DUK__MAGIC_M; 38 | h *= DUK__MAGIC_M; 39 | h ^= k; 40 | data += 4; 41 | len -= 4; 42 | } 43 | 44 | switch (len) { 45 | case 3: h ^= data[2] << 16; 46 | case 2: h ^= data[1] << 8; 47 | case 1: h ^= data[0]; 48 | h *= DUK__MAGIC_M; 49 | } 50 | 51 | h ^= h >> 13; 52 | h *= DUK__MAGIC_M; 53 | h ^= h >> 15; 54 | 55 | return h; 56 | } 57 | #endif /* DUK_USE_STRHASH_DENSE */ 58 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_util_hashprime.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Round a number upwards to a prime (not usually the nearest one). 3 | * 4 | * Uses a table of successive 32-bit primes whose ratio is roughly 5 | * constant. This keeps the relative upwards 'rounding error' bounded 6 | * and the data size small. A simple 'predict-correct' compression is 7 | * used to compress primes to one byte per prime. See genhashsizes.py 8 | * for details. 9 | * 10 | * The minimum prime returned here must be coordinated with the possible 11 | * probe sequence steps in duk_hobject and duk_heap stringtable. 12 | */ 13 | 14 | #include "duk_internal.h" 15 | 16 | /* Awkward inclusion condition: drop out of compilation if not needed by any 17 | * call site: object hash part or probing stringtable. 18 | */ 19 | #if defined(DUK_USE_HOBJECT_HASH_PART) || defined(DUK_USE_STRTAB_PROBE) 20 | 21 | /* hash size ratio goal, must match genhashsizes.py */ 22 | #define DUK__HASH_SIZE_RATIO 1177 /* floor(1.15 * (1 << 10)) */ 23 | 24 | /* prediction corrections for prime list (see genhashsizes.py) */ 25 | DUK_LOCAL const duk_int8_t duk__hash_size_corrections[] = { 26 | 17, /* minimum prime */ 27 | 4, 3, 4, 1, 4, 1, 1, 2, 2, 2, 2, 1, 6, 6, 9, 5, 1, 2, 2, 5, 1, 3, 3, 3, 28 | 5, 4, 4, 2, 4, 8, 3, 4, 23, 2, 4, 7, 8, 11, 2, 12, 15, 10, 1, 1, 5, 1, 5, 29 | 8, 9, 17, 14, 10, 7, 5, 2, 46, 21, 1, 9, 9, 4, 4, 10, 23, 36, 6, 20, 29, 30 | 18, 6, 19, 21, 16, 11, 5, 5, 48, 9, 1, 39, 14, 8, 4, 29, 9, 1, 15, 48, 12, 31 | 22, 6, 15, 27, 4, 2, 17, 28, 8, 9, 4, 5, 8, 3, 3, 8, 37, 11, 15, 8, 30, 32 | 43, 6, 33, 41, 5, 20, 32, 41, 38, 24, 77, 14, 19, 11, 4, 35, 18, 19, 41, 33 | 10, 23, 16, 9, 2, 34 | -1 35 | }; 36 | 37 | /* probe steps (see genhashsizes.py), currently assumed to be 32 entries long 38 | * (DUK_UTIL_GET_HASH_PROBE_STEP macro). 39 | */ 40 | DUK_INTERNAL duk_uint8_t duk_util_probe_steps[32] = { 41 | 2, 3, 5, 7, 11, 13, 19, 31, 41, 47, 59, 67, 73, 79, 89, 101, 103, 107, 42 | 109, 127, 137, 139, 149, 157, 163, 167, 173, 181, 191, 193, 197, 199 43 | }; 44 | 45 | DUK_INTERNAL duk_uint32_t duk_util_get_hash_prime(duk_uint32_t size) { 46 | const duk_int8_t *p = duk__hash_size_corrections; 47 | duk_uint32_t curr; 48 | 49 | curr = (duk_uint32_t) *p++; 50 | for (;;) { 51 | duk_small_int_t t = (duk_small_int_t) *p++; 52 | if (t < 0) { 53 | /* may happen if size is very close to 2^32-1 */ 54 | break; 55 | } 56 | 57 | /* prediction: portable variant using doubles if 64-bit values not available */ 58 | #ifdef DUK_USE_64BIT_OPS 59 | curr = (duk_uint32_t) ((((duk_uint64_t) curr) * ((duk_uint64_t) DUK__HASH_SIZE_RATIO)) >> 10); 60 | #else 61 | /* 32-bit x 11-bit = 43-bit, fits accurately into a double */ 62 | curr = (duk_uint32_t) DUK_FLOOR(((double) curr) * ((double) DUK__HASH_SIZE_RATIO) / 1024.0); 63 | #endif 64 | 65 | /* correction */ 66 | curr += t; 67 | 68 | DUK_DDD(DUK_DDDPRINT("size=%ld, curr=%ld", (long) size, (long) curr)); 69 | 70 | if (curr >= size) { 71 | return curr; 72 | } 73 | } 74 | return 0; 75 | } 76 | 77 | #endif /* DUK_USE_HOBJECT_HASH_PART || DUK_USE_STRTAB_PROBE */ 78 | -------------------------------------------------------------------------------- /duktape-1.4.0/src-separate/duk_util_tinyrandom.c: -------------------------------------------------------------------------------- 1 | /* 2 | * A tiny random number generator. 3 | * 4 | * Currently used for Math.random(). 5 | * 6 | * http://www.woodmann.com/forum/archive/index.php/t-3100.html 7 | */ 8 | 9 | #include "duk_internal.h" 10 | 11 | #define DUK__UPDATE_RND(rnd) do { \ 12 | (rnd) += ((rnd) * (rnd)) | 0x05; \ 13 | (rnd) = ((rnd) & 0xffffffffU); /* if duk_uint32_t is exactly 32 bits, this is a NOP */ \ 14 | } while (0) 15 | 16 | #define DUK__RND_BIT(rnd) ((rnd) >> 31) /* only use the highest bit */ 17 | 18 | DUK_INTERNAL duk_uint32_t duk_util_tinyrandom_get_bits(duk_hthread *thr, duk_small_int_t n) { 19 | duk_small_int_t i; 20 | duk_uint32_t res = 0; 21 | duk_uint32_t rnd; 22 | 23 | rnd = thr->heap->rnd_state; 24 | 25 | for (i = 0; i < n; i++) { 26 | DUK__UPDATE_RND(rnd); 27 | res <<= 1; 28 | res += DUK__RND_BIT(rnd); 29 | } 30 | 31 | thr->heap->rnd_state = rnd; 32 | 33 | return res; 34 | } 35 | 36 | DUK_INTERNAL duk_double_t duk_util_tinyrandom_get_double(duk_hthread *thr) { 37 | duk_double_t t; 38 | duk_small_int_t n; 39 | duk_uint32_t rnd; 40 | 41 | /* 42 | * XXX: could make this a lot faster if we create the double memory 43 | * representation directly. Feasible easily (must be uniform random). 44 | */ 45 | 46 | rnd = thr->heap->rnd_state; 47 | 48 | n = 53; /* enough to cover the whole mantissa */ 49 | t = 0.0; 50 | 51 | do { 52 | DUK__UPDATE_RND(rnd); 53 | t += DUK__RND_BIT(rnd); 54 | t /= 2.0; 55 | } while (--n); 56 | 57 | thr->heap->rnd_state = rnd; 58 | 59 | DUK_ASSERT(t >= (duk_double_t) 0.0); 60 | DUK_ASSERT(t < (duk_double_t) 1.0); 61 | 62 | return t; 63 | } 64 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | if (process.env.FORCE_MOCK_SECUREWORKER) { 2 | console.warn("Mock SGX secure worker forced. Do not use in production."); 3 | module.exports = require('./mock'); 4 | } 5 | else { 6 | try { 7 | module.exports = require('./real'); 8 | } 9 | catch (error) { 10 | if (error.stack) { 11 | console.warn("Could not load SGX secure worker binary:"); 12 | console.warn(error.stack); 13 | } 14 | else { 15 | console.warn("Could not load SGX secure worker binary: " + error); 16 | } 17 | console.warn("Mock implementation will be used instead. Do not use in production."); 18 | module.exports = require('./mock'); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lib/message-port.js: -------------------------------------------------------------------------------- 1 | var events = require('events'); 2 | var util = require('util'); 3 | 4 | var MessagePort = function MessagePort() { 5 | var self = this; 6 | 7 | events.EventEmitter.call(self); 8 | 9 | // Increase max listeners. 10 | self.setMaxListeners(100); 11 | 12 | self._started = false; 13 | self._queuedBeforeStarting = []; 14 | }; 15 | 16 | util.inherits(MessagePort, events.EventEmitter); 17 | 18 | MessagePort.prototype.start = function start() { 19 | var self = this; 20 | 21 | if (self._started) return; 22 | self._started = true; 23 | 24 | var eventArguments; 25 | while (eventArguments = self._queuedBeforeStarting.shift()) { 26 | // Because _started is true, this will now emit events properly. 27 | self.emit.apply(self, eventArguments); 28 | } 29 | }; 30 | 31 | MessagePort.prototype.emit = function emit(/* args */) { 32 | var self = this; 33 | 34 | if (!self._started) { 35 | self._queuedBeforeStarting.push(arguments); 36 | return; 37 | } 38 | 39 | // Calling super. 40 | return events.EventEmitter.prototype.emit.apply(self, arguments); 41 | }; 42 | 43 | module.exports = MessagePort; 44 | -------------------------------------------------------------------------------- /node-secureworker-internal/node-secureworker-internal.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {739DB09A-CC57-A953-A6CF-F64FA08E4FA7} 6 | 7 | 8 | {739DB09A-CC57-A953-A6CF-F64FA08E4FA7} 9 | 10 | 11 | {e20936af-5355-4520-a51d-9f0ecabfc14a} 12 | 13 | 14 | {fcd1b4c9-6640-45cb-b136-6eb26af9b4a1} 15 | 16 | 17 | 18 | 19 | .. 20 | 21 | 22 | .. 23 | 24 | 25 | Generated Files 26 | 27 | 28 | 29 | 30 | Generated Files 31 | 32 | 33 | 34 | 35 | Source Files 36 | 37 | 38 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "secureworker", 3 | "version": "0.3.0", 4 | "description": "Run JavaScript inside an Intel SGX enclave", 5 | "main": "./lib/index.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "git+https://github.com/evervault/node-secureworker.git" 9 | }, 10 | "keywords": [ 11 | "sgx", 12 | "enclave", 13 | "worker", 14 | "evervault" 15 | ], 16 | "bin": { 17 | "secureworker-create": "bin/secureworker-create" 18 | }, 19 | "scripts": { 20 | "build": "make node", 21 | "install": "make node || true", 22 | "test": "tests/run.js" 23 | }, 24 | "dependencies": { 25 | "node-webcrypto-ossl": "^1.0.20", 26 | "promise-polyfill": "^6.0.2", 27 | "node-uuid": "^1.4.7", 28 | "int64-buffer": "^0.1.9", 29 | "nan": "^2.5.1", 30 | "browserify": "^14.1.0", 31 | "yargs": "^17.7.2", 32 | "underscore": "^1.8.3" 33 | }, 34 | "engines": { 35 | "node": "13.1.0" 36 | }, 37 | "license": "BSD-3-Clause", 38 | "bugs": { 39 | "url": "https://github.com/evervault/node-secureworker/issues" 40 | }, 41 | "homepage": "https://github.com/evervault/node-secureworker" 42 | } 43 | -------------------------------------------------------------------------------- /scripts/generate-scripts-data.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | if [ "$#" -eq 0 ]; then 4 | echo "No scripts provided." 5 | exit 1 6 | fi 7 | 8 | cat < 2 | 3 | typedef struct duk_enclave_script { 4 | const char *key; 5 | const char *start; 6 | const char *end; 7 | } duk_enclave_script_t; 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | extern const size_t SCRIPTS_LENGTH; 13 | extern const duk_enclave_script_t SCRIPTS[]; 14 | extern const duk_enclave_script_t *AUTOEXEC_SCRIPT; 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | -------------------------------------------------------------------------------- /scripts/scripts.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | 23 | 24 | Resource Files 25 | 26 | 27 | Resource Files 28 | 29 | 30 | Resource Files 31 | 32 | 33 | 34 | 35 | Source Files 36 | 37 | 38 | -------------------------------------------------------------------------------- /secureworker-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evervault/node-secureworker/5b7a4579bc056c0f8bb2a9987512579cc76d7517/secureworker-logo.png -------------------------------------------------------------------------------- /tests/test-commands.js: -------------------------------------------------------------------------------- 1 | // Duktape's Buffer does not support toString. 2 | // See: https://github.com/svaarala/duktape/issues/1397 3 | function toBase64(data) { 4 | if (typeof Duktape !== 'undefined') { 5 | return Duktape.enc('base64', new Buffer(data)); 6 | } 7 | else { 8 | return Buffer.from(data).toString('base64'); 9 | } 10 | } 11 | 12 | function fromBase64(string) { 13 | if (typeof Duktape !== 'undefined') { 14 | return new Uint8Array(Duktape.dec('base64', string)).buffer; 15 | } 16 | else { 17 | return new Uint8Array(Buffer.from(string, 'base64').values()).buffer; 18 | } 19 | } 20 | 21 | SecureWorker.onMessage(function (message) { 22 | if (message.command !== 'time') return; 23 | 24 | var time = SecureWorker.getTrustedTime(); 25 | 26 | SecureWorker.postMessage({ 27 | command: 'time', 28 | currentTime: toBase64(time.currentTime), 29 | timeSourceNonce: toBase64(time.timeSourceNonce) 30 | }) 31 | }); 32 | 33 | SecureWorker.onMessage(function (message) { 34 | if (message.command !== 'report') return; 35 | 36 | SecureWorker.postMessage({ 37 | command: 'report', 38 | report: toBase64(SecureWorker.getReport(message.reportData ? fromBase64(message.reportData) : null)) 39 | }) 40 | }); 41 | -------------------------------------------------------------------------------- /tests/test.js: -------------------------------------------------------------------------------- 1 | var report = function (name) { 2 | return function (reason) { 3 | console.log(name + ' failed:', reason.stack || reason); 4 | SecureWorker.postMessage({success: false, name: name}); 5 | } 6 | }; 7 | 8 | var passed = function (name) { 9 | return function () { 10 | SecureWorker.postMessage({success: true, name: name}); 11 | }; 12 | }; 13 | 14 | var assertEqual = function (name, value1, value2) { 15 | if (value1 !== value2) { 16 | throw new Error(name + " not equal"); 17 | } 18 | }; 19 | 20 | var assertArraysEqual = function (name, array1, array2) { 21 | if (array1.length !== array2.length) { 22 | throw new Error(name + " not equal"); 23 | } 24 | 25 | for (var i = 0; i < array1.length; i++) { 26 | if (array1[i] !== array2[i]) { 27 | throw new Error(name + " not equal"); 28 | } 29 | } 30 | }; 31 | 32 | var algorithm = { 33 | name: "ECDH", 34 | namedCurve: "P-256" 35 | }; 36 | var uses = ["deriveKey", "deriveBits"]; 37 | 38 | SecureWorker.ready.then(function () { 39 | return Promise.all([ 40 | crypto.subtle.generateKey(algorithm, true, uses), 41 | crypto.subtle.generateKey(algorithm, true, uses), 42 | ]); 43 | }).then(function (generatedKeys) { 44 | return Promise.all([ 45 | crypto.subtle.exportKey('pkcs8', generatedKeys[0].privateKey), 46 | crypto.subtle.exportKey('spki', generatedKeys[0].publicKey), 47 | crypto.subtle.exportKey('pkcs8', generatedKeys[1].privateKey), 48 | crypto.subtle.exportKey('spki', generatedKeys[1].publicKey) 49 | ]); 50 | }).then(function (exportedKeys) { 51 | return Promise.all([ 52 | crypto.subtle.importKey('pkcs8', exportedKeys[0], algorithm, false, uses), 53 | crypto.subtle.importKey('spki', exportedKeys[1], algorithm, false, uses), 54 | crypto.subtle.importKey('pkcs8', exportedKeys[2], algorithm, false, uses), 55 | crypto.subtle.importKey('spki', exportedKeys[3], algorithm, false, uses) 56 | ]); 57 | }).then(function (importedKeys) { 58 | return Promise.all([ 59 | crypto.subtle.deriveBits({name: 'ECDH', public: importedKeys[1]}, importedKeys[2], 256), 60 | crypto.subtle.deriveBits({name: 'ECDH', public: importedKeys[3]}, importedKeys[0], 256) 61 | ]); 62 | }).then(function (derivedBits) { 63 | assertArraysEqual("derived bits", derivedBits[0], derivedBits[1]); 64 | 65 | return Promise.all([ 66 | crypto.subtle.digest({name: 'SHA-256'}, derivedBits[0]), 67 | crypto.subtle.digest({name: 'SHA-256'}, derivedBits[1]) 68 | ]); 69 | }).then(function (hashedBits) { 70 | assertArraysEqual("hashed bits", hashedBits[0], hashedBits[1]); 71 | 72 | var keyData1 = new Uint8Array(hashedBits[0], 0, 16); 73 | var keyData2 = new Uint8Array(hashedBits[1], 0, 16); 74 | 75 | assertArraysEqual("generated keys", keyData1, keyData2); 76 | 77 | return crypto.subtle.importKey('raw', keyData1, {name: 'AES-GCM'}, false, ['encrypt', 'decrypt']); 78 | }).then(function (key) { 79 | var iv = crypto.getRandomValues(new Uint8Array(12)); 80 | 81 | var clearText = new Uint8Array(new Buffer("foobar")); 82 | 83 | return crypto.subtle.encrypt({name: 'AES-GCM', iv: iv}, key, clearText).then(function (cipherText) { 84 | return crypto.subtle.decrypt({name: 'AES-GCM', iv: iv}, key, cipherText); 85 | }).then(function (result) { 86 | result = new Uint8Array(result); 87 | 88 | assertArraysEqual("decrypted encrypted clear text", clearText, result); 89 | }); 90 | }).then(passed("crypto")).catch(report("crypto")); 91 | 92 | SecureWorker.ready.then(function () { 93 | var counter = SecureWorker.monotonicCounters.create(); 94 | 95 | try { 96 | var value = counter.value; 97 | 98 | assertEqual("monotonic counter read", SecureWorker.monotonicCounters.read(counter.uuid), value); 99 | 100 | assertEqual("monotonic counter increment", SecureWorker.monotonicCounters.increment(counter.uuid), value + 1); 101 | 102 | assertEqual("monotonic counter read after increment", SecureWorker.monotonicCounters.read(counter.uuid), value + 1); 103 | } 104 | finally { 105 | SecureWorker.monotonicCounters.destroy(counter.uuid); 106 | } 107 | }).then(passed("monotonic counters")).catch(report("monotonic counters")); 108 | 109 | SecureWorker.ready.then(function () { 110 | SecureWorker.importScripts('test-commands.js'); 111 | }).then(passed("import scripts")).catch(report("import scripts")); 112 | 113 | // TODO: write tests for sealData and unsealData 114 | --------------------------------------------------------------------------------