Berry achieve: automatic expansion of the call stack

Outline

Call stack for local variables and all other functions during the execution of the call chain on call information stored function. Berry calls the call stack, stack refers specifically to the script, rather than the C call stack.

In be_vm.h can be seen in the fields VM structure and associated call stack:

struct bvm {
    // ...
    bvalue *stack; /* stack space */
    bvalue *stacktop; /* stack top register */
    bstack callstack; /* function call stack */
    // ...
};

stackAnd stacktopfor maintaining a local store stack variables (hereinafter referred to as "variable stack", refers to a function of stack space vm.stackfor a period of the function space is used), and callstackis a function of stack frame of the stack.

We use a simple script to explain the action of the field:

def func1(c)
    return c + 1
end

def func2(b)
    return func1(b) + 2
end

def func3(a)
    return func2(a) + 3
end

When we perform the func3(10)time, to perform func1the internal call chain up:

call stack top
+-------------------------+
|    function: func1      |
|  local variable(s): c   |
+-------------------------+
|    function: func2      |
|  local variable(s): b   |
+-------------------------+
|    function: func3      |
|  local variable(s): a   |
+-------------------------+
call stack base

Obviously, all local variables on the function call chain should be stored to ensure that the calling function can continue to be returned after the called function. All the local variables on the function call chain is arranged in a calling sequence, values of these variables are stored in vm.stackthe. So vm.stackis a bvaluearray. When the call reaches the deepest when the chain, the variables in the vm.stackarrangement is as follows:

stack index |    0    |    1    |    2    |
variable    | func3:a | func2:b | func1:c |  

Here we must note that vm.stackstored in the three variables belong to different functions, so to determine how each function in vm.stackoccupied those parts to store its local variables? The answer is a vm.callstackfield that is bstackthe type that stores elements bcallframetype. The latter is defined as follows:

typedef struct {
    bvalue *func; /* function register pointer */
    bvalue *top; /* top register pointer */
    bvalue *reg; /* base register pointer */
    binstruction *ip; /* instruction pointer (only berry-function) */
    int status;
} bcallframe;

The structure used to implement the stack frame function, the function of each field is:

  • func: Refers to the current in the calling function vm.stackthe position (before calling function will be pressed into the vm.stackmiddle).
  • top: The function stack pointer, pointing to vm.stacka location. Stack pointer always points to a function of the value after the last stack space.
  • reg: The function of the stack base pointer to vm.stacka location. Base pointer value points to a function of the position of the first stack space, which is always less than or equal function stack.
  • ip: Instruction pointer. VM is also a function of the current instruction pointer, the function call occurs, the function of the instruction pointer ganged need to be saved, and therefore set this field.
  • status: Some status flag for the function stack frame.

Have some information pressed into the virtual machine state and calling function of each function call occurs vm.callstackin order to be able to resume after the return to the state of the called function. This information includes the function stack base address, instruction pointer stack and the like.

Variable stack

Variable stack, which is vm.stackassigned when the VM is created, vm.stacktopfield points to vm.stackthe last element, it contains information on the total capacity of the stack variables. Berry variable stack supports dynamic expansion, when variable you just created a stack capacity is small in VM, and the implementation process will dynamically adjust. Stack expansion generally occurs when the function is called, the interpreter checks the function needs to decide whether to expand the capacity of the stack. If the expansion occurs perform the following process:

  1. Reallocate variable and copy the data stack.
  2. Update vm.callstackall of the elements func, topand regdomains.
  3. Update all open upvalue the valuedomain.

Wherein steps 2 and 3 mentioned structural point / variable references a value in the stack needs to be updated. Specific implementation can refer to be_stack_expansion()the source function.

Variable stack failure

Variable stack failure refers to a stack variable expansion leads element address has changed, and the stack pointer to the variable element has not updated so that while the program is running the wrong phenomenon. On GitHub AND DELINQUENCY # 42 also describes this problem.

Berry code itself may still exist some variables error stack failure. To avoid this problem, we summarize the situation may lead to failure of the stack variables:

  • Berry function call. A variety of API Berry function call occurs, and therefore there is a problem call stack failure.
  • be_val2str, be_tostring()Such as string conversion functions may call the instance tostringmethod.
  • You might call the destructor trigger GC, call stack failure may also occur.
  • GC GC may trigger when you create an object. Such actions include creating a string, closures, Map List, and the like.
  • Manual scaling variable stack occasion

The following cases do not consider the issue of the failure of the call stack:

  • Although the use of be_realloc()an interface ( be_malloc()may also be implemented by a trigger when it GC), but this case does not call the destructor, and therefore does not cause failure of the call stack.
  • Full use of Berry's public API (using BERRY_APImodified), this type of API instead of directly using an index using pointer variables, so do not worry about variable stack failure. In other words, only Berry internal code required to solve the problem of variable stack failure.

Guess you like

Origin www.cnblogs.com/skiars/p/12232625.html