Coverage Report

Created: 2024-05-20 06:23

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