diff --git a/quickjs/Makefile b/quickjs/Makefile new file mode 100644 index 000000000..10c014458 --- /dev/null +++ b/quickjs/Makefile @@ -0,0 +1,55 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=quickjs +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/bellard/quickjs.git +PKG_SOURCE_DATE:=2020-11-08 +PKG_SOURCE_VERSION:=204682fb87ab9312f0cf81f959ecd181180457bc +PKG_MIRROR_HASH:=skip +PKG_LICENSE:=MIT + +PKG_INSTALL:=1 +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/quickjs + SECTION:=lang + CATEGORY:=Languages + TITLE:=QuickJS Javascript engine + URL:=https://bellard.org/quickjs/ + MAINTAINER:=Erik Karlsson + DEPENDS:=+libatomic +endef + +define Package/quickjs/description + QuickJS is a small and embeddable Javascript engine. It supports + the ES2020 specification including modules, asynchronous + generators, proxies and BigInt. +endef + +MAKE_VARS += \ + LIBS="-latomic" + +MAKE_FLAGS = \ + prefix=/usr \ + CONFIG_SMALL=y \ + CROSS_PREFIX="$(TARGET_CROSS)" + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/lib/quickjs + $(CP) $(PKG_INSTALL_DIR)/usr/lib/quickjs/libquickjs.a $(1)/usr/lib/quickjs/ + $(CP) $(PKG_INSTALL_DIR)/usr/lib/quickjs/libquickjs.lto.a $(1)/usr/lib/quickjs/ + $(INSTALL_DIR) $(1)/usr/include/quickjs + $(CP) $(PKG_INSTALL_DIR)/usr/include/quickjs/quickjs.h $(1)/usr/include/quickjs/ + $(CP) $(PKG_INSTALL_DIR)/usr/include/quickjs/quickjs-libc.h $(1)/usr/include/quickjs/ +endef + +define Package/quickjs/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/qjs $(1)/usr/bin/ +endef + +$(eval $(call BuildPackage,quickjs)) diff --git a/quickjs/patches/000-build-options.patch b/quickjs/patches/000-build-options.patch new file mode 100644 index 000000000..3000ceb9c --- /dev/null +++ b/quickjs/patches/000-build-options.patch @@ -0,0 +1,96 @@ +diff --git a/Makefile b/Makefile +index e6ae827..bbd3ce8 100644 +--- a/Makefile ++++ b/Makefile +@@ -33,6 +33,8 @@ CONFIG_LTO=y + #CONFIG_WERROR=y + # force 32 bit build for some utilities + #CONFIG_M32=y ++# build with -Os instead of -O2 ++#CONFIG_SMALL=y + + ifdef CONFIG_DARWIN + # use clang instead of gcc +@@ -52,6 +54,13 @@ CONFIG_BIGNUM=y + + OBJDIR=.obj + ++CFLAGS_ENV:=$(CFLAGS) ++LDFLAGS_ENV:=$(LDFLAGS) ++ ++HOST_BUILD= ++CFLAGS=$(if $(HOST_BUILD),,$(CFLAGS_ENV)) ++LDFLAGS=$(if $(HOST_BUILD),,$(LDFLAGS_ENV)) ++ + ifdef CONFIG_WIN32 + ifdef CONFIG_M32 + CROSS_PREFIX=i686-w64-mingw32- +@@ -66,7 +75,7 @@ endif + ifdef CONFIG_CLANG + HOST_CC=clang + CC=$(CROSS_PREFIX)clang +- CFLAGS=-g -Wall -MMD -MF $(OBJDIR)/$(@F).d ++ CFLAGS += -g -Wall -MMD -MF $(OBJDIR)/$(@F).d + CFLAGS += -Wextra + CFLAGS += -Wno-sign-compare + CFLAGS += -Wno-missing-field-initializers +@@ -87,7 +96,7 @@ ifdef CONFIG_CLANG + else + HOST_CC=gcc + CC=$(CROSS_PREFIX)gcc +- CFLAGS=-g -Wall -MMD -MF $(OBJDIR)/$(@F).d ++ CFLAGS += -g -Wall -MMD -MF $(OBJDIR)/$(@F).d + CFLAGS += -Wno-array-bounds -Wno-format-truncation + ifdef CONFIG_LTO + AR=$(CROSS_PREFIX)gcc-ar +@@ -110,9 +119,13 @@ endif + CFLAGS+=$(DEFINES) + CFLAGS_DEBUG=$(CFLAGS) -O0 + CFLAGS_SMALL=$(CFLAGS) -Os ++ifdef CONFIG_SMALL ++CFLAGS_OPT=$(CFLAGS) -Os ++else + CFLAGS_OPT=$(CFLAGS) -O2 ++endif + CFLAGS_NOLTO:=$(CFLAGS_OPT) +-LDFLAGS=-g ++LDFLAGS+=-g + ifdef CONFIG_LTO + CFLAGS_SMALL+=-flto + CFLAGS_OPT+=-flto +@@ -175,7 +188,7 @@ QJS_OBJS+=$(OBJDIR)/qjscalc.o + endif + + HOST_LIBS=-lm -ldl -lpthread +-LIBS=-lm ++LIBS+=-lm + ifndef CONFIG_WIN32 + LIBS+=-ldl -lpthread + endif +@@ -194,6 +207,8 @@ qjsc$(EXE): $(OBJDIR)/qjsc.o $(QJS_LIB_OBJS) + + ifneq ($(CROSS_PREFIX),) + ++$(QJSC): HOST_BUILD=1 ++ + $(QJSC): $(OBJDIR)/qjsc.host.o \ + $(patsubst %.o, %.host.o, $(QJS_LIB_OBJS)) + $(HOST_CC) $(LDFLAGS) -o $@ $^ $(HOST_LIBS) +@@ -261,6 +276,8 @@ run-test262-32: $(patsubst %.o, %.m32.o, $(OBJDIR)/run-test262.o $(QJS_LIB_OBJS) + $(OBJDIR)/%.o: %.c | $(OBJDIR) + $(CC) $(CFLAGS_OPT) -c -o $@ $< + ++$(OBJDIR)/%.host.o: HOST_BUILD=1 ++ + $(OBJDIR)/%.host.o: %.c | $(OBJDIR) + $(HOST_CC) $(CFLAGS_OPT) -c -o $@ $< + +@@ -285,6 +302,8 @@ $(OBJDIR)/%.check.o: %.c | $(OBJDIR) + regexp_test: libregexp.c libunicode.c cutils.c + $(CC) $(LDFLAGS) $(CFLAGS) -DTEST -o $@ libregexp.c libunicode.c cutils.c $(LIBS) + ++unicode_gen: HOST_BUILD=1 ++ + unicode_gen: $(OBJDIR)/unicode_gen.host.o $(OBJDIR)/cutils.host.o libunicode.c unicode_gen_def.h + $(HOST_CC) $(LDFLAGS) $(CFLAGS) -o $@ $(OBJDIR)/unicode_gen.host.o $(OBJDIR)/cutils.host.o + diff --git a/quickjs/patches/001-no-fenv-dtoa-libbf.patch b/quickjs/patches/001-no-fenv-dtoa-libbf.patch new file mode 100644 index 000000000..57f4e7531 --- /dev/null +++ b/quickjs/patches/001-no-fenv-dtoa-libbf.patch @@ -0,0 +1,106 @@ +diff --git a/quickjs.c b/quickjs.c +index a39ff8f..635c506 100644 +--- a/quickjs.c ++++ b/quickjs.c +@@ -65,6 +65,16 @@ + #define CONFIG_PRINTF_RNDN + #endif + ++#ifdef CONFIG_PRINTF_RNDN ++#if !defined(FE_DOWNWARD) || !defined(FE_UPWARD) ++#ifdef CONFIG_BIGNUM ++#define CONFIG_DTOA_LIBBF ++#else ++#error "CONFIG_BIGNUM required if printf is RNDN and there is no fenv support" ++#endif ++#endif ++#endif ++ + /* define to include Atomics.* operations which depend on the OS + threads */ + #if !defined(EMSCRIPTEN) +@@ -11253,6 +11263,11 @@ static char *i64toa(char *buf_end, int64_t n, unsigned int base) + return q; + } + ++/* maximum buffer size for js_dtoa */ ++#define JS_DTOA_BUF_SIZE 128 ++ ++#ifndef CONFIG_DTOA_LIBBF ++ + /* buf1 contains the printf result */ + static void js_ecvt1(double d, int n_digits, int *decpt, int *sign, char *buf, + int rounding_mode, char *buf1, int buf1_size) +@@ -11272,9 +11287,6 @@ static void js_ecvt1(double d, int n_digits, int *decpt, int *sign, char *buf, + *decpt = atoi(buf1 + n_digits + 2 + (n_digits > 1)) + 1; + } + +-/* maximum buffer size for js_dtoa */ +-#define JS_DTOA_BUF_SIZE 128 +- + /* needed because ecvt usually limits the number of digits to + 17. Return the number of digits. */ + static int js_ecvt(double d, int n_digits, int *decpt, int *sign, char *buf, +@@ -11383,6 +11395,8 @@ static void js_fcvt(char *buf, int buf_size, double d, int n_digits) + js_fcvt1(buf, buf_size, d, n_digits, rounding_mode); + } + ++#endif /* CONFIG_DTOA_LIBBF */ ++ + /* radix != 10 is only supported with flags = JS_DTOA_VAR_FORMAT */ + /* use as many digits as necessary */ + #define JS_DTOA_VAR_FORMAT (0 << 0) +@@ -11396,8 +11410,10 @@ static void js_fcvt(char *buf, int buf_size, double d, int n_digits) + /* XXX: slow and maybe not fully correct. Use libbf when it is fast enough. + XXX: radix != 10 is only supported for small integers + */ +-static void js_dtoa1(char *buf, double d, int radix, int n_digits, int flags) ++static JSValue js_dtoa(JSContext *ctx, ++ double d, int radix, int n_digits, int flags) + { ++ char buf[JS_DTOA_BUF_SIZE]; + char *q; + + if (!isfinite(d)) { +@@ -11419,6 +11435,25 @@ static void js_dtoa1(char *buf, double d, int radix, int n_digits, int flags) + ptr = i64toa(buf1 + sizeof(buf1), i64, radix); + strcpy(buf, ptr); + } else { ++#ifdef CONFIG_DTOA_LIBBF ++ bf_flags_t bf_flags; ++ generic_conv: ++ bf_flags = BF_RNDNA; ++ switch (flags & 3) { ++ case JS_DTOA_VAR_FORMAT: ++ bf_flags |= BF_FTOA_FORMAT_FREE_MIN; ++ break; ++ case JS_DTOA_FIXED_FORMAT: ++ bf_flags |= BF_FTOA_FORMAT_FIXED; ++ break; ++ case JS_DTOA_FRAC_FORMAT: ++ bf_flags |= BF_FTOA_FORMAT_FRAC; ++ break; ++ } ++ if (flags & JS_DTOA_FORCE_EXP) ++ bf_flags |= BF_FTOA_FORCE_EXP; ++ return js_ftoa(ctx, JS_NewFloat64(ctx, d), radix, n_digits, bf_flags); ++#else /* CONFIG_DTOA_LIBBF */ + if (d == 0.0) + d = 0.0; /* convert -0 to 0 */ + if (flags == JS_DTOA_FRAC_FORMAT) { +@@ -11482,14 +11517,8 @@ static void js_dtoa1(char *buf, double d, int radix, int n_digits, int flags) + sprintf(q, "%d", p); + } + } ++#endif /* CONFIG_DTOA_LIBBF */ + } +-} +- +-static JSValue js_dtoa(JSContext *ctx, +- double d, int radix, int n_digits, int flags) +-{ +- char buf[JS_DTOA_BUF_SIZE]; +- js_dtoa1(buf, d, radix, n_digits, flags); + return JS_NewString(ctx, buf); + } +