You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

149 lines
4.0 KiB

  1. // Copyright 2013 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package pointer
  5. import "go/types"
  6. type constraint interface {
  7. // For a complex constraint, returns the nodeid of the pointer
  8. // to which it is attached. For addr and copy, returns dst.
  9. ptr() nodeid
  10. // renumber replaces each nodeid n in the constraint by mapping[n].
  11. renumber(mapping []nodeid)
  12. // presolve is a hook for constraint-specific behaviour during
  13. // pre-solver optimization. Typical implementations mark as
  14. // indirect the set of nodes to which the solver will add copy
  15. // edges or PTS labels.
  16. presolve(h *hvn)
  17. // solve is called for complex constraints when the pts for
  18. // the node to which they are attached has changed.
  19. solve(a *analysis, delta *nodeset)
  20. String() string
  21. }
  22. // dst = &src
  23. // pts(dst) ⊇ {src}
  24. // A base constraint used to initialize the solver's pt sets
  25. type addrConstraint struct {
  26. dst nodeid // (ptr)
  27. src nodeid
  28. }
  29. func (c *addrConstraint) ptr() nodeid { return c.dst }
  30. func (c *addrConstraint) renumber(mapping []nodeid) {
  31. c.dst = mapping[c.dst]
  32. c.src = mapping[c.src]
  33. }
  34. // dst = src
  35. // A simple constraint represented directly as a copyTo graph edge.
  36. type copyConstraint struct {
  37. dst nodeid // (ptr)
  38. src nodeid
  39. }
  40. func (c *copyConstraint) ptr() nodeid { return c.dst }
  41. func (c *copyConstraint) renumber(mapping []nodeid) {
  42. c.dst = mapping[c.dst]
  43. c.src = mapping[c.src]
  44. }
  45. // dst = src[offset]
  46. // A complex constraint attached to src (the pointer)
  47. type loadConstraint struct {
  48. offset uint32
  49. dst nodeid
  50. src nodeid // (ptr)
  51. }
  52. func (c *loadConstraint) ptr() nodeid { return c.src }
  53. func (c *loadConstraint) renumber(mapping []nodeid) {
  54. c.dst = mapping[c.dst]
  55. c.src = mapping[c.src]
  56. }
  57. // dst[offset] = src
  58. // A complex constraint attached to dst (the pointer)
  59. type storeConstraint struct {
  60. offset uint32
  61. dst nodeid // (ptr)
  62. src nodeid
  63. }
  64. func (c *storeConstraint) ptr() nodeid { return c.dst }
  65. func (c *storeConstraint) renumber(mapping []nodeid) {
  66. c.dst = mapping[c.dst]
  67. c.src = mapping[c.src]
  68. }
  69. // dst = &src.f or dst = &src[0]
  70. // A complex constraint attached to dst (the pointer)
  71. type offsetAddrConstraint struct {
  72. offset uint32
  73. dst nodeid
  74. src nodeid // (ptr)
  75. }
  76. func (c *offsetAddrConstraint) ptr() nodeid { return c.src }
  77. func (c *offsetAddrConstraint) renumber(mapping []nodeid) {
  78. c.dst = mapping[c.dst]
  79. c.src = mapping[c.src]
  80. }
  81. // dst = src.(typ) where typ is an interface
  82. // A complex constraint attached to src (the interface).
  83. // No representation change: pts(dst) and pts(src) contains tagged objects.
  84. type typeFilterConstraint struct {
  85. typ types.Type // an interface type
  86. dst nodeid
  87. src nodeid // (ptr)
  88. }
  89. func (c *typeFilterConstraint) ptr() nodeid { return c.src }
  90. func (c *typeFilterConstraint) renumber(mapping []nodeid) {
  91. c.dst = mapping[c.dst]
  92. c.src = mapping[c.src]
  93. }
  94. // dst = src.(typ) where typ is a concrete type
  95. // A complex constraint attached to src (the interface).
  96. //
  97. // If exact, only tagged objects identical to typ are untagged.
  98. // If !exact, tagged objects assignable to typ are untagged too.
  99. // The latter is needed for various reflect operators, e.g. Send.
  100. //
  101. // This entails a representation change:
  102. // pts(src) contains tagged objects,
  103. // pts(dst) contains their payloads.
  104. type untagConstraint struct {
  105. typ types.Type // a concrete type
  106. dst nodeid
  107. src nodeid // (ptr)
  108. exact bool
  109. }
  110. func (c *untagConstraint) ptr() nodeid { return c.src }
  111. func (c *untagConstraint) renumber(mapping []nodeid) {
  112. c.dst = mapping[c.dst]
  113. c.src = mapping[c.src]
  114. }
  115. // src.method(params...)
  116. // A complex constraint attached to iface.
  117. type invokeConstraint struct {
  118. method *types.Func // the abstract method
  119. iface nodeid // (ptr) the interface
  120. params nodeid // the start of the identity/params/results block
  121. }
  122. func (c *invokeConstraint) ptr() nodeid { return c.iface }
  123. func (c *invokeConstraint) renumber(mapping []nodeid) {
  124. c.iface = mapping[c.iface]
  125. c.params = mapping[c.params]
  126. }