comparison mupdf-source/thirdparty/mujs/jsfunction.c @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
1 #include "jsi.h"
2
3 static void jsB_Function(js_State *J)
4 {
5 int i, top = js_gettop(J);
6 js_Buffer *sb = NULL;
7 const char *body;
8 js_Ast *parse;
9 js_Function *fun;
10
11 if (js_try(J)) {
12 js_free(J, sb);
13 jsP_freeparse(J);
14 js_throw(J);
15 }
16
17 /* p1, p2, ..., pn */
18 if (top > 2) {
19 for (i = 1; i < top - 1; ++i) {
20 if (i > 1)
21 js_putc(J, &sb, ',');
22 js_puts(J, &sb, js_tostring(J, i));
23 }
24 js_putc(J, &sb, ')');
25 js_putc(J, &sb, 0);
26 }
27
28 /* body */
29 body = js_isdefined(J, top - 1) ? js_tostring(J, top - 1) : "";
30
31 parse = jsP_parsefunction(J, "[string]", sb ? sb->s : NULL, body);
32 fun = jsC_compilefunction(J, parse);
33
34 js_endtry(J);
35 js_free(J, sb);
36 jsP_freeparse(J);
37
38 js_newfunction(J, fun, J->GE);
39 }
40
41 static void jsB_Function_prototype(js_State *J)
42 {
43 js_pushundefined(J);
44 }
45
46 static void Fp_toString(js_State *J)
47 {
48 js_Object *self = js_toobject(J, 0);
49 js_Buffer *sb = NULL;
50 int i;
51
52 if (!js_iscallable(J, 0))
53 js_typeerror(J, "not a function");
54
55 if (self->type == JS_CFUNCTION || self->type == JS_CSCRIPT) {
56 js_Function *F = self->u.f.function;
57
58 if (js_try(J)) {
59 js_free(J, sb);
60 js_throw(J);
61 }
62
63 js_puts(J, &sb, "function ");
64 js_puts(J, &sb, F->name);
65 js_putc(J, &sb, '(');
66 for (i = 0; i < F->numparams; ++i) {
67 if (i > 0) js_putc(J, &sb, ',');
68 js_puts(J, &sb, F->vartab[i]);
69 }
70 js_puts(J, &sb, ") { [byte code] }");
71 js_putc(J, &sb, 0);
72
73 js_pushstring(J, sb->s);
74 js_endtry(J);
75 js_free(J, sb);
76 } else if (self->type == JS_CCFUNCTION) {
77 if (js_try(J)) {
78 js_free(J, sb);
79 js_throw(J);
80 }
81
82 js_puts(J, &sb, "function ");
83 js_puts(J, &sb, self->u.c.name);
84 js_puts(J, &sb, "() { [native code] }");
85 js_putc(J, &sb, 0);
86
87 js_pushstring(J, sb->s);
88 js_endtry(J);
89 js_free(J, sb);
90 } else {
91 js_pushliteral(J, "function () { }");
92 }
93 }
94
95 static void Fp_apply(js_State *J)
96 {
97 int i, n;
98
99 if (!js_iscallable(J, 0))
100 js_typeerror(J, "not a function");
101
102 js_copy(J, 0);
103 js_copy(J, 1);
104
105 if (js_isnull(J, 2) || js_isundefined(J, 2)) {
106 n = 0;
107 } else {
108 n = js_getlength(J, 2);
109 if (n < 0)
110 n = 0;
111 for (i = 0; i < n; ++i)
112 js_getindex(J, 2, i);
113 }
114
115 js_call(J, n);
116 }
117
118 static void Fp_call(js_State *J)
119 {
120 int i, top = js_gettop(J);
121
122 if (!js_iscallable(J, 0))
123 js_typeerror(J, "not a function");
124
125 for (i = 0; i < top; ++i)
126 js_copy(J, i);
127
128 js_call(J, top - 2);
129 }
130
131 static void callbound(js_State *J)
132 {
133 int top = js_gettop(J);
134 int i, fun, args, n;
135
136 fun = js_gettop(J);
137 js_currentfunction(J);
138 js_getproperty(J, fun, "__TargetFunction__");
139 js_getproperty(J, fun, "__BoundThis__");
140
141 args = js_gettop(J);
142 js_getproperty(J, fun, "__BoundArguments__");
143 n = js_getlength(J, args);
144 if (n < 0)
145 n = 0;
146 for (i = 0; i < n; ++i)
147 js_getindex(J, args, i);
148 js_remove(J, args);
149
150 for (i = 1; i < top; ++i)
151 js_copy(J, i);
152
153 js_call(J, n + top - 1);
154 }
155
156 static void constructbound(js_State *J)
157 {
158 int top = js_gettop(J);
159 int i, fun, args, n;
160
161 fun = js_gettop(J);
162 js_currentfunction(J);
163 js_getproperty(J, fun, "__TargetFunction__");
164
165 args = js_gettop(J);
166 js_getproperty(J, fun, "__BoundArguments__");
167 n = js_getlength(J, args);
168 if (n < 0)
169 n = 0;
170 for (i = 0; i < n; ++i)
171 js_getindex(J, args, i);
172 js_remove(J, args);
173
174 for (i = 1; i < top; ++i)
175 js_copy(J, i);
176
177 js_construct(J, n + top - 1);
178 }
179
180 static void Fp_bind(js_State *J)
181 {
182 int i, top = js_gettop(J);
183 int n;
184
185 if (!js_iscallable(J, 0))
186 js_typeerror(J, "not a function");
187
188 n = js_getlength(J, 0);
189 if (n > top - 2)
190 n -= top - 2;
191 else
192 n = 0;
193
194 /* Reuse target function's prototype for HasInstance check. */
195 js_getproperty(J, 0, "prototype");
196 js_newcconstructor(J, callbound, constructbound, "[bind]", n);
197
198 /* target function */
199 js_copy(J, 0);
200 js_defproperty(J, -2, "__TargetFunction__", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
201
202 /* bound this */
203 js_copy(J, 1);
204 js_defproperty(J, -2, "__BoundThis__", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
205
206 /* bound arguments */
207 js_newarray(J);
208 for (i = 2; i < top; ++i) {
209 js_copy(J, i);
210 js_setindex(J, -2, i - 2);
211 }
212 js_defproperty(J, -2, "__BoundArguments__", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
213 }
214
215 void jsB_initfunction(js_State *J)
216 {
217 J->Function_prototype->u.c.name = "Function.prototype";
218 J->Function_prototype->u.c.function = jsB_Function_prototype;
219 J->Function_prototype->u.c.constructor = NULL;
220 J->Function_prototype->u.c.length = 0;
221
222 js_pushobject(J, J->Function_prototype);
223 {
224 jsB_propf(J, "Function.prototype.toString", Fp_toString, 2);
225 jsB_propf(J, "Function.prototype.apply", Fp_apply, 2);
226 jsB_propf(J, "Function.prototype.call", Fp_call, 1);
227 jsB_propf(J, "Function.prototype.bind", Fp_bind, 1);
228 }
229 js_newcconstructor(J, jsB_Function, jsB_Function, "Function", 1);
230 js_defglobal(J, "Function", JS_DONTENUM);
231 }