Sigrid Solveig HaflínudóttirPlan 9 portf9452535 years agoHistory
1835 lines · 37.9 KB · C
RawDownload
#include "jsi.h"#include "jscompile.h"#include "jsvalue.h"#include "jsrun.h" #include "utf.h" static void jsR_run(js_State *J, js_Function *F); /* Push values on stack */ #define STACK (J->stack)#define TOP (J->top)#define BOT (J->bot) static void js_stackoverflow(js_State *J){	STACK[TOP].type = JS_TLITSTR;	STACK[TOP].u.litstr = "stack overflow";	++TOP;	js_throw(J);} static void js_outofmemory(js_State *J){	STACK[TOP].type = JS_TLITSTR;	STACK[TOP].u.litstr = "out of memory";	++TOP;	js_throw(J);} void *js_malloc(js_State *J, int size){	void *ptr = J->alloc(J->actx, NULL, size);	if (!ptr)		js_outofmemory(J);	return ptr;} void *js_realloc(js_State *J, void *ptr, int size){	ptr = J->alloc(J->actx, ptr, size);	if (!ptr)		js_outofmemory(J);	return ptr;} char *js_strdup(js_State *J, const char *s){	int n = strlen(s) + 1;	char *p = js_malloc(J, n);	memcpy(p, s, n);	return p;} void js_free(js_State *J, void *ptr){	J->alloc(J->actx, ptr, 0);} js_String *jsV_newmemstring(js_State *J, const char *s, int n){	js_String *v = js_malloc(J, soffsetof(js_String, p) + n + 1);	memcpy(v->p, s, n);	v->p[n] = 0;	v->gcmark = 0;	v->gcnext = J->gcstr;	J->gcstr = v;	++J->gccounter;	return v;} #define CHECKSTACK(n) if (TOP + n >= JS_STACKSIZE) js_stackoverflow(J) void js_pushvalue(js_State *J, js_Value v){	CHECKSTACK(1);	STACK[TOP] = v;	++TOP;} void js_pushundefined(js_State *J){	CHECKSTACK(1);	STACK[TOP].type = JS_TUNDEFINED;	++TOP;} void js_pushnull(js_State *J){	CHECKSTACK(1);	STACK[TOP].type = JS_TNULL;	++TOP;} void js_pushboolean(js_State *J, int v){	CHECKSTACK(1);	STACK[TOP].type = JS_TBOOLEAN;	STACK[TOP].u.boolean = !!v;	++TOP;} void js_pushnumber(js_State *J, double v){	CHECKSTACK(1);	STACK[TOP].type = JS_TNUMBER;	STACK[TOP].u.number = v;	++TOP;} void js_pushstring(js_State *J, const char *v){	int n = strlen(v);	CHECKSTACK(1);	if (n <= soffsetof(js_Value, type)) {		char *s = STACK[TOP].u.shrstr;		while (n--) *s++ = *v++;		*s = 0;		STACK[TOP].type = JS_TSHRSTR;	} else {		STACK[TOP].type = JS_TMEMSTR;		STACK[TOP].u.memstr = jsV_newmemstring(J, v, n);	}	++TOP;} void js_pushlstring(js_State *J, const char *v, int n){	CHECKSTACK(1);	if (n <= soffsetof(js_Value, type)) {		char *s = STACK[TOP].u.shrstr;		while (n--) *s++ = *v++;		*s = 0;		STACK[TOP].type = JS_TSHRSTR;	} else {		STACK[TOP].type = JS_TMEMSTR;		STACK[TOP].u.memstr = jsV_newmemstring(J, v, n);	}	++TOP;} void js_pushliteral(js_State *J, const char *v){	CHECKSTACK(1);	STACK[TOP].type = JS_TLITSTR;	STACK[TOP].u.litstr = v;	++TOP;} void js_pushobject(js_State *J, js_Object *v){	CHECKSTACK(1);	STACK[TOP].type = JS_TOBJECT;	STACK[TOP].u.object = v;	++TOP;} void js_pushglobal(js_State *J){	js_pushobject(J, J->G);} void js_currentfunction(js_State *J){	CHECKSTACK(1);	STACK[TOP] = STACK[BOT-1];	++TOP;} /* Read values from stack */ static js_Value *stackidx(js_State *J, int idx){	static js_Value undefined = { {0}, {0}, JS_TUNDEFINED };	idx = idx < 0 ? TOP + idx : BOT + idx;	if (idx < 0 || idx >= TOP)		return &undefined;	return STACK + idx;} js_Value *js_tovalue(js_State *J, int idx){	return stackidx(J, idx);} int js_isdefined(js_State *J, int idx) { return stackidx(J, idx)->type != JS_TUNDEFINED; }int js_isundefined(js_State *J, int idx) { return stackidx(J, idx)->type == JS_TUNDEFINED; }int js_isnull(js_State *J, int idx) { return stackidx(J, idx)->type == JS_TNULL; }int js_isboolean(js_State *J, int idx) { return stackidx(J, idx)->type == JS_TBOOLEAN; }int js_isnumber(js_State *J, int idx) { return stackidx(J, idx)->type == JS_TNUMBER; }int js_isstring(js_State *J, int idx) { enum js_Type t = stackidx(J, idx)->type; return t == JS_TSHRSTR || t == JS_TLITSTR || t == JS_TMEMSTR; }int js_isprimitive(js_State *J, int idx) { return stackidx(J, idx)->type != JS_TOBJECT; }int js_isobject(js_State *J, int idx) { return stackidx(J, idx)->type == JS_TOBJECT; }int js_iscoercible(js_State *J, int idx) { js_Value *v = stackidx(J, idx); return v->type != JS_TUNDEFINED && v->type != JS_TNULL; } int js_iscallable(js_State *J, int idx){	js_Value *v = stackidx(J, idx);	if (v->type == JS_TOBJECT)		return v->u.object->type == JS_CFUNCTION ||			v->u.object->type == JS_CSCRIPT ||			v->u.object->type == JS_CCFUNCTION;	return 0;} int js_isarray(js_State *J, int idx){	js_Value *v = stackidx(J, idx);	return v->type == JS_TOBJECT && v->u.object->type == JS_CARRAY;} int js_isregexp(js_State *J, int idx){	js_Value *v = stackidx(J, idx);	return v->type == JS_TOBJECT && v->u.object->type == JS_CREGEXP;} int js_isuserdata(js_State *J, int idx, const char *tag){	js_Value *v = stackidx(J, idx);	if (v->type == JS_TOBJECT && v->u.object->type == JS_CUSERDATA)		return !strcmp(tag, v->u.object->u.user.tag);	return 0;} int js_iserror(js_State *J, int idx){	js_Value *v = stackidx(J, idx);	return v->type == JS_TOBJECT && v->u.object->type == JS_CERROR;} const char *js_typeof(js_State *J, int idx){	js_Value *v = stackidx(J, idx);	switch (v->type) {	default:	case JS_TSHRSTR: return "string";	case JS_TUNDEFINED: return "undefined";	case JS_TNULL: return "object";	case JS_TBOOLEAN: return "boolean";	case JS_TNUMBER: return "number";	case JS_TLITSTR: return "string";	case JS_TMEMSTR: return "string";	case JS_TOBJECT:		if (v->u.object->type == JS_CFUNCTION || v->u.object->type == JS_CCFUNCTION)			return "function";		return "object";	}} int js_type(js_State *J, int idx){	js_Value *v = stackidx(J, idx);	switch (v->type) {	default:	case JS_TSHRSTR: return JS_ISSTRING;	case JS_TUNDEFINED: return JS_ISUNDEFINED;	case JS_TNULL: return JS_ISNULL;	case JS_TBOOLEAN: return JS_ISBOOLEAN;	case JS_TNUMBER: return JS_ISNUMBER;	case JS_TLITSTR: return JS_ISSTRING;	case JS_TMEMSTR: return JS_ISSTRING;	case JS_TOBJECT:		if (v->u.object->type == JS_CFUNCTION || v->u.object->type == JS_CCFUNCTION)			return JS_ISFUNCTION;		return JS_ISOBJECT;	}} int js_toboolean(js_State *J, int idx){	return jsV_toboolean(J, stackidx(J, idx));} double js_tonumber(js_State *J, int idx){	return jsV_tonumber(J, stackidx(J, idx));} int js_tointeger(js_State *J, int idx){	return jsV_numbertointeger(jsV_tonumber(J, stackidx(J, idx)));} int js_toint32(js_State *J, int idx){	return jsV_numbertoint32(jsV_tonumber(J, stackidx(J, idx)));} unsigned int js_touint32(js_State *J, int idx){	return jsV_numbertouint32(jsV_tonumber(J, stackidx(J, idx)));} short js_toint16(js_State *J, int idx){	return jsV_numbertoint16(jsV_tonumber(J, stackidx(J, idx)));} unsigned short js_touint16(js_State *J, int idx){	return jsV_numbertouint16(jsV_tonumber(J, stackidx(J, idx)));} const char *js_tostring(js_State *J, int idx){	return jsV_tostring(J, stackidx(J, idx));} js_Object *js_toobject(js_State *J, int idx){	return jsV_toobject(J, stackidx(J, idx));} void js_toprimitive(js_State *J, int idx, int hint){	jsV_toprimitive(J, stackidx(J, idx), hint);} js_Regexp *js_toregexp(js_State *J, int idx){	js_Value *v = stackidx(J, idx);	if (v->type == JS_TOBJECT && v->u.object->type == JS_CREGEXP)		return &v->u.object->u.r;	return js_typeerror(J, "not a regexp");} void *js_touserdata(js_State *J, int idx, const char *tag){	js_Value *v = stackidx(J, idx);	if (v->type == JS_TOBJECT && v->u.object->type == JS_CUSERDATA)		if (!strcmp(tag, v->u.object->u.user.tag))			return v->u.object->u.user.data;	return js_typeerror(J, "not a %s", tag);} static js_Object *jsR_tofunction(js_State *J, int idx){	js_Value *v = stackidx(J, idx);	if (v->type == JS_TUNDEFINED || v->type == JS_TNULL)		return NULL;	if (v->type == JS_TOBJECT)		if (v->u.object->type == JS_CFUNCTION || v->u.object->type == JS_CCFUNCTION)			return v->u.object;	return js_typeerror(J, "not a function");} /* Stack manipulation */ int js_gettop(js_State *J){	return TOP - BOT;} void js_pop(js_State *J, int n){	TOP -= n;	if (TOP < BOT) {		TOP = BOT;		js_error(J, "stack underflow!");	}} void js_remove(js_State *J, int idx){	idx = idx < 0 ? TOP + idx : BOT + idx;	if (idx < BOT || idx >= TOP)		js_error(J, "stack error!");	for (;idx < TOP - 1; ++idx)		STACK[idx] = STACK[idx+1];	--TOP;} void js_insert(js_State *J, int idx){	js_error(J, "not implemented yet");} void js_replace(js_State* J, int idx){	idx = idx < 0 ? TOP + idx : BOT + idx;	if (idx < BOT || idx >= TOP)		js_error(J, "stack error!");	STACK[idx] = STACK[--TOP];} void js_copy(js_State *J, int idx){	CHECKSTACK(1);	STACK[TOP] = *stackidx(J, idx);	++TOP;} void js_dup(js_State *J){	CHECKSTACK(1);	STACK[TOP] = STACK[TOP-1];	++TOP;} void js_dup2(js_State *J){	CHECKSTACK(2);	STACK[TOP] = STACK[TOP-2];	STACK[TOP+1] = STACK[TOP-1];	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 */	js_Value tmp = STACK[TOP-1];	/* A B C (C) */	STACK[TOP-1] = STACK[TOP-2];	/* A B B */	STACK[TOP-2] = STACK[TOP-3];	/* A A B */	STACK[TOP-3] = tmp;		/* C A B */} void js_rot4(js_State *J){	/* A B C D -> D A B C */	js_Value tmp = STACK[TOP-1];	/* A B C D (D) */	STACK[TOP-1] = STACK[TOP-2];	/* A B C C */	STACK[TOP-2] = STACK[TOP-3];	/* A B B C */	STACK[TOP-3] = STACK[TOP-4];	/* A A B C */	STACK[TOP-4] = tmp;		/* D A B C */} void js_rot2pop1(js_State *J){	/* A B -> B */	STACK[TOP-2] = STACK[TOP-1];	--TOP;} void js_rot3pop2(js_State *J){	/* A B C -> C */	STACK[TOP-3] = STACK[TOP-1];	TOP -= 2;} void js_rot(js_State *J, int n){	int i;	js_Value tmp = STACK[TOP-1];	for (i = 1; i < n; ++i)		STACK[TOP-i] = STACK[TOP-i-1];	STACK[TOP-i] = tmp;} /* Property access that takes care of attributes and getters/setters */ int js_isarrayindex(js_State *J, const char *p, int *idx){	int n = 0; 	/* check for empty string */	if (p[0] == 0)		return 0; 	/* check for '0' and integers with leading zero */	if (p[0] == '0')		return (p[1] == 0) ? *idx = 0, 1 : 0; 	while (*p) {		int c = *p++;		if (c >= '0' && c <= '9') {			if (n >= INT_MAX / 10)				return 0;			n = n * 10 + (c - '0');		} else {			return 0;		}	}	return *idx = n, 1;} static void js_pushrune(js_State *J, Rune rune){	char buf[UTFmax + 1];	if (rune >= 0) {		buf[runetochar(buf, &rune)] = 0;		js_pushstring(J, buf);	} else {		js_pushundefined(J);	}} static int jsR_hasproperty(js_State *J, js_Object *obj, const char *name){	js_Property *ref;

Lines 1–500 of 1835.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t