Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
8456 maxcodehac 1
#include "jsi.h"
2
#include "jsparse.h"
3
#include "jscompile.h"
4
#include "jsvalue.h"
5
#include "jsrun.h"
6
#include "jsbuiltin.h"
7
 
8
#include 
9
#include 
10
 
11
static void *js_defaultalloc(void *actx, void *ptr, int size)
12
{
13
#ifndef __has_feature
14
#define __has_feature(x) 0
15
#endif
16
#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
17
	if (size == 0) {
18
		free(ptr);
19
		return NULL;
20
	}
21
#endif
22
	return realloc(ptr, (size_t)size);
23
}
24
 
25
static void js_defaultreport(js_State *J, const char *message)
26
{
27
	fputs(message, stderr);
28
	fputc('\n', stderr);
29
}
30
 
31
static void js_defaultpanic(js_State *J)
32
{
33
	js_report(J, "uncaught exception");
34
	/* return to javascript to abort */
35
}
36
 
37
int js_ploadstring(js_State *J, const char *filename, const char *source)
38
{
39
	if (js_try(J))
40
		return 1;
41
	js_loadstring(J, filename, source);
42
	js_endtry(J);
43
	return 0;
44
}
45
 
46
int js_ploadfile(js_State *J, const char *filename)
47
{
48
	if (js_try(J))
49
		return 1;
50
	js_loadfile(J, filename);
51
	js_endtry(J);
52
	return 0;
53
}
54
 
55
const char *js_trystring(js_State *J, int idx, const char *error)
56
{
57
	const char *s;
58
	if (js_try(J)) {
59
		js_pop(J, 1);
60
		return error;
61
	}
62
	s = js_tostring(J, idx);
63
	js_endtry(J);
64
	return s;
65
}
66
 
67
double js_trynumber(js_State *J, int idx, double error)
68
{
69
	double v;
70
	if (js_try(J)) {
71
		js_pop(J, 1);
72
		return error;
73
	}
74
	v = js_tonumber(J, idx);
75
	js_endtry(J);
76
	return v;
77
}
78
 
79
int js_tryinteger(js_State *J, int idx, int error)
80
{
81
	int v;
82
	if (js_try(J)) {
83
		js_pop(J, 1);
84
		return error;
85
	}
86
	v = js_tointeger(J, idx);
87
	js_endtry(J);
88
	return v;
89
}
90
 
91
int js_tryboolean(js_State *J, int idx, int error)
92
{
93
	int v;
94
	if (js_try(J)) {
95
		js_pop(J, 1);
96
		return error;
97
	}
98
	v = js_toboolean(J, idx);
99
	js_endtry(J);
100
	return v;
101
}
102
 
103
static void js_loadstringx(js_State *J, const char *filename, const char *source, int iseval)
104
{
105
	js_Ast *P;
106
	js_Function *F;
107
 
108
	if (js_try(J)) {
109
		jsP_freeparse(J);
110
		js_throw(J);
111
	}
112
 
113
	P = jsP_parse(J, filename, source);
114
	F = jsC_compilescript(J, P, iseval ? J->strict : J->default_strict);
115
	jsP_freeparse(J);
116
	js_newscript(J, F, iseval ? (J->strict ? J->E : NULL) : J->GE, iseval ? JS_CEVAL : JS_CSCRIPT);
117
 
118
	js_endtry(J);
119
}
120
 
121
void js_loadeval(js_State *J, const char *filename, const char *source)
122
{
123
	js_loadstringx(J, filename, source, 1);
124
}
125
 
126
void js_loadstring(js_State *J, const char *filename, const char *source)
127
{
128
	js_loadstringx(J, filename, source, 0);
129
}
130
 
131
void js_loadfile(js_State *J, const char *filename)
132
{
133
	FILE *f;
134
	char *s, *p;
135
	int n, t;
136
 
137
	f = fopen(filename, "rb");
138
	if (!f) {
139
		js_error(J, "cannot open file '%s': %s", filename, strerror(errno));
140
	}
141
 
142
	if (fseek(f, 0, SEEK_END) < 0) {
143
		fclose(f);
144
		js_error(J, "cannot seek in file '%s': %s", filename, strerror(errno));
145
	}
146
 
147
	n = ftell(f);
148
	if (n < 0) {
149
		fclose(f);
150
		js_error(J, "cannot tell in file '%s': %s", filename, strerror(errno));
151
	}
152
 
153
	if (fseek(f, 0, SEEK_SET) < 0) {
154
		fclose(f);
155
		js_error(J, "cannot seek in file '%s': %s", filename, strerror(errno));
156
	}
157
 
158
	if (js_try(J)) {
159
		fclose(f);
160
		js_throw(J);
161
	}
162
	s = js_malloc(J, n + 1); /* add space for string terminator */
163
	js_endtry(J);
164
 
165
	t = fread(s, 1, (size_t)n, f);
166
	if (t != n) {
167
		js_free(J, s);
168
		fclose(f);
169
		js_error(J, "cannot read data from file '%s': %s", filename, strerror(errno));
170
	}
171
 
172
	s[n] = 0; /* zero-terminate string containing file data */
173
 
174
	if (js_try(J)) {
175
		js_free(J, s);
176
		fclose(f);
177
		js_throw(J);
178
	}
179
 
180
	/* skip first line if it starts with "#!" */
181
	p = s;
182
	if (p[0] == '#' && p[1] == '!') {
183
		p += 2;
184
		while (*p && *p != '\n')
185
			++p;
186
	}
187
 
188
	js_loadstring(J, filename, p);
189
 
190
	js_free(J, s);
191
	fclose(f);
192
	js_endtry(J);
193
}
194
 
195
int js_dostring(js_State *J, const char *source)
196
{
197
	if (js_try(J)) {
198
		js_report(J, js_trystring(J, -1, "Error"));
199
		js_pop(J, 1);
200
		return 1;
201
	}
202
	js_loadstring(J, "[string]", source);
203
	js_pushundefined(J);
204
	js_call(J, 0);
205
	js_pop(J, 1);
206
	js_endtry(J);
207
	return 0;
208
}
209
 
210
int js_dofile(js_State *J, const char *filename)
211
{
212
	if (js_try(J)) {
213
		js_report(J, js_trystring(J, -1, "Error"));
214
		js_pop(J, 1);
215
		return 1;
216
	}
217
	js_loadfile(J, filename);
218
	js_pushundefined(J);
219
	js_call(J, 0);
220
	js_pop(J, 1);
221
	js_endtry(J);
222
	return 0;
223
}
224
 
225
js_Panic js_atpanic(js_State *J, js_Panic panic)
226
{
227
	js_Panic old = J->panic;
228
	J->panic = panic;
229
	return old;
230
}
231
 
232
void js_report(js_State *J, const char *message)
233
{
234
	if (J->report)
235
		J->report(J, message);
236
}
237
 
238
void js_setreport(js_State *J, js_Report report)
239
{
240
	J->report = report;
241
}
242
 
243
void js_setcontext(js_State *J, void *uctx)
244
{
245
	J->uctx = uctx;
246
}
247
 
248
void *js_getcontext(js_State *J)
249
{
250
	return J->uctx;
251
}
252
 
253
js_State *js_newstate(js_Alloc alloc, void *actx, int flags)
254
{
255
	js_State *J;
256
 
257
	assert(sizeof(js_Value) == 16);
258
	assert(soffsetof(js_Value, type) == 15);
259
 
260
	if (!alloc)
261
		alloc = js_defaultalloc;
262
 
263
	J = alloc(actx, NULL, sizeof *J);
264
	if (!J)
265
		return NULL;
266
	memset(J, 0, sizeof(*J));
267
	J->actx = actx;
268
	J->alloc = alloc;
269
 
270
	if (flags & JS_STRICT)
271
		J->strict = J->default_strict = 1;
272
 
273
	J->trace[0].name = "-top-";
274
	J->trace[0].file = "native";
275
	J->trace[0].line = 0;
276
 
277
	J->report = js_defaultreport;
278
	J->panic = js_defaultpanic;
279
 
280
	J->stack = alloc(actx, NULL, JS_STACKSIZE * sizeof *J->stack);
281
	if (!J->stack) {
282
		alloc(actx, NULL, 0);
283
		return NULL;
284
	}
285
 
286
	J->gcmark = 1;
287
	J->nextref = 0;
288
	J->gcthresh = 0; /* reaches stability within ~ 2-5 GC cycles */
289
 
290
	J->R = jsV_newobject(J, JS_COBJECT, NULL);
291
	J->G = jsV_newobject(J, JS_COBJECT, NULL);
292
	J->E = jsR_newenvironment(J, J->G, NULL);
293
	J->GE = J->E;
294
 
295
	jsB_init(J);
296
 
297
	return J;
298
}