759 lines · 14.1 KB · C
RawDownload
#include "jsi.h"#include "jsvalue.h"#include "jsbuiltin.h" int js_getlength(js_State *J, int idx){	int len;	js_getproperty(J, idx, "length");	len = js_tointeger(J, -1);	js_pop(J, 1);	return len;} void js_setlength(js_State *J, int idx, int len){	js_pushnumber(J, len);	js_setproperty(J, idx < 0 ? idx - 1 : idx, "length");} int js_hasindex(js_State *J, int idx, int i){	char buf[32];	return js_hasproperty(J, idx, js_itoa(buf, i));} void js_getindex(js_State *J, int idx, int i){	char buf[32];	js_getproperty(J, idx, js_itoa(buf, i));} void js_setindex(js_State *J, int idx, int i){	char buf[32];	js_setproperty(J, idx, js_itoa(buf, i));} void js_delindex(js_State *J, int idx, int i){	char buf[32];	js_delproperty(J, idx, js_itoa(buf, i));} static void jsB_new_Array(js_State *J){	int i, top = js_gettop(J); 	js_newarray(J); 	if (top == 2) {		if (js_isnumber(J, 1)) {			js_copy(J, 1);			js_setproperty(J, -2, "length");		} else {			js_copy(J, 1);			js_setindex(J, -2, 0);		}	} else {		for (i = 1; i < top; ++i) {			js_copy(J, i);			js_setindex(J, -2, i - 1);		}	}} static void Ap_concat(js_State *J){	int i, top = js_gettop(J);	int n, k, len; 	js_newarray(J);	n = 0; 	for (i = 0; i < top; ++i) {		js_copy(J, i);		if (js_isarray(J, -1)) {			len = js_getlength(J, -1);			for (k = 0; k < len; ++k)				if (js_hasindex(J, -1, k))					js_setindex(J, -3, n++);			js_pop(J, 1);		} else {			js_setindex(J, -2, n++);		}	}} static void Ap_join(js_State *J){	char * volatile out = NULL;	const char *sep;	const char *r;	int seplen;	int k, n, len; 	len = js_getlength(J, 0); 	if (js_isdefined(J, 1)) {		sep = js_tostring(J, 1);		seplen = strlen(sep);	} else {		sep = ",";		seplen = 1;	} 	if (len <= 0) {		js_pushliteral(J, "");		return;	} 	if (js_try(J)) {		js_free(J, out);		js_throw(J);	} 	n = 1;	for (k = 0; k < len; ++k) {		js_getindex(J, 0, k);		if (js_isundefined(J, -1) || js_isnull(J, -1))			r = "";		else			r = js_tostring(J, -1);		n += strlen(r); 		if (k == 0) {			out = js_malloc(J, n);			strcpy(out, r);		} else {			n += seplen;			out = js_realloc(J, out, n);			strcat(out, sep);			strcat(out, r);		} 		js_pop(J, 1);	} 	js_pushstring(J, out);	js_endtry(J);	js_free(J, out);} static void Ap_pop(js_State *J){	int n; 	n = js_getlength(J, 0); 	if (n > 0) {		js_getindex(J, 0, n - 1);		js_delindex(J, 0, n - 1);		js_setlength(J, 0, n - 1);	} else {		js_setlength(J, 0, 0);		js_pushundefined(J);	}} static void Ap_push(js_State *J){	int i, top = js_gettop(J);	int n; 	n = js_getlength(J, 0); 	for (i = 1; i < top; ++i, ++n) {		js_copy(J, i);		js_setindex(J, 0, n);	} 	js_setlength(J, 0, n); 	js_pushnumber(J, n);} static void Ap_reverse(js_State *J){	int len, middle, lower; 	len = js_getlength(J, 0);	middle = len / 2;	lower = 0; 	while (lower != middle) {		int upper = len - lower - 1;		int haslower = js_hasindex(J, 0, lower);		int hasupper = js_hasindex(J, 0, upper);		if (haslower && hasupper) {			js_setindex(J, 0, lower);			js_setindex(J, 0, upper);		} else if (hasupper) {			js_setindex(J, 0, lower);			js_delindex(J, 0, upper);		} else if (haslower) {			js_setindex(J, 0, upper);			js_delindex(J, 0, lower);		}		++lower;	} 	js_copy(J, 0);} static void Ap_shift(js_State *J){	int k, len; 	len = js_getlength(J, 0); 	if (len == 0) {		js_setlength(J, 0, 0);		js_pushundefined(J);		return;	} 	js_getindex(J, 0, 0); 	for (k = 1; k < len; ++k) {		if (js_hasindex(J, 0, k))			js_setindex(J, 0, k - 1);		else			js_delindex(J, 0, k - 1);	} 	js_delindex(J, 0, len - 1);	js_setlength(J, 0, len - 1);} static void Ap_slice(js_State *J){	int len, s, e, n;	double sv, ev; 	js_newarray(J); 	len = js_getlength(J, 0);	sv = js_tointeger(J, 1);	ev = js_isdefined(J, 2) ? js_tointeger(J, 2) : len; 	if (sv < 0) sv = sv + len;	if (ev < 0) ev = ev + len; 	s = sv < 0 ? 0 : sv > len ? len : sv;	e = ev < 0 ? 0 : ev > len ? len : ev; 	for (n = 0; s < e; ++s, ++n)		if (js_hasindex(J, 0, s))			js_setindex(J, -2, n);} struct sortslot {	js_Value v;	js_State *J;}; static int sortcmp(const void *avoid, const void *bvoid){	const struct sortslot *aslot = avoid, *bslot = bvoid;	const js_Value *a = &aslot->v, *b = &bslot->v;	js_State *J = aslot->J;	const char *sx, *sy;	double v;	int c; 	int unx = (a->type == JS_TUNDEFINED);	int uny = (b->type == JS_TUNDEFINED);	if (unx) return !uny;	if (uny) return -1; 	if (js_iscallable(J, 1)) {		js_copy(J, 1); /* copy function */		js_pushundefined(J);		js_pushvalue(J, *a);		js_pushvalue(J, *b);		js_call(J, 2);		v = js_tonumber(J, -1);		c = (v == 0) ? 0 : (v < 0) ? -1 : 1;		js_pop(J, 1);	} else {		js_pushvalue(J, *a);		js_pushvalue(J, *b);		sx = js_tostring(J, -2);		sy = js_tostring(J, -1);		c = strcmp(sx, sy);		js_pop(J, 2);	}	return c;} static void Ap_sort(js_State *J){	struct sortslot *array = NULL;	int i, n, len; 	len = js_getlength(J, 0);	if (len <= 0) {		js_copy(J, 0);		return;	} 	if (len >= INT_MAX / (int)sizeof(*array))		js_rangeerror(J, "array is too large to sort"); 	array = js_malloc(J, len * sizeof *array); 	/* Holding objects where the GC cannot see them is illegal, but if we	 * don't allow the GC to run we can use qsort() on a temporary array of	 * js_Values for fast sorting.	 */	++J->gcpause; 	if (js_try(J)) {		--J->gcpause;		js_free(J, array);		js_throw(J);	} 	n = 0;	for (i = 0; i < len; ++i) {		if (js_hasindex(J, 0, i)) {			array[n].v = *js_tovalue(J, -1);			array[n].J = J;			js_pop(J, 1);			++n;		}	} 	qsort(array, n, sizeof *array, sortcmp); 	for (i = 0; i < n; ++i) {		js_pushvalue(J, array[i].v);		js_setindex(J, 0, i);	}	for (i = n; i < len; ++i) {		js_delindex(J, 0, i);	} 	--J->gcpause; 	js_endtry(J);	js_free(J, array); 	js_copy(J, 0);} static void Ap_splice(js_State *J){	int top = js_gettop(J);	int len, start, del, add, k;	double f; 	js_newarray(J); 	len = js_getlength(J, 0); 	f = js_tointeger(J, 1);	if (f < 0) f = f + len;	start = f < 0 ? 0 : f > len ? len : f; 	f = js_tointeger(J, 2);	del = f < 0 ? 0 : f > len - start ? len - start : f; 	/* copy deleted items to return array */	for (k = 0; k < del; ++k)		if (js_hasindex(J, 0, start + k))			js_setindex(J, -2, k);	js_setlength(J, -1, del); 	/* shift the tail to resize the hole left by deleted items */	add = top - 3;	if (add < del) {		for (k = start; k < len - del; ++k) {			if (js_hasindex(J, 0, k + del))				js_setindex(J, 0, k + add);			else				js_delindex(J, 0, k + add);		}		for (k = len; k > len - del + add; --k)			js_delindex(J, 0, k - 1);	} else if (add > del) {		for (k = len - del; k > start; --k) {			if (js_hasindex(J, 0, k + del - 1))				js_setindex(J, 0, k + add - 1);			else				js_delindex(J, 0, k + add - 1);		}	} 	/* copy new items into the hole */	for (k = 0; k < add; ++k) {		js_copy(J, 3 + k);		js_setindex(J, 0, start + k);	} 	js_setlength(J, 0, len - del + add);} static void Ap_unshift(js_State *J){	int i, top = js_gettop(J);	int k, len; 	len = js_getlength(J, 0); 	for (k = len; k > 0; --k) {		int from = k - 1;		int to = k + top - 2;		if (js_hasindex(J, 0, from))			js_setindex(J, 0, to);		else			js_delindex(J, 0, to);	} 	for (i = 1; i < top; ++i) {		js_copy(J, i);		js_setindex(J, 0, i - 1);	} 	js_setlength(J, 0, len + top - 1); 	js_pushnumber(J, len + top - 1);} static void Ap_toString(js_State *J){	if (!js_iscoercible(J, 0))		js_typeerror(J, "'this' is not an object");	js_getproperty(J, 0, "join");	if (!js_iscallable(J, -1)) {		js_pop(J, 1);		// TODO: call Object.prototype.toString implementation directly		js_getglobal(J, "Object");		js_getproperty(J, -1, "prototype");		js_rot2pop1(J);		js_getproperty(J, -1, "toString");		js_rot2pop1(J);	}	js_copy(J, 0);	js_call(J, 0);} static void Ap_indexOf(js_State *J){	int k, len, from; 	len = js_getlength(J, 0);	from = js_isdefined(J, 2) ? js_tointeger(J, 2) : 0;	if (from < 0) from = len + from;	if (from < 0) from = 0; 	js_copy(J, 1);	for (k = from; k < len; ++k) {		if (js_hasindex(J, 0, k)) {			if (js_strictequal(J)) {				js_pushnumber(J, k);				return;			}			js_pop(J, 1);		}	} 	js_pushnumber(J, -1);} static void Ap_lastIndexOf(js_State *J){	int k, len, from; 	len = js_getlength(J, 0);	from = js_isdefined(J, 2) ? js_tointeger(J, 2) : len - 1;	if (from > len - 1) from = len - 1;	if (from < 0) from = len + from; 	js_copy(J, 1);	for (k = from; k >= 0; --k) {		if (js_hasindex(J, 0, k)) {			if (js_strictequal(J)) {				js_pushnumber(J, k);				return;			}			js_pop(J, 1);		}	} 	js_pushnumber(J, -1);} static void Ap_every(js_State *J){	int hasthis = js_gettop(J) >= 3;	int k, len; 	if (!js_iscallable(J, 1))		js_typeerror(J, "callback is not a function"); 	len = js_getlength(J, 0);	for (k = 0; k < len; ++k) {		if (js_hasindex(J, 0, k)) {			js_copy(J, 1);			if (hasthis)

Lines 1–500 of 759.

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