1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
package vm
import (
"jinx/pkg/lang/vm/mem"
"jinx/pkg/lang/vm/value"
)
func (vm *VM) popAndDrop() (value.Value, error) {
v, err := vm.stack.Pop()
if err != nil {
return value.Value{}, err
}
v.Drop(vm.memory)
return v, nil
}
func (vm *VM) popCallAndDrop() (int, error) {
envPtr := vm.stack.CurrentCallEnv()
vm.memory.Release(envPtr)
for !vm.stack.ReachedBaseOfCall() {
_, err := vm.popAndDrop()
if err != nil {
return 0, err
}
}
return vm.stack.PopCall()
}
func (vm *VM) getMemCell(ptr mem.Ptr, kind mem.CellKind, allowNil bool) (mem.CellData, error) {
if ptr.IsNull() {
return nil, ErrNullPtrDereference{At: ptr}
}
if !vm.memory.Is(ptr, kind) {
return nil, ErrUnexpectedMemCell{Ptr: ptr, Expected: mem.CellKindEnv, Got: vm.memory.Kind(ptr)}
}
cell, err := vm.memory.Get(ptr)
if err != nil {
return nil, err
}
if cell == nil {
if allowNil {
return nil, nil
}
return nil, ErrMemNilCell{Ptr: ptr}
}
ok := false
switch kind {
case mem.CellKindString:
_, ok = cell.(value.StringCell)
case mem.CellKindArray:
_, ok = cell.(value.ArrayCell)
case mem.CellKindEnv:
_, ok = cell.(value.EnvCell)
case mem.CellKindOutlet:
_, ok = cell.(value.OutletCell)
case mem.CellKindType:
_, ok = cell.(value.TypeCell)
case mem.CellKindObject:
_, ok = cell.(value.ObjectCell)
}
if !ok {
return nil, ErrCorruptedMemCell{Ptr: ptr}
}
return cell, nil
}
|