zig-pug 0.2.0

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.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +346 -0
  3. package/binding.c +375 -0
  4. package/binding.gyp +28 -0
  5. package/common.gypi +5 -0
  6. package/include/zigpug.h +135 -0
  7. package/index.js +205 -0
  8. package/package.json +87 -0
  9. package/vendor/mujs/COPYING +16 -0
  10. package/vendor/mujs/README +50 -0
  11. package/vendor/mujs/astnames.h +92 -0
  12. package/vendor/mujs/jsarray.c +832 -0
  13. package/vendor/mujs/jsboolean.c +38 -0
  14. package/vendor/mujs/jsbuiltin.c +249 -0
  15. package/vendor/mujs/jscompile.c +1428 -0
  16. package/vendor/mujs/jsdate.c +861 -0
  17. package/vendor/mujs/jsdtoa.c +749 -0
  18. package/vendor/mujs/jserror.c +139 -0
  19. package/vendor/mujs/jsfunction.c +231 -0
  20. package/vendor/mujs/jsgc.c +284 -0
  21. package/vendor/mujs/jsi.h +870 -0
  22. package/vendor/mujs/jsintern.c +137 -0
  23. package/vendor/mujs/jslex.c +878 -0
  24. package/vendor/mujs/jsmath.c +194 -0
  25. package/vendor/mujs/jsnumber.c +198 -0
  26. package/vendor/mujs/jsobject.c +560 -0
  27. package/vendor/mujs/json.c +422 -0
  28. package/vendor/mujs/jsparse.c +1065 -0
  29. package/vendor/mujs/jsproperty.c +341 -0
  30. package/vendor/mujs/jsregexp.c +232 -0
  31. package/vendor/mujs/jsrepr.c +285 -0
  32. package/vendor/mujs/jsrun.c +2096 -0
  33. package/vendor/mujs/jsstate.c +334 -0
  34. package/vendor/mujs/jsstring.c +852 -0
  35. package/vendor/mujs/jsvalue.c +708 -0
  36. package/vendor/mujs/libmujs.a +0 -0
  37. package/vendor/mujs/main.c +396 -0
  38. package/vendor/mujs/mujs.h +253 -0
  39. package/vendor/mujs/one.c +25 -0
  40. package/vendor/mujs/opnames.h +85 -0
  41. package/vendor/mujs/pp.c +980 -0
  42. package/vendor/mujs/regexp.c +1277 -0
  43. package/vendor/mujs/regexp.h +46 -0
  44. package/vendor/mujs/utf.c +305 -0
  45. package/vendor/mujs/utf.h +52 -0
  46. package/vendor/mujs/utfdata.h +2209 -0
@@ -0,0 +1,139 @@
1
+ #include "jsi.h"
2
+
3
+ #define QQ(X) #X
4
+ #define Q(X) QQ(X)
5
+
6
+ static int jsB_stacktrace(js_State *J, int skip)
7
+ {
8
+ char buf[256];
9
+ int n = J->tracetop - skip;
10
+ if (n <= 0)
11
+ return 0;
12
+ for (; n > 0; --n) {
13
+ const char *name = J->trace[n].name;
14
+ const char *file = J->trace[n].file;
15
+ int line = J->trace[n].line;
16
+ if (line > 0) {
17
+ if (name[0])
18
+ snprintf(buf, sizeof buf, "\n\tat %s (%s:%d)", name, file, line);
19
+ else
20
+ snprintf(buf, sizeof buf, "\n\tat %s:%d", file, line);
21
+ } else
22
+ snprintf(buf, sizeof buf, "\n\tat %s (%s)", name, file);
23
+ js_pushstring(J, buf);
24
+ if (n < J->tracetop - skip)
25
+ js_concat(J);
26
+ }
27
+ return 1;
28
+ }
29
+
30
+ static void Ep_toString(js_State *J)
31
+ {
32
+ const char *name = "Error";
33
+ const char *message = "";
34
+
35
+ if (!js_isobject(J, -1))
36
+ js_typeerror(J, "not an object");
37
+
38
+ if (js_hasproperty(J, 0, "name"))
39
+ name = js_tostring(J, -1);
40
+ if (js_hasproperty(J, 0, "message"))
41
+ message = js_tostring(J, -1);
42
+
43
+ if (name[0] == 0)
44
+ js_pushstring(J, message);
45
+ else if (message[0] == 0)
46
+ js_pushstring(J, name);
47
+ else {
48
+ js_pushstring(J, name);
49
+ js_pushstring(J, ": ");
50
+ js_concat(J);
51
+ js_pushstring(J, message);
52
+ js_concat(J);
53
+ }
54
+ }
55
+
56
+ static void Ep_get_stack(js_State *J)
57
+ {
58
+ Ep_toString(J);
59
+ js_getproperty(J, 0, "stackTrace");
60
+ js_concat(J);
61
+ }
62
+
63
+ static int jsB_ErrorX(js_State *J, js_Object *prototype)
64
+ {
65
+ js_pushobject(J, jsV_newobject(J, JS_CERROR, prototype));
66
+ if (js_isdefined(J, 1)) {
67
+ js_pushstring(J, js_tostring(J, 1));
68
+ js_defproperty(J, -2, "message", JS_DONTENUM);
69
+ }
70
+ if (jsB_stacktrace(J, 1))
71
+ js_defproperty(J, -2, "stackTrace", JS_DONTENUM);
72
+ return 1;
73
+ }
74
+
75
+ static void js_newerrorx(js_State *J, const char *message, js_Object *prototype)
76
+ {
77
+ js_pushobject(J, jsV_newobject(J, JS_CERROR, prototype));
78
+ js_pushstring(J, message);
79
+ js_setproperty(J, -2, "message");
80
+ if (jsB_stacktrace(J, 0))
81
+ js_setproperty(J, -2, "stackTrace");
82
+ }
83
+
84
+ #define DERROR(name, Name) \
85
+ static void jsB_##Name(js_State *J) { \
86
+ jsB_ErrorX(J, J->Name##_prototype); \
87
+ } \
88
+ void js_new##name(js_State *J, const char *s) { \
89
+ js_newerrorx(J, s, J->Name##_prototype); \
90
+ } \
91
+ void js_##name(js_State *J, const char *fmt, ...) { \
92
+ va_list ap; \
93
+ char buf[256]; \
94
+ va_start(ap, fmt); \
95
+ vsnprintf(buf, sizeof buf, fmt, ap); \
96
+ va_end(ap); \
97
+ js_newerrorx(J, buf, J->Name##_prototype); \
98
+ js_throw(J); \
99
+ }
100
+
101
+ DERROR(error, Error)
102
+ DERROR(evalerror, EvalError)
103
+ DERROR(rangeerror, RangeError)
104
+ DERROR(referenceerror, ReferenceError)
105
+ DERROR(syntaxerror, SyntaxError)
106
+ DERROR(typeerror, TypeError)
107
+ DERROR(urierror, URIError)
108
+
109
+ #undef DERROR
110
+
111
+ void jsB_initerror(js_State *J)
112
+ {
113
+ js_pushobject(J, J->Error_prototype);
114
+ {
115
+ jsB_props(J, "name", "Error");
116
+ jsB_propf(J, "Error.prototype.toString", Ep_toString, 0);
117
+
118
+ js_newcfunction(J, Ep_get_stack, "stack", 0);
119
+ js_pushnull(J);
120
+ js_defaccessor(J, -3, "stack", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
121
+ }
122
+ js_newcconstructor(J, jsB_Error, jsB_Error, "Error", 1);
123
+ js_defglobal(J, "Error", JS_DONTENUM);
124
+
125
+ #define IERROR(NAME) \
126
+ js_pushobject(J, J->NAME##_prototype); \
127
+ jsB_props(J, "name", Q(NAME)); \
128
+ js_newcconstructor(J, jsB_##NAME, jsB_##NAME, Q(NAME), 1); \
129
+ js_defglobal(J, Q(NAME), JS_DONTENUM);
130
+
131
+ IERROR(EvalError);
132
+ IERROR(RangeError);
133
+ IERROR(ReferenceError);
134
+ IERROR(SyntaxError);
135
+ IERROR(TypeError);
136
+ IERROR(URIError);
137
+
138
+ #undef IERROR
139
+ }
@@ -0,0 +1,231 @@
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
+ }
@@ -0,0 +1,284 @@
1
+ #include "jsi.h"
2
+ #include "regexp.h"
3
+
4
+ static void jsG_freeenvironment(js_State *J, js_Environment *env)
5
+ {
6
+ js_free(J, env);
7
+ }
8
+
9
+ static void jsG_freefunction(js_State *J, js_Function *fun)
10
+ {
11
+ js_free(J, fun->funtab);
12
+ js_free(J, fun->vartab);
13
+ js_free(J, fun->code);
14
+ js_free(J, fun);
15
+ }
16
+
17
+ static void jsG_freeproperty(js_State *J, js_Property *node)
18
+ {
19
+ if (node->left->level) jsG_freeproperty(J, node->left);
20
+ if (node->right->level) jsG_freeproperty(J, node->right);
21
+ js_free(J, node);
22
+ }
23
+
24
+ static void jsG_freeiterator(js_State *J, js_Iterator *node)
25
+ {
26
+ while (node) {
27
+ js_Iterator *next = node->next;
28
+ js_free(J, node);
29
+ node = next;
30
+ }
31
+ }
32
+
33
+ static void jsG_freeobject(js_State *J, js_Object *obj)
34
+ {
35
+ if (obj->properties->level)
36
+ jsG_freeproperty(J, obj->properties);
37
+ if (obj->type == JS_CREGEXP) {
38
+ js_free(J, obj->u.r.source);
39
+ js_regfreex(J->alloc, J->actx, obj->u.r.prog);
40
+ }
41
+ if (obj->type == JS_CSTRING) {
42
+ if (obj->u.s.string != obj->u.s.shrstr)
43
+ js_free(J, obj->u.s.string);
44
+ }
45
+ if (obj->type == JS_CARRAY && obj->u.a.simple)
46
+ js_free(J, obj->u.a.array);
47
+ if (obj->type == JS_CITERATOR)
48
+ jsG_freeiterator(J, obj->u.iter.head);
49
+ if (obj->type == JS_CUSERDATA && obj->u.user.finalize)
50
+ obj->u.user.finalize(J, obj->u.user.data);
51
+ if (obj->type == JS_CCFUNCTION && obj->u.c.finalize)
52
+ obj->u.c.finalize(J, obj->u.c.data);
53
+ js_free(J, obj);
54
+ }
55
+
56
+ /* Mark and add object to scan queue */
57
+ static void jsG_markobject(js_State *J, int mark, js_Object *obj)
58
+ {
59
+ obj->gcmark = mark;
60
+ obj->gcroot = J->gcroot;
61
+ J->gcroot = obj;
62
+ }
63
+
64
+ static void jsG_markfunction(js_State *J, int mark, js_Function *fun)
65
+ {
66
+ int i;
67
+ fun->gcmark = mark;
68
+ for (i = 0; i < fun->funlen; ++i)
69
+ if (fun->funtab[i]->gcmark != mark)
70
+ jsG_markfunction(J, mark, fun->funtab[i]);
71
+ }
72
+
73
+ static void jsG_markenvironment(js_State *J, int mark, js_Environment *env)
74
+ {
75
+ do {
76
+ env->gcmark = mark;
77
+ if (env->variables->gcmark != mark)
78
+ jsG_markobject(J, mark, env->variables);
79
+ env = env->outer;
80
+ } while (env && env->gcmark != mark);
81
+ }
82
+
83
+ static void jsG_markproperty(js_State *J, int mark, js_Property *node)
84
+ {
85
+ if (node->left->level) jsG_markproperty(J, mark, node->left);
86
+ if (node->right->level) jsG_markproperty(J, mark, node->right);
87
+
88
+ if (node->value.t.type == JS_TMEMSTR && node->value.u.memstr->gcmark != mark)
89
+ node->value.u.memstr->gcmark = mark;
90
+ if (node->value.t.type == JS_TOBJECT && node->value.u.object->gcmark != mark)
91
+ jsG_markobject(J, mark, node->value.u.object);
92
+ if (node->getter && node->getter->gcmark != mark)
93
+ jsG_markobject(J, mark, node->getter);
94
+ if (node->setter && node->setter->gcmark != mark)
95
+ jsG_markobject(J, mark, node->setter);
96
+ }
97
+
98
+ /* Mark everything the object can reach. */
99
+ static void jsG_scanobject(js_State *J, int mark, js_Object *obj)
100
+ {
101
+ if (obj->properties->level)
102
+ jsG_markproperty(J, mark, obj->properties);
103
+ if (obj->prototype && obj->prototype->gcmark != mark)
104
+ jsG_markobject(J, mark, obj->prototype);
105
+ if (obj->type == JS_CARRAY && obj->u.a.simple) {
106
+ int i;
107
+ for (i = 0; i < obj->u.a.flat_length; ++i) {
108
+ js_Value *v = &obj->u.a.array[i];
109
+ if (v->t.type == JS_TMEMSTR && v->u.memstr->gcmark != mark)
110
+ v->u.memstr->gcmark = mark;
111
+ if (v->t.type == JS_TOBJECT && v->u.object->gcmark != mark)
112
+ jsG_markobject(J, mark, v->u.object);
113
+ }
114
+ }
115
+ if (obj->type == JS_CITERATOR && obj->u.iter.target->gcmark != mark) {
116
+ jsG_markobject(J, mark, obj->u.iter.target);
117
+ }
118
+ if (obj->type == JS_CFUNCTION || obj->type == JS_CSCRIPT) {
119
+ if (obj->u.f.scope && obj->u.f.scope->gcmark != mark)
120
+ jsG_markenvironment(J, mark, obj->u.f.scope);
121
+ if (obj->u.f.function && obj->u.f.function->gcmark != mark)
122
+ jsG_markfunction(J, mark, obj->u.f.function);
123
+ }
124
+ }
125
+
126
+ static void jsG_markstack(js_State *J, int mark)
127
+ {
128
+ js_Value *v = J->stack;
129
+ int n = J->top;
130
+ while (n--) {
131
+ if (v->t.type == JS_TMEMSTR && v->u.memstr->gcmark != mark)
132
+ v->u.memstr->gcmark = mark;
133
+ if (v->t.type == JS_TOBJECT && v->u.object->gcmark != mark)
134
+ jsG_markobject(J, mark, v->u.object);
135
+ ++v;
136
+ }
137
+ }
138
+
139
+ void js_gc(js_State *J, int report)
140
+ {
141
+ js_Function *fun, *nextfun, **prevnextfun;
142
+ js_Object *obj, *nextobj, **prevnextobj;
143
+ js_String *str, *nextstr, **prevnextstr;
144
+ js_Environment *env, *nextenv, **prevnextenv;
145
+ unsigned int nenv = 0, nfun = 0, nobj = 0, nstr = 0, nprop = 0;
146
+ unsigned int genv = 0, gfun = 0, gobj = 0, gstr = 0, gprop = 0;
147
+ int mark;
148
+ int i;
149
+
150
+ mark = J->gcmark = J->gcmark == 1 ? 2 : 1;
151
+
152
+ /* Add initial roots. */
153
+
154
+ jsG_markobject(J, mark, J->Object_prototype);
155
+ jsG_markobject(J, mark, J->Array_prototype);
156
+ jsG_markobject(J, mark, J->Function_prototype);
157
+ jsG_markobject(J, mark, J->Boolean_prototype);
158
+ jsG_markobject(J, mark, J->Number_prototype);
159
+ jsG_markobject(J, mark, J->String_prototype);
160
+ jsG_markobject(J, mark, J->RegExp_prototype);
161
+ jsG_markobject(J, mark, J->Date_prototype);
162
+
163
+ jsG_markobject(J, mark, J->Error_prototype);
164
+ jsG_markobject(J, mark, J->EvalError_prototype);
165
+ jsG_markobject(J, mark, J->RangeError_prototype);
166
+ jsG_markobject(J, mark, J->ReferenceError_prototype);
167
+ jsG_markobject(J, mark, J->SyntaxError_prototype);
168
+ jsG_markobject(J, mark, J->TypeError_prototype);
169
+ jsG_markobject(J, mark, J->URIError_prototype);
170
+
171
+ jsG_markobject(J, mark, J->R);
172
+ jsG_markobject(J, mark, J->G);
173
+
174
+ jsG_markstack(J, mark);
175
+
176
+ jsG_markenvironment(J, mark, J->E);
177
+ jsG_markenvironment(J, mark, J->GE);
178
+ for (i = 0; i < J->envtop; ++i)
179
+ jsG_markenvironment(J, mark, J->envstack[i]);
180
+
181
+ /* Scan objects until none remain. */
182
+
183
+ while ((obj = J->gcroot) != NULL) {
184
+ J->gcroot = obj->gcroot;
185
+ obj->gcroot = NULL;
186
+ jsG_scanobject(J, mark, obj);
187
+ }
188
+
189
+ /* Free everything not marked. */
190
+
191
+ prevnextenv = &J->gcenv;
192
+ for (env = J->gcenv; env; env = nextenv) {
193
+ nextenv = env->gcnext;
194
+ if (env->gcmark != mark) {
195
+ *prevnextenv = nextenv;
196
+ jsG_freeenvironment(J, env);
197
+ ++genv;
198
+ } else {
199
+ prevnextenv = &env->gcnext;
200
+ }
201
+ ++nenv;
202
+ }
203
+
204
+ prevnextfun = &J->gcfun;
205
+ for (fun = J->gcfun; fun; fun = nextfun) {
206
+ nextfun = fun->gcnext;
207
+ if (fun->gcmark != mark) {
208
+ *prevnextfun = nextfun;
209
+ jsG_freefunction(J, fun);
210
+ ++gfun;
211
+ } else {
212
+ prevnextfun = &fun->gcnext;
213
+ }
214
+ ++nfun;
215
+ }
216
+
217
+ prevnextobj = &J->gcobj;
218
+ for (obj = J->gcobj; obj; obj = nextobj) {
219
+ nprop += obj->count;
220
+ nextobj = obj->gcnext;
221
+ if (obj->gcmark != mark) {
222
+ gprop += obj->count;
223
+ *prevnextobj = nextobj;
224
+ jsG_freeobject(J, obj);
225
+ ++gobj;
226
+ } else {
227
+ prevnextobj = &obj->gcnext;
228
+ }
229
+ ++nobj;
230
+ }
231
+
232
+ prevnextstr = &J->gcstr;
233
+ for (str = J->gcstr; str; str = nextstr) {
234
+ nextstr = str->gcnext;
235
+ if (str->gcmark != mark) {
236
+ *prevnextstr = nextstr;
237
+ js_free(J, str);
238
+ ++gstr;
239
+ } else {
240
+ prevnextstr = &str->gcnext;
241
+ }
242
+ ++nstr;
243
+ }
244
+
245
+ unsigned int ntot = nenv + nfun + nobj + nstr + nprop;
246
+ unsigned int gtot = genv + gfun + gobj + gstr + gprop;
247
+ unsigned int remaining = ntot - gtot;
248
+
249
+ J->gccounter = remaining;
250
+ J->gcthresh = remaining * JS_GCFACTOR;
251
+
252
+ if (report) {
253
+ char buf[256];
254
+ snprintf(buf, sizeof buf, "garbage collected (%d%%): %d/%d envs, %d/%d funs, %d/%d objs, %d/%d props, %d/%d strs",
255
+ 100*gtot/ntot, genv, nenv, gfun, nfun, gobj, nobj, gprop, nprop, gstr, nstr);
256
+ js_report(J, buf);
257
+ }
258
+ }
259
+
260
+ void js_freestate(js_State *J)
261
+ {
262
+ js_Function *fun, *nextfun;
263
+ js_Object *obj, *nextobj;
264
+ js_Environment *env, *nextenv;
265
+ js_String *str, *nextstr;
266
+
267
+ if (!J)
268
+ return;
269
+
270
+ for (env = J->gcenv; env; env = nextenv)
271
+ nextenv = env->gcnext, jsG_freeenvironment(J, env);
272
+ for (fun = J->gcfun; fun; fun = nextfun)
273
+ nextfun = fun->gcnext, jsG_freefunction(J, fun);
274
+ for (obj = J->gcobj; obj; obj = nextobj)
275
+ nextobj = obj->gcnext, jsG_freeobject(J, obj);
276
+ for (str = J->gcstr; str; str = nextstr)
277
+ nextstr = str->gcnext, js_free(J, str);
278
+
279
+ jsS_freestrings(J);
280
+
281
+ js_free(J, J->lexbuf.text);
282
+ J->alloc(J->actx, J->stack, 0);
283
+ J->alloc(J->actx, J, 0);
284
+ }