mirror of
https://github.com/ccxvii/mujs.git
synced 2026-09-22 07:03:36 +08:00
Add prefixes and remove duplicate functions.
Allows compiling all sources as one big blob.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
+24
-24
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user