Skip to content

Commit 72f9cda

Browse files
committed
chore: bump instructions
Signed-off-by: Gordon Smith <GordonJSmith@gmail.com>
1 parent ed7c61e commit 72f9cda

File tree

10 files changed

+736
-22
lines changed

10 files changed

+736
-22
lines changed

.github/copilot-instructions.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
## Repository focus
22
- Header-only C++20 implementation of the WebAssembly Component Model canonical ABI; public surface aggregates through `include/cmcpp.hpp` and the `cmcpp` namespace.
33
- Core work revolves around marshaling values between C++ types and wasm flat values using `lift_flat`, `lower_flat`, `lift_flat_values`, and `lower_flat_values` templates.
4-
- Project is kept in sync with the upstream spec (`ref/component-model`) and the reference Python definitions (`definitions.py`, `run_tests.py`). Compare against those when adjusting ABI semantics.
4+
- **Implementation mirrors the official Python reference**: The C++ code structure, type names, and semantics directly correspond to the Python implementation in `ref/component-model/design/mvp/canonical-abi/definitions.py` and the specification in `ref/component-model/design/mvp/CanonicalABI.md`. When making changes, cross-reference these files to ensure alignment.
5+
- Supports async runtime primitives (`Store`, `Thread`, `Task`), resource management (`own`, `borrow`), streams/futures, waitables, and error contexts.
56

67
## Core headers
78
- `include/cmcpp/traits.hpp` defines `ValTrait`, type aliases (e.g., `bool_t`, `string_t`), and concept shortcuts that every new type must implement.
8-
- `include/cmcpp/context.hpp` + `InstanceContext` encapsulate guest memory (`std::span<uint8_t>`), realloc callbacks, and host traps; use `createInstanceContext` before calling lift/lower helpers.
9+
- `include/cmcpp/context.hpp` encapsulates `LiftLowerContext`, `ComponentInstance`, `Task`, resource tables (`HandleTable`, `InstanceTable`), and canonical operations like `canon_waitable_*`, `canon_stream_*`, `canon_future_*`.
10+
- `include/cmcpp/runtime.hpp` provides async primitives: `Store`, `Thread`, `Call`, and supporting types for cooperative scheduling.
11+
- `include/cmcpp/error_context.hpp` implements error context lifecycle (`canon_error_context_new/debug_message/drop`).
912
- Memory helpers live in `include/cmcpp/load.hpp`/`store.hpp`; always respect `ValTrait<T>::size` and `alignment` from those headers instead of hard-coding layout rules.
1013

1114
## Lift/Lower workflow
@@ -17,11 +20,14 @@
1720
- Extend `ValTrait` specializations and `ValTrait<T>::flat_types` for new composite types before touching lift/lower logic.
1821
- Use concepts from `traits.hpp` (e.g., `List`, `Variant`, `Flags`) so overload resolution stays consistent; mirror patterns in `include/cmcpp/list.hpp`, `variant.hpp`, etc.
1922
- Guard traps with `trap_if(cx, condition, message)` and route all host failures through the `HostTrap` provided by the context rather than throwing ad-hoc exceptions.
23+
- **Maintain Python equivalence**: When implementing new canonical operations or type handling, ensure the C++ behavior matches the corresponding Python code in `definitions.py`. Type names, state transitions, and error conditions should align with the reference implementation.
2024

2125
## Testing
22-
- Default build enables coverage flags on GCC/Clang; run `cmake --preset linux-ninja-Debug` followed by `cmake --build --preset linux-ninja-Debug` and then `ctest --preset linux-ninja-Debug` (or `ctest -VV` from the build tree).
26+
- Default build enables coverage flags on GCC/Clang; run `cmake --preset linux-ninja-Debug` followed by `cmake --build --preset linux-ninja-Debug` and then `ctest --output-on-failure` from the build tree.
2327
- C++ tests live in `test/main.cpp` using doctest and ICU for encoding checks; keep new tests near related sections for quick discovery.
24-
- `run_tests.py` exercises the same ABI rules via Python—use it to cross-check tricky canonical ABI edge cases when changing flattening behavior.
28+
- Test coverage workflow: run tests, then `lcov --capture --directory . --output-file coverage.info`, filter with `lcov --remove`, and optionally generate HTML with `genhtml`. See README for full workflow.
29+
- **Python reference tests**: The canonical ABI test suite in `ref/component-model/design/mvp/canonical-abi/run_tests.py` exercises the same ABI rules—use it to cross-check tricky canonical ABI edge cases when changing flattening behavior. Run with `python3 run_tests.py` (requires Python 3.10+).
30+
- When adding new features to the C++ implementation, verify behavior matches the Python reference by comparing against `definitions.py` logic and running the Python test suite.
2531

2632
## Samples & runtimes
2733
- Enabling `-DBUILD_SAMPLES=ON` builds the WAMR host sample (`samples/wamr`); it wraps host callbacks with `host_function`/`guest_function` helpers defined in `include/wamr.hpp`.
@@ -31,4 +37,5 @@
3137
## Tooling notes
3238
- Dependencies are managed through `vcpkg.json` with overlays in `vcpkg_overlays/` (notably for WAMR); stick with preset builds so CMake wires in the correct toolchain file automatically.
3339
- Cargo manifest (`Cargo.toml`) is only for fetching `wasm-tools` and `wit-bindgen-cli`; if you touch wasm generation logic, update both the manifest and any scripts referencing those versions.
40+
- Release management uses Release Please with conventional commits (`feat:`, `fix:`, etc.) to automate changelog and version bumps.
3441
- Keep documentation alongside code: update `README.md` when introducing new host types or workflows so downstream integrators stay aligned with the canonical ABI behavior.

.github/instructions/component-model.instructions.md

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,22 @@ applyTo: '**'
77

88
This repository implements a C++ ABI (Application Binary Interface) for the WebAssembly Component Model, providing host bindings that allow C++ applications to interact with WebAssembly components.
99

10+
### Relationship to the Official Specification
11+
12+
**This implementation directly mirrors the canonical Python reference implementation.** The C++ code in this repository is designed to be a faithful translation of:
13+
14+
- **Python definitions**: `ref/component-model/design/mvp/canonical-abi/definitions.py` - The authoritative reference implementation
15+
- **Specification**: `ref/component-model/design/mvp/CanonicalABI.md` - The formal specification document
16+
- **Test suite**: `ref/component-model/design/mvp/canonical-abi/run_tests.py` - Validation tests
17+
18+
The C++ implementation maintains structural and semantic alignment with the Python code:
19+
- Class names map directly (e.g., `Task`, `Store`, `Thread`, `ComponentInstance`)
20+
- State machines follow the same transitions (e.g., `Task::State` enum values)
21+
- Method signatures and behavior match the Python counterparts
22+
- Error conditions and trap points are equivalent
23+
24+
When modifying or extending the C++ implementation, **always cross-reference the Python code** to ensure conformance. Any divergence from the reference implementation should be documented and justified.
25+
1026
### WebAssembly Component Model Overview
1127
The [WebAssembly Component Model](https://github.com/WebAssembly/component-model) is a specification that extends WebAssembly with:
1228
- **Interface Types**: Rich type system beyond basic WebAssembly types
@@ -21,12 +37,16 @@ The [WebAssembly Component Model](https://github.com/WebAssembly/component-model
2137
- Primitive types: bool, integers (s8-s64, u8-u64), floats (f32, f64), char
2238
- String types: UTF-8, UTF-16, Latin-1+UTF-16 encoding support
2339
- Composite types: lists, records, tuples, variants, enums, options, results, flags
24-
- Resource types: own, borrow (planned)
40+
- Resource types: own, borrow
41+
- Async types: streams (readable/writable), futures (readable/writable), waitables, tasks
42+
- Error handling: error contexts with debug messages
2543

2644
- **ABI Functions**: Core Component Model operations
2745
- `lower_flat_values`: Convert C++ values to WebAssembly flat representation
2846
- `lift_flat_values`: Convert WebAssembly flat values to C++ types
2947
- Memory management with proper encoding handling
48+
- Canonical operations: `canon_waitable_*`, `canon_stream_*`, `canon_future_*`, `canon_task_*`, `canon_error_context_*`
49+
- Async runtime: `Store`, `Thread`, `Call`, cooperative scheduling with tick-based execution
3050

3151
#### Architecture
3252
- **Header-only Library**: Pure template-based implementation in `include/cmcpp/`
@@ -50,6 +70,19 @@ When working with this library:
5070
2. **Host Functions**: Implement host functions using the provided type wrappers
5171
3. **Guest Interaction**: Use lift/lower functions to marshal data between host and guest
5272
4. **Memory Management**: Use the provided realloc functions for guest memory allocation
73+
5. **Async Operations**: Use `Store::invoke` and `Store::tick()` for cooperative async execution
74+
6. **Resource Management**: Use `ComponentInstance::table` for handle tracking and canonical resource operations
75+
7. **Error Contexts**: Use `canon_error_context_*` functions for debug message handling
76+
8. **Validation**: Cross-check behavior against the Python reference in `ref/component-model/design/mvp/canonical-abi/definitions.py` when implementing new features
77+
78+
### Testing Against the Python Reference
79+
80+
When adding or modifying canonical ABI operations:
81+
1. Read the corresponding Python function in `definitions.py` to understand the expected behavior
82+
2. Ensure your C++ implementation produces equivalent results for the same inputs
83+
3. Run `python3 ref/component-model/design/mvp/canonical-abi/run_tests.py` to verify the reference tests still pass
84+
4. Add corresponding C++ tests in `test/main.cpp` that exercise the same edge cases
85+
5. Document any intentional deviations (e.g., performance optimizations) with clear justification
5386

5487
### References
5588
- [WebAssembly Component Model Specification](https://github.com/WebAssembly/component-model)

.github/instructions/general.instructions.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,14 @@ This repository is a modern C++20 header-only library implementing WebAssembly C
2525
- **Template Specializations**: Use template specialization for different WebAssembly types
2626

2727
### Build System
28-
- **CMake**: Uses CMake 3.5+ with modern CMake practices
28+
- **CMake**: Uses CMake 3.5+ with modern CMake practices (3.22+ recommended for presets)
2929
- **Interface Library**: Configured as an interface library target
30-
- **Cross-platform**: Supports Ubuntu, macOS, and Windows
30+
- **Cross-platform**: Supports Ubuntu 24.04 and Windows 2022
3131
- **Compiler Requirements**: Requires C++20 support
3232
- **Dependencies**: Uses vcpkg for third-party library management
3333
- Package definitions in `vcpkg.json` and `vcpkg-configuration.json`
3434
- Key dependencies: doctest (testing), ICU (Unicode), wasm-micro-runtime, wasi-sdk
35+
- **Coverage**: GCC/Clang builds enable coverage instrumentation; use lcov for report generation
3536

3637
### Type Safety and WebAssembly ABI
3738
- **Strong Typing**: Use distinct types for WebAssembly values (bool_t, char_t, etc.)
@@ -44,4 +45,5 @@ This repository is a modern C++20 header-only library implementing WebAssembly C
4445
- **Function Templates**: Use function templates for type-generic operations
4546
- **SFINAE/Concepts**: Use concepts or SFINAE for template constraints
4647
- **Const Correctness**: Maintain const correctness throughout
47-
- **Naming**: Use snake_case for variables, PascalCase for types
48+
- **Naming**: Use snake_case for variables, PascalCase for types
49+
- **Commit Messages**: Use conventional commits (`feat:`, `fix:`, etc.) for Release Please automation

.gitmodules

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44
[submodule "ref/component-model"]
55
path = ref/component-model
66
url = https://github.com/WebAssembly/component-model.git
7-
[submodule "ref/vscode-wasm"]
8-
path = ref/vscode-wasm
9-
url = git@github.com:microsoft/vscode-wasm.git
107
[submodule "ref/wasm-micro-runtime"]
118
path = ref/wasm-micro-runtime
129
url = git@github.com:bytecodealliance/wasm-micro-runtime.git

include/cmcpp/float.hpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,30 @@ namespace cmcpp
2626
return f;
2727
}
2828

29+
inline float64_t core_f64_reinterpret_i64(int64_t i)
30+
{
31+
float64_t f;
32+
std::memcpy(&f, &i, sizeof f);
33+
return f;
34+
}
35+
2936
template <Float T>
3037
T canonicalize_nan(T f)
3138
{
32-
if (!std::isfinite(f))
39+
if (std::isnan(f))
3340
{
34-
f = std::numeric_limits<T>::quiet_NaN();
41+
// Use canonical NaN bit patterns per Component Model spec
42+
// Ref: ref/component-model/design/mvp/canonical-abi/definitions.py
43+
if constexpr (std::is_same_v<T, float32_t>)
44+
{
45+
constexpr uint32_t CANONICAL_FLOAT32_NAN = 0x7fc00000;
46+
return core_f32_reinterpret_i32(CANONICAL_FLOAT32_NAN);
47+
}
48+
else if constexpr (std::is_same_v<T, float64_t>)
49+
{
50+
constexpr uint64_t CANONICAL_FLOAT64_NAN = 0x7ff8000000000000;
51+
return core_f64_reinterpret_i64(CANONICAL_FLOAT64_NAN);
52+
}
3553
}
3654
return f;
3755
}
@@ -71,13 +89,13 @@ namespace cmcpp
7189
template <>
7290
inline float32_t load<float32_t>(const LiftLowerContext &cx, offset ptr)
7391
{
74-
return decode_i32_as_float(integer::load<int32_t>(cx, ptr));
92+
return canonicalize_nan(decode_i32_as_float(integer::load<int32_t>(cx, ptr)));
7593
}
7694

7795
template <>
7896
inline float64_t load<float64_t>(const LiftLowerContext &cx, offset ptr)
7997
{
80-
return decode_i64_as_float(integer::load<int64_t>(cx, ptr));
98+
return canonicalize_nan(decode_i64_as_float(integer::load<int64_t>(cx, ptr)));
8199
}
82100
}
83101

include/cmcpp/integer.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ namespace cmcpp
5353
template <Boolean T>
5454
inline void store(LiftLowerContext &cx, const T &v, uint32_t ptr)
5555
{
56-
integer::store<T>(cx, v, ptr);
56+
uint8_t byte = v ? 1 : 0;
57+
integer::store<uint8_t>(cx, byte, ptr);
5758
}
5859
template <Boolean T>
5960
inline WasmValVector lower_flat(LiftLowerContext &cx, const T &v)

include/cmcpp/list.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ namespace cmcpp
1616
size_t nbytes = ValTrait<T>::size;
1717
for (size_t i = 0; i < v.size(); ++i)
1818
{
19-
cmcpp::store<T>(cx, v[i], ptr + i * nbytes);
19+
T elem = v[i]; // Convert to actual type (important for std::vector<bool>)
20+
cmcpp::store<T>(cx, elem, ptr + i * nbytes);
2021
}
2122
return {ptr, v.size()};
2223
}

ref/vscode-wasm

Lines changed: 0 additions & 1 deletion
This file was deleted.

test/host-util.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ class Heap
3535
last_alloc = ret + new_size;
3636
if (last_alloc > memory.size())
3737
{
38-
std::cout << "oom: have " << memory.size() << " need " << last_alloc << std::endl;
3938
trap("oom");
4039
}
4140
std::memcpy(&memory[ret], &memory[original_ptr], original_size);

0 commit comments

Comments
 (0)