| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- /*
- * 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 "dataStack.h"
- #include "PikaObj.h"
- #include "dataQueue.h"
- void _stack_overflow_handler(Stack* stack, size_t stack_require) {
- pika_platform_printf(
- "OverflowError: pika VM stack overflow, please use bigger "
- "PIKA_STACK_BUFF_SIZE\r\n");
- pika_platform_printf("Info: stack size request: %d\r\n",
- (int)stack_require);
- pika_platform_printf("Info: stack size now: %d\r\n",
- (int)stack->stack_totle_size);
- while (1) {
- }
- }
- uint8_t* stack_popPyload(Stack* stack, int32_t size);
- uint8_t* stack_getSpStart(Stack* stack) {
- return (uint8_t*)arg_getContent(stack->stack_pyload);
- }
- int32_t* stack_getSpSizeStart(Stack* stack) {
- return (int32_t*)arg_getContent(stack->stack_size_array);
- }
- uint32_t stack_spFree(Stack* stack) {
- return stack->stack_totle_size -
- ((uintptr_t)stack->sp - (uintptr_t)stack_getSpStart(stack));
- }
- uint32_t stack_spSizeFree(Stack* stack) {
- return stack->stack_totle_size / 4 -
- ((uintptr_t)stack->sp_size - (uintptr_t)stack_getSpSizeStart(stack));
- }
- void stack_reset(Stack* stack) {
- stack->sp = stack_getSpStart(stack);
- stack->sp_size = stack_getSpSizeStart(stack);
- stack->top = 0;
- }
- int32_t _stack_init(Stack* stack, size_t stack_size) {
- stack->stack_pyload = arg_setContent(NULL, NULL, stack_size);
- stack->stack_size_array = arg_setContent(NULL, NULL, stack_size / 4);
- stack_reset(stack);
- stack->stack_totle_size = stack_size;
- return 0;
- }
- int32_t stack_init(Stack* stack) {
- return _stack_init(stack, PIKA_STACK_BUFF_SIZE);
- };
- void stack_pushSize(Stack* stack, int32_t size) {
- *(stack->sp_size) = size;
- stack->sp_size++;
- if (stack_spSizeFree(stack) < sizeof(int32_t)) {
- _stack_overflow_handler(stack,
- stack->stack_totle_size + sizeof(int32_t) * 4);
- }
- }
- int32_t stack_popSize(Stack* stack) {
- stack->sp_size--;
- return *(stack->sp_size);
- }
- Arg* stack_checkArg(Stack* stack, int index) {
- if (stack->top - index <= 0) {
- return NULL;
- }
- int sp_offset = 0;
- int32_t size = 0;
- for (int i = 1; i <= index + 1; i++) {
- size = stack->sp_size[-i];
- if (size == -1) {
- sp_offset -= sizeof(Arg*);
- } else {
- sp_offset -= size;
- }
- }
- if (size == -1) {
- return *(Arg**)(stack->sp + sp_offset);
- }
- return (Arg*)(stack->sp + sp_offset);
- }
- int32_t stack_deinit(Stack* stack) {
- while (stack->top > 0) {
- int32_t size = stack_popSize(stack);
- uint8_t* pyload = stack_popPyload(stack, size);
- stack->top--;
- if (size == -1) {
- arg_deinit(*(Arg**)pyload);
- }
- }
- arg_deinit(stack->stack_pyload);
- arg_deinit(stack->stack_size_array);
- return 0;
- }
- void stack_pushPyload(Stack* stack,
- uint8_t* in,
- size_t size,
- pika_bool is_sample_copy) {
- size_t stack_require = size + (stack->sp - stack_getSpStart(stack));
- if (stack_require > stack->stack_totle_size) {
- _stack_overflow_handler(stack, stack_require);
- }
- Arg* top = (Arg*)stack->sp;
- if (is_sample_copy) {
- pika_platform_memcpy(top, in, size);
- } else {
- pika_platform_memcpy(top, in, sizeof(Arg));
- pika_platform_memcpy(top->content, ((Arg*)in)->_.buffer,
- size - sizeof(Arg));
- /* transfer to serialized form */
- arg_setSerialized(top, pika_true);
- }
- stack->sp += size;
- }
- uint8_t* stack_popPyload(Stack* stack, int32_t size) {
- if (size == -1) {
- size = sizeof(void*);
- }
- stack->sp -= size;
- return stack->sp;
- }
- static int32_t _stack_pushArg(Stack* stack, Arg* arg, pika_bool is_alloc) {
- pika_bool is_big_arg = pika_false;
- stack->top++;
- size_t size = arg_getTotleSize(arg);
- //! if you unsure about the __impl_pikaMalloc, uncomment this to force alignment
- #if PIKA_ARG_ALIGN_ENABLE
- /* force alignment to avoid unaligned access */
- size = (size + 4 - 1) & ~(4 - 1);
- #endif
- /* add ref_cnt to keep object in stack */
- arg_refcntInc(arg);
- if (arg_isSerialized(arg)) {
- is_big_arg = pika_true;
- }
- if (is_big_arg) {
- /* push a pointer to this arg */
- stack_pushSize(stack, -1);
- stack_pushPyload(stack, (uint8_t*)&arg, sizeof(Arg*), pika_true);
- } else {
- stack_pushSize(stack, size);
- stack_pushPyload(stack, (uint8_t*)arg, size,
- (pika_bool)arg_isSerialized(arg));
- }
- if (is_big_arg) {
- return 0;
- }
- if (is_alloc) {
- arg_deinit(arg);
- return 0;
- }
- arg_deinitHeap(arg);
- return 0;
- }
- int32_t stack_pushArg(Stack* stack, Arg* arg) {
- pika_assert(arg != NULL);
- if (arg_isObject(arg)) {
- pika_assert(obj_checkAlive(arg_getPtr(arg)));
- }
- if (arg_isSerialized(arg)) {
- return _stack_pushArg(stack, arg, pika_true);
- }
- return _stack_pushArg(stack, arg, pika_false);
- }
- int32_t stack_pushStr(Stack* stack, char* str) {
- Arg* newArg = arg_newStr(str);
- return stack_pushArg(stack, newArg);
- }
- Arg* _stack_popArg(Stack* stack, Arg* arg_dict, pika_bool is_alloc) {
- pika_bool is_big_arg = pika_false;
- if (stack->top == 0) {
- return NULL;
- }
- stack->top--;
- int32_t size = stack_popSize(stack);
- if (size == -1) {
- is_big_arg = pika_true;
- size = sizeof(Arg*);
- }
- Arg* arg = NULL;
- if (is_big_arg) {
- arg = *(Arg**)stack_popPyload(stack, size);
- } else {
- arg = (Arg*)stack_popPyload(stack, size);
- if (is_alloc) {
- arg = arg_copy(arg);
- } else {
- arg = arg_copy_noalloc(arg, arg_dict);
- }
- }
- /* decrase ref_cnt */
- arg_refcntDec(arg);
- pika_assert(arg->flag < ARG_FLAG_MAX);
- return arg;
- }
- Arg* stack_popArg_alloc(Stack* stack) {
- return _stack_popArg(stack, NULL, pika_true);
- }
- Arg* stack_popArg(Stack* stack, Arg* arg_dict) {
- return _stack_popArg(stack, arg_dict, pika_false);
- }
- char* stack_popStr(Stack* stack, char* outBuff) {
- Arg* arg = stack_popArg_alloc(stack);
- strcpy(outBuff, arg_getStr(arg));
- arg_deinit(arg);
- return outBuff;
- }
- int32_t stack_getTop(Stack* stack) {
- return stack->top;
- }
|