Browse Source

feat: 增加struct与ffi_type的映射

struct映射为ffi_type的pointer类型
ffi部分函数添加了注释

link #17
SongZihuan 4 years ago
parent
commit
1525f1f8c8
4 changed files with 34 additions and 30 deletions
  1. 2 2
      vmcore/ofunc/src/vmobj/function.c
  2. 2 2
      vmcore/ofunc/src/vmobj/lib_.c
  3. 9 5
      vmcore/src/parameter.c
  4. 21 21
      vmcore/src/runcall.c

+ 2 - 2
vmcore/ofunc/src/vmobj/function.c

@@ -72,7 +72,7 @@ static ResultType function_set(O_FUNC){  // 针对FFI设置vaargs
     if (!CHECK_RESULT(result))
         return result->type;
     freeResult(result);
-    if ((func = ap[0].value)->value->type != V_func || (func = ap[0].value)->value->data.function.type != f_func) {
+    if ((func = ap[0].value)->value->type != V_func || func->value->data.function.type != f_func) {
         setResultError(E_TypeException, INSTANCE_ERROR(func), LINEFILE, true, CNEXT_NT);
         return R_error;
     }
@@ -90,7 +90,7 @@ static ResultType function_set(O_FUNC){  // 针对FFI设置vaargs
 
     if (CHECK_RESULT(result))
         setResultOperation(result, func);
-    return result->type;
+    return result->type;  // 返回函数本身, 方便set完之后直接回调
 }
 
 void registeredFunction(R_FUNC){

+ 2 - 2
vmcore/ofunc/src/vmobj/lib_.c

@@ -131,7 +131,7 @@ static ResultType lib_add(O_FUNC){
     }
 
     lib_addCore(ap[1].value->value->data.str.str, clib, CNEXT_NT);
-    return result->type;
+    return result->type;  // 返回函数本身
 }
 
 static ResultType lib_attr(O_FUNC){
@@ -167,7 +167,7 @@ static ResultType lib_attr(O_FUNC){
     }
 
     lib_addCore(error->value->data.str.str, clib, CNEXT_NT);
-    return result->type;
+    return result->type;  // 返回函数本身
 }
 
 void registeredLib(R_FUNC){

+ 9 - 5
vmcore/src/parameter.c

@@ -833,7 +833,7 @@ ArgumentParser *parserArgumentNameDefault(ArgumentParser *ap){
     return ap;
 }
 
-void setArgumentFFICore(ArgumentFFI *af) {
+void setArgumentFFICore(ArgumentFFI *af) {  // 初始化设定
     af->type = NULL;
     af->arg = NULL;
     af->arg_v = NULL;
@@ -921,7 +921,8 @@ static bool setFFIArgFromValue(ArgumentFFI *af, Argument *arg, unsigned int i) {
         setFFIValue(V_dou, ffi_type_double, af_double, double, arg->data.value->value->data.dou.num);
         setFFIValue(V_bool, ffi_type_sint32, af_int, double, arg->data.value->value->data.bool_.bool_);
         setFFIValue(V_str, ffi_type_pointer, af_str, char *, memWcsToStr(arg->data.value->value->data.str.str, false));
-        setFFIValue(V_pointer, ffi_type_void, af_int, void *, arg->data.value->value->data.pointer.pointer);
+        setFFIValue(V_pointer, ffi_type_void, af_pointer, void *, arg->data.value->value->data.pointer.pointer);
+        setFFIValue(V_struct, ffi_type_void, af_pointer, void *, arg->data.value->value->data.struct_.data);
 
         case V_ell:
         setFFIValue(V_none, ffi_type_sint32, af_int, int, 0);
@@ -992,6 +993,9 @@ static bool setFFIArgFromType(ArgumentFFI *af, Argument *arg, unsigned int i) {
                 case V_pointer:
                     *(void **) (af->arg_v[i]) = (void *)arg->data.value->value->data.pointer.pointer;
                     break;
+                case V_struct:
+                    *(void **) (af->arg_v[i]) = (void *)arg->data.value->value->data.struct_.data;
+                    break;
                 default:
                     return 0;
             }
@@ -1027,7 +1031,7 @@ static bool setFFIArgFromType(ArgumentFFI *af, Argument *arg, unsigned int i) {
 
 bool setArgumentToFFI(ArgumentFFI *af, Argument *arg) {
     for (unsigned int i=0; arg != NULL && i < af->size; arg = arg->next, i++) {
-        if (af->arg[i] == NULL) {
+        if (af->arg[i] == NULL) {  // af->arg即ffi_type, 为NULL则表示该参数类型没有指定
             if (!setFFIArgFromValue(af, arg, i))
                 return false;
         } else{
@@ -1038,7 +1042,7 @@ bool setArgumentToFFI(ArgumentFFI *af, Argument *arg) {
     return arg == NULL;  // 若arg还没迭代完, 则证明有问题
 }
 
-ffi_type *getFFIType(wchar_t *str, enum ArgumentFFIType *aft) {
+ffi_type *getFFIType(wchar_t *str, enum ArgumentFFIType *aft) {  // 从str中翻译ffi类型
     ffi_type *return_ = NULL;
     if (eqWide(str, L"int")) {
         return_ = &ffi_type_sint32;
@@ -1089,7 +1093,7 @@ ffi_type *getFFIType(wchar_t *str, enum ArgumentFFIType *aft) {
     return return_;
 }
 
-ffi_type *getFFITypeUp(wchar_t *str, enum ArgumentFFIType *aft) {
+ffi_type *getFFITypeUp(wchar_t *str, enum ArgumentFFIType *aft) {  // 自带参数类型提升
     ffi_type *return_ = NULL;
     if (eqWide(str, L"int") || eqWide(str, L"sint") || eqWide(str, L"char")) {
         return_ = &ffi_type_sint32;

+ 21 - 21
vmcore/src/runcall.c

@@ -346,7 +346,7 @@ static bool FFIReturnValue(enum ArgumentFFIType aft, void *re_v, fline line, cha
             setResult(result, inter);
             break;
         default:
-            setResultError(E_ArgumentException, (wchar_t *) L"no-support return type for C function", line, file, true, CNEXT_NT);
+            setResultError(E_ArgumentException, L"no-support return type for C function", line, file, true, CNEXT_NT);
             return false;
     }
     return true;
@@ -365,8 +365,8 @@ static ffi_type *getRearg(LinkValue *function_value, enum ArgumentFFIType *aft,
             return NULL;
         }
         re = getFFIType(re_var->value->data.str.str, aft);
-        if (re == NULL) {
-            setResultError(E_ArgumentException, (wchar_t *) L"no-support argument type for C function", line, file, true, CNEXT_NT);
+        if (re == NULL) {  // 遇到了不支持的返回值类型
+            setResultError(E_ArgumentException, L"no-support argument type for C function", line, file, true, CNEXT_NT);
             return NULL;
         }
     } else
@@ -379,12 +379,12 @@ static ResultType getFuncargs(LinkValue *function_value, ArgumentFFI *af, fline
     LinkValue *vaarg_var = NULL;
     setResultCore(result);
 
-    arg_var = findAttributes(L"funcargs", false, line, file, true, CFUNC_NT(var_list, result, function_value));
+    arg_var = findAttributes(L"funcargs", false, line, file, true, CFUNC_NT(var_list, result, function_value));  // 获取 arg 类型
     if (!CHECK_RESULT(result))
         return result->type;
     freeResult(result);
 
-    vaarg_var = findAttributes(L"vaargs", false, line, file, true, CFUNC_NT(var_list, result, function_value));
+    vaarg_var = findAttributes(L"vaargs", false, line, file, true, CFUNC_NT(var_list, result, function_value));  // 获取 可变参数部分的 参数类型
     if (!CHECK_RESULT(result))
         return result->type;
     freeResult(result);
@@ -400,7 +400,7 @@ static ResultType getFuncargs(LinkValue *function_value, ArgumentFFI *af, fline
         }
 
         if (!listToArgumentFFI(af, arg_var->value->data.list.list, arg_var->value->data.list.size, valist, vasize)) {
-            setResultError(E_ArgumentException, (wchar_t *) L"no-support argument type for C function", line, file, true, CNEXT_NT);
+            setResultError(E_ArgumentException, L"no-support argument type for C function", line, file, true, CNEXT_NT);
             return R_error;
         }
     }
@@ -411,55 +411,55 @@ static ResultType callFFunction(LinkValue *function_value, Argument *arg, fline
     ffi_cif cif;
     ffi_type *re;
     unsigned int size;
-    ArgumentFFI af;
-    enum ArgumentFFIType aft = af_int;
+    ArgumentFFI af;  // 记录ffi函数的参数信息,包括具体类型和具体参数
+    enum ArgumentFFIType aft = af_void;  // 返回值类型 (默认为void)
     void *re_v = NULL;  // 存放返回值的函數
 
     setResultCore(result);
     if (function_value->value->data.function.function_data.cls->value->type != V_lib) {
-        setResultError(E_ArgumentException, (wchar_t *) L"c function source is not clear", line, file, true, CNEXT_NT);
+        setResultError(E_ArgumentException, L"c function source is not clear", line, file, true, CNEXT_NT);  // ffi函数应该来自lib
         return R_error;
     }
 
     if (function_value->value->data.function.function_data.cls->value->data.lib.handle == NULL) {
-        setResultError(E_ArgumentException, (wchar_t *) L"dynamic library is closed", line, file, true, CNEXT_NT);
+        setResultError(E_ArgumentException, L"dynamic library is closed", line, file, true, CNEXT_NT);  // 检查对应的lib的handle是否已经关闭
         return R_error;
     }
 
     setArgumentFFICore(&af);
-    if (pt_sep != 0 || (size = checkArgument(arg, value_arg)) == -1) {
-        setResultError(E_ArgumentException, (wchar_t *) L"does not support key-value arguments", line, file, true, CNEXT_NT);
+    if (pt_sep != 0 || (size = checkArgument(arg, value_arg)) == -1) {  // 不支持pt_sep, 不支持key-value, 并且统计arg的个数
+        setResultError(E_ArgumentException, L"does not support key-value arguments", line, file, true, CNEXT_NT);
         return R_error;
     }
 
-    re = getRearg(function_value, &aft, line, file, CNEXT_NT);
+    re = getRearg(function_value, &aft, line, file, CNEXT_NT);  // 获取返回值类型
     if (!CHECK_RESULT(result))
         return result->type;
 
-    setArgumentFFI(&af, size);
-    getFuncargs(function_value, &af, line, file, CNEXT_NT);
+    setArgumentFFI(&af, size);  // 为af中的数组申请内存
+    getFuncargs(function_value, &af, line, file, CNEXT_NT);  // 设定类型
     if (!CHECK_RESULT(result))
         goto return_;
 
-    if (!setArgumentToFFI(&af, arg)) {
-        setResultError(E_ArgumentException, (wchar_t *) L"parameter exception when calling C function", line, file, true, CNEXT_NT);
+    if (!setArgumentToFFI(&af, arg)) {  // 设定ffi_type和ffi参数的真实数据
+        setResultError(E_ArgumentException, L"parameter exception when calling C function", line, file, true, CNEXT_NT);
         goto return_;
     }
 
-    if (af.size == af.b_va)
+    if (af.size == af.b_va)  // b_va是确定参数的个数, size是总个数
         ffi_prep_cif(&cif, FFI_DEFAULT_ABI, af.size, re, af.arg);
     else
         ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, af.b_va, af.size, re, af.arg);
 
     if (makeFFIReturn(aft, &re_v)) {
-        ffi_call(&cif, function_value->value->data.function.ffunc, re_v, af.arg_v);
+        ffi_call(&cif, function_value->value->data.function.ffunc, re_v, af.arg_v); // 调用函数
         FFIReturnValue(aft, re_v, line, file, CNEXT_NT);
         memFree(re_v);
     } else
-        setResultError(E_ArgumentException, (wchar_t *) L"no-support return type for C function", line, file, true, CNEXT_NT);
+        setResultError(E_ArgumentException, L"no-support return type for C function", line, file, true, CNEXT_NT);
 
     return_:
-    freeArgumentFFI(&af);
+    freeArgumentFFI(&af);  // 释放af中的列表
     return result->type;
 }