Skip to content

Instantly share code, notes, and snippets.

@FROGGS
Created March 29, 2015 20:12
Show Gist options
  • Save FROGGS/7a95f8fd17b66fa51965 to your computer and use it in GitHub Desktop.
Save FROGGS/7a95f8fd17b66fa51965 to your computer and use it in GitHub Desktop.
diff --git a/src/6model/bootstrap.c b/src/6model/bootstrap.c
index dcf9870..24b0a43 100644
--- a/src/6model/bootstrap.c
+++ b/src/6model/bootstrap.c
@@ -542,6 +542,7 @@ static void string_consts(MVMThreadContext *tc) {
string_creator(name, "name");
string_creator(attribute, "attribute");
string_creator(of, "of");
+ string_creator(rw, "rw");
string_creator(type, "type");
string_creator(typeobj, "typeobj");
string_creator(free_str, "free_str");
diff --git a/src/core/instance.h b/src/core/instance.h
index 481015e..b7ab378 100644
--- a/src/core/instance.h
+++ b/src/core/instance.h
@@ -45,6 +45,7 @@ struct MVMStringConsts {
MVMString *name;
MVMString *attribute;
MVMString *of;
+ MVMString *rw;
MVMString *type;
MVMString *typeobj;
MVMString *free_str;
diff --git a/src/core/nativecall.c b/src/core/nativecall.c
index 385bfcf..7954bf8 100644
--- a/src/core/nativecall.c
+++ b/src/core/nativecall.c
@@ -18,6 +18,16 @@ static MVMint16 get_str_free_flag(MVMThreadContext *tc, MVMObject *info) {
return MVM_NATIVECALL_ARG_FREE_STR;
}
+/* Gets the flag for whether to free a string after a call or not. */
+static MVMint16 get_rw_flag(MVMThreadContext *tc, MVMObject *info) {
+ MVMString *flag = tc->instance->str_consts.rw;
+ if (MVM_repr_exists_key(tc, info, flag)) {
+ if (MVM_repr_get_int(tc, MVM_repr_at_key_o(tc, info, flag)))
+ return MVM_NATIVECALL_ARG_RW;
+ }
+ return MVM_NATIVECALL_ARG_NO_RW;
+}
+
/* Takes a hash describing a type hands back an argument type code. */
static MVMint16 get_arg_type(MVMThreadContext *tc, MVMObject *info, MVMint16 is_return) {
MVMString *typename = MVM_repr_get_str(tc, MVM_repr_at_key_o(tc, info,
@@ -43,7 +53,7 @@ static MVMint16 get_arg_type(MVMThreadContext *tc, MVMObject *info, MVMint16 is_
else if (strcmp(ctypename, "longlong") == 0)
result = MVM_NATIVECALL_ARG_LONGLONG;
else if (strcmp(ctypename, "float") == 0)
- result = MVM_NATIVECALL_ARG_FLOAT;
+ result = MVM_NATIVECALL_ARG_FLOAT | get_rw_flag(tc, info);
else if (strcmp(ctypename, "double") == 0)
result = MVM_NATIVECALL_ARG_DOUBLE;
else if (strcmp(ctypename, "asciistr") == 0)
@@ -89,6 +99,9 @@ static MVMint16 get_calling_convention(MVMThreadContext *tc, MVMString *name) {
/* Map argument type ID to dyncall character ID. */
static char get_signature_char(MVMint16 type_id) {
+ if (type_id & MVM_NATIVECALL_ARG_RW_MASK == MVM_NATIVECALL_ARG_RW)
+ return 'p';
+
switch (type_id & MVM_NATIVECALL_ARG_TYPE_MASK) {
case MVM_NATIVECALL_ARG_VOID:
return 'v';
@@ -647,7 +660,9 @@ MVMObject * MVM_nativecall_invoke(MVMThreadContext *tc, MVMObject *res_type,
MVMObject *site, MVMObject *args) {
MVMObject *result = NULL;
char **free_strs = NULL;
+ void **free_rws = NULL;
MVMint16 num_strs = 0;
+ MVMint16 num_rws = 0;
MVMint16 i;
/* Get native call body, so we can locate the call info. Read out all we
@@ -682,7 +697,17 @@ MVMObject * MVM_nativecall_invoke(MVMThreadContext *tc, MVMObject *res_type,
dcArgLongLong(vm, unmarshal_longlong(tc, value));
break;
case MVM_NATIVECALL_ARG_FLOAT:
- dcArgFloat(vm, unmarshal_float(tc, value));
+ if ((arg_types[i] & MVM_NATIVECALL_ARG_RW_MASK) == MVM_NATIVECALL_ARG_RW) {
+ DCfloat *rw = (DCfloat *)MVM_malloc(sizeof(DCfloat *));
+ *rw = unmarshal_float(tc, value);
+ if (!free_rws)
+ free_rws = (void **)MVM_malloc(num_args * sizeof(void *));
+ free_rws[num_rws] = rw;
+ num_rws++;
+ dcArgPointer(vm, rw);
+ }
+ else
+ dcArgFloat(vm, unmarshal_float(tc, value));
break;
case MVM_NATIVECALL_ARG_DOUBLE:
dcArgDouble(vm, unmarshal_double(tc, value));
@@ -778,9 +803,20 @@ MVMObject * MVM_nativecall_invoke(MVMThreadContext *tc, MVMObject *res_type,
});
});
- /* Perform CArray/CStruct write barriers. */
- for (i = 0; i < num_args; i++)
- MVM_nativecall_refresh(tc, MVM_repr_at_pos_o(tc, args, i));
+ for (i = 0; i < num_args; i++) {
+ MVMObject *value = MVM_repr_at_pos_o(tc, args, i);
+ if ((arg_types[i] & MVM_NATIVECALL_ARG_RW_MASK) == MVM_NATIVECALL_ARG_RW) {
+ fprintf(stderr, "got back %f\n", *(float *)free_rws[i]); /* correctly getting value */
+ switch (arg_types[i] & MVM_NATIVECALL_ARG_TYPE_MASK) {
+ case MVM_NATIVECALL_ARG_FLOAT:
+ fprintf(stderr, "setting %f\n", *(float *)free_rws[i]); /* we end up here */
+ MVM_repr_set_num(tc, value, (MVMnum64)*(float *)free_rws[i]);
+ break;
+ }
+ }
+ /* Perform CArray/CStruct write barriers. */
+ MVM_nativecall_refresh(tc, value);
+ }
/* Free any memory that we need to. */
if (free_strs) {
@@ -789,6 +825,12 @@ MVMObject * MVM_nativecall_invoke(MVMThreadContext *tc, MVMObject *res_type,
MVM_free(free_strs);
}
+ if (free_rws) {
+ for (i = 0; i < num_rws; i++)
+ MVM_free(free_rws[i]);
+ MVM_free(free_rws);
+ }
+
/* Finally, free call VM. */
dcFree(vm);
diff --git a/src/core/nativecall.h b/src/core/nativecall.h
index d6433d9..00e05d4 100644
--- a/src/core/nativecall.h
+++ b/src/core/nativecall.h
@@ -21,6 +21,9 @@
#define MVM_NATIVECALL_ARG_NO_FREE_STR 0
#define MVM_NATIVECALL_ARG_FREE_STR 1
#define MVM_NATIVECALL_ARG_FREE_STR_MASK 1
+#define MVM_NATIVECALL_ARG_NO_RW 0
+#define MVM_NATIVECALL_ARG_RW 256
+#define MVM_NATIVECALL_ARG_RW_MASK 256
/* Native callback entry. Hung off MVMNativeCallbackCacheHead, which is
* a hash owned by the ThreadContext. All MVMNativeCallbacks in a linked
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment