mirror of
https://github.com/ccxvii/mujs.git
synced 2026-09-22 15:13:35 +08:00
Implement instanceof expression.
This commit is contained in:
+3
-1
@@ -201,8 +201,10 @@ static void cobject(JF, js_Ast *list)
|
||||
cexp(J, F, kv->b);
|
||||
emit(J, F, OP_SETPROP);
|
||||
emit(J, F, OP_POP);
|
||||
} else {
|
||||
// TODO: set/get
|
||||
jsC_error(J, kv, "property setters and getters are not implemented");
|
||||
}
|
||||
// TODO: set, get
|
||||
list = list->b;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -1,7 +1,9 @@
|
||||
#ifndef js_compile_h
|
||||
#define js_compile_h
|
||||
|
||||
enum
|
||||
typedef enum js_OpCode js_OpCode;
|
||||
|
||||
enum js_OpCode
|
||||
{
|
||||
OP_POP, /* A -- */
|
||||
OP_POP2, /* A B -- */
|
||||
|
||||
@@ -400,7 +400,7 @@ void js_call(js_State *J, int n)
|
||||
else if (obj->type == JS_CCFUNCTION)
|
||||
jsR_callcfunction(J, n, obj->u.c.function);
|
||||
else
|
||||
js_typeerror(J, "not a function");
|
||||
js_typeerror(J, "call: not a function");
|
||||
BOT = savebot;
|
||||
}
|
||||
|
||||
@@ -451,7 +451,7 @@ void js_construct(js_State *J, int n)
|
||||
void js_savetry(js_State *J, short *pc)
|
||||
{
|
||||
if (J->trylen == JS_TRYLIMIT)
|
||||
js_error(J, "exception stack overflow");
|
||||
js_error(J, "try: exception stack overflow");
|
||||
J->trybuf[J->trylen].E = J->E;
|
||||
J->trybuf[J->trylen].top = J->top;
|
||||
J->trybuf[J->trylen].bot = J->bot;
|
||||
@@ -512,7 +512,8 @@ static void jsR_run(js_State *J, js_Function *F)
|
||||
const char **ST = F->strtab;
|
||||
short *pcstart = F->code;
|
||||
short *pc = F->code;
|
||||
int opcode, offset;
|
||||
js_OpCode opcode;
|
||||
int offset;
|
||||
|
||||
const char *str;
|
||||
js_Object *obj;
|
||||
@@ -574,7 +575,7 @@ static void jsR_run(js_State *J, js_Function *F)
|
||||
if (ref)
|
||||
js_pushvalue(J, ref->value);
|
||||
else
|
||||
js_referenceerror(J, "%s", str);
|
||||
js_referenceerror(J, "%s is not defined", str);
|
||||
break;
|
||||
|
||||
case OP_SETVAR:
|
||||
@@ -749,7 +750,9 @@ static void jsR_run(js_State *J, js_Function *F)
|
||||
case OP_LE: b = js_compare(J); js_pushboolean(J, b <= 0); break;
|
||||
case OP_GE: b = js_compare(J); js_pushboolean(J, b >= 0); break;
|
||||
|
||||
// OP_INSTANCEOF
|
||||
case OP_INSTANCEOF:
|
||||
js_instanceof(J);
|
||||
break;
|
||||
|
||||
/* Equality */
|
||||
|
||||
|
||||
@@ -296,6 +296,38 @@ void js_newcconstructor(js_State *J, js_CFunction cfun, js_CFunction ccon)
|
||||
|
||||
/* Non-trivial operations on values. These are implemented using the stack. */
|
||||
|
||||
void js_instanceof(js_State *J)
|
||||
{
|
||||
js_Object *O, *V;
|
||||
|
||||
if (!js_iscallable(J, -1))
|
||||
js_typeerror(J, "instanceof: invalid operand");
|
||||
|
||||
if (!js_isobject(J, -2)) {
|
||||
js_pop(J, 2);
|
||||
js_pushboolean(J, 0);
|
||||
return;
|
||||
}
|
||||
V = js_toobject(J, -2);
|
||||
|
||||
js_getproperty(J, -1, "prototype");
|
||||
if (!js_isobject(J, -1))
|
||||
js_typeerror(J, "instanceof: 'prototype' property is not an object");
|
||||
O = js_toobject(J, -1);
|
||||
|
||||
while (V) {
|
||||
V = V->prototype;
|
||||
if (O == V) {
|
||||
js_pop(J, 3);
|
||||
js_pushboolean(J, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
js_pop(J, 3);
|
||||
js_pushboolean(J, 0);
|
||||
}
|
||||
|
||||
void js_concat(js_State *J)
|
||||
{
|
||||
js_Value va = js_toprimitive(J, -2, JS_HNONE);
|
||||
|
||||
@@ -92,6 +92,8 @@ unsigned int jsV_numbertouint32(double n);
|
||||
const char *jsV_numbertostring(js_State *J, double number);
|
||||
double jsV_stringtonumber(js_State *J, const char *string);
|
||||
|
||||
void js_instanceof(js_State *J);
|
||||
|
||||
/* jsproperty.c */
|
||||
js_Object *jsV_newobject(js_State *J, js_Class type, js_Object *prototype);
|
||||
js_Property *jsV_getownproperty(js_State *J, js_Object *obj, const char *name);
|
||||
|
||||
Reference in New Issue
Block a user