@tishlang/tish 1.13.2 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.toml +2 -0
- package/bin/tish +0 -0
- package/crates/js_to_tish/src/transform/expr.rs +1 -0
- package/crates/tish/Cargo.toml +11 -3
- package/crates/tish/build.rs +21 -0
- package/crates/tish/src/cli_help.rs +15 -4
- package/crates/tish/src/main.rs +93 -21
- package/crates/tish/src/repl_completion.rs +0 -1
- package/crates/tish/tests/error_source_location.rs +36 -0
- package/crates/tish/tests/fixtures/runtime_error_location.tish +5 -0
- package/crates/tish/tests/fixtures/trycatch_runtime_errors.tish +15 -0
- package/crates/tish/tests/fixtures/tty_capability.tish +9 -0
- package/crates/tish/tests/integration_test.rs +402 -91
- package/crates/tish/tests/trycatch_runtime_errors.rs +45 -0
- package/crates/tish/tests/tty_capability.rs +43 -0
- package/crates/tish_ast/src/ast.rs +37 -8
- package/crates/tish_builtins/Cargo.toml +2 -0
- package/crates/tish_builtins/src/array.rs +375 -13
- package/crates/tish_builtins/src/collections.rs +481 -0
- package/crates/tish_builtins/src/construct.rs +59 -19
- package/crates/tish_builtins/src/date.rs +538 -0
- package/crates/tish_builtins/src/globals.rs +86 -6
- package/crates/tish_builtins/src/iterator.rs +129 -0
- package/crates/tish_builtins/src/lib.rs +5 -0
- package/crates/tish_builtins/src/number.rs +96 -0
- package/crates/tish_builtins/src/object.rs +2 -2
- package/crates/tish_builtins/src/string.rs +19 -20
- package/crates/tish_builtins/src/symbol.rs +1 -1
- package/crates/tish_builtins/src/typedarrays.rs +298 -0
- package/crates/tish_bytecode/src/chunk.rs +69 -1
- package/crates/tish_bytecode/src/compiler.rs +933 -89
- package/crates/tish_bytecode/src/encoding.rs +2 -0
- package/crates/tish_bytecode/src/lib.rs +2 -1
- package/crates/tish_bytecode/src/opcode.rs +47 -4
- package/crates/tish_bytecode/src/serialize.rs +31 -1
- package/crates/tish_compile/Cargo.toml +1 -0
- package/crates/tish_compile/src/check.rs +774 -0
- package/crates/tish_compile/src/codegen.rs +2334 -349
- package/crates/tish_compile/src/infer.rs +1395 -6
- package/crates/tish_compile/src/lib.rs +50 -8
- package/crates/tish_compile/src/resolve.rs +584 -21
- package/crates/tish_compile/src/types.rs +106 -2
- package/crates/tish_compile_js/src/codegen.rs +67 -0
- package/crates/tish_compile_js/src/tests_jsx.rs +64 -0
- package/crates/tish_core/Cargo.toml +7 -1
- package/crates/tish_core/src/console_style.rs +11 -1
- package/crates/tish_core/src/json.rs +81 -38
- package/crates/tish_core/src/lib.rs +3 -0
- package/crates/tish_core/src/shape.rs +85 -0
- package/crates/tish_core/src/value.rs +679 -25
- package/crates/tish_core/src/vmref.rs +13 -8
- package/crates/tish_cranelift/src/link.rs +17 -4
- package/crates/tish_cranelift_runtime/Cargo.toml +1 -0
- package/crates/tish_eval/Cargo.toml +6 -0
- package/crates/tish_eval/src/eval.rs +665 -117
- package/crates/tish_eval/src/http.rs +4 -1
- package/crates/tish_eval/src/natives.rs +165 -13
- package/crates/tish_eval/src/value.rs +31 -13
- package/crates/tish_eval/src/value_convert.rs +10 -4
- package/crates/tish_ffi/Cargo.toml +26 -0
- package/crates/tish_ffi/src/lib.rs +518 -0
- package/crates/tish_ffi/tests/fixtures/testmod/Cargo.toml +18 -0
- package/crates/tish_ffi/tests/fixtures/testmod/src/lib.rs +46 -0
- package/crates/tish_ffi/tests/loader.rs +65 -0
- package/crates/tish_fmt/src/lib.rs +61 -5
- package/crates/tish_lexer/src/lib.rs +397 -9
- package/crates/tish_lexer/src/token.rs +7 -0
- package/crates/tish_lint/src/lib.rs +2 -10
- package/crates/tish_lsp/src/import_goto.rs +2 -0
- package/crates/tish_lsp/src/main.rs +439 -26
- package/crates/tish_native/src/build.rs +55 -1
- package/crates/tish_opt/src/lib.rs +126 -23
- package/crates/tish_parser/src/lib.rs +55 -1
- package/crates/tish_parser/src/parser.rs +456 -34
- package/crates/tish_pg/src/lib.rs +3 -3
- package/crates/tish_resolve/src/lib.rs +99 -59
- package/crates/tish_runtime/Cargo.toml +4 -0
- package/crates/tish_runtime/src/http.rs +66 -17
- package/crates/tish_runtime/src/http_fetch.rs +29 -8
- package/crates/tish_runtime/src/http_hyper.rs +25 -2
- package/crates/tish_runtime/src/lib.rs +299 -44
- package/crates/tish_runtime/src/promise.rs +328 -18
- package/crates/tish_runtime/src/timers.rs +13 -7
- package/crates/tish_runtime/src/tty.rs +226 -0
- package/crates/tish_runtime/src/ws.rs +35 -18
- package/crates/tish_runtime/tests/fetch_readable_stream.rs +2 -2
- package/crates/tish_ui/src/jsx.rs +10 -0
- package/crates/tish_ui/src/runtime/hooks.rs +19 -15
- package/crates/tish_ui/src/runtime/mod.rs +15 -12
- package/crates/tish_vm/Cargo.toml +14 -1
- package/crates/tish_vm/src/jit.rs +1050 -0
- package/crates/tish_vm/src/lib.rs +2 -0
- package/crates/tish_vm/src/vm.rs +1546 -202
- package/crates/tish_vm/tests/concurrent_shared_state.rs +140 -0
- package/crates/tish_wasm/src/lib.rs +6 -2
- package/crates/tish_wasm_runtime/src/gpu.rs +17 -1
- package/crates/tishlang_cargo_bindgen/src/classify.rs +1 -3
- package/crates/tishlang_cargo_bindgen/src/lib.rs +2 -2
- package/crates/tishlang_cargo_bindgen/src/metadata.rs +1 -1
- package/justfile +8 -0
- package/package.json +1 -1
- package/platform/darwin-arm64/tish +0 -0
- package/platform/darwin-x64/tish +0 -0
- package/platform/linux-arm64/tish +0 -0
- package/platform/linux-x64/tish +0 -0
- package/platform/win32-x64/tish.exe +0 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
//! Hidden-class "shapes" for objects — the JavaScriptCore *Structure* idea.
|
|
2
|
+
//!
|
|
3
|
+
//! A [`ShapeId`] is an interned identity for an object's **ordered string-key set**. Two objects
|
|
4
|
+
//! built by inserting the same keys in the same order share a `ShapeId`. This lets the bytecode VM's
|
|
5
|
+
//! inline caches (see `tish_bytecode::Chunk::inline_caches`) compare a single `u32` instead of hashing
|
|
6
|
+
//! a property name — on a shape hit the property is at a fixed slot index, so access is a direct load.
|
|
7
|
+
//!
|
|
8
|
+
//! Identity is **path-dependent** (like JSC): `{x,y}` and `{y,x}` are *different* shapes, because the
|
|
9
|
+
//! slot index of `x` differs — which is exactly what makes the cached `(shape, index)` correct.
|
|
10
|
+
//!
|
|
11
|
+
//! Phase 1a uses shapes only as opaque identities (the property→index lookup still goes through
|
|
12
|
+
//! `PropMap` on a cache miss). Phase 1b will attach the ordered key list to each shape so objects can
|
|
13
|
+
//! drop per-object key storage entirely (the butterfly representation).
|
|
14
|
+
|
|
15
|
+
use std::collections::HashMap;
|
|
16
|
+
use std::sync::{Arc, OnceLock, RwLock};
|
|
17
|
+
|
|
18
|
+
/// Identity of an object's ordered key-set.
|
|
19
|
+
pub type ShapeId = u32;
|
|
20
|
+
|
|
21
|
+
/// The shape of a freshly-created empty object (`{}`).
|
|
22
|
+
pub const EMPTY_SHAPE: ShapeId = 0;
|
|
23
|
+
|
|
24
|
+
/// Sentinel for objects that have opted out of shape tracking (after a property *delete*, or when the
|
|
25
|
+
/// shape space is exhausted). Such objects never match an inline cache → always the slow path. Chosen
|
|
26
|
+
/// as `u32::MAX` so it can never collide with a real, sequentially-assigned id.
|
|
27
|
+
pub const DICT_SHAPE: ShapeId = u32::MAX;
|
|
28
|
+
|
|
29
|
+
/// One node in the structure-transition tree: from this shape, adding a given key yields a child shape.
|
|
30
|
+
#[derive(Default)]
|
|
31
|
+
struct ShapeNode {
|
|
32
|
+
transitions: HashMap<Arc<str>, ShapeId>,
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
struct Registry {
|
|
36
|
+
nodes: Vec<ShapeNode>,
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
fn registry() -> &'static RwLock<Registry> {
|
|
40
|
+
static REG: OnceLock<RwLock<Registry>> = OnceLock::new();
|
|
41
|
+
REG.get_or_init(|| {
|
|
42
|
+
RwLock::new(Registry {
|
|
43
|
+
// Index 0 == EMPTY_SHAPE.
|
|
44
|
+
nodes: vec![ShapeNode::default()],
|
|
45
|
+
})
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/// The shape reached by adding a **new** key `key` to an object currently of shape `from`.
|
|
50
|
+
///
|
|
51
|
+
/// Cached: the first object to take a given (shape, key) edge creates the child shape; every later
|
|
52
|
+
/// object with the same construction path reuses it. Cheap on the hot path (a read-lock + one hashmap
|
|
53
|
+
/// lookup once the edge exists). A `DICT_SHAPE` input (or shape-space exhaustion) stays `DICT_SHAPE`.
|
|
54
|
+
pub fn transition(from: ShapeId, key: &Arc<str>) -> ShapeId {
|
|
55
|
+
if from == DICT_SHAPE {
|
|
56
|
+
return DICT_SHAPE;
|
|
57
|
+
}
|
|
58
|
+
// Fast path: the edge already exists (the common case after the first object of this shape).
|
|
59
|
+
{
|
|
60
|
+
let reg = registry().read().unwrap();
|
|
61
|
+
match reg.nodes.get(from as usize) {
|
|
62
|
+
Some(node) => {
|
|
63
|
+
if let Some(&next) = node.transitions.get(key.as_ref()) {
|
|
64
|
+
return next;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
None => return DICT_SHAPE, // out of range — should not happen; degrade safely
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Slow path: create the child shape and cache the edge.
|
|
71
|
+
let mut reg = registry().write().unwrap();
|
|
72
|
+
// Re-check under the write lock (another thread may have created it meanwhile).
|
|
73
|
+
if let Some(&next) = reg.nodes[from as usize].transitions.get(key.as_ref()) {
|
|
74
|
+
return next;
|
|
75
|
+
}
|
|
76
|
+
let new_id = reg.nodes.len();
|
|
77
|
+
if new_id >= DICT_SHAPE as usize {
|
|
78
|
+
return DICT_SHAPE; // ran out of shape ids — extremely unlikely; degrade to dictionary mode
|
|
79
|
+
}
|
|
80
|
+
reg.nodes.push(ShapeNode::default());
|
|
81
|
+
reg.nodes[from as usize]
|
|
82
|
+
.transitions
|
|
83
|
+
.insert(Arc::clone(key), new_id as ShapeId);
|
|
84
|
+
new_id as ShapeId
|
|
85
|
+
}
|