Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7639 views
1
#include "jsi.h"
2
#include "jslex.h"
3
#include "jscompile.h"
4
#include "jsvalue.h"
5
#include "jsbuiltin.h"
6
7
static void jsB_globalf(js_State *J, const char *name, js_CFunction cfun, int n)
8
{
9
js_newcfunction(J, cfun, name, n);
10
js_defglobal(J, name, JS_DONTENUM);
11
}
12
13
void jsB_propf(js_State *J, const char *name, js_CFunction cfun, int n)
14
{
15
js_newcfunction(J, cfun, name, n);
16
js_defproperty(J, -2, name, JS_DONTENUM);
17
}
18
19
void jsB_propn(js_State *J, const char *name, double number)
20
{
21
js_pushnumber(J, number);
22
js_defproperty(J, -2, name, JS_READONLY | JS_DONTENUM | JS_DONTCONF);
23
}
24
25
void jsB_props(js_State *J, const char *name, const char *string)
26
{
27
js_pushliteral(J, string);
28
js_defproperty(J, -2, name, JS_DONTENUM);
29
}
30
31
static void jsB_parseInt(js_State *J)
32
{
33
const char *s = js_tostring(J, 1);
34
double radix = js_isdefined(J, 2) ? js_tonumber(J, 2) : 10;
35
char *e;
36
double n;
37
38
while (jsY_iswhite(*s) || jsY_isnewline(*s)) ++s;
39
if (radix == 0)
40
radix = 10;
41
if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
42
s += 2;
43
radix = 16;
44
}
45
n = strtol(s, &e, radix);
46
if (s == e)
47
js_pushnumber(J, NAN);
48
else
49
js_pushnumber(J, n);
50
}
51
52
static void jsB_parseFloat(js_State *J)
53
{
54
const char *s = js_tostring(J, 1);
55
char *e;
56
double n;
57
58
while (jsY_iswhite(*s) || jsY_isnewline(*s)) ++s;
59
if (!strncmp(s, "Infinity", 8))
60
js_pushnumber(J, INFINITY);
61
else if (!strncmp(s, "+Infinity", 9))
62
js_pushnumber(J, INFINITY);
63
else if (!strncmp(s, "-Infinity", 9))
64
js_pushnumber(J, -INFINITY);
65
else {
66
n = js_stringtofloat(s, &e);
67
if (e == s)
68
js_pushnumber(J, NAN);
69
else
70
js_pushnumber(J, n);
71
}
72
}
73
74
static void jsB_isNaN(js_State *J)
75
{
76
double n = js_tonumber(J, 1);
77
js_pushboolean(J, isnan(n));
78
}
79
80
static void jsB_isFinite(js_State *J)
81
{
82
double n = js_tonumber(J, 1);
83
js_pushboolean(J, isfinite(n));
84
}
85
86
static void Encode(js_State *J, const char *str, const char *unescaped)
87
{
88
js_Buffer *sb = NULL;
89
90
static const char *HEX = "0123456789ABCDEF";
91
92
while (*str) {
93
int c = (unsigned char) *str++;
94
if (strchr(unescaped, c))
95
js_putc(J, &sb, c);
96
else {
97
js_putc(J, &sb, '%');
98
js_putc(J, &sb, HEX[(c >> 4) & 0xf]);
99
js_putc(J, &sb, HEX[c & 0xf]);
100
}
101
}
102
js_putc(J, &sb, 0);
103
104
if (js_try(J)) {
105
js_free(J, sb);
106
js_throw(J);
107
}
108
js_pushstring(J, sb ? sb->s : "");
109
js_endtry(J);
110
js_free(J, sb);
111
}
112
113
static void Decode(js_State *J, const char *str, const char *reserved)
114
{
115
js_Buffer *sb = NULL;
116
int a, b;
117
118
while (*str) {
119
int c = (unsigned char) *str++;
120
if (c != '%')
121
js_putc(J, &sb, c);
122
else {
123
if (!str[0] || !str[1])
124
js_urierror(J, "truncated escape sequence");
125
a = *str++;
126
b = *str++;
127
if (!jsY_ishex(a) || !jsY_ishex(b))
128
js_urierror(J, "invalid escape sequence");
129
c = jsY_tohex(a) << 4 | jsY_tohex(b);
130
if (!strchr(reserved, c))
131
js_putc(J, &sb, c);
132
else {
133
js_putc(J, &sb, '%');
134
js_putc(J, &sb, a);
135
js_putc(J, &sb, b);
136
}
137
}
138
}
139
js_putc(J, &sb, 0);
140
141
if (js_try(J)) {
142
js_free(J, sb);
143
js_throw(J);
144
}
145
js_pushstring(J, sb ? sb->s : "");
146
js_endtry(J);
147
js_free(J, sb);
148
}
149
150
#define URIRESERVED ";/?:@&=+$,"
151
#define URIALPHA "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
152
#define URIDIGIT "0123456789"
153
#define URIMARK "-_.!~*`()"
154
#define URIUNESCAPED URIALPHA URIDIGIT URIMARK
155
156
static void jsB_decodeURI(js_State *J)
157
{
158
Decode(J, js_tostring(J, 1), URIRESERVED "#");
159
}
160
161
static void jsB_decodeURIComponent(js_State *J)
162
{
163
Decode(J, js_tostring(J, 1), "");
164
}
165
166
static void jsB_encodeURI(js_State *J)
167
{
168
Encode(J, js_tostring(J, 1), URIUNESCAPED URIRESERVED "#");
169
}
170
171
static void jsB_encodeURIComponent(js_State *J)
172
{
173
Encode(J, js_tostring(J, 1), URIUNESCAPED);
174
}
175
176
void jsB_init(js_State *J)
177
{
178
/* Create the prototype objects here, before the constructors */
179
J->Object_prototype = jsV_newobject(J, JS_COBJECT, NULL);
180
J->Array_prototype = jsV_newobject(J, JS_CARRAY, J->Object_prototype);
181
J->Function_prototype = jsV_newobject(J, JS_CCFUNCTION, J->Object_prototype);
182
J->Boolean_prototype = jsV_newobject(J, JS_CBOOLEAN, J->Object_prototype);
183
J->Number_prototype = jsV_newobject(J, JS_CNUMBER, J->Object_prototype);
184
J->String_prototype = jsV_newobject(J, JS_CSTRING, J->Object_prototype);
185
J->RegExp_prototype = jsV_newobject(J, JS_COBJECT, J->Object_prototype);
186
J->Date_prototype = jsV_newobject(J, JS_CDATE, J->Object_prototype);
187
188
/* All the native error types */
189
J->Error_prototype = jsV_newobject(J, JS_CERROR, J->Object_prototype);
190
J->EvalError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype);
191
J->RangeError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype);
192
J->ReferenceError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype);
193
J->SyntaxError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype);
194
J->TypeError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype);
195
J->URIError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype);
196
197
/* Create the constructors and fill out the prototype objects */
198
jsB_initobject(J);
199
jsB_initarray(J);
200
jsB_initfunction(J);
201
jsB_initboolean(J);
202
jsB_initnumber(J);
203
jsB_initstring(J);
204
jsB_initregexp(J);
205
jsB_initdate(J);
206
jsB_initerror(J);
207
jsB_initmath(J);
208
jsB_initjson(J);
209
210
/* Initialize the global object */
211
js_pushnumber(J, NAN);
212
js_defglobal(J, "NaN", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
213
214
js_pushnumber(J, INFINITY);
215
js_defglobal(J, "Infinity", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
216
217
js_pushundefined(J);
218
js_defglobal(J, "undefined", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
219
220
jsB_globalf(J, "parseInt", jsB_parseInt, 1);
221
jsB_globalf(J, "parseFloat", jsB_parseFloat, 1);
222
jsB_globalf(J, "isNaN", jsB_isNaN, 1);
223
jsB_globalf(J, "isFinite", jsB_isFinite, 1);
224
225
jsB_globalf(J, "decodeURI", jsB_decodeURI, 1);
226
jsB_globalf(J, "decodeURIComponent", jsB_decodeURIComponent, 1);
227
jsB_globalf(J, "encodeURI", jsB_encodeURI, 1);
228
jsB_globalf(J, "encodeURIComponent", jsB_encodeURIComponent, 1);
229
}
230
231