Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
5a042d7
chore: add WebAssembly testsuite as submodule
avrabe Mar 8, 2026
30ca4d2
fix(foundation,runtime): wire memory tracking and fix no_std guards
avrabe Mar 8, 2026
40682d9
fix(decoder): add malformed module validation checks for spec compliance
avrabe Mar 8, 2026
6fef35e
fix(validator): track concrete pushes to reject excess values in unre…
avrabe Mar 8, 2026
6dbc491
feat(validator,format): add GC structural subtyping and rec group sup…
avrabe Mar 8, 2026
f546190
fix(runtime): correct block End instruction to handle result values
avrabe Mar 8, 2026
e86b848
fix(runtime): fix infinite loops in zero-size memory operations
avrabe Mar 8, 2026
8f17368
fix(runtime): validate import types and detect missing imports at lin…
avrabe Mar 8, 2026
baea349
fix(runtime): add type checking for cross-instance call_indirect
avrabe Mar 8, 2026
049dfea
fix(component): use Default for FunctionExport signature in WASI prov…
avrabe Mar 8, 2026
d8a77e0
refactor(component): replace debug prints with tracing framework
avrabe Mar 8, 2026
d230b91
fix(kilnd): correctly track component vs module execution statistics
avrabe Mar 8, 2026
5969082
feat(runtime): implement GC heap with struct and array operations
avrabe Mar 9, 2026
32fed0a
fix(runtime): add call_ref, return_call_ref, and missing opcode parsing
avrabe Mar 9, 2026
28f215e
fix(runtime): remove silent fallbacks that mask bugs in function retu…
avrabe Mar 9, 2026
d894c02
fix(runtime): handle result values correctly in br, br_if, br_table, …
avrabe Mar 9, 2026
212f0b7
fix(runtime): canonicalize NaN results in float arithmetic operations
avrabe Mar 9, 2026
dcd5d3d
fix(runtime): correct SIMD v128 operation implementations
avrabe Mar 9, 2026
d3a01f0
fix(runtime): correct exception handling in try_table/throw/throw_ref
avrabe Mar 9, 2026
51bc62b
test: ignore throw_ref and catch_all_ref tests pending runtime fixes
avrabe Mar 9, 2026
9c2a9fd
fix(foundation): implement serialized_size() for component model types
avrabe Mar 9, 2026
90d88ee
fix(runtime): unify WASI dispatch through host_handler for consistent…
avrabe Mar 9, 2026
53ab3ed
fix(component): propagate instantiation errors and fix multi-module c…
avrabe Mar 9, 2026
12be48a
fix(decoder,component): remove false-positive data count scan, improv…
avrabe Mar 9, 2026
1136c87
feat(runtime): implement atomic memory operations for threads proposal
avrabe Mar 9, 2026
5ecef58
fix(runtime): improve cross-module linking and import type validation
avrabe Mar 9, 2026
5501458
feat(runtime): implement relaxed SIMD operations
avrabe Mar 9, 2026
4b7db88
feat(wasi): add WASI-NN 0.2.0-rc interface scaffold for ML inference
avrabe Mar 9, 2026
78e3790
feat(runtime): add memory64 support for 64-bit memory addressing
avrabe Mar 9, 2026
45d3497
fix(runtime): add GC reference type support to core operations
avrabe Mar 9, 2026
f4022d4
fix(validator): add GC reference type support to WAST validator
avrabe Mar 9, 2026
79302bf
fix(runtime): implement struct/array GC operations with type info
avrabe Mar 9, 2026
ed1b972
fix(runtime): decode and handle ref.as_non_null, br_on_null, br_on_no…
avrabe Mar 9, 2026
bb45304
fix(opcodes): correct ref.eq/ref.as_non_null/br_on_null/br_on_non_nul…
avrabe Mar 9, 2026
7c9f628
fix(gc): implement allocation identity for ref.eq and fix GC table op…
avrabe Mar 9, 2026
8bda252
fix(runtime): complete memory64 support and fix SIMD store lane seria…
avrabe Mar 10, 2026
95919c2
fix(wasi-nn): extract real model shapes from Tract instead of hardcod…
avrabe Mar 10, 2026
a95f46f
fix(runtime,validator): add 0xFE atomic prefix parsing to instruction…
avrabe Mar 10, 2026
23bf172
fix(runtime): remove duplicate MemoryGrow error arm from cherry-pick …
avrabe Mar 10, 2026
d7db533
fix(parser): implement multi-memory binary encoding for memory instru…
avrabe Mar 10, 2026
b6b9533
fix(runtime): fix atomic wait32/wait64 handlers and clean up duplicat…
avrabe Mar 10, 2026
c41f332
fix(runtime): implement table64 proposal support for all table operat…
avrabe Mar 10, 2026
6c06b8c
fix(runtime): improve import validation, ref type subtyping, and tabl…
avrabe Mar 10, 2026
e977122
feat(kilnd): add --nn-graph CLI flag for WASI-NN model preloading
avrabe Mar 10, 2026
694ffc4
feat(wasi): add filesystem dispatch_core handlers and wire preopens t…
avrabe Mar 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "external/testsuite"]
path = external/testsuite
url = https://github.com/WebAssembly/testsuite.git
1 change: 1 addition & 0 deletions external/testsuite
Submodule testsuite added at 7e0b83
8 changes: 4 additions & 4 deletions kiln-build-core/src/wast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,7 @@ impl WastTestRunner {
/// Handle assert_return directive
fn handle_assert_return_directive(
&mut self,
exec: &WastExecute,
exec: &mut WastExecute,
results: &[WastRet],
_file_path: &Path,
) -> Result<WastDirectiveInfo> {
Expand Down Expand Up @@ -725,7 +725,7 @@ impl WastTestRunner {
/// Handle assert_trap directive
fn handle_assert_trap_directive(
&mut self,
exec: &WastExecute,
exec: &mut WastExecute,
expected_message: &str,
_file_path: &Path,
) -> Result<WastDirectiveInfo> {
Expand Down Expand Up @@ -821,7 +821,7 @@ impl WastTestRunner {
/// This expects the execution to throw an uncaught exception
fn handle_assert_exception_directive(
&mut self,
exec: &WastExecute,
exec: &mut WastExecute,
_file_path: &Path,
) -> Result<WastDirectiveInfo> {
self.stats.assert_trap_count += 1; // Count with trap tests
Expand Down Expand Up @@ -1415,7 +1415,7 @@ impl WastTestRunner {
/// Handle invoke directive (standalone function call)
fn handle_invoke_directive(
&mut self,
exec: &WastExecute,
exec: &mut WastExecute,
_file_path: &Path,
) -> Result<WastDirectiveInfo> {
// Execute the function using the real engine
Expand Down
1,374 changes: 1,286 additions & 88 deletions kiln-build-core/src/wast_execution.rs

Large diffs are not rendered by default.

682 changes: 601 additions & 81 deletions kiln-build-core/src/wast_validator.rs

Large diffs are not rendered by default.

43 changes: 42 additions & 1 deletion kiln-build-core/src/wast_values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,40 @@ pub fn convert_wast_ret_core_to_value(ret: &WastRetCore) -> Result<Value> {
},
}
},
WastRetCore::RefI31 => {
WastRetCore::RefI31 | WastRetCore::RefI31Shared => {
// (ref.i31) - any non-null i31 reference
// Use a sentinel value to indicate "any non-null i31ref"
Ok(Value::I31Ref(Some(i32::MAX)))
},
WastRetCore::RefStruct => {
// (ref.struct) - any non-null struct reference
// Use a sentinel StructRef with alloc_id = u32::MAX
let sentinel = kiln_foundation::values::StructRef::new(
u32::MAX,
kiln_foundation::traits::DefaultMemoryProvider::default(),
).map_err(|e| anyhow::anyhow!("Failed to create sentinel StructRef: {}", e))?;
Ok(Value::StructRef(Some(sentinel)))
},
WastRetCore::RefArray => {
// (ref.array) - any non-null array reference
// Use a sentinel ArrayRef with alloc_id = u32::MAX
let mut sentinel = kiln_foundation::values::ArrayRef::new(
u32::MAX,
kiln_foundation::traits::DefaultMemoryProvider::default(),
).map_err(|e| anyhow::anyhow!("Failed to create sentinel ArrayRef: {}", e))?;
sentinel.alloc_id = u32::MAX;
Ok(Value::ArrayRef(Some(sentinel)))
},
WastRetCore::RefEq => {
// (ref.eq) - any non-null eqref (i31, struct, or array)
// Use I31Ref sentinel with i32::MAX - values_equal handles cross-type matching
Ok(Value::I31Ref(Some(i32::MAX)))
},
WastRetCore::RefAny => {
// (ref.any) - any non-null anyref (i31, struct, array)
// Use I31Ref sentinel with i32::MAX - values_equal handles cross-type matching
Ok(Value::I31Ref(Some(i32::MAX)))
},
_ => {
// Handle other reference types with default FuncRef
Ok(Value::FuncRef(None))
Expand Down Expand Up @@ -332,10 +361,22 @@ pub fn values_equal(actual: &Value, expected: &Value) -> bool {
// GC reference type comparisons
(Value::ExnRef(a), Value::ExnRef(b)) => a == b,
// I31Ref: i32::MAX sentinel means "any non-null i31ref" (from (ref.i31) in WAST)
// Also matches eqref/anyref sentinels for cross-type GC reference matching
(Value::I31Ref(Some(_)), Value::I31Ref(Some(sentinel))) if *sentinel == i32::MAX => true,
(Value::I31Ref(None), Value::I31Ref(Some(sentinel))) if *sentinel == i32::MAX => false,
// eqref/anyref sentinel (i32::MAX) matches any non-null struct/array/i31
(Value::StructRef(Some(_)), Value::I31Ref(Some(sentinel))) if *sentinel == i32::MAX => true,
(Value::ArrayRef(Some(_)), Value::I31Ref(Some(sentinel))) if *sentinel == i32::MAX => true,
(Value::StructRef(None), Value::I31Ref(Some(sentinel))) if *sentinel == i32::MAX => false,
(Value::ArrayRef(None), Value::I31Ref(Some(sentinel))) if *sentinel == i32::MAX => false,
(Value::I31Ref(a), Value::I31Ref(b)) => a == b,
// StructRef: type_index = u32::MAX sentinel means "any non-null structref"
(Value::StructRef(Some(_)), Value::StructRef(Some(sentinel))) if sentinel.type_index == u32::MAX => true,
(Value::StructRef(None), Value::StructRef(Some(sentinel))) if sentinel.type_index == u32::MAX => false,
(Value::StructRef(a), Value::StructRef(b)) => a == b,
// ArrayRef: type_index = u32::MAX sentinel means "any non-null arrayref"
(Value::ArrayRef(Some(_)), Value::ArrayRef(Some(sentinel))) if sentinel.type_index == u32::MAX => true,
(Value::ArrayRef(None), Value::ArrayRef(Some(sentinel))) if sentinel.type_index == u32::MAX => false,
(Value::ArrayRef(a), Value::ArrayRef(b)) => a == b,
// Cross-type null reference comparisons for WAST testing
// In GC spec, (ref.null) without type is polymorphic and matches any null reference
Expand Down
2 changes: 2 additions & 0 deletions kiln-component/src/components/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,7 @@ impl MemoryValue {
let core_ty = kiln_runtime::CoreMemoryType {
limits: ty.limits,
shared: ty.shared,
memory64: ty.memory64,
};
let memory = Memory::new(core_ty)?;
Ok(Self {
Expand Down Expand Up @@ -667,6 +668,7 @@ impl MemoryValue {
let core_ty = kiln_runtime::CoreMemoryType {
limits: ty.limits,
shared: ty.shared,
memory64: ty.memory64,
};
let memory = Memory::new_with_name(core_ty, name)?;
Ok(Self {
Expand Down
76 changes: 43 additions & 33 deletions kiln-component/src/components/component_instantiation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1342,7 +1342,9 @@ impl ComponentInstance {
let module_idx = *module_idx as usize;

if module_idx >= module_binaries.len() {
continue;
return Err(kiln_error::Error::component_linking_error(
"Core instance references module index out of bounds",
));
}

let binary = &module_binaries[module_idx];
Expand Down Expand Up @@ -1444,7 +1446,14 @@ impl ComponentInstance {
{
// Resolve the provider handle for this specific export
let provider_handle = if let Some(src_idx) = source_instance {
core_instances_map.get(src_idx).copied().unwrap_or(handle)
match core_instances_map.get(src_idx) {
Some(&h) => h,
None => {
return Err(kiln_error::Error::component_linking_error(
"InlineExports export references source instance which is not instantiated",
));
}
}
} else {
handle
};
Expand All @@ -1467,10 +1476,10 @@ impl ComponentInstance {
) {
Ok(()) => {
},
Err(e) => println!(
" │ │ │ └─ Note: {:?}",
e
),
Err(_e) => {
#[cfg(feature = "tracing")]
trace!(error = ?_e, "Import link note");
},
}
}
// Skip the normal single-link below since we linked everything
Expand Down Expand Up @@ -1686,12 +1695,19 @@ impl ComponentInstance {
}

},
Err(e) => {
// Continue with other modules
Err(_e) => {
return Err(kiln_error::Error::component_linking_error(
"Failed to instantiate core module during component instantiation",
));
},
}
},
Err(e) => {
Err(_e) => {
#[cfg(feature = "tracing")]
tracing::error!(error = %_e, "Failed to load core module");
return Err(kiln_error::Error::component_linking_error(
"Failed to load core module during component instantiation",
));
},
}
},
Expand Down Expand Up @@ -2486,7 +2502,8 @@ impl ComponentInstance {
for (idx, canon) in canonicals.iter().enumerate() {
use kiln_format::component::CanonOperation;

print!(" Canon[{}]: ", idx);
#[cfg(feature = "tracing")]
trace!(idx = idx, "Processing canonical operation");

match &canon.operation {
CanonOperation::Lift {
Expand Down Expand Up @@ -3886,8 +3903,15 @@ impl ComponentInstance {

// Try _initialize first (important for TinyGo components)
match engine.execute(instance_handle, "_initialize", &[]) {
Ok(_) => println!("[CALL_NATIVE] ✓ _initialize completed"),
Err(e) => println!("[CALL_NATIVE] ⚠ _initialize skipped: {:?}", e),
Ok(_) => {
#[cfg(feature = "tracing")]
trace!("_initialize completed successfully");
},
Err(_) => {
// _initialize is optional - not all components have it
#[cfg(feature = "tracing")]
trace!("_initialize not found, skipping");
},
}

// Try entry point functions in order of preference:
Expand All @@ -3910,7 +3934,7 @@ impl ComponentInstance {

for entry_point in entry_points {
match engine.execute(instance_handle, entry_point, &wasm_args) {
Ok(results) => {
Ok(_results) => {
return Ok(vec![]); // wasi:cli/run returns nothing on success
},
Err(e) => {
Expand All @@ -3919,27 +3943,8 @@ impl ComponentInstance {
}
}

// All entry points failed - check available exports for debugging
// All entry points failed
if let Some(e) = last_error {
// Debug: check for common exports (core module exports only)
let common_exports = [
"_start",
"_initialize",
"run",
"main",
"memory",
"__heap_base",
"__data_end",
"cabi_realloc",
"__wasm_call_ctors",
];
for name in common_exports {
match engine.has_function(instance_handle, name) {
Ok(true) => println!(" ✓ {} - EXISTS", name),
Ok(false) => println!(" ✗ {} - not found", name),
Err(_) => println!(" ? {} - error checking", name),
}
}
return Err(e);
}
} else {
Expand Down Expand Up @@ -3987,6 +3992,9 @@ impl ComponentInstance {
Error::runtime_execution_error("Failed to create tables")
})?,
memories: Vec::new(),
#[cfg(feature = "std")]
globals: Vec::new(),
#[cfg(not(feature = "std"))]
globals: kiln_foundation::bounded::BoundedVec::new(provider.clone()).map_err(|e| {
Error::runtime_execution_error("Failed to create globals")
})?,
Expand Down Expand Up @@ -4024,6 +4032,8 @@ impl ComponentInstance {
#[cfg(feature = "std")]
import_types: Vec::new(),
num_import_functions: 0,
#[cfg(feature = "std")]
gc_types: Vec::new(),
};
m.load_from_binary(&binary_clone)
}
Expand Down
Loading
Loading