| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531 |
- /*
- * This file is part of the PikaPython project.
- * http://github.com/pikastech/pikapython
- *
- * MIT License
- *
- * Copyright (c) 2021 lyon liang6516@outlook.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
- #include "PikaCompiler.h"
- #include "BaseObj.h"
- #include "PikaObj.h"
- #include "PikaParser.h"
- #include "dataQueue.h"
- #include "dataQueueObj.h"
- #include "dataStack.h"
- #include "dataStrs.h"
- const char magic_code_pyo[] = {0x0f, 'p', 'y', 'o'};
- /*
- * @brief check magic code of pyo file
- * @param bytecode
- * @return pika_true or pika_false
- */
- static pika_bool _check_magic_code_pyo(uint8_t* bytecode) {
- char* data = (char*)bytecode;
- if (data[0] == magic_code_pyo[0] && data[1] == magic_code_pyo[1] &&
- data[2] == magic_code_pyo[2] && data[3] == magic_code_pyo[3]) {
- return pika_true;
- }
- return pika_false;
- }
- /*
- * @brief get bytecode from bytes arg
- * @param self bytes arg
- * @return bytecode
- */
- static uint8_t* arg_getBytecode(Arg* self) {
- uint8_t* bytecode_file = arg_getBytes(self);
- if (_check_magic_code_pyo(bytecode_file)) {
- return bytecode_file + sizeof(magic_code_pyo) + sizeof(uint32_t);
- }
- return bytecode_file;
- }
- /*
- * @brief get bytecode size from bytes arg
- * @param self bytes arg
- * @return bytecode size
- */
- static size_t arg_getBytecodeSize(Arg* self) {
- size_t size_all = arg_getBytesSize(self);
- uint8_t* bytecode_file = arg_getBytes(self);
- if (_check_magic_code_pyo(bytecode_file)) {
- return size_all - sizeof(magic_code_pyo) - sizeof(uint32_t);
- }
- return size_all;
- }
- /* const Pool output redirect */
- static void __handler_constPool_output_file(ConstPool* self, char* content) {
- /* to ram */
- uint16_t size = strGetSize(content) + 1;
- self->arg_buff = arg_append(self->arg_buff, content, size);
- /* to flash */
- pika_platform_fwrite(content, 1, size, self->output_f);
- }
- /* instruct array output redirect */
- static void __handler_instructArray_output_none(InstructArray* self,
- InstructUnit* ins_unit) {
- /* none */
- }
- static void __handler_instructArray_output_file(InstructArray* self,
- InstructUnit* ins_unit) {
- /* to flash */
- pika_platform_fwrite(ins_unit, 1, instructUnit_getSize(), self->output_f);
- }
- /*
- need implament :
- pika_platform_fopen()
- pika_platform_fwrite()
- pika_platform_fclose()
- */
- PIKA_RES pikaCompile(char* output_file_name, char* py_lines) {
- PIKA_RES res = PIKA_RES_OK;
- ByteCodeFrame bytecode_frame = {0};
- uint32_t const_pool_size = 0;
- uint32_t instruct_array_size = 0;
- uint32_t bytecode_size = 0;
- char void_ = 0;
- FILE* bytecode_f = pika_platform_fopen(output_file_name, "wb+");
- if (NULL == bytecode_f) {
- pika_platform_printf("Error: open file %s failed.\r\n",
- output_file_name);
- res = PIKA_RES_ERR_IO_ERROR;
- goto __exit;
- }
- /* main process */
- /* step 1, get size of const pool and instruct array */
- byteCodeFrame_init(&bytecode_frame);
- bytecode_frame.const_pool.output_f = bytecode_f;
- bytecode_frame.instruct_array.output_f = bytecode_f;
- bytecode_frame.instruct_array.output_redirect_fun =
- __handler_instructArray_output_none;
- res = pika_lines2Bytes(&bytecode_frame, py_lines);
- if (PIKA_RES_OK != res) {
- pika_platform_printf(" Error: Syntax error.\r\n");
- goto __exit;
- }
- const_pool_size = bytecode_frame.const_pool.size;
- instruct_array_size = bytecode_frame.instruct_array.size;
- bytecode_size = const_pool_size + instruct_array_size +
- sizeof(const_pool_size) + sizeof(instruct_array_size);
- byteCodeFrame_deinit(&bytecode_frame);
- /* step 2, write instruct array to file */
- /* write magic code */
- pika_platform_fwrite(magic_code_pyo, 1, sizeof(magic_code_pyo), bytecode_f);
- /* write bytecode size */
- pika_platform_fwrite(&bytecode_size, 1, sizeof(bytecode_size), bytecode_f);
- /* write ins array size */
- pika_platform_fwrite(&instruct_array_size, 1, sizeof(instruct_array_size),
- bytecode_f);
- byteCodeFrame_init(&bytecode_frame);
- bytecode_frame.const_pool.output_f = bytecode_f;
- bytecode_frame.instruct_array.output_f = bytecode_f;
- /* instruct array to file */
- bytecode_frame.instruct_array.output_redirect_fun =
- __handler_instructArray_output_file;
- pika_lines2Bytes(&bytecode_frame, py_lines);
- byteCodeFrame_deinit(&bytecode_frame);
- /* step 3, write const pool to file */
- pika_platform_fwrite(&const_pool_size, 1, sizeof(const_pool_size),
- bytecode_f);
- void_ = 0;
- /* add \0 at the start */
- pika_platform_fwrite(&void_, 1, 1, bytecode_f);
- byteCodeFrame_init(&bytecode_frame);
- bytecode_frame.const_pool.output_f = bytecode_f;
- bytecode_frame.instruct_array.output_f = bytecode_f;
- /* const pool to file */
- bytecode_frame.const_pool.output_redirect_fun =
- __handler_constPool_output_file;
- /* instruct array to none */
- bytecode_frame.instruct_array.output_redirect_fun =
- __handler_instructArray_output_none;
- pika_lines2Bytes(&bytecode_frame, py_lines);
- /* deinit */
- __exit:
- byteCodeFrame_deinit(&bytecode_frame);
- if (NULL != bytecode_f) {
- pika_platform_fclose(bytecode_f);
- }
- /* succeed */
- return res;
- };
- /*
- need implament :
- pika_platform_fopen()
- pika_platform_fread()
- pika_platform_fwrite()
- pika_platform_fclose()
- */
- PIKA_RES pikaCompileFileWithOutputName(char* output_file_name,
- char* input_file_name) {
- Args buffs = {0};
- Arg* input_file_arg = arg_loadFile(NULL, input_file_name);
- if (NULL == input_file_arg) {
- pika_platform_printf("Error: Could not load file '%s'\n",
- input_file_name);
- return PIKA_RES_ERR_IO_ERROR;
- }
- char* lines = (char*)arg_getBytes(input_file_arg);
- lines = strsFilePreProcess(&buffs, lines);
- PIKA_RES res = pikaCompile(output_file_name, lines);
- arg_deinit(input_file_arg);
- strsDeinit(&buffs);
- return res;
- }
- PIKA_RES pikaCompileFile(char* input_file_name) {
- Args buffs = {0};
- char* output_file_name = strsGetFirstToken(&buffs, input_file_name, '.');
- output_file_name = strsAppend(&buffs, input_file_name, ".o");
- PIKA_RES res =
- pikaCompileFileWithOutputName(output_file_name, input_file_name);
- strsDeinit(&buffs);
- return res;
- }
- LibObj* New_LibObj(Args* args) {
- LibObj* self = New_PikaObj(NULL);
- return self;
- }
- void LibObj_deinit(LibObj* self) {
- obj_deinit(self);
- }
- /* add bytecode to lib, not copy the bytecode */
- void LibObj_dynamicLink(LibObj* self, char* module_name, uint8_t* bytecode) {
- Args buffs = {0};
- char* module_obj_name = strsReplace(&buffs, module_name, ".", "|");
- if (!obj_isArgExist(self, module_obj_name)) {
- obj_newObj(self, module_obj_name, "", New_TinyObj);
- }
- PikaObj* module_obj = obj_getObj(self, module_obj_name);
- obj_setStr(module_obj, "name", module_name);
- obj_setPtr(module_obj, "bytecode", bytecode);
- strsDeinit(&buffs);
- }
- /*
- * @brief add bytecode to lib, and copy the bytecode to the buff in the lib
- * @param self the lib obj
- * @param module_name the module name
- * @param bytecode the bytecode
- * @param size the size of the bytecode
- * @return error code
- */
- int LibObj_staticLink(LibObj* self,
- char* module_name,
- uint8_t* bytecode,
- size_t size) {
- Args buffs = {0};
- char* module_obj_name = strsReplace(&buffs, module_name, ".", "|");
- if (!obj_isArgExist(self, module_obj_name)) {
- obj_newObj(self, module_obj_name, "", New_TinyObj);
- }
- PikaObj* module_obj = obj_getObj(self, module_obj_name);
- uint16_t name_len = strGetSize(module_name);
- /* copy bytecode to buff */
- obj_setBytes(module_obj, "buff", bytecode, size);
- obj_setInt(module_obj, "namelen", name_len);
- obj_setInt(module_obj, "bytesize", size);
- /* link to buff */
- LibObj_dynamicLink(self, module_name, obj_getBytes(module_obj, "buff"));
- strsDeinit(&buffs);
- return 0;
- }
- int LibObj_staticLinkFileWithPath(LibObj* self,
- char* input_file_name,
- char* path) {
- Args buffs = {0};
- /* read file */
- Arg* input_file_arg = arg_loadFile(NULL, input_file_name);
- if (NULL == input_file_arg) {
- pika_platform_printf("Error: can't open file %s\r\n", input_file_name);
- return -1;
- }
- char* module_name = strsGetLastToken(&buffs, input_file_name, '/');
- size_t module_name_len = strlen(module_name);
- /* cut off '.py.o' */
- if (module_name[module_name_len - 1] == 'o' &&
- module_name[module_name_len - 2] == '.' &&
- module_name[module_name_len - 3] == 'y' &&
- module_name[module_name_len - 4] == 'p' &&
- module_name[module_name_len - 5] == '.') {
- module_name[module_name_len - 5] = 0;
- } else {
- // pika_platform_printf("linking raw %s:%s:%ld\r\n", input_file_name,
- // module_name, arg_getBytecodeSize(input_file_arg));
- /* replace . to | */
- module_name = strsReplace(&buffs, module_name, ".", "|");
- }
- char* module_name_new = strsPathJoin(&buffs, path, module_name);
- /* push bytecode */
- uint8_t* byte_code = arg_getBytecode(input_file_arg);
- size_t code_size = arg_getBytecodeSize(input_file_arg);
- LibObj_staticLink(self, module_name_new, byte_code, code_size);
- /* deinit */
- strsDeinit(&buffs);
- arg_deinit(input_file_arg);
- return 0;
- }
- int LibObj_staticLinkFile(LibObj* self, char* input_file_name) {
- return LibObj_staticLinkFileWithPath(self, input_file_name, "");
- }
- static int32_t __foreach_handler_listModules(Arg* argEach, void* context) {
- if (arg_isObject(argEach)) {
- PikaObj* module_obj = arg_getPtr(argEach);
- pika_platform_printf("%s\r\n", obj_getStr(module_obj, "name"));
- }
- return 0;
- }
- void LibObj_listModules(LibObj* self) {
- args_foreach(self->list, __foreach_handler_listModules, NULL);
- }
- typedef struct {
- FILE* out_file;
- uint32_t module_num;
- uint32_t sum_size;
- uint32_t block_size;
- size_t written_size;
- } PikaLinker;
- static void linker_fwrite(PikaLinker* context, uint8_t* bytes, size_t size) {
- size_t write_size = pika_platform_fwrite(bytes, 1, size, context->out_file);
- context->written_size += write_size;
- }
- static int32_t __foreach_handler_libWriteBytecode(Arg* argEach,
- PikaLinker* context) {
- if (arg_isObject(argEach)) {
- PikaObj* module_obj = arg_getPtr(argEach);
- pika_assert_obj_alive(module_obj);
- uint8_t* bytecode = obj_getPtr(module_obj, "bytecode");
- size_t bytecode_size = obj_getBytesSize(module_obj, "buff");
- /* align by 4 bytes */
- size_t align_size =
- align_by(bytecode_size, sizeof(uint32_t)) - bytecode_size;
- uint8_t aline_buff[sizeof(uint32_t)] = {0};
- // pika_platform_printf(" linking %s:%ld\r\n", obj_getStr(module_obj,
- // "name"),
- // bytecode_size);
- linker_fwrite(context, bytecode, bytecode_size);
- linker_fwrite(context, aline_buff, align_size);
- // printf("link success:%s\r\n", obj_getStr(module_obj, "name"));
- }
- return 0;
- }
- // #define NAME_BUFF_SIZE LIB_INFO_BLOCK_SIZE - sizeof(uint32_t)
- static int32_t __foreach_handler_libWriteIndex(Arg* argEach,
- PikaLinker* linker) {
- Args buffs = {0};
- if (arg_isObject(argEach)) {
- PikaObj* module_obj = arg_getPtr(argEach);
- uint32_t bytecode_size = obj_getInt(module_obj, "bytesize");
- char* module_name = obj_getStr(module_obj, "name");
- module_name = strsReplace(&buffs, module_name, "|", ".");
- uint32_t name_size = strGetSize(module_name);
- char* block_buff = (char*)pikaMalloc(linker->block_size);
- pika_platform_memset(block_buff, 0x00, linker->block_size);
- /*
- *create the block as [name][bytecode_size]
- * the space of name is LIB_INFO_BLOCK_SIZE - sizeof(bytecode_size)
- */
- pika_platform_memcpy(block_buff, module_name,
- name_size + 1); /* add '\0' after name */
- /* should write the size without align */
- pika_platform_memcpy(block_buff + linker->block_size - sizeof(uint32_t),
- &bytecode_size, sizeof(uint32_t));
- /* write the block to file */
- linker_fwrite(linker, (uint8_t*)block_buff, linker->block_size);
- pikaFree(block_buff, linker->block_size);
- }
- strsDeinit(&buffs);
- return 0;
- }
- static int32_t __foreach_handler_selectBlockSize(Arg* argEach,
- PikaLinker* linker) {
- uint32_t block_size = 0; /* block_size is the size of file info */
- if (arg_isObject(argEach)) {
- PikaObj* module_obj = arg_getPtr(argEach);
- /* namelen(aligned by 4bytes) and bytecode_size(uint32_t) */
- block_size =
- align_by(obj_getInt(module_obj, "namelen"), 4) + sizeof(uint32_t);
- if (block_size > linker->block_size) {
- // block_size should support the langest module name
- linker->block_size = block_size;
- }
- }
- return 0;
- }
- static int32_t __foreach_handler_libSumSize(Arg* argEach, PikaLinker* linker) {
- if (arg_isObject(argEach)) {
- PikaObj* module_obj = arg_getPtr(argEach);
- /* namelen(aligned by 4bytes) and bytecode_size(uint32_t) */
- uint32_t bytecode_size =
- obj_getInt(module_obj, "bytesize"); /* size of every module obj */
- /* align the bytecode_size by 4 bytes */
- linker->sum_size += align_by(bytecode_size, 4);
- }
- return 0;
- }
- static int32_t __foreach_handler_getModuleNum(Arg* argEach,
- PikaLinker* linker) {
- if (arg_isObject(argEach)) {
- linker->module_num++;
- }
- return 0;
- }
- int LibObj_linkFile(LibObj* self, char* output_file_name) {
- FILE* out_file = pika_platform_fopen(output_file_name, "wb+");
- PikaLinker linker = {0};
- linker.block_size = 64; /* 64 is the default block size */
- linker.out_file = out_file;
- /* write meta information */
- args_foreach(self->list, (fn_args_foreach)__foreach_handler_getModuleNum,
- &linker);
- /* select block size of pya */
- args_foreach(self->list, (fn_args_foreach)__foreach_handler_selectBlockSize,
- &linker);
- /* get sum size of pya */
- args_foreach(self->list, (fn_args_foreach)__foreach_handler_libSumSize,
- &linker);
- /* meta info */
- char magic_code[] = {0x0f, 'p', 'y', 'a'};
- uint32_t version_num = LIB_VERSION_NUMBER;
- uint32_t module_num = linker.module_num;
- uint32_t modules_size = linker.sum_size;
- uint32_t block_size = linker.block_size;
- uint32_t totle_size = block_size * (module_num + 1) + modules_size;
- uint8_t* meta_block_buff = pikaMalloc(block_size);
- pika_platform_memset(meta_block_buff, 0, block_size);
- /* write meta info */
- const uint32_t magic_code_offset =
- sizeof(uint32_t) * PIKA_APP_MAGIC_CODE_OFFSET;
- const uint32_t totle_size_offset =
- sizeof(uint32_t) * PIKA_APP_MODULE_SIZE_OFFSET;
- const uint32_t version_offset = sizeof(uint32_t) * PIKA_APP_VERSION_OFFSET;
- const uint32_t module_num_offset =
- sizeof(uint32_t) * PIKA_APP_MODULE_NUM_OFFSET;
- const uint32_t info_block_size_offset =
- sizeof(uint32_t) * PIKA_APP_INFO_BLOCK_SIZE_OFFSET;
- // the meta info is the first block
- pika_platform_memcpy(meta_block_buff + magic_code_offset, &magic_code,
- sizeof(uint32_t));
- pika_platform_memcpy(meta_block_buff + version_offset, &version_num,
- sizeof(uint32_t));
- /* write module_num to the file */
- pika_platform_memcpy(meta_block_buff + module_num_offset, &module_num,
- sizeof(uint32_t));
- /* write modules_size to the file */
- pika_platform_memcpy(meta_block_buff + totle_size_offset, &totle_size,
- sizeof(uint32_t));
- /* write block_size to the file */
- pika_platform_memcpy(meta_block_buff + info_block_size_offset, &block_size,
- sizeof(uint32_t));
- linker_fwrite(&linker, meta_block_buff, block_size);
- /* write module index to file */
- args_foreach(self->list, (fn_args_foreach)__foreach_handler_libWriteIndex,
- &linker);
- /* write module bytecode to file */
- args_foreach(self->list,
- (fn_args_foreach)__foreach_handler_libWriteBytecode, &linker);
- /* main process */
- /* deinit */
- pika_platform_fclose(out_file);
- pikaFree(meta_block_buff, block_size);
- pika_assert(totle_size == linker.written_size);
- return 0;
- }
- static int _getModuleNum(uint8_t* library_bytes) {
- if (0 != ((intptr_t)library_bytes & 0x03)) {
- return PIKA_RES_ERR_UNALIGNED_PTR;
- }
- char* magic_code = (char*)library_bytes;
- uint32_t* library_info = (uint32_t*)library_bytes;
- uint32_t version_num = library_info[PIKA_APP_VERSION_OFFSET];
- uint32_t module_num = library_info[PIKA_APP_MODULE_NUM_OFFSET];
- /* check magic_code */
- if (!((magic_code[0] == 0x0f) && (magic_code[1] == 'p') &&
- (magic_code[2] == 'y') && (magic_code[3] == 'a'))) {
- pika_platform_printf("Error: invalid magic code.\r\n");
- return PIKA_RES_ERR_ILLEGAL_MAGIC_CODE;
- }
- /* check version num */
- if (version_num != LIB_VERSION_NUMBER) {
- pika_platform_printf(
- "Error: invalid version number. Expected %d, got %d\r\n",
- LIB_VERSION_NUMBER, version_num);
- pika_platform_printf(
- "Please run the 'rus-msc-latest-win10.exe' again to update the "
- "version of compiled library.\r\n");
- return PIKA_RES_ERR_INVALID_VERSION_NUMBER;
- }
- return module_num;
- }
- #define MOD_NAMELEN_OFFSET 0
- #define MOD_NAME_OFFSET 4
- #define MOD_SIZE_OFFSET (name_len + 5) /* 5 = 4 + 1*/
- static PIKA_RES _loadModuleDataWithIndex(uint8_t* library_bytes,
- int module_num,
- int module_index,
- char** name_p,
- uint8_t** addr_p,
- size_t* size) {
- uint32_t block_size = *(uint32_t*)(library_bytes + 4 * sizeof(uint32_t));
- uint8_t* file_info_block_start = library_bytes + block_size;
- uint8_t* bytecode_ptr = file_info_block_start + block_size * module_num;
- uint8_t* bytecode_ptr_next = bytecode_ptr;
- uint32_t module_size = 0;
- char* module_name = NULL;
- uintptr_t offset = 0;
- for (uint32_t i = 0; i < module_index + 1; i++) {
- uint8_t* file_info_block = file_info_block_start + offset;
- module_name = (char*)(file_info_block);
- module_size =
- *(uint32_t*)(file_info_block + block_size - sizeof(uint32_t));
- bytecode_ptr = bytecode_ptr_next;
- offset += block_size;
- /* next module ptr, align by 4 bytes */
- bytecode_ptr_next += align_by(module_size, 4);
- }
- *name_p = module_name;
- *addr_p = bytecode_ptr;
- *size = module_size;
- /* fix size for string */
- PIKA_BOOL bIsString = PIKA_TRUE;
- for (size_t i = 0; i < module_size - 1; ++i) {
- if (bytecode_ptr[i] == 0) {
- bIsString = PIKA_FALSE;
- break;
- }
- }
- if (bIsString) {
- /* remove the last '\0' for stirng */
- if (bytecode_ptr[module_size - 1] == 0) {
- *size -= 1;
- }
- }
- return PIKA_RES_OK;
- }
- PIKA_RES _loadModuleDataWithName(uint8_t* library_bytes,
- char* module_name,
- uint8_t** addr_p,
- size_t* size_p) {
- int module_num = _getModuleNum(library_bytes);
- if (module_num < 0) {
- return (PIKA_RES)module_num;
- }
- Args buffs = {0};
- for (int i = 0; i < module_num; i++) {
- char* name = NULL;
- uint8_t* addr = NULL;
- size_t size = 0;
- _loadModuleDataWithIndex(library_bytes, module_num, i, &name, &addr,
- &size);
- name = strsGetLastToken(&buffs, name, '/');
- if (strEqu(module_name, name)) {
- *addr_p = addr;
- *size_p = size;
- strsDeinit(&buffs);
- return PIKA_RES_OK;
- }
- }
- strsDeinit(&buffs);
- return PIKA_RES_ERR_ARG_NO_FOUND;
- }
- Arg* _getPack_libraryBytes(char* pack_name) {
- if (NULL == pack_name) {
- pika_platform_printf(
- "[%s - %d]What I freakin' need is a damn pack file name! Why the "
- "hell did you give me a goddamn NULL?!\r\n",
- __FILE__, __LINE__);
- return NULL;
- }
- Arg* f_arg = NULL;
- f_arg = arg_loadFile(NULL, pack_name);
- if (NULL == f_arg) {
- pika_platform_printf("Error: Could not load file \'%s\'\r\n",
- pack_name);
- // pikaFree(*fp, sizeof(pikafs_FILE));
- // arg_deinit(f_arg);
- return NULL;
- }
- return f_arg;
- }
- typedef struct {
- char* module_name;
- PikaObj* module;
- } Context_LibObj_getModule;
- int32_t _handler_LibObj_getModule(Arg* argEach, void* context) {
- Context_LibObj_getModule* ctx = context;
- if (NULL != ctx->module) {
- return 0;
- }
- if (arg_isObject(argEach)) {
- PikaObj* module_obj = arg_getPtr(argEach);
- if (strEqu(obj_getStr(module_obj, "name"), ctx->module_name)) {
- ctx->module = module_obj;
- return 0;
- }
- }
- return 0;
- }
- PikaObj* LibObj_getModule(LibObj* self, char* module_name) {
- Context_LibObj_getModule context = {0};
- context.module_name = module_name;
- args_foreach(self->list, _handler_LibObj_getModule, &context);
- return context.module;
- }
- /*
- redirect import to module
- example:
- when IMP XXX.YYY.ZZZ and ZZZ is a calss
- then redirect to IMP XXX.YYY
- */
- char* LibObj_redirectModule(LibObj* self, Args* buffs_out, char* module_name) {
- if (NULL == self) {
- return NULL;
- }
- char* module_name_new = NULL;
- PikaObj* module_obj = NULL;
- Args buffs = {0};
- size_t token_num = strCountSign(module_name, '.');
- if (0 == token_num) {
- goto __exit;
- }
- module_obj = LibObj_getModule(self, module_name);
- if (NULL != module_obj) {
- module_name_new = module_name;
- goto __exit;
- }
- module_name_new = strsCopy(&buffs, module_name);
- for (int i = 0; i < token_num + 1; i++) {
- PikaObj* module_obj = LibObj_getModule(self, module_name_new);
- if (NULL != module_obj) {
- goto __exit;
- }
- strPopLastToken(module_name_new, '.');
- }
- __exit:
- if (NULL != module_name_new) {
- module_name_new = strsCopy(buffs_out, module_name_new);
- }
- strsDeinit(&buffs);
- return module_name_new;
- }
- int LibObj_loadLibrary(LibObj* self, uint8_t* library_bytes) {
- int module_num = _getModuleNum(library_bytes);
- if (module_num < 0) {
- /* load error */
- return module_num;
- }
- for (uint32_t i = 0; i < module_num; i++) {
- char* module_name = NULL;
- uint8_t* bytecode_addr = NULL;
- size_t bytecode_size = 0;
- _loadModuleDataWithIndex(library_bytes, module_num, i, &module_name,
- &bytecode_addr, &bytecode_size);
- LibObj_dynamicLink(self, module_name, bytecode_addr);
- }
- obj_setPtr(self, "@libraw", library_bytes);
- return PIKA_RES_OK;
- }
- int32_t __foreach_handler_printModule(Arg* argEach, void* context) {
- if (arg_isObject(argEach)) {
- PikaObj* module_obj = arg_getPtr(argEach);
- char* module_name = obj_getStr(module_obj, "name");
- if (NULL != module_name) {
- pika_platform_printf(module_name);
- pika_platform_printf("\r\n");
- }
- }
- return 0;
- }
- void LibObj_printModules(LibObj* self) {
- args_foreach(self->list, __foreach_handler_printModule, NULL);
- }
- int LibObj_loadLibraryFile(LibObj* self, char* lib_file_name) {
- Arg* aFile = arg_loadFile(NULL, lib_file_name);
- if (NULL == aFile) {
- pika_platform_printf("Error: Could not load library file '%s'\n",
- lib_file_name);
- return PIKA_RES_ERR_IO_ERROR;
- }
- /* save file_arg as @lib_buf to libObj */
- obj_setArg_noCopy(self, "@lib_buf", aFile);
- if (0 != LibObj_loadLibrary(self, arg_getBytes(aFile))) {
- pika_platform_printf("Error: Could not load library from '%s'\n",
- lib_file_name);
- return PIKA_RES_ERR_OPERATION_FAILED;
- }
- return PIKA_RES_OK;
- }
- /**
- * @brief unpack *.pack file to Specified path
- *
- * @param pack_name the name of *.pack file
- * @param out_path output path
- * @return
- */
- PIKA_RES pikafs_unpack_files(char* pack_name, char* out_path) {
- PIKA_RES stat = PIKA_RES_OK;
- Arg* file_arg = NULL;
- uint8_t* library_bytes = NULL;
- pikafs_FILE* fptr = NULL;
- if (NULL == out_path) {
- out_path = "./packout/";
- }
- file_arg = _getPack_libraryBytes(pack_name);
- if (NULL != file_arg) {
- library_bytes = arg_getBytes(file_arg);
- } else {
- return PIKA_RES_ERR_IO_ERROR;
- }
- int module_num = _getModuleNum(library_bytes);
- if (module_num < 0) {
- return (PIKA_RES)module_num;
- }
- Args buffs = {0};
- char* output_file_path = NULL;
- FILE* new_fp = NULL;
- char* name = NULL;
- uint8_t* addr = NULL;
- size_t size = 0;
- for (int i = 0; i < module_num; ++i) {
- size = 0;
- stat = _loadModuleDataWithIndex(library_bytes, module_num, i, &name,
- &addr, &size);
- name = strsGetLastToken(&buffs, name, '/');
- output_file_path = strsPathJoin(&buffs, out_path, name);
- pika_platform_printf("output_file_path: %s\r\n", output_file_path);
- new_fp = pika_platform_fopen(output_file_path, "wb+");
- if (NULL != new_fp) {
- pika_platform_fwrite(addr, size, 1, new_fp);
- pika_platform_fclose(new_fp);
- pika_platform_printf("unpack %s to %s\r\n", name, output_file_path);
- } else {
- pika_platform_printf("can't open %s\r\n", output_file_path);
- stat = PIKA_RES_ERR_IO_ERROR;
- break;
- }
- }
- arg_deinit(file_arg);
- strsDeinit(&buffs);
- pikaFree(fptr, sizeof(pikafs_FILE));
- return stat;
- }
- size_t pika_fputs(char* str, FILE* fp) {
- size_t size = strGetSize(str);
- return pika_platform_fwrite(str, 1, size, fp);
- }
- int Lib_loadLibraryFileToArray(char* origin_file_name, char* out_folder) {
- Args buffs = {0};
- Arg* file_arg = arg_loadFile(NULL, origin_file_name);
- int res = 0;
- if (NULL == file_arg) {
- pika_platform_printf("Error: Could not load file '%s'\n",
- origin_file_name);
- return 1;
- }
- char* output_file_name = NULL;
- output_file_name = strsGetLastToken(&buffs, origin_file_name, '/');
- output_file_name = strsAppend(&buffs, "__asset_", output_file_name);
- output_file_name = strsReplace(&buffs, output_file_name, ".", "_");
- output_file_name = strsAppend(&buffs, output_file_name, ".c");
- char* output_file_path = strsPathJoin(&buffs, out_folder, output_file_name);
- FILE* fp = pika_platform_fopen(output_file_path, "wb+");
- char* array_name = strsGetLastToken(&buffs, origin_file_name, '/');
- array_name = strsReplace(&buffs, array_name, ".", "_");
- pika_platform_printf(" loading %s[]...\n", array_name);
- pika_fputs("#include \"PikaPlatform.h\"\n", fp);
- pika_fputs("/* warning: auto generated file, please do not modify */\n",
- fp);
- pika_fputs("PIKA_BYTECODE_ALIGN const unsigned char ", fp);
- pika_fputs(array_name, fp);
- pika_fputs("[] = {", fp);
- char byte_buff[32] = {0};
- uint8_t* array = arg_getBytes(file_arg);
- for (size_t i = 0; i < arg_getBytesSize(file_arg); i++) {
- if (i % 12 == 0) {
- pika_fputs("\n ", fp);
- }
- pika_sprintf(byte_buff, "0x%02x, ", array[i]);
- pika_fputs(byte_buff, fp);
- }
- pika_fputs("\n};\n", fp);
- res = 0;
- goto __exit;
- __exit:
- pika_platform_fclose(fp);
- strsDeinit(&buffs);
- arg_deinit(file_arg);
- return res;
- }
- static PIKA_RES __Maker_compileModuleWithInfo(PikaMaker* self,
- char* module_name) {
- Args buffs = {0};
- char* input_file_name = strsReplace(&buffs, module_name, ".", "/");
- input_file_name = strsAppend(&buffs, input_file_name, ".py");
- char* input_file_path =
- strsPathJoin(&buffs, obj_getStr(self, "pwd"), input_file_name);
- pika_platform_printf(" compiling %s...\r\n", input_file_name);
- char* output_file_name = strsAppend(&buffs, module_name, ".py.o");
- char* output_file_path = NULL;
- output_file_path =
- strsPathJoin(&buffs, obj_getStr(self, "pwd"), "pikascript-api");
- output_file_path = strsPathJoin(&buffs, output_file_path, output_file_name);
- PIKA_RES res =
- pikaCompileFileWithOutputName(output_file_path, input_file_path);
- strsDeinit(&buffs);
- return res;
- }
- PikaMaker* New_PikaMaker(void) {
- PikaMaker* self = New_PikaObj(NULL);
- obj_setStr(self, "pwd", "");
- obj_setInt(self, "err", 0);
- LibObj* lib = New_LibObj(NULL);
- obj_setPtr(self, "lib", lib);
- return self;
- }
- /*
- * @brief: deinit PikaMaker
- * @param: self PikaMaker
- * @return: void
- */
- void pikaMaker_deinit(PikaMaker* self) {
- LibObj* lib = obj_getPtr(self, "lib");
- LibObj_deinit(lib);
- obj_deinit(self);
- }
- /*
- * @brief: set pwd
- * @param: self PikaMaker
- * @param: pwd
- * @return: void
- */
- void pikaMaker_setPWD(PikaMaker* self, char* pwd) {
- obj_setStr(self, "pwd", pwd);
- }
- /*
- * @brief: set state
- * @param: self PikaMaker
- * @param: module_name
- * @param: state
- * @return: void
- */
- void pikaMaker_setState(PikaMaker* self, char* module_name, char* state) {
- Args buffs = {0};
- char* module_obj_name = strsReplace(&buffs, module_name, ".", "|");
- obj_newMetaObj(self, module_obj_name, New_TinyObj);
- PikaObj* module_obj = obj_getObj(self, module_obj_name);
- obj_setStr(module_obj, "name", module_name);
- obj_setStr(module_obj, "state", state);
- strsDeinit(&buffs);
- }
- char* pikaMaker_getState(PikaMaker* self, char* module_name) {
- PikaObj* module_obj = obj_getObj(self, module_name);
- if (NULL == module_obj) {
- return "nocompiled";
- }
- return obj_getStr(module_obj, "state");
- }
- /*
- * @brief: compile module
- * @param: self PikaMaker
- * @param: module_name
- * @return: PIKA_RES
- */
- PIKA_RES pikaMaker_compileModule(PikaMaker* self, char* module_name) {
- PIKA_RES res = __Maker_compileModuleWithInfo(self, module_name);
- /* update compile info */
- if (PIKA_RES_OK == res) {
- pikaMaker_setState(self, module_name, "compiled");
- } else {
- pikaMaker_setState(self, module_name, "failed");
- }
- return res;
- }
- enum PIKA_MODULE_TYPE {
- PIKA_MODULE_TYPE_UNKNOWN,
- PIKA_MODULE_TYPE_PY,
- PIKA_MODULE_TYPE_PYI,
- PIKA_MODULE_TYPE_PYO
- };
- static enum PIKA_MODULE_TYPE _checkModuleType(char* module_path) {
- Args buffs = {0};
- enum PIKA_MODULE_TYPE module_type = PIKA_MODULE_TYPE_UNKNOWN;
- /* module info is not exist */
- /* set module to be compile */
- FILE* imp_file_py =
- pika_platform_fopen(strsAppend(&buffs, module_path, ".py"), "rb");
- FILE* imp_file_pyi =
- pika_platform_fopen(strsAppend(&buffs, module_path, ".pyi"), "rb");
- FILE* imp_file_pyo =
- pika_platform_fopen(strsAppend(&buffs, module_path, ".py.o"), "rb");
- if (NULL != imp_file_pyo) {
- module_type = PIKA_MODULE_TYPE_PYO;
- goto __exit;
- }
- if (NULL != imp_file_py) {
- module_type = PIKA_MODULE_TYPE_PY;
- goto __exit;
- }
- if (NULL != imp_file_pyi) {
- module_type = PIKA_MODULE_TYPE_PYI;
- goto __exit;
- }
- __exit:
- if (NULL != imp_file_pyo) {
- pika_platform_fclose(imp_file_pyo);
- }
- if (NULL != imp_file_pyi) {
- pika_platform_fclose(imp_file_pyi);
- }
- if (NULL != imp_file_py) {
- pika_platform_fclose(imp_file_py);
- }
- strsDeinit(&buffs);
- return module_type;
- }
- static char* _redirectModuleFromFs(Args* buffs_out,
- char* module_path,
- char* module_name) {
- Args buffs = {0};
- size_t token_num = strCountSign(module_name, '.');
- char* module_name_new = NULL;
- char* module_try = NULL;
- if (0 == token_num) {
- goto __exit;
- }
- module_try = strsCopy(&buffs, module_path);
- module_name_new = strsCopy(&buffs, module_name);
- for (int i = 0; i < token_num + 1; i++) {
- enum PIKA_MODULE_TYPE module_type = _checkModuleType(module_try);
- if (module_type != PIKA_MODULE_TYPE_UNKNOWN) {
- char* module_name = module_try;
- if (NULL != module_name) {
- goto __exit;
- }
- }
- strPopLastToken(module_try, '/');
- strPopLastToken(module_name_new, '.');
- }
- module_path = NULL;
- __exit:
- if (NULL != module_name_new) {
- module_name_new = strsCopy(buffs_out, module_name_new);
- }
- strsDeinit(&buffs);
- return module_name_new;
- }
- FILE* _openModuleFile(char* module_path, enum PIKA_MODULE_TYPE module_type) {
- Args buffs = {0};
- FILE* fp = NULL;
- switch (module_type) {
- case PIKA_MODULE_TYPE_PY:
- fp = pika_platform_fopen(strsAppend(&buffs, module_path, ".py"),
- "rb");
- break;
- case PIKA_MODULE_TYPE_PYI:
- fp = pika_platform_fopen(strsAppend(&buffs, module_path, ".pyi"),
- "rb");
- break;
- case PIKA_MODULE_TYPE_PYO:
- fp = pika_platform_fopen(strsAppend(&buffs, module_path, ".py.o"),
- "rb");
- break;
- default:
- break;
- }
- strsDeinit(&buffs);
- return fp;
- }
- int pikaMaker_linkByteocdeFile(PikaMaker* self, char* imp_module_name) {
- Args buffs = {0};
- char* imp_module_path =
- strsPathJoin(&buffs, obj_getStr(self, "pwd"), imp_module_name);
- FILE* imp_file = _openModuleFile(imp_module_path, PIKA_MODULE_TYPE_PYO);
- pika_platform_printf(" loading %s.py.o...\r\n", imp_module_path);
- /* found *.py.o, push to compiled list */
- pikaMaker_setState(self, imp_module_name, "compiled");
- char* imp_api_path =
- strsPathJoin(&buffs, obj_getStr(self, "pwd"), "pikascript-api/");
- imp_api_path = strsPathJoin(&buffs, imp_api_path, imp_module_name);
- FILE* imp_file_pyo_api =
- pika_platform_fopen(strsAppend(&buffs, imp_api_path, ".py.o"), "wb+");
- pika_assert(imp_file_pyo_api != NULL);
- /* copy imp_file_pyo to imp_api_path */
- uint8_t* buff = (uint8_t*)pika_platform_malloc(128);
- size_t read_size = 0;
- while (1) {
- read_size = pika_platform_fread(buff, 1, 128, imp_file);
- if (read_size > 0) {
- pika_platform_fwrite(buff, 1, read_size, imp_file_pyo_api);
- } else {
- break;
- }
- }
- pika_platform_free(buff);
- pika_platform_fclose(imp_file_pyo_api);
- pika_platform_fclose(imp_file);
- strsDeinit(&buffs);
- return 0;
- }
- int pikaMaker_getDependencies(PikaMaker* self, char* module_name) {
- int res = 0;
- ByteCodeFrame bf = {0};
- Args buffs = {0};
- byteCodeFrame_init(&bf);
- ConstPool* const_pool = NULL;
- InstructArray* ins_array = NULL;
- char* module_path =
- strsPathJoin(&buffs, obj_getStr(self, "pwd"), "pikascript-api/");
- module_path = strsPathJoin(&buffs, module_path, module_name);
- char* file_path = strsAppend(&buffs, module_path, ".py.o");
- Arg* file_arg = arg_loadFile(NULL, file_path);
- uint8_t offset_befor = 0;
- if (NULL == file_arg) {
- pika_platform_printf("Error: Could not load file '%s'\n", file_path);
- res = 1;
- goto __exit;
- }
- byteCodeFrame_loadByteCode(&bf, arg_getBytes(file_arg));
- const_pool = &bf.const_pool;
- ins_array = &bf.instruct_array;
- offset_befor = ins_array->content_offset_now;
- ins_array->content_offset_now = 0;
- while (1) {
- InstructUnit* ins_unit = instructArray_getNow(ins_array);
- if (NULL == ins_unit) {
- goto __exit;
- }
- if (instructUnit_getInstructIndex(ins_unit) == PIKA_INS(IMP) ||
- instructUnit_getInstructIndex(ins_unit) == PIKA_INS(INH)) {
- char* imp_module_name =
- constPool_getByOffset(const_pool, ins_unit->const_pool_index);
- char* imp_module_name_fs =
- strsReplace(&buffs, imp_module_name, ".", "/");
- char* imp_module_path = strsPathJoin(
- &buffs, obj_getStr(self, "pwd"), imp_module_name_fs);
- char* imp_module_name_redirect =
- _redirectModuleFromFs(&buffs, imp_module_path, imp_module_name);
- if (NULL != imp_module_name_redirect) {
- /* redirect to real module */
- imp_module_name = imp_module_name_redirect;
- imp_module_name_fs =
- strsReplace(&buffs, imp_module_name, ".", "/");
- imp_module_path = strsPathJoin(&buffs, obj_getStr(self, "pwd"),
- imp_module_name_fs);
- }
- /* check if compiled the module */
- if (args_isArgExist(self->list, imp_module_name)) {
- /* module info is exist, do nothing */
- } else {
- /* module info is not exist */
- /* set module to be compile */
- enum PIKA_MODULE_TYPE module_type =
- _checkModuleType(imp_module_path);
- if (module_type == PIKA_MODULE_TYPE_PYO) {
- pikaMaker_linkByteocdeFile(self, imp_module_path);
- } else if (module_type == PIKA_MODULE_TYPE_PY) {
- /* found *.py, push to nocompiled list */
- pikaMaker_setState(self, imp_module_name, "nocompiled");
- } else if (module_type == PIKA_MODULE_TYPE_PYI) {
- /* found *.py, push to nocompiled list */
- pikaMaker_setState(self, imp_module_name, "cmodule");
- } else {
- pika_platform_printf(
- " [warning]: file: '%s.pyi', '%s.py' or '%s.py.o' "
- "no found\n",
- imp_module_name_fs, imp_module_name_fs,
- imp_module_name_fs);
- }
- }
- }
- instructArray_getNext(ins_array);
- }
- __exit:
- if (NULL != ins_array) {
- ins_array->content_offset_now = offset_befor;
- }
- if (NULL != file_arg) {
- arg_deinit(file_arg);
- }
- strsDeinit(&buffs);
- byteCodeFrame_deinit(&bf);
- return res;
- }
- int32_t __foreach_handler_printStates(Arg* argEach, void* context) {
- if (arg_isObject(argEach)) {
- PikaObj* module_obj = arg_getPtr(argEach);
- pika_platform_printf("%s: %s\r\n", obj_getStr(module_obj, "name"),
- obj_getStr(module_obj, "state"));
- }
- return 0;
- }
- void pikaMaker_printStates(PikaMaker* self) {
- args_foreach(self->list, __foreach_handler_printStates, NULL);
- }
- int32_t __foreach_handler_getFirstNocompiled(Arg* argEach, void* context) {
- if (arg_isObject(argEach)) {
- PikaObj* module_obj = arg_getPtr(argEach);
- char* state = obj_getStr(module_obj, "state");
- if (args_isArgExist((Args*)context, "res")) {
- /* already get method */
- return 0;
- }
- if (strEqu("nocompiled", state)) {
- /* push module */
- args_setStr((Args*)context, "res", obj_getStr(module_obj, "name"));
- return 0;
- }
- }
- return 0;
- }
- char* pikaMaker_getFirstNocompiled(PikaMaker* self) {
- Args context = {0};
- args_foreach(self->list, __foreach_handler_getFirstNocompiled, &context);
- char* res = args_getStr(&context, "res");
- if (NULL == res) {
- /* remove res in maker */
- obj_removeArg(self, "res");
- } else {
- obj_setStr(self, "res", res);
- }
- args_deinit_stack(&context);
- return obj_getStr(self, "res");
- }
- /*
- * @brief compile module with depends
- * @param self PikaMaker
- * @param module_name
- * @return PIKA_RES
- */
- PIKA_RES pikaMaker_compileModuleWithDepends(PikaMaker* self,
- char* module_name) {
- PIKA_RES res = PIKA_RES_OK;
- if (!strEqu("nocompiled", pikaMaker_getState(self, module_name))) {
- return PIKA_RES_OK;
- }
- res = pikaMaker_compileModule(self, module_name);
- if (PIKA_RES_OK != res) {
- obj_setInt(self, "err", res);
- return res;
- }
- pikaMaker_getDependencies(self, module_name);
- while (1) {
- char* uncompiled = pikaMaker_getFirstNocompiled(self);
- /* compiled all modules */
- if (NULL == uncompiled) {
- break;
- }
- res = pikaMaker_compileModule(self, uncompiled);
- if (PIKA_RES_OK != res) {
- obj_setInt(self, "err", res);
- return res;
- }
- pikaMaker_getDependencies(self, uncompiled);
- }
- return PIKA_RES_OK;
- }
- PIKA_RES pikaMaker_compileModuleWithList(PikaMaker* self, char* list_content) {
- PIKA_RES res = PIKA_RES_OK;
- Args buffs = {0};
- char* module_name = NULL;
- char* module_name_start = list_content;
- char* module_name_end = NULL;
- pika_platform_printf(" <module list>\r\n");
- while (1) {
- module_name_end = strFind(module_name_start, '\n');
- if (NULL == module_name_end) {
- break;
- }
- module_name = strsSubStr(&buffs, module_name_start, module_name_end);
- if (!strIsBlank(module_name)) {
- pika_platform_printf(" - %s\r\n", module_name);
- }
- module_name_start = module_name_end + 1;
- }
- module_name_start = list_content;
- while (1) {
- module_name_end = strFind(module_name_start, '\n');
- if (NULL == module_name_end) {
- break;
- }
- module_name = strsSubStr(&buffs, module_name_start, module_name_end);
- if (!strIsBlank(module_name)) {
- char* module_name_fs = strsReplace(&buffs, module_name, ".", "/");
- enum PIKA_MODULE_TYPE module_type =
- _checkModuleType(module_name_fs);
- if (module_type == PIKA_MODULE_TYPE_PY) {
- res = pikaMaker_compileModuleWithDepends(self, module_name);
- if (PIKA_RES_OK != res) {
- obj_setInt(self, "err", res);
- goto __exit;
- }
- }
- if (module_type == PIKA_MODULE_TYPE_PYO) {
- pikaMaker_linkByteocdeFile(self, module_name);
- }
- if (module_type == PIKA_MODULE_TYPE_UNKNOWN) {
- pika_platform_printf(
- " [warning]: file: '%s.pyi', '%s.py' or '%s.py.o' "
- "no found\n",
- module_name, module_name, module_name);
- }
- }
- module_name_start = module_name_end + 1;
- }
- __exit:
- strsDeinit(&buffs);
- return PIKA_RES_OK;
- }
- PIKA_RES pikaMaker_compileModuleWithListFile(PikaMaker* self,
- char* list_file_name) {
- Args buffs = {0};
- PIKA_RES res = PIKA_RES_OK;
- char* folder_path =
- strsPathJoin(&buffs, obj_getStr(self, "pwd"), "pikascript-api/");
- char* list_file_path = strsPathJoin(&buffs, folder_path, list_file_name);
- char* list_file_content = NULL;
- pika_platform_printf(" loading %s...\r\n", list_file_name);
- Arg* list_file_arg = arg_loadFile(NULL, list_file_path);
- if (NULL == list_file_arg) {
- pika_platform_printf("Error: Could not load file '%s'\n",
- list_file_path);
- res = PIKA_RES_ERR_IO_ERROR;
- goto __exit;
- }
- list_file_content = (char*)arg_getBytes(list_file_arg);
- list_file_content = strsFilePreProcess_ex(&buffs, list_file_content, "\n");
- res = pikaMaker_compileModuleWithList(self, list_file_content);
- goto __exit;
- __exit:
- strsDeinit(&buffs);
- return res;
- }
- int32_t __foreach_handler_linkCompiledModules(Arg* argEach, void* context) {
- Args buffs = {0};
- if (arg_isObject(argEach)) {
- LibObj* lib = args_getPtr((Args*)context, "@lib");
- PikaMaker* maker = args_getPtr((Args*)context, "__maker");
- PikaObj* module_obj = arg_getPtr(argEach);
- char* module_name = obj_getStr(module_obj, "name");
- char* state = obj_getStr(module_obj, "state");
- if (strEqu(state, "compiled")) {
- char* pwd = obj_getStr(maker, "pwd");
- char* folder_path = strsPathJoin(&buffs, pwd, "pikascript-api/");
- char* module_file_name = strsAppend(&buffs, module_name, ".py.o");
- char* module_file_path =
- strsPathJoin(&buffs, folder_path, module_file_name);
- LibObj_staticLinkFile(lib, module_file_path);
- }
- }
- strsDeinit(&buffs);
- return 0;
- }
- PIKA_RES _do_pikaMaker_linkCompiledModulesFullPath(PikaMaker* self,
- char* lib_path,
- pika_bool gen_c_array) {
- PIKA_RES compile_err = (PIKA_RES)obj_getInt(self, "err");
- if (PIKA_RES_OK != compile_err) {
- pika_platform_printf(" Error: compile failed, link aborted.\r\n");
- return compile_err;
- }
- Args context = {0};
- Args buffs = {0};
- pika_platform_printf(" linking %s...\n", lib_path);
- LibObj* lib = obj_getPtr(self, "lib");
- args_setPtr(&context, "@lib", lib);
- args_setPtr(&context, "__maker", self);
- args_foreach(self->list, __foreach_handler_linkCompiledModules, &context);
- args_deinit_stack(&context);
- char* pwd = obj_getStr(self, "pwd");
- char* lib_path_folder = strsPathGetFolder(&buffs, lib_path);
- char* folder_path = strsPathJoin(&buffs, pwd, lib_path_folder);
- char* lib_file_path = strsPathJoin(&buffs, pwd, lib_path);
- LibObj_linkFile(lib, lib_file_path);
- if (gen_c_array) {
- Lib_loadLibraryFileToArray(lib_file_path, folder_path);
- }
- strsDeinit(&buffs);
- return PIKA_RES_OK;
- }
- PIKA_RES pikaMaker_linkCompiledModulesFullPath(PikaMaker* self,
- char* lib_path) {
- return _do_pikaMaker_linkCompiledModulesFullPath(self, lib_path, pika_true);
- }
- PIKA_RES _do_pikaMaker_linkCompiledModules(PikaMaker* self,
- char* lib_name,
- pika_bool gen_c_array) {
- Args buffs = {0};
- char* lib_file_path = strsPathJoin(&buffs, "pikascript-api/", lib_name);
- PIKA_RES res = _do_pikaMaker_linkCompiledModulesFullPath(
- self, lib_file_path, gen_c_array);
- strsDeinit(&buffs);
- return res;
- }
- PIKA_RES pikaMaker_linkCompiledModules(PikaMaker* self, char* lib_name) {
- return _do_pikaMaker_linkCompiledModules(self, lib_name, pika_true);
- }
- /*
- * @brief link raw file to library
- * @param self PikaMaker
- * @param file_path
- * @return PIKA_RES
- */
- PIKA_RES pikaMaker_linkRaw(PikaMaker* self, char* file_path) {
- LibObj* lib = obj_getPtr(self, "lib");
- LibObj_staticLinkFile(lib, file_path);
- return PIKA_RES_OK;
- }
- /*
- * @brief link raw file to library
- * @param self PikaMaker
- * @param path of the file to be packed
- * @param path of the file in pikafs
- * @return PIKA_RES
- */
- PIKA_RES pikaMaker_linkRawWithPath(PikaMaker* self,
- char* file_path,
- char* pack_path) {
- LibObj* lib = obj_getPtr(self, "lib");
- PIKA_RES ret =
- (PIKA_RES)LibObj_staticLinkFileWithPath(lib, file_path, pack_path);
- return ret;
- }
- /*
- * @brief open file from library
- * @param file_name
- * @param mode "r" or "rb"
- * @return pikafs_FILE* or NULL if failed
- */
- pikafs_FILE* pikafs_fopen(char* file_name, char* mode) {
- pikafs_FILE* f = (pikafs_FILE*)pikaMalloc(sizeof(pikafs_FILE));
- if (NULL == f) {
- return NULL;
- }
- memset(f, 0, sizeof(pikafs_FILE));
- uint8_t* library_bytes = obj_getPtr(pika_getLibObj(), "@libraw");
- if (NULL == library_bytes) {
- goto __error;
- }
- if (PIKA_RES_OK !=
- _loadModuleDataWithName(library_bytes, file_name, &f->addr, &f->size)) {
- goto __error;
- }
- return f;
- __error:
- pikaFree(f, sizeof(pikafs_FILE));
- return NULL;
- }
- pikafs_FILE* pikafs_fopen_pack(char* pack_name, char* file_name) {
- pikafs_FILE* f = NULL;
- Arg* file_arg = NULL;
- uint8_t* library_bytes = NULL;
- f = (pikafs_FILE*)pikaMalloc(sizeof(pikafs_FILE));
- if (NULL == f) {
- pika_platform_printf("Error: malloc failed \r\n");
- goto __malloc_err;
- // return PIKA_RES_ERR_OUT_OF_RANGE;
- }
- memset(f, 0, sizeof(pikafs_FILE));
- file_arg = _getPack_libraryBytes(pack_name);
- if (NULL != file_arg) {
- library_bytes = arg_getBytes(file_arg);
- } else {
- goto __getpack_err;
- }
- if (PIKA_RES_OK !=
- _loadModuleDataWithName(library_bytes, file_name, &f->addr, &f->size)) {
- goto __exit;
- }
- f->farg = file_arg;
- return f;
- __exit:
- if (NULL != f->farg) {
- arg_deinit(f->farg);
- }
- __getpack_err:
- pikaFree(f, sizeof(pikafs_FILE));
- __malloc_err:
- return NULL;
- }
- /*
- * @brief read file
- * @param buf the buffer to read
- * @param size size of each item
- * @param count count of items
- * @param f file
- * @return read count
- */
- int pikafs_fread(void* buf, size_t size, size_t count, pikafs_FILE* f) {
- size_t read_len = size * count;
- if (f->pos >= f->size) {
- return 0;
- }
- if (f->pos + read_len > f->size) {
- read_len = f->size;
- }
- __platform_memcpy(buf, f->addr + f->pos, read_len);
- f->pos += read_len;
- size_t actual_count = read_len / size;
- return actual_count;
- }
- /*
- * @brief write file
- * @param buf the buffer to write
- * @param size size of each item
- * @param count count of items
- * @param f file
- * @return write count or -1 if failed
- */
- int pikafs_fwrite(void* buf, size_t size, size_t count, pikafs_FILE* file) {
- return -1;
- }
- /*
- * @brief close file
- * @param f file
- * @return 0 if success
- */
- int pikafs_fclose(pikafs_FILE* file) {
- if (file->need_free) {
- pikaFree(file->addr, file->size);
- }
- if (NULL != file->farg) {
- arg_deinit(file->farg);
- }
- pikaFree(file, sizeof(pikafs_FILE));
- return 0;
- }
|