visaljs 0.0.0-stage → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +45 -2
- package/cli.js +8084 -0
- package/node/include/js_node.h +46 -0
- package/node/prelude/async_hooks.js +88 -0
- package/node/prelude/buffer.js +31 -0
- package/node/prelude/crypto.js +114 -0
- package/node/prelude/events.js +227 -0
- package/node/prelude/fs.js +79 -0
- package/node/prelude/http.js +536 -0
- package/node/prelude/http2.js +30 -0
- package/node/prelude/internal/crypto/asym.js +333 -0
- package/node/prelude/internal/crypto/cipher.js +205 -0
- package/node/prelude/internal/crypto/hash.js +137 -0
- package/node/prelude/internal/crypto/kdf.js +182 -0
- package/node/prelude/internal/crypto/keys.js +603 -0
- package/node/prelude/internal/crypto/random.js +118 -0
- package/node/prelude/internal/crypto/util.js +76 -0
- package/node/prelude/internal/errors.js +88 -0
- package/node/prelude/internal/querystring.js +105 -0
- package/node/prelude/module.js +53 -0
- package/node/prelude/net.js +51 -0
- package/node/prelude/os.js +129 -0
- package/node/prelude/path.js +257 -0
- package/node/prelude/process.js +21 -0
- package/node/prelude/querystring.js +469 -0
- package/node/prelude/stream.js +1327 -0
- package/node/prelude/stream_promises.js +7 -0
- package/node/prelude/stream_web.js +6 -0
- package/node/prelude/string_decoder.js +236 -0
- package/node/prelude/tty.js +18 -0
- package/node/prelude/url.js +1156 -0
- package/node/prelude/util.js +64 -0
- package/node/prelude/zlib.js +81 -0
- package/node/src/host_fs.c +126 -0
- package/node/src/host_http.c +486 -0
- package/node/src/host_os.c +505 -0
- package/node/src/host_sys.c +78 -0
- package/node/third_party/libuv/LICENSE +19 -0
- package/node/third_party/libuv/include/uv/aix.h +32 -0
- package/node/third_party/libuv/include/uv/bsd.h +34 -0
- package/node/third_party/libuv/include/uv/darwin.h +61 -0
- package/node/third_party/libuv/include/uv/errno.h +483 -0
- package/node/third_party/libuv/include/uv/linux.h +34 -0
- package/node/third_party/libuv/include/uv/os390.h +33 -0
- package/node/third_party/libuv/include/uv/posix.h +31 -0
- package/node/third_party/libuv/include/uv/sunos.h +44 -0
- package/node/third_party/libuv/include/uv/threadpool.h +37 -0
- package/node/third_party/libuv/include/uv/tree.h +521 -0
- package/node/third_party/libuv/include/uv/unix.h +512 -0
- package/node/third_party/libuv/include/uv/version.h +43 -0
- package/node/third_party/libuv/include/uv/win.h +698 -0
- package/node/third_party/libuv/include/uv.h +1990 -0
- package/node/third_party/libuv/src/fs-poll.c +290 -0
- package/node/third_party/libuv/src/heap-inl.h +245 -0
- package/node/third_party/libuv/src/idna.c +560 -0
- package/node/third_party/libuv/src/idna.h +31 -0
- package/node/third_party/libuv/src/inet.c +298 -0
- package/node/third_party/libuv/src/queue.h +90 -0
- package/node/third_party/libuv/src/random.c +123 -0
- package/node/third_party/libuv/src/strscpy.c +38 -0
- package/node/third_party/libuv/src/strscpy.h +39 -0
- package/node/third_party/libuv/src/strtok.c +52 -0
- package/node/third_party/libuv/src/strtok.h +27 -0
- package/node/third_party/libuv/src/thread-common.c +175 -0
- package/node/third_party/libuv/src/threadpool.c +419 -0
- package/node/third_party/libuv/src/timer.c +200 -0
- package/node/third_party/libuv/src/unix/async.c +418 -0
- package/node/third_party/libuv/src/unix/bsd-ifaddrs.c +164 -0
- package/node/third_party/libuv/src/unix/core.c +2104 -0
- package/node/third_party/libuv/src/unix/darwin-proctitle.c +176 -0
- package/node/third_party/libuv/src/unix/darwin-stub.h +97 -0
- package/node/third_party/libuv/src/unix/darwin-syscalls.h +17 -0
- package/node/third_party/libuv/src/unix/darwin.c +237 -0
- package/node/third_party/libuv/src/unix/dl.c +80 -0
- package/node/third_party/libuv/src/unix/fs.c +2303 -0
- package/node/third_party/libuv/src/unix/fsevents.c +906 -0
- package/node/third_party/libuv/src/unix/getaddrinfo.c +252 -0
- package/node/third_party/libuv/src/unix/getnameinfo.c +121 -0
- package/node/third_party/libuv/src/unix/internal.h +530 -0
- package/node/third_party/libuv/src/unix/kqueue.c +667 -0
- package/node/third_party/libuv/src/unix/linux.c +2761 -0
- package/node/third_party/libuv/src/unix/loop-watcher.c +68 -0
- package/node/third_party/libuv/src/unix/loop.c +240 -0
- package/node/third_party/libuv/src/unix/pipe.c +555 -0
- package/node/third_party/libuv/src/unix/poll.c +159 -0
- package/node/third_party/libuv/src/unix/process.c +1123 -0
- package/node/third_party/libuv/src/unix/procfs-exepath.c +45 -0
- package/node/third_party/libuv/src/unix/proctitle.c +157 -0
- package/node/third_party/libuv/src/unix/random-devurandom.c +93 -0
- package/node/third_party/libuv/src/unix/random-getentropy.c +57 -0
- package/node/third_party/libuv/src/unix/random-getrandom.c +86 -0
- package/node/third_party/libuv/src/unix/random-sysctl-linux.c +99 -0
- package/node/third_party/libuv/src/unix/signal.c +581 -0
- package/node/third_party/libuv/src/unix/stream.c +1567 -0
- package/node/third_party/libuv/src/unix/tcp.c +673 -0
- package/node/third_party/libuv/src/unix/thread.c +975 -0
- package/node/third_party/libuv/src/unix/tty.c +510 -0
- package/node/third_party/libuv/src/unix/udp.c +1434 -0
- package/node/third_party/libuv/src/uv-common.c +1051 -0
- package/node/third_party/libuv/src/uv-common.h +474 -0
- package/node/third_party/libuv/src/uv-data-getter-setters.c +119 -0
- package/node/third_party/libuv/src/version.c +45 -0
- package/node/third_party/llhttp/LICENSE +22 -0
- package/node/third_party/llhttp/api.c +509 -0
- package/node/third_party/llhttp/http.c +170 -0
- package/node/third_party/llhttp/llhttp.c +10099 -0
- package/node/third_party/llhttp/llhttp.h +907 -0
- package/package.json +25 -4
- package/runtime/include/js_atoms.gen.h +68 -0
- package/runtime/include/js_atoms.h +54 -0
- package/runtime/include/js_bigint.h +93 -0
- package/runtime/include/js_buffer.h +79 -0
- package/runtime/include/js_builtins.h +168 -0
- package/runtime/include/js_console.h +58 -0
- package/runtime/include/js_convert.h +22 -0
- package/runtime/include/js_core.def +188 -0
- package/runtime/include/js_crypto.h +58 -0
- package/runtime/include/js_error.h +37 -0
- package/runtime/include/js_exception.h +65 -0
- package/runtime/include/js_function.h +167 -0
- package/runtime/include/js_gc.h +195 -0
- package/runtime/include/js_generator.h +96 -0
- package/runtime/include/js_host.h +19 -0
- package/runtime/include/js_jobs.h +84 -0
- package/runtime/include/js_module.h +16 -0
- package/runtime/include/js_object.h +384 -0
- package/runtime/include/js_ops.h +111 -0
- package/runtime/include/js_promise.h +45 -0
- package/runtime/include/js_regexp.h +25 -0
- package/runtime/include/js_runtime.h +30 -0
- package/runtime/include/js_symbol.h +62 -0
- package/runtime/include/js_web.h +110 -0
- package/runtime/include/jscell.h +48 -0
- package/runtime/include/jscontext.h +240 -0
- package/runtime/include/jsnum.h +42 -0
- package/runtime/include/jsstring.h +161 -0
- package/runtime/include/jsvalue.h +142 -0
- package/runtime/src/arguments.c +115 -0
- package/runtime/src/array.c +1145 -0
- package/runtime/src/arraybuffer.c +608 -0
- package/runtime/src/async_iter.c +479 -0
- package/runtime/src/atoms.c +157 -0
- package/runtime/src/base64.c +107 -0
- package/runtime/src/bigint.c +1189 -0
- package/runtime/src/blob.c +371 -0
- package/runtime/src/buffer.c +1357 -0
- package/runtime/src/builtin_table.c +100 -0
- package/runtime/src/builtins.c +987 -0
- package/runtime/src/builtins_util.h +53 -0
- package/runtime/src/collections.c +912 -0
- package/runtime/src/components.c +28 -0
- package/runtime/src/console.c +637 -0
- package/runtime/src/convert.c +82 -0
- package/runtime/src/core_all.c +21 -0
- package/runtime/src/crypto.c +116 -0
- package/runtime/src/crypto_asym.c +644 -0
- package/runtime/src/crypto_cipher.c +671 -0
- package/runtime/src/crypto_hash.c +260 -0
- package/runtime/src/crypto_host.c +414 -0
- package/runtime/src/crypto_internal.h +304 -0
- package/runtime/src/crypto_kdf.c +143 -0
- package/runtime/src/crypto_key.c +171 -0
- package/runtime/src/crypto_pkey.c +794 -0
- package/runtime/src/crypto_subtle.c +1675 -0
- package/runtime/src/date.c +940 -0
- package/runtime/src/domexception.c +169 -0
- package/runtime/src/elements.c +312 -0
- package/runtime/src/elements.h +45 -0
- package/runtime/src/encoding.c +485 -0
- package/runtime/src/error.c +297 -0
- package/runtime/src/events.c +793 -0
- package/runtime/src/exception.c +56 -0
- package/runtime/src/fetch.c +772 -0
- package/runtime/src/function.c +530 -0
- package/runtime/src/gc.c +803 -0
- package/runtime/src/generator.c +218 -0
- package/runtime/src/global.c +119 -0
- package/runtime/src/headers.c +557 -0
- package/runtime/src/inspect.c +1792 -0
- package/runtime/src/internal.h +80 -0
- package/runtime/src/iterate.c +94 -0
- package/runtime/src/iterator.c +409 -0
- package/runtime/src/jobs.c +337 -0
- package/runtime/src/jsnum.c +353 -0
- package/runtime/src/json.c +1028 -0
- package/runtime/src/math.c +243 -0
- package/runtime/src/module.c +336 -0
- package/runtime/src/number.c +176 -0
- package/runtime/src/object.c +1265 -0
- package/runtime/src/ops.c +322 -0
- package/runtime/src/os.c +196 -0
- package/runtime/src/os.h +29 -0
- package/runtime/src/process.c +432 -0
- package/runtime/src/promise.c +721 -0
- package/runtime/src/proxy.c +570 -0
- package/runtime/src/reflect.c +194 -0
- package/runtime/src/regexp.c +1141 -0
- package/runtime/src/regexp_anchor.h +34 -0
- package/runtime/src/regexp_message.h +32 -0
- package/runtime/src/shape.c +294 -0
- package/runtime/src/shape.h +46 -0
- package/runtime/src/streams.c +1046 -0
- package/runtime/src/streams.h +47 -0
- package/runtime/src/string.c +364 -0
- package/runtime/src/string_builtins.c +837 -0
- package/runtime/src/symbol.c +143 -0
- package/runtime/src/test_host.c +59 -0
- package/runtime/src/typedarray.c +1330 -0
- package/runtime/src/tznames.gen.h +712 -0
- package/runtime/src/uri.c +169 -0
- package/runtime/src/url.c +2116 -0
- package/runtime/src/weak.c +486 -0
- package/runtime/src/web.c +214 -0
- package/runtime/src/wrapper.c +59 -0
- package/runtime/src/writable.c +1486 -0
- package/runtime/third_party/ada-idna/LICENSE-MIT +18 -0
- package/runtime/third_party/ada-idna/README.md +27 -0
- package/runtime/third_party/ada-idna/convert.mjs +83 -0
- package/runtime/third_party/ada-idna/idna.c +416 -0
- package/runtime/third_party/ada-idna/idna.h +15 -0
- package/runtime/third_party/ada-idna/idna_tables.h +2657 -0
- package/runtime/third_party/bearssl/LICENSE.txt +21 -0
- package/runtime/third_party/bearssl/README.txt +136 -0
- package/runtime/third_party/bearssl/VERSION +1 -0
- package/runtime/third_party/bearssl/inc/bearssl.h +183 -0
- package/runtime/third_party/bearssl/inc/bearssl_aead.h +1059 -0
- package/runtime/third_party/bearssl/inc/bearssl_block.h +2618 -0
- package/runtime/third_party/bearssl/inc/bearssl_ec.h +967 -0
- package/runtime/third_party/bearssl/inc/bearssl_hash.h +1346 -0
- package/runtime/third_party/bearssl/inc/bearssl_hmac.h +241 -0
- package/runtime/third_party/bearssl/inc/bearssl_kdf.h +284 -0
- package/runtime/third_party/bearssl/inc/bearssl_pem.h +294 -0
- package/runtime/third_party/bearssl/inc/bearssl_prf.h +150 -0
- package/runtime/third_party/bearssl/inc/bearssl_rand.h +397 -0
- package/runtime/third_party/bearssl/inc/bearssl_rsa.h +1655 -0
- package/runtime/third_party/bearssl/inc/bearssl_ssl.h +4296 -0
- package/runtime/third_party/bearssl/inc/bearssl_x509.h +1474 -0
- package/runtime/third_party/bearssl/src/aead/ccm.c +346 -0
- package/runtime/third_party/bearssl/src/aead/eax.c +525 -0
- package/runtime/third_party/bearssl/src/aead/gcm.c +318 -0
- package/runtime/third_party/bearssl/src/codec/ccopy.c +44 -0
- package/runtime/third_party/bearssl/src/codec/dec16be.c +38 -0
- package/runtime/third_party/bearssl/src/codec/dec16le.c +38 -0
- package/runtime/third_party/bearssl/src/codec/dec32be.c +38 -0
- package/runtime/third_party/bearssl/src/codec/dec32le.c +38 -0
- package/runtime/third_party/bearssl/src/codec/dec64be.c +38 -0
- package/runtime/third_party/bearssl/src/codec/dec64le.c +38 -0
- package/runtime/third_party/bearssl/src/codec/enc16be.c +38 -0
- package/runtime/third_party/bearssl/src/codec/enc16le.c +38 -0
- package/runtime/third_party/bearssl/src/codec/enc32be.c +38 -0
- package/runtime/third_party/bearssl/src/codec/enc32le.c +38 -0
- package/runtime/third_party/bearssl/src/codec/enc64be.c +38 -0
- package/runtime/third_party/bearssl/src/codec/enc64le.c +38 -0
- package/runtime/third_party/bearssl/src/codec/pemdec.c +526 -0
- package/runtime/third_party/bearssl/src/codec/pemdec.t0 +314 -0
- package/runtime/third_party/bearssl/src/codec/pemenc.c +173 -0
- package/runtime/third_party/bearssl/src/config.h +247 -0
- package/runtime/third_party/bearssl/src/ec/ec_all_m15.c +121 -0
- package/runtime/third_party/bearssl/src/ec/ec_all_m31.c +171 -0
- package/runtime/third_party/bearssl/src/ec/ec_c25519_i15.c +398 -0
- package/runtime/third_party/bearssl/src/ec/ec_c25519_i31.c +390 -0
- package/runtime/third_party/bearssl/src/ec/ec_c25519_m15.c +1478 -0
- package/runtime/third_party/bearssl/src/ec/ec_c25519_m31.c +800 -0
- package/runtime/third_party/bearssl/src/ec/ec_c25519_m62.c +605 -0
- package/runtime/third_party/bearssl/src/ec/ec_c25519_m64.c +831 -0
- package/runtime/third_party/bearssl/src/ec/ec_curve25519.c +46 -0
- package/runtime/third_party/bearssl/src/ec/ec_default.c +36 -0
- package/runtime/third_party/bearssl/src/ec/ec_keygen.c +86 -0
- package/runtime/third_party/bearssl/src/ec/ec_p256_m15.c +2124 -0
- package/runtime/third_party/bearssl/src/ec/ec_p256_m31.c +1469 -0
- package/runtime/third_party/bearssl/src/ec/ec_p256_m62.c +1765 -0
- package/runtime/third_party/bearssl/src/ec/ec_p256_m64.c +1781 -0
- package/runtime/third_party/bearssl/src/ec/ec_prime_i15.c +824 -0
- package/runtime/third_party/bearssl/src/ec/ec_prime_i31.c +826 -0
- package/runtime/third_party/bearssl/src/ec/ec_pubkey.c +85 -0
- package/runtime/third_party/bearssl/src/ec/ec_secp256r1.c +51 -0
- package/runtime/third_party/bearssl/src/ec/ec_secp384r1.c +57 -0
- package/runtime/third_party/bearssl/src/ec/ec_secp521r1.c +64 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_atr.c +134 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_default_sign_asn1.c +36 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_default_sign_raw.c +36 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_default_vrfy_asn1.c +36 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_default_vrfy_raw.c +36 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_i15_bits.c +47 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_i15_sign_asn1.c +45 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_i15_sign_raw.c +174 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_i15_vrfy_asn1.c +48 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_i15_vrfy_raw.c +166 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_i31_bits.c +47 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_i31_sign_asn1.c +45 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_i31_sign_raw.c +173 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_i31_vrfy_asn1.c +48 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_i31_vrfy_raw.c +165 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_rta.c +121 -0
- package/runtime/third_party/bearssl/src/hash/dig_oid.c +84 -0
- package/runtime/third_party/bearssl/src/hash/dig_size.c +50 -0
- package/runtime/third_party/bearssl/src/hash/ghash_ctmul.c +345 -0
- package/runtime/third_party/bearssl/src/hash/ghash_ctmul32.c +251 -0
- package/runtime/third_party/bearssl/src/hash/ghash_ctmul64.c +154 -0
- package/runtime/third_party/bearssl/src/hash/ghash_pclmul.c +389 -0
- package/runtime/third_party/bearssl/src/hash/ghash_pwr8.c +411 -0
- package/runtime/third_party/bearssl/src/hash/md5.c +208 -0
- package/runtime/third_party/bearssl/src/hash/md5sha1.c +141 -0
- package/runtime/third_party/bearssl/src/hash/mgf1.c +56 -0
- package/runtime/third_party/bearssl/src/hash/multihash.c +166 -0
- package/runtime/third_party/bearssl/src/hash/sha1.c +191 -0
- package/runtime/third_party/bearssl/src/hash/sha2big.c +285 -0
- package/runtime/third_party/bearssl/src/hash/sha2small.c +341 -0
- package/runtime/third_party/bearssl/src/inner.h +2577 -0
- package/runtime/third_party/bearssl/src/int/i15_add.c +46 -0
- package/runtime/third_party/bearssl/src/int/i15_bitlen.c +44 -0
- package/runtime/third_party/bearssl/src/int/i15_decmod.c +124 -0
- package/runtime/third_party/bearssl/src/int/i15_decode.c +56 -0
- package/runtime/third_party/bearssl/src/int/i15_decred.c +100 -0
- package/runtime/third_party/bearssl/src/int/i15_encode.c +56 -0
- package/runtime/third_party/bearssl/src/int/i15_fmont.c +59 -0
- package/runtime/third_party/bearssl/src/int/i15_iszero.c +39 -0
- package/runtime/third_party/bearssl/src/int/i15_moddiv.c +465 -0
- package/runtime/third_party/bearssl/src/int/i15_modpow.c +50 -0
- package/runtime/third_party/bearssl/src/int/i15_modpow2.c +160 -0
- package/runtime/third_party/bearssl/src/int/i15_montmul.c +184 -0
- package/runtime/third_party/bearssl/src/int/i15_mulacc.c +61 -0
- package/runtime/third_party/bearssl/src/int/i15_muladd.c +173 -0
- package/runtime/third_party/bearssl/src/int/i15_ninv15.c +38 -0
- package/runtime/third_party/bearssl/src/int/i15_reduce.c +66 -0
- package/runtime/third_party/bearssl/src/int/i15_rshift.c +47 -0
- package/runtime/third_party/bearssl/src/int/i15_sub.c +46 -0
- package/runtime/third_party/bearssl/src/int/i15_tmont.c +36 -0
- package/runtime/third_party/bearssl/src/int/i31_add.c +46 -0
- package/runtime/third_party/bearssl/src/int/i31_bitlen.c +44 -0
- package/runtime/third_party/bearssl/src/int/i31_decmod.c +124 -0
- package/runtime/third_party/bearssl/src/int/i31_decode.c +57 -0
- package/runtime/third_party/bearssl/src/int/i31_decred.c +103 -0
- package/runtime/third_party/bearssl/src/int/i31_encode.c +79 -0
- package/runtime/third_party/bearssl/src/int/i31_fmont.c +60 -0
- package/runtime/third_party/bearssl/src/int/i31_iszero.c +39 -0
- package/runtime/third_party/bearssl/src/int/i31_moddiv.c +488 -0
- package/runtime/third_party/bearssl/src/int/i31_modpow.c +65 -0
- package/runtime/third_party/bearssl/src/int/i31_modpow2.c +160 -0
- package/runtime/third_party/bearssl/src/int/i31_montmul.c +127 -0
- package/runtime/third_party/bearssl/src/int/i31_mulacc.c +74 -0
- package/runtime/third_party/bearssl/src/int/i31_muladd.c +157 -0
- package/runtime/third_party/bearssl/src/int/i31_ninv31.c +39 -0
- package/runtime/third_party/bearssl/src/int/i31_reduce.c +66 -0
- package/runtime/third_party/bearssl/src/int/i31_rshift.c +47 -0
- package/runtime/third_party/bearssl/src/int/i31_sub.c +46 -0
- package/runtime/third_party/bearssl/src/int/i31_tmont.c +36 -0
- package/runtime/third_party/bearssl/src/int/i32_add.c +51 -0
- package/runtime/third_party/bearssl/src/int/i32_bitlen.c +44 -0
- package/runtime/third_party/bearssl/src/int/i32_decmod.c +77 -0
- package/runtime/third_party/bearssl/src/int/i32_decode.c +63 -0
- package/runtime/third_party/bearssl/src/int/i32_decred.c +107 -0
- package/runtime/third_party/bearssl/src/int/i32_div32.c +56 -0
- package/runtime/third_party/bearssl/src/int/i32_encode.c +72 -0
- package/runtime/third_party/bearssl/src/int/i32_fmont.c +60 -0
- package/runtime/third_party/bearssl/src/int/i32_iszero.c +39 -0
- package/runtime/third_party/bearssl/src/int/i32_modpow.c +65 -0
- package/runtime/third_party/bearssl/src/int/i32_montmul.c +69 -0
- package/runtime/third_party/bearssl/src/int/i32_mulacc.c +56 -0
- package/runtime/third_party/bearssl/src/int/i32_muladd.c +138 -0
- package/runtime/third_party/bearssl/src/int/i32_ninv32.c +39 -0
- package/runtime/third_party/bearssl/src/int/i32_reduce.c +66 -0
- package/runtime/third_party/bearssl/src/int/i32_sub.c +51 -0
- package/runtime/third_party/bearssl/src/int/i32_tmont.c +36 -0
- package/runtime/third_party/bearssl/src/int/i62_modpow2.c +493 -0
- package/runtime/third_party/bearssl/src/kdf/hkdf.c +107 -0
- package/runtime/third_party/bearssl/src/kdf/shake.c +590 -0
- package/runtime/third_party/bearssl/src/mac/hmac.c +122 -0
- package/runtime/third_party/bearssl/src/mac/hmac_ct.c +193 -0
- package/runtime/third_party/bearssl/src/rand/aesctr_drbg.c +206 -0
- package/runtime/third_party/bearssl/src/rand/hmac_drbg.c +157 -0
- package/runtime/third_party/bearssl/src/rand/sysrng.c +252 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_default_keygen.c +38 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_default_modulus.c +36 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_default_oaep_decrypt.c +38 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_default_oaep_encrypt.c +38 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_default_pkcs1_sign.c +38 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_default_pkcs1_vrfy.c +38 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_default_priv.c +38 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_default_privexp.c +36 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_default_pss_sign.c +38 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_default_pss_vrfy.c +38 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_default_pub.c +38 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_default_pubexp.c +36 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i15_keygen.c +583 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i15_modulus.c +99 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i15_oaep_decrypt.c +41 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i15_oaep_encrypt.c +44 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i15_pkcs1_sign.c +37 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i15_pkcs1_vrfy.c +43 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i15_priv.c +209 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i15_privexp.c +320 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i15_pss_sign.c +40 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i15_pss_vrfy.c +44 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i15_pub.c +113 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i15_pubexp.c +152 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_keygen.c +37 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_keygen_inner.c +608 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_modulus.c +99 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_oaep_decrypt.c +41 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_oaep_encrypt.c +44 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_pkcs1_sign.c +37 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_pkcs1_vrfy.c +43 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_priv.c +203 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_privexp.c +318 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_pss_sign.c +40 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_pss_vrfy.c +44 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_pub.c +106 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_pubexp.c +152 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i32_oaep_decrypt.c +41 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i32_oaep_encrypt.c +44 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i32_pkcs1_sign.c +37 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i32_pkcs1_vrfy.c +43 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i32_priv.c +160 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i32_pss_sign.c +40 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i32_pss_vrfy.c +44 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i32_pub.c +77 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i62_keygen.c +57 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i62_oaep_decrypt.c +61 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i62_oaep_encrypt.c +64 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i62_pkcs1_sign.c +57 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i62_pkcs1_vrfy.c +63 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i62_priv.c +223 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i62_pss_sign.c +60 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i62_pss_vrfy.c +64 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i62_pub.c +125 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_oaep_pad.c +112 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_oaep_unpad.c +145 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_pkcs1_sig_pad.c +100 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_pkcs1_sig_unpad.c +121 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_pss_sig_pad.c +106 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_pss_sig_unpad.c +121 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_ssl_decrypt.c +52 -0
- package/runtime/third_party/bearssl/src/settings.c +306 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_big_cbcdec.c +69 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_big_cbcenc.c +67 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_big_ctr.c +84 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_big_ctrcbc.c +142 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_big_dec.c +254 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_big_enc.c +157 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_common.c +112 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct.c +328 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct64.c +398 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct64_cbcdec.c +104 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct64_cbcenc.c +81 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct64_ctr.c +114 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct64_ctrcbc.c +433 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct64_dec.c +159 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct64_enc.c +115 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct_cbcdec.c +111 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct_cbcenc.c +91 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct_ctr.c +116 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct_ctrcbc.c +422 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct_dec.c +170 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct_enc.c +112 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_pwr8.c +445 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_pwr8_cbcdec.c +670 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_pwr8_cbcenc.c +417 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_pwr8_ctr.c +717 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_pwr8_ctrcbc.c +946 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_small_cbcdec.c +69 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_small_cbcenc.c +67 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_small_ctr.c +84 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_small_ctrcbc.c +142 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_small_dec.c +176 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_small_enc.c +129 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_x86ni.c +240 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_x86ni_cbcdec.c +223 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_x86ni_cbcenc.c +122 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_x86ni_ctr.c +211 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_x86ni_ctrcbc.c +596 -0
- package/runtime/third_party/bearssl/src/symcipher/chacha20_ct.c +106 -0
- package/runtime/third_party/bearssl/src/symcipher/chacha20_sse2.c +237 -0
- package/runtime/third_party/bearssl/src/symcipher/des_ct.c +411 -0
- package/runtime/third_party/bearssl/src/symcipher/des_ct_cbcdec.c +87 -0
- package/runtime/third_party/bearssl/src/symcipher/des_ct_cbcenc.c +69 -0
- package/runtime/third_party/bearssl/src/symcipher/des_support.c +166 -0
- package/runtime/third_party/bearssl/src/symcipher/des_tab.c +310 -0
- package/runtime/third_party/bearssl/src/symcipher/des_tab_cbcdec.c +85 -0
- package/runtime/third_party/bearssl/src/symcipher/des_tab_cbcenc.c +67 -0
- package/runtime/third_party/bearssl/src/symcipher/poly1305_ctmul.c +260 -0
- package/runtime/third_party/bearssl/src/symcipher/poly1305_ctmul32.c +297 -0
- package/runtime/third_party/bearssl/src/symcipher/poly1305_ctmulq.c +475 -0
- package/runtime/third_party/bearssl/src/symcipher/poly1305_i15.c +221 -0
- package/runtime/third_party/bearssl/src/x509/asn1.t0 +757 -0
- package/runtime/third_party/bearssl/src/x509/asn1enc.c +93 -0
- package/runtime/third_party/bearssl/src/x509/encode_ec_pk8der.c +110 -0
- package/runtime/third_party/bearssl/src/x509/encode_ec_rawder.c +161 -0
- package/runtime/third_party/bearssl/src/x509/encode_rsa_pk8der.c +97 -0
- package/runtime/third_party/bearssl/src/x509/encode_rsa_rawder.c +96 -0
- package/runtime/third_party/bearssl/src/x509/skey_decoder.c +653 -0
- package/runtime/third_party/bearssl/src/x509/skey_decoder.t0 +376 -0
- package/runtime/third_party/bearssl/src/x509/x509_decoder.c +776 -0
- package/runtime/third_party/bearssl/src/x509/x509_decoder.t0 +324 -0
- package/runtime/third_party/bearssl/src/x509/x509_knownkey.c +105 -0
- package/runtime/third_party/bearssl/src/x509/x509_minimal.c +1722 -0
- package/runtime/third_party/bearssl/src/x509/x509_minimal.t0 +1526 -0
- package/runtime/third_party/bearssl/src/x509/x509_minimal_full.c +59 -0
- package/runtime/third_party/quickjs-dtoa/LICENSE +22 -0
- package/runtime/third_party/quickjs-dtoa/README.md +23 -0
- package/runtime/third_party/quickjs-dtoa/dtoa.c +1640 -0
- package/runtime/third_party/quickjs-dtoa/dtoa.h +83 -0
- package/runtime/third_party/quickjs-dtoa/dtoa_compat.h +89 -0
- package/runtime/third_party/quickjs-regexp/LICENSE +22 -0
- package/runtime/third_party/quickjs-regexp/README.md +22 -0
- package/runtime/third_party/quickjs-regexp/cutils.c +641 -0
- package/runtime/third_party/quickjs-regexp/cutils.h +457 -0
- package/runtime/third_party/quickjs-regexp/libregexp-opcode.h +73 -0
- package/runtime/third_party/quickjs-regexp/libregexp.c +3448 -0
- package/runtime/third_party/quickjs-regexp/libregexp.h +65 -0
- package/runtime/third_party/quickjs-regexp/libunicode-table.h +5206 -0
- package/runtime/third_party/quickjs-regexp/libunicode.c +2124 -0
- package/runtime/third_party/quickjs-regexp/libunicode.h +196 -0
- package/runtime/third_party/v8-ieee754/LICENSE +61 -0
- package/runtime/third_party/v8-ieee754/README.md +22 -0
- package/runtime/third_party/v8-ieee754/convert.py +84 -0
- package/runtime/third_party/v8-ieee754/ieee754.c +3030 -0
- package/runtime/third_party/v8-ieee754/ieee754.h +27 -0
- package/runtime/tools/regexp_compile.c +90 -0
|
@@ -0,0 +1,1028 @@
|
|
|
1
|
+
/* JSON (§25.5): an optional component (ADR 0014), and the serializer util.format's %j uses.
|
|
2
|
+
*
|
|
3
|
+
* JSON.parse follows V8's parser closely enough to give its error messages: the same checks in
|
|
4
|
+
* the same order, at the same positions ("Unexpected token '}', "[1,}" is not valid JSON",
|
|
5
|
+
* "Expected ',' or ']' after array element in JSON at position 3 (line 1 column 4)"). It is
|
|
6
|
+
* iterative, so nesting depth is bounded by memory, as in V8. With a reviver it keeps a parse
|
|
7
|
+
* node per value, for the reviver's `context` argument (JSON.parse source text access, in
|
|
8
|
+
* Node 22): a primitive's source text, while the value is unchanged.
|
|
9
|
+
*
|
|
10
|
+
* JSON.stringify is the spec's SerializeJSONProperty; a cycle's TypeError describes the
|
|
11
|
+
* cycle as V8 does. JSON.rawJSON / isRawJSON are here too. */
|
|
12
|
+
#include <math.h>
|
|
13
|
+
#include <stdio.h>
|
|
14
|
+
#include <stdlib.h>
|
|
15
|
+
#include <string.h>
|
|
16
|
+
|
|
17
|
+
#include "internal.h"
|
|
18
|
+
#include "builtins_util.h"
|
|
19
|
+
#include "js_atoms.h"
|
|
20
|
+
#include "js_convert.h"
|
|
21
|
+
#include "js_error.h"
|
|
22
|
+
#include "js_symbol.h"
|
|
23
|
+
#include "jsnum.h"
|
|
24
|
+
|
|
25
|
+
/* ---- A growable UTF-16 buffer ------------------------------------------------------------- */
|
|
26
|
+
|
|
27
|
+
typedef struct {
|
|
28
|
+
uint16_t *units;
|
|
29
|
+
size_t length, cap;
|
|
30
|
+
} Builder;
|
|
31
|
+
|
|
32
|
+
static void reserve(Builder *b, size_t more) {
|
|
33
|
+
if (b->length + more <= b->cap) return;
|
|
34
|
+
size_t cap = b->cap ? b->cap * 2 : 64;
|
|
35
|
+
while (cap < b->length + more) cap *= 2;
|
|
36
|
+
uint16_t *u = realloc(b->units, cap * sizeof *u);
|
|
37
|
+
if (!u) js_fatal("out of memory building a string");
|
|
38
|
+
b->units = u;
|
|
39
|
+
b->cap = cap;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static void put_unit(Builder *b, uint32_t u) {
|
|
43
|
+
reserve(b, 1);
|
|
44
|
+
b->units[b->length++] = (uint16_t)u;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
static void put_ascii(Builder *b, const char *s) {
|
|
48
|
+
while (*s) put_unit(b, (uint8_t)*s++);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static void put_view(Builder *b, JSStrView v, uint32_t start, uint32_t end) {
|
|
52
|
+
reserve(b, end - start);
|
|
53
|
+
for (uint32_t i = start; i < end; i++) b->units[b->length++] = (uint16_t)js_view_at(v, i);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
static void put_string(Builder *b, JSContext *ctx, JSValue s) {
|
|
57
|
+
JSStrView v = js_string_view(ctx, s);
|
|
58
|
+
put_view(b, v, 0, v.length);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
static JSValue finish(JSContext *ctx, Builder *b) {
|
|
62
|
+
if (b->length > JS_STRING_MAX_LENGTH) {
|
|
63
|
+
free(b->units);
|
|
64
|
+
return js_throw_range_error(ctx, "Invalid string length");
|
|
65
|
+
}
|
|
66
|
+
JSValue s = js_new_string_utf16(ctx, b->units, (uint32_t)b->length);
|
|
67
|
+
free(b->units);
|
|
68
|
+
return s;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* ---- JSON.parse (§25.5.1) ----------------------------------------------------------------- */
|
|
72
|
+
|
|
73
|
+
typedef enum {
|
|
74
|
+
TOK_STRING, TOK_NUMBER, TOK_LBRACE, TOK_RBRACE, TOK_LBRACK, TOK_RBRACK, TOK_TRUE, TOK_FALSE,
|
|
75
|
+
TOK_NULL, TOK_COLON, TOK_COMMA, TOK_WHITESPACE, TOK_ILLEGAL, TOK_EOS,
|
|
76
|
+
} Token;
|
|
77
|
+
|
|
78
|
+
/* V8's one_char_json_tokens */
|
|
79
|
+
static Token token_of(uint32_t c) {
|
|
80
|
+
switch (c) {
|
|
81
|
+
case '"': return TOK_STRING;
|
|
82
|
+
case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
|
|
83
|
+
return TOK_NUMBER;
|
|
84
|
+
case '{': return TOK_LBRACE;
|
|
85
|
+
case '}': return TOK_RBRACE;
|
|
86
|
+
case '[': return TOK_LBRACK;
|
|
87
|
+
case ']': return TOK_RBRACK;
|
|
88
|
+
case 't': return TOK_TRUE;
|
|
89
|
+
case 'f': return TOK_FALSE;
|
|
90
|
+
case 'n': return TOK_NULL;
|
|
91
|
+
case ':': return TOK_COLON;
|
|
92
|
+
case ',': return TOK_COMMA;
|
|
93
|
+
case ' ': case '\t': case '\n': case '\r': return TOK_WHITESPACE;
|
|
94
|
+
default: return TOK_ILLEGAL;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
typedef struct {
|
|
99
|
+
JSContext *ctx;
|
|
100
|
+
JSValue source; /* the string being parsed (rooted: the parser lives on the C stack) */
|
|
101
|
+
JSStrView s;
|
|
102
|
+
uint32_t pos;
|
|
103
|
+
bool failed;
|
|
104
|
+
} Parser;
|
|
105
|
+
|
|
106
|
+
static bool at_end(Parser *p) { return p->pos >= p->s.length; }
|
|
107
|
+
static uint32_t cur(Parser *p) { return at_end(p) ? 0xFFFFFFFFu : js_view_at(p->s, p->pos); }
|
|
108
|
+
static uint32_t next_char(Parser *p) {
|
|
109
|
+
p->pos++;
|
|
110
|
+
return cur(p);
|
|
111
|
+
}
|
|
112
|
+
static Token peek(Parser *p) { return at_end(p) ? TOK_EOS : token_of(cur(p)); }
|
|
113
|
+
|
|
114
|
+
static void skip_whitespace(Parser *p) {
|
|
115
|
+
while (!at_end(p) && token_of(cur(p)) == TOK_WHITESPACE) p->pos++;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
typedef enum {
|
|
119
|
+
MSG_NONE, MSG_PROP_NAME_OR_RBRACE, MSG_COMMA_OR_RBRACK, MSG_COMMA_OR_RBRACE, MSG_COLON,
|
|
120
|
+
MSG_DOUBLE_QUOTED_NAME, MSG_EXPONENT, MSG_UNTERMINATED_STRING, MSG_CONTROL, MSG_ESCAPE,
|
|
121
|
+
MSG_UNICODE_ESCAPE, MSG_MINUS, MSG_FRACTION, MSG_NON_WHITESPACE, MSG_NUMBER, MSG_STRING,
|
|
122
|
+
} Msg;
|
|
123
|
+
|
|
124
|
+
static const char *msg_text(Msg m) {
|
|
125
|
+
switch (m) {
|
|
126
|
+
case MSG_PROP_NAME_OR_RBRACE: return "Expected property name or '}' in JSON";
|
|
127
|
+
case MSG_COMMA_OR_RBRACK: return "Expected ',' or ']' after array element in JSON";
|
|
128
|
+
case MSG_COMMA_OR_RBRACE: return "Expected ',' or '}' after property value in JSON";
|
|
129
|
+
case MSG_COLON: return "Expected ':' after property name in JSON";
|
|
130
|
+
case MSG_DOUBLE_QUOTED_NAME: return "Expected double-quoted property name in JSON";
|
|
131
|
+
case MSG_EXPONENT: return "Exponent part is missing a number in JSON";
|
|
132
|
+
case MSG_UNTERMINATED_STRING: return "Unterminated string in JSON";
|
|
133
|
+
case MSG_CONTROL: return "Bad control character in string literal in JSON";
|
|
134
|
+
case MSG_ESCAPE: return "Bad escaped character in JSON";
|
|
135
|
+
case MSG_UNICODE_ESCAPE: return "Bad Unicode escape in JSON";
|
|
136
|
+
case MSG_MINUS: return "No number after minus sign in JSON";
|
|
137
|
+
case MSG_FRACTION: return "Unterminated fractional number in JSON";
|
|
138
|
+
case MSG_NON_WHITESPACE: return "Unexpected non-whitespace character after JSON";
|
|
139
|
+
case MSG_NUMBER: return "Unexpected number in JSON";
|
|
140
|
+
case MSG_STRING: return "Unexpected string in JSON";
|
|
141
|
+
case MSG_NONE: break;
|
|
142
|
+
}
|
|
143
|
+
return "";
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
static bool source_is(Parser *p, const char *text) {
|
|
147
|
+
size_t n = strlen(text);
|
|
148
|
+
if (p->s.length != n) return false;
|
|
149
|
+
for (uint32_t i = 0; i < n; i++)
|
|
150
|
+
if (js_view_at(p->s, i) != (uint8_t)text[i]) return false;
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
#define CONTEXT_CHARS 10 /* V8's kMaxContextCharacters */
|
|
155
|
+
|
|
156
|
+
/* ReportUnexpectedToken: the SyntaxError V8 throws for `token` at the current position, with
|
|
157
|
+
* `msg` if given, else the token's own message. */
|
|
158
|
+
static void report(Parser *p, Token token, Msg msg) {
|
|
159
|
+
if (p->failed) return;
|
|
160
|
+
p->failed = true;
|
|
161
|
+
JSContext *ctx = p->ctx;
|
|
162
|
+
uint32_t pos = p->pos;
|
|
163
|
+
Builder b = { 0 };
|
|
164
|
+
if (msg == MSG_NONE) {
|
|
165
|
+
if (token == TOK_EOS) {
|
|
166
|
+
put_ascii(&b, "Unexpected end of JSON input");
|
|
167
|
+
goto throw;
|
|
168
|
+
}
|
|
169
|
+
if (token == TOK_NUMBER) msg = MSG_NUMBER;
|
|
170
|
+
else if (token == TOK_STRING) msg = MSG_STRING;
|
|
171
|
+
}
|
|
172
|
+
if (msg == MSG_NONE) {
|
|
173
|
+
if (source_is(p, "[object Object]") || source_is(p, "undefined") || source_is(p, "Infinity") || source_is(p, "NaN")) {
|
|
174
|
+
put_unit(&b, '"');
|
|
175
|
+
put_view(&b, p->s, 0, p->s.length);
|
|
176
|
+
put_ascii(&b, "\" is not valid JSON");
|
|
177
|
+
goto throw;
|
|
178
|
+
}
|
|
179
|
+
put_ascii(&b, "Unexpected token '");
|
|
180
|
+
put_unit(&b, cur(p));
|
|
181
|
+
put_ascii(&b, "', ");
|
|
182
|
+
uint32_t len = p->s.length;
|
|
183
|
+
if (len < 2 * CONTEXT_CHARS + 1) {
|
|
184
|
+
put_unit(&b, '"');
|
|
185
|
+
put_view(&b, p->s, 0, len);
|
|
186
|
+
put_ascii(&b, "\" is not valid JSON");
|
|
187
|
+
} else if (pos < CONTEXT_CHARS) {
|
|
188
|
+
put_unit(&b, '"');
|
|
189
|
+
put_view(&b, p->s, 0, pos + CONTEXT_CHARS);
|
|
190
|
+
put_ascii(&b, "\"... is not valid JSON");
|
|
191
|
+
} else if (pos < len - CONTEXT_CHARS) {
|
|
192
|
+
put_ascii(&b, "...\"");
|
|
193
|
+
put_view(&b, p->s, pos - CONTEXT_CHARS, pos + CONTEXT_CHARS);
|
|
194
|
+
put_ascii(&b, "\"... is not valid JSON");
|
|
195
|
+
} else {
|
|
196
|
+
put_ascii(&b, "...\"");
|
|
197
|
+
put_view(&b, p->s, pos - CONTEXT_CHARS, len);
|
|
198
|
+
put_ascii(&b, "\" is not valid JSON");
|
|
199
|
+
}
|
|
200
|
+
goto throw;
|
|
201
|
+
}
|
|
202
|
+
/* "… in JSON at position 4 (line 1 column 5)": \r\n is one line break */
|
|
203
|
+
uint32_t line = 1, line_start = 0;
|
|
204
|
+
for (uint32_t i = 0; i < pos && i < p->s.length; i++) {
|
|
205
|
+
uint32_t c = js_view_at(p->s, i);
|
|
206
|
+
if (c == '\r' && i + 1 < pos && js_view_at(p->s, i + 1) == '\n') i++;
|
|
207
|
+
if (c == '\r' || c == '\n') {
|
|
208
|
+
line++;
|
|
209
|
+
line_start = i + 1;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
char where[96];
|
|
213
|
+
snprintf(where, sizeof where, " at position %u (line %u column %u)", pos, line, pos - line_start + 1);
|
|
214
|
+
put_ascii(&b, msg_text(msg));
|
|
215
|
+
put_ascii(&b, where);
|
|
216
|
+
throw:;
|
|
217
|
+
JSValue text = finish(ctx, &b);
|
|
218
|
+
if (js_is_exception(text)) return;
|
|
219
|
+
js_discard(js_throw(ctx, js_new_error(ctx, JS_SYNTAX_ERROR, text)));
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/* ReportUnexpectedCharacter */
|
|
223
|
+
static void report_char(Parser *p, uint32_t c) {
|
|
224
|
+
report(p, c == 0xFFFFFFFFu ? TOK_EOS : token_of(c), MSG_NONE);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/* ScanLiteral: "true", "false", "null" (the first character matched already). */
|
|
228
|
+
static JSValue scan_literal(Parser *p, const char *text, JSValue value) {
|
|
229
|
+
size_t n = strlen(text);
|
|
230
|
+
uint32_t remaining = p->s.length - p->pos;
|
|
231
|
+
uint32_t i = 1;
|
|
232
|
+
for (; i < n && i < remaining; i++) {
|
|
233
|
+
if (js_view_at(p->s, p->pos + i) != (uint8_t)text[i]) {
|
|
234
|
+
p->pos += i;
|
|
235
|
+
report_char(p, cur(p));
|
|
236
|
+
return JS_EXCEPTION;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
p->pos += i;
|
|
240
|
+
if (i < n) {
|
|
241
|
+
report(p, TOK_EOS, MSG_NONE);
|
|
242
|
+
return JS_EXCEPTION;
|
|
243
|
+
}
|
|
244
|
+
return value;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
static bool is_digit(uint32_t c) { return c >= '0' && c <= '9'; }
|
|
248
|
+
|
|
249
|
+
static void skip_digits(Parser *p) {
|
|
250
|
+
while (is_digit(cur(p))) p->pos++;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/* ParseJsonNumber */
|
|
254
|
+
static JSValue scan_number(Parser *p) {
|
|
255
|
+
uint32_t start = p->pos;
|
|
256
|
+
uint32_t c = cur(p);
|
|
257
|
+
if (c == '-') c = next_char(p);
|
|
258
|
+
if (c == '0') {
|
|
259
|
+
c = next_char(p);
|
|
260
|
+
if (is_digit(c)) {
|
|
261
|
+
report(p, TOK_NUMBER, MSG_NONE);
|
|
262
|
+
return JS_EXCEPTION;
|
|
263
|
+
}
|
|
264
|
+
} else {
|
|
265
|
+
if (!is_digit(c)) {
|
|
266
|
+
report(p, TOK_ILLEGAL, MSG_MINUS);
|
|
267
|
+
return JS_EXCEPTION;
|
|
268
|
+
}
|
|
269
|
+
skip_digits(p);
|
|
270
|
+
}
|
|
271
|
+
if (cur(p) == '.') {
|
|
272
|
+
if (!is_digit(next_char(p))) {
|
|
273
|
+
report(p, TOK_ILLEGAL, MSG_FRACTION);
|
|
274
|
+
return JS_EXCEPTION;
|
|
275
|
+
}
|
|
276
|
+
skip_digits(p);
|
|
277
|
+
}
|
|
278
|
+
if (cur(p) == 'e' || cur(p) == 'E') {
|
|
279
|
+
c = next_char(p);
|
|
280
|
+
if (c == '-' || c == '+') c = next_char(p);
|
|
281
|
+
if (!is_digit(c)) {
|
|
282
|
+
report(p, TOK_ILLEGAL, MSG_EXPONENT);
|
|
283
|
+
return JS_EXCEPTION;
|
|
284
|
+
}
|
|
285
|
+
skip_digits(p);
|
|
286
|
+
}
|
|
287
|
+
char buf[64];
|
|
288
|
+
uint32_t n = p->pos - start;
|
|
289
|
+
if (n < sizeof buf) {
|
|
290
|
+
for (uint32_t i = 0; i < n; i++) buf[i] = (char)js_view_at(p->s, start + i);
|
|
291
|
+
buf[n] = '\0';
|
|
292
|
+
return js_number(strtod(buf, NULL));
|
|
293
|
+
}
|
|
294
|
+
char *big = malloc(n + 1);
|
|
295
|
+
if (!big) js_fatal("out of memory parsing JSON");
|
|
296
|
+
for (uint32_t i = 0; i < n; i++) big[i] = (char)js_view_at(p->s, start + i);
|
|
297
|
+
big[n] = '\0';
|
|
298
|
+
double d = strtod(big, NULL);
|
|
299
|
+
free(big);
|
|
300
|
+
return js_number(d);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
static int hex_value(uint32_t c) {
|
|
304
|
+
if (c >= '0' && c <= '9') return (int)(c - '0');
|
|
305
|
+
if (c >= 'a' && c <= 'f') return (int)(c - 'a' + 10);
|
|
306
|
+
if (c >= 'A' && c <= 'F') return (int)(c - 'A' + 10);
|
|
307
|
+
return -1;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/* ScanJsonString: at the opening quote. */
|
|
311
|
+
static JSValue scan_string(Parser *p) {
|
|
312
|
+
uint32_t start = ++p->pos;
|
|
313
|
+
/* the common case: no escapes, a substring */
|
|
314
|
+
for (;;) {
|
|
315
|
+
if (at_end(p)) {
|
|
316
|
+
report(p, TOK_ILLEGAL, MSG_UNTERMINATED_STRING);
|
|
317
|
+
return JS_EXCEPTION;
|
|
318
|
+
}
|
|
319
|
+
uint32_t c = cur(p);
|
|
320
|
+
if (c == '"') {
|
|
321
|
+
JSValue s = js_substring(p->ctx, p->source, start, p->pos);
|
|
322
|
+
p->pos++;
|
|
323
|
+
return s;
|
|
324
|
+
}
|
|
325
|
+
if (c == '\\') break;
|
|
326
|
+
if (c < 0x20) {
|
|
327
|
+
report(p, TOK_ILLEGAL, MSG_CONTROL);
|
|
328
|
+
return JS_EXCEPTION;
|
|
329
|
+
}
|
|
330
|
+
p->pos++;
|
|
331
|
+
}
|
|
332
|
+
Builder b = { 0 };
|
|
333
|
+
put_view(&b, p->s, start, p->pos);
|
|
334
|
+
for (;;) {
|
|
335
|
+
if (at_end(p)) {
|
|
336
|
+
free(b.units);
|
|
337
|
+
report(p, TOK_ILLEGAL, MSG_UNTERMINATED_STRING);
|
|
338
|
+
return JS_EXCEPTION;
|
|
339
|
+
}
|
|
340
|
+
uint32_t c = cur(p);
|
|
341
|
+
if (c == '"') {
|
|
342
|
+
p->pos++;
|
|
343
|
+
return finish(p->ctx, &b);
|
|
344
|
+
}
|
|
345
|
+
if (c < 0x20) {
|
|
346
|
+
free(b.units);
|
|
347
|
+
report(p, TOK_ILLEGAL, MSG_CONTROL);
|
|
348
|
+
return JS_EXCEPTION;
|
|
349
|
+
}
|
|
350
|
+
if (c != '\\') {
|
|
351
|
+
put_unit(&b, c);
|
|
352
|
+
p->pos++;
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
c = next_char(p);
|
|
356
|
+
if (c > 0xFF) { /* the end, or past Latin-1: V8 reports the character itself */
|
|
357
|
+
free(b.units);
|
|
358
|
+
report_char(p, c);
|
|
359
|
+
return JS_EXCEPTION;
|
|
360
|
+
}
|
|
361
|
+
uint32_t out;
|
|
362
|
+
switch (c) {
|
|
363
|
+
case '"': case '\\': case '/': out = c; break;
|
|
364
|
+
case 'b': out = '\b'; break;
|
|
365
|
+
case 'f': out = '\f'; break;
|
|
366
|
+
case 'n': out = '\n'; break;
|
|
367
|
+
case 'r': out = '\r'; break;
|
|
368
|
+
case 't': out = '\t'; break;
|
|
369
|
+
case 'u': {
|
|
370
|
+
out = 0;
|
|
371
|
+
for (int i = 0; i < 4; i++) {
|
|
372
|
+
int d = hex_value(next_char(p));
|
|
373
|
+
if (d < 0) {
|
|
374
|
+
free(b.units);
|
|
375
|
+
report(p, TOK_ILLEGAL, MSG_UNICODE_ESCAPE);
|
|
376
|
+
return JS_EXCEPTION;
|
|
377
|
+
}
|
|
378
|
+
out = out * 16 + (uint32_t)d;
|
|
379
|
+
}
|
|
380
|
+
break;
|
|
381
|
+
}
|
|
382
|
+
default:
|
|
383
|
+
free(b.units);
|
|
384
|
+
report(p, TOK_ILLEGAL, MSG_ESCAPE);
|
|
385
|
+
return JS_EXCEPTION;
|
|
386
|
+
}
|
|
387
|
+
put_unit(&b, out);
|
|
388
|
+
p->pos++;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/* Parse nodes, kept only with a reviver: a primitive's node is [value, source]; an object's
|
|
393
|
+
* or array's is [container, children], children an object (by key) or an array (by index). */
|
|
394
|
+
static JSValue primitive_node(JSContext *ctx, Parser *p, JSValue v, uint32_t start) {
|
|
395
|
+
JSValue src = js_substring(ctx, p->source, start, p->pos);
|
|
396
|
+
JSValue pair[2] = { v, src };
|
|
397
|
+
return js_new_array_from(ctx, pair, 2);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
static JSValue container_node(JSContext *ctx, JSValue container) {
|
|
401
|
+
JSValue children = js_is_array(container) ? js_new_array(ctx, 0) : js_new_object_proto(ctx, JS_NULL, JS_DEFAULT_INLINE_SLOTS);
|
|
402
|
+
JSValue pair[2] = { container, children };
|
|
403
|
+
return js_new_array_from(ctx, pair, 2);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
static JSValue node_part(JSContext *ctx, JSValue node, int i) {
|
|
407
|
+
return js_get_value(ctx, node, js_int32(i));
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/* ParseJsonValue, iteratively: `stack` holds each open container and its node, and an
|
|
411
|
+
* object's pending key. *node_out gets the root's parse node when `nodes` is set. */
|
|
412
|
+
static JSValue parse_value(Parser *p, bool nodes, JSValue *node_out) {
|
|
413
|
+
JSContext *ctx = p->ctx;
|
|
414
|
+
JSValue stack = js_new_array(ctx, 0); /* [container, key or undefined, node or undefined]… */
|
|
415
|
+
JSValue v = JS_UNDEFINED, node = JS_UNDEFINED;
|
|
416
|
+
for (;;) {
|
|
417
|
+
/* a value */
|
|
418
|
+
skip_whitespace(p);
|
|
419
|
+
uint32_t start = p->pos;
|
|
420
|
+
Token t = peek(p);
|
|
421
|
+
switch (t) {
|
|
422
|
+
case TOK_STRING: v = scan_string(p); break;
|
|
423
|
+
case TOK_NUMBER: v = scan_number(p); break;
|
|
424
|
+
case TOK_TRUE: v = scan_literal(p, "true", JS_TRUE); break;
|
|
425
|
+
case TOK_FALSE: v = scan_literal(p, "false", JS_FALSE); break;
|
|
426
|
+
case TOK_NULL: v = scan_literal(p, "null", JS_NULL); break;
|
|
427
|
+
case TOK_LBRACE: {
|
|
428
|
+
p->pos++;
|
|
429
|
+
JSValue o = js_new_object(ctx);
|
|
430
|
+
skip_whitespace(p);
|
|
431
|
+
if (peek(p) == TOK_RBRACE) {
|
|
432
|
+
p->pos++;
|
|
433
|
+
v = o;
|
|
434
|
+
break;
|
|
435
|
+
}
|
|
436
|
+
if (peek(p) != TOK_STRING) {
|
|
437
|
+
report(p, peek(p), MSG_PROP_NAME_OR_RBRACE);
|
|
438
|
+
return JS_EXCEPTION;
|
|
439
|
+
}
|
|
440
|
+
JSValue key = scan_string(p);
|
|
441
|
+
if (js_is_exception(key)) return key;
|
|
442
|
+
skip_whitespace(p);
|
|
443
|
+
if (peek(p) != TOK_COLON) {
|
|
444
|
+
report(p, peek(p), MSG_COLON);
|
|
445
|
+
return JS_EXCEPTION;
|
|
446
|
+
}
|
|
447
|
+
p->pos++;
|
|
448
|
+
JSValue entry[3] = { o, key, nodes ? container_node(ctx, o) : JS_UNDEFINED };
|
|
449
|
+
for (int i = 0; i < 3; i++)
|
|
450
|
+
if (js_array_push(ctx, js_as_object(stack), entry[i]) < 0) return JS_EXCEPTION;
|
|
451
|
+
continue;
|
|
452
|
+
}
|
|
453
|
+
case TOK_LBRACK: {
|
|
454
|
+
p->pos++;
|
|
455
|
+
JSValue a = js_new_array(ctx, 0);
|
|
456
|
+
skip_whitespace(p);
|
|
457
|
+
if (peek(p) == TOK_RBRACK) {
|
|
458
|
+
p->pos++;
|
|
459
|
+
v = a;
|
|
460
|
+
break;
|
|
461
|
+
}
|
|
462
|
+
JSValue entry[3] = { a, JS_UNDEFINED, nodes ? container_node(ctx, a) : JS_UNDEFINED };
|
|
463
|
+
for (int i = 0; i < 3; i++)
|
|
464
|
+
if (js_array_push(ctx, js_as_object(stack), entry[i]) < 0) return JS_EXCEPTION;
|
|
465
|
+
continue;
|
|
466
|
+
}
|
|
467
|
+
default:
|
|
468
|
+
report(p, t, MSG_NONE);
|
|
469
|
+
return JS_EXCEPTION;
|
|
470
|
+
}
|
|
471
|
+
if (js_is_exception(v)) return v;
|
|
472
|
+
if (nodes) node = js_is_object(v) ? container_node(ctx, v) : primitive_node(ctx, p, v, start);
|
|
473
|
+
|
|
474
|
+
/* close the containers this value completes */
|
|
475
|
+
for (;;) {
|
|
476
|
+
uint32_t depth = js_array_length(js_as_object(stack));
|
|
477
|
+
if (depth == 0) {
|
|
478
|
+
if (nodes) *node_out = node;
|
|
479
|
+
return v;
|
|
480
|
+
}
|
|
481
|
+
JSValue container = js_get_value(ctx, stack, js_int32((int32_t)depth - 3));
|
|
482
|
+
JSValue cnode = js_get_value(ctx, stack, js_int32((int32_t)depth - 1));
|
|
483
|
+
skip_whitespace(p);
|
|
484
|
+
if (js_is_array(container)) {
|
|
485
|
+
if (js_array_push(ctx, js_as_object(container), v) < 0) return JS_EXCEPTION;
|
|
486
|
+
if (nodes && js_array_push(ctx, js_as_object(node_part(ctx, cnode, 1)), node) < 0) return JS_EXCEPTION;
|
|
487
|
+
if (peek(p) == TOK_COMMA) {
|
|
488
|
+
p->pos++;
|
|
489
|
+
break;
|
|
490
|
+
}
|
|
491
|
+
if (peek(p) != TOK_RBRACK) {
|
|
492
|
+
report(p, peek(p), MSG_COMMA_OR_RBRACK);
|
|
493
|
+
return JS_EXCEPTION;
|
|
494
|
+
}
|
|
495
|
+
} else {
|
|
496
|
+
JSValue key = js_to_property_key(ctx, js_get_value(ctx, stack, js_int32((int32_t)depth - 2)));
|
|
497
|
+
if (js_is_exception(key) || js_create_data_property(ctx, container, key, v) < 0) return JS_EXCEPTION;
|
|
498
|
+
if (nodes && js_create_data_property(ctx, node_part(ctx, cnode, 1), key, node) < 0) return JS_EXCEPTION;
|
|
499
|
+
if (peek(p) == TOK_COMMA) {
|
|
500
|
+
p->pos++;
|
|
501
|
+
skip_whitespace(p);
|
|
502
|
+
if (peek(p) != TOK_STRING) {
|
|
503
|
+
report(p, peek(p), MSG_DOUBLE_QUOTED_NAME);
|
|
504
|
+
return JS_EXCEPTION;
|
|
505
|
+
}
|
|
506
|
+
JSValue next = scan_string(p);
|
|
507
|
+
if (js_is_exception(next)) return next;
|
|
508
|
+
skip_whitespace(p);
|
|
509
|
+
if (peek(p) != TOK_COLON) {
|
|
510
|
+
report(p, peek(p), MSG_COLON);
|
|
511
|
+
return JS_EXCEPTION;
|
|
512
|
+
}
|
|
513
|
+
p->pos++;
|
|
514
|
+
if (js_set_value(ctx, stack, js_int32((int32_t)depth - 2), next, true) < 0) return JS_EXCEPTION;
|
|
515
|
+
break;
|
|
516
|
+
}
|
|
517
|
+
if (peek(p) != TOK_RBRACE) {
|
|
518
|
+
report(p, peek(p), MSG_COMMA_OR_RBRACE);
|
|
519
|
+
return JS_EXCEPTION;
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
p->pos++; /* the closing bracket */
|
|
523
|
+
v = container;
|
|
524
|
+
node = cnode;
|
|
525
|
+
JSPropertyDescriptor len = js_data_descriptor(js_int32((int32_t)depth - 3), JS_PROP_WRITABLE);
|
|
526
|
+
if (js_define_own_property(ctx, js_as_object(stack), JS_ATOM(length), &len, true) < 0) return JS_EXCEPTION;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/* InternalizeJSONProperty (§25.5.1.1, with the source text proposal's context). */
|
|
532
|
+
static JSValue internalize(JSContext *ctx, JSValue holder, JSValue name, JSValue reviver, JSValue node) {
|
|
533
|
+
JS_CHECK_STACK(ctx);
|
|
534
|
+
JSValue pname = js_to_property_key(ctx, name);
|
|
535
|
+
if (js_is_exception(pname)) return pname;
|
|
536
|
+
JSValue val = js_get_value(ctx, holder, pname);
|
|
537
|
+
if (js_is_exception(val)) return val;
|
|
538
|
+
JSValue children = JS_UNDEFINED;
|
|
539
|
+
if (js_is_array(node) && js_is_object(val) && js_same_bits(node_part(ctx, node, 0), val)) children = node_part(ctx, node, 1);
|
|
540
|
+
if (js_is_object(val)) {
|
|
541
|
+
int is_array = js_is_array_spec(ctx, val);
|
|
542
|
+
if (is_array < 0) return JS_EXCEPTION;
|
|
543
|
+
if (is_array) {
|
|
544
|
+
double len;
|
|
545
|
+
if (js_length_of_array_like(ctx, val, &len) < 0) return JS_EXCEPTION;
|
|
546
|
+
for (double i = 0; i < len; i++) {
|
|
547
|
+
JSValue key = js_to_string(ctx, js_number(i));
|
|
548
|
+
if (js_is_exception(key)) return key;
|
|
549
|
+
JSValue child = js_is_array(children) && i < js_array_length(js_as_object(children)) ? js_get_value(ctx, children, js_number(i)) : JS_UNDEFINED;
|
|
550
|
+
JSValue e = internalize(ctx, val, key, reviver, child);
|
|
551
|
+
if (js_is_exception(e)) return e;
|
|
552
|
+
JSValue k = js_index_key_of(ctx, i);
|
|
553
|
+
if (js_is_undefined(e)) {
|
|
554
|
+
if (js_delete_property(ctx, js_as_object(val), k, false) < 0) return JS_EXCEPTION;
|
|
555
|
+
} else if (js_create_data_property(ctx, val, k, e) < 0) {
|
|
556
|
+
js_discard(js_take_exception(ctx)); /* CreateDataProperty: a failure is ignored */
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
} else {
|
|
560
|
+
JSValue keys = js_get_own_enumerable_string_keys(ctx, val);
|
|
561
|
+
if (js_is_exception(keys)) return keys;
|
|
562
|
+
uint32_t n = js_array_length(js_as_object(keys));
|
|
563
|
+
for (uint32_t i = 0; i < n; i++) {
|
|
564
|
+
JSValue key = js_get_value(ctx, keys, js_int32((int32_t)i));
|
|
565
|
+
JSValue pkey = js_to_property_key(ctx, key);
|
|
566
|
+
if (js_is_exception(pkey)) return pkey;
|
|
567
|
+
JSValue child = JS_UNDEFINED;
|
|
568
|
+
if (js_is_object(children)) {
|
|
569
|
+
JSPropertyDescriptor d;
|
|
570
|
+
if (js_get_own_property(ctx, js_as_object(children), pkey, &d) == 1) child = d.value;
|
|
571
|
+
}
|
|
572
|
+
JSValue e = internalize(ctx, val, key, reviver, child);
|
|
573
|
+
if (js_is_exception(e)) return e;
|
|
574
|
+
if (js_is_undefined(e)) {
|
|
575
|
+
if (js_delete_property(ctx, js_as_object(val), pkey, false) < 0) return JS_EXCEPTION;
|
|
576
|
+
} else if (js_create_data_property(ctx, val, pkey, e) < 0) {
|
|
577
|
+
js_discard(js_take_exception(ctx));
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
JSValue context = js_new_object(ctx);
|
|
583
|
+
if (js_is_array(node) && !js_is_object(val)) {
|
|
584
|
+
JSValue parsed = node_part(ctx, node, 0);
|
|
585
|
+
if (!js_is_object(parsed) && js_same_value(ctx, parsed, val) &&
|
|
586
|
+
js_create_data_property(ctx, context, js_atom_from_cstr(ctx, "source"), node_part(ctx, node, 1)) < 0)
|
|
587
|
+
return JS_EXCEPTION;
|
|
588
|
+
}
|
|
589
|
+
JSValue args[3] = { name, val, context };
|
|
590
|
+
return js_call(ctx, reviver, holder, 3, args);
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
static JSValue json_parse(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc, const JSValue *argv, JSValue new_target) {
|
|
594
|
+
UNUSED_ARGS;
|
|
595
|
+
JSValue text = js_to_string(ctx, ARG(0));
|
|
596
|
+
if (js_is_exception(text)) return text;
|
|
597
|
+
Parser p = { ctx, text, js_string_view(ctx, text), 0, false };
|
|
598
|
+
bool revive = js_is_callable(ARG(1));
|
|
599
|
+
JSValue node = JS_UNDEFINED;
|
|
600
|
+
JSValue v = parse_value(&p, revive, &node);
|
|
601
|
+
if (js_is_exception(v)) return v;
|
|
602
|
+
skip_whitespace(&p);
|
|
603
|
+
if (!at_end(&p)) {
|
|
604
|
+
report(&p, peek(&p), MSG_NON_WHITESPACE);
|
|
605
|
+
return JS_EXCEPTION;
|
|
606
|
+
}
|
|
607
|
+
if (!revive) return v;
|
|
608
|
+
JSValue root = js_new_object(ctx);
|
|
609
|
+
if (js_create_data_property(ctx, root, js_empty_string(), v) < 0) return JS_EXCEPTION;
|
|
610
|
+
return internalize(ctx, root, js_empty_string(), ARG(1), node);
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
JSValue js_json_parse(JSContext *ctx, JSValue text) { return json_parse(ctx, JS_UNDEFINED, JS_UNDEFINED, 1, &text, JS_UNDEFINED); }
|
|
614
|
+
|
|
615
|
+
/* ---- JSON.rawJSON / isRawJSON ------------------------------------------------------------- */
|
|
616
|
+
|
|
617
|
+
static const JSClass raw_json_class = { "RawJSON", sizeof(JSObject), NULL, NULL, NULL, NULL, NULL, NULL, NULL };
|
|
618
|
+
|
|
619
|
+
static bool is_raw_json(JSValue v) {
|
|
620
|
+
return js_is_object(v) && js_as_object(v)->shape->cls == &raw_json_class;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
static JSValue json_raw_json(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc, const JSValue *argv, JSValue new_target) {
|
|
624
|
+
UNUSED_ARGS;
|
|
625
|
+
JSValue text = js_to_string(ctx, ARG(0));
|
|
626
|
+
if (js_is_exception(text)) return text;
|
|
627
|
+
Parser p = { ctx, text, js_string_view(ctx, text), 0, false };
|
|
628
|
+
if (at_end(&p)) return js_throw_syntax_error(ctx, "Invalid value for JSON.rawJSON");
|
|
629
|
+
JSValue v;
|
|
630
|
+
switch (peek(&p)) { /* ParseRawJson: one primitive, nothing around it */
|
|
631
|
+
case TOK_STRING: v = scan_string(&p); break;
|
|
632
|
+
case TOK_NUMBER: v = scan_number(&p); break;
|
|
633
|
+
case TOK_TRUE: v = scan_literal(&p, "true", JS_TRUE); break;
|
|
634
|
+
case TOK_FALSE: v = scan_literal(&p, "false", JS_FALSE); break;
|
|
635
|
+
case TOK_NULL: v = scan_literal(&p, "null", JS_NULL); break;
|
|
636
|
+
default:
|
|
637
|
+
report_char(&p, cur(&p));
|
|
638
|
+
return JS_EXCEPTION;
|
|
639
|
+
}
|
|
640
|
+
if (js_is_exception(v)) return v;
|
|
641
|
+
if (!at_end(&p)) return js_throw_syntax_error(ctx, "Invalid value for JSON.rawJSON");
|
|
642
|
+
JSShape *shape = js_shape_root(ctx, &raw_json_class, JS_NULL, 1);
|
|
643
|
+
JSObject *o = js_alloc_object(ctx, JS_CELL_OBJECT, shape);
|
|
644
|
+
js_define_data(ctx, o, js_atom_from_cstr(ctx, "rawJSON"), text, JS_PROP_DEFAULT);
|
|
645
|
+
if (js_freeze(ctx, o) < 0) return JS_EXCEPTION;
|
|
646
|
+
return js_object_value(o);
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
static JSValue json_is_raw_json(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc, const JSValue *argv, JSValue new_target) {
|
|
650
|
+
UNUSED_ARGS;
|
|
651
|
+
return js_bool(is_raw_json(ARG(0)));
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
/* ---- JSON.stringify (§25.5.2) --------------------------------------------------------------- */
|
|
655
|
+
|
|
656
|
+
typedef struct {
|
|
657
|
+
JSContext *ctx;
|
|
658
|
+
Builder b;
|
|
659
|
+
JSValue replacer; /* a function, or undefined */
|
|
660
|
+
JSValue property_list; /* an array of strings, or undefined */
|
|
661
|
+
JSValue gap; /* a string, maybe empty */
|
|
662
|
+
JSValue stack; /* [key, object]…: the objects being serialized, for cycles */
|
|
663
|
+
uint32_t depth; /* indentation = gap × depth */
|
|
664
|
+
} Stringifier;
|
|
665
|
+
|
|
666
|
+
static void put_json_string(Builder *b, JSStrView s) {
|
|
667
|
+
put_unit(b, '"');
|
|
668
|
+
for (uint32_t i = 0; i < s.length; i++) {
|
|
669
|
+
uint32_t c = js_view_at(s, i);
|
|
670
|
+
switch (c) {
|
|
671
|
+
case '"': put_ascii(b, "\\\""); continue;
|
|
672
|
+
case '\\': put_ascii(b, "\\\\"); continue;
|
|
673
|
+
case '\b': put_ascii(b, "\\b"); continue;
|
|
674
|
+
case '\f': put_ascii(b, "\\f"); continue;
|
|
675
|
+
case '\n': put_ascii(b, "\\n"); continue;
|
|
676
|
+
case '\r': put_ascii(b, "\\r"); continue;
|
|
677
|
+
case '\t': put_ascii(b, "\\t"); continue;
|
|
678
|
+
}
|
|
679
|
+
bool lone = false;
|
|
680
|
+
if (c >= 0xD800 && c <= 0xDFFF) {
|
|
681
|
+
uint32_t d = i + 1 < s.length ? js_view_at(s, i + 1) : 0;
|
|
682
|
+
if (c <= 0xDBFF && d >= 0xDC00 && d <= 0xDFFF) {
|
|
683
|
+
put_unit(b, c);
|
|
684
|
+
put_unit(b, d);
|
|
685
|
+
i++;
|
|
686
|
+
continue;
|
|
687
|
+
}
|
|
688
|
+
lone = true; /* well-formed JSON.stringify (ES2019) */
|
|
689
|
+
}
|
|
690
|
+
if (c < 0x20 || lone) {
|
|
691
|
+
char esc[8];
|
|
692
|
+
snprintf(esc, sizeof esc, "\\u%04x", c);
|
|
693
|
+
put_ascii(b, esc);
|
|
694
|
+
} else {
|
|
695
|
+
put_unit(b, c);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
put_unit(b, '"');
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
static void put_indent(Stringifier *st) {
|
|
702
|
+
put_unit(&st->b, '\n');
|
|
703
|
+
for (uint32_t i = 0; i < st->depth; i++) put_string(&st->b, st->ctx, st->gap);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
/* V8's JSReceiver::GetConstructorName, without side effects: a @@toStringTag string, or the
|
|
707
|
+
* name of a `constructor` on the prototype chain, else the kind of object. */
|
|
708
|
+
static void put_constructor_name(Builder *b, JSContext *ctx, JSValue obj) {
|
|
709
|
+
bool self = true;
|
|
710
|
+
for (JSValue o = obj; js_is_object(o); o = js_get_prototype_of(js_as_object(o)), self = false) {
|
|
711
|
+
JSPropertyDescriptor d;
|
|
712
|
+
if (js_get_own_property(ctx, js_as_object(o), JS_SYMBOL(toStringTag), &d) == 1 && (d.has & JS_DESC_VALUE) && js_is_string(d.value)) {
|
|
713
|
+
put_string(b, ctx, d.value);
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
716
|
+
if (self) continue;
|
|
717
|
+
if (js_get_own_property(ctx, js_as_object(o), JS_ATOM(constructor), &d) == 1 && (d.has & JS_DESC_VALUE) && js_is_function(d.value)) {
|
|
718
|
+
JSPropertyDescriptor n;
|
|
719
|
+
if (js_get_own_property(ctx, js_as_object(d.value), JS_ATOM(name), &n) == 1 && (n.has & JS_DESC_VALUE) && js_is_string(n.value) &&
|
|
720
|
+
js_string_length(n.value) != 0 && !js_string_equals(ctx, n.value, js_atom_from_cstr(ctx, "Object"))) {
|
|
721
|
+
put_string(b, ctx, n.value);
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
if (js_is_array(obj)) put_ascii(b, "Array");
|
|
727
|
+
else if (js_is_function(obj)) put_ascii(b, "Function");
|
|
728
|
+
else if (js_is_error(obj)) put_ascii(b, "Error");
|
|
729
|
+
else put_ascii(b, "Object");
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
static void put_cycle_key(Builder *b, JSContext *ctx, JSValue key) {
|
|
733
|
+
if (js_is_number(key)) {
|
|
734
|
+
char buf[32];
|
|
735
|
+
snprintf(buf, sizeof buf, "index %.0f", js_as_number(key));
|
|
736
|
+
put_ascii(b, buf);
|
|
737
|
+
} else if (js_string_length(key) == 0) {
|
|
738
|
+
put_ascii(b, "<anonymous>");
|
|
739
|
+
} else {
|
|
740
|
+
put_ascii(b, "property '");
|
|
741
|
+
put_string(b, ctx, key);
|
|
742
|
+
put_unit(b, '\'');
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
/* V8's ConstructCircularStructureErrorMessage: the cycle from the object seen again, at most two
|
|
747
|
+
* lines after the start and one before the end, "..." for the rest. */
|
|
748
|
+
static JSValue throw_circular(Stringifier *st, uint32_t start, JSValue closing_key) {
|
|
749
|
+
JSContext *ctx = st->ctx;
|
|
750
|
+
uint32_t n = js_array_length(js_as_object(st->stack)) / 2;
|
|
751
|
+
Builder b = { 0 };
|
|
752
|
+
put_ascii(&b, "Converting circular structure to JSON\n --> starting at object with constructor '");
|
|
753
|
+
put_constructor_name(&b, ctx, js_get_value(ctx, st->stack, js_int32((int32_t)(2 * start + 1))));
|
|
754
|
+
put_unit(&b, '\'');
|
|
755
|
+
uint32_t index = start + 1;
|
|
756
|
+
uint32_t prefix_end = index + 2 < n ? index + 2 : n;
|
|
757
|
+
for (int part = 0; part < 2; part++) {
|
|
758
|
+
for (; index < prefix_end; index++) {
|
|
759
|
+
put_ascii(&b, "\n | ");
|
|
760
|
+
put_cycle_key(&b, ctx, js_get_value(ctx, st->stack, js_int32((int32_t)(2 * index))));
|
|
761
|
+
put_ascii(&b, " -> object with constructor '");
|
|
762
|
+
put_constructor_name(&b, ctx, js_get_value(ctx, st->stack, js_int32((int32_t)(2 * index + 1))));
|
|
763
|
+
put_unit(&b, '\'');
|
|
764
|
+
}
|
|
765
|
+
if (part == 0) {
|
|
766
|
+
if (n > index + 1) put_ascii(&b, "\n | ...");
|
|
767
|
+
if (index < n - 1) index = n - 1;
|
|
768
|
+
prefix_end = n;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
put_ascii(&b, "\n --- ");
|
|
772
|
+
put_cycle_key(&b, ctx, closing_key);
|
|
773
|
+
put_ascii(&b, " closes the circle");
|
|
774
|
+
JSValue text = finish(ctx, &b);
|
|
775
|
+
if (js_is_exception(text)) return text;
|
|
776
|
+
return js_throw(ctx, js_new_error(ctx, JS_TYPE_ERROR, text));
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
enum { SER_OK = 0, SER_UNDEFINED = 1, SER_ERROR = -1 };
|
|
780
|
+
|
|
781
|
+
static int serialize_property(Stringifier *st, JSValue key, JSValue holder, JSValue cycle_key);
|
|
782
|
+
|
|
783
|
+
/* A cycle check, then [key, value] onto the stack. */
|
|
784
|
+
static int enter(Stringifier *st, JSValue value, JSValue cycle_key) {
|
|
785
|
+
JSContext *ctx = st->ctx;
|
|
786
|
+
uint32_t n = js_array_length(js_as_object(st->stack));
|
|
787
|
+
for (uint32_t i = 1; i < n; i += 2)
|
|
788
|
+
if (js_same_bits(js_get_value(ctx, st->stack, js_int32((int32_t)i)), value)) {
|
|
789
|
+
js_discard(throw_circular(st, i / 2, cycle_key));
|
|
790
|
+
return SER_ERROR;
|
|
791
|
+
}
|
|
792
|
+
if (js_array_push(ctx, js_as_object(st->stack), cycle_key) < 0 || js_array_push(ctx, js_as_object(st->stack), value) < 0) return SER_ERROR;
|
|
793
|
+
st->depth++;
|
|
794
|
+
return SER_OK;
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
static int leave(Stringifier *st) {
|
|
798
|
+
st->depth--;
|
|
799
|
+
uint32_t n = js_array_length(js_as_object(st->stack));
|
|
800
|
+
JSPropertyDescriptor len = js_data_descriptor(js_int32((int32_t)n - 2), JS_PROP_WRITABLE);
|
|
801
|
+
return js_define_own_property(st->ctx, js_as_object(st->stack), JS_ATOM(length), &len, true) < 0 ? SER_ERROR : SER_OK;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
/* SerializeJSONObject (§25.5.2.5) */
|
|
805
|
+
static int serialize_object(Stringifier *st, JSValue value, JSValue cycle_key) {
|
|
806
|
+
JSContext *ctx = st->ctx;
|
|
807
|
+
if (enter(st, value, cycle_key) < 0) return SER_ERROR;
|
|
808
|
+
JSValue keys = st->property_list;
|
|
809
|
+
if (js_is_undefined(keys)) keys = js_get_own_enumerable_string_keys(ctx, value);
|
|
810
|
+
if (js_is_exception(keys)) return SER_ERROR;
|
|
811
|
+
uint32_t n = js_array_length(js_as_object(keys));
|
|
812
|
+
bool gap = js_string_length(st->gap) != 0;
|
|
813
|
+
bool any = false;
|
|
814
|
+
put_unit(&st->b, '{');
|
|
815
|
+
for (uint32_t i = 0; i < n; i++) {
|
|
816
|
+
JSValue key = js_get_value(ctx, keys, js_int32((int32_t)i));
|
|
817
|
+
if (js_is_exception(key)) return SER_ERROR;
|
|
818
|
+
size_t mark = st->b.length;
|
|
819
|
+
if (any) put_unit(&st->b, ',');
|
|
820
|
+
if (gap) put_indent(st);
|
|
821
|
+
put_json_string(&st->b, js_string_view(ctx, key));
|
|
822
|
+
put_unit(&st->b, ':');
|
|
823
|
+
if (gap) put_unit(&st->b, ' ');
|
|
824
|
+
int r = serialize_property(st, key, value, key);
|
|
825
|
+
if (r == SER_ERROR) return SER_ERROR;
|
|
826
|
+
if (r == SER_UNDEFINED) st->b.length = mark;
|
|
827
|
+
else any = true;
|
|
828
|
+
}
|
|
829
|
+
if (leave(st) < 0) return SER_ERROR;
|
|
830
|
+
if (any && gap) put_indent(st);
|
|
831
|
+
put_unit(&st->b, '}');
|
|
832
|
+
return SER_OK;
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
/* SerializeJSONArray (§25.5.2.6) */
|
|
836
|
+
static int serialize_array(Stringifier *st, JSValue value, JSValue cycle_key) {
|
|
837
|
+
JSContext *ctx = st->ctx;
|
|
838
|
+
if (enter(st, value, cycle_key) < 0) return SER_ERROR;
|
|
839
|
+
double len;
|
|
840
|
+
if (js_length_of_array_like(ctx, value, &len) < 0) return SER_ERROR;
|
|
841
|
+
bool gap = js_string_length(st->gap) != 0;
|
|
842
|
+
put_unit(&st->b, '[');
|
|
843
|
+
for (double i = 0; i < len; i++) {
|
|
844
|
+
if (i > 0) put_unit(&st->b, ',');
|
|
845
|
+
if (gap) put_indent(st);
|
|
846
|
+
JSValue key = js_to_string(ctx, js_number(i));
|
|
847
|
+
if (js_is_exception(key)) return SER_ERROR;
|
|
848
|
+
int r = serialize_property(st, key, value, js_number(i));
|
|
849
|
+
if (r == SER_ERROR) return SER_ERROR;
|
|
850
|
+
if (r == SER_UNDEFINED) put_ascii(&st->b, "null");
|
|
851
|
+
}
|
|
852
|
+
if (leave(st) < 0) return SER_ERROR;
|
|
853
|
+
if (len > 0 && gap) put_indent(st);
|
|
854
|
+
put_unit(&st->b, ']');
|
|
855
|
+
return SER_OK;
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
/* SerializeJSONProperty (§25.5.2.2): the value of holder[key], appended. `cycle_key` is how a
|
|
859
|
+
* cycle's message names the key (an array index is a number). */
|
|
860
|
+
static int serialize_property(Stringifier *st, JSValue key, JSValue holder, JSValue cycle_key) {
|
|
861
|
+
JSContext *ctx = st->ctx;
|
|
862
|
+
if (JS_FRAME_ADDRESS() < ctx->stack_limit) {
|
|
863
|
+
js_discard(js_throw_stack_overflow(ctx));
|
|
864
|
+
return SER_ERROR;
|
|
865
|
+
}
|
|
866
|
+
JSValue pkey = js_to_property_key(ctx, key);
|
|
867
|
+
if (js_is_exception(pkey)) return SER_ERROR;
|
|
868
|
+
JSValue value = js_get_value(ctx, holder, pkey);
|
|
869
|
+
if (js_is_exception(value)) return SER_ERROR;
|
|
870
|
+
if (js_is_object(value) || js_is_bigint(value)) {
|
|
871
|
+
JSValue to_json = js_get_value(ctx, value, js_atom_from_cstr(ctx, "toJSON"));
|
|
872
|
+
if (js_is_exception(to_json)) return SER_ERROR;
|
|
873
|
+
if (js_is_callable(to_json)) {
|
|
874
|
+
value = js_call(ctx, to_json, value, 1, &key);
|
|
875
|
+
if (js_is_exception(value)) return SER_ERROR;
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
if (!js_is_undefined(st->replacer)) {
|
|
879
|
+
JSValue args[2] = { key, value };
|
|
880
|
+
value = js_call(ctx, st->replacer, holder, 2, args);
|
|
881
|
+
if (js_is_exception(value)) return SER_ERROR;
|
|
882
|
+
}
|
|
883
|
+
if (js_is_wrapper(value)) { /* [[NumberData]], [[StringData]], [[BooleanData]] */
|
|
884
|
+
JSValue prim = js_wrapped_value(value);
|
|
885
|
+
if (js_is_number(prim)) {
|
|
886
|
+
double d;
|
|
887
|
+
if (js_to_number(ctx, &d, value) < 0) return SER_ERROR;
|
|
888
|
+
value = js_number(d);
|
|
889
|
+
} else if (js_is_string(prim)) {
|
|
890
|
+
value = js_to_string(ctx, value);
|
|
891
|
+
if (js_is_exception(value)) return SER_ERROR;
|
|
892
|
+
} else if (js_is_bool(prim) || js_is_bigint(prim)) {
|
|
893
|
+
value = prim;
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
if (js_is_bigint(value)) {
|
|
897
|
+
js_discard(js_throw_type_error(ctx, "Do not know how to serialize a BigInt"));
|
|
898
|
+
return SER_ERROR;
|
|
899
|
+
}
|
|
900
|
+
if (is_raw_json(value)) {
|
|
901
|
+
JSValue raw = js_get_value(ctx, value, js_atom_from_cstr(ctx, "rawJSON"));
|
|
902
|
+
if (js_is_exception(raw)) return SER_ERROR;
|
|
903
|
+
put_string(&st->b, ctx, raw);
|
|
904
|
+
return SER_OK;
|
|
905
|
+
}
|
|
906
|
+
if (js_is_null(value)) put_ascii(&st->b, "null");
|
|
907
|
+
else if (js_is_bool(value)) put_ascii(&st->b, js_as_bool(value) ? "true" : "false");
|
|
908
|
+
else if (js_is_string(value)) put_json_string(&st->b, js_string_view(ctx, value));
|
|
909
|
+
else if (js_is_number(value)) {
|
|
910
|
+
double d = js_as_number(value);
|
|
911
|
+
if (!isfinite(d)) {
|
|
912
|
+
put_ascii(&st->b, "null");
|
|
913
|
+
} else {
|
|
914
|
+
char buf[64];
|
|
915
|
+
js_num_to_cstr(buf, d);
|
|
916
|
+
put_ascii(&st->b, buf);
|
|
917
|
+
}
|
|
918
|
+
} else if (js_is_object(value) && !js_is_callable(value)) {
|
|
919
|
+
int is_array = js_is_array_spec(st->ctx, value);
|
|
920
|
+
if (is_array < 0) return SER_ERROR;
|
|
921
|
+
return is_array ? serialize_array(st, value, cycle_key) : serialize_object(st, value, cycle_key);
|
|
922
|
+
} else {
|
|
923
|
+
return SER_UNDEFINED; /* undefined, symbols, functions */
|
|
924
|
+
}
|
|
925
|
+
return SER_OK;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
JSValue js_json_stringify(JSContext *ctx, JSValue value, JSValue replacer, JSValue space, bool *circular) {
|
|
929
|
+
Stringifier st = { ctx, { 0 }, JS_UNDEFINED, JS_UNDEFINED, js_empty_string(), js_new_array(ctx, 0), 0 };
|
|
930
|
+
if (circular) *circular = false;
|
|
931
|
+
int replacer_is_array = js_is_callable(replacer) ? 0 : js_is_array_spec(ctx, replacer);
|
|
932
|
+
if (replacer_is_array < 0) return JS_EXCEPTION;
|
|
933
|
+
if (js_is_callable(replacer)) {
|
|
934
|
+
st.replacer = replacer;
|
|
935
|
+
} else if (replacer_is_array) { /* the property list: strings and numbers, once each */
|
|
936
|
+
double len;
|
|
937
|
+
if (js_length_of_array_like(ctx, replacer, &len) < 0) return JS_EXCEPTION;
|
|
938
|
+
JSValue list = js_new_array(ctx, 0);
|
|
939
|
+
JSValue seen = js_new_object_proto(ctx, JS_NULL, JS_DEFAULT_INLINE_SLOTS);
|
|
940
|
+
for (double i = 0; i < len; i++) {
|
|
941
|
+
JSValue v = js_get_value(ctx, replacer, js_index_key_of(ctx, i));
|
|
942
|
+
if (js_is_exception(v)) return v;
|
|
943
|
+
JSValue item = JS_UNDEFINED;
|
|
944
|
+
if (js_is_string(v)) item = v;
|
|
945
|
+
else if (js_is_number(v) || (js_is_wrapper(v) && (js_is_string(js_wrapped_value(v)) || js_is_number(js_wrapped_value(v))))) {
|
|
946
|
+
item = js_to_string(ctx, v);
|
|
947
|
+
if (js_is_exception(item)) return item;
|
|
948
|
+
}
|
|
949
|
+
if (js_is_undefined(item)) continue;
|
|
950
|
+
JSValue k = js_to_property_key(ctx, item);
|
|
951
|
+
if (js_is_exception(k)) return k;
|
|
952
|
+
JSPropertyDescriptor d;
|
|
953
|
+
if (js_get_own_property(ctx, js_as_object(seen), k, &d) == 1) continue;
|
|
954
|
+
js_define_data(ctx, js_as_object(seen), k, JS_TRUE, JS_PROP_DEFAULT);
|
|
955
|
+
if (js_array_push(ctx, js_as_object(list), item) < 0) return JS_EXCEPTION;
|
|
956
|
+
}
|
|
957
|
+
st.property_list = list;
|
|
958
|
+
}
|
|
959
|
+
if (js_is_wrapper(space)) {
|
|
960
|
+
JSValue prim = js_wrapped_value(space);
|
|
961
|
+
if (js_is_number(prim)) {
|
|
962
|
+
double d;
|
|
963
|
+
if (js_to_number(ctx, &d, space) < 0) return JS_EXCEPTION;
|
|
964
|
+
space = js_number(d);
|
|
965
|
+
} else if (js_is_string(prim)) {
|
|
966
|
+
space = js_to_string(ctx, space);
|
|
967
|
+
if (js_is_exception(space)) return space;
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
if (js_is_number(space)) {
|
|
971
|
+
double n;
|
|
972
|
+
if (js_to_integer_or_infinity(ctx, &n, space) < 0) return JS_EXCEPTION;
|
|
973
|
+
if (n > 10) n = 10;
|
|
974
|
+
static const char spaces[] = " ";
|
|
975
|
+
st.gap = n >= 1 ? js_new_string_latin1(ctx, (const uint8_t *)spaces, (uint32_t)n) : js_empty_string();
|
|
976
|
+
} else if (js_is_string(space)) {
|
|
977
|
+
uint32_t n = js_string_length(space);
|
|
978
|
+
st.gap = n > 10 ? js_substring(ctx, space, 0, 10) : space;
|
|
979
|
+
}
|
|
980
|
+
JSValue wrapper = js_new_object(ctx);
|
|
981
|
+
if (js_create_data_property(ctx, wrapper, js_empty_string(), value) < 0) return JS_EXCEPTION;
|
|
982
|
+
int r = serialize_property(&st, js_empty_string(), wrapper, js_empty_string());
|
|
983
|
+
if (r == SER_ERROR) {
|
|
984
|
+
free(st.b.units);
|
|
985
|
+
if (circular) {
|
|
986
|
+
/* tryStringify's check: a TypeError whose first line is the cycle message */
|
|
987
|
+
JSValue e = js_take_exception(ctx);
|
|
988
|
+
JSValue msg = js_is_error(e) ? js_get_value(ctx, e, JS_ATOM(message)) : JS_UNDEFINED;
|
|
989
|
+
if (js_is_exception(msg)) msg = JS_UNDEFINED;
|
|
990
|
+
static const char head[] = "Converting circular structure to JSON";
|
|
991
|
+
if (js_is_string(msg)) {
|
|
992
|
+
JSStrView m = js_string_view(ctx, msg);
|
|
993
|
+
bool match = m.length >= sizeof head - 1 && (m.length == sizeof head - 1 || js_view_at(m, sizeof head - 1) == '\n');
|
|
994
|
+
for (uint32_t i = 0; match && i < sizeof head - 1; i++) match = js_view_at(m, i) == (uint8_t)head[i];
|
|
995
|
+
*circular = match && js_get_prototype_of(js_as_object(e)).bits == ctx->intrinsics[JS_INTRINSIC_TYPE_ERROR_PROTOTYPE].bits;
|
|
996
|
+
}
|
|
997
|
+
js_discard(js_throw(ctx, e));
|
|
998
|
+
}
|
|
999
|
+
return JS_EXCEPTION;
|
|
1000
|
+
}
|
|
1001
|
+
if (r == SER_UNDEFINED) {
|
|
1002
|
+
free(st.b.units);
|
|
1003
|
+
return JS_UNDEFINED;
|
|
1004
|
+
}
|
|
1005
|
+
return finish(ctx, &st.b);
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
static JSValue json_stringify(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc, const JSValue *argv, JSValue new_target) {
|
|
1009
|
+
UNUSED_ARGS;
|
|
1010
|
+
return js_json_stringify(ctx, ARG(0), ARG(1), ARG(2), NULL);
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
/* ---- The component ------------------------------------------------------------------------ */
|
|
1014
|
+
|
|
1015
|
+
static const JSBuiltin json_entries[] = {
|
|
1016
|
+
JS_BUILTIN_FN("parse", json_parse, 2),
|
|
1017
|
+
JS_BUILTIN_FN("stringify", json_stringify, 3),
|
|
1018
|
+
JS_BUILTIN_FN("rawJSON", json_raw_json, 1),
|
|
1019
|
+
JS_BUILTIN_FN("isRawJSON", json_is_raw_json, 1),
|
|
1020
|
+
JS_BUILTIN_SYMBOL_STRING(toStringTag, "JSON", JS_PROP_CONFIGURABLE),
|
|
1021
|
+
};
|
|
1022
|
+
|
|
1023
|
+
static void install_json(JSContext *ctx, JSObject *global) {
|
|
1024
|
+
JSValue json = js_new_builtin_object(ctx, json_entries, JS_COUNTOF(json_entries));
|
|
1025
|
+
js_define_data(ctx, global, js_atom_from_cstr(ctx, "JSON"), json, JS_BUILTIN_METHOD_ATTRS);
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
const JSComponent js_component_json = { "json", install_json };
|