7 #define OBJ(i) ((pdf_jsimp_obj*)((intptr_t)(i)))
8 #define IDX(p) ((intptr_t)(p))
9 #define NEWOBJ(J,x) OBJ(js_gettop(J) + (x))
18 static void *alloc(void *ud, void *ptr, unsigned int n)
26 return fz_resize_array(ctx, ptr, n, 1);
27 return fz_malloc_array(ctx, n, 1);
30 pdf_jsimp *pdf_new_jsimp(fz_context *ctx, void *jsctx)
35 J = js_newstate(alloc, ctx, 0);
36 js_setcontext(J, jsctx);
38 imp = fz_malloc_struct(ctx, pdf_jsimp);
45 void pdf_drop_jsimp(pdf_jsimp *imp)
50 fz_free(imp->ctx, imp);
54 pdf_jsimp_type *pdf_jsimp_new_type(pdf_jsimp *imp, pdf_jsimp_dtr *dtr, char *name)
58 js_setregistry(J, name);
59 return (pdf_jsimp_type*)name;
62 void pdf_jsimp_drop_type(pdf_jsimp *imp, pdf_jsimp_type *type)
67 js_delregistry(J, (const char *)type);
71 static void wrapmethod(js_State *J)
73 pdf_jsimp_obj *args[MAXARGS];
75 pdf_jsimp_method *meth;
81 int argc = js_gettop(J) - 1;
83 jsctx = js_getcontext(J);
85 js_currentfunction(J);
87 js_getproperty(J, -1, "__call");
88 meth = js_touserdata(J, -1, "method");
91 js_getproperty(J, -1, "__type");
92 type = js_tostring(J, -1);
97 if (js_isuserdata(J, 0, type))
98 obj = js_touserdata(J, 0, type);
103 js_rangeerror(J, "too many arguments");
105 for (i = 0; i < argc; ++i)
107 ret = meth(jsctx, obj, argc, args);
109 js_copy(J, IDX(ret));
114 static void wrapgetter(js_State *J)
117 pdf_jsimp_getter *get;
122 jsctx = js_getcontext(J);
124 js_currentfunction(J);
126 js_getproperty(J, -1, "__get");
127 get = js_touserdata(J, -1, "getter");
130 js_getproperty(J, -1, "__type");
131 type = js_tostring(J, -1);
136 if (js_isuserdata(J, 0, type))
137 obj = js_touserdata(J, 0, type);
141 ret = get(jsctx, obj);
143 js_copy(J, IDX(ret));
148 static void wrapsetter(js_State *J)
150 pdf_jsimp_setter *set;
155 jsctx = js_getcontext(J);
157 js_currentfunction(J);
159 js_getproperty(J, -1, "__set");
160 set = js_touserdata(J, -1, "setter");
163 js_getproperty(J, -1, "__type");
164 type = js_tostring(J, -1);
169 if (js_isuserdata(J, 0, type))
170 obj = js_touserdata(J, 0, type);
174 set(jsctx, obj, OBJ(1));
179 void pdf_jsimp_addmethod(pdf_jsimp *imp, pdf_jsimp_type *type, char *name, pdf_jsimp_method *meth)
181 js_State *J = imp->J;
182 js_getregistry(J, (const char *)type);
184 js_newcfunction(J, wrapmethod, name, 0);
187 js_newuserdata(J, "method", meth, NULL);
188 js_defproperty(J, -2, "__call", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
189 js_pushstring(J, (const char *)type);
190 js_defproperty(J, -2, "__type", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
192 js_defproperty(J, -2, name, JS_READONLY | JS_DONTCONF);
197 void pdf_jsimp_addproperty(pdf_jsimp *imp, pdf_jsimp_type *type, char *name, pdf_jsimp_getter *get, pdf_jsimp_setter *set)
199 js_State *J = imp->J;
200 js_getregistry(J, (const char *)type);
202 js_newcfunction(J, wrapgetter, name, 0);
205 js_newuserdata(J, "getter", get, NULL);
206 js_defproperty(J, -2, "__get", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
207 js_pushstring(J, (const char *)type);
208 js_defproperty(J, -2, "__type", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
210 js_newcfunction(J, wrapsetter, name, 0);
213 js_newuserdata(J, "setter", set, NULL);
214 js_defproperty(J, -2, "__set", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
215 js_pushstring(J, (const char *)type);
216 js_defproperty(J, -2, "__type", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
218 js_defaccessor(J, -3, name, JS_READONLY | JS_DONTCONF);
223 void pdf_jsimp_set_global_type(pdf_jsimp *imp, pdf_jsimp_type *type)
225 js_State *J = imp->J;
228 js_getregistry(J, (const char *)type);
229 js_pushiterator(J, -1, 1);
230 while ((name = js_nextiterator(J, -1)))
232 js_getproperty(J, -2, name);
233 js_setglobal(J, name);
237 pdf_jsimp_obj *pdf_jsimp_new_obj(pdf_jsimp *imp, pdf_jsimp_type *type, void *natobj)
239 js_State *J = imp->J;
240 js_getregistry(J, (const char *)type);
241 js_newuserdata(J, (const char *)type, natobj, NULL);
242 return NEWOBJ(J, -1);
245 void pdf_jsimp_drop_obj(pdf_jsimp *imp, pdf_jsimp_obj *obj)
249 int pdf_jsimp_to_type(pdf_jsimp *imp, pdf_jsimp_obj *obj)
251 js_State *J = imp->J;
252 if (js_isnull(J, IDX(obj))) return JS_TYPE_NULL;
253 if (js_isboolean(J, IDX(obj))) return JS_TYPE_BOOLEAN;
254 if (js_isnumber(J, IDX(obj))) return JS_TYPE_NUMBER;
255 if (js_isstring(J, IDX(obj))) return JS_TYPE_STRING;
256 if (js_isarray(J, IDX(obj))) return JS_TYPE_ARRAY;
257 return JS_TYPE_UNKNOWN;
260 pdf_jsimp_obj *pdf_jsimp_from_string(pdf_jsimp *imp, char *str)
262 js_State *J = imp->J;
263 js_pushstring(J, str);
264 return NEWOBJ(J, -1);
267 char *pdf_jsimp_to_string(pdf_jsimp *imp, pdf_jsimp_obj *obj)
269 /* cast away const :( */
270 return (char*)js_tostring(imp->J, IDX(obj));
273 pdf_jsimp_obj *pdf_jsimp_from_number(pdf_jsimp *imp, double num)
275 js_State *J = imp->J;
276 js_pushnumber(J, num);
277 return NEWOBJ(J, -1);
280 double pdf_jsimp_to_number(pdf_jsimp *imp, pdf_jsimp_obj *obj)
282 return js_tonumber(imp->J, IDX(obj));
285 int pdf_jsimp_array_len(pdf_jsimp *imp, pdf_jsimp_obj *obj)
287 js_State *J = imp->J;
288 return js_getlength(J, IDX(obj));
291 pdf_jsimp_obj *pdf_jsimp_array_item(pdf_jsimp *imp, pdf_jsimp_obj *obj, int i)
293 js_State *J = imp->J;
294 js_getindex(J, IDX(obj), i);
295 return NEWOBJ(J, -1);
298 pdf_jsimp_obj *pdf_jsimp_property(pdf_jsimp *imp, pdf_jsimp_obj *obj, char *prop)
300 js_State *J = imp->J;
301 js_getproperty(J, IDX(obj), prop);
302 return NEWOBJ(J, -1);
305 void pdf_jsimp_execute(pdf_jsimp *imp, char *code)
307 js_State *J = imp->J;
308 js_dostring(J, code, 0);
311 void pdf_jsimp_execute_count(pdf_jsimp *imp, char *code, int count)
313 char *terminated = fz_malloc(imp->ctx, count+1);
314 memcpy(terminated, code, count);
315 terminated[count] = 0;
316 pdf_jsimp_execute(imp, terminated);
317 fz_free(imp->ctx, terminated);