@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
|
@@ -29,6 +29,7 @@ pub fn binop_to_u8(op: BinOp) -> u8 {
|
|
|
29
29
|
Shl => 19,
|
|
30
30
|
Shr => 20,
|
|
31
31
|
In => 21,
|
|
32
|
+
UShr => 22,
|
|
32
33
|
}
|
|
33
34
|
}
|
|
34
35
|
|
|
@@ -58,6 +59,7 @@ pub fn u8_to_binop(b: u8) -> Option<BinOp> {
|
|
|
58
59
|
19 => Shl,
|
|
59
60
|
20 => Shr,
|
|
60
61
|
21 => In,
|
|
62
|
+
22 => UShr,
|
|
61
63
|
_ => return None,
|
|
62
64
|
})
|
|
63
65
|
}
|
|
@@ -12,7 +12,8 @@ pub const NO_REST_PARAM: u16 = 0xFFFF;
|
|
|
12
12
|
|
|
13
13
|
pub use chunk::{Chunk, Constant};
|
|
14
14
|
pub use compiler::{
|
|
15
|
-
compile, compile_for_repl, compile_for_repl_unoptimized, compile_unoptimized,
|
|
15
|
+
compile, compile_for_repl, compile_for_repl_unoptimized, compile_unoptimized,
|
|
16
|
+
compile_with_source, CompileError,
|
|
16
17
|
};
|
|
17
18
|
pub use encoding::{binop_to_u8, compound_op_to_u8, u8_to_binop, u8_to_unaryop, unaryop_to_u8};
|
|
18
19
|
pub use opcode::Opcode;
|
|
@@ -96,14 +96,51 @@ pub enum Opcode {
|
|
|
96
96
|
/// Pop the `await` operand value; if it is a `Promise`, block until settled, push the result,
|
|
97
97
|
/// or unwind to `catch` like `Throw` on rejection.
|
|
98
98
|
AwaitPromise = 43,
|
|
99
|
+
/// Load a local variable by frame slot (operand: u16 slot). Fast path: direct
|
|
100
|
+
/// index into the current call frame's locals, no name lookup.
|
|
101
|
+
LoadLocal = 44,
|
|
102
|
+
/// Store top of stack into a local frame slot (operand: u16 slot). Leaves nothing.
|
|
103
|
+
StoreLocal = 45,
|
|
104
|
+
/// Load a captured variable from an enclosing frame (operands: u16 hops, u16 slot).
|
|
105
|
+
/// Walks `hops` parent frames, then indexes `slot`.
|
|
106
|
+
LoadUpvalue = 46,
|
|
107
|
+
/// Store top of stack into an enclosing frame slot (operands: u16 hops, u16 slot).
|
|
108
|
+
StoreUpvalue = 47,
|
|
109
|
+
/// Begin a per-iteration binding region for a loop variable (operand: u16 name index).
|
|
110
|
+
/// Registers the name so closures created in the loop body snapshot it into a fresh overlay
|
|
111
|
+
/// (ES `let` per-iteration semantics); the rest of the frame stays shared. Emitted only when
|
|
112
|
+
/// the loop body creates a closure, so closure-free (hot) loops are untouched.
|
|
113
|
+
LoopVarsBegin = 48,
|
|
114
|
+
/// End the innermost per-iteration binding region (no operand).
|
|
115
|
+
LoopVarsEnd = 49,
|
|
116
|
+
/// Push `Bool(param_index >= argc)` — true when the positional argument at `param_index`
|
|
117
|
+
/// was not supplied by the caller (operand: u16 param index). Emitted by the function
|
|
118
|
+
/// prologue so default parameter values apply only for *missing* args, matching the
|
|
119
|
+
/// interpreter: an explicit `null` argument does NOT trigger the default.
|
|
120
|
+
ArgMissing = 50,
|
|
121
|
+
/// Direct self-recursive call (operand: u16 arg count). Emitted by the compiler ONLY when a
|
|
122
|
+
/// `fn NAME` body calls `NAME(args)` and `NAME` is provably the function itself (not shadowed
|
|
123
|
+
/// by a param/local, not reassigned anywhere in the body). Args are on the stack as for `Call`,
|
|
124
|
+
/// but the callee is implicitly the currently-executing chunk — no name lookup, no closure
|
|
125
|
+
/// dispatch. The numeric JIT lowers this to a native recursive call (the big recursion win);
|
|
126
|
+
/// the VM runs the current chunk directly. Behaviour is identical to `LoadVar NAME; Call argc`.
|
|
127
|
+
SelfCall = 51,
|
|
128
|
+
/// Normalize the top-of-stack iterable for `for…of`: a JS iterator object (one with a
|
|
129
|
+
/// callable `next()` returning `{ value, done }`, e.g. a `Map`/`Set` `.values()` result)
|
|
130
|
+
/// is drained into an array; arrays/strings/anything else pass through unchanged. Emitted
|
|
131
|
+
/// right after the iterable expression so the existing index-based loop can iterate it.
|
|
132
|
+
IterNormalize = 52,
|
|
133
|
+
/// `delete obj[key]` / `delete obj.prop`. Pops `[obj, key]`, removes the property
|
|
134
|
+
/// (objects: drop the key; arrays: set the index to a null hole), pushes `true`.
|
|
135
|
+
DeleteIndex = 53,
|
|
99
136
|
}
|
|
100
137
|
|
|
101
138
|
impl Opcode {
|
|
102
|
-
/// Decode byte to opcode. Safe for b in 0..=
|
|
139
|
+
/// Decode byte to opcode. Safe for b in 0..=53 (matches #[repr(u8)] discriminants).
|
|
103
140
|
#[inline]
|
|
104
141
|
pub fn from_u8(b: u8) -> Option<Opcode> {
|
|
105
|
-
if b <=
|
|
106
|
-
Some(unsafe { std::mem::transmute(b) })
|
|
142
|
+
if b <= 53 {
|
|
143
|
+
Some(unsafe { std::mem::transmute::<u8, Opcode>(b) })
|
|
107
144
|
} else {
|
|
108
145
|
None
|
|
109
146
|
}
|
|
@@ -127,11 +164,17 @@ impl Opcode {
|
|
|
127
164
|
| Opcode::ConstructSpread
|
|
128
165
|
| Opcode::EnterBlock
|
|
129
166
|
| Opcode::ExitBlock
|
|
167
|
+
| Opcode::LoopVarsEnd
|
|
168
|
+
| Opcode::IterNormalize
|
|
169
|
+
| Opcode::DeleteIndex
|
|
130
170
|
| Opcode::AwaitPromise => 1,
|
|
131
171
|
Opcode::ArraySortByProperty
|
|
132
172
|
| Opcode::ArrayMapBinOp
|
|
133
173
|
| Opcode::ArrayFilterBinOp
|
|
134
|
-
| Opcode::LoadNativeExport
|
|
174
|
+
| Opcode::LoadNativeExport
|
|
175
|
+
| Opcode::LoadUpvalue
|
|
176
|
+
| Opcode::StoreUpvalue => 5,
|
|
177
|
+
// LoadLocal / StoreLocal take a single u16 operand → 3 bytes (default).
|
|
135
178
|
_ => 3,
|
|
136
179
|
};
|
|
137
180
|
if ip + size > code.len() {
|
|
@@ -48,6 +48,8 @@ pub fn serialize(chunk: &Chunk) -> Vec<u8> {
|
|
|
48
48
|
}
|
|
49
49
|
out.extend_from_slice(&chunk.rest_param_index.to_le_bytes());
|
|
50
50
|
out.extend_from_slice(&chunk.param_count.to_le_bytes());
|
|
51
|
+
out.extend_from_slice(&chunk.num_slots.to_le_bytes());
|
|
52
|
+
out.push(if chunk.slot_based { 1 } else { 0 });
|
|
51
53
|
out
|
|
52
54
|
}
|
|
53
55
|
|
|
@@ -146,12 +148,34 @@ pub fn deserialize(mut data: &[u8]) -> Result<Chunk, String> {
|
|
|
146
148
|
super::NO_REST_PARAM
|
|
147
149
|
};
|
|
148
150
|
let param_count = if data.len() >= 2 {
|
|
149
|
-
let (p_bytes,
|
|
151
|
+
let (p_bytes, rest) = data.split_at(2);
|
|
152
|
+
data = rest;
|
|
150
153
|
u16::from_le_bytes(p_bytes.try_into().unwrap())
|
|
151
154
|
} else {
|
|
152
155
|
0
|
|
153
156
|
};
|
|
157
|
+
let num_slots = if data.len() >= 2 {
|
|
158
|
+
let (s_bytes, rest) = data.split_at(2);
|
|
159
|
+
data = rest;
|
|
160
|
+
u16::from_le_bytes(s_bytes.try_into().unwrap())
|
|
161
|
+
} else {
|
|
162
|
+
0
|
|
163
|
+
};
|
|
164
|
+
let slot_based = if !data.is_empty() {
|
|
165
|
+
let b = data[0] != 0;
|
|
166
|
+
data = &data[1..];
|
|
167
|
+
b
|
|
168
|
+
} else {
|
|
169
|
+
false
|
|
170
|
+
};
|
|
171
|
+
let _ = data;
|
|
154
172
|
|
|
173
|
+
// Inline caches are a runtime-only cache, not serialized — start empty, sized to `names`.
|
|
174
|
+
let inline_caches = crate::chunk::InlineCaches(
|
|
175
|
+
(0..names.len())
|
|
176
|
+
.map(|_| std::sync::atomic::AtomicU64::new(0))
|
|
177
|
+
.collect(),
|
|
178
|
+
);
|
|
155
179
|
Ok(Chunk {
|
|
156
180
|
code,
|
|
157
181
|
constants,
|
|
@@ -159,5 +183,11 @@ pub fn deserialize(mut data: &[u8]) -> Result<Chunk, String> {
|
|
|
159
183
|
nested,
|
|
160
184
|
rest_param_index,
|
|
161
185
|
param_count,
|
|
186
|
+
num_slots,
|
|
187
|
+
slot_based,
|
|
188
|
+
inline_caches,
|
|
189
|
+
// Debug-only; not part of the serialized format (issue #74).
|
|
190
|
+
lines: Vec::new(),
|
|
191
|
+
source: None,
|
|
162
192
|
})
|
|
163
193
|
}
|