Пример #1
0
static duk_ret_t dukky_application_cache_onobsolete_setter(duk_context *ctx)
{
	/* Get private data for method */
	application_cache_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

	return 0;
}
Пример #2
0
void test(duk_context *ctx) {
        int rc;

        duk_eval_string(ctx, "this.testFunc = eval.bind(this, 'print(\\'hello from eval\\')');");
	duk_pop(ctx);

	duk_push_global_object(ctx);
	duk_get_prop_string(ctx, -1, "testFunc");
	rc = duk_pcall(ctx, 0);
	printf("rc=%d\n", rc);
	duk_pop_2(ctx);

        printf("final top: %d\n", duk_get_top(ctx));
}
Пример #3
0
static duk_ret_t dukky_audio_track_kind_getter(duk_context *ctx)
{
	/* Get private data for method */
	audio_track_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

	return 0;
}
Пример #4
0
static duk_ret_t dukky_validity_state_typeMismatch_getter(duk_context *ctx)
{
	/* Get private data for method */
	validity_state_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

	return 0;
}
Пример #5
0
static duk_ret_t dukky_drag_event_dataTransfer_getter(duk_context *ctx)
{
	/* Get private data for method */
	drag_event_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

	return 0;
}
Пример #6
0
static duk_ret_t dukky_html_anchor_element_protocol_getter(duk_context *ctx)
{
	/* Get private data for method */
	html_anchor_element_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

	return 0;
}
Пример #7
0
static duk_ret_t dukky_mutation_record_oldValue_getter(duk_context *ctx)
{
	/* Get private data for method */
	mutation_record_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

	return 0;
}
Пример #8
0
static duk_ret_t dukky_document_fragment_childElementCount_getter(duk_context *ctx)
{
	/* Get private data for method */
	document_fragment_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

	return 0;
}
Пример #9
0
void test(duk_context *ctx) {
	duk_ret_t rc;

	duk_set_top(ctx, 0);

	duk_push_string(ctx, "foo");  /* dummy */

	/* success case */
	duk_push_int(ctx, 10);
	duk_push_int(ctx, 11);
	duk_push_int(ctx, 12);
	rc = duk_safe_call(ctx, test_1, 3 /*nargs*/, 2 /*nrets*/);
	if (rc == DUK_EXEC_SUCCESS) {
		printf("1st return value: %s\n", duk_to_string(ctx, -2));  /* 21 */
		printf("2nd return value: %s\n", duk_to_string(ctx, -1));  /* undefined */
	} else {
		printf("error: %s\n", duk_to_string(ctx, -2));
	}
	duk_pop_2(ctx);

	/* error case */
	duk_push_int(ctx, 10);
	duk_push_int(ctx, 11);
	duk_push_int(ctx, 12);
	rc = duk_safe_call(ctx, test_2, 3 /*nargs*/, 2 /*nrets*/);
	if (rc == DUK_EXEC_SUCCESS) {
		printf("1st return value: %s\n", duk_to_string(ctx, -2));  /* 21 */
		printf("2nd return value: %s\n", duk_to_string(ctx, -1));  /* undefined */
	} else {
		printf("error: %s\n", duk_to_string(ctx, -2));
	}
	duk_pop_2(ctx);

	/* XXX: also test invalid input stack shapes (like not enough args) */

	printf("final top: %ld\n", (long) duk_get_top(ctx));
}
Пример #10
0
static int NativeSignal(duk_context* ctx)
{
    const char* dest;
    uint32_t session;

    duk_push_this(ctx);
    duk_get_prop_string(ctx, -1, "dest");
    dest = duk_get_string(ctx, -1);
    duk_pop(ctx);
    duk_get_prop_string(ctx, -1, "session");
    session = duk_get_int(ctx, -1);
    duk_pop_2(ctx);
    InitSignal(ctx, dest, session);
    return 1;
}
Пример #11
0
    duk_ret_t js_register_LocalStorage(duk_context *ctx)
    {
        duk_push_global_object(ctx); /* global */
        duk_get_prop_string(ctx, -1, MURAL_JS_NAMESPACE); /* global, __MURAL__ */
        
        duk_push_c_function(ctx, w_LocalStorage_constructor, 0); /* global, __MURAL__, constructor */
        duk_push_object(ctx); /* global, __MURAL__, constructor, prototype */
        duk_put_function_list(ctx, -1, methods_of_LocalStorage);
        duk_put_prop_string(ctx, -2, "prototype"); /* global, __MURAL__, constructor */
        
        duk_put_prop_string(ctx, -2, "LocalStorage"); /* global, __MURAL__ */
        duk_pop_2(ctx);

        return 0;
    }
Пример #12
0
    int w_LocalStorage_prototype_removeItem(duk_context *ctx)
    {
        const char *key = duk_require_string(ctx, 0);

        duk_push_this(ctx); /* this */
        duk_get_prop_string(ctx, -1, "__MURAL_DATA__"); /* this, __MURAL_DATA__ */
        duk_del_prop_string(ctx, -1, key); /* this, __MURAL_DATA__ */

        LocalStorage *inst = getNativePointer<LocalStorage>(ctx);
        duk_json_encode(ctx, -1); /* this, JSON(__MURAL_DATA__) */
        inst->setData(duk_to_string(ctx, -1)); /* this, string(JSON(__MURAL_DATA__)) */

        duk_pop_2(ctx);

        return 0;
    }
Пример #13
0
guint64
_gum_duk_require_uint64 (duk_context * ctx,
                         duk_idx_t index,
                         GumDukCore * core)
{
  GumDukUInt64 * object;

  duk_dup (ctx, index);
  duk_push_heapptr (ctx, core->uint64);
  if (!duk_instanceof (ctx, -2, -1))
    _gum_duk_throw (ctx, "expected UInt64");
  duk_pop_2 (ctx);

  object = _gum_duk_require_data (ctx, index);

  return object->value;
}
Пример #14
0
// Duktape.modSearch function, needed for loading modules with require()
duk_ret_t module_search(duk_context *ctx) {
    const char *id = duk_require_string(ctx, 0);

    // C modules: add functions to exports variable (3rd argument) and return undefined
    for (int i = 0; i < c_module_count; i++) {
	if (!strcmp(c_module_list[i].name, id)) {
	    duk_push_c_function(ctx, c_module_list[i].init_func, 0);
	    duk_call(ctx, 0);
	    duk_enum(ctx, -1, 0);
	    while(duk_next(ctx, -1, 1)) {
		duk_put_prop(ctx, 2);
	    }
	    duk_pop_2(ctx);
	    return 0;
	}
    }

    // JS modules: return source code as a string
    // Read from file "modname.js.tns"
    int module_filename_len = strlen(id) + strlen(".js.tns") + 1;
    char *module_filename = malloc(module_filename_len);
    if (!module_filename) goto error;
    snprintf(module_filename, module_filename_len, "%s.js.tns", id);
    FILE *module_file = fopen(module_filename, "r");
    free(module_filename);
    if (!module_file) goto error;
    if (fseek(module_file, 0, SEEK_END) != 0) goto error;
    long module_file_size = ftell(module_file);
    if (module_file_size == -1) goto error;
    rewind(module_file);
    char *src = malloc(module_file_size);
    if (!src) goto error;
    fread(src, 1, module_file_size, module_file);
    if (ferror(module_file)) goto error;
    fclose(module_file);

    duk_push_lstring(ctx, src, module_file_size);
    free(src);

    return 1;
    
error:
    duk_push_error_object(ctx, DUK_ERR_ERROR, "module %s not found: %s", id, strerror(errno));
    duk_throw(ctx);
}
Пример #15
0
/*----------------------------------------------------------------------------*/
static duk_ret_t
kbjs_PinId_str(duk_context *context)
{
    /* STACK: [this] */
    duk_push_this(context);

    /* STACK: [this, void*] */
    duk_get_prop_string(context, (duk_idx_t)-1, KBJS_INSTANCE_PTR);
    kbjs_PinId *pin_id = duk_get_pointer(context, (duk_idx_t)-1);
    /* STACK: [] */
    duk_pop_2(context);

    /* STACK: ["PIN*"] */
    duk_push_string(context, pin_id->str);

    /* Return string */
    return (duk_ret_t)1;
}
Пример #16
0
void test(duk_context *ctx) {
	duk_ret_t rc;

        duk_eval_string(ctx, "this.testFunc = eval.bind(this, 'print(\\'hello from eval\\')');");
	duk_pop(ctx);

	duk_push_global_object(ctx);
	duk_get_prop_string(ctx, -1, "testFunc");
	rc = duk_pcall(ctx, 0);
	printf("rc=%d\n", (int) rc);
	if (rc != 0) {
		/* unexpected error */
		printf("error=%s\n", duk_safe_to_string(ctx, -1));
	}
	duk_pop_2(ctx);

        printf("final top: %ld\n", (long) duk_get_top(ctx));
}
Пример #17
0
static duk_ret_t test_2(duk_context *ctx) {
	const char *str;

	printf("context is strict: %d\n", duk_is_strict_call(ctx));

	duk_push_c_function(ctx, test_2_inner, 0);
	duk_call(ctx, 0);
	duk_pop(ctx);

	duk_push_global_object(ctx);
	duk_get_prop_string(ctx, -1, "foo2");
	str = duk_get_string(ctx, -1);
	printf("global.foo2=%s\n", str ? str : "NULL");
	duk_pop_2(ctx);

	printf("final top: %ld\n", (long) duk_get_top(ctx));
	return 0;
}
Пример #18
0
static duk_ret_t test_1(duk_context *ctx) {
	const char *str;

	/* Eval happens outside of a Duktape/C activation.  The eval code was
	 * executed in non-strict mode also in Duktape 0.11.0 and prior.
	 */

	printf("context is strict: %d\n", duk_is_strict_call(ctx));
	duk_eval_string_noresult(ctx, "print('test_1 evalcode, typeof Math:', typeof Math); var foo1 = 'bar';");
	duk_push_global_object(ctx);
	duk_get_prop_string(ctx, -1, "foo1");
	str = duk_get_string(ctx, -1);
	printf("global.foo1=%s\n", str ? str : "NULL");
	duk_pop_2(ctx);

	printf("final top: %ld\n", (long) duk_get_top(ctx));
	return 0;
}
Пример #19
0
static int ClearTriggerCallback(duk_context* ctx, int pinFunc, AJS_IO_PinTriggerCondition condition)
{
    int32_t trigId;

    AJS_TargetIO_PinDisableTrigger(PinCtxPtr(ctx), pinFunc, condition, &trigId);
    if (trigId != AJS_IO_PIN_NO_TRIGGER) {
        duk_get_global_string(ctx, AJS_IOObjectName);
        duk_get_prop_string(ctx, -1, AJS_HIDDEN_PROP("trigs"));
        duk_del_prop_index(ctx, -1, trigId);
        duk_pop_2(ctx);
    }
    duk_push_this(ctx);
    duk_del_prop_string(ctx, -1, "trigger");
    /*
     * Leave pin object on the stack
     */
    return 1;
}
Пример #20
0
AJ_Status AJS_HandleAcceptSession(duk_context* ctx, AJ_Message* msg, uint16_t port, uint32_t sessionId, const char* joiner)
{
    uint32_t accept = TRUE;
    SessionInfo* sessionInfo;

    /*
     * Create an entry in the sessions table so we can track this peer
     */
    AJS_GetGlobalStashObject(ctx, "sessions");
    sessionInfo = AllocSessionObject(ctx, joiner);
    /*
     * If there is no handler automatically accept the connection
     */
    AJS_GetAllJoynProperty(ctx, "onPeerConnected");
    if (duk_is_callable(ctx, -1)) {
        /* Empty interface array */
        duk_push_array(ctx);
        AddServiceObject(ctx, sessionInfo, "/", joiner);
        if (AJS_DebuggerIsAttached()) {
            msg = AJS_CloneAndCloseMessage(ctx, msg);
        }
        if (duk_pcall(ctx, 1) != DUK_EXEC_SUCCESS) {
            AJS_ConsoleSignalError(ctx);
            accept = FALSE;
        } else {
            accept = duk_get_boolean(ctx, -1);
        }
    }
    duk_pop_2(ctx);
    /*
     * It is possible that we already have an outbound session to this peer so if we are not
     * accepting the session we can only delete the entry if the refCount is zero.
     */
    if (accept) {
        ++sessionInfo->refCount;
        sessionInfo->port = port;
        sessionInfo->sessionId = sessionId;
    } else if (sessionInfo->refCount == 0) {
        duk_del_prop_string(ctx, -1, joiner);
    }
    /* Pop sessions object */
    duk_pop(ctx);
    return AJ_BusReplyAcceptSession(msg, accept);
}
Пример #21
0
gboolean
_gum_duk_get_uint64 (duk_context * ctx,
                     duk_idx_t index,
                     GumDukCore * core,
                     guint64 * u)
{
  if (duk_is_pointer (ctx, index))
  {
    *u = *((const guint64 *) duk_require_pointer (ctx, index));
    return TRUE;
  }
  else if (duk_is_number (ctx, index))
  {
    duk_double_t number;

    number = duk_require_number (ctx, index);
    if (number < 0)
      return FALSE;

    *u = (guint64) number;
    return TRUE;
  }
  else
  {
    gboolean success = FALSE;

    duk_dup (ctx, index);
    duk_push_heapptr (ctx, core->uint64);

    if (duk_instanceof (ctx, -2, -1))
    {
      GumDukUInt64 * object;

      object = _gum_duk_require_data (ctx, -2);

      *u = object->value;
      success = TRUE;
    }

    duk_pop_2 (ctx);

    return success;
  }
}
Пример #22
0
AJ_Status AJS_ServiceIO(duk_context* ctx)
{
    AJS_IO_PinTriggerCondition condition;
    int32_t trigId;

    trigId = AJS_TargetIO_PinTrigId(&condition);
    if (trigId != AJS_IO_PIN_NO_TRIGGER) {
        AJ_InfoPrintf(("triggered on id %d\n", trigId));
        /*
         * Lookup the pin object in the triggers array
         */
        duk_get_global_string(ctx, AJS_IOObjectName);
        duk_get_prop_string(ctx, -1, AJS_HIDDEN_PROP("trigs"));
        do {
            duk_get_prop_index(ctx, -1, trigId);
            if (duk_is_object(ctx, -1)) {
                /*
                 * Call the trigger function passing the pin object and value as the argument
                 */
                duk_get_prop_string(ctx, -1, "trigger");
                if (duk_is_callable(ctx, -1)) {
                    /*
                     * Pin object is the "this" object
                     */
                    duk_dup(ctx, -2);
                    duk_push_int(ctx, condition);
                    if (duk_pcall_method(ctx, 1) != DUK_EXEC_SUCCESS) {
                        AJS_ConsoleSignalError(ctx);
                    }
                }
                /*
                 * Pop pin object
                 */
                duk_pop(ctx);
            } else {
                AJ_ErrPrintf(("Expected a pin object trigId = %d\n", trigId));
            }
            duk_pop(ctx);
            trigId = AJS_TargetIO_PinTrigId(&condition);
        } while (trigId != AJS_IO_PIN_NO_TRIGGER);
        duk_pop_2(ctx);
    }
    return AJ_OK;
}
Пример #23
0
static duk_ret_t test_passthrough(duk_context *ctx, void *udata) {
	(void) udata;

	duk_push_c_function(ctx, my_constructor, 1 /*nargs*/);  /* target */
	duk_push_object(ctx);  /* handler */

	duk_push_proxy(ctx, 0);

	duk_push_uint(ctx, 123);
	duk_new(ctx, 1 /*nargs*/);

	duk_get_prop_string(ctx, -1, "foo");
	printf("ret.foo=%s\n", duk_to_string(ctx, -1));

	duk_pop_2(ctx);  /* 'foo', constructor result */

	printf("final top: %ld\n", (long) duk_get_top(ctx));
	return 0;
}
Пример #24
0
static void dukzip_zip_checkoptions(duk_context *ctx, duk_idx_t idx, const char **filename, duk_int_t *level, duk_int_t *method, const char **comment) 
{
	duk_get_prop_string(ctx, idx, "filename");
	if (duk_is_string(ctx, -1)) {
		*filename = duk_get_string(ctx, -1);
		duk_pop(ctx);
	} else {
		duk_pop(ctx);
	}

	duk_get_prop_string(ctx, idx, "level");
	if (duk_is_number(ctx, -1)) {
		*level = duk_get_int(ctx, -1);
		duk_pop(ctx);
	} else {
		duk_pop(ctx);
	}

	duk_get_prop_string(ctx, idx, "method");
	if (duk_is_string(ctx, -1)) {
		duk_push_string(ctx, "deflate");
		if (duk_equals(ctx, -1, -2)) {
			*method = Z_DEFLATED;
		} else {
			duk_pop(ctx);
			duk_push_string(ctx, "store");
			if (duk_equals(ctx, -1, -2)) {
				*method = 0;
			}
		}
		duk_pop_2(ctx);
	} else {
		duk_pop(ctx);
	}

	duk_get_prop_string(ctx, idx, "comment");
	if (duk_is_string(ctx, -1)) {
		*comment = duk_get_string(ctx, -1);
		duk_pop(ctx);
	} else {
		duk_pop(ctx);
	}
}
Пример #25
0
static void print_error(duk_context *ctx, FILE *f) {
	if (duk_is_object(ctx, -1) && duk_has_prop_string(ctx, -1, "stack")) {
		/* FIXME: print error objects specially */
		/* FIXME: pcall the string coercion */
		duk_get_prop_string (ctx, -1, "stack");
		if (duk_is_string (ctx, -1)) {
			fprintf (f, "%s\n", duk_get_string(ctx, -1));
			fflush (f);
			duk_pop_2 (ctx);
			return;
		} else {
			duk_pop (ctx);
		}
	}
	duk_to_string(ctx, -1);
	fprintf (f, "%s\n", duk_get_string(ctx, -1));
	fflush (f);
	duk_pop(ctx);
}
Пример #26
0
DUK_LOCAL duk_ret_t duk__pcall_prop_raw(duk_context *ctx) {
	duk_idx_t obj_index;
	duk_idx_t nargs;

	/* Get the original arguments.  Note that obj_index may be a relative
	 * index so the stack must have the same top when we use it.
	 */

	DUK_ASSERT_CTX_VALID(ctx);

	obj_index = (duk_idx_t) duk_get_int(ctx, -2);
	nargs = (duk_idx_t) duk_get_int(ctx, -1);
	duk_pop_2(ctx);

	obj_index = duk_require_normalize_index(ctx, obj_index);  /* make absolute */
	duk__call_prop_prep_stack(ctx, obj_index, nargs);
	duk_call_method(ctx, nargs);
	return 1;
}
Пример #27
0
static duk_ret_t my_func_1(duk_context *ctx) {
	printf("duk_is_constructor_call: %d\n", (int) duk_is_constructor_call(ctx));

	/* check 'this'; it should have internal prototype set below to
	 * constructor's "prototype" property.
	 */
	duk_push_this(ctx);
	duk_push_string(ctx, "own_value");
	duk_put_prop_string(ctx, -2, "own_key");
	duk_enum(ctx, -1, 0 /*enum_flags*/);
	while (duk_next(ctx, -1, 1 /*get_value*/)) {
		printf("key='%s', value='%s'\n", duk_to_string(ctx, -2), duk_to_string(ctx, -1));
		duk_pop_2(ctx);
	}
	duk_pop(ctx);
	duk_pop(ctx);

	return 0;
}
void duk_hobject_run_finalizer(duk_hthread *thr, duk_hobject *obj) {
	duk_context *ctx = (duk_context *) thr;
	int rc;
#ifdef DUK_USE_ASSERTIONS
	int entry_top;
#endif

	DUK_DDDPRINT("running object finalizer for object: %p", (void *) obj);

	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(ctx != NULL);
	DUK_ASSERT(obj != NULL);

	/* FIXME: assert stack space */

#ifdef DUK_USE_ASSERTIONS
	entry_top = duk_get_top(ctx);
#endif
	/*
	 *  Get and call the finalizer.  All of this must be wrapped
	 *  in a protected call, because even getting the finalizer
	 *  may trigger an error (getter may throw one, for instance).
	 */

	/* FIXME: use a NULL error handler for the finalizer call? */

	DUK_DDDPRINT("-> finalizer found, calling wrapped finalize helper");
	duk_push_hobject(ctx, obj);  /* this also increases refcount by one */
	rc = duk_safe_call(ctx, _finalize_helper, 0 /*nargs*/, 1 /*nrets*/, DUK_INVALID_INDEX);  /* -> [... obj retval/error] */
	DUK_ASSERT_TOP(ctx, entry_top + 2);  /* duk_safe_call discipline */

	if (rc != DUK_ERR_EXEC_SUCCESS) {
		/* Note: we ask for one return value from duk_safe_call to get this
		 * error debugging here.
		 */
		DUK_DPRINT("wrapped finalizer call failed for object %p (ignored); error: %!T",
		           (void *) obj, duk_get_tval(ctx, -1));
	}
	duk_pop_2(ctx);  /* -> [...] */

	DUK_ASSERT_TOP(ctx, entry_top);
}
Пример #29
0
    int w_LocalStorage_prototype_setItem(duk_context *ctx)
    {
        const char *key = duk_require_string(ctx, 0);
        // Make sure value is string
        duk_to_string(ctx, 1);
        const char *value = duk_require_string(ctx, 1);

        duk_push_this(ctx); /* this */
        duk_get_prop_string(ctx, -1, "__MURAL_DATA__"); /* this, __MURAL_DATA__ */
        duk_push_string(ctx, value); /* this, __MURAL_DATA__, value */
        duk_put_prop_string(ctx, -2, key); /* this, __MURAL_DATA__ */

        LocalStorage *inst = getNativePointer<LocalStorage>(ctx);
        duk_json_encode(ctx, -1); /* this, JSON(__MURAL_DATA__) */
        inst->setData(duk_to_string(ctx, -1)); /* this, string(JSON(__MURAL_DATA__)) */

        duk_pop_2(ctx);

        return 0;
    }
Пример #30
0
static int NativeIoUart(duk_context* ctx)
{
    AJ_Status status;
    uint8_t tx, rx;
    uint32_t baud;
    void* uartCtx = NULL;
    int32_t rxTrigId;
    int idx;

    tx = GetPinId(ctx, 0, AJS_IO_FUNCTION_UART_TX);
    rx = GetPinId(ctx, 1, AJS_IO_FUNCTION_UART_RX);
    baud = duk_require_int(ctx, 2);
    duk_pop(ctx);
    status = AJS_TargetIO_UartOpen(tx, rx, baud, &uartCtx, &rxTrigId);
    if (status != AJ_OK) {
        duk_error(ctx, DUK_ERR_INTERNAL_ERROR, "Failed to open UART device\n");
    }
    idx = NewIOObject(ctx, uartCtx, AJS_IO_FUNCTION_UART, NativeUartFinalizer);

    duk_push_c_lightfunc(ctx, NativeUartSetTrigger, 2, 0, 0);
    duk_put_prop_string(ctx, idx, "setTrigger");

    duk_push_c_lightfunc(ctx, NativeUartClearTrigger, 1, 0, 0);
    duk_put_prop_string(ctx, idx, "clearTrigger");

    duk_push_c_lightfunc(ctx, NativeUartRead, 2, 0, 0);
    duk_put_prop_string(ctx, idx, "read");

    duk_push_c_lightfunc(ctx, NativeUartWrite, 1, 0, 0);
    duk_put_prop_string(ctx, idx, "write");
    /*
     * Add the uart I/O object to the triggers array.
     */
    duk_get_global_string(ctx, AJS_IOObjectName);
    duk_get_prop_string(ctx, -1, AJS_HIDDEN_PROP("trigs"));
    duk_dup(ctx, idx);
    duk_put_prop_index(ctx, -2, rxTrigId);
    duk_pop_2(ctx);

    return 1;
}