Exemple #1
0
static int sys1_poll(duk_context *ctx)
{
	int nfds = duk_to_int(ctx, 1);
	int timeout = duk_to_int(ctx, 2);
	int i, rc;
	struct pollfd *fds;

	fds = malloc(sizeof(struct pollfd)*nfds);
	memset(fds, 0, sizeof(struct pollfd)*nfds);
	
	for(i=0;i<nfds;i++) {
		duk_get_prop_index(ctx, 0, i);
		duk_get_prop_string(ctx, 3, "fd");	
		fds[i].fd = duk_to_int(ctx, 4);
		duk_get_prop_string(ctx, 3, "events");	
		fds[i].events = duk_to_int(ctx, 5);
		duk_pop_n(ctx, 3);
	}

	rc = poll(fds, nfds, timeout);
	duk_push_object(ctx);
	duk_push_int(ctx, rc);
	duk_put_prop_string(ctx, -2, "rc");
	duk_dup(ctx, 0); // dup reference to arg0 array
	for(i=0;i<nfds;i++) {
		duk_get_prop_index(ctx, -1, i); // fetch object from array at i
		duk_push_int(ctx, fds[i].revents);
		duk_put_prop_string(ctx, -2, "revents"); // put revents into object
		duk_pop(ctx); // remove object from stack
	}
	duk_put_prop_string(ctx, -2, "fds");

	return 1;
}
Exemple #2
0
/* duk_get_prop_index(), success cases */
static duk_ret_t test_3a(duk_context *ctx) {
	duk_ret_t rc;

	prep(ctx);

	rc = duk_get_prop_index(ctx, 0, 31337);
	printf("obj[31337] -> rc=%d, result='%s'\n", (int) rc, duk_to_string(ctx, -1));
	duk_pop(ctx);

	rc = duk_get_prop_index(ctx, 0, 123);
	printf("obj[123] -> rc=%d, result='%s'\n", (int) rc, duk_to_string(ctx, -1));
	duk_pop(ctx);

	rc = duk_get_prop_index(ctx, 1, 31337);
	printf("arr[31337] -> rc=%d, result='%s'\n", (int) rc, duk_to_string(ctx, -1));
	duk_pop(ctx);

	rc = duk_get_prop_index(ctx, 1, 2);
	printf("arr[2] -> rc=%d, result='%s'\n", (int) rc, duk_to_string(ctx, -1));
	duk_pop(ctx);

	rc = duk_get_prop_index(ctx, 2, 5);
	printf("'test_string'[5] -> rc=%d, result='%s'\n", (int) rc, duk_to_string(ctx, -1));
	duk_pop(ctx);

	printf("final top: %ld\n", (long) duk_get_top(ctx));
	return 0;
}
Exemple #3
0
/*
 * High precission time. If an optional array is given
 * it returns the difference.
 */
static duk_ret_t time_hrtime(duk_context* ctx) {
    uint64_t t = sjs_time_hrtime();
    uint64_t sec;
    uint64_t nsec;
    if (duk_is_array(ctx, 0)) {
        uint64_t t0;
        uint64_t sec0;
        uint64_t nsec0;
        duk_get_prop_index(ctx, 0, 0);
        sec0 = duk_require_uint(ctx, -1);
        duk_pop(ctx);
        duk_get_prop_index(ctx, 0, 1);
        nsec0 = duk_require_uint(ctx, -1);
        duk_pop(ctx);
        t0 = sec0 * NANOS_PER_SEC + nsec0;
        t -= t0;
    }
    sec = t / NANOS_PER_SEC;
    nsec = t % NANOS_PER_SEC;
    duk_push_array(ctx);
    duk_push_uint(ctx, sec);
    duk_put_prop_index(ctx, -2, 0);
    duk_push_uint(ctx, nsec);
    duk_put_prop_index(ctx, -2, 1);
    return 1;
}
Exemple #4
0
static void remapCallback(void* data, s32 x, s32 y, RemapResult* result)
{

	RemapData* remap = (RemapData*)data;
	duk_context* duk = remap->duk;

	duk_push_heapptr(duk, remap->remap);
	duk_push_int(duk, result->index);
	duk_push_int(duk, x);
	duk_push_int(duk, y);
	duk_pcall(duk, 3);

	if(duk_is_array(duk, -1))
	{
		duk_get_prop_index(duk, -1, 0);
		result->index = duk_to_int(duk, -1);
		duk_pop(duk);

		duk_get_prop_index(duk, -1, 1);
		result->flip = duk_to_int(duk, -1);
		duk_pop(duk);

		duk_get_prop_index(duk, -1, 2);
		result->rotate = duk_to_int(duk, -1);
		duk_pop(duk);
	}
	else
	{
		result->index = duk_to_int(duk, -1);		
	}

	duk_pop(duk);
}
Exemple #5
0
DUK_LOCAL void duk__array_sort_swap(duk_context *ctx, duk_int_t l, duk_int_t r) {
	duk_bool_t have_l, have_r;
	duk_idx_t idx_obj = 1;  /* fixed offset in valstack */

	if (l == r) {
		return;
	}

	/* swap elements; deal with non-existent elements correctly */
	have_l = duk_get_prop_index(ctx, idx_obj, (duk_uarridx_t) l);
	have_r = duk_get_prop_index(ctx, idx_obj, (duk_uarridx_t) r);

	if (have_r) {
		/* right exists, [[Put]] regardless whether or not left exists */
		duk_put_prop_index(ctx, idx_obj, (duk_uarridx_t) l);
	} else {
		duk_del_prop_index(ctx, idx_obj, (duk_uarridx_t) l);
		duk_pop(ctx);
	}

	if (have_l) {
		duk_put_prop_index(ctx, idx_obj, (duk_uarridx_t) r);
	} else {
		duk_del_prop_index(ctx, idx_obj, (duk_uarridx_t) r);
		duk_pop(ctx);
	}
}
Exemple #6
0
static int sys1_execve(duk_context *ctx)
{
	const char *filename = duk_to_string(ctx, 0);
	int rc;
	char **argv;
	char **envp;
	int argc = 0, envc = 0, i;
	
	// count arguments
	// FIXME: Use duk_get_length() instead ?
	while(1) {
		rc = duk_get_prop_index(ctx, 1, argc);
		duk_pop(ctx);
		if(rc == 0) break;
		argc++;
	}

	argv = malloc(sizeof(char*)*(argc+1));
	
	for(i=0;i<argc;i++) {
		duk_get_prop_index(ctx, 1, i);
		argv[i] = (char*) duk_to_string(ctx, 3);
		duk_pop(ctx);
	}
	argv[i] = (void*)0;

	// count arguments
	// FIXME: Use duk_get_length() instead ?
	while(1) {
		rc = duk_get_prop_index(ctx, 2, envc);
		duk_pop(ctx);
		if(rc == 0) break;
		envc++;
	}

	envp = malloc(sizeof(char*)*(envc+1));
	
	for(i=0;i<envc;i++) {
		duk_get_prop_index(ctx, 2, i);
		envp[i] = (char*) duk_to_string(ctx, 3);
		duk_pop(ctx);
	}
	envp[i] = (void*)0;
	
	rc = execve(filename, argv, envp);
	
	duk_push_int(ctx, rc);
	return 1;
}
void test(duk_context *ctx) {
	duk_idx_t arr_idx;

	duk_push_int(ctx, 123);  /* dummy */

	arr_idx = duk_push_bare_array(ctx);
	printf("arr_idx = %ld\n", (long) arr_idx);
	duk_get_prototype(ctx, -1);
	printf("prototype is undefined: %ld\n", (long) duk_is_undefined(ctx, -1));
	duk_pop(ctx);

	duk_push_string(ctx, "foo");
	duk_put_prop_index(ctx, arr_idx, 0);
	duk_push_string(ctx, "bar");
	duk_put_prop_index(ctx, arr_idx, 1);

	/* Array is now: [ "foo", "bar" ], and array.length is 2 (automatically
	 * updated for ECMAScript arrays).  The array being bare does not affect
	 * JSON serialization.
	 */

	printf("duk_is_array(%ld) = %d\n", (long) arr_idx, (int) duk_is_array(ctx, arr_idx));

	duk_eval_string_noresult(ctx, "Array.prototype[5] = 'inherit';");
	(void) duk_get_prop_index(ctx, arr_idx, 5);
	printf("arr[5] = '%s'\n", duk_to_string(ctx, -1));
	duk_pop(ctx);

	duk_json_encode(ctx, arr_idx);  /* in-place */
	printf("json encoded: %s\n", duk_get_string(ctx, arr_idx));

	printf("top=%ld\n", (long) duk_get_top(ctx));
}
Exemple #8
0
static duk_ret_t
js_PointSeries(duk_context* ctx)
{
	duk_require_object_coercible(ctx, 0);
	color_t color = duk_require_sphere_color(ctx, 1);

	size_t          num_points;
	int             x, y;
	ALLEGRO_VERTEX* vertices;
	ALLEGRO_COLOR   vtx_color;

	size_t i;

	if (!duk_is_array(ctx, 0))
		duk_error_ni(ctx, -1, DUK_ERR_ERROR, "PointSeries(): First argument must be an array");
	duk_get_prop_string(ctx, 0, "length"); num_points = duk_get_uint(ctx, 0); duk_pop(ctx);
	if (num_points < 1)
		duk_error_ni(ctx, -1, DUK_ERR_RANGE_ERROR, "PointSeries(): One or more vertices required");
	if (num_points > INT_MAX)
		duk_error_ni(ctx, -1, DUK_ERR_RANGE_ERROR, "PointSeries(): Too many vertices");
	if ((vertices = calloc(num_points, sizeof(ALLEGRO_VERTEX))) == NULL)
		duk_error_ni(ctx, -1, DUK_ERR_ERROR, "PointSeries(): Failed to allocate vertex buffer");
	vtx_color = nativecolor(color);
	for (i = 0; i < num_points; ++i) {
		duk_get_prop_index(ctx, 0, (duk_uarridx_t)i);
		duk_get_prop_string(ctx, 0, "x"); x = duk_require_int(ctx, -1); duk_pop(ctx);
		duk_get_prop_string(ctx, 0, "y"); y = duk_require_int(ctx, -1); duk_pop(ctx);
		duk_pop(ctx);
		vertices[i].x = x + 0.5; vertices[i].y = y + 0.5;
		vertices[i].color = vtx_color;
	}
	al_draw_prim(vertices, NULL, NULL, 0, (int)num_points, ALLEGRO_PRIM_POINT_LIST);
	free(vertices);
	return 0;
}
Exemple #9
0
bool StyleContext::evalFilter(FunctionID _id) const {
    if (!duk_get_global_string(m_ctx, FUNC_ID)) {
        logMsg("Error: evalFilterFn - functions not initialized\n");
        return false;
    }

    if (!duk_get_prop_index(m_ctx, -1, _id)) {
        logMsg("Error: evalFilterFn - function %d not set\n", _id);
    }

    if (duk_pcall(m_ctx, 0) != 0) {
        logMsg("Error: evalFilterFn: %s\n", duk_safe_to_string(m_ctx, -1));
    }

    bool result = false;

    if (duk_is_boolean(m_ctx, -1)) {
        result = duk_get_boolean(m_ctx, -1);
    }

    // pop result
    duk_pop(m_ctx);
    // pop fns obj
    duk_pop(m_ctx);

    DUMP("evalFilterFn\n");
    return result;
}
bool StyleContext::evalFunction(FunctionID id) {
    // Get all functions (array) in context
    if (!duk_get_global_string(m_ctx, FUNC_ID)) {
        LOGE("EvalFilterFn - functions array not initialized");
        duk_pop(m_ctx); // pop [undefined] sitting at stack top
        return false;
    }

    // Get function at index `id` from functions array, put it at stack top
    if (!duk_get_prop_index(m_ctx, -1, id)) {
        LOGE("EvalFilterFn - function %d not set", id);
        duk_pop(m_ctx); // pop "undefined" sitting at stack top
        duk_pop(m_ctx); // pop functions (array) now sitting at stack top
        return false;
    }

    // pop fns array
    duk_remove(m_ctx, -2);

    // call popped function (sitting at stack top), evaluated value is put on stack top
    if (duk_pcall(m_ctx, 0) != 0) {
        LOGE("EvalFilterFn: %s", duk_safe_to_string(m_ctx, -1));
        duk_pop(m_ctx);
        return false;
    }

    return true;
}
duk_ret_t JavaScriptObject::finalizer(duk_context* ctx) {
    // Remove this pointers from the JS object's property.
    if (duk_get_prop_string(ctx, -1, WRAPPER_THIS_PROP_NAME)) {
        const duk_size_t length = duk_get_length(ctx, -1);
        for (duk_uarridx_t i = 0; i < length; ++i) {
            duk_get_prop_index(ctx, -1, i);

            JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(duk_get_pointer(ctx, -1));
            if (obj && obj->m_instance) {
                // Null out the instance pointer - it's been garbage collected!
                obj->m_instance = nullptr;

                if (obj->m_nextFinalizer) {
                    // Continue with the next finalizer in the chain.
                    obj->m_nextFinalizer(ctx);
                }
            }
            duk_pop(ctx);
        }
    }

    // Pop the array (or undefined if there was none).
    duk_pop(ctx);

    return 0;
}
Variant DuktapeScriptFunction::call(const std::vector<Variant> & args)
{
    // Get function wrapper from stash
    duk_push_global_stash(m_context);
    duk_get_prop_index(m_context, -1, m_stashIndex);

    // Push arguments
    for (Variant var : args)
    {
        m_scriptBackend->pushToDukStack(var);
    }

    // Call function
    duk_int_t error = duk_pcall(m_context, args.size());

    // Check for error
    if (error)
    {
        // Raise script exception
        m_scriptBackend->m_scriptContext->scriptException(std::string(duk_safe_to_string(m_context, -1)));
        duk_pop_2(m_context);
        return Variant();
    }

    // Convert return value
    Variant value = m_scriptBackend->fromDukStack(-1);
    duk_pop_2(m_context);
    return value;
}
void JSEventDispatcher::EndSendEvent(Context* context, Object* sender, StringHash eventType, VariantMap& eventData)
{
    if (!jsEvents_.Contains(eventType))
        return;

    JSVM* vm = JSVM::GetJSVM(NULL);

    if (!vm)
        return;

    duk_context* ctx = vm->GetJSContext();

    duk_push_global_stash(ctx);
    duk_get_prop_index(ctx, -1, JS_GLOBALSTASH_VARIANTMAP_CACHE);

    duk_push_pointer(ctx, (void*) &eventData);
    duk_get_prop(ctx, -2);


    // If this issue is addressed, revisit this to simply remove
    // the variantmap object from the cache, if the user explicitly
    // keeps the event object alive in a local closure, that is allowed
    // (though, will keep object properties from being GC'd)
    // https://github.com/svaarala/duktape/issues/229

    // Ok, this is unfortunate, in an event callback it is possible
    // to capture the Proxy object which represents the event VariantMap
    // in a function() {} closure, which will keep the event data alive
    // until the function happens to be gc'd (it is a member of the eventhandler)
    // which will leave things like scenes up if there was a P_SCENE event data
    // member, etc
    // So, we need to check if we have an object in the variant map cache
    // and thense call it's delete property method on the Proxy, which will clear
    // all the data (the proxy can still be alive as a captured local, though
    // the members won't be held
    // This all makes it that much more important that the pointer to eventData
    // is consistent across entire event, otherwise references may be held

    // see note above about: https://github.com/svaarala/duktape/issues/229

    if (duk_is_object(ctx, -1))
    {
        // deletes all properties, thus freeing references, even if
        // the variant map object is held onto by script (it will be invalid, post
        // event send)
        // see JSAPI.cpp variantmap_property_deleteproperty
        duk_del_prop_index(ctx, -1, 0);

        duk_push_pointer(ctx, (void*) &eventData);
        duk_push_undefined(ctx);

        // clear the variant map object from the cache
        duk_put_prop(ctx, -4);

    }

    duk_pop_3(ctx);

}
Exemple #14
0
DUK_INTERNAL duk_ret_t duk_bi_array_prototype_reverse(duk_context *ctx) {
	duk_uint32_t len;
	duk_uint32_t middle;
	duk_uint32_t lower, upper;
	duk_bool_t have_lower, have_upper;

	len = duk__push_this_obj_len_u32(ctx);
	middle = len / 2;

	/* If len <= 1, middle will be 0 and for-loop bails out
	 * immediately (0 < 0 -> false).
	 */

	for (lower = 0; lower < middle; lower++) {
		DUK_ASSERT(len >= 2);
		DUK_ASSERT_TOP(ctx, 2);

		DUK_ASSERT(len >= lower + 1);
		upper = len - lower - 1;

		have_lower = duk_get_prop_index(ctx, -2, (duk_uarridx_t) lower);
		have_upper = duk_get_prop_index(ctx, -3, (duk_uarridx_t) upper);

		/* [ ToObject(this) ToUint32(length) lowerValue upperValue ] */

		if (have_upper) {
			duk_put_prop_index(ctx, -4, (duk_uarridx_t) lower);
		} else {
			duk_del_prop_index(ctx, -4, (duk_uarridx_t) lower);
			duk_pop(ctx);
		}

		if (have_lower) {
			duk_put_prop_index(ctx, -3, (duk_uarridx_t) upper);
		} else {
			duk_del_prop_index(ctx, -3, (duk_uarridx_t) upper);
			duk_pop(ctx);
		}

		DUK_ASSERT_TOP(ctx, 2);
	}

	DUK_ASSERT_TOP(ctx, 2);
	duk_pop(ctx);  /* -> [ ToObject(this) ] */
	return 1;
}
Exemple #15
0
DUK_INTERNAL duk_ret_t duk_bi_array_prototype_unshift(duk_context *ctx) {
	duk_idx_t nargs;
	duk_uint32_t len;
	duk_uint32_t i;

	nargs = duk_get_top(ctx);
	len = duk__push_this_obj_len_u32(ctx);

	/* stack[0...nargs-1] = unshift args (vararg)
	 * stack[nargs] = ToObject(this)
	 * stack[nargs+1] = ToUint32(length)
	 */

	DUK_ASSERT_TOP(ctx, nargs + 2);

	/* Note: unshift() may operate on indices above unsigned 32-bit range
	 * and the final length may be >= 2**32.  However, we restrict the
	 * final result to 32-bit range for practicality.
	 */

	if (len + (duk_uint32_t) nargs < len) {
		DUK_D(DUK_DPRINT("Array.prototype.unshift() would go beyond 32-bit length, throw"));
		return DUK_RET_RANGE_ERROR;
	}

	i = len;
	while (i > 0) {
		DUK_ASSERT_TOP(ctx, nargs + 2);
		i--;
		/* k+argCount-1; note that may be above 32-bit range */

		if (duk_get_prop_index(ctx, -2, (duk_uarridx_t) i)) {
			/* fromPresent = true */
			/* [ ... ToObject(this) ToUint32(length) val ] */
			duk_put_prop_index(ctx, -3, (duk_uarridx_t) (i + nargs));  /* -> [ ... ToObject(this) ToUint32(length) ] */
		} else {
			/* fromPresent = false */
			/* [ ... ToObject(this) ToUint32(length) val ] */
			duk_pop(ctx);
			duk_del_prop_index(ctx, -2, (duk_uarridx_t) (i + nargs));  /* -> [ ... ToObject(this) ToUint32(length) ] */
		}
		DUK_ASSERT_TOP(ctx, nargs + 2);
	}

	for (i = 0; i < (duk_uint32_t) nargs; i++) {
		DUK_ASSERT_TOP(ctx, nargs + 2);
		duk_dup(ctx, i);  /* -> [ ... ToObject(this) ToUint32(length) arg[i] ] */
		duk_put_prop_index(ctx, -3, (duk_uarridx_t) i);
		DUK_ASSERT_TOP(ctx, nargs + 2);
	}

	DUK_ASSERT_TOP(ctx, nargs + 2);
	duk_push_u32(ctx, len + nargs);
	duk_dup_top(ctx);  /* -> [ ... ToObject(this) ToUint32(length) final_len final_len ] */
	duk_put_prop_stridx(ctx, -4, DUK_STRIDX_LENGTH);
	return 1;
}
Exemple #16
0
DUK_INTERNAL duk_ret_t duk_bi_array_prototype_slice(duk_context *ctx) {
	duk_uint32_t len;
	duk_int_t start, end;
	duk_int_t i;
	duk_uarridx_t idx;
	duk_uint32_t res_length = 0;

	/* XXX: len >= 0x80000000 won't work below because we need to be
	 * able to represent -len.
	 */
	len = duk__push_this_obj_len_u32_limited(ctx);
	duk_push_array(ctx);

	/* stack[0] = start
	 * stack[1] = end
	 * stack[2] = ToObject(this)
	 * stack[3] = ToUint32(length)
	 * stack[4] = result array
	 */

	start = duk_to_int_clamped(ctx, 0, -((duk_int_t) len), (duk_int_t) len);
	if (start < 0) {
		start = len + start;
	}
	/* XXX: could duk_is_undefined() provide defaulting undefined to 'len'
	 * (the upper limit)?
	 */
	if (duk_is_undefined(ctx, 1)) {
		end = len;
	} else {
		end = duk_to_int_clamped(ctx, 1, -((duk_int_t) len), (duk_int_t) len);
		if (end < 0) {
			end = len + end;
		}
	}
	DUK_ASSERT(start >= 0 && (duk_uint32_t) start <= len);
	DUK_ASSERT(end >= 0 && (duk_uint32_t) end <= len);

	idx = 0;
	for (i = start; i < end; i++) {
		DUK_ASSERT_TOP(ctx, 5);
		if (duk_get_prop_index(ctx, 2, (duk_uarridx_t) i)) {
			duk_xdef_prop_index_wec(ctx, 4, idx);
			res_length = idx + 1;
		} else {
			duk_pop(ctx);
		}
		idx++;
		DUK_ASSERT_TOP(ctx, 5);
	}

	duk_push_u32(ctx, res_length);
	duk_xdef_prop_stridx(ctx, 4, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);

	DUK_ASSERT_TOP(ctx, 5);
	return 1;
}
DUK_INTERNAL duk_ret_t duk_bi_function_prototype_apply(duk_context *ctx) {
	duk_idx_t len;
	duk_idx_t i;

	DUK_ASSERT_TOP(ctx, 2);  /* not a vararg function */

	duk_push_this(ctx);
	if (!duk_is_callable(ctx, -1)) {
		DUK_DDD(DUK_DDDPRINT("func is not callable"));
		goto type_error;
	}
	duk_insert(ctx, 0);
	DUK_ASSERT_TOP(ctx, 3);

	DUK_DDD(DUK_DDDPRINT("func=%!iT, thisArg=%!iT, argArray=%!iT",
	                     (duk_tval *) duk_get_tval(ctx, 0),
	                     (duk_tval *) duk_get_tval(ctx, 1),
	                     (duk_tval *) duk_get_tval(ctx, 2)));

	/* [ func thisArg argArray ] */

	if (duk_is_null_or_undefined(ctx, 2)) {
		DUK_DDD(DUK_DDDPRINT("argArray is null/undefined, no args"));
		len = 0;
	} else if (!duk_is_object(ctx, 2)) {
		goto type_error;
	} else {
		DUK_DDD(DUK_DDDPRINT("argArray is an object"));

		/* XXX: make this an internal helper */
		duk_get_prop_stridx(ctx, 2, DUK_STRIDX_LENGTH);
		len = (duk_idx_t) duk_to_uint32(ctx, -1);  /* ToUint32() coercion required */
		duk_pop(ctx);

		duk_require_stack(ctx, len);

		DUK_DDD(DUK_DDDPRINT("argArray length is %ld", (long) len));
		for (i = 0; i < len; i++) {
			duk_get_prop_index(ctx, 2, i);
		}
	}
	duk_remove(ctx, 2);
	DUK_ASSERT_TOP(ctx, 2 + len);

	/* [ func thisArg arg1 ... argN ] */

	DUK_DDD(DUK_DDDPRINT("apply, func=%!iT, thisArg=%!iT, len=%ld",
	                     (duk_tval *) duk_get_tval(ctx, 0),
	                     (duk_tval *) duk_get_tval(ctx, 1),
	                     (long) len));
	duk_call_method(ctx, len);
	return 1;

 type_error:
	return DUK_RET_TYPE_ERROR;
}
void PushWeakObject(duk_context* ctx, Object* object)
{
    if (!object)
    {
        duk_push_null(ctx);
        return;
    }

    duk_push_heap_stash(ctx);

    // Check if the wrapper for the object already exists in stash
    // This is required so that comparisons of object references (e.g. against the me property) work properly
    if (duk_has_prop_index(ctx, -1, (size_t)object))
    {
        duk_get_prop_index(ctx, -1, (size_t)object);
        WeakPtr<Object>* oldPtr = GetWeakPtr(ctx, -1);
        if (oldPtr && oldPtr->Get() == object)
        {
            duk_remove(ctx, -2); // Remove stash
            return;
        }
        else
            duk_pop(ctx); // Valid existing wrapper not found
    }

    duk_push_object(ctx);
    WeakPtr<Object>* ptr = new WeakPtr<Object>(object);
    duk_push_pointer(ctx, ptr);
    duk_put_prop_string(ctx, -2, "\xff""weak");
    duk_push_c_function(ctx, WeakPtr_Finalizer, 1);
    duk_set_finalizer(ctx, -2);

    // Set prototype. If not found, use base class prototype (e.g. IComponent)
    duk_get_global_string(ctx, object->GetTypeName().CString());
    if (!duk_is_object(ctx, -1))
    {
        duk_pop(ctx);
        duk_get_global_string(ctx, object->GetTypeInfo()->GetBaseTypeInfo()->GetTypeName().CString());
    }
    duk_get_prop_string(ctx, -1, "prototype");
    duk_set_prototype(ctx, -3);
    duk_pop(ctx);

    // Proxied property access handling for scene, entity & component
    if (object->GetType() == Scene::GetTypeStatic())
        SetupProxy(ctx, SceneProxyFunctions);
    if (object->GetType() == Entity::GetTypeStatic())
        SetupProxy(ctx, EntityProxyFunctions);
    else if (dynamic_cast<IComponent*>(object))
        SetupProxy(ctx, ComponentProxyFunctions);

    // Store to stash
    duk_dup(ctx, -1);
    duk_put_prop_index(ctx, -3, (size_t)object);
    duk_remove(ctx, -2); // Remove stash
}
Exemple #19
0
int duk_bi_array_prototype_slice(duk_context *ctx) {
	unsigned int len;
	int start, end;
	int idx;
	int i;
	duk_uint32_t res_length = 0;

	len = duk__push_this_obj_len_u32(ctx);
	duk_push_array(ctx);

	/* stack[0] = start
	 * stack[1] = end
	 * stack[2] = ToObject(this)
	 * stack[3] = ToUint32(length)
	 * stack[4] = result array
	 */

	start = duk_to_int_clamped(ctx, 0, -len, len);  /* FIXME: does not support full 32-bit range */
	if (start < 0) {
		start = len + start;
	}
	/* FIXME: could duk_is_undefined() provide defaulting undefined to 'len'
	 * (the upper limit)?
	 */
	if (duk_is_undefined(ctx, 1)) {
		end = len;
	} else {
		end = duk_to_int_clamped(ctx, 1, -len, len);
		if (end < 0) {
			end = len + end;
		}
	}
	DUK_ASSERT(start >= 0 && (duk_uint32_t) start <= len);
	DUK_ASSERT(end >= 0 && (duk_uint32_t) end <= len);

	idx = 0;
	for (i = start; i < end; i++) {
		DUK_ASSERT_TOP(ctx, 5);
		if (duk_get_prop_index(ctx, 2, i)) {
			duk_def_prop_index(ctx, 4, idx, DUK_PROPDESC_FLAGS_WEC);
			res_length = idx + 1;
		} else {
			duk_pop(ctx);
		}
		idx++;
		DUK_ASSERT_TOP(ctx, 5);
	}

	duk_push_int(ctx, res_length);  /* FIXME */
	duk_def_prop_stridx(ctx, 4, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);

	DUK_ASSERT_TOP(ctx, 5);
	return 1;
}
Exemple #20
0
int duk_bi_array_prototype_unshift(duk_context *ctx) {
	unsigned int nargs;
	unsigned int len;
	unsigned int i;
	double final_len;

	/* FIXME: duk_get_top return type */
	nargs = (unsigned int) duk_get_top(ctx);
	len = duk__push_this_obj_len_u32(ctx);

	/* stack[0...nargs-1] = unshift args (vararg)
	 * stack[nargs] = ToObject(this)
	 * stack[nargs+1] = ToUint32(length)
	 */

	DUK_ASSERT_TOP(ctx, nargs + 2);

	/* Note: unshift() may operate on indices above unsigned 32-bit range
	 * and the final length may be >= 2**32.  Hence we use 'double' vars
	 * here, when appropriate.
	 */

	i = len;
	while (i > 0) {
		DUK_ASSERT_TOP(ctx, nargs + 2);
		i--;
		duk_push_number(ctx, ((double) i) + ((double) nargs));  /* k+argCount-1; note that may be above 32-bit range */
		if (duk_get_prop_index(ctx, -3, i)) {
			/* fromPresent = true */
			/* [ ... ToObject(this) ToUint32(length) to val ] */
			duk_put_prop(ctx, -4);  /* -> [ ... ToObject(this) ToUint32(length) ] */  /* FIXME: Throw */
		} else {
			/* fromPresent = false */
			/* [ ... ToObject(this) ToUint32(length) to val ] */
			duk_pop(ctx);
			duk_del_prop(ctx, -3);  /* -> [ ... ToObject(this) ToUint32(length) ] */  /* FIXME: Throw */
		}
		DUK_ASSERT_TOP(ctx, nargs + 2);
	}

	for (i = 0; i < nargs; i++) {
		DUK_ASSERT_TOP(ctx, nargs + 2);
		duk_dup(ctx, i);  /* -> [ ... ToObject(this) ToUint32(length) arg[i] ] */
		duk_put_prop_index(ctx, -3, i);  /* FIXME: Throw */
		DUK_ASSERT_TOP(ctx, nargs + 2);
	}

	DUK_ASSERT_TOP(ctx, nargs + 2);
	final_len = ((double) len) + ((double) nargs);
	duk_push_number(ctx, final_len);
	duk_dup_top(ctx);  /* -> [ ... ToObject(this) ToUint32(length) final_len final_len ] */
	duk_put_prop_stridx(ctx, -4, DUK_STRIDX_LENGTH);  /* FIXME: Throw */
	return 1;
}
Exemple #21
0
/* duk_get_prop_index(), invalid index */
int test_3b(duk_context *ctx) {
	int rc;

	prep(ctx);

	rc = duk_get_prop_index(ctx, 234, 123);
	printf("obj[123] -> rc=%d, result='%s'\n", rc, duk_to_string(ctx, -1));
	duk_pop(ctx);

	printf("final top: %d\n", duk_get_top(ctx));
	return 0;
}
Exemple #22
0
/* duk_get_prop_index(), DUK_INVALID_INDEX */
static duk_ret_t test_3c(duk_context *ctx) {
	duk_ret_t rc;

	prep(ctx);

	rc = duk_get_prop_index(ctx, DUK_INVALID_INDEX, 123);
	printf("obj[123] -> rc=%d, result='%s'\n", (int) rc, duk_to_string(ctx, -1));
	duk_pop(ctx);

	printf("final top: %ld\n", (long) duk_get_top(ctx));
	return 0;
}
/*
 * Looks for an interface that defines a specific member.
 *
 * TODO - check for ambiguity - same member defined on multiple interfaces
 */
static const char* FindInterfaceForMember(duk_context* ctx, duk_idx_t mbrIdx, const char** member)
{
    const char* iface = NULL;
    uint8_t found = FALSE;
    size_t numInterfaces;
    duk_idx_t listIdx;

    duk_get_prop_string(ctx, -1, "interfaces");
    numInterfaces = duk_get_length(ctx, -1);
    listIdx = AJS_GetAllJoynProperty(ctx, "interfaceDefinition");

    if (duk_is_object(ctx, mbrIdx)) {
        /*
         * Expect an object of form { member:"org.foo.interface" }
         */
        duk_enum(ctx, mbrIdx, DUK_ENUM_OWN_PROPERTIES_ONLY);
        if (!duk_next(ctx, -1, 1)) {
            duk_error(ctx, DUK_ERR_TYPE_ERROR, "Require object of form { 'member-name':'interface-name' }");
        }
        iface = duk_require_string(ctx, -1);
        if (!AJ_StringFindFirstOf(iface, ".") == -1) {
            duk_error(ctx, DUK_ERR_TYPE_ERROR, "Interface name '%s' is not a dotted name", iface);
        }
        *member = duk_require_string(ctx, -2);
        duk_get_prop_string(ctx, listIdx, iface);
        if (duk_is_undefined(ctx, -1)) {
            duk_error(ctx, DUK_ERR_REFERENCE_ERROR, "Unknown interface: '%s'", iface);
        }
        found = duk_has_prop_string(ctx, -1, *member);
        duk_pop_n(ctx, 4);
    } else {
        size_t i;
        /*
         * Expect a string
         */
        *member = duk_require_string(ctx, mbrIdx);
        for (i = 0; !found && (i < numInterfaces); ++i) {
            duk_get_prop_index(ctx, -2, i);
            iface = duk_require_string(ctx, -1);
            duk_get_prop_string(ctx, listIdx, iface);
            /*
             * See if the requested member exists on this interface
             */
            found = duk_has_prop_string(ctx, -1, *member);
            duk_pop_2(ctx);
        }
    }
    duk_pop_2(ctx);
    if (!found) {
        duk_error(ctx, DUK_ERR_REFERENCE_ERROR, "Unknown member: '%s'", *member);
    }
    return iface;
}
Exemple #24
0
int duk_bi_array_prototype_reverse(duk_context *ctx) {
	unsigned int len;
	unsigned int middle;
	unsigned int lower, upper;
	int have_lower, have_upper;

	len = duk__push_this_obj_len_u32(ctx);
	middle = len / 2;

	for (lower = 0; lower < middle; lower++) {
		DUK_ASSERT_TOP(ctx, 2);

		upper = len - lower - 1;

		have_lower = duk_get_prop_index(ctx, -2, lower);
		have_upper = duk_get_prop_index(ctx, -3, upper);

		/* [ ToObject(this) ToUint32(length) lowerValue upperValue ] */

		if (have_upper) {
			duk_put_prop_index(ctx, -4, lower);  /* FIXME: Throw */
		} else {
			duk_del_prop_index(ctx, -4, lower);
			duk_pop(ctx);
		}

		if (have_lower) {
			duk_put_prop_index(ctx, -3, upper);
		} else {
			duk_del_prop_index(ctx, -3, upper);
			duk_pop(ctx);
		}

		DUK_ASSERT_TOP(ctx, 2);
	}

	DUK_ASSERT_TOP(ctx, 2);
	duk_pop(ctx);  /* -> [ ToObject(this) ] */
	return 1;
}
Exemple #25
0
void GCObjectPool::addNewList() {
    Isolate *isolate = Isolate::GetCurrent();
    duk_context *ctx = isolate->GetDukContext();

    // Get the "refs" array in the heap stash
    duk_push_global_stash(ctx);
    duk_get_prop_string(ctx, -1, "__object_list");
    duk_remove(ctx, -2);

    int type = duk_get_type(ctx, -1);

    int freeSlot;

    // freeSlot = scopeList[0]
    duk_get_prop_index(ctx, -1, 0);                                // <scopeList> <scopeList[0]>
    freeSlot = duk_get_int(ctx, -1);
    duk_pop(ctx);                                                  // <scopeList>

    if (freeSlot != 0) {
        // scopeList[0] = scopeList[freeSlot]
        duk_get_prop_index(ctx, -1, (duk_uarridx_t) freeSlot);    // <scopeList> <scopeList[freeSlot]>
        duk_put_prop_index(ctx, -2, 0);                            // <scopeList>
    } else {
        // freeSlot = scopeList.length;
        freeSlot = (int) duk_get_length(ctx, -1);
    }

    duk_push_array(ctx);
    list_ptr_ = duk_get_heapptr(ctx, -1);                         // <scopeList> <scope>

    // scopeList[freeSlot] = scope
    duk_put_prop_index(ctx, -2, (duk_uarridx_t) freeSlot);        // <scopeList>

    // Remove the refs array from the stack.
    duk_pop(ctx);                                                  //

    list_idx_ = freeSlot;
}
Exemple #26
0
/*
 * like luaL_ref, but assumes storage in "refs" property of heap stash
 */
int
mn_ref(duk_context *ctx) {
	int ref;
	if (duk_is_undefined(ctx, -1)) {
		duk_pop(ctx);
		return 0;
	}
	/* Get the "refs" array in the heap stash */
	duk_push_heap_stash(ctx);
	duk_get_prop_string(ctx, -1, "refs");
	duk_remove(ctx, -2);

	/* ref = refs[0] */
	duk_get_prop_index(ctx, -1, 0);
	ref = duk_get_int(ctx, -1);
	duk_pop(ctx);

	/* If there was a free slot, remove it from the list */
	if (ref != 0) {
		/* refs[0] = refs[ref] */
		duk_get_prop_index(ctx, -1, ref);
		duk_put_prop_index(ctx, -2, 0);
	} else {
		/* Otherwise use the end of the list */
		ref = duk_get_length(ctx, -1);
	}

	/* Swap the array and the user value in the stack */
	duk_insert(ctx, -2);

	/* refs[ref] = value */
	duk_put_prop_index(ctx, -2, ref);

	/* Remove the refs array from the stack. */
	duk_pop(ctx);

	return ref;
}
gboolean
_gum_duk_parse_bytes (duk_context * ctx,
                      duk_idx_t index,
                      GBytes ** bytes)
{
  gpointer data;
  duk_size_t size;

  data = duk_get_buffer_data (ctx, index, &size);
  if (data != NULL)
  {
    *bytes = g_bytes_new (data, size);
    return TRUE;
  }
  else if (duk_is_array (ctx, index))
  {
    duk_size_t i;

    duk_get_prop_string (ctx, index, "length");
    size = duk_get_uint (ctx, -1);
    duk_pop (ctx);

    if (size >= GUM_MAX_JS_BYTE_ARRAY_LENGTH)
      return FALSE;

    data = g_malloc (size);

    for (i = 0; i != size; i++)
    {
      duk_get_prop_index (ctx, index, (duk_uarridx_t) i);
      ((guint8 *) data)[i] = duk_get_uint (ctx, -1) & 0xff;
      duk_pop (ctx);
    }

    *bytes = g_bytes_new_take (data, size);
    return TRUE;
  }
  else if (duk_is_null_or_undefined (ctx, index) ||
      duk_is_boolean (ctx, index) ||
      duk_is_number (ctx, index) ||
      duk_is_nan (ctx, index) ||
      duk_is_string (ctx, index) ||
      duk_is_function (ctx, index))
  {
    return FALSE;
  }

  *bytes = g_bytes_new (NULL, 0);
  return TRUE;
}
Exemple #28
0
/* duk_get_prop_index(), invalid index */
static duk_ret_t test_getpropindex_b(duk_context *ctx, void *udata) {
	duk_ret_t rc;

	(void) udata;

	prep(ctx);

	rc = duk_get_prop_index(ctx, 234, 123);
	printf("obj[123] -> rc=%d, result='%s'\n", (int) rc, duk_to_string(ctx, -1));
	duk_pop(ctx);

	printf("final top: %ld\n", (long) duk_get_top(ctx));
	return 0;
}
Exemple #29
0
int GlobalStash::AddObject(void *ptr) {
    Isolate *isolate = Isolate::GetCurrent();
    duk_context *ctx = isolate->GetDukContext();

    // Get the "refs" array in the heap stash
    duk_push_global_stash(ctx);
    duk_get_prop_string(ctx, -1, name_);
    duk_remove(ctx, -2);

    int type = duk_get_type(ctx, -1);

    int freeSlot;

    // freeSlot = scopeList[0]
    duk_get_prop_index(ctx, -1, 0);                                // <scopeList> <scopeList[0]>
    freeSlot = duk_get_int(ctx, -1);
    duk_pop(ctx);                                                  // <scopeList>

    if (freeSlot != 0) {
        // scopeList[0] = scopeList[freeSlot]
        duk_get_prop_index(ctx, -1, (duk_uarridx_t) freeSlot);    // <scopeList> <scopeList[freeSlot]>
        duk_put_prop_index(ctx, -2, 0);                            // <scopeList>
    } else {
        // freeSlot = scopeList.length;
        freeSlot = (int) duk_get_length(ctx, -1);
    }

    duk_push_heapptr(ctx, ptr);                                   // <scopeList> <scope>

    // scopeList[freeSlot] = scope
    duk_put_prop_index(ctx, -2, (duk_uarridx_t) freeSlot);        // <scopeList>

    // Remove the refs array from the stack.
    duk_pop(ctx);                                                  //

    return freeSlot;
}
Exemple #30
0
DUK_INTERNAL duk_ret_t duk_bi_array_prototype_shift(duk_context *ctx) {
	duk_uint32_t len;
	duk_uint32_t i;

	len = duk__push_this_obj_len_u32(ctx);
	if (len == 0) {
		duk_push_int(ctx, 0);
		duk_put_prop_stridx(ctx, 0, DUK_STRIDX_LENGTH);
		return 0;
	}

	duk_get_prop_index(ctx, 0, 0);

	/* stack[0] = object (this)
	 * stack[1] = ToUint32(length)
	 * stack[2] = elem at index 0 (retval)
	 */

	for (i = 1; i < len; i++) {
		DUK_ASSERT_TOP(ctx, 3);
		if (duk_get_prop_index(ctx, 0, (duk_uarridx_t) i)) {
			/* fromPresent = true */
			duk_put_prop_index(ctx, 0, (duk_uarridx_t) (i - 1));
		} else {
			/* fromPresent = false */
			duk_del_prop_index(ctx, 0, (duk_uarridx_t) (i - 1));
			duk_pop(ctx);
		}
	}
	duk_del_prop_index(ctx, 0, (duk_uarridx_t) (len - 1));

	duk_push_u32(ctx, (duk_uint32_t) (len - 1));
	duk_put_prop_stridx(ctx, 0, DUK_STRIDX_LENGTH);

	DUK_ASSERT_TOP(ctx, 3);
	return 1;
}