Skip to main content

BytecodeCompiler

Struct BytecodeCompiler 

Source
pub struct BytecodeCompiler {
    pub stdlib_function_names: HashSet<String>,
    /* private fields */
}
Expand description

Compiler state

Fields§

§stdlib_function_names: HashSet<String>

Legacy cache of function names collected from stdlib-loaded modules.

Internal builtin access is now gated by per-definition declaring-module provenance, not by membership in this set.

Implementations§

Source§

impl BytecodeCompiler

Source

pub fn closure_registry(&self) -> &ClosureRegistry

Read-only access to the compiler’s closure registry. Populated by each closure literal during lowering (Phase A).

Source

pub fn closure_type_ids(&self) -> &[(u16, ClosureTypeId)]

(function_id, ClosureTypeId) pairs, one per closure literal lowered during compilation. Phase C consumes this to key the monomorphization cache by closure layout.

Source

pub fn function_type_registry(&self) -> &FunctionTypeRegistry

Read-only access to the compiler’s function-type registry. Populated per closure literal during lowering (Phase F).

Source

pub fn function_type_ids(&self) -> &[(u16, FunctionTypeId)]

(function_id, FunctionTypeId) pairs, one per closure literal. Phase F uses this to pick a Cranelift call_indirect signature for polymorphic Function<A, R> dispatch.

Source§

impl BytecodeCompiler

Source

pub fn type_tracker(&self) -> &TypeTracker

Source

pub fn type_tracker_mut(&mut self) -> &mut TypeTracker

Get mutable type tracker (for registering types)

Source§

impl BytecodeCompiler

Source

pub fn ensure_monomorphic_function( &mut self, base_fn_name: &str, type_args: &[ConcreteType], ) -> Result<u16>

Ensure a monomorphized specialization of base_fn_name for the given concrete type arguments exists in the bytecode program. Returns the function index of the specialized function.

On a cache hit, this is a constant-time lookup.

On a cache miss, the original FunctionDef is fetched from function_defs, cloned, and handed to Agent 2’s substitution helpers to produce a type-specialized clone. The clone is then registered and compiled via the normal pipeline, and its index is recorded in the cache before being returned.

type_args is a positional list aligned to the callee’s declared type_params: type_args[i] binds def.type_params[i]. If the callee declares no type parameters or the arity does not match, an error is returned.

§Errors
  • Err(...) if base_fn_name is not a known function in the current compiler state.
  • Err(...) if the callee declares no type parameters but type arguments were supplied.
  • Err(...) if type_args.len() does not match the number of declared type parameters.
  • Any compile error returned by compile_function for the substituted body.
Source

pub fn ensure_monomorphic_function_with_consts( &mut self, base_fn_name: &str, type_args: &[ConcreteType], const_args: &[ComptimeConstValue], ) -> Result<u16>

Ensure a monomorphized specialization of base_fn_name for the given type AND const generic arguments exists. Returns the function index of the specialized function.

This is the const-generic-aware sibling of Self::ensure_monomorphic_function. The cache key incorporates both the type args and the const args (see [build_mono_key_with_consts]), so the same callee specialised twice with different N values (repeat<3> vs repeat<5>) produces two cache entries; specialised twice with the same N produces one. The same applies to mixed type+const generic functions (fn matrix<T, const ROWS: int>(...)).

Grammar gap: as of Phase 5 the grammar does not yet allow declaring const generic params, so the const_args slice is empty for every real call site. This entry point exists so that the cache + naming + substitution path is exercised by tests today and is ready to wire up the moment the grammar adds <const N: int>.

On a cache hit, this is a constant-time lookup.

On a cache miss, the original FunctionDef is fetched from function_defs, cloned, and substituted by [substitution::substitute_function_def_with_consts]. The clone is then registered, compiled, and recorded in the cache.

type_args is positional against def.type_params (the type-kind generics). const_args is positional against the const-kind generics in declaration order. When the grammar exposes a way to mark a generic as const, the alignment logic here will need to interleave them correctly — see the TODO inside the body.

§Errors

Same as Self::ensure_monomorphic_function, plus:

  • Err(...) if the type args don’t satisfy the same arity / presence constraints as the type-only path.
Source

pub fn ensure_monomorphic_function_with_closures( &mut self, base_fn_name: &str, type_args: &[ConcreteType], closure_specs: &[ClosureSpec], closure_defs: &[ClosureDefPeek], callee_closure_param_names: &[String], ) -> Result<Option<u16>>

Phase C — closure-aware specialization entry point.

Like Self::ensure_monomorphic_function but additionally keys the specialization on per-closure-arg [ClosureSpec]s and inlines each closure literal’s body into the specialized stdlib template (replacing calls to the formal closure parameter with the closure body).

Flow:

  1. Build the full mono key (base::T1_..._closure_N_ret_...).
  2. Cache hit → return existing index.
  3. Budget exhausted → bail out (Ok(None)) so the caller falls back to the generic path.
  4. Substitute type params through the function def (as in the type-only path).
  5. For each closure spec, call [super::substitution::inline_closure_body_into_specialization] to rewrite the specialized body.
  6. Register + compile the specialized function; record cache entry; bump the closure-specialization count.

The closure_defs parallel to closure_specs carries the peeked closure literals (params, body, captures) that the inliner needs. callee_closure_param_names[i] is the name of the callee’s formal parameter that holds the i-th closure; it’s the identifier the inliner rewrites. When empty or mismatched, specialization bails and returns Ok(None).

Source§

impl BytecodeCompiler

Source

pub fn register_imported_items(&mut self, items: &[Item])

Pre-register items from an imported module (enums, struct types, functions).

Called by the LSP before compilation to make imported enums/types known to the compiler’s type tracker. Reuses register_enum as single source of truth.

Source§

impl BytecodeCompiler

Source

pub fn new() -> Self

Source

pub fn set_comptime_mode(&mut self, enabled: bool)

Enable comptime compilation mode for this compiler instance.

Source

pub fn set_blob_cache(&mut self, cache: BlobCache)

Attach a blob-level cache for incremental compilation.

When set, finalize_current_blob stores each compiled blob in the cache, and build_content_addressed_program populates the function store from cached blobs when possible.

Source

pub fn register_known_export(&mut self, function_name: &str, module_path: &str)

Register a known export for import suggestions

This enables helpful error messages like: “Unknown function ‘sma’. Did you mean to import from ‘@stdlib/finance/indicators/moving_averages’?”

Source

pub fn register_known_exports(&mut self, exports: &HashMap<String, String>)

Register multiple known exports at once

Source

pub fn suggest_import(&self, function_name: &str) -> Option<&str>

Suggest an import for an unknown function

Source

pub fn set_source(&mut self, source: &str)

Set the source text for error messages

Source

pub fn set_source_with_file(&mut self, source: &str, file_name: &str)

Set the source text and file name for error messages

Source

pub fn set_line(&mut self, line: u32)

Set the current source line (from AST span)

Source

pub fn set_line_from_span(&mut self, span: Span)

Set line from a Span (converts byte offset to line number)

Source

pub fn get_source_line(&self, line: usize) -> Option<&str>

Get a source line by line number (1-indexed)

Source

pub fn register_known_bindings(&mut self, names: &[String])

Pre-register known root-scope bindings (for REPL persistence)

Call this before compilation to register bindings from previous REPL sessions. This ensures that references to these bindings compile to LoadModuleBinding/StoreModuleBinding instructions rather than causing “Undefined variable” errors.

Source

pub fn register_known_binding_type(&mut self, name: &str, type_name: &str)

Register the type for a previously-known module binding (e.g. from a persisted REPL ExecutionContext). Wave E+5.5 host-boundary extension to register_known_bindings: pairs the binding name with the inferred type so subsequent expressions referencing the binding (e.g. a + b) resolve through the strict-typing arithmetic path. Without this, the next REPL command’s a + b falls into unknown + unknown and errors out under strict typing.

Type names use the same canonical strings as set_module_binding_type_info ("int", "number", "bool", "string", etc.) — typically derived from the persisted ValueWord’s tag/heap kind via valueword_type_name_for_persistence.

Source

pub fn seed_persistent_schemas(&mut self, schemas: &[TypeSchema])

Seed the compiler’s type-schema registry with user type schemas from prior REPL cells (WS-11 cross-cell schema-id stabilization).

Each TypeSchema is registered under its original id (the id it received the first time its type was compiled this REPL session). Because predeclare_struct_schema / register_struct_type both short-circuit on schema_registry().get(name).is_some(), pre-seeding a schema makes the cell’s re-injected type resolve to that same id instead of allocating a fresh one — so a TypedObject persisted from an earlier cell (which carries the original schema_id) still resolves under this cell’s program registry.

ensure_next_id_above advances the allocator past every seeded id so a new type declared in this cell cannot collide with a seeded one.

Source

pub fn with_schema(schema: DataFrameSchema) -> Self

Create a new compiler with a data schema for column resolution. This enables optimized GetDataField/GetDataRow opcodes.

Source

pub fn set_schema(&mut self, schema: DataFrameSchema)

Set the data schema for column resolution. Must be called before compiling data access expressions.

Source

pub fn set_source_dir(&mut self, dir: PathBuf)

Set the source directory for resolving relative source file paths.

Source

pub fn with_extensions(self, extensions: Vec<ModuleExports>) -> Self

Set extension modules for comptime execution.

Source

pub fn set_type_diagnostic_mode(&mut self, mode: TypeDiagnosticMode)

Configure how shared analyzer diagnostics are emitted.

Source

pub fn set_compile_diagnostic_mode(&mut self, mode: CompileDiagnosticMode)

Configure expression-compilation error recovery behavior.

Source

pub fn set_permission_set(&mut self, permissions: Option<PermissionSet>)

Set the active permission set for compile-time capability checking.

When set, imports that require permissions not in this set will produce compile errors. Pass None to disable checking (default).

Source§

impl BytecodeCompiler

Source

pub fn compile(self, program: &Program) -> Result<BytecodeProgram>

Compile a program to bytecode

Source

pub fn compile_with_source( self, program: &Program, source: &str, ) -> Result<BytecodeProgram>

Compile a program to bytecode with source text for error messages

Source

pub fn compile_with_graph( self, root_program: &Program, graph: Arc<ModuleGraph>, ) -> Result<BytecodeProgram>

Compile a program using the module graph for import resolution.

This is the graph-driven compilation pipeline. Modules compile in topological order using the graph for cross-module name resolution. No AST inlining occurs — each module’s imports are resolved from the graph’s ResolvedImport entries.

Source

pub fn compile_with_graph_and_prelude( self, root_program: &Program, graph: Arc<ModuleGraph>, _prelude_paths: &[String], ) -> Result<BytecodeProgram>

Compile with graph and prelude information.

All modules (including prelude dependencies) compile uniformly through the normal module path. The prelude_paths parameter is retained for API compatibility but no longer used.

Source

pub fn compile_module_ast( module_ast: &Program, ) -> Result<(BytecodeProgram, HashMap<String, usize>)>

Compile an imported module’s AST to a standalone BytecodeProgram.

This takes the Module’s AST (Program), compiles all exported functions to bytecode, and returns the compiled program along with a mapping of exported function names to their function indices in the compiled output.

The returned BytecodeProgram and function name mapping allow the import handler to resolve imported function calls to the correct bytecode indices.

Currently handles function exports only. Types and values can be added later.

Trait Implementations§

Source§

impl Default for BytecodeCompiler

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more