Emit interface values from source rather than only from hand-written fixtures:
store and copy all four bytes of an object/table pair in locals, parameters,
fields and array elements; convert a class reference or null at a use site;
and call an interface method through if_call with the compile-time slot. The
emitted code reuses the E06-S02 trampoline, the E06-S04 conversions, and
iface_slot, so no new runtime entry point or layout is introduced (D153).
src/compiler/emit.s: four-byte value paths for a slot, a field and a call
site; interface-aware em_target/em_store_targetsrc/compiler/members.s: four-byte member load/store between a field and
if_dst/if_srcsrc/compiler/parser.s: pass-2 hooks for conversion assignment and interface
call sitessrc/compiler/iftables.s: the table lookup the conversion emission needs
(it_find, already present)src/common/emit.inc: new emitter error codes for an unsupported interface
shapetests/compiler/iface.n8, tests/compiler/iface-test.sscripts/build-iface-test.ps1, scripts/verify-iface-test.ps1tests/semantic/*.n8 for the misuse diagnosticsdocs/decisions.md (D153), docs/architecture.md, docs/memory-map.mdplanning/claims/E06-S07.mdbuild/iface-test/null in an interface context produces the canonical null value and a
call through it takes the fault path.if_call with the value pointer in
A/X and the slot in Y, with arguments and one-/two-byte returns.types.s already classifies class and
interface references by name and ty_assign accepts a class for an interface
it implements (tests/semantic/refs.n8). Interface slots therefore allocate
four bytes through the existing size argument; the byte-only emitter is what
refuses them (EM_ERR_SIZE from em_expr_name, em_target, em_bin).if_assign takes the destination in A/X and the mode in Y (0 copies
if_src, any other value converts if_obj with if_tab); if_call takes
the value pointer in A/X and the slot in Y and reports through if_error.
Both are already proven by tests/runtime/convert-test.s and
tests/runtime/ifcall-test.s.$F2-$F4 is the only free gap, so
D153 keeps one value address (EM_LP) plus the runtime's own module
pointers.emit.s, members.s, codegen.s, emit.inc, interfaces.inc,
types.s and the runtime interface API. The emitter is byte-only end to end:
em_size is compared with 1 in load, push, combine, target and store, and
em_target accepts only a one-byte local or a one-byte self field.mb_ld_field/mb_st_field accept MB_BYTE or MB_WORD only, so a
four-byte interface field needs its own member transfer; mb_point already
loads any object reference into MB_SELF, which a receiver expression can
reuse.iface_slot returns the slot from the interface's signature rows and is the
only correct source of the call's Y; it_find returns the class's table for a
given interface, which is the compile-time half of a conversion.em_size is a single byte count and the
left-operand path pushes exactly one byte. Conversions and copies must move
all four bytes through the runtime routines rather than a new temp.in-progress rather than done.if_assign mode 0 and 1 from the source type
that types.s already computed.em_target/em_store_target cases
with IF_VALUE_SIZE, plus EM_ERR_SIZE only for shapes that are still
unsupported.mb_ld_iface/mb_st_iface and use them for interface fields.it_find for if_tab, source
pointer or zero into if_obj, destination slot pointer into if_dst,
JSR if_assign with mode 0 or 1.if_call from an interface receiver with iface_slot as Y, then the
iface.n8 fixture with two classes and two interfaces, and the misuse
diagnostics in the semantic suite.Powered by TurnKey Linux.