diff --git a/js.h b/js.h index 39ded99..411001b 100644 --- a/js.h +++ b/js.h @@ -128,6 +128,7 @@ unsigned short js_touint16(js_State *J, int idx); int js_gettop(js_State *J); void js_settop(js_State *J, int idx); void js_pop(js_State *J, int n); +void js_rot(js_State *J, int n); void js_copy(js_State *J, int idx); void js_remove(js_State *J, int idx); void js_insert(js_State *J, int idx); diff --git a/jsi.h b/jsi.h index 2870d2d..19a5052 100644 --- a/jsi.h +++ b/jsi.h @@ -39,7 +39,6 @@ void js_newfunction(js_State *J, js_Function *function, js_Environment *scope); void js_newscript(js_State *J, js_Function *function); void js_dup(js_State *J); -void js_rot(js_State *J, int n); void js_rot2(js_State *J); void js_rot3(js_State *J); diff --git a/jsintern.c b/jsintern.c index e0a12f0..e6f9e0b 100644 --- a/jsintern.c +++ b/jsintern.c @@ -9,19 +9,19 @@ struct js_StringNode char string[1]; }; -static js_StringNode sentinel = { &sentinel, &sentinel, 0, ""}; +static js_StringNode jsS_sentinel = { &jsS_sentinel, &jsS_sentinel, 0, ""}; -static js_StringNode *newstringnode(const char *string, const char **result) +static js_StringNode *jsS_newstringnode(const char *string, const char **result) { int n = strlen(string); js_StringNode *node = malloc(offsetof(js_StringNode, string) + n + 1); - node->left = node->right = &sentinel; + node->left = node->right = &jsS_sentinel; node->level = 1; strcpy(node->string, string); return *result = node->string, node; } -static js_StringNode *skew(js_StringNode *node) +static js_StringNode *jsS_skew(js_StringNode *node) { if (node->level != 0) { if (node->left->level == node->level) { @@ -30,12 +30,12 @@ static js_StringNode *skew(js_StringNode *node) save->left = node->right; node->right = save; } - node->right = skew(node->right); + node->right = jsS_skew(node->right); } return node; } -static js_StringNode *split(js_StringNode *node) +static js_StringNode *jsS_split(js_StringNode *node) { if (node->level != 0 && node->right->right->level == node->level) { js_StringNode *save = node; @@ -43,38 +43,38 @@ static js_StringNode *split(js_StringNode *node) save->right = node->left; node->left = save; node->level++; - node->right = split(node->right); + node->right = jsS_split(node->right); } return node; } -static js_StringNode *insert(js_StringNode *node, const char *string, const char **result) +static js_StringNode *jsS_insert(js_StringNode *node, const char *string, const char **result) { - if (node != &sentinel) { + if (node != &jsS_sentinel) { int c = strcmp(string, node->string); if (c < 0) - node->left = insert(node->left, string, result); + node->left = jsS_insert(node->left, string, result); else if (c > 0) - node->right = insert(node->right, string, result); + node->right = jsS_insert(node->right, string, result); else return *result = node->string, node; - node = skew(node); - node = split(node); + node = jsS_skew(node); + node = jsS_split(node); return node; } - return newstringnode(string, result); + return jsS_newstringnode(string, result); } static void dumpstringnode(js_StringNode *node, int level) { int i; - if (node->left != &sentinel) + if (node->left != &jsS_sentinel) dumpstringnode(node->left, level + 1); printf("%d: ", node->level); for (i = 0; i < level; ++i) putchar('\t'); printf("'%s'\n", node->string); - if (node->right != &sentinel) + if (node->right != &jsS_sentinel) dumpstringnode(node->right, level + 1); } @@ -82,29 +82,29 @@ void jsS_dumpstrings(js_State *J) { js_StringNode *root = J->strings; printf("interned strings {\n"); - if (root && root != &sentinel) + if (root && root != &jsS_sentinel) dumpstringnode(root, 1); printf("}\n"); } -static void js_freestringnode(js_State *J, js_StringNode *node) +static void jsS_freestringnode(js_State *J, js_StringNode *node) { - if (node->left != &sentinel) js_freestringnode(J, node->left); - if (node->right != &sentinel) js_freestringnode(J, node->right); + if (node->left != &jsS_sentinel) jsS_freestringnode(J, node->left); + if (node->right != &jsS_sentinel) jsS_freestringnode(J, node->right); free(node); } void jsS_freestrings(js_State *J) { - if (J->strings && J->strings != &sentinel) - js_freestringnode(J, J->strings); + if (J->strings && J->strings != &jsS_sentinel) + jsS_freestringnode(J, J->strings); } const char *js_intern(js_State *J, const char *s) { const char *result; if (!J->strings) - J->strings = &sentinel; - J->strings = insert(J->strings, s, &result); + J->strings = &jsS_sentinel; + J->strings = jsS_insert(J->strings, s, &result); return result; } diff --git a/jslex.c b/jslex.c index 4725f78..0d4f33d 100644 --- a/jslex.c +++ b/jslex.c @@ -81,7 +81,7 @@ static const char *keywords[] = { "true", "try", "typeof", "var", "void", "while", "with", }; -static inline int findword(const char *s, const char **list, int num) +int jsY_findword(const char *s, const char **list, int num) { int l = 0; int r = num - 1; @@ -100,7 +100,7 @@ static inline int findword(const char *s, const char **list, int num) static inline int findkeyword(js_State *J, const char *s) { - int i = findword(s, keywords, nelem(keywords)); + int i = jsY_findword(s, keywords, nelem(keywords)); if (i >= 0) { J->text = keywords[i]; return TK_BREAK + i; /* first keyword + i */ @@ -151,11 +151,11 @@ static inline int tohex(int c) } #define PEEK (J->lexchar) -#define NEXT() next(J) +#define NEXT() jsY_next(J) #define ACCEPT(x) (PEEK == x ? (NEXT(), 1) : 0) #define EXPECT(x) (ACCEPT(x) || (jsY_error(J, "expected '%c'", x), 0)) -static void next(js_State *J) +static void jsY_next(js_State *J) { Rune c; J->source += chartorune(&c, J->source); @@ -652,7 +652,7 @@ void jsY_initlex(js_State *J, const char *filename, const char *source) J->source = source; J->line = 1; J->lasttoken = 0; - next(J); /* load first lookahead character */ + NEXT(); /* load first lookahead character */ } int jsY_lex(js_State *J) diff --git a/jslex.h b/jslex.h index 95538b9..c8bbd56 100644 --- a/jslex.h +++ b/jslex.h @@ -67,6 +67,7 @@ enum }; const char *jsY_tokenstring(int token); +int jsY_findword(const char *s, const char **list, int num); void jsY_initlex(js_State *J, const char *filename, const char *source); int jsY_lex(js_State *J); diff --git a/jsparse.c b/jsparse.c index b7897ea..6621248 100644 --- a/jsparse.c +++ b/jsparse.c @@ -134,23 +134,6 @@ static void semicolon(js_State *J) /* Literals */ -static inline int findword(const char *s, const char **list, int num) -{ - int l = 0; - int r = num - 1; - while (l <= r) { - int m = (l + r) >> 1; - int c = strcmp(s, list[m]); - if (c < 0) - r = m - 1; - else if (c > 0) - l = m + 1; - else - return m; - } - return -1; -} - static const char *futurewords[] = { "class", "const", "enum", "export", "extends", "import", "super", }; @@ -162,9 +145,9 @@ static const char *strictfuturewords[] = { static void checkfutureword(js_State *J, const char *s) { - if (findword(s, futurewords, nelem(futurewords)) >= 0) + if (jsY_findword(s, futurewords, nelem(futurewords)) >= 0) jsP_error(J, "'%s' is a future reserved word", s); - if (J->strict && findword(s, strictfuturewords, nelem(strictfuturewords)) >= 0) + if (J->strict && jsY_findword(s, strictfuturewords, nelem(strictfuturewords)) >= 0) jsP_error(J, "'%s' is a strict mode future reserved word", s); } diff --git a/jsrun.c b/jsrun.c index 653119b..672e755 100644 --- a/jsrun.c +++ b/jsrun.c @@ -5,35 +5,6 @@ static void jsR_run(js_State *J, js_Function *F); -static inline double tointeger(double n) -{ - double sign = n < 0 ? -1 : 1; - if (isnan(n)) return 0; - if (n == 0 || isinf(n)) return n; - return sign * floor(abs(n)); -} - -static inline int toint32(double n) -{ - double two32 = 4294967296.0; - double two31 = 2147483648.0; - - if (!isfinite(n) || n == 0) - return 0; - - n = fmod(n, two32); - n = n >= 0 ? floor(n) : ceil(n) + two32; - if (n >= two31) - return n - two32; - else - return n; -} - -static inline unsigned int touint32(double n) -{ - return toint32(n); -} - /* Push values on stack */ #define STACK (J->stack) @@ -155,17 +126,17 @@ double js_tonumber(js_State *J, int idx) double js_tointeger(js_State *J, int idx) { - return tointeger(jsV_tonumber(J, stackidx(J, idx))); + return jsV_numbertointeger(jsV_tonumber(J, stackidx(J, idx))); } int js_toint32(js_State *J, int idx) { - return toint32(jsV_tonumber(J, stackidx(J, idx))); + return jsV_numbertoint32(jsV_tonumber(J, stackidx(J, idx))); } unsigned int js_touint32(js_State *J, int idx) { - return touint32(jsV_tonumber(J, stackidx(J, idx))); + return jsV_numbertouint32(jsV_tonumber(J, stackidx(J, idx))); } const char *js_tostring(js_State *J, int idx) @@ -534,6 +505,8 @@ static void jsR_run(js_State *J, js_Function *F) js_Object *obj; js_Property *ref; double x, y; + unsigned int ux, uy; + int ix, iy; int b; while (1) { @@ -684,9 +657,9 @@ static void jsR_run(js_State *J, js_Function *F) break; case OP_BITNOT: - x = js_tonumber(J, -1); + ix = js_toint32(J, -1); js_pop(J, 1); - js_pushnumber(J, ~toint32(x)); + js_pushnumber(J, ~ix); break; case OP_LOGNOT: @@ -734,24 +707,24 @@ static void jsR_run(js_State *J, js_Function *F) /* Shift operators */ case OP_SHL: - x = js_tonumber(J, -2); - y = js_tonumber(J, -1); + ix = js_toint32(J, -2); + uy = js_touint32(J, -1); js_pop(J, 2); - js_pushnumber(J, toint32(x) << (touint32(y) & 0x1F)); + js_pushnumber(J, ix << (uy & 0x1F)); break; case OP_SHR: - x = js_tonumber(J, -2); - y = js_tonumber(J, -1); + ix = js_toint32(J, -2); + uy = js_touint32(J, -1); js_pop(J, 2); - js_pushnumber(J, toint32(x) >> (touint32(y) & 0x1F)); break; + js_pushnumber(J, ix >> (uy & 0x1F)); break; break; case OP_USHR: - x = js_tonumber(J, -2); - y = js_tonumber(J, -1); + ux = js_touint32(J, -2); + uy = js_touint32(J, -1); js_pop(J, 2); - js_pushnumber(J, touint32(x) >> (touint32(y) & 0x1F)); break; + js_pushnumber(J, ux >> (uy & 0x1F)); break; break; /* Relational operators */ @@ -773,24 +746,24 @@ static void jsR_run(js_State *J, js_Function *F) /* Binary bitwise operators */ case OP_BITAND: - x = js_tonumber(J, -2); - y = js_tonumber(J, -1); + ix = js_toint32(J, -2); + iy = js_toint32(J, -1); js_pop(J, 2); - js_pushnumber(J, toint32(x) & toint32(y)); + js_pushnumber(J, ix & iy); break; case OP_BITXOR: - x = js_tonumber(J, -2); - y = js_tonumber(J, -1); + ix = js_toint32(J, -2); + iy = js_toint32(J, -1); js_pop(J, 2); - js_pushnumber(J, toint32(x) ^ toint32(y)); + js_pushnumber(J, ix ^ iy); break; case OP_BITOR: - x = js_tonumber(J, -2); - y = js_tonumber(J, -1); + ix = js_toint32(J, -2); + iy = js_toint32(J, -1); js_pop(J, 2); - js_pushnumber(J, toint32(x) | toint32(y)); + js_pushnumber(J, ix | iy); break; /* With */ diff --git a/jsvalue.c b/jsvalue.c index 89d31d5..4bd8d99 100644 --- a/jsvalue.c +++ b/jsvalue.c @@ -3,6 +3,35 @@ #include "jsvalue.h" #include "jsutf.h" +double jsV_numbertointeger(double n) +{ + double sign = n < 0 ? -1 : 1; + if (isnan(n)) return 0; + if (n == 0 || isinf(n)) return n; + return sign * floor(abs(n)); +} + +int jsV_numbertoint32(double n) +{ + double two32 = 4294967296.0; + double two31 = 2147483648.0; + + if (!isfinite(n) || n == 0) + return 0; + + n = fmod(n, two32); + n = n >= 0 ? floor(n) : ceil(n) + two32; + if (n >= two31) + return n - two32; + else + return n; +} + +unsigned int jsV_numbertouint32(double n) +{ + return jsV_numbertoint32(n); +} + /* obj.toString() */ static int jsV_toString(js_State *J, js_Object *obj) { diff --git a/jsvalue.h b/jsvalue.h index ad4dc79..78d8ec9 100644 --- a/jsvalue.h +++ b/jsvalue.h @@ -86,6 +86,9 @@ const char *jsV_tostring(js_State *J, const js_Value *v); js_Object *jsV_toobject(js_State *J, const js_Value *v); js_Value jsV_toprimitive(js_State *J, const js_Value *v, int preferred); +double jsV_numbertointeger(double n); +int jsV_numbertoint32(double n); +unsigned int jsV_numbertouint32(double n); const char *jsV_numbertostring(js_State *J, double number); double jsV_stringtonumber(js_State *J, const char *string);