hp.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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(o object.Object, t object.PointerType, par ...interface{}) scope.ValueFor {
  57. //fmt.Println("HEAP ALLOCATE")
  58. mod := rtm.ModuleOfType(h.area.d, t)
  59. assert.For(t != nil, 20)
  60. assert.For(o != nil, 21)
  61. if h.area.data == nil {
  62. h.area.data = append(h.area.data, newlvl())
  63. }
  64. var ol []object.Object
  65. skip := make(map[cp.ID]interface{})
  66. l := h.area.top()
  67. var res scope.Value
  68. f_res := func(x scope.Value) scope.Value {
  69. return res
  70. }
  71. var talloc func(t object.PointerType)
  72. talloc = func(t object.PointerType) {
  73. switch bt := t.Complex().(type) {
  74. case object.RecordType:
  75. fake := object.New(object.VARIABLE, cp.Some())
  76. fake.SetComplex(bt)
  77. fake.SetType(object.COMPLEX)
  78. fake.SetName("{" + o.Name() + "}")
  79. l.alloc(h.area.d, mod, nil, append(ol, fake), skip)
  80. res = &ptrValue{scope: h.area, id: fake.Adr(), link: o}
  81. case object.DynArrayType:
  82. assert.For(len(par) > 0, 20)
  83. fake := object.New(object.VARIABLE, cp.Some())
  84. fake.SetComplex(bt)
  85. fake.SetType(object.COMPLEX)
  86. fake.SetName("[]")
  87. l.alloc(h.area.d, mod, nil, append(ol, fake), skip)
  88. h.area.Select(fake.Adr(), func(v scope.Value) {
  89. arr, ok := v.(*dynarr)
  90. assert.For(ok, 60)
  91. arr.Set(par[0].(scope.Value))
  92. })
  93. res = &ptrValue{scope: h.area, id: fake.Adr(), link: o}
  94. default:
  95. halt.As(100, fmt.Sprintln("cannot allocate", reflect.TypeOf(bt)))
  96. }
  97. }
  98. talloc(t)
  99. assert.For(res != nil, 60)
  100. runtime.SetFinalizer(res, fin)
  101. return f_res
  102. }
  103. func (h *halloc) Dispose(id cp.ID) {
  104. h.area.Select(id, func(v scope.Value) {
  105. //fmt.Println("dispose", v)
  106. a := h.area.top()
  107. k := a.k[id]
  108. delete(a.l, k)
  109. delete(a.r, k)
  110. delete(a.v, k)
  111. delete(a.k, id)
  112. })
  113. }
  114. func (a *halloc) Join(m scope.Manager) { a.area = m.(*area) }