Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 3 additions & 16 deletions qjs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,14 @@
#include <iostream>
#include <string_view>

static bool bignum_ext = false;

/* also used to initialize the worker context */
static JSContext *JS_NewCustomContext(JSRuntime *rt)
{
JSContext *ctx;
ctx = JS_NewContext(rt);
if (!ctx)
return NULL;
if (bignum_ext) {
JS_AddIntrinsicBigFloat(ctx);
JS_AddIntrinsicBigDecimal(ctx);
JS_AddIntrinsicOperators(ctx);
JS_EnableBignumExt(ctx, true);
}

/* system modules */
js_init_module_std(ctx, "std");
js_init_module_os(ctx, "os");
Expand All @@ -34,7 +27,7 @@ int main(int argc, char ** argv)
js_std_init_handlers(rt);

/* loader for ES6 modules */
JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
JS_SetModuleLoaderFunc2(rt, NULL, js_module_loader, NULL, NULL);

qjs::Context context(JS_NewCustomContext(rt));
auto ctx = context.ctx;
Expand All @@ -53,12 +46,6 @@ int main(int argc, char ** argv)
flags = JS_EVAL_TYPE_GLOBAL;
optind++;
}
// enable bignum
if(argv[optind] && argv[optind] == std::string_view{"--bignum"})
{
bignum_ext = true;
optind++;
}

js_std_add_helpers(ctx, argc - optind, argv + optind);

Expand Down Expand Up @@ -87,7 +74,7 @@ int main(int argc, char ** argv)
}
else
{
std::cout << argv[0] << " [--module|--script] [--bignum] <filename>" << std::endl;
std::cout << argv[0] << " [--module|--script] <filename>" << std::endl;
js_std_free_handlers(rt);
return 1;
}
Expand Down
10 changes: 9 additions & 1 deletion quickjs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@ project(quickjs LANGUAGES C)

file(STRINGS VERSION version)

set(quickjs_src quickjs.c libbf.c libunicode.c libregexp.c cutils.c quickjs-libc.c)
set(quickjs_src
cutils.c
dtoa.c
libregexp.c
libunicode.c
quickjs-libc.c
quickjs.c
)

set(quickjs_def CONFIG_VERSION="${version}" _GNU_SOURCE CONFIG_BIGNUM)

add_library(quickjs ${quickjs_src})
Expand Down
22 changes: 22 additions & 0 deletions quickjs/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
QuickJS Javascript Engine

Copyright (c) 2017-2021 Fabrice Bellard
Copyright (c) 2017-2021 Charlie Gordon

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
2 changes: 1 addition & 1 deletion quickjs/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2023-12-09
2025-04-26
8 changes: 5 additions & 3 deletions quickjs/cutils.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* C utilities
*
*
* Copyright (c) 2017 Fabrice Bellard
* Copyright (c) 2018 Charlie Gordon
*
Expand Down Expand Up @@ -140,7 +140,7 @@ int dbuf_put(DynBuf *s, const uint8_t *data, size_t len)
if (dbuf_realloc(s, s->size + len))
return -1;
}
memcpy(s->buf + s->size, data, len);
memcpy_no_ub(s->buf + s->size, data, len);
s->size += len;
return 0;
}
Expand Down Expand Up @@ -172,10 +172,12 @@ int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s,
va_list ap;
char buf[128];
int len;

va_start(ap, fmt);
len = vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
if (len < 0)
return -1;
if (len < sizeof(buf)) {
/* fast case */
return dbuf_put(s, (uint8_t *)buf, len);
Expand Down
148 changes: 137 additions & 11 deletions quickjs/cutils.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* C utilities
*
*
* Copyright (c) 2017 Fabrice Bellard
* Copyright (c) 2018 Charlie Gordon
*
Expand All @@ -26,11 +26,9 @@
#define CUTILS_H

#include <stdlib.h>
#include <string.h>
#include <inttypes.h>

/* set if CPU is big endian */
#undef WORDS_BIGENDIAN

#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#define force_inline inline __attribute__((always_inline))
Expand All @@ -48,6 +46,16 @@
#ifndef countof
#define countof(x) (sizeof(x) / sizeof((x)[0]))
#endif
#ifndef container_of
/* return the pointer of type 'type *' containing 'ptr' as field 'member' */
#define container_of(ptr, type, member) ((type *)((uint8_t *)(ptr) - offsetof(type, member)))
#endif

#if !defined(_MSC_VER) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
#define minimum_length(n) static n
#else
#define minimum_length(n) n
#endif

typedef int BOOL;

Expand All @@ -63,6 +71,12 @@ char *pstrcat(char *buf, int buf_size, const char *s);
int strstart(const char *str, const char *val, const char **ptr);
int has_suffix(const char *str, const char *suffix);

/* Prevent UB when n == 0 and (src == NULL or dest == NULL) */
static inline void memcpy_no_ub(void *dest, const void *src, size_t n) {
if (n)
memcpy(dest, src, n);
}

static inline int max_int(int a, int b)
{
if (a > b)
Expand Down Expand Up @@ -207,28 +221,34 @@ static inline void put_u8(uint8_t *tab, uint8_t val)
*tab = val;
}

#ifndef bswap16
static inline uint16_t bswap16(uint16_t x)
{
return (x >> 8) | (x << 8);
}
#endif

#ifndef bswap32
static inline uint32_t bswap32(uint32_t v)
{
return ((v & 0xff000000) >> 24) | ((v & 0x00ff0000) >> 8) |
((v & 0x0000ff00) << 8) | ((v & 0x000000ff) << 24);
}
#endif

#ifndef bswap64
static inline uint64_t bswap64(uint64_t v)
{
return ((v & ((uint64_t)0xff << (7 * 8))) >> (7 * 8)) |
((v & ((uint64_t)0xff << (6 * 8))) >> (5 * 8)) |
((v & ((uint64_t)0xff << (5 * 8))) >> (3 * 8)) |
((v & ((uint64_t)0xff << (4 * 8))) >> (1 * 8)) |
((v & ((uint64_t)0xff << (3 * 8))) << (1 * 8)) |
((v & ((uint64_t)0xff << (2 * 8))) << (3 * 8)) |
((v & ((uint64_t)0xff << (1 * 8))) << (5 * 8)) |
return ((v & ((uint64_t)0xff << (7 * 8))) >> (7 * 8)) |
((v & ((uint64_t)0xff << (6 * 8))) >> (5 * 8)) |
((v & ((uint64_t)0xff << (5 * 8))) >> (3 * 8)) |
((v & ((uint64_t)0xff << (4 * 8))) >> (1 * 8)) |
((v & ((uint64_t)0xff << (3 * 8))) << (1 * 8)) |
((v & ((uint64_t)0xff << (2 * 8))) << (3 * 8)) |
((v & ((uint64_t)0xff << (1 * 8))) << (5 * 8)) |
((v & ((uint64_t)0xff << (0 * 8))) << (7 * 8));
}
#endif

/* XXX: should take an extra argument to pass slack information to the caller */
typedef void *DynBufReallocFunc(void *opaque, void *ptr, size_t size);
Expand Down Expand Up @@ -278,6 +298,36 @@ static inline void dbuf_set_error(DynBuf *s)
int unicode_to_utf8(uint8_t *buf, unsigned int c);
int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp);

static inline BOOL is_surrogate(uint32_t c)
{
return (c >> 11) == (0xD800 >> 11); // 0xD800-0xDFFF
}

static inline BOOL is_hi_surrogate(uint32_t c)
{
return (c >> 10) == (0xD800 >> 10); // 0xD800-0xDBFF
}

static inline BOOL is_lo_surrogate(uint32_t c)
{
return (c >> 10) == (0xDC00 >> 10); // 0xDC00-0xDFFF
}

static inline uint32_t get_hi_surrogate(uint32_t c)
{
return (c >> 10) - (0x10000 >> 10) + 0xD800;
}

static inline uint32_t get_lo_surrogate(uint32_t c)
{
return (c & 0x3FF) | 0xDC00;
}

static inline uint32_t from_surrogate(uint32_t hi, uint32_t lo)
{
return 0x10000 + 0x400 * (hi - 0xD800) + (lo - 0xDC00);
}

static inline int from_hex(int c)
{
if (c >= '0' && c <= '9')
Expand All @@ -294,4 +344,80 @@ void rqsort(void *base, size_t nmemb, size_t size,
int (*cmp)(const void *, const void *, void *),
void *arg);

static inline uint64_t float64_as_uint64(double d)
{
union {
double d;
uint64_t u64;
} u;
u.d = d;
return u.u64;
}

static inline double uint64_as_float64(uint64_t u64)
{
union {
double d;
uint64_t u64;
} u;
u.u64 = u64;
return u.d;
}

static inline double fromfp16(uint16_t v)
{
double d;
uint32_t v1;
v1 = v & 0x7fff;
if (unlikely(v1 >= 0x7c00))
v1 += 0x1f8000; /* NaN or infinity */
d = uint64_as_float64(((uint64_t)(v >> 15) << 63) | ((uint64_t)v1 << (52 - 10)));
return d * 0x1p1008;
}

static inline uint16_t tofp16(double d)
{
uint64_t a, addend;
uint32_t v, sgn;
int shift;

a = float64_as_uint64(d);
sgn = a >> 63;
a = a & 0x7fffffffffffffff;
if (unlikely(a > 0x7ff0000000000000)) {
/* nan */
v = 0x7c01;
} else if (a < 0x3f10000000000000) { /* 0x1p-14 */
/* subnormal f16 number or zero */
if (a <= 0x3e60000000000000) { /* 0x1p-25 */
v = 0x0000; /* zero */
} else {
shift = 1051 - (a >> 52);
a = ((uint64_t)1 << 52) | (a & (((uint64_t)1 << 52) - 1));
addend = ((a >> shift) & 1) + (((uint64_t)1 << (shift - 1)) - 1);
v = (a + addend) >> shift;
}
} else {
/* normal number or infinity */
a -= 0x3f00000000000000; /* adjust the exponent */
/* round */
addend = ((a >> (52 - 10)) & 1) + (((uint64_t)1 << (52 - 11)) - 1);
v = (a + addend) >> (52 - 10);
/* overflow ? */
if (unlikely(v > 0x7c00))
v = 0x7c00;
}
return v | (sgn << 15);
}

static inline int isfp16nan(uint16_t v)
{
return (v & 0x7FFF) > 0x7C00;
}

static inline int isfp16zero(uint16_t v)
{
return (v & 0x7FFF) == 0;
}

#endif /* CUTILS_H */
Loading
Loading