mirror of
https://github.com/duhanbalci/dexpr.git
synced 2026-07-01 16:19:16 +00:00
203 lines
7.0 KiB
Markdown
203 lines
7.0 KiB
Markdown
# VM (Virtual Machine) Modülü
|
||
|
||
**Konum:** `src/vm/`
|
||
|
||
Register tabanlı sanal makine. Bytecode'u çalıştırır, 8 register ve global değişken deposu içerir.
|
||
|
||
---
|
||
|
||
## Alt Modüller
|
||
|
||
| Dosya | İçerik |
|
||
|-------|--------|
|
||
| `vm/mod.rs` | Modül export'ları |
|
||
| `vm/vm.rs` | Ana VM implementasyonu |
|
||
| `vm/error.rs` | Hata türleri (VMError) |
|
||
| `vm/debug_info.rs` | Bytecode offset → kaynak konum eşleştirme |
|
||
|
||
---
|
||
|
||
## VMError (Hata Türleri)
|
||
|
||
**Dosya:** `src/vm/error.rs`
|
||
|
||
| Hata | Açıklama |
|
||
|------|----------|
|
||
| `TypeMismatch { expected, got }` | Tip uyuşmazlığı |
|
||
| `UndefinedVariable(SmolStr)` | Tanımlanmamış değişken |
|
||
| `DivisionByZero` | Sıfıra bölme |
|
||
| `BytecodeError(String)` | Bozuk bytecode |
|
||
| `MethodNotFound { type_name, method }` | Metod bulunamadı |
|
||
| `RuntimeError(String)` | Genel çalışma zamanı hatası |
|
||
| `InvalidOperation { operation, left_type, right_type }` | Desteklenmeyen operasyon |
|
||
| `WithLocation { span, message }` | Kaynak konum bilgili hata |
|
||
|
||
`with_span(span)` metodu hatayı kaynak konum bilgisi ile sarar (çift sarmalamayı önler).
|
||
|
||
---
|
||
|
||
## DebugInfo
|
||
|
||
**Dosya:** `src/vm/debug_info.rs`
|
||
|
||
Bytecode offset'lerini kaynak kod konumlarına (Span) eşleştirir. Run-length encoded yapıda: her girdi bir sonraki girdiye kadar geçerlidir.
|
||
|
||
```rust
|
||
struct DebugInfo {
|
||
entries: Vec<(u32, Span)>, // sıralı (offset, span) çiftleri
|
||
}
|
||
```
|
||
|
||
**Metodlar:**
|
||
- `add_entry(offset, span)` — Eşleştirme ekle (artan offset sırasında)
|
||
- `get_span(offset) -> Option<Span>` — Binary search ile konum bul
|
||
|
||
---
|
||
|
||
## VM Yapısı
|
||
|
||
```rust
|
||
struct VM<'a> {
|
||
// Bytecode durumu
|
||
bytecode: &'a [u8],
|
||
reader: BytecodeReader<'a>,
|
||
pc: usize,
|
||
|
||
// Hesaplama
|
||
registers: [Value; 8], // 8 register
|
||
|
||
// Değişkenler
|
||
globals: Map<SmolStr, Value, 64>, // Global kapsam (max 64 giriş)
|
||
|
||
// Kaynaklar
|
||
heap: Bump, // Bump allocator
|
||
|
||
// Debug
|
||
debug_info: Option<DebugInfo>,
|
||
debug: bool, // Debug çıktısı (debug build'lerde)
|
||
opcode_counts: [usize; 256], // Profiling (debug build'lerde)
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Başlatma ve API
|
||
|
||
| Metod | Açıklama |
|
||
|-------|----------|
|
||
| `new(bytecode)` | VM oluştur |
|
||
| `set_debug_info(debug_info)` | Kaynak konum eşleştirmesi sağla |
|
||
| `set_global(name, value)` | Global değişken ata |
|
||
| `get_global(name) -> Option<&Value>` | Global değişken oku |
|
||
| `register_function(name, fn)` | Harici (host) fonksiyon kaydet |
|
||
| `register_method(type_name, method_name, fn)` | Tipe özel harici metod kaydet |
|
||
| `reset()` | Durumu sıfırla, yeniden çalıştırmaya hazırla |
|
||
|
||
---
|
||
|
||
## Çalıştırma Döngüsü
|
||
|
||
`execute() -> Result<Value, VMError>` (son expression'ın değerini döndürür):
|
||
|
||
1. VM durumunu sıfırla
|
||
2. Bytecode kaldığı sürece döngüde çalış:
|
||
- Opcode byte'ını oku
|
||
- İlgili handler'a yönlendir
|
||
- Hataları kaynak konum bilgisi ile sar
|
||
- Profiling verilerini güncelle (debug build)
|
||
- `End` opcode'unda dur
|
||
|
||
---
|
||
|
||
## Opcode Handler'ları
|
||
|
||
### Register ve Bellek
|
||
- **`handle_load_const()`** — Bytecode'dan değer oku, register'a koy
|
||
- **`handle_move()`** — Register → register kopyala
|
||
- **`handle_load_global()`** — Global map → register
|
||
- **`handle_store_global()`** — Register → global map
|
||
|
||
### Aritmetik
|
||
- **`binary_op(f, name)`** — Genel handler: iki operand register'ı oku, fonksiyonu uygula, sonucu kaydet
|
||
- Sıfıra bölme kontrolü yapılır
|
||
- **`handle_neg()`** — Sadece Number tipinde tekli negatif
|
||
|
||
### Karşılaştırma
|
||
- **`compare_op(f, name)`** — Decimal değerler üzerinde karşılaştırma, Boolean döndürür
|
||
|
||
### Boolean
|
||
- **`handle_and()`**, **`handle_or()`**, **`handle_not()`** — Boolean register'lar üzerinde mantık operasyonları
|
||
|
||
### Kontrol Akışı
|
||
- **`handle_jump()`** — 4-byte adres oku, reader pozisyonunu ayarla
|
||
- **`handle_jump_if_false()`** — Register `Boolean(false)` ise atla
|
||
|
||
### String, Nesne ve Metodlar
|
||
- **`handle_concat()`** — İki String register'ını birleştir
|
||
- **`handle_get_property()`** — Object register'ından alan oku, alan yoksa `Null` döndür
|
||
- **`handle_set_property()`** — Object register'ında alan değerini ayarla
|
||
- **`handle_method_call()`** — Nesne register'ı, metod adı, argümanlar
|
||
- **String metodları:** `upper`, `lower`, `trim`, `trimStart`, `trimEnd`, `split(delimiter)`, `replace(old, new)`, `startsWith(prefix)`, `endsWith(suffix)`, `contains(substr)`, `length`, `charAt(index)`, `substring(start, end?)`
|
||
- **StringList metodları:** `length`/`len`, `isEmpty`, `first`, `last`, `get(index)`, `contains(value)`, `indexOf(value)`, `slice(start, end?)`, `reverse()`, `sort()`, `join(delimiter?)`
|
||
- **NumberList metodları:** `length`/`len`, `isEmpty`, `first`, `last`, `get(index)`, `contains(value)`, `indexOf(value)`, `slice(start, end?)`, `reverse()`, `sort()`, `sum`, `avg`, `min`, `max`
|
||
- **Object metodları:** `keys()`, `values()`, `length`/`len()`, `contains(key)`, `get(key)`
|
||
- **Harici metodlar:** Yukarıdaki built-in metodlar bulunamazsa `external_methods` HashMap'inde aranır
|
||
|
||
### Üyelik Testi
|
||
- **`handle_contains()`** — `in` operatörü: String in StringList, Number in NumberList, String in String (substring), String in Object (anahtar varlığı kontrolü)
|
||
|
||
### Harici Fonksiyonlar ve Sonuç
|
||
- **`handle_call_external()`** — İsimle harici fonksiyon çağır (HashMap lookup)
|
||
- **`handle_set_result()`** — ExprStmt sonucunu `last_result`'a kaydet
|
||
|
||
### Built-in
|
||
- **`handle_log()`** — Register değerini stdout'a yazdır
|
||
- **`rand(min, max)`** — min ile max arasında rastgele tamsayı üret (varsayılan harici fonksiyon)
|
||
|
||
---
|
||
|
||
## Yardımcı Metodlar
|
||
|
||
| Metod | Açıklama |
|
||
|-------|----------|
|
||
| `read_register_checked()` | Register oku ve doğrula |
|
||
| `validate_register()` | Register indeks sınır kontrolü |
|
||
| `read_jump_address()` | 4-byte adres oku ve sınır kontrolü yap |
|
||
| `set_position(addr)` | Reader pozisyonunu doğrulayarak ayarla |
|
||
| `wrap_error(err)` | Hataya kaynak konum bilgisi ekle |
|
||
| `debug_print_state()` | Debug çıktısı (debug build) |
|
||
| `print_profile_summary()` | Opcode çalışma sayıları (debug build) |
|
||
|
||
---
|
||
|
||
## Harici Fonksiyon ve Metod Kaydı
|
||
|
||
```rust
|
||
// Harici fonksiyon
|
||
vm.register_function("getRate", |args| {
|
||
match &args[0] {
|
||
Value::String(currency) => Ok(Value::Number(dec!(34.5))),
|
||
_ => Err("expected string".to_string()),
|
||
}
|
||
});
|
||
|
||
// Tipe özel harici metod
|
||
vm.register_method("Number", "format", |this, args| {
|
||
// this: &Value, args: &[Value]
|
||
Ok(Value::String("formatted".into()))
|
||
});
|
||
```
|
||
|
||
**Tip isimleri:** `"Number"`, `"String"`, `"Boolean"`, `"NumberList"`, `"StringList"`, `"Object"`, `"Null"`
|
||
|
||
---
|
||
|
||
## Çalışma Modeli Özeti
|
||
|
||
- **Register tabanlı:** 8 register ile hesaplama
|
||
- **Global depo:** SmolStr → Value map'i
|
||
- **Harici fonksiyonlar:** İsimle çözümlenen host fonksiyonları (HashMap lookup)
|
||
- **Harici metodlar:** Tipe özel host metodları
|
||
- **Expression return:** Son ExprStmt'ın değeri `execute()` dönüş değeri olarak verilir
|
||
- **Dinamik tip sistemi:** Tip uyuşmazlıklarında çalışma zamanı hatası
|