Skip to content

Commit

Permalink
mjs: Allow null as char and void pointers in FFI
Browse files Browse the repository at this point in the history
CL: mjs: Allow null as char and void pointers in FFI

PUBLISHED_FROM=525a6a938eee8a7641c7af4e6996fd506f6fcfcd
  • Loading branch information
Deomid Ryabkov authored and cesantabot committed May 9, 2018
1 parent 9154b61 commit 1c59386
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 26 deletions.
30 changes: 17 additions & 13 deletions mjs.c
Expand Up @@ -11130,26 +11130,24 @@ MJS_PRIVATE mjs_err_t mjs_ffi_call2(struct mjs *mjs) {
break;
case MJS_FFI_CTYPE_CHAR_PTR: {
size_t s;
if (!mjs_is_string(arg)) {
if (mjs_is_string(arg)) {
/*
* String argument should be saved separately in order to support
* short strings (which are packed into mjs_val_t itself)
*/
argvs[i] = arg;
ffi_set_ptr(&args[i], (void *) mjs_get_string(mjs, &argvs[i], &s));
} else if (mjs_is_null(arg)) {
ffi_set_ptr(&args[i], NULL);
} else {
ret = MJS_TYPE_ERROR;
mjs_prepend_errorf(
mjs, ret, "actual arg #%d is not a string (the type idx is: %s)",
i, mjs_typeof(arg));
goto clean;
}
/*
* String argument should be saved separately in order to support
* short strings (which are packed into mjs_val_t itself)
*/
argvs[i] = arg;
ffi_set_ptr(&args[i], (void *) mjs_get_string(mjs, &argvs[i], &s));
} break;
case MJS_FFI_CTYPE_VOID_PTR:
if (!mjs_is_foreign(arg) && !mjs_is_string(arg)) {
ret = MJS_TYPE_ERROR;
mjs_prepend_errorf(mjs, ret, "actual arg #%d is not a ptr", i);
goto clean;
}
if (mjs_is_string(arg)) {
size_t n;
/*
Expand All @@ -11158,8 +11156,14 @@ MJS_PRIVATE mjs_err_t mjs_ffi_call2(struct mjs *mjs) {
*/
argvs[i] = arg;
ffi_set_ptr(&args[i], (void *) mjs_get_string(mjs, &argvs[i], &n));
} else {
} else if (mjs_is_foreign(arg)) {
ffi_set_ptr(&args[i], (void *) mjs_get_ptr(mjs, arg));
} else if (mjs_is_null(arg)) {
ffi_set_ptr(&args[i], NULL);
} else {
ret = MJS_TYPE_ERROR;
mjs_prepend_errorf(mjs, ret, "actual arg #%d is not a ptr", i);
goto clean;
}
break;
case MJS_FFI_CTYPE_CALLBACK:
Expand Down
30 changes: 17 additions & 13 deletions mjs/src/mjs_ffi.c
Expand Up @@ -809,26 +809,24 @@ MJS_PRIVATE mjs_err_t mjs_ffi_call2(struct mjs *mjs) {
break;
case MJS_FFI_CTYPE_CHAR_PTR: {
size_t s;
if (!mjs_is_string(arg)) {
if (mjs_is_string(arg)) {
/*
* String argument should be saved separately in order to support
* short strings (which are packed into mjs_val_t itself)
*/
argvs[i] = arg;
ffi_set_ptr(&args[i], (void *) mjs_get_string(mjs, &argvs[i], &s));
} else if (mjs_is_null(arg)) {
ffi_set_ptr(&args[i], NULL);
} else {
ret = MJS_TYPE_ERROR;
mjs_prepend_errorf(
mjs, ret, "actual arg #%d is not a string (the type idx is: %s)",
i, mjs_typeof(arg));
goto clean;
}
/*
* String argument should be saved separately in order to support
* short strings (which are packed into mjs_val_t itself)
*/
argvs[i] = arg;
ffi_set_ptr(&args[i], (void *) mjs_get_string(mjs, &argvs[i], &s));
} break;
case MJS_FFI_CTYPE_VOID_PTR:
if (!mjs_is_foreign(arg) && !mjs_is_string(arg)) {
ret = MJS_TYPE_ERROR;
mjs_prepend_errorf(mjs, ret, "actual arg #%d is not a ptr", i);
goto clean;
}
if (mjs_is_string(arg)) {
size_t n;
/*
Expand All @@ -837,8 +835,14 @@ MJS_PRIVATE mjs_err_t mjs_ffi_call2(struct mjs *mjs) {
*/
argvs[i] = arg;
ffi_set_ptr(&args[i], (void *) mjs_get_string(mjs, &argvs[i], &n));
} else {
} else if (mjs_is_foreign(arg)) {
ffi_set_ptr(&args[i], (void *) mjs_get_ptr(mjs, arg));
} else if (mjs_is_null(arg)) {
ffi_set_ptr(&args[i], NULL);
} else {
ret = MJS_TYPE_ERROR;
mjs_prepend_errorf(mjs, ret, "actual arg #%d is not a ptr", i);
goto clean;
}
break;
case MJS_FFI_CTYPE_CALLBACK:
Expand Down
13 changes: 13 additions & 0 deletions mjs/tests/unit_test.c
Expand Up @@ -1176,6 +1176,11 @@ const char *test_call_ffi(struct mjs *mjs) {
ASSERT_EQ(mjs_exec(mjs, "ffi_test_s1s('\\x00')", &res), MJS_OK);
ASSERT_STREQ(mjs_get_cstring(mjs, &res), "");

/* null as an argument is allowed and becomes NULL;
* return value of NULL becomes null. */
ASSERT_EQ(mjs_exec(mjs, "ffi_test_s1s(null)", &res), MJS_OK);
ASSERT_TRUE(mjs_is_null(res));

ASSERT_EXEC_OK(
mjs_exec(mjs, "ffi('double ffi_test_d2d(double,double)')(3.71, 1.28)",
&res));
Expand Down Expand Up @@ -3177,6 +3182,14 @@ const char *test_foreign_ptr(struct mjs *mjs) {
), &res));
ASSERT_EQ(mjs_get_bool(mjs, res), 1);

ASSERT_EXEC_OK(mjs_exec(mjs,
STRINGIFY(
let free = ffi('void free(void *)');
free(null); // null is allowed
true;
), &res));
ASSERT_EQ(mjs_get_bool(mjs, res), 1);

ASSERT_EXEC_OK(mjs_exec(mjs,
STRINGIFY(
let calloc = ffi('void *calloc(int, int)');
Expand Down

0 comments on commit 1c59386

Please sign in to comment.