Bläddra i källkod

support get host object for c extern object

Lyon 2 år sedan
förälder
incheckning
3c031e4e5d

+ 10 - 0
examples/builtins/base_type.py

@@ -0,0 +1,10 @@
+assert type('test') == str
+assert type(b'test') == bytes
+assert type(bytearray(b'test')) == bytearray
+assert type(1) == int
+assert type(1.0) == float
+assert type(True) == bool
+assert type([]) == list
+assert type({}) == dict
+assert type(()) == tuple
+print('PASS')

+ 6 - 0
examples/builtins/write_fn.py

@@ -0,0 +1,6 @@
+f = open('test/out/_test.txt', 'w')
+w = f.write
+n = w('test')
+f.close()
+assert n == 4
+print('PASS')

+ 2 - 1
port/linux/.vscode/launch.json

@@ -38,7 +38,8 @@
                 // "--gtest_filter=zlib.*"
                 // "--gtest_filter=vm.run_file"
                 // "--gtest_filter=modbus.rtu_request"
-                "--gtest_filter=PikaStdDevice.inhert"
+                // "--gtest_filter=builtin.write_fn"
+                "--gtest_filter=builtin.base_type"
             ],
             "stopAtEntry": false,
             "cwd": "${workspaceFolder}",

+ 10 - 0
port/linux/test/python/builtins/base_type.py

@@ -0,0 +1,10 @@
+assert type('test') == str
+assert type(b'test') == bytes
+assert type(bytearray(b'test')) == bytearray
+assert type(1) == int
+assert type(1.0) == float
+assert type(True) == bool
+assert type([]) == list
+assert type({}) == dict
+assert type(()) == tuple
+print('PASS')

+ 6 - 0
port/linux/test/python/builtins/write_fn.py

@@ -0,0 +1,6 @@
+f = open('test/out/_test.txt', 'w')
+w = f.write
+n = w('test')
+f.close()
+assert n == 4
+print('PASS')

+ 31 - 14
src/PikaObj.c

@@ -977,21 +977,37 @@ char* methodArg_getTypeList(Arg* method_arg, char* buffs, size_t size) {
 }
 
 PikaObj* methodArg_getHostObj(Arg* method_arg) {
+    pika_assert(argType_isObjectMethodActive(arg_getType(method_arg)));
     MethodProp* prop = (MethodProp*)arg_getContent(method_arg);
     return prop->host_obj;
 }
 
-int methodArg_setHostObj(Arg* method_arg, PikaObj* host_obj) {
-    if (arg_getType(method_arg) != ARG_TYPE_METHOD_OBJECT) {
-        return -1;
+Arg* methodArg_active(Arg* method_arg) {
+    pika_assert(arg_getType(method_arg) == ARG_TYPE_METHOD_NATIVE);
+    Arg* aActive = New_arg(NULL);
+    MethodPropNative* propNative =
+        (MethodPropNative*)arg_getContent(method_arg);
+    MethodProp prop = {0};
+    /* active the method */
+    pika_platform_memcpy(&prop, propNative, sizeof(MethodPropNative));
+    aActive = arg_setStruct(aActive, "", (uint8_t*)&prop, sizeof(MethodProp));
+    arg_setType(aActive, ARG_TYPE_METHOD_NATIVE_ACTIVE);
+    return aActive;
+}
+
+Arg* methodArg_setHostObj(Arg* method_arg, PikaObj* host_obj) {
+    if (!argType_isObjectMethod(arg_getType(method_arg))) {
+        return method_arg;
+    }
+    if (arg_getType(method_arg) == ARG_TYPE_METHOD_NATIVE) {
+        method_arg = methodArg_active(method_arg);
     }
     MethodProp* prop = (MethodProp*)arg_getContent(method_arg);
     if (prop->host_obj == NULL) {
         prop->host_obj = host_obj;
-        // obj_refcntInc(host_obj);
-        return 0;
+        return method_arg;
     }
-    return 0;
+    return method_arg;
 }
 
 char* methodArg_getName(Arg* method_arg, char* buffs, size_t size) {
@@ -3457,21 +3473,22 @@ void builtins_exec(PikaObj* self, char* code) {
 }
 
 Arg* builtins_getattr(PikaObj* self, PikaObj* obj, char* name) {
-    Arg* res = NULL;
     if (NULL == obj) {
         obj_setErrorCode(self, 1);
         __platform_printf("[Error] getattr: can not get attr of NULL.\r\n");
         return NULL;
     }
-    Arg* arg = obj_getArg(obj, name);
-    if (NULL == arg) {
-        arg = obj_getMethodArgWithFullPath(obj, name);
+    Arg* aRes = obj_getArg(obj, name);
+    if (NULL == aRes) {
+        aRes = obj_getMethodArgWithFullPath(obj, name);
     }
-    if (NULL != arg) {
-        res = arg_copy(arg);
-        methodArg_setHostObj(res, obj);
+    if (NULL != aRes) {
+        aRes = methodArg_setHostObj(aRes, obj);
+        if (arg_getType(aRes) != ARG_TYPE_METHOD_NATIVE_ACTIVE) {
+            aRes = arg_copy(aRes);
+        }
     }
-    return res;
+    return aRes;
 }
 
 void builtins_setattr(PikaObj* self, PikaObj* obj, char* name, Arg* val) {

+ 1 - 1
src/PikaObj.h

@@ -322,7 +322,7 @@ void method_returnArg(Args* args, Arg* arg);
 char* methodArg_getDec(Arg* method_arg);
 char* methodArg_getTypeList(Arg* method_arg, char* buffs, size_t size);
 char* methodArg_getName(Arg* method_arg, char* buffs, size_t size);
-int methodArg_setHostObj(Arg* method_arg, PikaObj* host_obj);
+Arg* methodArg_setHostObj(Arg* method_arg, PikaObj* host_obj);
 Arg* methodArg_super(Arg* aThis, NativeProperty** p_prop);
 PikaObj* methodArg_getHostObj(Arg* method_arg);
 ByteCodeFrame* methodArg_getBytecodeFrame(Arg* method_arg);

+ 11 - 10
src/PikaVM.c

@@ -1056,8 +1056,10 @@ __exit:
         pika_platform_printf("NameError: name '%s' is not defined\r\n",
                              arg_path);
     } else {
-        methodArg_setHostObj(aRes, oHost);
-        aRes = arg_copy_noalloc(aRes, aRetReg);
+        aRes = methodArg_setHostObj(aRes, oHost);
+        if (arg_getType(aRes) != ARG_TYPE_METHOD_NATIVE_ACTIVE) {
+            aRes = arg_copy_noalloc(aRes, aRetReg);
+        }
         pika_assert_arg_alive(aRes);
     }
     if (is_temp) {
@@ -1105,14 +1107,13 @@ Arg* _obj_runMethodArgWithState(PikaObj* self,
     obj_setErrorCode(self, PIKA_RES_OK);
 
     /* run method */
-    if (methodType == ARG_TYPE_METHOD_NATIVE) {
+    if (argType_isNative(methodType)) {
         /* native method */
-        fMethod(self, locals->list);
-        /* get method return */
-        aReturn = _get_return_arg(locals);
-    } else if (methodType == ARG_TYPE_METHOD_NATIVE_CONSTRUCTOR) {
-        /* native method */
-        fMethod(self, locals->list);
+        PikaObj* oHost = self;
+        if (methodType == ARG_TYPE_METHOD_NATIVE_ACTIVE) {
+            oHost = methodArg_getHostObj(aMethod);
+        }
+        fMethod(oHost, locals->list);
         /* get method return */
         aReturn = _get_return_arg(locals);
     } else {
@@ -2656,7 +2657,7 @@ static void _OPT_EQU(OperatorInfo* op) {
         goto exit;
     }
     /* type not equl, and type is not int or float */
-    if (op->t1 != op->t2) {
+    if (!argType_isEqual(op->t1, op->t2)) {
         if ((op->t1 != ARG_TYPE_FLOAT) && (op->t1 != ARG_TYPE_INT)) {
             is_equ = 0;
             goto exit;

+ 2 - 1
src/dataArg.c

@@ -312,7 +312,8 @@ Arg* arg_toStrArg(Arg* arg) {
     }
     if (argType_isCallable(type)) {
         /* support basic type */
-        if (type == ARG_TYPE_METHOD_NATIVE) {
+        if (_argType_or(type, ARG_TYPE_METHOD_NATIVE,
+                        ARG_TYPE_METHOD_NATIVE_ACTIVE)) {
             MethodProp* method_store = (MethodProp*)arg_getContent(arg);
             if (strEqu(method_store->name, "int") ||
                 strEqu(method_store->name, "bool") ||

+ 32 - 2
src/dataArg.h

@@ -50,6 +50,7 @@ typedef enum {
     ARG_TYPE_OBJECT_META,
     ARG_TYPE_OBJECT_NEW,
     ARG_TYPE_METHOD_NATIVE,
+    ARG_TYPE_METHOD_NATIVE_ACTIVE,
     ARG_TYPE_METHOD_NATIVE_CONSTRUCTOR,
     ARG_TYPE_METHOD_CONSTRUCTOR,
     ARG_TYPE_METHOD_OBJECT,
@@ -278,7 +279,18 @@ static inline uint8_t argType_isCallable(ArgType type) {
             (type) == ARG_TYPE_METHOD_OBJECT ||
             (type) == ARG_TYPE_METHOD_STATIC ||
             (type) == ARG_TYPE_METHOD_NATIVE ||
-            (type) == ARG_TYPE_METHOD_NATIVE_CONSTRUCTOR);
+            (type) == ARG_TYPE_METHOD_NATIVE_CONSTRUCTOR ||
+            (type) == ARG_TYPE_METHOD_NATIVE_ACTIVE);
+}
+
+static inline uint8_t argType_isObjectMethod(ArgType type) {
+    return ((type) == ARG_TYPE_METHOD_OBJECT ||
+            (type) == ARG_TYPE_METHOD_NATIVE);
+}
+
+static inline uint8_t argType_isObjectMethodActive(ArgType type) {
+    return ((type) == ARG_TYPE_METHOD_OBJECT ||
+            (type) == ARG_TYPE_METHOD_NATIVE_ACTIVE);
 }
 
 static inline uint8_t argType_isConstructor(ArgType type) {
@@ -288,7 +300,25 @@ static inline uint8_t argType_isConstructor(ArgType type) {
 
 static inline uint8_t argType_isNative(ArgType type) {
     return ((type) == ARG_TYPE_METHOD_NATIVE ||
-            (type) == ARG_TYPE_METHOD_NATIVE_CONSTRUCTOR);
+            (type) == ARG_TYPE_METHOD_NATIVE_CONSTRUCTOR ||
+            (type) == ARG_TYPE_METHOD_NATIVE_ACTIVE);
+}
+
+static inline uint8_t _argType_or(ArgType type, ArgType type1, ArgType type2) {
+    return ((type) == (type1) || (type) == (type2));
+}
+
+static inline uint8_t argType_isEqual(ArgType type1, ArgType type2) {
+    if (type1 == type2) {
+        return 1;
+    }
+    if (_argType_or(type1, ARG_TYPE_METHOD_NATIVE,
+                    ARG_TYPE_METHOD_NATIVE_ACTIVE) &&
+        _argType_or(type2, ARG_TYPE_METHOD_NATIVE,
+                    ARG_TYPE_METHOD_NATIVE_ACTIVE)) {
+        return 1;
+    }
+    return 0;
 }
 
 static inline uint8_t argType_isIterable(ArgType type) {