Files
hakorune/docs/development/architecture/box-externcall-design.md
Selfhosting Dev 0ac22427e5 docs: Architecture decision - Box/ExternCall boundary design
Documented the architectural decision for Nyash runtime design:

1. Core boxes (String/Integer/Array/Map/Bool) built into nyrt
   - Essential for self-hosting
   - Available at boot without plugin loader
   - High performance (no FFI overhead)

2. All other boxes as plugins (File/Net/User-defined)
   - Extensible ecosystem
   - Clear separation of concerns

3. Minimal ExternCall (only 5 functions)
   - print/error (output)
   - panic/exit (process control)
   - now (time)

Key principle: Everything goes through BoxCall interface
- No special fast paths
- Unified architecture
- "Everything is Box" philosophy maintained

This design balances self-hosting requirements with architectural purity.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-11 20:58:18 +09:00

77 lines
2.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Box/ExternCall Architecture Design Decision
## Date: 2025-09-11
### Background
During LLVM backend development, confusion arose about the proper boundary between:
- ExternCall (core runtime functions)
- BoxCall (unified Box method dispatch)
- nyrt (Nyash runtime library)
### Design Decision
#### 1. **nyrt Built-in Core Boxes**
The following boxes are built into nyrt for self-hosting stability:
```rust
// crates/nyrt/src/core_boxes/
├── integer.rs // IntegerBoxarithmetic, comparison
├── string.rs // StringBoxstring operations
├── array.rs // ArrayBoxarray operations
├── map.rs // MapBoxkey-value storage
└── bool.rs // BoolBoxlogical operations
```
**Rationale**:
- Essential for self-hosting (compiler needs these)
- Available at boot time (no plugin loader dependency)
- High performance (no FFI overhead)
- Environment independent
#### 2. **Plugin Boxes**
All other boxes are implemented as plugins:
```
plugins/
├── file/ // FileBox
├── net/ // NetBox
└── custom/ // User-defined boxes
```
#### 3. **Minimal ExternCall**
ExternCall is limited to truly external operations:
```rust
// Only these 5 functions!
extern nyash.io.print(handle: i64)
extern nyash.io.error(handle: i64)
extern nyash.runtime.panic(handle: i64)
extern nyash.runtime.exit(code: i64)
extern nyash.time.now() -> i64
```
### Key Principle: Everything Goes Through BoxCall
```nyash
local s = new StringBox("Hello") // BoxCall → nyrt built-in
local f = new FileBox() // BoxCall → plugin
s.concat(" World") // BoxCall (unified interface)
```
Even core boxes use the same BoxCall mechanism - no special fast paths!
### Trade-offs Considered
**Option 1: Everything as plugins**
- ✅ Beautiful uniformity
- ❌ Complex bootstrap
- ❌ Performance overhead
- ❌ Environment dependencies
**Option 2: Core boxes in nyrt (chosen)**
- ✅ Simple, stable bootstrap
- ✅ Self-hosting friendly
- ✅ High performance for basics
- ❌ Slightly larger core
### Conclusion
This design prioritizes self-hosting stability while maintaining the "Everything is Box" philosophy through unified BoxCall interface.