summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2014-03-20 14:13:06 +0100
committerRobin Watts <robin.watts@artifex.com>2014-03-25 16:44:41 +0000
commitdb6353067cf545f4ca6fd854c8e8b4c4145dc537 (patch)
treec06d40f931c33ff335b474412392896a685657e6
parent332fb2e7033f3376fcdcfe0762e15ce78d221fbc (diff)
downloadmupdf-db6353067cf545f4ca6fd854c8e8b4c4145dc537.tar.xz
Add MuJS submodule, implementation and build.
Adds simpler choice of Javascript library to makefiles. Will prefer in order: MuJS, JavaScriptCore, V8, none based on HAVE_MUJS, HAVE_JSCORE, and HAVE_V8. For simplicity, we build mujstest even with no javascript implementation.
-rw-r--r--.gitmodules3
-rw-r--r--Makefile83
-rw-r--r--Makerules9
-rw-r--r--Makethird53
-rw-r--r--source/pdf/js/pdf-jsimp-mu.c322
m---------thirdparty/mujs0
6 files changed, 403 insertions, 67 deletions
diff --git a/.gitmodules b/.gitmodules
index 9b1c5506..186e0b02 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,9 @@
[submodule "thirdparty/jbig2dec"]
path = thirdparty/jbig2dec
url = git://git.ghostscript.com/jbig2dec.git
+[submodule "thirdparty/mujs"]
+ path = thirdparty/mujs
+ url = git://git.ghostscript.com/mujs.git
[submodule "thirdparty/freetype"]
path = thirdparty/freetype
url = git://git.ghostscript.com/thirdparty/freetype.git
diff --git a/Makefile b/Makefile
index be650cc3..7ab1ec60 100644
--- a/Makefile
+++ b/Makefile
@@ -41,7 +41,7 @@ CFLAGS += $(ZLIB_CFLAGS)
# --- Commands ---
-ifeq "$(verbose)" ""
+ifneq "$(verbose)" "yes"
QUIET_AR = @ echo ' ' ' ' AR $@ ;
QUIET_CC = @ echo ' ' ' ' CC $@ ;
QUIET_CXX = @ echo ' ' ' ' CXX $@ ;
@@ -97,9 +97,27 @@ CBZ_OBJ := $(subst source/, $(OUT)/, $(addsuffix .o, $(basename $(CBZ_SRC))))
IMG_OBJ := $(subst source/, $(OUT)/, $(addsuffix .o, $(basename $(IMG_SRC))))
TIFF_OBJ := $(subst source/, $(OUT)/, $(addsuffix .o, $(basename $(TIFF_SRC))))
-PDF_JS_JSCORE_OBJ := $(OUT)/pdf/js/pdf-js.o $(OUT)/pdf/js/pdf-jsimp-jscore.o
-PDF_JS_V8_OBJ := $(OUT)/pdf/js/pdf-js.o $(OUT)/pdf/js/pdf-jsimp-cpp.o $(OUT)/pdf/js/pdf-jsimp-v8.o
-PDF_JS_NONE_OBJ := $(OUT)/pdf/js/pdf-js-none.o
+# --- Choice of Javascript library ---
+
+ifeq "$(HAVE_MUJS)" "yes"
+PDF_OBJ += $(OUT)/pdf/js/pdf-js.o
+PDF_OBJ += $(OUT)/pdf/js/pdf-jsimp-mu.o
+THIRD_LIBS += $(MUJS_LIB)
+LIBS += $(MUJS_LIBS)
+CFLAGS += $(MUJS_CFLAGS)
+else ifeq "$(HAVE_JSCORE)" "yes"
+PDF_OBJ += $(OUT)/pdf/js/pdf-js.o
+PDF_OBJ += $(OUT)/pdf/js/pdf-jsimp-jscore.o
+LIBS += $(JSCORE_LIBS)
+CFLAGS += $(JSCORE_CFLAGS)
+else ifeq "$(HAVE_V8)" "yes"
+PDF_OBJ += $(OUT)/pdf/js/pdf-js.o
+PDF_OBJ += $(OUT)/pdf/js/pdf-jsimp-cpp.o $(OUT)/pdf/js/pdf-jsimp-v8.o
+LIBS += $(V8_LIBS)
+CFLAGS += $(V8_CFLAGS)
+else
+PDF_OBJ += $(OUT)/pdf/js/pdf-js-none.o
+endif
$(FITZ_OBJ) : $(FITZ_HDR) $(FITZ_SRC_HDR)
$(PDF_OBJ) : $(FITZ_HDR) $(PDF_HDR) $(PDF_SRC_HDR)
@@ -108,29 +126,13 @@ $(CBZ_OBJ) : $(FITZ_HDR) $(CBZ_HDR) $(CBZ_SRC_HDR)
$(IMG_OBJ) : $(FITZ_HDR) $(IMG_HDR) $(IMG_SRC_HDR)
$(TIFF_OBJ) : $(FITZ_HDR) $(IMG_HDR) $(TIFF_SRC_HDR)
-$(PDF_JS_JSCORE_OBJ) : $(FITZ_HDR) $(PDF_HDR) $(PDF_SRC_HDR)
-$(PDF_JS_V8_OBJ) : $(FITZ_HDR) $(PDF_HDR) $(PDF_SRC_HDR)
-$(PDF_JS_NONE_OBJ) := $(FITZ_HDR) $(PDF_HDR) $(PDF_SRC_HDR)
-
# --- Library ---
MUPDF_LIB := $(OUT)/libmupdf.a
-MUPDF_JS_NONE_LIB := $(OUT)/libmupdf-js-none.a
$(MUPDF_LIB) : $(FITZ_OBJ) $(PDF_OBJ) $(XPS_OBJ) $(CBZ_OBJ) $(IMG_OBJ) $(TIFF_OBJ)
-$(MUPDF_JS_NONE_LIB) : $(PDF_JS_NONE_OBJ)
-
-ifeq "$(V8_PRESENT)" "yes"
-MUPDF_JS_V8_LIB := $(OUT)/libmupdf-js-v8.a
-$(MUPDF_JS_V8_LIB) : $(PDF_JS_V8_OBJ)
-endif
-
-ifeq "$(JSCORE_PRESENT)" "yes"
-MUPDF_JS_JSCORE_LIB := $(OUT)/libmupdf-js-jscore.a
-$(MUPDF_JS_JSCORE_LIB) : $(PDF_JS_JSCORE_OBJ)
-endif
-INSTALL_LIBS := $(MUPDF_LIB) $(MUPDF_JS_NONE_LIB) $(MUPDF_JS_V8_LIB) $(MUPDF_JS_JSCORE_LIB)
+INSTALL_LIBS := $(MUPDF_LIB)
# --- Rules ---
@@ -211,7 +213,7 @@ ADOBECA_GEN := $(GEN)/gen_adobe_ca.h
$(ADOBECA_GEN) : $(ADOBECA_SRC)
$(QUIET_GEN) $(BIN2HEX) $@ $(ADOBECA_SRC)
-ifeq "$(CROSSCOMPILE)" ""
+ifneq "$(CROSSCOMPILE)" "yes"
$(CMAP_GEN) : $(CMAPDUMP) | $(GEN)
$(FONT_GEN) : $(FONTDUMP) | $(GEN)
$(JAVASCRIPT_GEN) : $(CQUOTE) | $(GEN)
@@ -231,52 +233,40 @@ $(OUT)/cmapdump.o : source/pdf/pdf-cmap.c source/pdf/pdf-cmap-parse.c
MUDRAW := $(addprefix $(OUT)/, mudraw)
MUDRAW_OBJ := $(addprefix $(OUT)/tools/, mudraw.o)
$(MUDRAW_OBJ) : $(FITZ_HDR)
-$(MUDRAW) : $(MUPDF_LIB) $(MUPDF_JS_NONE_LIB) $(THIRD_LIBS)
+$(MUDRAW) : $(MUPDF_LIB) $(THIRD_LIBS)
$(MUDRAW) : $(MUDRAW_OBJ)
$(LINK_CMD)
MUTOOL := $(addprefix $(OUT)/, mutool)
MUTOOL_OBJ := $(addprefix $(OUT)/tools/, mutool.o pdfclean.o pdfextract.o pdfinfo.o pdfposter.o pdfshow.o)
$(MUTOOL_OBJ): $(FITZ_HDR) $(PDF_HDR)
-$(MUTOOL) : $(MUPDF_LIB) $(MUPDF_JS_NONE_LIB) $(THIRD_LIBS)
+$(MUTOOL) : $(MUPDF_LIB) $(THIRD_LIBS)
$(MUTOOL) : $(MUTOOL_OBJ)
$(LINK_CMD)
-ifeq "$(V8_PRESENT)" "yes"
-MUJSTEST_V8 := $(OUT)/mujstest-v8
-$(MUJSTEST_V8) : $(MUPDF_LIB) $(MUPDF_JS_V8_LIB) $(THIRD_LIBS)
-$(MUJSTEST_V8) : $(addprefix $(OUT)/platform/x11/, jstest_main.o pdfapp.o)
- $(LINK_CMD) $(V8_LIBS)
-endif
+MUJSTEST := $(OUT)/mujstest
+$(MUJSTEST) : $(MUPDF_LIB) $(THIRD_LIBS)
+$(MUJSTEST) : $(addprefix $(OUT)/platform/x11/, jstest_main.o pdfapp.o)
+ $(LINK_CMD)
-ifeq "$(NOX11)" ""
+ifeq "$(HAVE_X11)" "yes"
MUVIEW_X11 := $(OUT)/mupdf-x11
-$(MUVIEW_X11) : $(MUPDF_LIB) $(MUPDF_JS_NONE_LIB) $(THIRD_LIBS)
+$(MUVIEW_X11) : $(MUPDF_LIB) $(THIRD_LIBS)
$(MUVIEW_X11) : $(addprefix $(OUT)/platform/x11/, x11_main.o x11_image.o pdfapp.o)
$(LINK_CMD) $(X11_LIBS)
-ifeq "$(NOCURL)" ""
+ifeq "$(HAVE_CURL)" "yes"
MUVIEW_X11_CURL := $(OUT)/mupdf-x11-curl
-$(MUVIEW_X11_CURL) : $(MUPDF_LIB) $(MUPDF_JS_NONE_LIB) $(THIRD_LIBS) $(CURL_LIB)
+$(MUVIEW_X11_CURL) : $(MUPDF_LIB) $(THIRD_LIBS) $(CURL_LIB)
$(MUVIEW_X11_CURL) : $(addprefix $(OUT)/platform/x11/curl/, x11_main.o x11_image.o pdfapp.o curl_stream.o)
$(LINK_CMD) $(X11_LIBS) $(CURL_LIBS)
endif
endif
-ifeq "$(V8_PRESENT)" "yes"
-ifeq "$(NOX11)" ""
-MUVIEW_X11_V8 := $(OUT)/mupdf-x11-v8
-$(MUVIEW_X11_V8) : $(MUPDF_LIB) $(MUPDF_JS_V8_LIB) $(THIRD_LIBS)
-$(MUVIEW_X11_V8) : $(addprefix $(OUT)/platform/x11/, x11_main.o x11_image.o pdfapp.o)
- $(LINK_CMD) $(X11_LIBS) $(V8_LIBS)
-endif
-endif
-
MUVIEW := $(MUVIEW_X11)
-MUVIEW_V8 := $(MUVIEW_X11_V8)
MUVIEW_CURL := $(MUVIEW_X11_CURL)
-INSTALL_APPS := $(MUDRAW) $(MUTOOL) $(MUVIEW) $(MUJSTEST_V8) $(MUVIEW_V8) $(MUVIEW_CURL)
+INSTALL_APPS := $(MUDRAW) $(MUTOOL) $(MUVIEW) $(MUJSTEST) $(MUVIEW_CURL)
# --- Update version string header ---
@@ -338,9 +328,6 @@ tags: $(shell find include source platform -name '*.[ch]')
all: libs apps
-all-nojs:
- $(MAKE) V8_PRESENT=no
-
clean:
rm -rf $(OUT)
nuke:
diff --git a/Makerules b/Makerules
index e52571ec..682160c7 100644
--- a/Makerules
+++ b/Makerules
@@ -27,10 +27,12 @@ endif
# Windows (MINGW) build doesn't use system libraries.
ifeq "$(OS)" "MINGW"
-NOX11 ?= yes
# Mac OS X doesn't have pkg-config so we hard code paths.
else ifeq "$(OS)" "MACOS"
+
+HAVE_X11 ?= yes
+
SYS_OPENSSL_CFLAGS = -DHAVE_OPENSSL
SYS_OPENSSL_LIBS = -lcrypto
@@ -54,6 +56,8 @@ RANLIB_CMD = xcrun ranlib $@
# Linux uses pkg-config for system libraries.
else ifeq "$(OS)" "Linux"
+HAVE_X11 ?= yes
+
ifeq "$(shell pkg-config --exists libcrypto && echo yes)" "yes"
SYS_OPENSSL_CFLAGS = -DHAVE_OPENSSL $(shell pkg-config --cflags libcrypto)
SYS_OPENSSL_LIBS = $(shell pkg-config --libs libcrypto)
@@ -138,6 +142,7 @@ RANLIB_CMD = xcrun ranlib $@
CROSSCOMPILE=yes
endif
+# TODO: If crosscompiling, why not just call "make libs" instead of this exception?
ifeq "$(CROSSCOMPILE)" "yes"
-NOX11 ?= yes
+HAVE_X11 ?= no
endif
diff --git a/Makethird b/Makethird
index cc7478c2..123d5509 100644
--- a/Makethird
+++ b/Makethird
@@ -9,6 +9,7 @@
FREETYPE_DIR := thirdparty/freetype
JBIG2DEC_DIR := thirdparty/jbig2dec
JPEG_DIR := thirdparty/jpeg
+MUJS_DIR := thirdparty/mujs
OPENJPEG_DIR := thirdparty/openjpeg/libopenjpeg
OPENSSL_DIR := thirdparty/openssl
ZLIB_DIR := thirdparty/zlib
@@ -23,7 +24,6 @@ V8_DIR := $(wildcard thirdparty/v8*)
ifneq "$(V8_DIR)" ""
-CFLAGS += -I$(V8_DIR)/include
ifeq "$(build)" "release"
V8_LIB_CHOICE := release
else ifeq "$(build)" "profile"
@@ -36,14 +36,33 @@ V8_ARCH ?= x64
# If you are building for 32bit linux use V8_ARCH=ia32
ifeq "$(OS)" "Darwin"
-V8_LIBS = -L$(V8_DIR)/out-mac/$(V8_ARCH).$(V8_LIB_CHOICE)/ -lv8_base -lv8_snapshot -lstdc++
+V8_LIBS := -L$(V8_DIR)/out-mac/$(V8_ARCH).$(V8_LIB_CHOICE)/ -lv8_base -lv8_snapshot -lstdc++
else
-V8_LIBS = -L$(V8_DIR)/out/$(V8_ARCH).$(V8_LIB_CHOICE)/obj.target/tools/gyp -lv8_base -lv8_snapshot -lpthread -ldl -lstdc++
+V8_LIBS := -L$(V8_DIR)/out/$(V8_ARCH).$(V8_LIB_CHOICE)/obj.target/tools/gyp -lv8_base -lv8_snapshot -lpthread -ldl -lstdc++
endif
-V8_PRESENT := yes
-else
-V8_PRESENT := no
+V8_CFLAGS := -I$(V8_DIR)/include
+
+HAVE_V8 := yes
+endif
+
+# --- MuJS ---
+
+ifneq "$(wildcard $(MUJS_DIR)/README)" ""
+
+MUJS_LIB := $(OUT)/libmujs.a
+MUJS_OUT := $(OUT)/mujs
+MUJS_SRC := one.c
+
+$(MUJS_LIB): $(addprefix $(MUJS_OUT)/, $(MUJS_SRC:%.c=%.o))
+$(MUJS_OUT):
+ $(MKDIR_CMD)
+$(MUJS_OUT)/%.o: $(MUJS_DIR)/%.c | $(MUJS_OUT)
+ $(CC_CMD)
+
+MUJS_CFLAGS := -I$(MUJS_DIR)
+
+HAVE_MUJS := yes
endif
# --- FreeType 2 ---
@@ -302,16 +321,6 @@ OPENSSL_CFLAGS := $(SYS_OPENSSL_CFLAGS)
OPENSSL_LIBS := $(SYS_OPENSSL_LIBS)
endif
-# --- X11 ---
-
-ifeq "$(NOX11)" ""
-X11_CFLAGS := $(SYS_X11_CFLAGS)
-X11_LIBS := $(SYS_X11_LIBS)
-else
-X11_CFLAGS :=
-X11_LIBS :=
-endif
-
# --- cURL ---
ifneq "$(wildcard $(CURL_DIR)/README)" ""
@@ -443,6 +452,16 @@ $(CURL_OUT)/%.o: $(CURL_DIR)/lib/%.c | $(CURL_OUT)
CURL_CFLAGS := -I$(CURL_DIR)/include
CURL_LIBS := $(SYS_CURL_DEPS)
+
+HAVE_CURL := yes
+endif
+
+# --- X11 ---
+
+ifeq "$(HAVE_X11)" "yes"
+X11_CFLAGS := $(SYS_X11_CFLAGS)
+X11_LIBS := $(SYS_X11_LIBS)
else
-NOCURL := yes
+X11_CFLAGS :=
+X11_LIBS :=
endif
diff --git a/source/pdf/js/pdf-jsimp-mu.c b/source/pdf/js/pdf-jsimp-mu.c
new file mode 100644
index 00000000..9a02aea3
--- /dev/null
+++ b/source/pdf/js/pdf-jsimp-mu.c
@@ -0,0 +1,322 @@
+#include "mupdf/pdf.h"
+
+#include <mujs.h>
+
+#define MAXARGS 16
+
+#define OBJ(i) ((pdf_jsimp_obj*)((intptr_t)(i)))
+#define IDX(p) ((intptr_t)(p))
+#define NEWOBJ(J,x) OBJ(js_gettop(J) + (x))
+
+struct pdf_jsimp_s
+{
+ fz_context *ctx;
+ void *jsctx;
+ js_State *J;
+};
+
+static void *alloc(void *ud, void *ptr, unsigned int n)
+{
+ fz_context *ctx = ud;
+ if (n == 0) {
+ fz_free(ctx, ptr);
+ return NULL;
+ }
+ if (ptr)
+ return fz_resize_array(ctx, ptr, n, 1);
+ return fz_malloc_array(ctx, n, 1);
+}
+
+pdf_jsimp *pdf_new_jsimp(fz_context *ctx, void *jsctx)
+{
+ js_State *J;
+ pdf_jsimp *imp;
+
+ J = js_newstate(alloc, ctx);
+
+ js_pushnull(J); /* prototype for jsctx userdata object */
+ js_newuserdata(J, "jsctx", jsctx); /* create jsctx userdata object */
+ js_setregistry(J, "jsctx"); /* hide it in the registry */
+
+ imp = fz_malloc_struct(ctx, pdf_jsimp);
+ imp->ctx = ctx;
+ imp->jsctx = jsctx;
+ imp->J = J;
+ return imp;
+}
+
+void pdf_drop_jsimp(pdf_jsimp *imp)
+{
+ if (imp)
+ {
+ js_freestate(imp->J);
+ fz_free(imp->ctx, imp);
+ }
+}
+
+pdf_jsimp_type *pdf_jsimp_new_type(pdf_jsimp *imp, pdf_jsimp_dtr *dtr, char *name)
+{
+ js_State *J = imp->J;
+ js_newobject(J);
+ js_setregistry(J, name);
+ return (pdf_jsimp_type*)name;
+}
+
+void pdf_jsimp_drop_type(pdf_jsimp *imp, pdf_jsimp_type *type)
+{
+ if (imp && type)
+ {
+ js_State *J = imp->J;
+ js_delregistry(J, (const char *)type);
+ }
+}
+
+static void wrapmethod(js_State *J)
+{
+ pdf_jsimp_obj *args[MAXARGS];
+ pdf_jsimp_obj *ret;
+ pdf_jsimp_method *meth;
+ const char *type;
+ void *jsctx;
+ void *obj;
+ int i;
+
+ int argc = js_gettop(J) - 1;
+
+ js_getregistry(J, "jsctx");
+ jsctx = js_touserdata(J, "jsctx", -1);
+ js_pop(J, 1);
+
+ js_currentfunction(J);
+ {
+ js_getproperty(J, -1, "__call");
+ meth = js_touserdata(J, "method", -1);
+ js_pop(J, 1);
+
+ js_getproperty(J, -1, "__type");
+ type = js_tostring(J, -1);
+ js_pop(J, 1);
+ }
+ js_pop(J, 1);
+
+ if (js_isuserdata(J, type, 0))
+ obj = js_touserdata(J, type, 0);
+ else
+ obj = NULL;
+
+ if (argc > MAXARGS)
+ js_rangeerror(J, "too many arguments");
+
+ for (i = 0; i < argc; ++i)
+ args[i] = OBJ(i+1);
+ ret = meth(jsctx, obj, argc, args);
+ if (ret)
+ js_copy(J, IDX(ret));
+ else
+ js_pushundefined(J);
+}
+
+static void wrapgetter(js_State *J)
+{
+ pdf_jsimp_obj *ret;
+ pdf_jsimp_getter *get;
+ const char *type;
+ void *jsctx;
+ void *obj;
+
+ js_getregistry(J, "jsctx");
+ jsctx = js_touserdata(J, "jsctx", -1);
+ js_pop(J, 1);
+
+ js_currentfunction(J);
+ {
+ js_getproperty(J, -1, "__get");
+ get = js_touserdata(J, "getter", -1);
+ js_pop(J, 1);
+
+ js_getproperty(J, -1, "__type");
+ type = js_tostring(J, -1);
+ js_pop(J, 1);
+ }
+ js_pop(J, 1);
+
+ if (js_isuserdata(J, type, 0))
+ obj = js_touserdata(J, type, 0);
+ else
+ obj = NULL;
+
+ ret = get(jsctx, obj);
+ if (ret)
+ js_copy(J, IDX(ret));
+ else
+ js_pushundefined(J);
+}
+
+static void wrapsetter(js_State *J)
+{
+ pdf_jsimp_setter *set;
+ const char *type;
+ void *jsctx;
+ void *obj;
+
+ js_getregistry(J, "jsctx");
+ jsctx = js_touserdata(J, "jsctx", -1);
+ js_pop(J, 1);
+
+ js_currentfunction(J);
+ {
+ js_getproperty(J, -1, "__set");
+ set = js_touserdata(J, "setter", -1);
+ js_pop(J, 1);
+
+ js_getproperty(J, -1, "__type");
+ type = js_tostring(J, -1);
+ js_pop(J, 1);
+ }
+ js_pop(J, 1);
+
+ if (js_isuserdata(J, type, 0))
+ obj = js_touserdata(J, type, 0);
+ else
+ obj = NULL;
+
+ set(jsctx, obj, OBJ(1));
+
+ js_pushundefined(J);
+}
+
+void pdf_jsimp_addmethod(pdf_jsimp *imp, pdf_jsimp_type *type, char *name, pdf_jsimp_method *meth)
+{
+ js_State *J = imp->J;
+ js_getregistry(J, (const char *)type);
+ {
+ js_newcfunction(J, wrapmethod, 0);
+ {
+ js_pushnull(J);
+ js_newuserdata(J, "method", meth);
+ js_defproperty(J, -2, "__call", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
+ js_pushstring(J, (const char *)type);
+ js_defproperty(J, -2, "__type", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
+ }
+ js_defproperty(J, -2, name, JS_READONLY | JS_DONTENUM | JS_DONTCONF);
+ }
+ js_pop(J, 1);
+}
+
+void pdf_jsimp_addproperty(pdf_jsimp *imp, pdf_jsimp_type *type, char *name, pdf_jsimp_getter *get, pdf_jsimp_setter *set)
+{
+ js_State *J = imp->J;
+ js_getregistry(J, (const char *)type);
+ {
+ js_newcfunction(J, wrapgetter, 0);
+ {
+ js_pushnull(J);
+ js_newuserdata(J, "getter", get);
+ js_defproperty(J, -2, "__get", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
+ js_pushstring(J, (const char *)type);
+ js_defproperty(J, -2, "__type", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
+ }
+ js_newcfunction(J, wrapsetter, 0);
+ {
+ js_pushnull(J);
+ js_newuserdata(J, "setter", set);
+ js_defproperty(J, -2, "__set", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
+ js_pushstring(J, (const char *)type);
+ js_defproperty(J, -2, "__type", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
+ }
+ js_defaccessor(J, -3, name, JS_READONLY | JS_DONTENUM | JS_DONTCONF);
+ }
+ js_pop(J, 1);
+}
+
+void pdf_jsimp_set_global_type(pdf_jsimp *imp, pdf_jsimp_type *type)
+{
+ js_State *J = imp->J;
+ js_getregistry(J, (const char *)type);
+ js_setglobal(J, "global");
+ js_dostring(J, "Object.getOwnPropertyNames(global).forEach(function(k){this[k]=global[k]}, this)", 0);
+ js_dostring(J, "delete global", 0);
+}
+
+pdf_jsimp_obj *pdf_jsimp_new_obj(pdf_jsimp *imp, pdf_jsimp_type *type, void *natobj)
+{
+ js_State *J = imp->J;
+ js_getregistry(J, (const char *)type);
+ js_newuserdata(J, (const char *)type, natobj);
+ return NEWOBJ(J, -1);
+}
+
+void pdf_jsimp_drop_obj(pdf_jsimp *imp, pdf_jsimp_obj *obj)
+{
+}
+
+int pdf_jsimp_to_type(pdf_jsimp *imp, pdf_jsimp_obj *obj)
+{
+ js_State *J = imp->J;
+ if (js_isnull(J, IDX(obj))) return JS_TYPE_NULL;
+ if (js_isboolean(J, IDX(obj))) return JS_TYPE_BOOLEAN;
+ if (js_isnumber(J, IDX(obj))) return JS_TYPE_NUMBER;
+ if (js_isstring(J, IDX(obj))) return JS_TYPE_STRING;
+ if (js_isarray(J, IDX(obj))) return JS_TYPE_ARRAY;
+ return JS_TYPE_UNKNOWN;
+}
+
+pdf_jsimp_obj *pdf_jsimp_from_string(pdf_jsimp *imp, char *str)
+{
+ js_State *J = imp->J;
+ js_pushstring(J, str);
+ return NEWOBJ(J, -1);
+}
+
+char *pdf_jsimp_to_string(pdf_jsimp *imp, pdf_jsimp_obj *obj)
+{
+ /* cast away const :( */
+ return (char*)js_tostring(imp->J, IDX(obj));
+}
+
+pdf_jsimp_obj *pdf_jsimp_from_number(pdf_jsimp *imp, double num)
+{
+ js_State *J = imp->J;
+ js_pushnumber(J, num);
+ return NEWOBJ(J, -1);
+}
+
+double pdf_jsimp_to_number(pdf_jsimp *imp, pdf_jsimp_obj *obj)
+{
+ return js_tonumber(imp->J, IDX(obj));
+}
+
+int pdf_jsimp_array_len(pdf_jsimp *imp, pdf_jsimp_obj *obj)
+{
+ js_State *J = imp->J;
+ return js_getlength(J, IDX(obj));
+}
+
+pdf_jsimp_obj *pdf_jsimp_array_item(pdf_jsimp *imp, pdf_jsimp_obj *obj, int i)
+{
+ js_State *J = imp->J;
+ js_getindex(J, IDX(obj), i);
+ return NEWOBJ(J, -1);
+}
+
+pdf_jsimp_obj *pdf_jsimp_property(pdf_jsimp *imp, pdf_jsimp_obj *obj, char *prop)
+{
+ js_State *J = imp->J;
+ js_getproperty(J, IDX(obj), prop);
+ return NEWOBJ(J, -1);
+}
+
+void pdf_jsimp_execute(pdf_jsimp *imp, char *code)
+{
+ js_State *J = imp->J;
+ js_dostring(J, code, 0);
+}
+
+void pdf_jsimp_execute_count(pdf_jsimp *imp, char *code, int count)
+{
+ char *terminated = fz_malloc(imp->ctx, count+1);
+ memcpy(terminated, code, count);
+ terminated[count] = 0;
+ pdf_jsimp_execute(imp, terminated);
+ fz_free(imp->ctx, terminated);
+}
diff --git a/thirdparty/mujs b/thirdparty/mujs
new file mode 160000
+Subproject 546f0330a832eb382fe0f6197c90fd21074b5ed