mustardscript 0.1.0

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.
Files changed (99) hide show
  1. package/Cargo.lock +1579 -0
  2. package/Cargo.toml +40 -0
  3. package/LICENSE +201 -0
  4. package/README.md +828 -0
  5. package/SECURITY.md +34 -0
  6. package/crates/mustard/Cargo.toml +31 -0
  7. package/crates/mustard/src/cancellation.rs +28 -0
  8. package/crates/mustard/src/diagnostic.rs +145 -0
  9. package/crates/mustard/src/ir.rs +435 -0
  10. package/crates/mustard/src/lib.rs +21 -0
  11. package/crates/mustard/src/limits.rs +22 -0
  12. package/crates/mustard/src/parser/expressions.rs +723 -0
  13. package/crates/mustard/src/parser/mod.rs +115 -0
  14. package/crates/mustard/src/parser/operators.rs +105 -0
  15. package/crates/mustard/src/parser/patterns.rs +123 -0
  16. package/crates/mustard/src/parser/scope.rs +107 -0
  17. package/crates/mustard/src/parser/statements.rs +298 -0
  18. package/crates/mustard/src/parser/tests/acceptance.rs +339 -0
  19. package/crates/mustard/src/parser/tests/mod.rs +2 -0
  20. package/crates/mustard/src/parser/tests/rejections.rs +107 -0
  21. package/crates/mustard/src/runtime/accounting.rs +613 -0
  22. package/crates/mustard/src/runtime/api.rs +192 -0
  23. package/crates/mustard/src/runtime/async_runtime/mod.rs +5 -0
  24. package/crates/mustard/src/runtime/async_runtime/promises.rs +246 -0
  25. package/crates/mustard/src/runtime/async_runtime/reactions.rs +400 -0
  26. package/crates/mustard/src/runtime/async_runtime/scheduler.rs +224 -0
  27. package/crates/mustard/src/runtime/builtins/arrays.rs +1205 -0
  28. package/crates/mustard/src/runtime/builtins/collections.rs +573 -0
  29. package/crates/mustard/src/runtime/builtins/install.rs +501 -0
  30. package/crates/mustard/src/runtime/builtins/intl.rs +553 -0
  31. package/crates/mustard/src/runtime/builtins/mod.rs +25 -0
  32. package/crates/mustard/src/runtime/builtins/objects.rs +405 -0
  33. package/crates/mustard/src/runtime/builtins/primitives.rs +859 -0
  34. package/crates/mustard/src/runtime/builtins/promises.rs +335 -0
  35. package/crates/mustard/src/runtime/builtins/regexp.rs +356 -0
  36. package/crates/mustard/src/runtime/builtins/strings.rs +803 -0
  37. package/crates/mustard/src/runtime/builtins/support.rs +561 -0
  38. package/crates/mustard/src/runtime/bytecode.rs +123 -0
  39. package/crates/mustard/src/runtime/compiler/assignments.rs +690 -0
  40. package/crates/mustard/src/runtime/compiler/bindings.rs +92 -0
  41. package/crates/mustard/src/runtime/compiler/context.rs +46 -0
  42. package/crates/mustard/src/runtime/compiler/control.rs +342 -0
  43. package/crates/mustard/src/runtime/compiler/expressions.rs +372 -0
  44. package/crates/mustard/src/runtime/compiler/mod.rs +173 -0
  45. package/crates/mustard/src/runtime/compiler/statements.rs +459 -0
  46. package/crates/mustard/src/runtime/conversions/boundary.rs +293 -0
  47. package/crates/mustard/src/runtime/conversions/coercions.rs +217 -0
  48. package/crates/mustard/src/runtime/conversions/errors.rs +118 -0
  49. package/crates/mustard/src/runtime/conversions/mod.rs +14 -0
  50. package/crates/mustard/src/runtime/conversions/operators.rs +334 -0
  51. package/crates/mustard/src/runtime/env.rs +355 -0
  52. package/crates/mustard/src/runtime/exceptions.rs +377 -0
  53. package/crates/mustard/src/runtime/gc.rs +595 -0
  54. package/crates/mustard/src/runtime/mod.rs +318 -0
  55. package/crates/mustard/src/runtime/properties.rs +1762 -0
  56. package/crates/mustard/src/runtime/serialization.rs +127 -0
  57. package/crates/mustard/src/runtime/shared.rs +108 -0
  58. package/crates/mustard/src/runtime/snapshot_validation_tests.rs +93 -0
  59. package/crates/mustard/src/runtime/state.rs +652 -0
  60. package/crates/mustard/src/runtime/tests/async_host.rs +104 -0
  61. package/crates/mustard/src/runtime/tests/collections.rs +50 -0
  62. package/crates/mustard/src/runtime/tests/diagnostics.rs +36 -0
  63. package/crates/mustard/src/runtime/tests/exceptions.rs +122 -0
  64. package/crates/mustard/src/runtime/tests/execution.rs +553 -0
  65. package/crates/mustard/src/runtime/tests/gc.rs +533 -0
  66. package/crates/mustard/src/runtime/tests/mod.rs +56 -0
  67. package/crates/mustard/src/runtime/tests/serialization.rs +170 -0
  68. package/crates/mustard/src/runtime/validation/bytecode.rs +484 -0
  69. package/crates/mustard/src/runtime/validation/mod.rs +14 -0
  70. package/crates/mustard/src/runtime/validation/policy.rs +94 -0
  71. package/crates/mustard/src/runtime/validation/snapshot.rs +406 -0
  72. package/crates/mustard/src/runtime/validation/walk.rs +206 -0
  73. package/crates/mustard/src/runtime/vm.rs +1016 -0
  74. package/crates/mustard/src/span.rs +22 -0
  75. package/crates/mustard/src/structured.rs +107 -0
  76. package/crates/mustard-bridge/Cargo.toml +17 -0
  77. package/crates/mustard-bridge/src/codec.rs +46 -0
  78. package/crates/mustard-bridge/src/dto.rs +99 -0
  79. package/crates/mustard-bridge/src/lib.rs +12 -0
  80. package/crates/mustard-bridge/src/operations.rs +142 -0
  81. package/crates/mustard-node/Cargo.toml +24 -0
  82. package/crates/mustard-node/build.rs +3 -0
  83. package/crates/mustard-node/src/lib.rs +236 -0
  84. package/crates/mustard-sidecar/Cargo.toml +21 -0
  85. package/crates/mustard-sidecar/src/lib.rs +134 -0
  86. package/crates/mustard-sidecar/src/main.rs +36 -0
  87. package/dist/index.js +20 -0
  88. package/dist/install.js +117 -0
  89. package/dist/lib/cancellation.js +124 -0
  90. package/dist/lib/errors.js +46 -0
  91. package/dist/lib/executor.js +555 -0
  92. package/dist/lib/policy.js +292 -0
  93. package/dist/lib/progress.js +356 -0
  94. package/dist/lib/runtime.js +109 -0
  95. package/dist/lib/structured.js +286 -0
  96. package/dist/native-loader.js +227 -0
  97. package/index.d.ts +23 -0
  98. package/mustard.d.ts +220 -0
  99. package/package.json +97 -0
@@ -0,0 +1,405 @@
1
+ use super::*;
2
+
3
+ impl Runtime {
4
+ fn object_helper_type_error() -> MustardError {
5
+ MustardError::runtime(
6
+ "TypeError: Object helpers currently only support plain objects and arrays",
7
+ )
8
+ }
9
+
10
+ fn object_spread_type_error() -> MustardError {
11
+ MustardError::runtime(
12
+ "TypeError: object spread currently only supports plain objects and arrays",
13
+ )
14
+ }
15
+
16
+ fn ensure_assign_target(&self, value: Value) -> MustardResult<()> {
17
+ match value {
18
+ Value::Object(object) => match self
19
+ .objects
20
+ .get(object)
21
+ .ok_or_else(|| MustardError::runtime("object missing"))?
22
+ .kind
23
+ {
24
+ ObjectKind::Plain
25
+ | ObjectKind::FunctionPrototype(_)
26
+ | ObjectKind::NumberObject(_)
27
+ | ObjectKind::StringObject(_)
28
+ | ObjectKind::BooleanObject(_) => Ok(()),
29
+ _ => Err(Self::object_helper_type_error()),
30
+ },
31
+ Value::Array(array) => {
32
+ self.arrays
33
+ .get(array)
34
+ .ok_or_else(|| MustardError::runtime("array missing"))?;
35
+ Ok(())
36
+ }
37
+ Value::Closure(closure) => {
38
+ self.closures
39
+ .get(closure)
40
+ .ok_or_else(|| MustardError::runtime("closure missing"))?;
41
+ Ok(())
42
+ }
43
+ Value::BuiltinFunction(_) | Value::HostFunction(_) => Ok(()),
44
+ _ => Err(Self::object_helper_type_error()),
45
+ }
46
+ }
47
+
48
+ fn ensure_object_spread_source(&self, value: Value) -> MustardResult<()> {
49
+ match value {
50
+ Value::Object(object) => match self
51
+ .objects
52
+ .get(object)
53
+ .ok_or_else(|| MustardError::runtime("object missing"))?
54
+ .kind
55
+ {
56
+ ObjectKind::Plain => Ok(()),
57
+ _ => Err(Self::object_spread_type_error()),
58
+ },
59
+ Value::Array(array) => {
60
+ self.arrays
61
+ .get(array)
62
+ .ok_or_else(|| MustardError::runtime("array missing"))?;
63
+ Ok(())
64
+ }
65
+ _ => Err(Self::object_spread_type_error()),
66
+ }
67
+ }
68
+ fn enumerable_keys(&mut self, value: Value) -> MustardResult<Vec<String>> {
69
+ match value {
70
+ Value::Object(object) => {
71
+ let (count, keys) = {
72
+ let object = self
73
+ .objects
74
+ .get(object)
75
+ .ok_or_else(|| MustardError::runtime("object missing"))?;
76
+ match &object.kind {
77
+ ObjectKind::StringObject(value) => {
78
+ let mut keys = (0..value.chars().count())
79
+ .map(|index| index.to_string())
80
+ .collect::<Vec<_>>();
81
+ keys.extend(ordered_own_property_keys(&object.properties));
82
+ (keys.len(), keys)
83
+ }
84
+ _ => (
85
+ object.properties.len(),
86
+ ordered_own_property_keys(&object.properties),
87
+ ),
88
+ }
89
+ };
90
+ self.charge_native_helper_work(count)?;
91
+ Ok(keys)
92
+ }
93
+ Value::Array(array) => {
94
+ let (array_len, extra_len, extra_keys) = {
95
+ let array = self
96
+ .arrays
97
+ .get(array)
98
+ .ok_or_else(|| MustardError::runtime("array missing"))?;
99
+ (
100
+ array
101
+ .elements
102
+ .iter()
103
+ .enumerate()
104
+ .filter_map(|(index, value)| value.as_ref().map(|_| index.to_string()))
105
+ .collect::<Vec<_>>(),
106
+ array.properties.len(),
107
+ ordered_own_property_keys(&array.properties),
108
+ )
109
+ };
110
+ let mut keys = array_len;
111
+ self.charge_native_helper_work(keys.len())?;
112
+ self.charge_native_helper_work(extra_len)?;
113
+ keys.extend(extra_keys);
114
+ Ok(keys)
115
+ }
116
+ Value::Closure(closure) => {
117
+ let keys = ordered_own_property_keys(
118
+ &self
119
+ .closures
120
+ .get(closure)
121
+ .ok_or_else(|| MustardError::runtime("closure missing"))?
122
+ .properties,
123
+ );
124
+ self.charge_native_helper_work(keys.len())?;
125
+ Ok(keys)
126
+ }
127
+ Value::BuiltinFunction(function) => {
128
+ let keys = self.builtin_function_custom_keys(function)?;
129
+ self.charge_native_helper_work(keys.len())?;
130
+ Ok(keys)
131
+ }
132
+ Value::HostFunction(capability) => {
133
+ let keys = self.host_function_custom_keys(&capability)?;
134
+ self.charge_native_helper_work(keys.len())?;
135
+ Ok(keys)
136
+ }
137
+ _ => Err(Self::object_helper_type_error()),
138
+ }
139
+ }
140
+
141
+ fn enumerable_value(&self, target: Value, key: &str) -> MustardResult<Value> {
142
+ match target {
143
+ Value::Object(object) => {
144
+ let object = self
145
+ .objects
146
+ .get(object)
147
+ .ok_or_else(|| MustardError::runtime("object missing"))?;
148
+ if let ObjectKind::StringObject(value) = &object.kind
149
+ && let Some(index) = array_index_from_property_key(key)
150
+ && let Some(ch) = value.chars().nth(index)
151
+ {
152
+ return Ok(Value::String(ch.to_string()));
153
+ }
154
+ object
155
+ .properties
156
+ .get(key)
157
+ .cloned()
158
+ .ok_or_else(|| MustardError::runtime("object property missing"))
159
+ }
160
+ Value::Array(array) => {
161
+ let array = self
162
+ .arrays
163
+ .get(array)
164
+ .ok_or_else(|| MustardError::runtime("array missing"))?;
165
+ if let Some(index) = array_index_from_property_key(key) {
166
+ Ok(array
167
+ .elements
168
+ .get(index)
169
+ .cloned()
170
+ .flatten()
171
+ .unwrap_or(Value::Undefined))
172
+ } else {
173
+ array
174
+ .properties
175
+ .get(key)
176
+ .cloned()
177
+ .ok_or_else(|| MustardError::runtime("array property missing"))
178
+ }
179
+ }
180
+ Value::Closure(closure) => self
181
+ .closures
182
+ .get(closure)
183
+ .and_then(|closure| closure.properties.get(key))
184
+ .cloned()
185
+ .ok_or_else(|| MustardError::runtime("closure property missing")),
186
+ Value::BuiltinFunction(function) => self
187
+ .builtin_function_custom_property(function, key)?
188
+ .ok_or_else(|| MustardError::runtime("builtin function property missing")),
189
+ Value::HostFunction(capability) => self
190
+ .host_function_custom_property(&capability, key)?
191
+ .ok_or_else(|| MustardError::runtime("host function property missing")),
192
+ _ => Err(Self::object_helper_type_error()),
193
+ }
194
+ }
195
+
196
+ pub(crate) fn copy_data_properties(
197
+ &mut self,
198
+ target: Value,
199
+ source: Value,
200
+ ) -> MustardResult<()> {
201
+ self.ensure_assign_target(target.clone())?;
202
+ if matches!(source, Value::Null | Value::Undefined) {
203
+ return Ok(());
204
+ }
205
+
206
+ self.ensure_object_spread_source(source.clone())?;
207
+ let keys = self.enumerable_keys(source.clone())?;
208
+ for key in keys {
209
+ let value = self.enumerable_value(source.clone(), &key)?;
210
+ self.set_property(target.clone(), Value::String(key), value)?;
211
+ }
212
+ Ok(())
213
+ }
214
+
215
+ pub(crate) fn call_object_assign(&mut self, args: &[Value]) -> MustardResult<Value> {
216
+ let target = args.first().cloned().unwrap_or(Value::Undefined);
217
+ self.ensure_assign_target(target.clone())?;
218
+
219
+ for source in args.iter().skip(1).cloned() {
220
+ if matches!(source, Value::Null | Value::Undefined) {
221
+ continue;
222
+ }
223
+ self.ensure_assign_target(source.clone())?;
224
+ let keys = self.enumerable_keys(source.clone())?;
225
+ for key in keys {
226
+ let value = self.enumerable_value(source.clone(), &key)?;
227
+ self.set_property(target.clone(), Value::String(key), value)?;
228
+ }
229
+ }
230
+
231
+ Ok(target)
232
+ }
233
+
234
+ pub(crate) fn call_object_ctor(&mut self, args: &[Value]) -> MustardResult<Value> {
235
+ match args.first().cloned().unwrap_or(Value::Undefined) {
236
+ Value::Undefined | Value::Null => Ok(Value::Object(
237
+ self.insert_object(IndexMap::new(), ObjectKind::Plain)?,
238
+ )),
239
+ Value::Bool(value) => Ok(Value::Object(
240
+ self.insert_object(IndexMap::new(), ObjectKind::BooleanObject(value))?,
241
+ )),
242
+ Value::Number(value) => Ok(Value::Object(
243
+ self.insert_object(IndexMap::new(), ObjectKind::NumberObject(value))?,
244
+ )),
245
+ Value::String(value) => Ok(Value::Object(
246
+ self.insert_object(IndexMap::new(), ObjectKind::StringObject(value))?,
247
+ )),
248
+ value @ (Value::Object(_)
249
+ | Value::Array(_)
250
+ | Value::Map(_)
251
+ | Value::Set(_)
252
+ | Value::Iterator(_)
253
+ | Value::Promise(_)
254
+ | Value::Closure(_)
255
+ | Value::BuiltinFunction(_)
256
+ | Value::HostFunction(_)) => Ok(value),
257
+ Value::BigInt(_) => Err(MustardError::runtime(
258
+ "TypeError: BigInt values cannot be boxed with Object in the supported surface",
259
+ )),
260
+ }
261
+ }
262
+
263
+ pub(crate) fn reject_object_create(&self) -> MustardResult<Value> {
264
+ Err(MustardError::runtime(
265
+ "TypeError: Object.create is unsupported because prototype semantics are deferred",
266
+ ))
267
+ }
268
+
269
+ pub(crate) fn reject_object_freeze(&self) -> MustardResult<Value> {
270
+ Err(MustardError::runtime(
271
+ "TypeError: Object.freeze is unsupported because property descriptor semantics are deferred",
272
+ ))
273
+ }
274
+
275
+ pub(crate) fn reject_object_seal(&self) -> MustardResult<Value> {
276
+ Err(MustardError::runtime(
277
+ "TypeError: Object.seal is unsupported because property descriptor semantics are deferred",
278
+ ))
279
+ }
280
+
281
+ pub(crate) fn call_object_keys(&mut self, args: &[Value]) -> MustardResult<Value> {
282
+ let target = args.first().cloned().unwrap_or(Value::Undefined);
283
+ let keys = self
284
+ .enumerable_keys(target)?
285
+ .into_iter()
286
+ .map(Value::String)
287
+ .collect();
288
+ Ok(Value::Array(self.insert_array(keys, IndexMap::new())?))
289
+ }
290
+
291
+ pub(crate) fn call_object_from_entries(&mut self, args: &[Value]) -> MustardResult<Value> {
292
+ let iterable = args.first().cloned().unwrap_or(Value::Undefined);
293
+ let iterator = self.create_iterator(iterable.clone())?;
294
+ let result = self.insert_object(IndexMap::new(), ObjectKind::Plain)?;
295
+ self.with_temporary_roots(
296
+ &[iterable, iterator.clone(), Value::Object(result)],
297
+ |runtime| {
298
+ loop {
299
+ let (entry, done) = runtime.iterator_next(iterator.clone())?;
300
+ if done {
301
+ break;
302
+ }
303
+ let items: Vec<Value> = match entry {
304
+ Value::Array(array) => runtime
305
+ .arrays
306
+ .get(array)
307
+ .ok_or_else(|| MustardError::runtime("array missing"))?
308
+ .elements
309
+ .iter()
310
+ .map(|value| value.clone().unwrap_or(Value::Undefined))
311
+ .collect(),
312
+ _ => {
313
+ return Err(MustardError::runtime(
314
+ "TypeError: Object.fromEntries expects an iterable of [key, value] pairs",
315
+ ));
316
+ }
317
+ };
318
+ let key = runtime
319
+ .to_property_key(items.first().cloned().unwrap_or(Value::Undefined))?;
320
+ let value = items.get(1).cloned().unwrap_or(Value::Undefined);
321
+ runtime
322
+ .objects
323
+ .get_mut(result)
324
+ .ok_or_else(|| MustardError::runtime("object missing"))?
325
+ .properties
326
+ .insert(key, value);
327
+ runtime.refresh_object_accounting(result)?;
328
+ }
329
+ Ok(Value::Object(result))
330
+ },
331
+ )
332
+ }
333
+
334
+ pub(crate) fn call_object_values(&mut self, args: &[Value]) -> MustardResult<Value> {
335
+ let target = args.first().cloned().unwrap_or(Value::Undefined);
336
+ let keys = self.enumerable_keys(target.clone())?;
337
+ let mut values = Vec::with_capacity(keys.len());
338
+ for key in keys {
339
+ self.charge_native_helper_work(1)?;
340
+ values.push(self.enumerable_value(target.clone(), &key)?);
341
+ }
342
+ Ok(Value::Array(self.insert_array(values, IndexMap::new())?))
343
+ }
344
+
345
+ pub(crate) fn call_object_entries(&mut self, args: &[Value]) -> MustardResult<Value> {
346
+ let target = args.first().cloned().unwrap_or(Value::Undefined);
347
+ let keys = self.enumerable_keys(target.clone())?;
348
+ let mut entries = Vec::with_capacity(keys.len());
349
+ for key in keys {
350
+ self.charge_native_helper_work(1)?;
351
+ let pair = self.insert_array(
352
+ vec![
353
+ Value::String(key.clone()),
354
+ self.enumerable_value(target.clone(), &key)?,
355
+ ],
356
+ IndexMap::new(),
357
+ )?;
358
+ entries.push(Value::Array(pair));
359
+ }
360
+ Ok(Value::Array(self.insert_array(entries, IndexMap::new())?))
361
+ }
362
+
363
+ pub(crate) fn call_object_has_own(&self, args: &[Value]) -> MustardResult<Value> {
364
+ let target = args.first().cloned().unwrap_or(Value::Undefined);
365
+ let key = self.to_property_key(args.get(1).cloned().unwrap_or(Value::Undefined))?;
366
+ let has_key = match target {
367
+ Value::Object(object) => {
368
+ let object = self
369
+ .objects
370
+ .get(object)
371
+ .ok_or_else(|| MustardError::runtime("object missing"))?;
372
+ object.properties.contains_key(&key)
373
+ || matches!(&object.kind, ObjectKind::FunctionPrototype(_) if key == "constructor")
374
+ || matches!(&object.kind, ObjectKind::StringObject(_) if key == "length")
375
+ || matches!(&object.kind, ObjectKind::StringObject(value)
376
+ if array_index_from_property_key(&key)
377
+ .is_some_and(|index| value.chars().nth(index).is_some()))
378
+ || matches!(&object.kind, ObjectKind::BoundFunction(_) if matches!(key.as_str(), "name" | "length"))
379
+ }
380
+ Value::Array(array) => {
381
+ let array = self
382
+ .arrays
383
+ .get(array)
384
+ .ok_or_else(|| MustardError::runtime("array missing"))?;
385
+ key == "length"
386
+ || array_index_from_property_key(&key)
387
+ .is_some_and(|index| array.elements.get(index).is_some_and(Option::is_some))
388
+ || array.properties.contains_key(&key)
389
+ }
390
+ Value::Closure(closure) => self.closure_has_own_property(closure, &key)?,
391
+ Value::BuiltinFunction(function) => {
392
+ self.builtin_function_custom_property(function, &key)?
393
+ .is_some()
394
+ || self.builtin_function_own_property(function, &key).is_some()
395
+ }
396
+ Value::HostFunction(capability) => {
397
+ self.host_function_custom_property(&capability, &key)?
398
+ .is_some()
399
+ || matches!(key.as_str(), "name" | "length")
400
+ }
401
+ _ => return Err(Self::object_helper_type_error()),
402
+ };
403
+ Ok(Value::Bool(has_key))
404
+ }
405
+ }