Subversion Repositories Kolibri OS

Rev

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

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