-
-
Notifications
You must be signed in to change notification settings - Fork 0
JVM Backend
meris compile source.meris --out classes
java -cp "classes:compiler/build/install/meris/lib/*" meris.generated.ModuleKt
Status: implemented for the constructs listed below. Generated names and layouts are deterministic for tests, not a stable public ABI.
| Construct | JVM behavior |
|---|---|
value / data declarations |
Emits final classes with public final fields and constructors. |
| Variant type declarations | Emits root and variant case artifact classes. |
| Top-level functions | Emits static module methods. |
| Script entry points | Emits Java-compatible main(String[]). |
| Hidden runtime context | Generated Meris methods receive MerisRuntime as a hidden first parameter; public wrappers construct the default runtime. |
| Literals, locals, calls, arithmetic, booleans | Emits ordinary bytecode. |
| Product constructor calls | Emits new calls against generated product constructors. |
| Product field access | Emits GETFIELD against generated product classes. |
| Typed variant constructor calls | Emits concrete variant case classes assignable to the root variant type. Fieldless variant values use the same path without an empty call. |
| Structural equality | Emits value equality for primitives and strings, runtime carrier equality for Unit, Option, and List, and generated equals(Object) / hashCode() for product and variant artifact classes. |
match |
Dispatches on generated variant classes and binds selected fields. |
if |
Emits branch labels with one checked result type. |
raise |
Throws JvmRuntimeError with variant name and payload fields. |
handle |
Catches JvmRuntimeError, binds payload fields, and rethrows unmatched failures. |
Args, Env, Json, Http, Fs bridges |
Calls JVM host APIs and converts failures to typed runtime errors. Json includes default typed encode/decode and explicit product field-name codec plans. |
Server.* response constructors |
Emits public runtime response/status/content/header carrier calls and typed response-construction failures. |
routes declarations |
Emits internal static descriptor methods for checked route graph metadata. |
| Checked Server applications | Emits internal static descriptor methods for checked application metadata, including resources, body/response codecs, function codec callable metadata, default product Json codec plan metadata, custom Json codec plan metadata, route codec attachment metadata, route graph, and pipeline metadata. Route codec attachment is internal descriptor metadata, not public ABI. |
| Internal Server HTTP host adapter | Serves checked route graph or application descriptors through a JDK host. |
meris serve route graph startup |
Loads generated route graph descriptors in memory and starts the internal HTTP host. |
| Packaged Server descriptor startup | Loads compiled application descriptor metadata from project output and starts the internal HTTP host. |
java fun |
Emits INVOKESTATIC for the supported static Java interop subset. |
java new |
Emits NEW, DUP, and INVOKESPECIAL <init> for declared Java constructors. |
java method |
Emits INVOKEVIRTUAL or INVOKEINTERFACE for borrowed Java-handle receivers. |
| Construct | Status |
|---|---|
| General Java interop | Not implemented. The current subset is explicit and compile-only. |
| Source-free packaged Server runtime | Limited support. Packaged descriptor startup runs route handlers, ordinary pipeline middleware, entered-stage request cleanup hooks, supported application resource lifecycle calls including metadata-backed generated product and variant resource values, non-empty owned-resource application environments, function-backed body/response codec hooks for primitives, runtime carriers, and metadata-backed generated product or variant descriptor values, default product Json body/response codec plans including List<Product> response values, top-level List<Product> / Option<Product> request bodies, and mixed one-layer List<Option<Product>> / Option<List<Product>> request bodies, custom Json body/response codec plans, and packaged static roots from compiled descriptor/ABI metadata. Same-kind or deeper erased request-body containers, arbitrary external dependency injection, dependency resolution, and jar assembly remain follow-up work. |
| Stable JVM ABI | Not promised. |
Source-level Clock standard module |
Implemented for Clock.UnixSeconds() through the hidden runtime context. |
java fun is compile-only. The JVM backend derives the Java descriptor from
checked Meris types and emits INVOKESTATIC against the declared binary owner
and method. The type checker resolves the owner and exact public static method
on the compiler classpath before lowering. When the owner is a Java interface,
emission uses an interface method reference; java.util.List.of is part of the
supported static interop shape.
The supported subset is:
| Shape | JVM behavior |
|---|---|
Int, Bool, String parameters |
Passed directly. |
Int, Bool, Unit returns |
Returned directly. |
String nonnull |
Returned directly as String. |
String nullable |
Wrapped as Meris Option<String>. |
String platform unsafe |
Wrapped as Meris Option<String>; unsafe is valid only here. |
throws Java.Exception as Error.Variant |
Catches the declared Java exception and throws JvmRuntimeError. |
throws Java.Exception as Error.Variant(Field = message) |
Catches the declared Java exception and carries mapped payload fields. |
List copy Element |
Copies a Java List or object array into dev.meris.runtime.List. |
List copy Option<Element> |
Copies a Java List or object array and preserves null scalar elements as Option.none(). |
List copy List<Element> |
Recursively copies nested Java collections when leaves are supported scalar or explicit optional scalar elements. |
List nullable copy Element |
Copies a present Java List, then wraps it as Option<List<Element>>. |
List platform unsafe copy Element |
Same runtime shape as nullable collection copy. |
Exception mappings may target fieldless or payload typed-error variants. Payload
translations must map every target field. The first supported source is
message, exposed as Option<String> from Throwable.getMessage(). Each Java
exception class may appear once per java fun.
java type declares an opaque handle for one Java binary owner. java new
constructors return matching handles marked owned nonnull. java method
calls take the borrowed handle as the first ordinary function parameter.
Constructors and instance methods use the same checked classpath resolution,
return adapters, collection-copy adapters, declared exception translation, and
panic-level unchecked exception policy as the static boundary.
The collection copy adapter is valid only on List returns in Meris source.
Collection nullability applies to the Java collection object. Object arrays can
back non-null List copy Element declarations, including array returns whose
elements are Java lists for nested copy adapters. Array-backed nullable
collection returns and primitive arrays are not supported yet. Element
nullability requires an explicit Option<Element> copy adapter.
Generated classes live under meris.generated by default. Source packages
extend that root. For example:
package app.users
value UserId(Raw: String)
emits a JVM owner under meris/generated/app/users/UserId.
The release smoke script runs the installed CLI lane and the extracted
distZip and distTar archive lanes. It prints SHA-256 checksums for the
archives, extracts each archive into an isolated temporary directory, runs the
same CLI smoke suite through each extracted bin/meris, and executes generated
entry classes with the runtime libraries from that lane.
The smoke fixture includes product constructors, typed variant constructors,
match, selected field binding, compile-only java fun, Java String
nullability, Java interface static calls, declared Java exception translation,
Java collection copy, standard-library file output, local HTTP text-client
coverage for Http.GetText and Http.PostText, generated class count checks,
and packaged meris serve coverage for manifest-declared Server package
metadata plus missing classpath diagnostics. It is a release linkage check, not
a replacement for backend unit tests.