interface.inc 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. ; vim:ft=fasm:
  2. ;include 'utils.inc'
  3. ;include 'align.inc'
  4. ;include 'struct.inc'
  5. if ~ defined interface
  6. restore interface
  7. define interface
  8. struct interface.wideptr
  9. data_ptr dq ?
  10. vtable_ptr dq ?
  11. ends
  12. macro interface if_name*
  13. ; define if_name.__names__
  14. macro interface_inner
  15. macro ? line&
  16. match =end =interface_inner, line
  17. purge ?
  18. else match name args, line
  19. if_name.__names__ equ name
  20. name#_ptr dq ?
  21. align 8
  22. macro name self*, args
  23. local vtable, self_data
  24. vtable = rcx
  25. mov rax, self
  26. mov vtable, [rax + interface.wideptr.vtable_ptr]
  27. call_args [vtable + if_name.name#_ptr], args
  28. end macro
  29. else match name, line
  30. if_name.__names__ equ name
  31. name#_ptr dq ?
  32. align 8
  33. macro name self*
  34. local vtable, self_data
  35. vtable = rcx
  36. mov rax, self
  37. mov vtable, [rax + interface.wideptr.vtable_ptr]
  38. call [vtable + if_name.name#_ptr]
  39. end macro
  40. ; err 'invalid expression: ', '"', `line, '"'
  41. end match
  42. end macro
  43. end macro
  44. macro end?.interface!
  45. esc end interface_inner
  46. align 16
  47. esc ends
  48. sizeof.if_name.new = (sizeof.if_name + sizeof.interface.wideptr)
  49. purge interface_inner
  50. purge end?.interface
  51. end macro
  52. esc struct if_name
  53. esc interface_inner
  54. end macro
  55. ; macro interface.impl if_name*, self*, data_p*, vtable*
  56. ; local implemented
  57. ; define implemented
  58. ; mov rax, vtable
  59. ; mov [self + interface.wideptr.data_ptr], data_p
  60. ; mov [self + interface.wideptr.vtable_ptr], rax
  61. ; macro ? line&
  62. ; match =end =interface.impl, line
  63. ; irpv need, if_name.__names__
  64. ; local found
  65. ; found = 0
  66. ; irpv has, implemented
  67. ; if `need = `has
  68. ; found = 1
  69. ; break
  70. ; end if
  71. ; end irpv
  72. ; if found = 0
  73. ; err '"', `need, '"', ' not implemented for ', '"', `if_name, '"'
  74. ; end if
  75. ; end irpv
  76. ; purge ?
  77. ; else match name:f, line
  78. ; implemented equ name
  79. ; mov [rax + if_name.name#_ptr], f
  80. ; else match any, line
  81. ; err 'invalid expression: ', `any
  82. ; end match
  83. ; end macro
  84. ; end macro
  85. macro interface.self_data self*, out_reg:rax
  86. mov out_reg, [self + interface.wideptr.data_ptr]
  87. end macro
  88. macro interface.impl if_name*, implementation*, self*, data*
  89. lea rax, [self] ; wide ptr
  90. ; data
  91. lea rcx, [data]
  92. mov [rax + interface.wideptr.data_ptr], rcx
  93. ; vtable
  94. lea rcx, [self + sizeof.interface.wideptr]
  95. mov [rax + interface.wideptr.vtable_ptr], rcx
  96. irpv name, if_name.__names__
  97. ; display `name, 10
  98. local impl
  99. if defined implementation.name
  100. impl = implementation.name
  101. else if defined if_name.name#_default
  102. impl = if_name.name#_default
  103. else
  104. err '"', `name, '"', ' not implemented for ', '"', `if_name, '"'
  105. end if
  106. mov [rcx + if_name.name#_ptr], impl
  107. end irpv
  108. end macro
  109. end if