diff --git a/port/linux/.vscode/launch.json b/port/linux/.vscode/launch.json index 2c5776e5a..8ca72b543 100644 --- a/port/linux/.vscode/launch.json +++ b/port/linux/.vscode/launch.json @@ -11,7 +11,7 @@ "program": "${workspaceFolder}/build/test/pikascript_test", // "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain", "args": [ - // "--gtest_filter=compiler.snake_file" + "--gtest_filter=lib.compile_link_import" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", diff --git a/port/linux/test/compile-test.cpp b/port/linux/test/compile-test.cpp index 60d8ce0b5..ffe27ec42 100644 --- a/port/linux/test/compile-test.cpp +++ b/port/linux/test/compile-test.cpp @@ -1,5 +1,6 @@ #include "gtest/gtest.h" extern "C" { +#include "PikaCompiler.h" #include "PikaMain.h" #include "PikaParser.h" #include "PikaStdLib_MemChecker.h" @@ -7,7 +8,6 @@ extern "C" { #include "dataArgs.h" #include "dataMemory.h" #include "dataStrs.h" -#include "pikaCompiler.h" #include "pikaScript.h" #include "pika_config_gtest.h" } @@ -387,3 +387,23 @@ TEST(lib, lib_compile_link) { LibObj_deinit(lib); EXPECT_EQ(pikaMemNow(), 0); } + +TEST(lib, compile_link_import) { + LibObj* lib = New_LibObj(); + + pikaCompileFile("test/python/test_module1.py"); + LibObj_staticLinkFile(lib, "test/python/test_module1.py.o"); + LibObj_listModules(lib); + + PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain); + obj_linkLibrary(pikaMain, lib); + obj_run(pikaMain, + "import test_module1\n" + "test_module1.mytest()\n"); + /* asset */ + EXPECT_STREQ(log_buff[0], "test_module_1_hello\r\n"); + /* deinit */ + LibObj_deinit(lib); + obj_deinit(pikaMain); + EXPECT_EQ(pikaMemNow(), 0); +} diff --git a/port/linux/test/python/test_module1.py b/port/linux/test/python/test_module1.py new file mode 100644 index 000000000..646b06b9d --- /dev/null +++ b/port/linux/test/python/test_module1.py @@ -0,0 +1,2 @@ +def mytest(): + print('test_module_1_hello') diff --git a/src/PikaObj.c b/src/PikaObj.c index 02b1668ac..1e97bf2a5 100644 --- a/src/PikaObj.c +++ b/src/PikaObj.c @@ -28,6 +28,7 @@ #define __PIKA_OBJ_CLASS_IMPLEMENT #include "PikaObj.h" #include "BaseObj.h" +#include "PikaCompiler.h" #include "PikaPlatform.h" #include "dataArgs.h" #include "dataMemory.h" @@ -913,6 +914,14 @@ int32_t obj_newObj(PikaObj* self, return obj_newMetaObj(self, objName, newFunPtr); } +PikaObj* obj_importModuleWithByteCode(PikaObj* self, + char* name, + uint8_t* byteCode) { + obj_newDirectObj(self, name, New_TinyObj); + pikaVM_runByteCode(obj_getObj(self, name), (uint8_t*)byteCode); + return self; +} + PikaObj* obj_importModuleWithByteCodeFrame(PikaObj* self, char* name, ByteCodeFrame* byteCode_frame) { @@ -920,3 +929,8 @@ PikaObj* obj_importModuleWithByteCodeFrame(PikaObj* self, pikaVM_runByteCodeFrame(obj_getObj(self, name), byteCode_frame); return self; } + +PikaObj* obj_linkLibrary(PikaObj* self, LibObj* library) { + obj_setPtr(self, "__lib", library); + return self; +} diff --git a/src/PikaObj.h b/src/PikaObj.h index 822ede7fa..00a62a3f7 100644 --- a/src/PikaObj.h +++ b/src/PikaObj.h @@ -94,6 +94,8 @@ typedef struct MethodInfo_t { ByteCodeFrame* bytecode_frame; } MethodInfo; +typedef PikaObj LibObj; + /* operation */ int32_t obj_deinit(PikaObj* self); int32_t obj_init(PikaObj* self, Args* args); @@ -232,6 +234,9 @@ Arg* arg_setWeakRef(Arg* self, char* name, PikaObj* obj); PikaObj* obj_importModuleWithByteCodeFrame(PikaObj* self, char* name, ByteCodeFrame* bytecode_frame); +PikaObj* obj_importModuleWithByteCode(PikaObj* self, + char* name, + uint8_t* byteCode); int32_t obj_newObj(PikaObj* self, char* objName, @@ -239,6 +244,7 @@ int32_t obj_newObj(PikaObj* self, NewFun newFunPtr); Arg* arg_newMetaObj(NewFun objPtr); +PikaObj* obj_linkLibrary(PikaObj* self, LibObj* library); #define PIKA_PYTHON_BEGIN #define PIKA_PYTHON(x) diff --git a/src/PikaVM.c b/src/PikaVM.c index cf61f7036..e7200fa4a 100644 --- a/src/PikaVM.c +++ b/src/PikaVM.c @@ -28,6 +28,7 @@ #define __PIKA_OBJ_CLASS_IMPLEMENT #include "PikaVM.h" #include "BaseObj.h" +#include "PikaCompiler.h" #include "PikaObj.h" #include "PikaParser.h" #include "PikaPlatform.h" @@ -919,6 +920,20 @@ static Arg* VM_instruction_handler_IMP(PikaObj* self, VMState* vs, char* data) { data); return NULL; } + /* find module from the library */ + LibObj* lib = obj_getPtr(self, "__lib"); + PikaObj* index = obj_getObj(lib, "index"); + PikaObj* module = obj_getObj(index, data); + /* exit when no module in '__lib' */ + if (NULL == module) { + VMState_setErrorCode(vs, 3); + __platform_printf("ModuleNotFoundError: No module named '%s'\r\n", + data); + return NULL; + } + /* import bytecode of the module */ + uint8_t* bytecode = obj_getPtr(module, "bytecode"); + obj_importModuleWithByteCode(self, data, bytecode); return NULL; }