zig-pug 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/binding.gyp +16 -10
- package/package.json +4 -3
- package/prebuilts/darwin-arm64/libzig-pug.a +0 -0
- package/prebuilts/darwin-x64/libzig-pug.a +0 -0
- package/prebuilts/linux-arm64/libzig-pug.a +0 -0
- package/prebuilts/linux-x64/libzig-pug.a +0 -0
- package/prebuilts/win32-x64/zig-pug.lib +0 -0
- package/vendor/mujs/COPYING +0 -16
- package/vendor/mujs/README +0 -50
- package/vendor/mujs/astnames.h +0 -92
- package/vendor/mujs/jsarray.c +0 -832
- package/vendor/mujs/jsboolean.c +0 -38
- package/vendor/mujs/jsbuiltin.c +0 -249
- package/vendor/mujs/jscompile.c +0 -1428
- package/vendor/mujs/jsdate.c +0 -861
- package/vendor/mujs/jsdtoa.c +0 -749
- package/vendor/mujs/jserror.c +0 -139
- package/vendor/mujs/jsfunction.c +0 -231
- package/vendor/mujs/jsgc.c +0 -284
- package/vendor/mujs/jsi.h +0 -870
- package/vendor/mujs/jsintern.c +0 -137
- package/vendor/mujs/jslex.c +0 -878
- package/vendor/mujs/jsmath.c +0 -194
- package/vendor/mujs/jsnumber.c +0 -198
- package/vendor/mujs/jsobject.c +0 -560
- package/vendor/mujs/json.c +0 -422
- package/vendor/mujs/jsparse.c +0 -1065
- package/vendor/mujs/jsproperty.c +0 -341
- package/vendor/mujs/jsregexp.c +0 -232
- package/vendor/mujs/jsrepr.c +0 -285
- package/vendor/mujs/jsrun.c +0 -2096
- package/vendor/mujs/jsstate.c +0 -334
- package/vendor/mujs/jsstring.c +0 -852
- package/vendor/mujs/jsvalue.c +0 -708
- package/vendor/mujs/libmujs.a +0 -0
- package/vendor/mujs/main.c +0 -396
- package/vendor/mujs/mujs.h +0 -253
- package/vendor/mujs/one.c +0 -25
- package/vendor/mujs/opnames.h +0 -85
- package/vendor/mujs/pp.c +0 -980
- package/vendor/mujs/regexp.c +0 -1277
- package/vendor/mujs/regexp.h +0 -46
- package/vendor/mujs/utf.c +0 -305
- package/vendor/mujs/utf.h +0 -52
- package/vendor/mujs/utfdata.h +0 -2209
package/vendor/mujs/jsrun.c
DELETED
|
@@ -1,2096 +0,0 @@
|
|
|
1
|
-
#include "jsi.h"
|
|
2
|
-
#include "utf.h"
|
|
3
|
-
|
|
4
|
-
#include <assert.h>
|
|
5
|
-
|
|
6
|
-
static void jsR_run(js_State *J, js_Function *F);
|
|
7
|
-
|
|
8
|
-
/* Push values on stack */
|
|
9
|
-
|
|
10
|
-
#define STACK (J->stack)
|
|
11
|
-
#define TOP (J->top)
|
|
12
|
-
#define BOT (J->bot)
|
|
13
|
-
|
|
14
|
-
static void js_trystackoverflow(js_State *J)
|
|
15
|
-
{
|
|
16
|
-
STACK[TOP].t.type = JS_TLITSTR;
|
|
17
|
-
STACK[TOP].u.litstr = "exception stack overflow";
|
|
18
|
-
++TOP;
|
|
19
|
-
js_throw(J);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
static void js_stackoverflow(js_State *J)
|
|
23
|
-
{
|
|
24
|
-
STACK[TOP].t.type = JS_TLITSTR;
|
|
25
|
-
STACK[TOP].u.litstr = "stack overflow";
|
|
26
|
-
++TOP;
|
|
27
|
-
js_throw(J);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
static void js_outofmemory(js_State *J)
|
|
31
|
-
{
|
|
32
|
-
STACK[TOP].t.type = JS_TLITSTR;
|
|
33
|
-
STACK[TOP].u.litstr = "out of memory";
|
|
34
|
-
++TOP;
|
|
35
|
-
js_throw(J);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
static void js_runlimit(js_State *J)
|
|
39
|
-
{
|
|
40
|
-
STACK[TOP].t.type = JS_TLITSTR;
|
|
41
|
-
STACK[TOP].u.litstr = "script ran too long";
|
|
42
|
-
++TOP;
|
|
43
|
-
js_throw(J);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
void js_setlimit(js_State *J, int runlimit, int memlimit)
|
|
47
|
-
{
|
|
48
|
-
J->runlimit = runlimit;
|
|
49
|
-
J->memlimit = memlimit;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
void *js_malloc(js_State *J, int size)
|
|
53
|
-
{
|
|
54
|
-
void *ptr;
|
|
55
|
-
if (J->memlimit > 0) {
|
|
56
|
-
if (size >= J->memlimit)
|
|
57
|
-
js_outofmemory(J);
|
|
58
|
-
J->memlimit -= size;
|
|
59
|
-
}
|
|
60
|
-
ptr = J->alloc(J->actx, NULL, size);
|
|
61
|
-
if (!ptr)
|
|
62
|
-
js_outofmemory(J);
|
|
63
|
-
return ptr;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
void *js_realloc(js_State *J, void *ptr, int size)
|
|
67
|
-
{
|
|
68
|
-
if (J->memlimit > 0) {
|
|
69
|
-
// TODO: track released memory
|
|
70
|
-
if (size >= J->memlimit)
|
|
71
|
-
js_outofmemory(J);
|
|
72
|
-
J->memlimit -= size;
|
|
73
|
-
}
|
|
74
|
-
ptr = J->alloc(J->actx, ptr, size);
|
|
75
|
-
if (!ptr)
|
|
76
|
-
js_outofmemory(J);
|
|
77
|
-
return ptr;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
char *js_strdup(js_State *J, const char *s)
|
|
81
|
-
{
|
|
82
|
-
int n = strlen(s) + 1;
|
|
83
|
-
char *p = js_malloc(J, n);
|
|
84
|
-
memcpy(p, s, n);
|
|
85
|
-
return p;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
void js_free(js_State *J, void *ptr)
|
|
89
|
-
{
|
|
90
|
-
// TODO: track released memory (J->memlimit)
|
|
91
|
-
J->alloc(J->actx, ptr, 0);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
js_String *jsV_newmemstring(js_State *J, const char *s, int n)
|
|
95
|
-
{
|
|
96
|
-
js_String *v = js_malloc(J, soffsetof(js_String, p) + n + 1);
|
|
97
|
-
memcpy(v->p, s, n);
|
|
98
|
-
v->p[n] = 0;
|
|
99
|
-
v->gcmark = 0;
|
|
100
|
-
v->gcnext = J->gcstr;
|
|
101
|
-
J->gcstr = v;
|
|
102
|
-
++J->gccounter;
|
|
103
|
-
return v;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
#define CHECKSTACK(n) if (TOP + n >= JS_STACKSIZE) js_stackoverflow(J)
|
|
107
|
-
|
|
108
|
-
void js_pushvalue(js_State *J, js_Value v)
|
|
109
|
-
{
|
|
110
|
-
CHECKSTACK(1);
|
|
111
|
-
STACK[TOP] = v;
|
|
112
|
-
++TOP;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
void js_pushundefined(js_State *J)
|
|
116
|
-
{
|
|
117
|
-
CHECKSTACK(1);
|
|
118
|
-
STACK[TOP].t.type = JS_TUNDEFINED;
|
|
119
|
-
++TOP;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
void js_pushnull(js_State *J)
|
|
123
|
-
{
|
|
124
|
-
CHECKSTACK(1);
|
|
125
|
-
STACK[TOP].t.type = JS_TNULL;
|
|
126
|
-
++TOP;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
void js_pushboolean(js_State *J, int v)
|
|
130
|
-
{
|
|
131
|
-
CHECKSTACK(1);
|
|
132
|
-
STACK[TOP].t.type = JS_TBOOLEAN;
|
|
133
|
-
STACK[TOP].u.boolean = !!v;
|
|
134
|
-
++TOP;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
void js_pushnumber(js_State *J, double v)
|
|
138
|
-
{
|
|
139
|
-
CHECKSTACK(1);
|
|
140
|
-
STACK[TOP].t.type = JS_TNUMBER;
|
|
141
|
-
STACK[TOP].u.number = v;
|
|
142
|
-
++TOP;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
void js_pushstring(js_State *J, const char *v)
|
|
146
|
-
{
|
|
147
|
-
size_t n = strlen(v);
|
|
148
|
-
if (n > JS_STRLIMIT)
|
|
149
|
-
js_rangeerror(J, "invalid string length");
|
|
150
|
-
CHECKSTACK(1);
|
|
151
|
-
if (n <= soffsetof(js_Value, t.type)) {
|
|
152
|
-
char *s = STACK[TOP].u.shrstr;
|
|
153
|
-
while (n--) *s++ = *v++;
|
|
154
|
-
*s = 0;
|
|
155
|
-
STACK[TOP].t.type = JS_TSHRSTR;
|
|
156
|
-
} else {
|
|
157
|
-
STACK[TOP].t.type = JS_TMEMSTR;
|
|
158
|
-
STACK[TOP].u.memstr = jsV_newmemstring(J, v, n);
|
|
159
|
-
}
|
|
160
|
-
++TOP;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
void js_pushlstring(js_State *J, const char *v, int n)
|
|
164
|
-
{
|
|
165
|
-
if (n > JS_STRLIMIT)
|
|
166
|
-
js_rangeerror(J, "invalid string length");
|
|
167
|
-
CHECKSTACK(1);
|
|
168
|
-
if (n <= soffsetof(js_Value, t.type)) {
|
|
169
|
-
char *s = STACK[TOP].u.shrstr;
|
|
170
|
-
while (n--) *s++ = *v++;
|
|
171
|
-
*s = 0;
|
|
172
|
-
STACK[TOP].t.type = JS_TSHRSTR;
|
|
173
|
-
} else {
|
|
174
|
-
STACK[TOP].t.type = JS_TMEMSTR;
|
|
175
|
-
STACK[TOP].u.memstr = jsV_newmemstring(J, v, n);
|
|
176
|
-
}
|
|
177
|
-
++TOP;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
void js_pushliteral(js_State *J, const char *v)
|
|
181
|
-
{
|
|
182
|
-
CHECKSTACK(1);
|
|
183
|
-
STACK[TOP].t.type = JS_TLITSTR;
|
|
184
|
-
STACK[TOP].u.litstr = v;
|
|
185
|
-
++TOP;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
void js_pushobject(js_State *J, js_Object *v)
|
|
189
|
-
{
|
|
190
|
-
CHECKSTACK(1);
|
|
191
|
-
STACK[TOP].t.type = JS_TOBJECT;
|
|
192
|
-
STACK[TOP].u.object = v;
|
|
193
|
-
++TOP;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
void js_pushglobal(js_State *J)
|
|
197
|
-
{
|
|
198
|
-
js_pushobject(J, J->G);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
void js_currentfunction(js_State *J)
|
|
202
|
-
{
|
|
203
|
-
CHECKSTACK(1);
|
|
204
|
-
if (BOT > 0)
|
|
205
|
-
STACK[TOP] = STACK[BOT-1];
|
|
206
|
-
else
|
|
207
|
-
STACK[TOP].t.type = JS_TUNDEFINED;
|
|
208
|
-
++TOP;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
void *js_currentfunctiondata(js_State *J)
|
|
212
|
-
{
|
|
213
|
-
if (BOT > 0)
|
|
214
|
-
return STACK[BOT-1].u.object->u.c.data;
|
|
215
|
-
return NULL;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/* Read values from stack */
|
|
219
|
-
|
|
220
|
-
static js_Value *stackidx(js_State *J, int idx)
|
|
221
|
-
{
|
|
222
|
-
static js_Value undefined = { { {0}, JS_TUNDEFINED } };
|
|
223
|
-
idx = idx < 0 ? TOP + idx : BOT + idx;
|
|
224
|
-
if (idx < 0 || idx >= TOP)
|
|
225
|
-
return &undefined;
|
|
226
|
-
return STACK + idx;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
js_Value *js_tovalue(js_State *J, int idx)
|
|
230
|
-
{
|
|
231
|
-
return stackidx(J, idx);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
int js_isdefined(js_State *J, int idx) { return stackidx(J, idx)->t.type != JS_TUNDEFINED; }
|
|
235
|
-
int js_isundefined(js_State *J, int idx) { return stackidx(J, idx)->t.type == JS_TUNDEFINED; }
|
|
236
|
-
int js_isnull(js_State *J, int idx) { return stackidx(J, idx)->t.type == JS_TNULL; }
|
|
237
|
-
int js_isboolean(js_State *J, int idx) { return stackidx(J, idx)->t.type == JS_TBOOLEAN; }
|
|
238
|
-
int js_isnumber(js_State *J, int idx) { return stackidx(J, idx)->t.type == JS_TNUMBER; }
|
|
239
|
-
int js_isstring(js_State *J, int idx) { enum js_Type t = stackidx(J, idx)->t.type; return t == JS_TSHRSTR || t == JS_TLITSTR || t == JS_TMEMSTR; }
|
|
240
|
-
int js_isprimitive(js_State *J, int idx) { return stackidx(J, idx)->t.type != JS_TOBJECT; }
|
|
241
|
-
int js_isobject(js_State *J, int idx) { return stackidx(J, idx)->t.type == JS_TOBJECT; }
|
|
242
|
-
int js_iscoercible(js_State *J, int idx) { js_Value *v = stackidx(J, idx); return v->t.type != JS_TUNDEFINED && v->t.type != JS_TNULL; }
|
|
243
|
-
|
|
244
|
-
int js_iscallable(js_State *J, int idx)
|
|
245
|
-
{
|
|
246
|
-
js_Value *v = stackidx(J, idx);
|
|
247
|
-
if (v->t.type == JS_TOBJECT)
|
|
248
|
-
return v->u.object->type == JS_CFUNCTION ||
|
|
249
|
-
v->u.object->type == JS_CSCRIPT ||
|
|
250
|
-
v->u.object->type == JS_CCFUNCTION;
|
|
251
|
-
return 0;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
int js_isarray(js_State *J, int idx)
|
|
255
|
-
{
|
|
256
|
-
js_Value *v = stackidx(J, idx);
|
|
257
|
-
return v->t.type == JS_TOBJECT && v->u.object->type == JS_CARRAY;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
int js_isregexp(js_State *J, int idx)
|
|
261
|
-
{
|
|
262
|
-
js_Value *v = stackidx(J, idx);
|
|
263
|
-
return v->t.type == JS_TOBJECT && v->u.object->type == JS_CREGEXP;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
int js_isuserdata(js_State *J, int idx, const char *tag)
|
|
267
|
-
{
|
|
268
|
-
js_Value *v = stackidx(J, idx);
|
|
269
|
-
if (v->t.type == JS_TOBJECT && v->u.object->type == JS_CUSERDATA)
|
|
270
|
-
return !strcmp(tag, v->u.object->u.user.tag);
|
|
271
|
-
return 0;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
int js_iserror(js_State *J, int idx)
|
|
275
|
-
{
|
|
276
|
-
js_Value *v = stackidx(J, idx);
|
|
277
|
-
return v->t.type == JS_TOBJECT && v->u.object->type == JS_CERROR;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
const char *js_typeof(js_State *J, int idx)
|
|
281
|
-
{
|
|
282
|
-
js_Value *v = stackidx(J, idx);
|
|
283
|
-
switch (v->t.type) {
|
|
284
|
-
default:
|
|
285
|
-
case JS_TSHRSTR: return "string";
|
|
286
|
-
case JS_TUNDEFINED: return "undefined";
|
|
287
|
-
case JS_TNULL: return "object";
|
|
288
|
-
case JS_TBOOLEAN: return "boolean";
|
|
289
|
-
case JS_TNUMBER: return "number";
|
|
290
|
-
case JS_TLITSTR: return "string";
|
|
291
|
-
case JS_TMEMSTR: return "string";
|
|
292
|
-
case JS_TOBJECT:
|
|
293
|
-
if (v->u.object->type == JS_CFUNCTION || v->u.object->type == JS_CCFUNCTION)
|
|
294
|
-
return "function";
|
|
295
|
-
return "object";
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
int js_type(js_State *J, int idx)
|
|
300
|
-
{
|
|
301
|
-
js_Value *v = stackidx(J, idx);
|
|
302
|
-
switch (v->t.type) {
|
|
303
|
-
default:
|
|
304
|
-
case JS_TSHRSTR: return JS_ISSTRING;
|
|
305
|
-
case JS_TUNDEFINED: return JS_ISUNDEFINED;
|
|
306
|
-
case JS_TNULL: return JS_ISNULL;
|
|
307
|
-
case JS_TBOOLEAN: return JS_ISBOOLEAN;
|
|
308
|
-
case JS_TNUMBER: return JS_ISNUMBER;
|
|
309
|
-
case JS_TLITSTR: return JS_ISSTRING;
|
|
310
|
-
case JS_TMEMSTR: return JS_ISSTRING;
|
|
311
|
-
case JS_TOBJECT:
|
|
312
|
-
if (v->u.object->type == JS_CFUNCTION || v->u.object->type == JS_CCFUNCTION)
|
|
313
|
-
return JS_ISFUNCTION;
|
|
314
|
-
return JS_ISOBJECT;
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
int js_toboolean(js_State *J, int idx)
|
|
319
|
-
{
|
|
320
|
-
return jsV_toboolean(J, stackidx(J, idx));
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
double js_tonumber(js_State *J, int idx)
|
|
324
|
-
{
|
|
325
|
-
return jsV_tonumber(J, stackidx(J, idx));
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
int js_tointeger(js_State *J, int idx)
|
|
329
|
-
{
|
|
330
|
-
return jsV_numbertointeger(jsV_tonumber(J, stackidx(J, idx)));
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
int js_toint32(js_State *J, int idx)
|
|
334
|
-
{
|
|
335
|
-
return jsV_numbertoint32(jsV_tonumber(J, stackidx(J, idx)));
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
unsigned int js_touint32(js_State *J, int idx)
|
|
339
|
-
{
|
|
340
|
-
return jsV_numbertouint32(jsV_tonumber(J, stackidx(J, idx)));
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
short js_toint16(js_State *J, int idx)
|
|
344
|
-
{
|
|
345
|
-
return jsV_numbertoint16(jsV_tonumber(J, stackidx(J, idx)));
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
unsigned short js_touint16(js_State *J, int idx)
|
|
349
|
-
{
|
|
350
|
-
return jsV_numbertouint16(jsV_tonumber(J, stackidx(J, idx)));
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
const char *js_tostring(js_State *J, int idx)
|
|
354
|
-
{
|
|
355
|
-
return jsV_tostring(J, stackidx(J, idx));
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
js_Object *js_toobject(js_State *J, int idx)
|
|
359
|
-
{
|
|
360
|
-
return jsV_toobject(J, stackidx(J, idx));
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
void js_toprimitive(js_State *J, int idx, int hint)
|
|
364
|
-
{
|
|
365
|
-
jsV_toprimitive(J, stackidx(J, idx), hint);
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
js_Regexp *js_toregexp(js_State *J, int idx)
|
|
369
|
-
{
|
|
370
|
-
js_Value *v = stackidx(J, idx);
|
|
371
|
-
if (v->t.type == JS_TOBJECT && v->u.object->type == JS_CREGEXP)
|
|
372
|
-
return &v->u.object->u.r;
|
|
373
|
-
js_typeerror(J, "not a regexp");
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
void *js_touserdata(js_State *J, int idx, const char *tag)
|
|
377
|
-
{
|
|
378
|
-
js_Value *v = stackidx(J, idx);
|
|
379
|
-
if (v->t.type == JS_TOBJECT && v->u.object->type == JS_CUSERDATA)
|
|
380
|
-
if (!strcmp(tag, v->u.object->u.user.tag))
|
|
381
|
-
return v->u.object->u.user.data;
|
|
382
|
-
js_typeerror(J, "not a %s", tag);
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
static js_Object *jsR_tofunction(js_State *J, int idx)
|
|
386
|
-
{
|
|
387
|
-
js_Value *v = stackidx(J, idx);
|
|
388
|
-
if (v->t.type == JS_TUNDEFINED || v->t.type == JS_TNULL)
|
|
389
|
-
return NULL;
|
|
390
|
-
if (v->t.type == JS_TOBJECT)
|
|
391
|
-
if (v->u.object->type == JS_CFUNCTION || v->u.object->type == JS_CCFUNCTION)
|
|
392
|
-
return v->u.object;
|
|
393
|
-
js_typeerror(J, "not a function");
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
/* Stack manipulation */
|
|
397
|
-
|
|
398
|
-
int js_gettop(js_State *J)
|
|
399
|
-
{
|
|
400
|
-
return TOP - BOT;
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
void js_pop(js_State *J, int n)
|
|
404
|
-
{
|
|
405
|
-
TOP -= n;
|
|
406
|
-
if (TOP < BOT) {
|
|
407
|
-
TOP = BOT;
|
|
408
|
-
js_error(J, "stack underflow!");
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
void js_remove(js_State *J, int idx)
|
|
413
|
-
{
|
|
414
|
-
idx = idx < 0 ? TOP + idx : BOT + idx;
|
|
415
|
-
if (idx < BOT || idx >= TOP)
|
|
416
|
-
js_error(J, "stack error!");
|
|
417
|
-
for (;idx < TOP - 1; ++idx)
|
|
418
|
-
STACK[idx] = STACK[idx+1];
|
|
419
|
-
--TOP;
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
void js_insert(js_State *J, int idx)
|
|
423
|
-
{
|
|
424
|
-
js_error(J, "not implemented yet");
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
void js_replace(js_State* J, int idx)
|
|
428
|
-
{
|
|
429
|
-
idx = idx < 0 ? TOP + idx : BOT + idx;
|
|
430
|
-
if (idx < BOT || idx >= TOP)
|
|
431
|
-
js_error(J, "stack error!");
|
|
432
|
-
STACK[idx] = STACK[--TOP];
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
void js_copy(js_State *J, int idx)
|
|
436
|
-
{
|
|
437
|
-
CHECKSTACK(1);
|
|
438
|
-
STACK[TOP] = *stackidx(J, idx);
|
|
439
|
-
++TOP;
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
void js_dup(js_State *J)
|
|
443
|
-
{
|
|
444
|
-
CHECKSTACK(1);
|
|
445
|
-
STACK[TOP] = STACK[TOP-1];
|
|
446
|
-
++TOP;
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
void js_dup2(js_State *J)
|
|
450
|
-
{
|
|
451
|
-
CHECKSTACK(2);
|
|
452
|
-
STACK[TOP] = STACK[TOP-2];
|
|
453
|
-
STACK[TOP+1] = STACK[TOP-1];
|
|
454
|
-
TOP += 2;
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
void js_rot2(js_State *J)
|
|
458
|
-
{
|
|
459
|
-
/* A B -> B A */
|
|
460
|
-
js_Value tmp = STACK[TOP-1]; /* A B (B) */
|
|
461
|
-
STACK[TOP-1] = STACK[TOP-2]; /* A A */
|
|
462
|
-
STACK[TOP-2] = tmp; /* B A */
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
void js_rot3(js_State *J)
|
|
466
|
-
{
|
|
467
|
-
/* A B C -> C A B */
|
|
468
|
-
js_Value tmp = STACK[TOP-1]; /* A B C (C) */
|
|
469
|
-
STACK[TOP-1] = STACK[TOP-2]; /* A B B */
|
|
470
|
-
STACK[TOP-2] = STACK[TOP-3]; /* A A B */
|
|
471
|
-
STACK[TOP-3] = tmp; /* C A B */
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
void js_rot4(js_State *J)
|
|
475
|
-
{
|
|
476
|
-
/* A B C D -> D A B C */
|
|
477
|
-
js_Value tmp = STACK[TOP-1]; /* A B C D (D) */
|
|
478
|
-
STACK[TOP-1] = STACK[TOP-2]; /* A B C C */
|
|
479
|
-
STACK[TOP-2] = STACK[TOP-3]; /* A B B C */
|
|
480
|
-
STACK[TOP-3] = STACK[TOP-4]; /* A A B C */
|
|
481
|
-
STACK[TOP-4] = tmp; /* D A B C */
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
void js_rot2pop1(js_State *J)
|
|
485
|
-
{
|
|
486
|
-
/* A B -> B */
|
|
487
|
-
STACK[TOP-2] = STACK[TOP-1];
|
|
488
|
-
--TOP;
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
void js_rot3pop2(js_State *J)
|
|
492
|
-
{
|
|
493
|
-
/* A B C -> C */
|
|
494
|
-
STACK[TOP-3] = STACK[TOP-1];
|
|
495
|
-
TOP -= 2;
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
void js_rot(js_State *J, int n)
|
|
499
|
-
{
|
|
500
|
-
int i;
|
|
501
|
-
js_Value tmp = STACK[TOP-1];
|
|
502
|
-
for (i = 1; i < n; ++i)
|
|
503
|
-
STACK[TOP-i] = STACK[TOP-i-1];
|
|
504
|
-
STACK[TOP-i] = tmp;
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
/* Property access that takes care of attributes and getters/setters */
|
|
508
|
-
|
|
509
|
-
int js_isarrayindex(js_State *J, const char *p, int *idx)
|
|
510
|
-
{
|
|
511
|
-
int n = 0;
|
|
512
|
-
|
|
513
|
-
/* check for empty string */
|
|
514
|
-
if (p[0] == 0)
|
|
515
|
-
return 0;
|
|
516
|
-
|
|
517
|
-
/* check for '0' and integers with leading zero */
|
|
518
|
-
if (p[0] == '0')
|
|
519
|
-
return (p[1] == 0) ? *idx = 0, 1 : 0;
|
|
520
|
-
|
|
521
|
-
while (*p) {
|
|
522
|
-
int c = *p++;
|
|
523
|
-
if (c >= '0' && c <= '9') {
|
|
524
|
-
if (n >= INT_MAX / 10)
|
|
525
|
-
return 0;
|
|
526
|
-
n = n * 10 + (c - '0');
|
|
527
|
-
} else {
|
|
528
|
-
return 0;
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
return *idx = n, 1;
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
static void js_pushrune(js_State *J, Rune rune)
|
|
535
|
-
{
|
|
536
|
-
char buf[UTFmax + 1];
|
|
537
|
-
if (rune >= 0) {
|
|
538
|
-
buf[runetochar(buf, &rune)] = 0;
|
|
539
|
-
js_pushstring(J, buf);
|
|
540
|
-
} else {
|
|
541
|
-
js_pushundefined(J);
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
void jsR_unflattenarray(js_State *J, js_Object *obj) {
|
|
546
|
-
if (obj->type == JS_CARRAY && obj->u.a.simple) {
|
|
547
|
-
js_Property *ref;
|
|
548
|
-
int i;
|
|
549
|
-
char name[32];
|
|
550
|
-
if (js_try(J)) {
|
|
551
|
-
obj->properties = NULL;
|
|
552
|
-
js_throw(J);
|
|
553
|
-
}
|
|
554
|
-
for (i = 0; i < obj->u.a.flat_length; ++i) {
|
|
555
|
-
js_itoa(name, i);
|
|
556
|
-
ref = jsV_setproperty(J, obj, name);
|
|
557
|
-
ref->value = obj->u.a.array[i];
|
|
558
|
-
}
|
|
559
|
-
js_free(J, obj->u.a.array);
|
|
560
|
-
obj->u.a.simple = 0;
|
|
561
|
-
obj->u.a.flat_length = 0;
|
|
562
|
-
obj->u.a.flat_capacity = 0;
|
|
563
|
-
obj->u.a.array = NULL;
|
|
564
|
-
js_endtry(J);
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
static int jsR_hasproperty(js_State *J, js_Object *obj, const char *name)
|
|
569
|
-
{
|
|
570
|
-
js_Property *ref;
|
|
571
|
-
int k;
|
|
572
|
-
|
|
573
|
-
if (obj->type == JS_CARRAY) {
|
|
574
|
-
if (!strcmp(name, "length")) {
|
|
575
|
-
js_pushnumber(J, obj->u.a.length);
|
|
576
|
-
return 1;
|
|
577
|
-
}
|
|
578
|
-
if (obj->u.a.simple) {
|
|
579
|
-
if (js_isarrayindex(J, name, &k)) {
|
|
580
|
-
if (k >= 0 && k < obj->u.a.flat_length) {
|
|
581
|
-
js_pushvalue(J, obj->u.a.array[k]);
|
|
582
|
-
return 1;
|
|
583
|
-
}
|
|
584
|
-
return 0;
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
else if (obj->type == JS_CSTRING) {
|
|
590
|
-
if (!strcmp(name, "length")) {
|
|
591
|
-
js_pushnumber(J, obj->u.s.length);
|
|
592
|
-
return 1;
|
|
593
|
-
}
|
|
594
|
-
if (js_isarrayindex(J, name, &k)) {
|
|
595
|
-
if (k >= 0 && k < obj->u.s.length) {
|
|
596
|
-
js_pushrune(J, js_runeat(J, obj->u.s.string, k));
|
|
597
|
-
return 1;
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
else if (obj->type == JS_CREGEXP) {
|
|
603
|
-
if (!strcmp(name, "source")) {
|
|
604
|
-
js_pushstring(J, obj->u.r.source);
|
|
605
|
-
return 1;
|
|
606
|
-
}
|
|
607
|
-
if (!strcmp(name, "global")) {
|
|
608
|
-
js_pushboolean(J, obj->u.r.flags & JS_REGEXP_G);
|
|
609
|
-
return 1;
|
|
610
|
-
}
|
|
611
|
-
if (!strcmp(name, "ignoreCase")) {
|
|
612
|
-
js_pushboolean(J, obj->u.r.flags & JS_REGEXP_I);
|
|
613
|
-
return 1;
|
|
614
|
-
}
|
|
615
|
-
if (!strcmp(name, "multiline")) {
|
|
616
|
-
js_pushboolean(J, obj->u.r.flags & JS_REGEXP_M);
|
|
617
|
-
return 1;
|
|
618
|
-
}
|
|
619
|
-
if (!strcmp(name, "lastIndex")) {
|
|
620
|
-
js_pushnumber(J, obj->u.r.last);
|
|
621
|
-
return 1;
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
else if (obj->type == JS_CUSERDATA) {
|
|
626
|
-
if (obj->u.user.has && obj->u.user.has(J, obj->u.user.data, name))
|
|
627
|
-
return 1;
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
ref = jsV_getproperty(J, obj, name);
|
|
631
|
-
if (ref) {
|
|
632
|
-
if (ref->getter) {
|
|
633
|
-
js_pushobject(J, ref->getter);
|
|
634
|
-
js_pushobject(J, obj);
|
|
635
|
-
js_call(J, 0);
|
|
636
|
-
} else {
|
|
637
|
-
js_pushvalue(J, ref->value);
|
|
638
|
-
}
|
|
639
|
-
return 1;
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
return 0;
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
static void jsR_getproperty(js_State *J, js_Object *obj, const char *name)
|
|
646
|
-
{
|
|
647
|
-
if (!jsR_hasproperty(J, obj, name))
|
|
648
|
-
js_pushundefined(J);
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
static int jsR_hasindex(js_State *J, js_Object *obj, int k)
|
|
652
|
-
{
|
|
653
|
-
char buf[32];
|
|
654
|
-
if (obj->type == JS_CARRAY && obj->u.a.simple) {
|
|
655
|
-
if (k >= 0 && k < obj->u.a.flat_length) {
|
|
656
|
-
js_pushvalue(J, obj->u.a.array[k]);
|
|
657
|
-
return 1;
|
|
658
|
-
}
|
|
659
|
-
return 0;
|
|
660
|
-
}
|
|
661
|
-
return jsR_hasproperty(J, obj, js_itoa(buf, k));
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
static void jsR_getindex(js_State *J, js_Object *obj, int k)
|
|
665
|
-
{
|
|
666
|
-
if (!jsR_hasindex(J, obj, k))
|
|
667
|
-
js_pushundefined(J);
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
static void jsR_setarrayindex(js_State *J, js_Object *obj, int k, js_Value *value)
|
|
671
|
-
{
|
|
672
|
-
int newlen = k + 1;
|
|
673
|
-
assert(obj->u.a.simple);
|
|
674
|
-
assert(k >= 0);
|
|
675
|
-
if (newlen > JS_ARRAYLIMIT)
|
|
676
|
-
js_rangeerror(J, "array too large");
|
|
677
|
-
if (newlen > obj->u.a.flat_length) {
|
|
678
|
-
assert(newlen == obj->u.a.flat_length + 1);
|
|
679
|
-
if (newlen > obj->u.a.flat_capacity) {
|
|
680
|
-
int newcap = obj->u.a.flat_capacity;
|
|
681
|
-
if (newcap == 0)
|
|
682
|
-
newcap = 8;
|
|
683
|
-
while (newcap < newlen)
|
|
684
|
-
newcap <<= 1;
|
|
685
|
-
obj->u.a.array = js_realloc(J, obj->u.a.array, newcap * sizeof(js_Value));
|
|
686
|
-
obj->u.a.flat_capacity = newcap;
|
|
687
|
-
}
|
|
688
|
-
obj->u.a.flat_length = newlen;
|
|
689
|
-
}
|
|
690
|
-
if (newlen > obj->u.a.length)
|
|
691
|
-
obj->u.a.length = newlen;
|
|
692
|
-
obj->u.a.array[k] = *value;
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
static void jsR_setproperty(js_State *J, js_Object *obj, const char *name, int transient)
|
|
696
|
-
{
|
|
697
|
-
js_Value *value = stackidx(J, -1);
|
|
698
|
-
js_Property *ref;
|
|
699
|
-
int k;
|
|
700
|
-
int own;
|
|
701
|
-
|
|
702
|
-
if (obj->type == JS_CARRAY) {
|
|
703
|
-
if (!strcmp(name, "length")) {
|
|
704
|
-
double rawlen = jsV_tonumber(J, value);
|
|
705
|
-
int newlen = jsV_numbertointeger(rawlen);
|
|
706
|
-
if (newlen != rawlen || newlen < 0)
|
|
707
|
-
js_rangeerror(J, "invalid array length");
|
|
708
|
-
if (newlen > JS_ARRAYLIMIT)
|
|
709
|
-
js_rangeerror(J, "array too large");
|
|
710
|
-
if (obj->u.a.simple) {
|
|
711
|
-
obj->u.a.length = newlen;
|
|
712
|
-
if (newlen <= obj->u.a.flat_length)
|
|
713
|
-
obj->u.a.flat_length = newlen;
|
|
714
|
-
} else {
|
|
715
|
-
jsV_resizearray(J, obj, newlen);
|
|
716
|
-
}
|
|
717
|
-
return;
|
|
718
|
-
}
|
|
719
|
-
|
|
720
|
-
if (js_isarrayindex(J, name, &k)) {
|
|
721
|
-
if (obj->u.a.simple) {
|
|
722
|
-
if (k >= 0 && k <= obj->u.a.flat_length) {
|
|
723
|
-
jsR_setarrayindex(J, obj, k, value);
|
|
724
|
-
} else {
|
|
725
|
-
jsR_unflattenarray(J, obj);
|
|
726
|
-
if (obj->u.a.length < k + 1)
|
|
727
|
-
obj->u.a.length = k + 1;
|
|
728
|
-
}
|
|
729
|
-
} else {
|
|
730
|
-
if (obj->u.a.length < k + 1)
|
|
731
|
-
obj->u.a.length = k + 1;
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
else if (obj->type == JS_CSTRING) {
|
|
737
|
-
if (!strcmp(name, "length"))
|
|
738
|
-
goto readonly;
|
|
739
|
-
if (js_isarrayindex(J, name, &k))
|
|
740
|
-
if (k >= 0 && k < obj->u.s.length)
|
|
741
|
-
goto readonly;
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
else if (obj->type == JS_CREGEXP) {
|
|
745
|
-
if (!strcmp(name, "source")) goto readonly;
|
|
746
|
-
if (!strcmp(name, "global")) goto readonly;
|
|
747
|
-
if (!strcmp(name, "ignoreCase")) goto readonly;
|
|
748
|
-
if (!strcmp(name, "multiline")) goto readonly;
|
|
749
|
-
if (!strcmp(name, "lastIndex")) {
|
|
750
|
-
obj->u.r.last = jsV_tointeger(J, value);
|
|
751
|
-
return;
|
|
752
|
-
}
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
else if (obj->type == JS_CUSERDATA) {
|
|
756
|
-
if (obj->u.user.put && obj->u.user.put(J, obj->u.user.data, name))
|
|
757
|
-
return;
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
/* First try to find a setter in prototype chain */
|
|
761
|
-
ref = jsV_getpropertyx(J, obj, name, &own);
|
|
762
|
-
if (ref) {
|
|
763
|
-
if (ref->setter) {
|
|
764
|
-
js_pushobject(J, ref->setter);
|
|
765
|
-
js_pushobject(J, obj);
|
|
766
|
-
js_pushvalue(J, *value);
|
|
767
|
-
js_call(J, 1);
|
|
768
|
-
js_pop(J, 1);
|
|
769
|
-
return;
|
|
770
|
-
} else {
|
|
771
|
-
if (J->strict)
|
|
772
|
-
if (ref->getter)
|
|
773
|
-
js_typeerror(J, "setting property '%s' that only has a getter", name);
|
|
774
|
-
if (ref->atts & JS_READONLY)
|
|
775
|
-
goto readonly;
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
/* Property not found on this object, so create one */
|
|
780
|
-
if (!ref || !own) {
|
|
781
|
-
if (transient) {
|
|
782
|
-
if (J->strict)
|
|
783
|
-
js_typeerror(J, "cannot create property '%s' on transient object", name);
|
|
784
|
-
return;
|
|
785
|
-
}
|
|
786
|
-
ref = jsV_setproperty(J, obj, name);
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
if (ref) {
|
|
790
|
-
if (!(ref->atts & JS_READONLY))
|
|
791
|
-
ref->value = *value;
|
|
792
|
-
else
|
|
793
|
-
goto readonly;
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
return;
|
|
797
|
-
|
|
798
|
-
readonly:
|
|
799
|
-
if (J->strict)
|
|
800
|
-
js_typeerror(J, "'%s' is read-only", name);
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
static void jsR_setindex(js_State *J, js_Object *obj, int k, int transient)
|
|
804
|
-
{
|
|
805
|
-
char buf[32];
|
|
806
|
-
if (obj->type == JS_CARRAY && obj->u.a.simple && k >= 0 && k <= obj->u.a.flat_length) {
|
|
807
|
-
jsR_setarrayindex(J, obj, k, stackidx(J, -1));
|
|
808
|
-
} else {
|
|
809
|
-
jsR_setproperty(J, obj, js_itoa(buf, k), transient);
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
static void jsR_defproperty(js_State *J, js_Object *obj, const char *name,
|
|
814
|
-
int atts, js_Value *value, js_Object *getter, js_Object *setter,
|
|
815
|
-
int throw)
|
|
816
|
-
{
|
|
817
|
-
js_Property *ref;
|
|
818
|
-
int k;
|
|
819
|
-
|
|
820
|
-
if (obj->type == JS_CARRAY) {
|
|
821
|
-
if (!strcmp(name, "length"))
|
|
822
|
-
goto readonly;
|
|
823
|
-
if (obj->u.a.simple)
|
|
824
|
-
jsR_unflattenarray(J, obj);
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
else if (obj->type == JS_CSTRING) {
|
|
828
|
-
if (!strcmp(name, "length"))
|
|
829
|
-
goto readonly;
|
|
830
|
-
if (js_isarrayindex(J, name, &k))
|
|
831
|
-
if (k >= 0 && k < obj->u.s.length)
|
|
832
|
-
goto readonly;
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
else if (obj->type == JS_CREGEXP) {
|
|
836
|
-
if (!strcmp(name, "source")) goto readonly;
|
|
837
|
-
if (!strcmp(name, "global")) goto readonly;
|
|
838
|
-
if (!strcmp(name, "ignoreCase")) goto readonly;
|
|
839
|
-
if (!strcmp(name, "multiline")) goto readonly;
|
|
840
|
-
if (!strcmp(name, "lastIndex")) goto readonly;
|
|
841
|
-
}
|
|
842
|
-
|
|
843
|
-
else if (obj->type == JS_CUSERDATA) {
|
|
844
|
-
if (obj->u.user.put && obj->u.user.put(J, obj->u.user.data, name))
|
|
845
|
-
return;
|
|
846
|
-
}
|
|
847
|
-
|
|
848
|
-
ref = jsV_setproperty(J, obj, name);
|
|
849
|
-
if (ref) {
|
|
850
|
-
if (value) {
|
|
851
|
-
if (!(ref->atts & JS_READONLY))
|
|
852
|
-
ref->value = *value;
|
|
853
|
-
else if (J->strict)
|
|
854
|
-
js_typeerror(J, "'%s' is read-only", name);
|
|
855
|
-
}
|
|
856
|
-
if (getter) {
|
|
857
|
-
if (!(ref->atts & JS_DONTCONF))
|
|
858
|
-
ref->getter = getter;
|
|
859
|
-
else if (J->strict)
|
|
860
|
-
js_typeerror(J, "'%s' is non-configurable", name);
|
|
861
|
-
}
|
|
862
|
-
if (setter) {
|
|
863
|
-
if (!(ref->atts & JS_DONTCONF))
|
|
864
|
-
ref->setter = setter;
|
|
865
|
-
else if (J->strict)
|
|
866
|
-
js_typeerror(J, "'%s' is non-configurable", name);
|
|
867
|
-
}
|
|
868
|
-
ref->atts |= atts;
|
|
869
|
-
}
|
|
870
|
-
|
|
871
|
-
return;
|
|
872
|
-
|
|
873
|
-
readonly:
|
|
874
|
-
if (J->strict || throw)
|
|
875
|
-
js_typeerror(J, "'%s' is read-only or non-configurable", name);
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
static int jsR_delproperty(js_State *J, js_Object *obj, const char *name)
|
|
879
|
-
{
|
|
880
|
-
js_Property *ref;
|
|
881
|
-
int k;
|
|
882
|
-
|
|
883
|
-
if (obj->type == JS_CARRAY) {
|
|
884
|
-
if (!strcmp(name, "length"))
|
|
885
|
-
goto dontconf;
|
|
886
|
-
if (obj->u.a.simple)
|
|
887
|
-
jsR_unflattenarray(J, obj);
|
|
888
|
-
}
|
|
889
|
-
|
|
890
|
-
else if (obj->type == JS_CSTRING) {
|
|
891
|
-
if (!strcmp(name, "length"))
|
|
892
|
-
goto dontconf;
|
|
893
|
-
if (js_isarrayindex(J, name, &k))
|
|
894
|
-
if (k >= 0 && k < obj->u.s.length)
|
|
895
|
-
goto dontconf;
|
|
896
|
-
}
|
|
897
|
-
|
|
898
|
-
else if (obj->type == JS_CREGEXP) {
|
|
899
|
-
if (!strcmp(name, "source")) goto dontconf;
|
|
900
|
-
if (!strcmp(name, "global")) goto dontconf;
|
|
901
|
-
if (!strcmp(name, "ignoreCase")) goto dontconf;
|
|
902
|
-
if (!strcmp(name, "multiline")) goto dontconf;
|
|
903
|
-
if (!strcmp(name, "lastIndex")) goto dontconf;
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
else if (obj->type == JS_CUSERDATA) {
|
|
907
|
-
if (obj->u.user.delete && obj->u.user.delete(J, obj->u.user.data, name))
|
|
908
|
-
return 1;
|
|
909
|
-
}
|
|
910
|
-
|
|
911
|
-
ref = jsV_getownproperty(J, obj, name);
|
|
912
|
-
if (ref) {
|
|
913
|
-
if (ref->atts & JS_DONTCONF)
|
|
914
|
-
goto dontconf;
|
|
915
|
-
jsV_delproperty(J, obj, name);
|
|
916
|
-
}
|
|
917
|
-
return 1;
|
|
918
|
-
|
|
919
|
-
dontconf:
|
|
920
|
-
if (J->strict)
|
|
921
|
-
js_typeerror(J, "'%s' is non-configurable", name);
|
|
922
|
-
return 0;
|
|
923
|
-
}
|
|
924
|
-
|
|
925
|
-
static void jsR_delindex(js_State *J, js_Object *obj, int k)
|
|
926
|
-
{
|
|
927
|
-
char buf[32];
|
|
928
|
-
/* Allow deleting last element of a simple array without unflattening */
|
|
929
|
-
if (obj->type == JS_CARRAY && obj->u.a.simple && k == obj->u.a.flat_length - 1)
|
|
930
|
-
obj->u.a.flat_length = k;
|
|
931
|
-
else
|
|
932
|
-
jsR_delproperty(J, obj, js_itoa(buf, k));
|
|
933
|
-
}
|
|
934
|
-
|
|
935
|
-
/* Registry, global and object property accessors */
|
|
936
|
-
|
|
937
|
-
const char *js_ref(js_State *J)
|
|
938
|
-
{
|
|
939
|
-
js_Value *v = stackidx(J, -1);
|
|
940
|
-
const char *s;
|
|
941
|
-
char buf[32];
|
|
942
|
-
switch (v->t.type) {
|
|
943
|
-
case JS_TUNDEFINED: s = "_Undefined"; break;
|
|
944
|
-
case JS_TNULL: s = "_Null"; break;
|
|
945
|
-
case JS_TBOOLEAN:
|
|
946
|
-
s = v->u.boolean ? "_True" : "_False";
|
|
947
|
-
break;
|
|
948
|
-
case JS_TOBJECT:
|
|
949
|
-
sprintf(buf, "%p", (void*)v->u.object);
|
|
950
|
-
s = js_intern(J, buf);
|
|
951
|
-
break;
|
|
952
|
-
default:
|
|
953
|
-
sprintf(buf, "%d", J->nextref++);
|
|
954
|
-
s = js_intern(J, buf);
|
|
955
|
-
break;
|
|
956
|
-
}
|
|
957
|
-
js_setregistry(J, s);
|
|
958
|
-
return s;
|
|
959
|
-
}
|
|
960
|
-
|
|
961
|
-
void js_unref(js_State *J, const char *ref)
|
|
962
|
-
{
|
|
963
|
-
js_delregistry(J, ref);
|
|
964
|
-
}
|
|
965
|
-
|
|
966
|
-
void js_getregistry(js_State *J, const char *name)
|
|
967
|
-
{
|
|
968
|
-
jsR_getproperty(J, J->R, name);
|
|
969
|
-
}
|
|
970
|
-
|
|
971
|
-
void js_setregistry(js_State *J, const char *name)
|
|
972
|
-
{
|
|
973
|
-
jsR_setproperty(J, J->R, name, 0);
|
|
974
|
-
js_pop(J, 1);
|
|
975
|
-
}
|
|
976
|
-
|
|
977
|
-
void js_delregistry(js_State *J, const char *name)
|
|
978
|
-
{
|
|
979
|
-
jsR_delproperty(J, J->R, name);
|
|
980
|
-
}
|
|
981
|
-
|
|
982
|
-
void js_getglobal(js_State *J, const char *name)
|
|
983
|
-
{
|
|
984
|
-
jsR_getproperty(J, J->G, name);
|
|
985
|
-
}
|
|
986
|
-
|
|
987
|
-
void js_setglobal(js_State *J, const char *name)
|
|
988
|
-
{
|
|
989
|
-
jsR_setproperty(J, J->G, name, 0);
|
|
990
|
-
js_pop(J, 1);
|
|
991
|
-
}
|
|
992
|
-
|
|
993
|
-
void js_defglobal(js_State *J, const char *name, int atts)
|
|
994
|
-
{
|
|
995
|
-
jsR_defproperty(J, J->G, name, atts, stackidx(J, -1), NULL, NULL, 0);
|
|
996
|
-
js_pop(J, 1);
|
|
997
|
-
}
|
|
998
|
-
|
|
999
|
-
void js_delglobal(js_State *J, const char *name)
|
|
1000
|
-
{
|
|
1001
|
-
jsR_delproperty(J, J->G, name);
|
|
1002
|
-
}
|
|
1003
|
-
|
|
1004
|
-
void js_getproperty(js_State *J, int idx, const char *name)
|
|
1005
|
-
{
|
|
1006
|
-
jsR_getproperty(J, js_toobject(J, idx), name);
|
|
1007
|
-
}
|
|
1008
|
-
|
|
1009
|
-
void js_setproperty(js_State *J, int idx, const char *name)
|
|
1010
|
-
{
|
|
1011
|
-
jsR_setproperty(J, js_toobject(J, idx), name, !js_isobject(J, idx));
|
|
1012
|
-
js_pop(J, 1);
|
|
1013
|
-
}
|
|
1014
|
-
|
|
1015
|
-
void js_defproperty(js_State *J, int idx, const char *name, int atts)
|
|
1016
|
-
{
|
|
1017
|
-
jsR_defproperty(J, js_toobject(J, idx), name, atts, stackidx(J, -1), NULL, NULL, 1);
|
|
1018
|
-
js_pop(J, 1);
|
|
1019
|
-
}
|
|
1020
|
-
|
|
1021
|
-
void js_delproperty(js_State *J, int idx, const char *name)
|
|
1022
|
-
{
|
|
1023
|
-
jsR_delproperty(J, js_toobject(J, idx), name);
|
|
1024
|
-
}
|
|
1025
|
-
|
|
1026
|
-
void js_defaccessor(js_State *J, int idx, const char *name, int atts)
|
|
1027
|
-
{
|
|
1028
|
-
jsR_defproperty(J, js_toobject(J, idx), name, atts, NULL, jsR_tofunction(J, -2), jsR_tofunction(J, -1), 1);
|
|
1029
|
-
js_pop(J, 2);
|
|
1030
|
-
}
|
|
1031
|
-
|
|
1032
|
-
int js_hasproperty(js_State *J, int idx, const char *name)
|
|
1033
|
-
{
|
|
1034
|
-
return jsR_hasproperty(J, js_toobject(J, idx), name);
|
|
1035
|
-
}
|
|
1036
|
-
|
|
1037
|
-
void js_getindex(js_State *J, int idx, int i)
|
|
1038
|
-
{
|
|
1039
|
-
jsR_getindex(J, js_toobject(J, idx), i);
|
|
1040
|
-
}
|
|
1041
|
-
|
|
1042
|
-
int js_hasindex(js_State *J, int idx, int i)
|
|
1043
|
-
{
|
|
1044
|
-
return jsR_hasindex(J, js_toobject(J, idx), i);
|
|
1045
|
-
}
|
|
1046
|
-
|
|
1047
|
-
void js_setindex(js_State *J, int idx, int i)
|
|
1048
|
-
{
|
|
1049
|
-
jsR_setindex(J, js_toobject(J, idx), i, !js_isobject(J, idx));
|
|
1050
|
-
js_pop(J, 1);
|
|
1051
|
-
}
|
|
1052
|
-
|
|
1053
|
-
void js_delindex(js_State *J, int idx, int i)
|
|
1054
|
-
{
|
|
1055
|
-
jsR_delindex(J, js_toobject(J, idx), i);
|
|
1056
|
-
}
|
|
1057
|
-
|
|
1058
|
-
/* Iterator */
|
|
1059
|
-
|
|
1060
|
-
void js_pushiterator(js_State *J, int idx, int own)
|
|
1061
|
-
{
|
|
1062
|
-
js_pushobject(J, jsV_newiterator(J, js_toobject(J, idx), own));
|
|
1063
|
-
}
|
|
1064
|
-
|
|
1065
|
-
const char *js_nextiterator(js_State *J, int idx)
|
|
1066
|
-
{
|
|
1067
|
-
return jsV_nextiterator(J, js_toobject(J, idx));
|
|
1068
|
-
}
|
|
1069
|
-
|
|
1070
|
-
/* Environment records */
|
|
1071
|
-
|
|
1072
|
-
js_Environment *jsR_newenvironment(js_State *J, js_Object *vars, js_Environment *outer)
|
|
1073
|
-
{
|
|
1074
|
-
js_Environment *E = js_malloc(J, sizeof *E);
|
|
1075
|
-
E->gcmark = 0;
|
|
1076
|
-
E->gcnext = J->gcenv;
|
|
1077
|
-
J->gcenv = E;
|
|
1078
|
-
++J->gccounter;
|
|
1079
|
-
|
|
1080
|
-
E->outer = outer;
|
|
1081
|
-
E->variables = vars;
|
|
1082
|
-
return E;
|
|
1083
|
-
}
|
|
1084
|
-
|
|
1085
|
-
static void js_initvar(js_State *J, const char *name, int idx)
|
|
1086
|
-
{
|
|
1087
|
-
jsR_defproperty(J, J->E->variables, name, JS_DONTENUM | JS_DONTCONF, stackidx(J, idx), NULL, NULL, 0);
|
|
1088
|
-
}
|
|
1089
|
-
|
|
1090
|
-
static int js_hasvar(js_State *J, const char *name)
|
|
1091
|
-
{
|
|
1092
|
-
js_Environment *E = J->E;
|
|
1093
|
-
do {
|
|
1094
|
-
js_Property *ref = jsV_getproperty(J, E->variables, name);
|
|
1095
|
-
if (ref) {
|
|
1096
|
-
if (ref->getter) {
|
|
1097
|
-
js_pushobject(J, ref->getter);
|
|
1098
|
-
js_pushobject(J, E->variables);
|
|
1099
|
-
js_call(J, 0);
|
|
1100
|
-
} else {
|
|
1101
|
-
js_pushvalue(J, ref->value);
|
|
1102
|
-
}
|
|
1103
|
-
return 1;
|
|
1104
|
-
}
|
|
1105
|
-
E = E->outer;
|
|
1106
|
-
} while (E);
|
|
1107
|
-
return 0;
|
|
1108
|
-
}
|
|
1109
|
-
|
|
1110
|
-
static void js_setvar(js_State *J, const char *name)
|
|
1111
|
-
{
|
|
1112
|
-
js_Environment *E = J->E;
|
|
1113
|
-
do {
|
|
1114
|
-
js_Property *ref = jsV_getproperty(J, E->variables, name);
|
|
1115
|
-
if (ref) {
|
|
1116
|
-
if (ref->setter) {
|
|
1117
|
-
js_pushobject(J, ref->setter);
|
|
1118
|
-
js_pushobject(J, E->variables);
|
|
1119
|
-
js_copy(J, -3);
|
|
1120
|
-
js_call(J, 1);
|
|
1121
|
-
js_pop(J, 1);
|
|
1122
|
-
return;
|
|
1123
|
-
}
|
|
1124
|
-
if (!(ref->atts & JS_READONLY))
|
|
1125
|
-
ref->value = *stackidx(J, -1);
|
|
1126
|
-
else if (J->strict)
|
|
1127
|
-
js_typeerror(J, "'%s' is read-only", name);
|
|
1128
|
-
return;
|
|
1129
|
-
}
|
|
1130
|
-
E = E->outer;
|
|
1131
|
-
} while (E);
|
|
1132
|
-
if (J->strict)
|
|
1133
|
-
js_referenceerror(J, "assignment to undeclared variable '%s'", name);
|
|
1134
|
-
jsR_setproperty(J, J->G, name, 0);
|
|
1135
|
-
}
|
|
1136
|
-
|
|
1137
|
-
static int js_delvar(js_State *J, const char *name)
|
|
1138
|
-
{
|
|
1139
|
-
js_Environment *E = J->E;
|
|
1140
|
-
do {
|
|
1141
|
-
js_Property *ref = jsV_getownproperty(J, E->variables, name);
|
|
1142
|
-
if (ref) {
|
|
1143
|
-
if (ref->atts & JS_DONTCONF) {
|
|
1144
|
-
if (J->strict)
|
|
1145
|
-
js_typeerror(J, "'%s' is non-configurable", name);
|
|
1146
|
-
return 0;
|
|
1147
|
-
}
|
|
1148
|
-
jsV_delproperty(J, E->variables, name);
|
|
1149
|
-
return 1;
|
|
1150
|
-
}
|
|
1151
|
-
E = E->outer;
|
|
1152
|
-
} while (E);
|
|
1153
|
-
return jsR_delproperty(J, J->G, name);
|
|
1154
|
-
}
|
|
1155
|
-
|
|
1156
|
-
/* Function calls */
|
|
1157
|
-
|
|
1158
|
-
static void jsR_savescope(js_State *J, js_Environment *newE)
|
|
1159
|
-
{
|
|
1160
|
-
if (J->envtop + 1 >= JS_ENVLIMIT)
|
|
1161
|
-
js_stackoverflow(J);
|
|
1162
|
-
J->envstack[J->envtop++] = J->E;
|
|
1163
|
-
J->E = newE;
|
|
1164
|
-
}
|
|
1165
|
-
|
|
1166
|
-
static void jsR_restorescope(js_State *J)
|
|
1167
|
-
{
|
|
1168
|
-
J->E = J->envstack[--J->envtop];
|
|
1169
|
-
}
|
|
1170
|
-
|
|
1171
|
-
static void jsR_calllwfunction(js_State *J, int n, js_Function *F, js_Environment *scope)
|
|
1172
|
-
{
|
|
1173
|
-
js_Value v;
|
|
1174
|
-
int i;
|
|
1175
|
-
|
|
1176
|
-
jsR_savescope(J, scope);
|
|
1177
|
-
|
|
1178
|
-
if (n > F->numparams) {
|
|
1179
|
-
js_pop(J, n - F->numparams);
|
|
1180
|
-
n = F->numparams;
|
|
1181
|
-
}
|
|
1182
|
-
|
|
1183
|
-
for (i = n; i < F->varlen; ++i)
|
|
1184
|
-
js_pushundefined(J);
|
|
1185
|
-
|
|
1186
|
-
jsR_run(J, F);
|
|
1187
|
-
v = *stackidx(J, -1);
|
|
1188
|
-
TOP = --BOT; /* clear stack */
|
|
1189
|
-
js_pushvalue(J, v);
|
|
1190
|
-
|
|
1191
|
-
jsR_restorescope(J);
|
|
1192
|
-
}
|
|
1193
|
-
|
|
1194
|
-
static void jsR_callfunction(js_State *J, int n, js_Function *F, js_Environment *scope)
|
|
1195
|
-
{
|
|
1196
|
-
js_Value v;
|
|
1197
|
-
int i;
|
|
1198
|
-
|
|
1199
|
-
scope = jsR_newenvironment(J, jsV_newobject(J, JS_COBJECT, NULL), scope);
|
|
1200
|
-
|
|
1201
|
-
jsR_savescope(J, scope);
|
|
1202
|
-
|
|
1203
|
-
if (F->arguments) {
|
|
1204
|
-
js_newarguments(J);
|
|
1205
|
-
if (!J->strict) {
|
|
1206
|
-
js_currentfunction(J);
|
|
1207
|
-
js_defproperty(J, -2, "callee", JS_DONTENUM);
|
|
1208
|
-
}
|
|
1209
|
-
js_pushnumber(J, n);
|
|
1210
|
-
js_defproperty(J, -2, "length", JS_DONTENUM);
|
|
1211
|
-
for (i = 0; i < n; ++i) {
|
|
1212
|
-
js_copy(J, i + 1);
|
|
1213
|
-
js_setindex(J, -2, i);
|
|
1214
|
-
}
|
|
1215
|
-
js_initvar(J, "arguments", -1);
|
|
1216
|
-
js_pop(J, 1);
|
|
1217
|
-
}
|
|
1218
|
-
|
|
1219
|
-
for (i = 0; i < n && i < F->numparams; ++i)
|
|
1220
|
-
js_initvar(J, F->vartab[i], i + 1);
|
|
1221
|
-
js_pop(J, n);
|
|
1222
|
-
|
|
1223
|
-
for (; i < F->varlen; ++i) {
|
|
1224
|
-
js_pushundefined(J);
|
|
1225
|
-
js_initvar(J, F->vartab[i], -1);
|
|
1226
|
-
js_pop(J, 1);
|
|
1227
|
-
}
|
|
1228
|
-
|
|
1229
|
-
jsR_run(J, F);
|
|
1230
|
-
v = *stackidx(J, -1);
|
|
1231
|
-
TOP = --BOT; /* clear stack */
|
|
1232
|
-
js_pushvalue(J, v);
|
|
1233
|
-
|
|
1234
|
-
jsR_restorescope(J);
|
|
1235
|
-
}
|
|
1236
|
-
|
|
1237
|
-
static void jsR_callscript(js_State *J, int n, js_Function *F, js_Environment *scope)
|
|
1238
|
-
{
|
|
1239
|
-
js_Value v;
|
|
1240
|
-
int i;
|
|
1241
|
-
|
|
1242
|
-
if (scope)
|
|
1243
|
-
jsR_savescope(J, scope);
|
|
1244
|
-
|
|
1245
|
-
/* scripts take no arguments */
|
|
1246
|
-
js_pop(J, n);
|
|
1247
|
-
|
|
1248
|
-
for (i = 0; i < F->varlen; ++i) {
|
|
1249
|
-
/* Bug 701886: don't redefine existing vars in eval/scripts */
|
|
1250
|
-
if (!js_hasvar(J, F->vartab[i])) {
|
|
1251
|
-
js_pushundefined(J);
|
|
1252
|
-
js_initvar(J, F->vartab[i], -1);
|
|
1253
|
-
js_pop(J, 1);
|
|
1254
|
-
}
|
|
1255
|
-
}
|
|
1256
|
-
|
|
1257
|
-
jsR_run(J, F);
|
|
1258
|
-
v = *stackidx(J, -1);
|
|
1259
|
-
TOP = --BOT; /* clear stack */
|
|
1260
|
-
js_pushvalue(J, v);
|
|
1261
|
-
|
|
1262
|
-
if (scope)
|
|
1263
|
-
jsR_restorescope(J);
|
|
1264
|
-
}
|
|
1265
|
-
|
|
1266
|
-
static void jsR_callcfunction(js_State *J, int n, int min, js_CFunction F)
|
|
1267
|
-
{
|
|
1268
|
-
int save_top;
|
|
1269
|
-
int i;
|
|
1270
|
-
js_Value v;
|
|
1271
|
-
|
|
1272
|
-
for (i = n; i < min; ++i)
|
|
1273
|
-
js_pushundefined(J);
|
|
1274
|
-
|
|
1275
|
-
save_top = TOP;
|
|
1276
|
-
F(J);
|
|
1277
|
-
if (TOP > save_top) {
|
|
1278
|
-
v = *stackidx(J, -1);
|
|
1279
|
-
TOP = --BOT; /* clear stack */
|
|
1280
|
-
js_pushvalue(J, v);
|
|
1281
|
-
} else {
|
|
1282
|
-
TOP = --BOT; /* clear stack */
|
|
1283
|
-
js_pushundefined(J);
|
|
1284
|
-
}
|
|
1285
|
-
}
|
|
1286
|
-
|
|
1287
|
-
static void jsR_pushtrace(js_State *J, const char *name, const char *file, int line)
|
|
1288
|
-
{
|
|
1289
|
-
if (J->tracetop + 1 == JS_ENVLIMIT)
|
|
1290
|
-
js_error(J, "call stack overflow");
|
|
1291
|
-
++J->tracetop;
|
|
1292
|
-
J->trace[J->tracetop].name = name;
|
|
1293
|
-
J->trace[J->tracetop].file = file;
|
|
1294
|
-
J->trace[J->tracetop].line = line;
|
|
1295
|
-
}
|
|
1296
|
-
|
|
1297
|
-
void js_call(js_State *J, int n)
|
|
1298
|
-
{
|
|
1299
|
-
js_Object *obj;
|
|
1300
|
-
int savebot;
|
|
1301
|
-
|
|
1302
|
-
if (n < 0)
|
|
1303
|
-
js_rangeerror(J, "number of arguments cannot be negative");
|
|
1304
|
-
|
|
1305
|
-
if (!js_iscallable(J, -n-2))
|
|
1306
|
-
js_typeerror(J, "%s is not callable", js_typeof(J, -n-2));
|
|
1307
|
-
|
|
1308
|
-
obj = js_toobject(J, -n-2);
|
|
1309
|
-
|
|
1310
|
-
savebot = BOT;
|
|
1311
|
-
BOT = TOP - n - 1;
|
|
1312
|
-
|
|
1313
|
-
if (obj->type == JS_CFUNCTION) {
|
|
1314
|
-
jsR_pushtrace(J, obj->u.f.function->name, obj->u.f.function->filename, obj->u.f.function->line);
|
|
1315
|
-
if (obj->u.f.function->lightweight)
|
|
1316
|
-
jsR_calllwfunction(J, n, obj->u.f.function, obj->u.f.scope);
|
|
1317
|
-
else
|
|
1318
|
-
jsR_callfunction(J, n, obj->u.f.function, obj->u.f.scope);
|
|
1319
|
-
--J->tracetop;
|
|
1320
|
-
} else if (obj->type == JS_CSCRIPT) {
|
|
1321
|
-
jsR_pushtrace(J, obj->u.f.function->name, obj->u.f.function->filename, obj->u.f.function->line);
|
|
1322
|
-
jsR_callscript(J, n, obj->u.f.function, obj->u.f.scope);
|
|
1323
|
-
--J->tracetop;
|
|
1324
|
-
} else if (obj->type == JS_CCFUNCTION) {
|
|
1325
|
-
jsR_pushtrace(J, obj->u.c.name, "native", 0);
|
|
1326
|
-
jsR_callcfunction(J, n, obj->u.c.length, obj->u.c.function);
|
|
1327
|
-
--J->tracetop;
|
|
1328
|
-
}
|
|
1329
|
-
|
|
1330
|
-
BOT = savebot;
|
|
1331
|
-
}
|
|
1332
|
-
|
|
1333
|
-
void js_construct(js_State *J, int n)
|
|
1334
|
-
{
|
|
1335
|
-
js_Object *obj;
|
|
1336
|
-
js_Object *prototype;
|
|
1337
|
-
js_Object *newobj;
|
|
1338
|
-
|
|
1339
|
-
if (!js_iscallable(J, -n-1))
|
|
1340
|
-
js_typeerror(J, "%s is not callable", js_typeof(J, -n-1));
|
|
1341
|
-
|
|
1342
|
-
obj = js_toobject(J, -n-1);
|
|
1343
|
-
|
|
1344
|
-
/* built-in constructors create their own objects, give them a 'null' this */
|
|
1345
|
-
if (obj->type == JS_CCFUNCTION && obj->u.c.constructor) {
|
|
1346
|
-
int savebot = BOT;
|
|
1347
|
-
js_pushnull(J);
|
|
1348
|
-
if (n > 0)
|
|
1349
|
-
js_rot(J, n + 1);
|
|
1350
|
-
BOT = TOP - n - 1;
|
|
1351
|
-
|
|
1352
|
-
jsR_pushtrace(J, obj->u.c.name, "native", 0);
|
|
1353
|
-
jsR_callcfunction(J, n, obj->u.c.length, obj->u.c.constructor);
|
|
1354
|
-
--J->tracetop;
|
|
1355
|
-
|
|
1356
|
-
BOT = savebot;
|
|
1357
|
-
return;
|
|
1358
|
-
}
|
|
1359
|
-
|
|
1360
|
-
/* extract the function object's prototype property */
|
|
1361
|
-
js_getproperty(J, -n - 1, "prototype");
|
|
1362
|
-
if (js_isobject(J, -1))
|
|
1363
|
-
prototype = js_toobject(J, -1);
|
|
1364
|
-
else
|
|
1365
|
-
prototype = J->Object_prototype;
|
|
1366
|
-
js_pop(J, 1);
|
|
1367
|
-
|
|
1368
|
-
/* create a new object with above prototype, and shift it into the 'this' slot */
|
|
1369
|
-
newobj = jsV_newobject(J, JS_COBJECT, prototype);
|
|
1370
|
-
js_pushobject(J, newobj);
|
|
1371
|
-
if (n > 0)
|
|
1372
|
-
js_rot(J, n + 1);
|
|
1373
|
-
|
|
1374
|
-
/* and save a copy to return */
|
|
1375
|
-
js_pushobject(J, newobj);
|
|
1376
|
-
js_rot(J, n + 3);
|
|
1377
|
-
|
|
1378
|
-
/* call the function */
|
|
1379
|
-
js_call(J, n);
|
|
1380
|
-
|
|
1381
|
-
/* if result is not an object, return the original object we created */
|
|
1382
|
-
if (!js_isobject(J, -1)) {
|
|
1383
|
-
js_pop(J, 1);
|
|
1384
|
-
} else {
|
|
1385
|
-
js_rot2pop1(J);
|
|
1386
|
-
}
|
|
1387
|
-
}
|
|
1388
|
-
|
|
1389
|
-
void js_eval(js_State *J)
|
|
1390
|
-
{
|
|
1391
|
-
if (!js_isstring(J, -1))
|
|
1392
|
-
return;
|
|
1393
|
-
js_loadeval(J, "(eval)", js_tostring(J, -1));
|
|
1394
|
-
js_rot2pop1(J);
|
|
1395
|
-
js_copy(J, 0); /* copy 'this' */
|
|
1396
|
-
js_call(J, 0);
|
|
1397
|
-
}
|
|
1398
|
-
|
|
1399
|
-
int js_pconstruct(js_State *J, int n)
|
|
1400
|
-
{
|
|
1401
|
-
int savetop = TOP - n - 2;
|
|
1402
|
-
if (js_try(J)) {
|
|
1403
|
-
/* clean up the stack to only hold the error object */
|
|
1404
|
-
STACK[savetop] = STACK[TOP-1];
|
|
1405
|
-
TOP = savetop + 1;
|
|
1406
|
-
return 1;
|
|
1407
|
-
}
|
|
1408
|
-
js_construct(J, n);
|
|
1409
|
-
js_endtry(J);
|
|
1410
|
-
return 0;
|
|
1411
|
-
}
|
|
1412
|
-
|
|
1413
|
-
int js_pcall(js_State *J, int n)
|
|
1414
|
-
{
|
|
1415
|
-
int savetop = TOP - n - 2;
|
|
1416
|
-
if (js_try(J)) {
|
|
1417
|
-
/* clean up the stack to only hold the error object */
|
|
1418
|
-
STACK[savetop] = STACK[TOP-1];
|
|
1419
|
-
TOP = savetop + 1;
|
|
1420
|
-
return 1;
|
|
1421
|
-
}
|
|
1422
|
-
js_call(J, n);
|
|
1423
|
-
js_endtry(J);
|
|
1424
|
-
return 0;
|
|
1425
|
-
}
|
|
1426
|
-
|
|
1427
|
-
/* Exceptions */
|
|
1428
|
-
|
|
1429
|
-
void *js_savetrypc(js_State *J, js_Instruction *pc)
|
|
1430
|
-
{
|
|
1431
|
-
if (J->trytop == JS_TRYLIMIT)
|
|
1432
|
-
js_trystackoverflow(J);
|
|
1433
|
-
J->trybuf[J->trytop].E = J->E;
|
|
1434
|
-
J->trybuf[J->trytop].envtop = J->envtop;
|
|
1435
|
-
J->trybuf[J->trytop].tracetop = J->tracetop;
|
|
1436
|
-
J->trybuf[J->trytop].top = J->top;
|
|
1437
|
-
J->trybuf[J->trytop].bot = J->bot;
|
|
1438
|
-
J->trybuf[J->trytop].strict = J->strict;
|
|
1439
|
-
J->trybuf[J->trytop].pc = pc;
|
|
1440
|
-
return J->trybuf[J->trytop++].buf;
|
|
1441
|
-
}
|
|
1442
|
-
|
|
1443
|
-
void *js_savetry(js_State *J)
|
|
1444
|
-
{
|
|
1445
|
-
if (J->trytop == JS_TRYLIMIT)
|
|
1446
|
-
js_trystackoverflow(J);
|
|
1447
|
-
J->trybuf[J->trytop].E = J->E;
|
|
1448
|
-
J->trybuf[J->trytop].envtop = J->envtop;
|
|
1449
|
-
J->trybuf[J->trytop].tracetop = J->tracetop;
|
|
1450
|
-
J->trybuf[J->trytop].top = J->top;
|
|
1451
|
-
J->trybuf[J->trytop].bot = J->bot;
|
|
1452
|
-
J->trybuf[J->trytop].strict = J->strict;
|
|
1453
|
-
J->trybuf[J->trytop].pc = NULL;
|
|
1454
|
-
return J->trybuf[J->trytop++].buf;
|
|
1455
|
-
}
|
|
1456
|
-
|
|
1457
|
-
void js_endtry(js_State *J)
|
|
1458
|
-
{
|
|
1459
|
-
if (J->trytop == 0)
|
|
1460
|
-
js_error(J, "endtry: exception stack underflow");
|
|
1461
|
-
--J->trytop;
|
|
1462
|
-
}
|
|
1463
|
-
|
|
1464
|
-
void js_throw(js_State *J)
|
|
1465
|
-
{
|
|
1466
|
-
if (J->trytop > 0) {
|
|
1467
|
-
js_Value v = *stackidx(J, -1);
|
|
1468
|
-
--J->trytop;
|
|
1469
|
-
J->E = J->trybuf[J->trytop].E;
|
|
1470
|
-
J->envtop = J->trybuf[J->trytop].envtop;
|
|
1471
|
-
J->tracetop = J->trybuf[J->trytop].tracetop;
|
|
1472
|
-
J->top = J->trybuf[J->trytop].top;
|
|
1473
|
-
J->bot = J->trybuf[J->trytop].bot;
|
|
1474
|
-
J->strict = J->trybuf[J->trytop].strict;
|
|
1475
|
-
js_pushvalue(J, v);
|
|
1476
|
-
longjmp(J->trybuf[J->trytop].buf, 1);
|
|
1477
|
-
}
|
|
1478
|
-
if (J->panic)
|
|
1479
|
-
J->panic(J);
|
|
1480
|
-
abort();
|
|
1481
|
-
}
|
|
1482
|
-
|
|
1483
|
-
/* Main interpreter loop */
|
|
1484
|
-
|
|
1485
|
-
static void js_dumpvalue(js_State *J, js_Value v)
|
|
1486
|
-
{
|
|
1487
|
-
switch (v.t.type) {
|
|
1488
|
-
case JS_TUNDEFINED: printf("undefined"); break;
|
|
1489
|
-
case JS_TNULL: printf("null"); break;
|
|
1490
|
-
case JS_TBOOLEAN: printf(v.u.boolean ? "true" : "false"); break;
|
|
1491
|
-
case JS_TNUMBER: printf("%.9g", v.u.number); break;
|
|
1492
|
-
case JS_TSHRSTR: printf("'%s'", v.u.shrstr); break;
|
|
1493
|
-
case JS_TLITSTR: printf("'%s'", v.u.litstr); break;
|
|
1494
|
-
case JS_TMEMSTR: printf("'%s'", v.u.memstr->p); break;
|
|
1495
|
-
case JS_TOBJECT:
|
|
1496
|
-
if (v.u.object == J->G) {
|
|
1497
|
-
printf("[Global]");
|
|
1498
|
-
break;
|
|
1499
|
-
}
|
|
1500
|
-
switch (v.u.object->type) {
|
|
1501
|
-
case JS_COBJECT: printf("[Object %p]", (void*)v.u.object); break;
|
|
1502
|
-
case JS_CARRAY: printf("[Array %p]", (void*)v.u.object); break;
|
|
1503
|
-
case JS_CFUNCTION:
|
|
1504
|
-
printf("[Function %p, %s, %s:%d]",
|
|
1505
|
-
(void*)v.u.object,
|
|
1506
|
-
v.u.object->u.f.function->name,
|
|
1507
|
-
v.u.object->u.f.function->filename,
|
|
1508
|
-
v.u.object->u.f.function->line);
|
|
1509
|
-
break;
|
|
1510
|
-
case JS_CSCRIPT: printf("[Script %s]", v.u.object->u.f.function->filename); break;
|
|
1511
|
-
case JS_CCFUNCTION: printf("[CFunction %s]", v.u.object->u.c.name); break;
|
|
1512
|
-
case JS_CBOOLEAN: printf("[Boolean %d]", v.u.object->u.boolean); break;
|
|
1513
|
-
case JS_CNUMBER: printf("[Number %g]", v.u.object->u.number); break;
|
|
1514
|
-
case JS_CSTRING: printf("[String'%s']", v.u.object->u.s.string); break;
|
|
1515
|
-
case JS_CERROR: printf("[Error]"); break;
|
|
1516
|
-
case JS_CARGUMENTS: printf("[Arguments %p]", (void*)v.u.object); break;
|
|
1517
|
-
case JS_CITERATOR: printf("[Iterator %p]", (void*)v.u.object); break;
|
|
1518
|
-
case JS_CUSERDATA:
|
|
1519
|
-
printf("[Userdata %s %p]", v.u.object->u.user.tag, v.u.object->u.user.data);
|
|
1520
|
-
break;
|
|
1521
|
-
default: printf("[Object %p]", (void*)v.u.object); break;
|
|
1522
|
-
}
|
|
1523
|
-
break;
|
|
1524
|
-
}
|
|
1525
|
-
}
|
|
1526
|
-
|
|
1527
|
-
static void js_stacktrace(js_State *J)
|
|
1528
|
-
{
|
|
1529
|
-
int n;
|
|
1530
|
-
printf("stack trace:\n");
|
|
1531
|
-
for (n = J->tracetop; n >= 0; --n) {
|
|
1532
|
-
const char *name = J->trace[n].name;
|
|
1533
|
-
const char *file = J->trace[n].file;
|
|
1534
|
-
int line = J->trace[n].line;
|
|
1535
|
-
if (line > 0) {
|
|
1536
|
-
if (name[0])
|
|
1537
|
-
printf("\tat %s (%s:%d)\n", name, file, line);
|
|
1538
|
-
else
|
|
1539
|
-
printf("\tat %s:%d\n", file, line);
|
|
1540
|
-
} else
|
|
1541
|
-
printf("\tat %s (%s)\n", name, file);
|
|
1542
|
-
}
|
|
1543
|
-
}
|
|
1544
|
-
|
|
1545
|
-
static void js_dumpstack(js_State *J)
|
|
1546
|
-
{
|
|
1547
|
-
int i;
|
|
1548
|
-
printf("stack {\n");
|
|
1549
|
-
for (i = 0; i < TOP; ++i) {
|
|
1550
|
-
putchar(i == BOT ? '>' : ' ');
|
|
1551
|
-
printf("%4d: ", i);
|
|
1552
|
-
js_dumpvalue(J, STACK[i]);
|
|
1553
|
-
putchar('\n');
|
|
1554
|
-
}
|
|
1555
|
-
printf("}\n");
|
|
1556
|
-
}
|
|
1557
|
-
|
|
1558
|
-
void js_trap(js_State *J, int pc)
|
|
1559
|
-
{
|
|
1560
|
-
js_dumpstack(J);
|
|
1561
|
-
js_stacktrace(J);
|
|
1562
|
-
}
|
|
1563
|
-
|
|
1564
|
-
static int jsR_isindex(js_State *J, int idx, int *k)
|
|
1565
|
-
{
|
|
1566
|
-
js_Value *v = stackidx(J, idx);
|
|
1567
|
-
if (v->t.type == JS_TNUMBER) {
|
|
1568
|
-
*k = v->u.number;
|
|
1569
|
-
return *k == v->u.number && *k >= 0;
|
|
1570
|
-
}
|
|
1571
|
-
return 0;
|
|
1572
|
-
}
|
|
1573
|
-
|
|
1574
|
-
static void jsR_run(js_State *J, js_Function *F)
|
|
1575
|
-
{
|
|
1576
|
-
js_Function **FT = F->funtab;
|
|
1577
|
-
const char **VT = F->vartab-1;
|
|
1578
|
-
int lightweight = F->lightweight;
|
|
1579
|
-
js_Instruction *pcstart = F->code;
|
|
1580
|
-
js_Instruction *pc = F->code;
|
|
1581
|
-
enum js_OpCode opcode;
|
|
1582
|
-
int offset;
|
|
1583
|
-
int savestrict;
|
|
1584
|
-
|
|
1585
|
-
const char *str;
|
|
1586
|
-
js_Object *obj;
|
|
1587
|
-
double x, y;
|
|
1588
|
-
unsigned int ux, uy;
|
|
1589
|
-
int ix, iy, okay;
|
|
1590
|
-
int b;
|
|
1591
|
-
int transient;
|
|
1592
|
-
|
|
1593
|
-
savestrict = J->strict;
|
|
1594
|
-
J->strict = F->strict;
|
|
1595
|
-
|
|
1596
|
-
#define READSTRING() \
|
|
1597
|
-
memcpy(&str, pc, sizeof(str)); \
|
|
1598
|
-
pc += sizeof(str) / sizeof(*pc)
|
|
1599
|
-
|
|
1600
|
-
while (1) {
|
|
1601
|
-
if (J->runlimit > 0) {
|
|
1602
|
-
if (J->runlimit == 1)
|
|
1603
|
-
js_runlimit(J);
|
|
1604
|
-
--J->runlimit;
|
|
1605
|
-
}
|
|
1606
|
-
|
|
1607
|
-
if (J->gccounter > J->gcthresh)
|
|
1608
|
-
js_gc(J, 0);
|
|
1609
|
-
|
|
1610
|
-
J->trace[J->tracetop].line = *pc++;
|
|
1611
|
-
|
|
1612
|
-
opcode = *pc++;
|
|
1613
|
-
|
|
1614
|
-
switch (opcode) {
|
|
1615
|
-
case OP_POP: js_pop(J, 1); break;
|
|
1616
|
-
case OP_DUP: js_dup(J); break;
|
|
1617
|
-
case OP_DUP2: js_dup2(J); break;
|
|
1618
|
-
case OP_ROT2: js_rot2(J); break;
|
|
1619
|
-
case OP_ROT3: js_rot3(J); break;
|
|
1620
|
-
case OP_ROT4: js_rot4(J); break;
|
|
1621
|
-
|
|
1622
|
-
case OP_INTEGER:
|
|
1623
|
-
js_pushnumber(J, *pc++ - 32768);
|
|
1624
|
-
break;
|
|
1625
|
-
|
|
1626
|
-
case OP_NUMBER:
|
|
1627
|
-
memcpy(&x, pc, sizeof(x));
|
|
1628
|
-
pc += sizeof(x) / sizeof(*pc);
|
|
1629
|
-
js_pushnumber(J, x);
|
|
1630
|
-
break;
|
|
1631
|
-
|
|
1632
|
-
case OP_STRING:
|
|
1633
|
-
READSTRING();
|
|
1634
|
-
js_pushliteral(J, str);
|
|
1635
|
-
break;
|
|
1636
|
-
|
|
1637
|
-
case OP_CLOSURE: js_newfunction(J, FT[*pc++], J->E); break;
|
|
1638
|
-
case OP_NEWOBJECT: js_newobject(J); break;
|
|
1639
|
-
case OP_NEWARRAY: js_newarray(J); break;
|
|
1640
|
-
case OP_NEWREGEXP:
|
|
1641
|
-
READSTRING();
|
|
1642
|
-
js_newregexp(J, str, *pc++);
|
|
1643
|
-
break;
|
|
1644
|
-
|
|
1645
|
-
case OP_UNDEF: js_pushundefined(J); break;
|
|
1646
|
-
case OP_NULL: js_pushnull(J); break;
|
|
1647
|
-
case OP_TRUE: js_pushboolean(J, 1); break;
|
|
1648
|
-
case OP_FALSE: js_pushboolean(J, 0); break;
|
|
1649
|
-
|
|
1650
|
-
case OP_THIS:
|
|
1651
|
-
if (J->strict) {
|
|
1652
|
-
js_copy(J, 0);
|
|
1653
|
-
} else {
|
|
1654
|
-
if (js_iscoercible(J, 0))
|
|
1655
|
-
js_copy(J, 0);
|
|
1656
|
-
else
|
|
1657
|
-
js_pushglobal(J);
|
|
1658
|
-
}
|
|
1659
|
-
break;
|
|
1660
|
-
|
|
1661
|
-
case OP_CURRENT:
|
|
1662
|
-
js_currentfunction(J);
|
|
1663
|
-
break;
|
|
1664
|
-
|
|
1665
|
-
case OP_GETLOCAL:
|
|
1666
|
-
if (lightweight) {
|
|
1667
|
-
CHECKSTACK(1);
|
|
1668
|
-
STACK[TOP++] = STACK[BOT + *pc++];
|
|
1669
|
-
} else {
|
|
1670
|
-
str = VT[*pc++];
|
|
1671
|
-
if (!js_hasvar(J, str))
|
|
1672
|
-
js_referenceerror(J, "'%s' is not defined", str);
|
|
1673
|
-
}
|
|
1674
|
-
break;
|
|
1675
|
-
|
|
1676
|
-
case OP_SETLOCAL:
|
|
1677
|
-
if (lightweight) {
|
|
1678
|
-
STACK[BOT + *pc++] = STACK[TOP-1];
|
|
1679
|
-
} else {
|
|
1680
|
-
js_setvar(J, VT[*pc++]);
|
|
1681
|
-
}
|
|
1682
|
-
break;
|
|
1683
|
-
|
|
1684
|
-
case OP_DELLOCAL:
|
|
1685
|
-
if (lightweight) {
|
|
1686
|
-
++pc;
|
|
1687
|
-
js_pushboolean(J, 0);
|
|
1688
|
-
} else {
|
|
1689
|
-
b = js_delvar(J, VT[*pc++]);
|
|
1690
|
-
js_pushboolean(J, b);
|
|
1691
|
-
}
|
|
1692
|
-
break;
|
|
1693
|
-
|
|
1694
|
-
case OP_GETVAR:
|
|
1695
|
-
READSTRING();
|
|
1696
|
-
if (!js_hasvar(J, str))
|
|
1697
|
-
js_referenceerror(J, "'%s' is not defined", str);
|
|
1698
|
-
break;
|
|
1699
|
-
|
|
1700
|
-
case OP_HASVAR:
|
|
1701
|
-
READSTRING();
|
|
1702
|
-
if (!js_hasvar(J, str))
|
|
1703
|
-
js_pushundefined(J);
|
|
1704
|
-
break;
|
|
1705
|
-
|
|
1706
|
-
case OP_SETVAR:
|
|
1707
|
-
READSTRING();
|
|
1708
|
-
js_setvar(J, str);
|
|
1709
|
-
break;
|
|
1710
|
-
|
|
1711
|
-
case OP_DELVAR:
|
|
1712
|
-
READSTRING();
|
|
1713
|
-
b = js_delvar(J, str);
|
|
1714
|
-
js_pushboolean(J, b);
|
|
1715
|
-
break;
|
|
1716
|
-
|
|
1717
|
-
case OP_IN:
|
|
1718
|
-
str = js_tostring(J, -2);
|
|
1719
|
-
if (!js_isobject(J, -1))
|
|
1720
|
-
js_typeerror(J, "operand to 'in' is not an object");
|
|
1721
|
-
b = js_hasproperty(J, -1, str);
|
|
1722
|
-
js_pop(J, 2 + b);
|
|
1723
|
-
js_pushboolean(J, b);
|
|
1724
|
-
break;
|
|
1725
|
-
|
|
1726
|
-
case OP_SKIPARRAY:
|
|
1727
|
-
js_setlength(J, -1, js_getlength(J, -1) + 1);
|
|
1728
|
-
break;
|
|
1729
|
-
case OP_INITARRAY:
|
|
1730
|
-
js_setindex(J, -2, js_getlength(J, -2));
|
|
1731
|
-
break;
|
|
1732
|
-
|
|
1733
|
-
case OP_INITPROP:
|
|
1734
|
-
obj = js_toobject(J, -3);
|
|
1735
|
-
str = js_tostring(J, -2);
|
|
1736
|
-
jsR_setproperty(J, obj, str, 0);
|
|
1737
|
-
js_pop(J, 2);
|
|
1738
|
-
break;
|
|
1739
|
-
|
|
1740
|
-
case OP_INITGETTER:
|
|
1741
|
-
obj = js_toobject(J, -3);
|
|
1742
|
-
str = js_tostring(J, -2);
|
|
1743
|
-
jsR_defproperty(J, obj, str, 0, NULL, jsR_tofunction(J, -1), NULL, 0);
|
|
1744
|
-
js_pop(J, 2);
|
|
1745
|
-
break;
|
|
1746
|
-
|
|
1747
|
-
case OP_INITSETTER:
|
|
1748
|
-
obj = js_toobject(J, -3);
|
|
1749
|
-
str = js_tostring(J, -2);
|
|
1750
|
-
jsR_defproperty(J, obj, str, 0, NULL, NULL, jsR_tofunction(J, -1), 0);
|
|
1751
|
-
js_pop(J, 2);
|
|
1752
|
-
break;
|
|
1753
|
-
|
|
1754
|
-
case OP_GETPROP:
|
|
1755
|
-
if (jsR_isindex(J, -1, &ix)) {
|
|
1756
|
-
obj = js_toobject(J, -2);
|
|
1757
|
-
jsR_getindex(J, obj, ix);
|
|
1758
|
-
} else {
|
|
1759
|
-
str = js_tostring(J, -1);
|
|
1760
|
-
obj = js_toobject(J, -2);
|
|
1761
|
-
jsR_getproperty(J, obj, str);
|
|
1762
|
-
}
|
|
1763
|
-
js_rot3pop2(J);
|
|
1764
|
-
break;
|
|
1765
|
-
|
|
1766
|
-
case OP_GETPROP_S:
|
|
1767
|
-
READSTRING();
|
|
1768
|
-
obj = js_toobject(J, -1);
|
|
1769
|
-
jsR_getproperty(J, obj, str);
|
|
1770
|
-
js_rot2pop1(J);
|
|
1771
|
-
break;
|
|
1772
|
-
|
|
1773
|
-
case OP_SETPROP:
|
|
1774
|
-
if (jsR_isindex(J, -2, &ix)) {
|
|
1775
|
-
obj = js_toobject(J, -3);
|
|
1776
|
-
transient = !js_isobject(J, -3);
|
|
1777
|
-
jsR_setindex(J, obj, ix, transient);
|
|
1778
|
-
} else {
|
|
1779
|
-
str = js_tostring(J, -2);
|
|
1780
|
-
obj = js_toobject(J, -3);
|
|
1781
|
-
transient = !js_isobject(J, -3);
|
|
1782
|
-
jsR_setproperty(J, obj, str, transient);
|
|
1783
|
-
}
|
|
1784
|
-
js_rot3pop2(J);
|
|
1785
|
-
break;
|
|
1786
|
-
|
|
1787
|
-
case OP_SETPROP_S:
|
|
1788
|
-
READSTRING();
|
|
1789
|
-
obj = js_toobject(J, -2);
|
|
1790
|
-
transient = !js_isobject(J, -2);
|
|
1791
|
-
jsR_setproperty(J, obj, str, transient);
|
|
1792
|
-
js_rot2pop1(J);
|
|
1793
|
-
break;
|
|
1794
|
-
|
|
1795
|
-
case OP_DELPROP:
|
|
1796
|
-
str = js_tostring(J, -1);
|
|
1797
|
-
obj = js_toobject(J, -2);
|
|
1798
|
-
b = jsR_delproperty(J, obj, str);
|
|
1799
|
-
js_pop(J, 2);
|
|
1800
|
-
js_pushboolean(J, b);
|
|
1801
|
-
break;
|
|
1802
|
-
|
|
1803
|
-
case OP_DELPROP_S:
|
|
1804
|
-
READSTRING();
|
|
1805
|
-
obj = js_toobject(J, -1);
|
|
1806
|
-
b = jsR_delproperty(J, obj, str);
|
|
1807
|
-
js_pop(J, 1);
|
|
1808
|
-
js_pushboolean(J, b);
|
|
1809
|
-
break;
|
|
1810
|
-
|
|
1811
|
-
case OP_ITERATOR:
|
|
1812
|
-
if (js_iscoercible(J, -1)) {
|
|
1813
|
-
obj = jsV_newiterator(J, js_toobject(J, -1), 0);
|
|
1814
|
-
js_pop(J, 1);
|
|
1815
|
-
js_pushobject(J, obj);
|
|
1816
|
-
}
|
|
1817
|
-
break;
|
|
1818
|
-
|
|
1819
|
-
case OP_NEXTITER:
|
|
1820
|
-
if (js_isobject(J, -1)) {
|
|
1821
|
-
obj = js_toobject(J, -1);
|
|
1822
|
-
str = jsV_nextiterator(J, obj);
|
|
1823
|
-
if (str) {
|
|
1824
|
-
js_pushstring(J, str);
|
|
1825
|
-
js_pushboolean(J, 1);
|
|
1826
|
-
} else {
|
|
1827
|
-
js_pop(J, 1);
|
|
1828
|
-
js_pushboolean(J, 0);
|
|
1829
|
-
}
|
|
1830
|
-
} else {
|
|
1831
|
-
js_pop(J, 1);
|
|
1832
|
-
js_pushboolean(J, 0);
|
|
1833
|
-
}
|
|
1834
|
-
break;
|
|
1835
|
-
|
|
1836
|
-
/* Function calls */
|
|
1837
|
-
|
|
1838
|
-
case OP_EVAL:
|
|
1839
|
-
js_eval(J);
|
|
1840
|
-
break;
|
|
1841
|
-
|
|
1842
|
-
case OP_CALL:
|
|
1843
|
-
js_call(J, *pc++);
|
|
1844
|
-
break;
|
|
1845
|
-
|
|
1846
|
-
case OP_NEW:
|
|
1847
|
-
js_construct(J, *pc++);
|
|
1848
|
-
break;
|
|
1849
|
-
|
|
1850
|
-
/* Unary operators */
|
|
1851
|
-
|
|
1852
|
-
case OP_TYPEOF:
|
|
1853
|
-
str = js_typeof(J, -1);
|
|
1854
|
-
js_pop(J, 1);
|
|
1855
|
-
js_pushliteral(J, str);
|
|
1856
|
-
break;
|
|
1857
|
-
|
|
1858
|
-
case OP_POS:
|
|
1859
|
-
x = js_tonumber(J, -1);
|
|
1860
|
-
js_pop(J, 1);
|
|
1861
|
-
js_pushnumber(J, x);
|
|
1862
|
-
break;
|
|
1863
|
-
|
|
1864
|
-
case OP_NEG:
|
|
1865
|
-
x = js_tonumber(J, -1);
|
|
1866
|
-
js_pop(J, 1);
|
|
1867
|
-
js_pushnumber(J, -x);
|
|
1868
|
-
break;
|
|
1869
|
-
|
|
1870
|
-
case OP_BITNOT:
|
|
1871
|
-
ix = js_toint32(J, -1);
|
|
1872
|
-
js_pop(J, 1);
|
|
1873
|
-
js_pushnumber(J, ~ix);
|
|
1874
|
-
break;
|
|
1875
|
-
|
|
1876
|
-
case OP_LOGNOT:
|
|
1877
|
-
b = js_toboolean(J, -1);
|
|
1878
|
-
js_pop(J, 1);
|
|
1879
|
-
js_pushboolean(J, !b);
|
|
1880
|
-
break;
|
|
1881
|
-
|
|
1882
|
-
case OP_INC:
|
|
1883
|
-
x = js_tonumber(J, -1);
|
|
1884
|
-
js_pop(J, 1);
|
|
1885
|
-
js_pushnumber(J, x + 1);
|
|
1886
|
-
break;
|
|
1887
|
-
|
|
1888
|
-
case OP_DEC:
|
|
1889
|
-
x = js_tonumber(J, -1);
|
|
1890
|
-
js_pop(J, 1);
|
|
1891
|
-
js_pushnumber(J, x - 1);
|
|
1892
|
-
break;
|
|
1893
|
-
|
|
1894
|
-
case OP_POSTINC:
|
|
1895
|
-
x = js_tonumber(J, -1);
|
|
1896
|
-
js_pop(J, 1);
|
|
1897
|
-
js_pushnumber(J, x + 1);
|
|
1898
|
-
js_pushnumber(J, x);
|
|
1899
|
-
break;
|
|
1900
|
-
|
|
1901
|
-
case OP_POSTDEC:
|
|
1902
|
-
x = js_tonumber(J, -1);
|
|
1903
|
-
js_pop(J, 1);
|
|
1904
|
-
js_pushnumber(J, x - 1);
|
|
1905
|
-
js_pushnumber(J, x);
|
|
1906
|
-
break;
|
|
1907
|
-
|
|
1908
|
-
/* Multiplicative operators */
|
|
1909
|
-
|
|
1910
|
-
case OP_MUL:
|
|
1911
|
-
x = js_tonumber(J, -2);
|
|
1912
|
-
y = js_tonumber(J, -1);
|
|
1913
|
-
js_pop(J, 2);
|
|
1914
|
-
js_pushnumber(J, x * y);
|
|
1915
|
-
break;
|
|
1916
|
-
|
|
1917
|
-
case OP_DIV:
|
|
1918
|
-
x = js_tonumber(J, -2);
|
|
1919
|
-
y = js_tonumber(J, -1);
|
|
1920
|
-
js_pop(J, 2);
|
|
1921
|
-
js_pushnumber(J, x / y);
|
|
1922
|
-
break;
|
|
1923
|
-
|
|
1924
|
-
case OP_MOD:
|
|
1925
|
-
x = js_tonumber(J, -2);
|
|
1926
|
-
y = js_tonumber(J, -1);
|
|
1927
|
-
js_pop(J, 2);
|
|
1928
|
-
js_pushnumber(J, fmod(x, y));
|
|
1929
|
-
break;
|
|
1930
|
-
|
|
1931
|
-
/* Additive operators */
|
|
1932
|
-
|
|
1933
|
-
case OP_ADD:
|
|
1934
|
-
js_concat(J);
|
|
1935
|
-
break;
|
|
1936
|
-
|
|
1937
|
-
case OP_SUB:
|
|
1938
|
-
x = js_tonumber(J, -2);
|
|
1939
|
-
y = js_tonumber(J, -1);
|
|
1940
|
-
js_pop(J, 2);
|
|
1941
|
-
js_pushnumber(J, x - y);
|
|
1942
|
-
break;
|
|
1943
|
-
|
|
1944
|
-
/* Shift operators */
|
|
1945
|
-
|
|
1946
|
-
case OP_SHL:
|
|
1947
|
-
ix = js_toint32(J, -2);
|
|
1948
|
-
uy = js_touint32(J, -1);
|
|
1949
|
-
js_pop(J, 2);
|
|
1950
|
-
js_pushnumber(J, ix << (uy & 0x1F));
|
|
1951
|
-
break;
|
|
1952
|
-
|
|
1953
|
-
case OP_SHR:
|
|
1954
|
-
ix = js_toint32(J, -2);
|
|
1955
|
-
uy = js_touint32(J, -1);
|
|
1956
|
-
js_pop(J, 2);
|
|
1957
|
-
js_pushnumber(J, ix >> (uy & 0x1F));
|
|
1958
|
-
break;
|
|
1959
|
-
|
|
1960
|
-
case OP_USHR:
|
|
1961
|
-
ux = js_touint32(J, -2);
|
|
1962
|
-
uy = js_touint32(J, -1);
|
|
1963
|
-
js_pop(J, 2);
|
|
1964
|
-
js_pushnumber(J, ux >> (uy & 0x1F));
|
|
1965
|
-
break;
|
|
1966
|
-
|
|
1967
|
-
/* Relational operators */
|
|
1968
|
-
|
|
1969
|
-
case OP_LT: b = js_compare(J, &okay); js_pop(J, 2); js_pushboolean(J, okay && b < 0); break;
|
|
1970
|
-
case OP_GT: b = js_compare(J, &okay); js_pop(J, 2); js_pushboolean(J, okay && b > 0); break;
|
|
1971
|
-
case OP_LE: b = js_compare(J, &okay); js_pop(J, 2); js_pushboolean(J, okay && b <= 0); break;
|
|
1972
|
-
case OP_GE: b = js_compare(J, &okay); js_pop(J, 2); js_pushboolean(J, okay && b >= 0); break;
|
|
1973
|
-
|
|
1974
|
-
case OP_INSTANCEOF:
|
|
1975
|
-
b = js_instanceof(J);
|
|
1976
|
-
js_pop(J, 2);
|
|
1977
|
-
js_pushboolean(J, b);
|
|
1978
|
-
break;
|
|
1979
|
-
|
|
1980
|
-
/* Equality */
|
|
1981
|
-
|
|
1982
|
-
case OP_EQ: b = js_equal(J); js_pop(J, 2); js_pushboolean(J, b); break;
|
|
1983
|
-
case OP_NE: b = js_equal(J); js_pop(J, 2); js_pushboolean(J, !b); break;
|
|
1984
|
-
case OP_STRICTEQ: b = js_strictequal(J); js_pop(J, 2); js_pushboolean(J, b); break;
|
|
1985
|
-
case OP_STRICTNE: b = js_strictequal(J); js_pop(J, 2); js_pushboolean(J, !b); break;
|
|
1986
|
-
|
|
1987
|
-
case OP_JCASE:
|
|
1988
|
-
offset = *pc++;
|
|
1989
|
-
b = js_strictequal(J);
|
|
1990
|
-
if (b) {
|
|
1991
|
-
js_pop(J, 2);
|
|
1992
|
-
pc = pcstart + offset;
|
|
1993
|
-
} else {
|
|
1994
|
-
js_pop(J, 1);
|
|
1995
|
-
}
|
|
1996
|
-
break;
|
|
1997
|
-
|
|
1998
|
-
/* Binary bitwise operators */
|
|
1999
|
-
|
|
2000
|
-
case OP_BITAND:
|
|
2001
|
-
ix = js_toint32(J, -2);
|
|
2002
|
-
iy = js_toint32(J, -1);
|
|
2003
|
-
js_pop(J, 2);
|
|
2004
|
-
js_pushnumber(J, ix & iy);
|
|
2005
|
-
break;
|
|
2006
|
-
|
|
2007
|
-
case OP_BITXOR:
|
|
2008
|
-
ix = js_toint32(J, -2);
|
|
2009
|
-
iy = js_toint32(J, -1);
|
|
2010
|
-
js_pop(J, 2);
|
|
2011
|
-
js_pushnumber(J, ix ^ iy);
|
|
2012
|
-
break;
|
|
2013
|
-
|
|
2014
|
-
case OP_BITOR:
|
|
2015
|
-
ix = js_toint32(J, -2);
|
|
2016
|
-
iy = js_toint32(J, -1);
|
|
2017
|
-
js_pop(J, 2);
|
|
2018
|
-
js_pushnumber(J, ix | iy);
|
|
2019
|
-
break;
|
|
2020
|
-
|
|
2021
|
-
/* Try and Catch */
|
|
2022
|
-
|
|
2023
|
-
case OP_THROW:
|
|
2024
|
-
js_throw(J);
|
|
2025
|
-
|
|
2026
|
-
case OP_TRY:
|
|
2027
|
-
offset = *pc++;
|
|
2028
|
-
if (js_trypc(J, pc)) {
|
|
2029
|
-
pc = J->trybuf[J->trytop].pc;
|
|
2030
|
-
} else {
|
|
2031
|
-
pc = pcstart + offset;
|
|
2032
|
-
}
|
|
2033
|
-
break;
|
|
2034
|
-
|
|
2035
|
-
case OP_ENDTRY:
|
|
2036
|
-
js_endtry(J);
|
|
2037
|
-
break;
|
|
2038
|
-
|
|
2039
|
-
case OP_CATCH:
|
|
2040
|
-
READSTRING();
|
|
2041
|
-
obj = jsV_newobject(J, JS_COBJECT, NULL);
|
|
2042
|
-
js_pushobject(J, obj);
|
|
2043
|
-
js_rot2(J);
|
|
2044
|
-
js_setproperty(J, -2, str);
|
|
2045
|
-
J->E = jsR_newenvironment(J, obj, J->E);
|
|
2046
|
-
js_pop(J, 1);
|
|
2047
|
-
break;
|
|
2048
|
-
|
|
2049
|
-
case OP_ENDCATCH:
|
|
2050
|
-
J->E = J->E->outer;
|
|
2051
|
-
break;
|
|
2052
|
-
|
|
2053
|
-
/* With */
|
|
2054
|
-
|
|
2055
|
-
case OP_WITH:
|
|
2056
|
-
obj = js_toobject(J, -1);
|
|
2057
|
-
J->E = jsR_newenvironment(J, obj, J->E);
|
|
2058
|
-
js_pop(J, 1);
|
|
2059
|
-
break;
|
|
2060
|
-
|
|
2061
|
-
case OP_ENDWITH:
|
|
2062
|
-
J->E = J->E->outer;
|
|
2063
|
-
break;
|
|
2064
|
-
|
|
2065
|
-
/* Branching */
|
|
2066
|
-
|
|
2067
|
-
case OP_DEBUGGER:
|
|
2068
|
-
js_trap(J, (int)(pc - pcstart) - 1);
|
|
2069
|
-
break;
|
|
2070
|
-
|
|
2071
|
-
case OP_JUMP:
|
|
2072
|
-
pc = pcstart + *pc;
|
|
2073
|
-
break;
|
|
2074
|
-
|
|
2075
|
-
case OP_JTRUE:
|
|
2076
|
-
offset = *pc++;
|
|
2077
|
-
b = js_toboolean(J, -1);
|
|
2078
|
-
js_pop(J, 1);
|
|
2079
|
-
if (b)
|
|
2080
|
-
pc = pcstart + offset;
|
|
2081
|
-
break;
|
|
2082
|
-
|
|
2083
|
-
case OP_JFALSE:
|
|
2084
|
-
offset = *pc++;
|
|
2085
|
-
b = js_toboolean(J, -1);
|
|
2086
|
-
js_pop(J, 1);
|
|
2087
|
-
if (!b)
|
|
2088
|
-
pc = pcstart + offset;
|
|
2089
|
-
break;
|
|
2090
|
-
|
|
2091
|
-
case OP_RETURN:
|
|
2092
|
-
J->strict = savestrict;
|
|
2093
|
-
return;
|
|
2094
|
-
}
|
|
2095
|
-
}
|
|
2096
|
-
}
|