Allow Object members on unknown types

This commit is contained in:
sergeych committed 2026-02-04 03:40:07 +03:00
1 parent 47654aee38
commit 1fab2702dd
7 files changed
+34 -35

No files matched your search

+7 -23
View File
@@ -6,32 +6,16 @@ Module focus: :lynglib
Current focus
- Enforce compile-time name/member resolution only; no runtime scope lookup or fallback.
- Bytecode uses memberId-based ops (CALL_MEMBER_SLOT/GET_MEMBER_SLOT/SET_MEMBER_SLOT).
- Fallbacks are forbidden and throw BytecodeFallbackException.
- Runtime lookup opcodes (CALL_VIRTUAL/GET_FIELD/SET_FIELD) and fallback callsites are removed.
Key recent changes
- Added memberId storage and lookup on ObjClass/ObjInstance; compiler emits memberId ops.
- Removed GET_THIS_MEMBER/SET_THIS_MEMBER usage from bytecode.
- Added ObjIterable.iterator() abstract method to ensure methodId exists.
- Bytecode compiler now throws if receiver type is unknown for member calls.
- Added static receiver inference attempts (name/slot maps), but still failing for stdlib list usage.
- Compiler now wraps function bodies into BytecodeStatement when possible.
- VarDeclStatement now includes initializerObjClass (compile-time type hint).
- Removed method callsite PICs and fallback opcodes; bytecode now relies on compile-time member ids only.
- Operator dispatch emits memberId calls when known; falls back to Obj opcodes for allowed built-ins without name lookup.
- Object members are allowed on unknown types; other members still require a statically known receiver type.
- Renamed BytecodeFallbackException to BytecodeCompileException.
Known failing test
- ScriptTest.testForInIterableUnknownTypeDisasm (jvmTest)
Failure: BytecodeFallbackException "Member call requires compile-time receiver type: add"
Location: stdlib root.lyng filter() -> "val result = []" then "result.add(item)"
Current debug shows LocalSlotRef(result) slotClass/nameClass/initClass all null.
Likely cause
- Initializer type inference for "val result = []" in stdlib is not reaching BytecodeCompiler:
- stdlib is generated at build time; initializer is wrapped in BytecodeStatement and losing ListLiteralRef info.
- Need a stable compile-time type hint from the compiler or a way to preserve list literal info.
Potential fixes to pursue
1) Preserve ObjRef for var initializers (e.g., store initializer ref/type in VarDeclStatement).
2) When initializer is BytecodeStatement, use its CmdFunction to detect list/range literal usage.
3) Ensure stdlib compilation sets initializerObjClass for list literals.
Known failing tests
- None (jvmTest passing).
Files touched recently
- notes/type_system_spec.md (spec updated)
+2 -1
View File
@@ -1,10 +1,11 @@
# Bytecode call-site PIC + fallback gating
# Bytecode call-site PIC + fallback gating (obsolete)
Changes
- Added method call PIC path in bytecode VM with new CALL_SLOT/CALL_VIRTUAL opcodes.
- Fixed FieldRef property/delegate resolution to avoid bypassing ObjRecord delegation.
- Prevent delegated ObjRecord mutation by returning a resolved copy.
- Restricted bytecode call compilation to args that are ExpressionStatement (no splat/named/tail-block), fallback otherwise.
- NOTE: PICs and fallback callsites have been removed; keep this for historical context only.
Rationale
- Fixes JVM test regressions and avoids premature evaluation of Statement args.
+1 -1
View File
@@ -212,7 +212,7 @@ Type params are erased by default. Hidden `Class` args are only injected when a
- Member access rules: If a variable is Object (dynamic), is member access a compile-time error, or allowed with fallback (which we are trying to remove)? If error, do we require explicit cast first?
Compile time error unless it is an Object own method. Let's force rewriting existing code in favor of explicit casts. It will repay itself: I laready have a project on Lyng that suffers from implicit casts har to trace errors.
Compile time error unless it is an Object own method. Object members are always allowed even on unknown types; non-Object members require explicit casts. This avoids runtime lookup while keeping common Object APIs available.
No runtime lookups or fallbacks:
- All symbol and member resolution must be done at compile time.