| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- #include "jsi.h"
- #include "regexp.h"
- static void jsB_globalf(js_State *J, const char *name, js_CFunction cfun, int n)
- {
- js_newcfunction(J, cfun, name, n);
- js_defglobal(J, name, JS_DONTENUM);
- }
- void jsB_propf(js_State *J, const char *name, js_CFunction cfun, int n)
- {
- const char *pname = strrchr(name, '.');
- pname = pname ? pname + 1 : name;
- js_newcfunction(J, cfun, name, n);
- js_defproperty(J, -2, pname, JS_DONTENUM);
- }
- void jsB_propn(js_State *J, const char *name, double number)
- {
- js_pushnumber(J, number);
- js_defproperty(J, -2, name, JS_READONLY | JS_DONTENUM | JS_DONTCONF);
- }
- void jsB_props(js_State *J, const char *name, const char *string)
- {
- js_pushliteral(J, string);
- js_defproperty(J, -2, name, JS_DONTENUM);
- }
- static void jsB_parseInt(js_State *J)
- {
- const char *s = js_tostring(J, 1);
- int radix = js_isdefined(J, 2) ? js_tointeger(J, 2) : 0;
- double sign = 1;
- double n;
- char *e;
- while (jsY_iswhite(*s) || jsY_isnewline(*s))
- ++s;
- if (*s == '-') {
- ++s;
- sign = -1;
- } else if (*s == '+') {
- ++s;
- }
- if (radix == 0) {
- radix = 10;
- if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
- s += 2;
- radix = 16;
- }
- } else if (radix < 2 || radix > 36) {
- js_pushnumber(J, NAN);
- return;
- }
- n = js_strtol(s, &e, radix);
- if (s == e)
- js_pushnumber(J, NAN);
- else
- js_pushnumber(J, n * sign);
- }
- static void jsB_parseFloat(js_State *J)
- {
- const char *s = js_tostring(J, 1);
- char *e;
- double n;
- while (jsY_iswhite(*s) || jsY_isnewline(*s)) ++s;
- if (!strncmp(s, "Infinity", 8))
- js_pushnumber(J, INFINITY);
- else if (!strncmp(s, "+Infinity", 9))
- js_pushnumber(J, INFINITY);
- else if (!strncmp(s, "-Infinity", 9))
- js_pushnumber(J, -INFINITY);
- else {
- n = js_stringtofloat(s, &e);
- if (e == s)
- js_pushnumber(J, NAN);
- else
- js_pushnumber(J, n);
- }
- }
- static void jsB_isNaN(js_State *J)
- {
- double n = js_tonumber(J, 1);
- js_pushboolean(J, isnan(n));
- }
- static void jsB_isFinite(js_State *J)
- {
- double n = js_tonumber(J, 1);
- js_pushboolean(J, isfinite(n));
- }
- static void Encode(js_State *J, const char *str_, const char *unescaped)
- {
- /* NOTE: volatile to silence GCC warning about longjmp clobbering a variable */
- const char * volatile str = str_;
- js_Buffer *sb = NULL;
- static const char *HEX = "0123456789ABCDEF";
- if (js_try(J)) {
- js_free(J, sb);
- js_throw(J);
- }
- while (*str) {
- int c = (unsigned char) *str++;
- if (strchr(unescaped, c))
- js_putc(J, &sb, c);
- else {
- js_putc(J, &sb, '%');
- js_putc(J, &sb, HEX[(c >> 4) & 0xf]);
- js_putc(J, &sb, HEX[c & 0xf]);
- }
- }
- js_putc(J, &sb, 0);
- js_pushstring(J, sb ? sb->s : "");
- js_endtry(J);
- js_free(J, sb);
- }
- static void Decode(js_State *J, const char *str_, const char *reserved)
- {
- /* NOTE: volatile to silence GCC warning about longjmp clobbering a variable */
- const char * volatile str = str_;
- js_Buffer *sb = NULL;
- int a, b;
- if (js_try(J)) {
- js_free(J, sb);
- js_throw(J);
- }
- while (*str) {
- int c = (unsigned char) *str++;
- if (c != '%')
- js_putc(J, &sb, c);
- else {
- if (!str[0] || !str[1])
- js_urierror(J, "truncated escape sequence");
- a = *str++;
- b = *str++;
- if (!jsY_ishex(a) || !jsY_ishex(b))
- js_urierror(J, "invalid escape sequence");
- c = jsY_tohex(a) << 4 | jsY_tohex(b);
- if (!strchr(reserved, c))
- js_putc(J, &sb, c);
- else {
- js_putc(J, &sb, '%');
- js_putc(J, &sb, a);
- js_putc(J, &sb, b);
- }
- }
- }
- js_putc(J, &sb, 0);
- js_pushstring(J, sb ? sb->s : "");
- js_endtry(J);
- js_free(J, sb);
- }
- #define URIRESERVED ";/?:@&=+$,"
- #define URIALPHA "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
- #define URIDIGIT "0123456789"
- #define URIMARK "-_.!~*'()"
- #define URIUNESCAPED URIALPHA URIDIGIT URIMARK
- static void jsB_decodeURI(js_State *J)
- {
- Decode(J, js_tostring(J, 1), URIRESERVED "#");
- }
- static void jsB_decodeURIComponent(js_State *J)
- {
- Decode(J, js_tostring(J, 1), "");
- }
- static void jsB_encodeURI(js_State *J)
- {
- Encode(J, js_tostring(J, 1), URIUNESCAPED URIRESERVED "#");
- }
- static void jsB_encodeURIComponent(js_State *J)
- {
- Encode(J, js_tostring(J, 1), URIUNESCAPED);
- }
- void jsB_init(js_State *J)
- {
- /* Create the prototype objects here, before the constructors */
- J->Object_prototype = jsV_newobject(J, JS_COBJECT, NULL);
- J->Array_prototype = jsV_newobject(J, JS_CARRAY, J->Object_prototype);
- J->Function_prototype = jsV_newobject(J, JS_CCFUNCTION, J->Object_prototype);
- J->Boolean_prototype = jsV_newobject(J, JS_CBOOLEAN, J->Object_prototype);
- J->Number_prototype = jsV_newobject(J, JS_CNUMBER, J->Object_prototype);
- J->String_prototype = jsV_newobject(J, JS_CSTRING, J->Object_prototype);
- J->Date_prototype = jsV_newobject(J, JS_CDATE, J->Object_prototype);
- J->RegExp_prototype = jsV_newobject(J, JS_CREGEXP, J->Object_prototype);
- J->RegExp_prototype->u.r.prog = js_regcompx(J->alloc, J->actx, "(?:)", 0, NULL);
- J->RegExp_prototype->u.r.source = js_strdup(J, "(?:)");
- /* All the native error types */
- J->Error_prototype = jsV_newobject(J, JS_CERROR, J->Object_prototype);
- J->EvalError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype);
- J->RangeError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype);
- J->ReferenceError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype);
- J->SyntaxError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype);
- J->TypeError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype);
- J->URIError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype);
- /* Create the constructors and fill out the prototype objects */
- jsB_initobject(J);
- jsB_initarray(J);
- jsB_initfunction(J);
- jsB_initboolean(J);
- jsB_initnumber(J);
- jsB_initstring(J);
- jsB_initregexp(J);
- jsB_initdate(J);
- jsB_initerror(J);
- jsB_initmath(J);
- jsB_initjson(J);
- /* Initialize the global object */
- js_pushnumber(J, NAN);
- js_defglobal(J, "NaN", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
- js_pushnumber(J, INFINITY);
- js_defglobal(J, "Infinity", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
- js_pushundefined(J);
- js_defglobal(J, "undefined", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
- jsB_globalf(J, "parseInt", jsB_parseInt, 1);
- jsB_globalf(J, "parseFloat", jsB_parseFloat, 1);
- jsB_globalf(J, "isNaN", jsB_isNaN, 1);
- jsB_globalf(J, "isFinite", jsB_isFinite, 1);
- jsB_globalf(J, "decodeURI", jsB_decodeURI, 1);
- jsB_globalf(J, "decodeURIComponent", jsB_decodeURIComponent, 1);
- jsB_globalf(J, "encodeURI", jsB_encodeURI, 1);
- jsB_globalf(J, "encodeURIComponent", jsB_encodeURIComponent, 1);
- }
|