Calculate stack index for both positive and negative numbers.

Call all functions with "this" as the first argument.

Negative indexes count from the top, positive indexes count from
the current function call frame (so arguments start at 0).
This commit is contained in:
Tor Andersson
2014-01-15 01:34:30 +01:00
parent 6b1906f3b5
commit 47e88ac805
5 changed files with 45 additions and 29 deletions
+1 -1
View File
@@ -12,7 +12,7 @@
typedef struct js_State js_State;
typedef enum js_ValueType js_ValueType;
typedef int (*js_CFunction)(js_State *J);
typedef int (*js_CFunction)(js_State *J, int n);
typedef struct js_Ast js_Ast;
typedef struct js_Closure js_Closure;
typedef struct js_Function js_Function;
+5 -3
View File
@@ -376,21 +376,23 @@ static void ccall(JF, js_Ast *fun, js_Ast *args)
emit(J, F, OP_DUP);
cexp(J, F, fun->b);
emit(J, F, OP_GETPROP);
emit(J, F, OP_ROT2);
break;
case EXP_MEMBER:
cexp(J, F, fun->a);
emit(J, F, OP_DUP);
emitstring(J, F, OP_STRING, fun->b->string);
emit(J, F, OP_GETPROP);
emit(J, F, OP_ROT2);
break;
default:
emit(J, F, OP_THIS);
cexp(J, F, fun);
emit(J, F, OP_THIS);
break;
}
n = cargs(J, F, args);
emit(J, F, OP_CALL);
emit(J, F, n);
emit(J, F, 1 + n);
}
static void cexp(JF, js_Ast *exp)
@@ -661,6 +663,7 @@ static void cstm(JF, js_Ast *stm)
label(J, F, end);
break;
// label
// break
// continue
@@ -687,7 +690,6 @@ static void cstm(JF, js_Ast *stm)
break;
// try
// label
case STM_DEBUGGER:
emit(J, F, OP_DEBUGGER);
+2 -1
View File
@@ -6,6 +6,7 @@ enum
OP_POP, /* A -- */
OP_DUP, /* A -- A A */
OP_DUP2, /* A B -- A B A B */
OP_ROT2, /* A B -- B A */
OP_ROT3, /* A B C -- C A B */
OP_DUP1ROT4, /* A B C -- C A B C */
@@ -39,7 +40,7 @@ enum
OP_DELPROP, /* <obj> <name> -- <success> */
OP_NEXTPROP, /* <obj> <name> -- <obj> <name+1> true || false */
OP_CALL, /* <thisvalue> <closure> <args...> -(numargs)- <returnvalue> */
OP_CALL, /* <closure> <this> <args...> -(numargs)- <returnvalue> */
OP_NEW, /* <closure> <args...> -(numargs)- <returnvalue> */
OP_VOID,
+1 -1
View File
@@ -20,7 +20,7 @@ struct js_Value
const char *string;
js_Object *object;
js_Closure *closure;
js_CFunction *cfunction;
js_CFunction cfunction;
} u;
js_ValueType type;
};
+36 -23
View File
@@ -6,6 +6,7 @@
static js_Value stack[256];
static int top = 0;
static int bot = 0;
static inline double tointeger(double n)
{
@@ -82,21 +83,34 @@ void js_pushobject(js_State *J, js_Object *v)
++top;
}
static int stackidx(js_State *J, int idx)
{
if (idx < 0)
return top + idx;
return bot + idx;
}
int js_isundefined(js_State *J, int idx)
{
idx += top;
idx = stackidx(J, idx);
return stack[idx].type == JS_TUNDEFINED;
}
int js_isstring(js_State *J, int idx)
{
idx += top;
idx = stackidx(J, idx);
return stack[idx].type == JS_TSTRING;
}
int js_iscfunction(js_State *J, int idx)
{
idx = stackidx(J, idx);
return stack[idx].type == JS_TCFUNCTION;
}
js_Value js_tovalue(js_State *J, int idx)
{
idx += top;
idx = stackidx(J, idx);
return stack[idx];
}
@@ -104,7 +118,7 @@ int js_toboolean(js_State *J, int idx)
{
const char *s;
double n;
idx += top;
idx = stackidx(J, idx);
switch (stack[idx].type) {
case JS_TUNDEFINED: return 0;
case JS_TNULL: return 0;
@@ -117,7 +131,7 @@ int js_toboolean(js_State *J, int idx)
double js_tonumber(js_State *J, int idx)
{
idx += top;
idx = stackidx(J, idx);
switch (stack[idx].type) {
case JS_TUNDEFINED: return NAN;
case JS_TNULL: return 0;
@@ -133,20 +147,10 @@ double js_tointeger(js_State *J, int idx)
return toint32(js_tonumber(J, idx));
}
int js_toint32(js_State *J, int idx)
{
return toint32(js_tonumber(J, idx));
}
unsigned int js_touint32(js_State *J, int idx)
{
return toint32(js_tonumber(J, idx));
}
const char *js_tostring(js_State *J, int idx)
{
char buf[20];
idx += top;
idx = stackidx(J, idx);
switch (stack[idx].type) {
case JS_TUNDEFINED: return "undefined";
case JS_TNULL: return "null";
@@ -159,7 +163,7 @@ const char *js_tostring(js_State *J, int idx)
js_Object *js_toobject(js_State *J, int idx)
{
idx += top;
idx = stackidx(J, idx);
switch (stack[idx].type) {
case JS_TUNDEFINED: jsR_error(J, "TypeError");
case JS_TNULL: jsR_error(J, "TypeError");
@@ -190,6 +194,14 @@ void js_dup2(js_State *J)
top += 2;
}
void js_rot2(js_State *J)
{
/* A B -> B A */
js_Value tmp = stack[top-1]; /* A B (B) */
stack[top-1] = stack[top-2]; /* A A */
stack[top-2] = tmp; /* B A */
}
void js_rot3(js_State *J)
{
/* A B C -> C A B */
@@ -241,6 +253,7 @@ static void runfun(js_State *J, js_Function *F, js_Object *E)
case OP_POP: js_pop(J, 1); break;
case OP_DUP: js_dup(J); break;
case OP_DUP2: js_dup2(J); break;
case OP_ROT2: js_rot2(J); break;
case OP_ROT3: js_rot3(J); break;
case OP_DUP1ROT4: js_dup1rot4(J); break;
@@ -255,7 +268,8 @@ static void runfun(js_State *J, js_Function *F, js_Object *E)
case OP_NULL: js_pushnull(J); break;
case OP_TRUE: js_pushboolean(J, 1); break;
case OP_FALSE: js_pushboolean(J, 0); break;
// case OP_THIS: break;
case OP_THIS: js_pushnull(J); break;
case OP_NEWOBJECT: js_pushobject(J, js_newobject(J)); break;
case OP_NEWARRAY: js_pushobject(J, js_newobject(J)); break;
@@ -323,7 +337,6 @@ static void runfun(js_State *J, js_Function *F, js_Object *E)
ref = js_firstproperty(J, obj);
else
ref = js_nextproperty(J, obj, js_tostring(J, -1));
printf("nextprop -> %s\n", ref ? ref->name : "(end)");
if (ref) {
js_pop(J, 1);
js_pushstring(J, ref->name);
@@ -517,14 +530,14 @@ void jsR_error(js_State *J, const char *message)
void jsR_runfunction(js_State *J, js_Function *F)
{
js_Object *varenv = js_newobject(J);
js_Object *E = js_newobject(J);
if (setjmp(J->jb)) {
js_dumpobject(J, varenv);
js_dumpobject(J, E);
return;
}
runfun(J, F, varenv);
runfun(J, F, E);
js_dumpobject(J, varenv);
js_dumpobject(J, E);
}