Beispiel #1
0
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);
}
Beispiel #2
0
static void wrapmethod(js_State *J)
{
	pdf_jsimp_obj *args[MAXARGS];
	pdf_jsimp_obj *ret;
	pdf_jsimp_method *meth;
	const char *type;
	void *jsctx;
	void *obj;
	int i;

	int argc = js_gettop(J) - 1;

	js_getregistry(J, "jsctx");
	jsctx = js_touserdata(J, "jsctx", -1);
	js_pop(J, 1);

	js_currentfunction(J);
	{
		js_getproperty(J, -1, "__call");
		meth = js_touserdata(J, "method", -1);
		js_pop(J, 1);

		js_getproperty(J, -1, "__type");
		type = js_tostring(J, -1);
		js_pop(J, 1);
	}
	js_pop(J, 1);

	if (js_isuserdata(J, type, 0))
		obj = js_touserdata(J, type, 0);
	else
		obj = NULL;

	if (argc > MAXARGS)
		js_rangeerror(J, "too many arguments");

	for (i = 0; i < argc; ++i)
		args[i] = OBJ(i+1);
	ret = meth(jsctx, obj, argc, args);
	if (ret)
		js_copy(J, IDX(ret));
	else
		js_pushundefined(J);
}
Beispiel #3
0
static void jsR_setproperty(js_State *J, js_Object *obj, const char *name, js_Value *value)
{
	js_Property *ref;
	unsigned int k;
	int own;

	if (obj->type == JS_CARRAY) {
		if (!strcmp(name, "length")) {
			double rawlen = jsV_tonumber(J, value);
			unsigned int newlen = jsV_numbertouint32(rawlen);
			if (newlen != rawlen)
				js_rangeerror(J, "array length");
			jsV_resizearray(J, obj, newlen);
			return;
		}
		if (js_isarrayindex(J, name, &k))
			if (k >= obj->u.a.length)
				obj->u.a.length = k + 1;
	}

	if (obj->type == JS_CSTRING) {
		if (!strcmp(name, "length"))
			goto readonly;
		if (js_isarrayindex(J, name, &k))
			if (js_runeat(J, obj->u.s.string, k))
				goto readonly;
	}

	if (obj->type == JS_CREGEXP) {
		if (!strcmp(name, "source")) goto readonly;
		if (!strcmp(name, "global")) goto readonly;
		if (!strcmp(name, "ignoreCase")) goto readonly;
		if (!strcmp(name, "multiline")) goto readonly;
		if (!strcmp(name, "lastIndex")) {
			obj->u.r.last = jsV_tointeger(J, value);
			return;
		}
	}

	/* First try to find a setter in prototype chain */
	ref = jsV_getpropertyx(J, obj, name, &own);
	if (ref && ref->setter) {
		js_pushobject(J, ref->setter);
		js_pushobject(J, obj);
		js_pushvalue(J, *value);
		js_call(J, 1);
		js_pop(J, 1);
		return;
	}

	/* Property not found on this object, so create one */
	if (!ref || !own)
		ref = jsV_setproperty(J, obj, name);

	if (ref) {
		if (!(ref->atts & JS_READONLY))
			ref->value = *value;
		else
			goto readonly;
	}

	return;

readonly:
	if (J->strict)
		js_typeerror(J, "'%s' is read-only", name);
}