123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- ; vim:ft=fasm:
- ;include 'utils.inc'
- ;include 'align.inc'
- ;include 'struct.inc'
- if ~ defined interface
- restore interface
- define interface
- struct interface.wideptr
- data_ptr dq ?
- vtable_ptr dq ?
- ends
- macro interface if_name*
- ; define if_name.__names__
- macro interface_inner
- macro ? line&
- match =end =interface_inner, line
- purge ?
- else match name args, line
- if_name.__names__ equ name
- name#_ptr dq ?
- align 8
- macro name self*, args
- local vtable, self_data
- vtable = rcx
- mov rax, self
- mov vtable, [rax + interface.wideptr.vtable_ptr]
- call_args [vtable + if_name.name#_ptr], args
- end macro
- else match name, line
- if_name.__names__ equ name
- name#_ptr dq ?
- align 8
- macro name self*
- local vtable, self_data
- vtable = rcx
- mov rax, self
- mov vtable, [rax + interface.wideptr.vtable_ptr]
- call [vtable + if_name.name#_ptr]
- end macro
- ; err 'invalid expression: ', '"', `line, '"'
- end match
- end macro
- end macro
- macro end?.interface!
- esc end interface_inner
- align 16
- esc ends
- sizeof.if_name.new = (sizeof.if_name + sizeof.interface.wideptr)
- purge interface_inner
- purge end?.interface
- end macro
- esc struct if_name
- esc interface_inner
- end macro
- ; macro interface.impl if_name*, self*, data_p*, vtable*
- ; local implemented
- ; define implemented
- ; mov rax, vtable
- ; mov [self + interface.wideptr.data_ptr], data_p
- ; mov [self + interface.wideptr.vtable_ptr], rax
- ; macro ? line&
- ; match =end =interface.impl, line
- ; irpv need, if_name.__names__
- ; local found
- ; found = 0
- ; irpv has, implemented
- ; if `need = `has
- ; found = 1
- ; break
- ; end if
- ; end irpv
- ; if found = 0
- ; err '"', `need, '"', ' not implemented for ', '"', `if_name, '"'
- ; end if
- ; end irpv
- ; purge ?
- ; else match name:f, line
- ; implemented equ name
- ; mov [rax + if_name.name#_ptr], f
- ; else match any, line
- ; err 'invalid expression: ', `any
- ; end match
- ; end macro
- ; end macro
- macro interface.self_data self*, out_reg:rax
- mov out_reg, [self + interface.wideptr.data_ptr]
- end macro
- macro interface.impl if_name*, implementation*, self*, data*
- lea rax, [self] ; wide ptr
- ; data
- lea rcx, [data]
- mov [rax + interface.wideptr.data_ptr], rcx
- ; vtable
- lea rcx, [self + sizeof.interface.wideptr]
- mov [rax + interface.wideptr.vtable_ptr], rcx
-
- irpv name, if_name.__names__
- ; display `name, 10
- local impl
- if defined implementation.name
- impl = implementation.name
- else if defined if_name.name#_default
- impl = if_name.name#_default
- else
- err '"', `name, '"', ' not implemented for ', '"', `if_name, '"'
- end if
- mov [rcx + if_name.name#_ptr], impl
- end irpv
- end macro
- end if
|