浏览代码

feat: ffi读取funcargs时使用__iter__

link #17
SongZihuan 4 年之前
父节点
当前提交
bcca373740

+ 1 - 0
CMakeLists.txt

@@ -65,3 +65,4 @@ SET_TARGET_PROPERTIES(VirtualMath PROPERTIES
         )
 
 INSTALL(TARGETS VirtualMath)
+MESSAGE(STATUS "hellovm cmake configure finish")

+ 2 - 2
src/virtualmath.c

@@ -7,11 +7,11 @@ void runCodeFile(Inter *inter, char *file[]) {
     setResultCore(&result);
     for (PASS; !should_break && *file != NULL; file++) {
         int status;
-        if ((status = checkFileReadble((*file))) == 3)
+        if ((status = checkFileReadable((*file))) == 3)
             continue;
         else if (status == 2) {
             *file = memStrcat(*file, ((*file)[memStrlen(*file) - 1] != SEP_CH ? SEP"__main__.vm" : "__main__.vm"), false, false);
-            if (checkFileReadble(*file) != 1)
+            if (checkFileReadable(*file) != 1)
                 continue;
         }
         if (runParser(*file, inter, false, &pst)) {

+ 4 - 1
vmcore/CMakeLists.txt

@@ -55,4 +55,7 @@ INSTALL(CODE "SET(ENV{VIRTUALMATHPATH} \"${VMLIB_PATH},${CLIB_PATH}\")")  # 设
 INSTALL(CODE "MESSAGE(STATUS \"Now Install\")")  # 安装时运行
 
 # 安装clib
-ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/clib)
+ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/clib)
+
+# 结束语
+MESSAGE(STATUS "vmcore cmake configure finish")

+ 1 - 1
vmcore/file/file.c

@@ -4,7 +4,7 @@
  * @param dir 文件地址
  * @return 0-错误, 1-普通文件, 2-目录
  */
-int checkFileReadble(char *dir){
+int checkFileReadable(char *dir){
     struct stat my_stat;
     int status;
     if (dir == NULL)

+ 1 - 1
vmcore/include/file.h

@@ -1,7 +1,7 @@
 #ifndef VIRTUALMATH_FILE_H
 #define VIRTUALMATH_FILE_H
 
-int checkFileReadble(char *dir);
+int checkFileReadable(char *dir);
 char *splitDir(char * dir);
 
 #endif //VIRTUALMATH_FILE_H

+ 1 - 1
vmcore/include/parameter.h

@@ -138,7 +138,7 @@ void setArgumentFFI(ArgumentFFI *af, unsigned int size);
 void freeArgumentFFI(ArgumentFFI *af);
 
 unsigned int checkArgument(Argument *arg, enum ArgumentType type);
-bool listToArgumentFFI(ArgumentFFI *af, LinkValue **list, vint size, LinkValue **valist, vint vasize);
+enum ResultType listToArgumentFFI(ArgumentFFI *af, LinkValue *list_b, LinkValue *valiste_b, FUNC_NT);
 bool setArgumentToFFI(ArgumentFFI *af, Argument *arg);
 ffi_type *getFFIType(wchar_t *str, enum ArgumentFFIType *aft);
 ffi_type *getFFITypeUp(wchar_t *str, enum ArgumentFFIType *aft);

+ 1 - 1
vmcore/ofunc/src/vmobj/file_.c

@@ -62,7 +62,7 @@ static ResultType file_init(O_FUNC){
     else
         mode = memStrcpy("rt");  // 默认模式是rt
 
-    if (checkFileReadble(path) != 1) {
+    if (checkFileReadable(path) != 1) {
         setResultError(E_TypeException, L"file is not readable", LINEFILE, true, CNEXT_NT);
         return R_error;
     }

+ 7 - 0
vmcore/src/__run.c

@@ -531,6 +531,13 @@ ResultType getElement(LinkValue *from, LinkValue *index, fline line, char *file,
     return result->type;
 }
 
+
+/**
+ * 执行__iter__或__next__函数
+ * @param value 遍历对象
+ * @param status 1-执行__iter__, 否则执行__next__
+ * @return
+ */
 ResultType getIter(LinkValue *value, int status, fline line, char *file, FUNC_NT) {
     LinkValue *_func_ = NULL;
     setResultCore(result);

+ 65 - 21
vmcore/src/parameter.c

@@ -883,33 +883,77 @@ unsigned int checkArgument(Argument *arg, enum ArgumentType type) {
     return count;
 }
 
-bool listToArgumentFFI(ArgumentFFI *af, LinkValue **list, vint size, LinkValue **valist, vint vasize) {
-    int i=0;
-    if ((size + vasize) != af->size)
-        return false;
-
-    for (PASS; i < size; i++) {
-        LinkValue *str = list[i];
-        if (str->value->type != V_str)
-            return false;
-        af->arg[i] = getFFIType(str->value->data.str.str, af->type + i);
-        if (af->arg[i] == NULL || af->type[i] == af_void)
-            return false;
+enum ResultType listToArgumentFFI(ArgumentFFI *af, LinkValue *list_b, LinkValue *valiste_b, FUNC_NT) {  // TODO-szh 内存检查
+    int i = 0;
+    LinkValue *iter[3] = {};  // 待遍历列表 (默认三个都为NULL)
+
+    setResultCore(result);
+    gc_addTmpLink(&list_b->gc_status);
+    if (valiste_b != NULL)
+        gc_addTmpLink(&valiste_b->gc_status);
+
+    getIter(list_b, 1, LINEFILE, CNEXT_NT);  // 获取__iter__对象
+    if (!CHECK_RESULT(result))
+        goto return_;
+    iter[0] = result->value;
+    result->value = NULL;
+    freeResult(result);
+
+    if (valiste_b != NULL) {
+        getIter(valiste_b, 1, LINEFILE, CNEXT_NT);  // 获取__iter__对象
+        if (!CHECK_RESULT(result))
+            goto return_;
+        iter[1] = result->value;
+        result->value = NULL;
+        freeResult(result);
+    } else
+        iter[1] = NULL;
+
+    for (int a=0; iter[a] != NULL; a++) {  // 开始遍历
+        while (1) {
+            LinkValue *str;
+            getIter(iter[a], 0, LINEFILE, CNEXT_NT);
+            if (is_iterStop(result->value, inter)) {  // 执行__next__
+                freeResult(result);
+                break;
+            } else if (!CHECK_RESULT(result))
+                return result->type;
+            else
+                str = result->value;
+
+            if (str->value->type != V_str) {  // 检查是否为str
+                freeResult(result);
+                setResultError(E_ArgumentException, L"no-support argument type for C function", LINEFILE, true,
+                               CNEXT_NT);
+                goto return_;
+            }
+
+            af->arg[i] = getFFIType(str->value->data.str.str, af->type + i);
+            i++;
+            freeResult(result);
+
+            if (af->arg[i] == NULL || af->type[i] == af_void) { // 不支持的类型
+                setResultError(E_ArgumentException, L"no-support argument type for C function", LINEFILE, true,
+                               CNEXT_NT);
+                goto return_;
+            }
+        }
     }
 
-    for (PASS; i < af->size; i++) {  // 处理可变参数
-        LinkValue *str = valist[i - size];
-        if (str->value->type != V_str)
-            return false;
-        af->arg[i] = getFFITypeUp(str->value->data.str.str, af->type + i);
-        if (af->arg[i] == NULL || af->type[i] == af_void)
-            return false;
+    setResult(result, inter);
+
+    return_:
+    gc_freeTmpLink(&list_b->gc_status);
+    gc_freeTmpLink(&iter[0]->gc_status);
+    if (valiste_b != NULL) {
+        gc_freeTmpLink(&valiste_b->gc_status);
+        gc_freeTmpLink(&iter[1]->gc_status);
     }
-    return true;
+    return result->type;
 }
 
 #define setFFIValue(v_t, ffi_t, af_t, type_, data_) case v_t: \
-af->arg[i] = &ffi_t;  /* af->arg是ffi_type **arg, 即*arg[] */ \
+af->arg[i] = &(ffi_t);  /* af->arg是ffi_type **arg, 即*arg[] */ \
 af->type[i] = af_t; \
 af->arg_v[i] = (type_ *)memCalloc(1, sizeof(type_));  /* af->arg_v是ffi_type **arg_v, 即 *arg_v[] */ \
 *(type_ *)(af->arg_v[i]) = (type_)(data_); \

+ 3 - 12
vmcore/src/runcall.c

@@ -390,19 +390,8 @@ static ResultType getFuncargs(LinkValue *function_value, ArgumentFFI *af, fline
     freeResult(result);
 
     if (arg_var != NULL) {
-        LinkValue **valist = vaarg_var != NULL ? vaarg_var->value->data.list.list : NULL;
-        vint vasize = vaarg_var != NULL ? vaarg_var->value->data.list.size : 0;
         af->b_va = arg_var->value->data.list.size;
-
-        if (arg_var->value->type != V_list || vaarg_var != NULL && vaarg_var->value->type != V_list) {
-            setResultError(E_TypeException, ONLY_ACC(funcargs / vaarg_var, list), line, file, true, CNEXT_NT);
-            return R_error;
-        }
-
-        if (!listToArgumentFFI(af, arg_var->value->data.list.list, arg_var->value->data.list.size, valist, vasize)) {
-            setResultError(E_ArgumentException, L"no-support argument type for C function", line, file, true, CNEXT_NT);
-            return R_error;
-        }
+        listToArgumentFFI(af, arg_var, vaarg_var, CNEXT_NT);
     }
     return result->type;
 }
@@ -440,6 +429,8 @@ static ResultType callFFunction(LinkValue *function_value, Argument *arg, fline
     getFuncargs(function_value, &af, line, file, CNEXT_NT);  // 设定类型
     if (!CHECK_RESULT(result))
         goto return_;
+    else
+        freeResult(result);
 
     if (!setArgumentToFFI(&af, arg)) {  // 设定ffi_type和ffi参数的真实数据
         setResultError(E_ArgumentException, L"parameter exception when calling C function", line, file, true, CNEXT_NT);

+ 2 - 2
vmcore/src/runfile.c

@@ -30,7 +30,7 @@ int isAbsolutePath(const char *path) {  // 检查路径模式
 static bool isExist(char **path, bool is_ab, char *file) {  // is_ab 参数参见 isAbsolutePath
     char *backup = is_ab ? memStrcpy((*path) + 1) : memStrcpy(*path);  // 是否跳过第一个字符
     int status;
-    if ((status = checkFileReadble(backup)) != 3) {
+    if ((status = checkFileReadable(backup)) != 3) {
         memFree(*path);  // 若文件存在则替换文件路径
         *path = backup;
         if (status == 2) {  // 如果是文件夹
@@ -42,7 +42,7 @@ static bool isExist(char **path, bool is_ab, char *file) {  // is_ab 参数参
             return isExist(path, false, NULL);
         } else
             return true;
-    } else if (checkFileReadble(backup = memStrcat(backup, ".vm", true, false)) == 1) {
+    } else if (checkFileReadable(backup = memStrcat(backup, ".vm", true, false)) == 1) {
         memFree(*path);  // 若文件存在则替换文件路径
         *path = backup;
         return true;