hp.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package modern
  2. import (
  3. "fmt"
  4. "fw/cp"
  5. "fw/cp/constant"
  6. "fw/cp/node"
  7. "fw/cp/object"
  8. "fw/rt2"
  9. "fw/rt2/context"
  10. "fw/rt2/frame"
  11. rtm "fw/rt2/module"
  12. "fw/rt2/scope"
  13. "reflect"
  14. "runtime"
  15. "ypk/assert"
  16. "ypk/halt"
  17. )
  18. type halloc struct {
  19. area *area
  20. }
  21. func fin(x interface{}) {
  22. switch p := x.(type) {
  23. case *ptrValue:
  24. defer func() {
  25. mod := rtm.ModuleOfType(p.scope.Domain(), p.link.Complex())
  26. ol := mod.Objects[mod.Enter]
  27. var fn object.ProcedureObject
  28. for _, _po := range ol {
  29. switch po := _po.(type) {
  30. case object.ProcedureObject:
  31. if po.Name() == "FINALIZE" && po.Link().Complex().Equals(p.link.Complex()) {
  32. fn = po
  33. break
  34. }
  35. }
  36. }
  37. if fn != nil {
  38. global := p.scope.Domain().Discover(context.UNIVERSE).(context.Domain)
  39. root := global.Discover(context.STACK).(frame.Stack)
  40. cn := node.New(constant.CALL, cp.Some())
  41. ol := mod.NodeByObject(fn)
  42. assert.For(len(ol) <= 1, 40)
  43. cn.SetLeft(ol[0])
  44. cc := node.New(constant.CONSTANT, cp.Some()).(node.ConstantNode)
  45. cc.SetData(p)
  46. cc.SetType(object.COMPLEX)
  47. cn.SetRight(cc)
  48. nf := rt2.New(cn)
  49. nf.Init(global.Discover(mod.Name).(context.Domain))
  50. root.Queue(nf)
  51. }
  52. p.scope.Target().(scope.HeapAllocator).Dispose(p.id)
  53. }()
  54. }
  55. }
  56. func (h *halloc) Allocate(n node.Node, par ...interface{}) scope.ValueFor {
  57. //fmt.Println("HEAP ALLOCATE")
  58. mod := rtm.ModuleOfNode(h.area.d, n)
  59. if h.area.data == nil {
  60. h.area.data = append(h.area.data, newlvl())
  61. }
  62. var ol []object.Object
  63. skip := make(map[cp.ID]interface{})
  64. l := h.area.top()
  65. var res scope.Value
  66. f_res := func(x scope.Value) scope.Value {
  67. return res
  68. }
  69. var talloc func(t object.PointerType)
  70. talloc = func(t object.PointerType) {
  71. switch bt := t.Base().(type) {
  72. case object.RecordType:
  73. fake := object.New(object.VARIABLE, cp.Some())
  74. fake.SetComplex(bt)
  75. fake.SetType(object.COMPLEX)
  76. fake.SetName("{" + n.Object().Name() + "}")
  77. l.alloc(h.area.d, mod, nil, append(ol, fake), skip)
  78. res = &ptrValue{scope: h.area, id: fake.Adr(), link: n.Object()}
  79. case object.DynArrayType:
  80. assert.For(len(par) > 0, 20)
  81. fake := object.New(object.VARIABLE, cp.Some())
  82. fake.SetComplex(bt)
  83. fake.SetType(object.COMPLEX)
  84. fake.SetName("[]")
  85. l.alloc(h.area.d, mod, nil, append(ol, fake), skip)
  86. h.area.Select(fake.Adr(), func(v scope.Value) {
  87. arr, ok := v.(*dynarr)
  88. assert.For(ok, 60)
  89. arr.Set(par[0].(scope.Value))
  90. })
  91. res = &ptrValue{scope: h.area, id: fake.Adr(), link: n.Object()}
  92. default:
  93. halt.As(100, fmt.Sprintln("cannot allocate", reflect.TypeOf(bt)))
  94. }
  95. }
  96. switch v := n.(type) {
  97. case node.VariableNode, node.FieldNode:
  98. switch t := v.Object().Complex().(type) {
  99. case object.PointerType:
  100. talloc(t)
  101. //h.area.data[0].alloc(mod, nil, )
  102. default:
  103. halt.As(100, reflect.TypeOf(t))
  104. }
  105. default:
  106. halt.As(101, reflect.TypeOf(v), v)
  107. }
  108. assert.For(res != nil, 60)
  109. runtime.SetFinalizer(res, fin)
  110. return f_res
  111. }
  112. func (h *halloc) Dispose(id cp.ID) {
  113. h.area.Select(id, func(v scope.Value) {
  114. //fmt.Println("dispose", v)
  115. a := h.area.top()
  116. k := a.k[id]
  117. delete(a.l, k)
  118. delete(a.r, k)
  119. delete(a.v, k)
  120. delete(a.k, id)
  121. })
  122. }
  123. func (a *halloc) Join(m scope.Manager) { a.area = m.(*area) }