mustardscript 0.1.0 → 0.1.2

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 (96) hide show
  1. package/README.md +65 -22
  2. package/SECURITY.md +1 -1
  3. package/dist/index.js +2 -0
  4. package/dist/lib/executor.js +16 -1
  5. package/dist/lib/policy.js +301 -22
  6. package/dist/lib/progress.js +499 -113
  7. package/dist/lib/runtime.js +109 -40
  8. package/dist/lib/structured.js +327 -11
  9. package/dist/native-loader.js +11 -12
  10. package/index.d.ts +54 -6
  11. package/mustard.d.ts +23 -1
  12. package/package.json +34 -25
  13. package/Cargo.lock +0 -1579
  14. package/Cargo.toml +0 -40
  15. package/crates/mustard/Cargo.toml +0 -31
  16. package/crates/mustard/src/cancellation.rs +0 -28
  17. package/crates/mustard/src/diagnostic.rs +0 -145
  18. package/crates/mustard/src/ir.rs +0 -435
  19. package/crates/mustard/src/lib.rs +0 -21
  20. package/crates/mustard/src/limits.rs +0 -22
  21. package/crates/mustard/src/parser/expressions.rs +0 -723
  22. package/crates/mustard/src/parser/mod.rs +0 -115
  23. package/crates/mustard/src/parser/operators.rs +0 -105
  24. package/crates/mustard/src/parser/patterns.rs +0 -123
  25. package/crates/mustard/src/parser/scope.rs +0 -107
  26. package/crates/mustard/src/parser/statements.rs +0 -298
  27. package/crates/mustard/src/parser/tests/acceptance.rs +0 -339
  28. package/crates/mustard/src/parser/tests/mod.rs +0 -2
  29. package/crates/mustard/src/parser/tests/rejections.rs +0 -107
  30. package/crates/mustard/src/runtime/accounting.rs +0 -613
  31. package/crates/mustard/src/runtime/api.rs +0 -192
  32. package/crates/mustard/src/runtime/async_runtime/mod.rs +0 -5
  33. package/crates/mustard/src/runtime/async_runtime/promises.rs +0 -246
  34. package/crates/mustard/src/runtime/async_runtime/reactions.rs +0 -400
  35. package/crates/mustard/src/runtime/async_runtime/scheduler.rs +0 -224
  36. package/crates/mustard/src/runtime/builtins/arrays.rs +0 -1205
  37. package/crates/mustard/src/runtime/builtins/collections.rs +0 -573
  38. package/crates/mustard/src/runtime/builtins/install.rs +0 -501
  39. package/crates/mustard/src/runtime/builtins/intl.rs +0 -553
  40. package/crates/mustard/src/runtime/builtins/mod.rs +0 -25
  41. package/crates/mustard/src/runtime/builtins/objects.rs +0 -405
  42. package/crates/mustard/src/runtime/builtins/primitives.rs +0 -859
  43. package/crates/mustard/src/runtime/builtins/promises.rs +0 -335
  44. package/crates/mustard/src/runtime/builtins/regexp.rs +0 -356
  45. package/crates/mustard/src/runtime/builtins/strings.rs +0 -803
  46. package/crates/mustard/src/runtime/builtins/support.rs +0 -561
  47. package/crates/mustard/src/runtime/bytecode.rs +0 -123
  48. package/crates/mustard/src/runtime/compiler/assignments.rs +0 -690
  49. package/crates/mustard/src/runtime/compiler/bindings.rs +0 -92
  50. package/crates/mustard/src/runtime/compiler/context.rs +0 -46
  51. package/crates/mustard/src/runtime/compiler/control.rs +0 -342
  52. package/crates/mustard/src/runtime/compiler/expressions.rs +0 -372
  53. package/crates/mustard/src/runtime/compiler/mod.rs +0 -173
  54. package/crates/mustard/src/runtime/compiler/statements.rs +0 -459
  55. package/crates/mustard/src/runtime/conversions/boundary.rs +0 -293
  56. package/crates/mustard/src/runtime/conversions/coercions.rs +0 -217
  57. package/crates/mustard/src/runtime/conversions/errors.rs +0 -118
  58. package/crates/mustard/src/runtime/conversions/mod.rs +0 -14
  59. package/crates/mustard/src/runtime/conversions/operators.rs +0 -334
  60. package/crates/mustard/src/runtime/env.rs +0 -355
  61. package/crates/mustard/src/runtime/exceptions.rs +0 -377
  62. package/crates/mustard/src/runtime/gc.rs +0 -595
  63. package/crates/mustard/src/runtime/mod.rs +0 -318
  64. package/crates/mustard/src/runtime/properties.rs +0 -1762
  65. package/crates/mustard/src/runtime/serialization.rs +0 -127
  66. package/crates/mustard/src/runtime/shared.rs +0 -108
  67. package/crates/mustard/src/runtime/snapshot_validation_tests.rs +0 -93
  68. package/crates/mustard/src/runtime/state.rs +0 -652
  69. package/crates/mustard/src/runtime/tests/async_host.rs +0 -104
  70. package/crates/mustard/src/runtime/tests/collections.rs +0 -50
  71. package/crates/mustard/src/runtime/tests/diagnostics.rs +0 -36
  72. package/crates/mustard/src/runtime/tests/exceptions.rs +0 -122
  73. package/crates/mustard/src/runtime/tests/execution.rs +0 -553
  74. package/crates/mustard/src/runtime/tests/gc.rs +0 -533
  75. package/crates/mustard/src/runtime/tests/mod.rs +0 -56
  76. package/crates/mustard/src/runtime/tests/serialization.rs +0 -170
  77. package/crates/mustard/src/runtime/validation/bytecode.rs +0 -484
  78. package/crates/mustard/src/runtime/validation/mod.rs +0 -14
  79. package/crates/mustard/src/runtime/validation/policy.rs +0 -94
  80. package/crates/mustard/src/runtime/validation/snapshot.rs +0 -406
  81. package/crates/mustard/src/runtime/validation/walk.rs +0 -206
  82. package/crates/mustard/src/runtime/vm.rs +0 -1016
  83. package/crates/mustard/src/span.rs +0 -22
  84. package/crates/mustard/src/structured.rs +0 -107
  85. package/crates/mustard-bridge/Cargo.toml +0 -17
  86. package/crates/mustard-bridge/src/codec.rs +0 -46
  87. package/crates/mustard-bridge/src/dto.rs +0 -99
  88. package/crates/mustard-bridge/src/lib.rs +0 -12
  89. package/crates/mustard-bridge/src/operations.rs +0 -142
  90. package/crates/mustard-node/Cargo.toml +0 -24
  91. package/crates/mustard-node/build.rs +0 -3
  92. package/crates/mustard-node/src/lib.rs +0 -236
  93. package/crates/mustard-sidecar/Cargo.toml +0 -21
  94. package/crates/mustard-sidecar/src/lib.rs +0 -134
  95. package/crates/mustard-sidecar/src/main.rs +0 -36
  96. package/dist/install.js +0 -117
@@ -1,1762 +0,0 @@
1
- use super::*;
2
-
3
- impl Runtime {
4
- fn function_helper_method(key: &str) -> Option<Value> {
5
- match key {
6
- "call" => Some(Value::BuiltinFunction(BuiltinFunction::FunctionCall)),
7
- "apply" => Some(Value::BuiltinFunction(BuiltinFunction::FunctionApply)),
8
- "bind" => Some(Value::BuiltinFunction(BuiltinFunction::FunctionBind)),
9
- _ => None,
10
- }
11
- }
12
-
13
- fn callable_constructor() -> Value {
14
- Value::BuiltinFunction(BuiltinFunction::FunctionCtor)
15
- }
16
-
17
- pub(super) fn array_length(&self, array: ArrayKey) -> MustardResult<usize> {
18
- Ok(self
19
- .arrays
20
- .get(array)
21
- .ok_or_else(|| MustardError::runtime("array missing"))?
22
- .elements
23
- .len())
24
- }
25
-
26
- pub(super) fn array_has_index(&self, array: ArrayKey, index: usize) -> MustardResult<bool> {
27
- Ok(self
28
- .arrays
29
- .get(array)
30
- .ok_or_else(|| MustardError::runtime("array missing"))?
31
- .elements
32
- .get(index)
33
- .is_some_and(Option::is_some))
34
- }
35
-
36
- pub(super) fn array_value_at(&self, array: ArrayKey, index: usize) -> MustardResult<Value> {
37
- Ok(self
38
- .arrays
39
- .get(array)
40
- .ok_or_else(|| MustardError::runtime("array missing"))?
41
- .elements
42
- .get(index)
43
- .cloned()
44
- .flatten()
45
- .unwrap_or(Value::Undefined))
46
- }
47
-
48
- pub(super) fn closure_own_property(
49
- &self,
50
- closure: ClosureKey,
51
- key: &str,
52
- ) -> MustardResult<Option<Value>> {
53
- let closure_ref = self
54
- .closures
55
- .get(closure)
56
- .ok_or_else(|| MustardError::runtime("closure missing"))?;
57
- let function = self
58
- .program
59
- .functions
60
- .get(closure_ref.function_id)
61
- .ok_or_else(|| MustardError::runtime("function not found"))?;
62
- Ok(match key {
63
- "name" => Some(Value::String(
64
- closure_ref
65
- .name
66
- .clone()
67
- .or_else(|| function.name.clone())
68
- .unwrap_or_default(),
69
- )),
70
- "length" => Some(Value::Number(function.length as f64)),
71
- "prototype" => closure_ref.prototype.map(Value::Object),
72
- _ => closure_ref.properties.get(key).cloned(),
73
- })
74
- }
75
-
76
- pub(super) fn closure_has_own_property(
77
- &self,
78
- closure: ClosureKey,
79
- key: &str,
80
- ) -> MustardResult<bool> {
81
- Ok(self.closure_own_property(closure, key)?.is_some())
82
- }
83
-
84
- fn set_closure_property(
85
- &mut self,
86
- closure: ClosureKey,
87
- key: String,
88
- value: Value,
89
- ) -> MustardResult<()> {
90
- if matches!(key.as_str(), "name" | "length" | "prototype") {
91
- return Err(MustardError::runtime(
92
- "TypeError: cannot assign to read-only function metadata",
93
- ));
94
- }
95
- self.closures
96
- .get_mut(closure)
97
- .ok_or_else(|| MustardError::runtime("closure missing"))?
98
- .properties
99
- .insert(key, value);
100
- self.refresh_closure_accounting(closure)?;
101
- Ok(())
102
- }
103
-
104
- pub(super) fn builtin_function_custom_property(
105
- &self,
106
- function: BuiltinFunction,
107
- key: &str,
108
- ) -> MustardResult<Option<Value>> {
109
- let Some(object) = self.builtin_function_objects.get(&function).copied() else {
110
- return Ok(None);
111
- };
112
- Ok(self
113
- .objects
114
- .get(object)
115
- .ok_or_else(|| MustardError::runtime("object missing"))?
116
- .properties
117
- .get(key)
118
- .cloned())
119
- }
120
-
121
- pub(super) fn host_function_custom_property(
122
- &self,
123
- capability: &str,
124
- key: &str,
125
- ) -> MustardResult<Option<Value>> {
126
- let Some(object) = self.host_function_objects.get(capability).copied() else {
127
- return Ok(None);
128
- };
129
- Ok(self
130
- .objects
131
- .get(object)
132
- .ok_or_else(|| MustardError::runtime("object missing"))?
133
- .properties
134
- .get(key)
135
- .cloned())
136
- }
137
-
138
- pub(super) fn builtin_function_custom_keys(
139
- &self,
140
- function: BuiltinFunction,
141
- ) -> MustardResult<Vec<String>> {
142
- let Some(object) = self.builtin_function_objects.get(&function).copied() else {
143
- return Ok(Vec::new());
144
- };
145
- Ok(ordered_own_property_keys(
146
- &self
147
- .objects
148
- .get(object)
149
- .ok_or_else(|| MustardError::runtime("object missing"))?
150
- .properties,
151
- ))
152
- }
153
-
154
- pub(super) fn host_function_custom_keys(&self, capability: &str) -> MustardResult<Vec<String>> {
155
- let Some(object) = self.host_function_objects.get(capability).copied() else {
156
- return Ok(Vec::new());
157
- };
158
- Ok(ordered_own_property_keys(
159
- &self
160
- .objects
161
- .get(object)
162
- .ok_or_else(|| MustardError::runtime("object missing"))?
163
- .properties,
164
- ))
165
- }
166
-
167
- fn set_builtin_function_property(
168
- &mut self,
169
- function: BuiltinFunction,
170
- key: String,
171
- value: Value,
172
- ) -> MustardResult<()> {
173
- if matches!(key.as_str(), "name" | "length" | "prototype") {
174
- return Err(MustardError::runtime(
175
- "TypeError: cannot assign to read-only function metadata",
176
- ));
177
- }
178
- let object = match self.builtin_function_objects.get(&function).copied() {
179
- Some(object) => object,
180
- None => {
181
- let object = self.insert_object(IndexMap::new(), ObjectKind::Plain)?;
182
- self.builtin_function_objects.insert(function, object);
183
- object
184
- }
185
- };
186
- self.objects
187
- .get_mut(object)
188
- .ok_or_else(|| MustardError::runtime("object missing"))?
189
- .properties
190
- .insert(key, value);
191
- self.refresh_object_accounting(object)?;
192
- Ok(())
193
- }
194
-
195
- fn set_host_function_property(
196
- &mut self,
197
- capability: String,
198
- key: String,
199
- value: Value,
200
- ) -> MustardResult<()> {
201
- if matches!(key.as_str(), "name" | "length") {
202
- return Err(MustardError::runtime(
203
- "TypeError: cannot assign to read-only function metadata",
204
- ));
205
- }
206
- let object = match self.host_function_objects.get(&capability).copied() {
207
- Some(object) => object,
208
- None => {
209
- let object = self.insert_object(IndexMap::new(), ObjectKind::Plain)?;
210
- self.host_function_objects.insert(capability, object);
211
- object
212
- }
213
- };
214
- self.objects
215
- .get_mut(object)
216
- .ok_or_else(|| MustardError::runtime("object missing"))?
217
- .properties
218
- .insert(key, value);
219
- self.refresh_object_accounting(object)?;
220
- Ok(())
221
- }
222
-
223
- fn builtin_function_name(function: BuiltinFunction) -> &'static str {
224
- match function {
225
- BuiltinFunction::FunctionCtor => "Function",
226
- BuiltinFunction::FunctionCall => "call",
227
- BuiltinFunction::FunctionApply => "apply",
228
- BuiltinFunction::FunctionBind => "bind",
229
- BuiltinFunction::ArrayCtor => "Array",
230
- BuiltinFunction::ArrayFrom => "from",
231
- BuiltinFunction::ArrayOf => "of",
232
- BuiltinFunction::ArrayIsArray => "isArray",
233
- BuiltinFunction::ArrayPush => "push",
234
- BuiltinFunction::ArrayPop => "pop",
235
- BuiltinFunction::ArraySlice => "slice",
236
- BuiltinFunction::ArraySplice => "splice",
237
- BuiltinFunction::ArrayConcat => "concat",
238
- BuiltinFunction::ArrayAt => "at",
239
- BuiltinFunction::ArrayJoin => "join",
240
- BuiltinFunction::ArrayIncludes => "includes",
241
- BuiltinFunction::ArrayIndexOf => "indexOf",
242
- BuiltinFunction::ArrayLastIndexOf => "lastIndexOf",
243
- BuiltinFunction::ArrayReverse => "reverse",
244
- BuiltinFunction::ArrayFill => "fill",
245
- BuiltinFunction::ArraySort => "sort",
246
- BuiltinFunction::ArrayValues => "values",
247
- BuiltinFunction::ArrayKeys => "keys",
248
- BuiltinFunction::ArrayEntries => "entries",
249
- BuiltinFunction::ArrayForEach => "forEach",
250
- BuiltinFunction::ArrayMap => "map",
251
- BuiltinFunction::ArrayFilter => "filter",
252
- BuiltinFunction::ArrayFind => "find",
253
- BuiltinFunction::ArrayFindIndex => "findIndex",
254
- BuiltinFunction::ArraySome => "some",
255
- BuiltinFunction::ArrayEvery => "every",
256
- BuiltinFunction::ArrayFlat => "flat",
257
- BuiltinFunction::ArrayFlatMap => "flatMap",
258
- BuiltinFunction::ArrayReduce => "reduce",
259
- BuiltinFunction::ArrayReduceRight => "reduceRight",
260
- BuiltinFunction::ArrayFindLast => "findLast",
261
- BuiltinFunction::ArrayFindLastIndex => "findLastIndex",
262
- BuiltinFunction::ObjectCtor => "Object",
263
- BuiltinFunction::ObjectAssign => "assign",
264
- BuiltinFunction::ObjectCreate => "create",
265
- BuiltinFunction::ObjectFreeze => "freeze",
266
- BuiltinFunction::ObjectSeal => "seal",
267
- BuiltinFunction::ObjectFromEntries => "fromEntries",
268
- BuiltinFunction::ObjectKeys => "keys",
269
- BuiltinFunction::ObjectValues => "values",
270
- BuiltinFunction::ObjectEntries => "entries",
271
- BuiltinFunction::ObjectHasOwn => "hasOwn",
272
- BuiltinFunction::MapCtor => "Map",
273
- BuiltinFunction::MapGet => "get",
274
- BuiltinFunction::MapSet => "set",
275
- BuiltinFunction::MapHas => "has",
276
- BuiltinFunction::MapDelete => "delete",
277
- BuiltinFunction::MapClear => "clear",
278
- BuiltinFunction::MapEntries => "entries",
279
- BuiltinFunction::MapKeys => "keys",
280
- BuiltinFunction::MapValues => "values",
281
- BuiltinFunction::MapForEach => "forEach",
282
- BuiltinFunction::SetCtor => "Set",
283
- BuiltinFunction::SetAdd => "add",
284
- BuiltinFunction::SetHas => "has",
285
- BuiltinFunction::SetDelete => "delete",
286
- BuiltinFunction::SetClear => "clear",
287
- BuiltinFunction::SetEntries => "entries",
288
- BuiltinFunction::SetKeys => "keys",
289
- BuiltinFunction::SetValues => "values",
290
- BuiltinFunction::SetForEach => "forEach",
291
- BuiltinFunction::IteratorNext => "next",
292
- BuiltinFunction::PromiseCtor => "Promise",
293
- BuiltinFunction::PromiseResolve => "resolve",
294
- BuiltinFunction::PromiseReject => "reject",
295
- BuiltinFunction::PromiseResolveFunction(_) => "",
296
- BuiltinFunction::PromiseRejectFunction(_) => "",
297
- BuiltinFunction::PromiseThen => "then",
298
- BuiltinFunction::PromiseCatch => "catch",
299
- BuiltinFunction::PromiseFinally => "finally",
300
- BuiltinFunction::PromiseAll => "all",
301
- BuiltinFunction::PromiseRace => "race",
302
- BuiltinFunction::PromiseAny => "any",
303
- BuiltinFunction::PromiseAllSettled => "allSettled",
304
- BuiltinFunction::RegExpCtor => "RegExp",
305
- BuiltinFunction::RegExpExec => "exec",
306
- BuiltinFunction::RegExpTest => "test",
307
- BuiltinFunction::ErrorCtor => "Error",
308
- BuiltinFunction::TypeErrorCtor => "TypeError",
309
- BuiltinFunction::ReferenceErrorCtor => "ReferenceError",
310
- BuiltinFunction::RangeErrorCtor => "RangeError",
311
- BuiltinFunction::SyntaxErrorCtor => "SyntaxError",
312
- BuiltinFunction::NumberCtor => "Number",
313
- BuiltinFunction::NumberParseInt => "parseInt",
314
- BuiltinFunction::NumberParseFloat => "parseFloat",
315
- BuiltinFunction::NumberIsNaN => "isNaN",
316
- BuiltinFunction::NumberIsFinite => "isFinite",
317
- BuiltinFunction::NumberIsInteger => "isInteger",
318
- BuiltinFunction::NumberIsSafeInteger => "isSafeInteger",
319
- BuiltinFunction::DateCtor => "Date",
320
- BuiltinFunction::DateNow => "now",
321
- BuiltinFunction::DateGetTime => "getTime",
322
- BuiltinFunction::DateValueOf => "valueOf",
323
- BuiltinFunction::DateToISOString => "toISOString",
324
- BuiltinFunction::DateToJSON => "toJSON",
325
- BuiltinFunction::DateGetUTCFullYear => "getUTCFullYear",
326
- BuiltinFunction::DateGetUTCMonth => "getUTCMonth",
327
- BuiltinFunction::DateGetUTCDate => "getUTCDate",
328
- BuiltinFunction::DateGetUTCHours => "getUTCHours",
329
- BuiltinFunction::DateGetUTCMinutes => "getUTCMinutes",
330
- BuiltinFunction::DateGetUTCSeconds => "getUTCSeconds",
331
- BuiltinFunction::IntlDateTimeFormatCtor => "DateTimeFormat",
332
- BuiltinFunction::IntlNumberFormatCtor => "NumberFormat",
333
- BuiltinFunction::IntlDateTimeFormatFormat => "format",
334
- BuiltinFunction::IntlDateTimeFormatResolvedOptions => "resolvedOptions",
335
- BuiltinFunction::IntlNumberFormatFormat => "format",
336
- BuiltinFunction::IntlNumberFormatResolvedOptions => "resolvedOptions",
337
- BuiltinFunction::StringCtor => "String",
338
- BuiltinFunction::StringTrim => "trim",
339
- BuiltinFunction::StringTrimStart => "trimStart",
340
- BuiltinFunction::StringTrimEnd => "trimEnd",
341
- BuiltinFunction::StringIncludes => "includes",
342
- BuiltinFunction::StringStartsWith => "startsWith",
343
- BuiltinFunction::StringEndsWith => "endsWith",
344
- BuiltinFunction::StringIndexOf => "indexOf",
345
- BuiltinFunction::StringLastIndexOf => "lastIndexOf",
346
- BuiltinFunction::StringCharAt => "charAt",
347
- BuiltinFunction::StringAt => "at",
348
- BuiltinFunction::StringSlice => "slice",
349
- BuiltinFunction::StringSubstring => "substring",
350
- BuiltinFunction::StringToLowerCase => "toLowerCase",
351
- BuiltinFunction::StringToUpperCase => "toUpperCase",
352
- BuiltinFunction::StringRepeat => "repeat",
353
- BuiltinFunction::StringConcat => "concat",
354
- BuiltinFunction::StringPadStart => "padStart",
355
- BuiltinFunction::StringPadEnd => "padEnd",
356
- BuiltinFunction::StringSplit => "split",
357
- BuiltinFunction::StringReplace => "replace",
358
- BuiltinFunction::StringReplaceAll => "replaceAll",
359
- BuiltinFunction::StringSearch => "search",
360
- BuiltinFunction::StringMatch => "match",
361
- BuiltinFunction::StringMatchAll => "matchAll",
362
- BuiltinFunction::StringToString => "toString",
363
- BuiltinFunction::StringValueOf => "valueOf",
364
- BuiltinFunction::BooleanCtor => "Boolean",
365
- BuiltinFunction::BooleanToString => "toString",
366
- BuiltinFunction::BooleanValueOf => "valueOf",
367
- BuiltinFunction::NumberToString => "toString",
368
- BuiltinFunction::NumberValueOf => "valueOf",
369
- BuiltinFunction::MathAbs => "abs",
370
- BuiltinFunction::MathMax => "max",
371
- BuiltinFunction::MathMin => "min",
372
- BuiltinFunction::MathFloor => "floor",
373
- BuiltinFunction::MathCeil => "ceil",
374
- BuiltinFunction::MathRound => "round",
375
- BuiltinFunction::MathPow => "pow",
376
- BuiltinFunction::MathSqrt => "sqrt",
377
- BuiltinFunction::MathTrunc => "trunc",
378
- BuiltinFunction::MathSign => "sign",
379
- BuiltinFunction::MathLog => "log",
380
- BuiltinFunction::MathExp => "exp",
381
- BuiltinFunction::MathLog2 => "log2",
382
- BuiltinFunction::MathLog10 => "log10",
383
- BuiltinFunction::MathSin => "sin",
384
- BuiltinFunction::MathCos => "cos",
385
- BuiltinFunction::MathAtan2 => "atan2",
386
- BuiltinFunction::MathHypot => "hypot",
387
- BuiltinFunction::MathCbrt => "cbrt",
388
- BuiltinFunction::MathRandom => "random",
389
- BuiltinFunction::JsonStringify => "stringify",
390
- BuiltinFunction::JsonParse => "parse",
391
- }
392
- }
393
-
394
- fn builtin_function_length(function: BuiltinFunction) -> usize {
395
- match function {
396
- BuiltinFunction::FunctionCtor => 1,
397
- BuiltinFunction::FunctionCall => 1,
398
- BuiltinFunction::FunctionApply => 2,
399
- BuiltinFunction::FunctionBind => 1,
400
- BuiltinFunction::ArrayCtor => 1,
401
- BuiltinFunction::ArrayFrom => 1,
402
- BuiltinFunction::ArrayOf => 0,
403
- BuiltinFunction::ArrayIsArray => 1,
404
- BuiltinFunction::ArrayPush => 1,
405
- BuiltinFunction::ArrayPop => 0,
406
- BuiltinFunction::ArraySlice => 2,
407
- BuiltinFunction::ArraySplice => 2,
408
- BuiltinFunction::ArrayConcat => 1,
409
- BuiltinFunction::ArrayAt => 1,
410
- BuiltinFunction::ArrayJoin => 1,
411
- BuiltinFunction::ArrayIncludes => 1,
412
- BuiltinFunction::ArrayIndexOf => 1,
413
- BuiltinFunction::ArrayLastIndexOf => 1,
414
- BuiltinFunction::ArrayReverse => 0,
415
- BuiltinFunction::ArrayFill => 1,
416
- BuiltinFunction::ArraySort => 1,
417
- BuiltinFunction::ArrayValues => 0,
418
- BuiltinFunction::ArrayKeys => 0,
419
- BuiltinFunction::ArrayEntries => 0,
420
- BuiltinFunction::ArrayForEach => 1,
421
- BuiltinFunction::ArrayMap => 1,
422
- BuiltinFunction::ArrayFilter => 1,
423
- BuiltinFunction::ArrayFind => 1,
424
- BuiltinFunction::ArrayFindIndex => 1,
425
- BuiltinFunction::ArraySome => 1,
426
- BuiltinFunction::ArrayEvery => 1,
427
- BuiltinFunction::ArrayFlat => 0,
428
- BuiltinFunction::ArrayFlatMap => 1,
429
- BuiltinFunction::ArrayReduce => 1,
430
- BuiltinFunction::ArrayReduceRight => 1,
431
- BuiltinFunction::ArrayFindLast => 1,
432
- BuiltinFunction::ArrayFindLastIndex => 1,
433
- BuiltinFunction::ObjectCtor => 1,
434
- BuiltinFunction::ObjectAssign => 2,
435
- BuiltinFunction::ObjectCreate => 2,
436
- BuiltinFunction::ObjectFreeze => 1,
437
- BuiltinFunction::ObjectSeal => 1,
438
- BuiltinFunction::ObjectFromEntries => 1,
439
- BuiltinFunction::ObjectKeys => 1,
440
- BuiltinFunction::ObjectValues => 1,
441
- BuiltinFunction::ObjectEntries => 1,
442
- BuiltinFunction::ObjectHasOwn => 2,
443
- BuiltinFunction::MapCtor => 0,
444
- BuiltinFunction::MapGet => 1,
445
- BuiltinFunction::MapSet => 2,
446
- BuiltinFunction::MapHas => 1,
447
- BuiltinFunction::MapDelete => 1,
448
- BuiltinFunction::MapClear => 0,
449
- BuiltinFunction::MapEntries => 0,
450
- BuiltinFunction::MapKeys => 0,
451
- BuiltinFunction::MapValues => 0,
452
- BuiltinFunction::MapForEach => 1,
453
- BuiltinFunction::SetCtor => 0,
454
- BuiltinFunction::SetAdd => 1,
455
- BuiltinFunction::SetHas => 1,
456
- BuiltinFunction::SetDelete => 1,
457
- BuiltinFunction::SetClear => 0,
458
- BuiltinFunction::SetEntries => 0,
459
- BuiltinFunction::SetKeys => 0,
460
- BuiltinFunction::SetValues => 0,
461
- BuiltinFunction::SetForEach => 1,
462
- BuiltinFunction::IteratorNext => 0,
463
- BuiltinFunction::PromiseCtor => 1,
464
- BuiltinFunction::PromiseResolve => 1,
465
- BuiltinFunction::PromiseReject => 1,
466
- BuiltinFunction::PromiseResolveFunction(_) => 1,
467
- BuiltinFunction::PromiseRejectFunction(_) => 1,
468
- BuiltinFunction::PromiseThen => 2,
469
- BuiltinFunction::PromiseCatch => 1,
470
- BuiltinFunction::PromiseFinally => 1,
471
- BuiltinFunction::PromiseAll => 1,
472
- BuiltinFunction::PromiseRace => 1,
473
- BuiltinFunction::PromiseAny => 1,
474
- BuiltinFunction::PromiseAllSettled => 1,
475
- BuiltinFunction::RegExpCtor => 2,
476
- BuiltinFunction::RegExpExec => 1,
477
- BuiltinFunction::RegExpTest => 1,
478
- BuiltinFunction::ErrorCtor => 1,
479
- BuiltinFunction::TypeErrorCtor => 1,
480
- BuiltinFunction::ReferenceErrorCtor => 1,
481
- BuiltinFunction::RangeErrorCtor => 1,
482
- BuiltinFunction::SyntaxErrorCtor => 1,
483
- BuiltinFunction::NumberCtor => 1,
484
- BuiltinFunction::NumberParseInt => 2,
485
- BuiltinFunction::NumberParseFloat => 1,
486
- BuiltinFunction::NumberIsNaN => 1,
487
- BuiltinFunction::NumberIsFinite => 1,
488
- BuiltinFunction::NumberIsInteger => 1,
489
- BuiltinFunction::NumberIsSafeInteger => 1,
490
- BuiltinFunction::DateCtor => 7,
491
- BuiltinFunction::DateNow => 0,
492
- BuiltinFunction::DateGetTime => 0,
493
- BuiltinFunction::DateValueOf => 0,
494
- BuiltinFunction::DateToISOString => 0,
495
- BuiltinFunction::DateToJSON => 0,
496
- BuiltinFunction::DateGetUTCFullYear => 0,
497
- BuiltinFunction::DateGetUTCMonth => 0,
498
- BuiltinFunction::DateGetUTCDate => 0,
499
- BuiltinFunction::DateGetUTCHours => 0,
500
- BuiltinFunction::DateGetUTCMinutes => 0,
501
- BuiltinFunction::DateGetUTCSeconds => 0,
502
- BuiltinFunction::IntlDateTimeFormatCtor => 0,
503
- BuiltinFunction::IntlNumberFormatCtor => 0,
504
- BuiltinFunction::IntlDateTimeFormatFormat => 1,
505
- BuiltinFunction::IntlDateTimeFormatResolvedOptions => 0,
506
- BuiltinFunction::IntlNumberFormatFormat => 1,
507
- BuiltinFunction::IntlNumberFormatResolvedOptions => 0,
508
- BuiltinFunction::StringCtor => 1,
509
- BuiltinFunction::StringTrim => 0,
510
- BuiltinFunction::StringTrimStart => 0,
511
- BuiltinFunction::StringTrimEnd => 0,
512
- BuiltinFunction::StringIncludes => 1,
513
- BuiltinFunction::StringStartsWith => 1,
514
- BuiltinFunction::StringEndsWith => 1,
515
- BuiltinFunction::StringIndexOf => 1,
516
- BuiltinFunction::StringLastIndexOf => 1,
517
- BuiltinFunction::StringCharAt => 1,
518
- BuiltinFunction::StringAt => 1,
519
- BuiltinFunction::StringSlice => 2,
520
- BuiltinFunction::StringSubstring => 2,
521
- BuiltinFunction::StringToLowerCase => 0,
522
- BuiltinFunction::StringToUpperCase => 0,
523
- BuiltinFunction::StringRepeat => 1,
524
- BuiltinFunction::StringConcat => 1,
525
- BuiltinFunction::StringPadStart => 1,
526
- BuiltinFunction::StringPadEnd => 1,
527
- BuiltinFunction::StringSplit => 2,
528
- BuiltinFunction::StringReplace => 2,
529
- BuiltinFunction::StringReplaceAll => 2,
530
- BuiltinFunction::StringSearch => 1,
531
- BuiltinFunction::StringMatch => 1,
532
- BuiltinFunction::StringMatchAll => 1,
533
- BuiltinFunction::StringToString => 0,
534
- BuiltinFunction::StringValueOf => 0,
535
- BuiltinFunction::BooleanCtor => 1,
536
- BuiltinFunction::BooleanToString => 0,
537
- BuiltinFunction::BooleanValueOf => 0,
538
- BuiltinFunction::NumberToString => 0,
539
- BuiltinFunction::NumberValueOf => 0,
540
- BuiltinFunction::MathAbs => 1,
541
- BuiltinFunction::MathMax => 2,
542
- BuiltinFunction::MathMin => 2,
543
- BuiltinFunction::MathFloor => 1,
544
- BuiltinFunction::MathCeil => 1,
545
- BuiltinFunction::MathRound => 1,
546
- BuiltinFunction::MathPow => 2,
547
- BuiltinFunction::MathSqrt => 1,
548
- BuiltinFunction::MathTrunc => 1,
549
- BuiltinFunction::MathSign => 1,
550
- BuiltinFunction::MathLog => 1,
551
- BuiltinFunction::MathExp => 1,
552
- BuiltinFunction::MathLog2 => 1,
553
- BuiltinFunction::MathLog10 => 1,
554
- BuiltinFunction::MathSin => 1,
555
- BuiltinFunction::MathCos => 1,
556
- BuiltinFunction::MathAtan2 => 2,
557
- BuiltinFunction::MathHypot => 2,
558
- BuiltinFunction::MathCbrt => 1,
559
- BuiltinFunction::MathRandom => 0,
560
- BuiltinFunction::JsonStringify => 3,
561
- BuiltinFunction::JsonParse => 2,
562
- }
563
- }
564
-
565
- pub(super) fn builtin_function_own_property(
566
- &self,
567
- function: BuiltinFunction,
568
- key: &str,
569
- ) -> Option<Value> {
570
- match key {
571
- "name" => Some(Value::String(
572
- Self::builtin_function_name(function).to_string(),
573
- )),
574
- "length" => Some(Value::Number(Self::builtin_function_length(function) as f64)),
575
- "prototype" => self
576
- .builtin_prototypes
577
- .get(&function)
578
- .copied()
579
- .map(Value::Object),
580
- _ => match function {
581
- BuiltinFunction::ArrayCtor => match key {
582
- "isArray" => Some(Value::BuiltinFunction(BuiltinFunction::ArrayIsArray)),
583
- "from" => Some(Value::BuiltinFunction(BuiltinFunction::ArrayFrom)),
584
- "of" => Some(Value::BuiltinFunction(BuiltinFunction::ArrayOf)),
585
- _ => None,
586
- },
587
- BuiltinFunction::ObjectCtor => match key {
588
- "assign" => Some(Value::BuiltinFunction(BuiltinFunction::ObjectAssign)),
589
- "create" => Some(Value::BuiltinFunction(BuiltinFunction::ObjectCreate)),
590
- "freeze" => Some(Value::BuiltinFunction(BuiltinFunction::ObjectFreeze)),
591
- "seal" => Some(Value::BuiltinFunction(BuiltinFunction::ObjectSeal)),
592
- "fromEntries" => {
593
- Some(Value::BuiltinFunction(BuiltinFunction::ObjectFromEntries))
594
- }
595
- "keys" => Some(Value::BuiltinFunction(BuiltinFunction::ObjectKeys)),
596
- "values" => Some(Value::BuiltinFunction(BuiltinFunction::ObjectValues)),
597
- "entries" => Some(Value::BuiltinFunction(BuiltinFunction::ObjectEntries)),
598
- "hasOwn" => Some(Value::BuiltinFunction(BuiltinFunction::ObjectHasOwn)),
599
- _ => None,
600
- },
601
- BuiltinFunction::DateCtor if key == "now" => {
602
- Some(Value::BuiltinFunction(BuiltinFunction::DateNow))
603
- }
604
- BuiltinFunction::NumberCtor => match key {
605
- "parseInt" => Some(Value::BuiltinFunction(BuiltinFunction::NumberParseInt)),
606
- "parseFloat" => Some(Value::BuiltinFunction(BuiltinFunction::NumberParseFloat)),
607
- "isNaN" => Some(Value::BuiltinFunction(BuiltinFunction::NumberIsNaN)),
608
- "isFinite" => Some(Value::BuiltinFunction(BuiltinFunction::NumberIsFinite)),
609
- "isInteger" => Some(Value::BuiltinFunction(BuiltinFunction::NumberIsInteger)),
610
- "isSafeInteger" => {
611
- Some(Value::BuiltinFunction(BuiltinFunction::NumberIsSafeInteger))
612
- }
613
- "MAX_SAFE_INTEGER" => Some(Value::Number(9_007_199_254_740_991.0)),
614
- "MIN_SAFE_INTEGER" => Some(Value::Number(-9_007_199_254_740_991.0)),
615
- "EPSILON" => Some(Value::Number(f64::EPSILON)),
616
- "MAX_VALUE" => Some(Value::Number(f64::MAX)),
617
- "MIN_VALUE" => Some(Value::Number(f64::MIN_POSITIVE)),
618
- "POSITIVE_INFINITY" => Some(Value::Number(f64::INFINITY)),
619
- "NEGATIVE_INFINITY" => Some(Value::Number(f64::NEG_INFINITY)),
620
- "NaN" => Some(Value::Number(f64::NAN)),
621
- _ => None,
622
- },
623
- BuiltinFunction::PromiseCtor => match key {
624
- "resolve" => Some(Value::BuiltinFunction(BuiltinFunction::PromiseResolve)),
625
- "reject" => Some(Value::BuiltinFunction(BuiltinFunction::PromiseReject)),
626
- "all" => Some(Value::BuiltinFunction(BuiltinFunction::PromiseAll)),
627
- "race" => Some(Value::BuiltinFunction(BuiltinFunction::PromiseRace)),
628
- "any" => Some(Value::BuiltinFunction(BuiltinFunction::PromiseAny)),
629
- "allSettled" => {
630
- Some(Value::BuiltinFunction(BuiltinFunction::PromiseAllSettled))
631
- }
632
- _ => None,
633
- },
634
- BuiltinFunction::IntlDateTimeFormatCtor if key == "supportedLocalesOf" => None,
635
- BuiltinFunction::IntlNumberFormatCtor if key == "supportedLocalesOf" => None,
636
- _ => None,
637
- },
638
- }
639
- }
640
-
641
- pub(super) fn has_property_in_supported_surface(
642
- &self,
643
- object: Value,
644
- property: Value,
645
- ) -> MustardResult<bool> {
646
- let key = self.to_property_key(property)?;
647
- match object {
648
- Value::Object(object) => {
649
- let object = self
650
- .objects
651
- .get(object)
652
- .ok_or_else(|| MustardError::runtime("object missing"))?;
653
- if object.properties.contains_key(&key) {
654
- return Ok(true);
655
- }
656
- Ok(match &object.kind {
657
- ObjectKind::FunctionPrototype(constructor) => {
658
- key == "constructor"
659
- || matches!(
660
- (constructor, key.as_str()),
661
- (
662
- Value::BuiltinFunction(BuiltinFunction::DateCtor),
663
- "getTime"
664
- | "valueOf"
665
- | "toISOString"
666
- | "toJSON"
667
- | "getUTCFullYear"
668
- | "getUTCMonth"
669
- | "getUTCDate"
670
- | "getUTCHours"
671
- | "getUTCMinutes"
672
- | "getUTCSeconds"
673
- )
674
- )
675
- }
676
- ObjectKind::BoundFunction(_) => {
677
- key == "name"
678
- || key == "length"
679
- || key == "constructor"
680
- || matches!(key.as_str(), "call" | "apply" | "bind")
681
- }
682
- ObjectKind::Date(_) => matches!(
683
- key.as_str(),
684
- "getTime"
685
- | "valueOf"
686
- | "toISOString"
687
- | "toJSON"
688
- | "getUTCFullYear"
689
- | "getUTCMonth"
690
- | "getUTCDate"
691
- | "getUTCHours"
692
- | "getUTCMinutes"
693
- | "getUTCSeconds"
694
- ),
695
- ObjectKind::RegExp(_) => matches!(
696
- key.as_str(),
697
- "source"
698
- | "flags"
699
- | "global"
700
- | "ignoreCase"
701
- | "multiline"
702
- | "dotAll"
703
- | "unicode"
704
- | "sticky"
705
- | "lastIndex"
706
- | "exec"
707
- | "test"
708
- ),
709
- ObjectKind::Intl => matches!(key.as_str(), "DateTimeFormat" | "NumberFormat"),
710
- ObjectKind::IntlDateTimeFormat(_) => {
711
- matches!(key.as_str(), "constructor" | "format" | "resolvedOptions")
712
- }
713
- ObjectKind::IntlNumberFormat(_) => {
714
- matches!(key.as_str(), "constructor" | "format" | "resolvedOptions")
715
- }
716
- ObjectKind::StringObject(value) => {
717
- key == "constructor"
718
- || key == "length"
719
- || matches!(
720
- key.as_str(),
721
- "trim"
722
- | "trimStart"
723
- | "trimEnd"
724
- | "includes"
725
- | "startsWith"
726
- | "endsWith"
727
- | "indexOf"
728
- | "lastIndexOf"
729
- | "charAt"
730
- | "at"
731
- | "slice"
732
- | "substring"
733
- | "toLowerCase"
734
- | "toUpperCase"
735
- | "repeat"
736
- | "concat"
737
- | "padStart"
738
- | "padEnd"
739
- | "split"
740
- | "replace"
741
- | "replaceAll"
742
- | "search"
743
- | "match"
744
- | "matchAll"
745
- | "toString"
746
- | "valueOf"
747
- )
748
- || array_index_from_property_key(&key)
749
- .is_some_and(|index| value.chars().nth(index).is_some())
750
- }
751
- ObjectKind::NumberObject(_) | ObjectKind::BooleanObject(_) => {
752
- matches!(key.as_str(), "constructor" | "toString" | "valueOf")
753
- }
754
- ObjectKind::Console => self.console_method(&key).is_some(),
755
- ObjectKind::Plain
756
- | ObjectKind::Global
757
- | ObjectKind::Math
758
- | ObjectKind::Json
759
- | ObjectKind::Error(_) => key == "constructor",
760
- })
761
- }
762
- Value::Array(array) => {
763
- let array = self
764
- .arrays
765
- .get(array)
766
- .ok_or_else(|| MustardError::runtime("array missing"))?;
767
- Ok(key == "length"
768
- || key.parse::<usize>().ok().is_some_and(|index| {
769
- array.elements.get(index).is_some_and(Option::is_some)
770
- })
771
- || array.properties.contains_key(&key)
772
- || matches!(
773
- key.as_str(),
774
- "constructor"
775
- | "sort"
776
- | "push"
777
- | "pop"
778
- | "slice"
779
- | "splice"
780
- | "concat"
781
- | "at"
782
- | "join"
783
- | "includes"
784
- | "indexOf"
785
- | "lastIndexOf"
786
- | "reverse"
787
- | "fill"
788
- | "values"
789
- | "keys"
790
- | "entries"
791
- | "forEach"
792
- | "map"
793
- | "filter"
794
- | "find"
795
- | "findIndex"
796
- | "some"
797
- | "every"
798
- | "flat"
799
- | "flatMap"
800
- | "reduce"
801
- | "reduceRight"
802
- | "findLast"
803
- | "findLastIndex"
804
- ))
805
- }
806
- Value::Map(map) => {
807
- self.maps
808
- .get(map)
809
- .ok_or_else(|| MustardError::runtime("map missing"))?;
810
- Ok(matches!(
811
- key.as_str(),
812
- "constructor"
813
- | "size"
814
- | "get"
815
- | "set"
816
- | "has"
817
- | "delete"
818
- | "clear"
819
- | "entries"
820
- | "keys"
821
- | "values"
822
- | "forEach"
823
- ))
824
- }
825
- Value::Set(set) => {
826
- self.sets
827
- .get(set)
828
- .ok_or_else(|| MustardError::runtime("set missing"))?;
829
- Ok(matches!(
830
- key.as_str(),
831
- "constructor"
832
- | "size"
833
- | "add"
834
- | "has"
835
- | "delete"
836
- | "clear"
837
- | "entries"
838
- | "keys"
839
- | "values"
840
- | "forEach"
841
- ))
842
- }
843
- Value::Iterator(iterator) => {
844
- self.iterators
845
- .get(iterator)
846
- .ok_or_else(|| MustardError::runtime("iterator missing"))?;
847
- Ok(matches!(key.as_str(), "constructor" | "next"))
848
- }
849
- Value::Promise(promise) => {
850
- self.promises
851
- .get(promise)
852
- .ok_or_else(|| MustardError::runtime("promise missing"))?;
853
- Ok(matches!(
854
- key.as_str(),
855
- "constructor" | "then" | "catch" | "finally"
856
- ))
857
- }
858
- Value::BuiltinFunction(function) => Ok(self
859
- .builtin_function_custom_property(function, &key)?
860
- .is_some()
861
- || self.builtin_function_own_property(function, &key).is_some()
862
- || key == "constructor"
863
- || Self::function_helper_method(&key).is_some()),
864
- Value::Closure(closure) => Ok(self.closure_has_own_property(closure, &key)?
865
- || key == "constructor"
866
- || Self::function_helper_method(&key).is_some()),
867
- Value::HostFunction(capability) => Ok(self
868
- .host_function_custom_property(&capability, &key)?
869
- .is_some()
870
- || matches!(key.as_str(), "name" | "length" | "constructor")
871
- || Self::function_helper_method(&key).is_some()),
872
- Value::Undefined
873
- | Value::Null
874
- | Value::Bool(_)
875
- | Value::Number(_)
876
- | Value::String(_)
877
- | Value::BigInt(_) => Err(MustardError::runtime(
878
- "TypeError: right-hand side of 'in' must be an object in the supported surface",
879
- )),
880
- }
881
- }
882
-
883
- pub(super) fn create_iterator(&mut self, iterable: Value) -> MustardResult<Value> {
884
- let iterator = match iterable {
885
- Value::Array(array) => {
886
- self.insert_iterator(IteratorState::Array(ArrayIteratorState {
887
- array,
888
- next_index: 0,
889
- }))?
890
- }
891
- Value::String(value) => {
892
- self.insert_iterator(IteratorState::String(StringIteratorState {
893
- value,
894
- next_index: 0,
895
- }))?
896
- }
897
- Value::Map(map) => {
898
- self.insert_iterator(IteratorState::MapEntries(MapIteratorState {
899
- map,
900
- next_index: 0,
901
- }))?
902
- }
903
- Value::Set(set) => {
904
- self.insert_iterator(IteratorState::SetValues(SetIteratorState {
905
- set,
906
- next_index: 0,
907
- }))?
908
- }
909
- Value::Iterator(iterator) => iterator,
910
- _ => {
911
- return Err(MustardError::runtime(
912
- "TypeError: value is not iterable in the supported surface",
913
- ));
914
- }
915
- };
916
- Ok(Value::Iterator(iterator))
917
- }
918
-
919
- pub(super) fn iterator_next(&mut self, iterator: Value) -> MustardResult<(Value, bool)> {
920
- let key = match iterator {
921
- Value::Iterator(key) => key,
922
- _ => return Err(MustardError::runtime("value is not an iterator")),
923
- };
924
-
925
- let state = self
926
- .iterators
927
- .get(key)
928
- .ok_or_else(|| MustardError::runtime("iterator missing"))?
929
- .state
930
- .clone();
931
-
932
- let value = match state {
933
- IteratorState::Array(state) => self
934
- .arrays
935
- .get(state.array)
936
- .ok_or_else(|| MustardError::runtime("array missing"))?
937
- .elements
938
- .get(state.next_index)
939
- .map(|value| value.clone().unwrap_or(Value::Undefined)),
940
- IteratorState::ArrayKeys(state) => self
941
- .arrays
942
- .get(state.array)
943
- .ok_or_else(|| MustardError::runtime("array missing"))?
944
- .elements
945
- .get(state.next_index)
946
- .map(|_| Value::Number(state.next_index as f64)),
947
- IteratorState::ArrayEntries(state) => {
948
- let value = self
949
- .arrays
950
- .get(state.array)
951
- .ok_or_else(|| MustardError::runtime("array missing"))?
952
- .elements
953
- .get(state.next_index)
954
- .map(|value| value.clone().unwrap_or(Value::Undefined));
955
- match value {
956
- Some(value) => Some(Value::Array(self.insert_array(
957
- vec![Value::Number(state.next_index as f64), value],
958
- IndexMap::new(),
959
- )?)),
960
- None => None,
961
- }
962
- }
963
- IteratorState::String(state) => {
964
- let chars = state.value.chars().collect::<Vec<_>>();
965
- chars
966
- .get(state.next_index)
967
- .map(|ch| Value::String(ch.to_string()))
968
- }
969
- IteratorState::MapEntries(state) => {
970
- let entry = self
971
- .maps
972
- .get(state.map)
973
- .ok_or_else(|| MustardError::runtime("map missing"))?
974
- .entries
975
- .get(state.next_index)
976
- .cloned();
977
- match entry {
978
- Some(entry) => Some(Value::Array(
979
- self.insert_array(vec![entry.key, entry.value], IndexMap::new())?,
980
- )),
981
- None => None,
982
- }
983
- }
984
- IteratorState::MapKeys(state) => self
985
- .maps
986
- .get(state.map)
987
- .ok_or_else(|| MustardError::runtime("map missing"))?
988
- .entries
989
- .get(state.next_index)
990
- .map(|entry| entry.key.clone()),
991
- IteratorState::MapValues(state) => self
992
- .maps
993
- .get(state.map)
994
- .ok_or_else(|| MustardError::runtime("map missing"))?
995
- .entries
996
- .get(state.next_index)
997
- .map(|entry| entry.value.clone()),
998
- IteratorState::SetEntries(state) => self
999
- .sets
1000
- .get(state.set)
1001
- .ok_or_else(|| MustardError::runtime("set missing"))?
1002
- .entries
1003
- .get(state.next_index)
1004
- .cloned()
1005
- .map(|value| {
1006
- self.insert_array(vec![value.clone(), value], IndexMap::new())
1007
- .map(Value::Array)
1008
- })
1009
- .transpose()?,
1010
- IteratorState::SetValues(state) => self
1011
- .sets
1012
- .get(state.set)
1013
- .ok_or_else(|| MustardError::runtime("set missing"))?
1014
- .entries
1015
- .get(state.next_index)
1016
- .cloned(),
1017
- };
1018
-
1019
- if value.is_some() {
1020
- if let Some(iterator) = self.iterators.get_mut(key) {
1021
- match &mut iterator.state {
1022
- IteratorState::Array(state)
1023
- | IteratorState::ArrayKeys(state)
1024
- | IteratorState::ArrayEntries(state) => state.next_index += 1,
1025
- IteratorState::String(state) => state.next_index += 1,
1026
- IteratorState::MapEntries(state)
1027
- | IteratorState::MapKeys(state)
1028
- | IteratorState::MapValues(state) => state.next_index += 1,
1029
- IteratorState::SetEntries(state) | IteratorState::SetValues(state) => {
1030
- state.next_index += 1
1031
- }
1032
- }
1033
- }
1034
- self.refresh_iterator_accounting(key)?;
1035
- }
1036
-
1037
- Ok(match value {
1038
- Some(value) => (value, false),
1039
- None => (Value::Undefined, true),
1040
- })
1041
- }
1042
-
1043
- pub(super) fn get_property(
1044
- &self,
1045
- object: Value,
1046
- property: Value,
1047
- optional: bool,
1048
- ) -> MustardResult<Value> {
1049
- if optional && matches!(object, Value::Null | Value::Undefined) {
1050
- return Ok(Value::Undefined);
1051
- }
1052
- let key = self.to_property_key(property)?;
1053
- match object {
1054
- Value::Object(object) => {
1055
- let object = self
1056
- .objects
1057
- .get(object)
1058
- .ok_or_else(|| MustardError::runtime("object missing"))?;
1059
- if let ObjectKind::Date(_) = &object.kind {
1060
- let built_in = match key.as_str() {
1061
- "getTime" => Some(Value::BuiltinFunction(BuiltinFunction::DateGetTime)),
1062
- "valueOf" => Some(Value::BuiltinFunction(BuiltinFunction::DateValueOf)),
1063
- "toISOString" => {
1064
- Some(Value::BuiltinFunction(BuiltinFunction::DateToISOString))
1065
- }
1066
- "toJSON" => Some(Value::BuiltinFunction(BuiltinFunction::DateToJSON)),
1067
- "getUTCFullYear" => {
1068
- Some(Value::BuiltinFunction(BuiltinFunction::DateGetUTCFullYear))
1069
- }
1070
- "getUTCMonth" => {
1071
- Some(Value::BuiltinFunction(BuiltinFunction::DateGetUTCMonth))
1072
- }
1073
- "getUTCDate" => {
1074
- Some(Value::BuiltinFunction(BuiltinFunction::DateGetUTCDate))
1075
- }
1076
- "getUTCHours" => {
1077
- Some(Value::BuiltinFunction(BuiltinFunction::DateGetUTCHours))
1078
- }
1079
- "getUTCMinutes" => {
1080
- Some(Value::BuiltinFunction(BuiltinFunction::DateGetUTCMinutes))
1081
- }
1082
- "getUTCSeconds" => {
1083
- Some(Value::BuiltinFunction(BuiltinFunction::DateGetUTCSeconds))
1084
- }
1085
- "constructor" => Some(Value::BuiltinFunction(BuiltinFunction::DateCtor)),
1086
- _ => None,
1087
- };
1088
- if let Some(value) = built_in {
1089
- return Ok(value);
1090
- }
1091
- }
1092
- if let ObjectKind::RegExp(regex) = &object.kind {
1093
- let built_in = match key.as_str() {
1094
- "source" => Some(Value::String(regex.pattern.clone())),
1095
- "flags" => Some(Value::String(regex.flags.clone())),
1096
- "global" => Some(Value::Bool(regex.flags.contains('g'))),
1097
- "ignoreCase" => Some(Value::Bool(regex.flags.contains('i'))),
1098
- "multiline" => Some(Value::Bool(regex.flags.contains('m'))),
1099
- "dotAll" => Some(Value::Bool(regex.flags.contains('s'))),
1100
- "unicode" => Some(Value::Bool(regex.flags.contains('u'))),
1101
- "sticky" => Some(Value::Bool(regex.flags.contains('y'))),
1102
- "lastIndex" => Some(Value::Number(regex.last_index as f64)),
1103
- "exec" => Some(Value::BuiltinFunction(BuiltinFunction::RegExpExec)),
1104
- "test" => Some(Value::BuiltinFunction(BuiltinFunction::RegExpTest)),
1105
- "constructor" => Some(Value::BuiltinFunction(BuiltinFunction::RegExpCtor)),
1106
- _ => None,
1107
- };
1108
- if let Some(value) = built_in {
1109
- return Ok(value);
1110
- }
1111
- }
1112
- if let ObjectKind::StringObject(value) = &object.kind {
1113
- if key == "length" {
1114
- return Ok(Value::Number(value.chars().count() as f64));
1115
- }
1116
- if let Some(index) = array_index_from_property_key(&key)
1117
- && let Some(ch) = value.chars().nth(index)
1118
- {
1119
- return Ok(Value::String(ch.to_string()));
1120
- }
1121
- if let Some(method) = match key.as_str() {
1122
- "trim" => Some(Value::BuiltinFunction(BuiltinFunction::StringTrim)),
1123
- "trimStart" => {
1124
- Some(Value::BuiltinFunction(BuiltinFunction::StringTrimStart))
1125
- }
1126
- "trimEnd" => Some(Value::BuiltinFunction(BuiltinFunction::StringTrimEnd)),
1127
- "includes" => Some(Value::BuiltinFunction(BuiltinFunction::StringIncludes)),
1128
- "startsWith" => {
1129
- Some(Value::BuiltinFunction(BuiltinFunction::StringStartsWith))
1130
- }
1131
- "endsWith" => Some(Value::BuiltinFunction(BuiltinFunction::StringEndsWith)),
1132
- "indexOf" => Some(Value::BuiltinFunction(BuiltinFunction::StringIndexOf)),
1133
- "lastIndexOf" => {
1134
- Some(Value::BuiltinFunction(BuiltinFunction::StringLastIndexOf))
1135
- }
1136
- "charAt" => Some(Value::BuiltinFunction(BuiltinFunction::StringCharAt)),
1137
- "at" => Some(Value::BuiltinFunction(BuiltinFunction::StringAt)),
1138
- "slice" => Some(Value::BuiltinFunction(BuiltinFunction::StringSlice)),
1139
- "substring" => {
1140
- Some(Value::BuiltinFunction(BuiltinFunction::StringSubstring))
1141
- }
1142
- "toLowerCase" => {
1143
- Some(Value::BuiltinFunction(BuiltinFunction::StringToLowerCase))
1144
- }
1145
- "toUpperCase" => {
1146
- Some(Value::BuiltinFunction(BuiltinFunction::StringToUpperCase))
1147
- }
1148
- "repeat" => Some(Value::BuiltinFunction(BuiltinFunction::StringRepeat)),
1149
- "concat" => Some(Value::BuiltinFunction(BuiltinFunction::StringConcat)),
1150
- "padStart" => Some(Value::BuiltinFunction(BuiltinFunction::StringPadStart)),
1151
- "padEnd" => Some(Value::BuiltinFunction(BuiltinFunction::StringPadEnd)),
1152
- "split" => Some(Value::BuiltinFunction(BuiltinFunction::StringSplit)),
1153
- "replace" => Some(Value::BuiltinFunction(BuiltinFunction::StringReplace)),
1154
- "replaceAll" => {
1155
- Some(Value::BuiltinFunction(BuiltinFunction::StringReplaceAll))
1156
- }
1157
- "search" => Some(Value::BuiltinFunction(BuiltinFunction::StringSearch)),
1158
- "match" => Some(Value::BuiltinFunction(BuiltinFunction::StringMatch)),
1159
- "matchAll" => Some(Value::BuiltinFunction(BuiltinFunction::StringMatchAll)),
1160
- "toString" => Some(Value::BuiltinFunction(BuiltinFunction::StringToString)),
1161
- "valueOf" => Some(Value::BuiltinFunction(BuiltinFunction::StringValueOf)),
1162
- _ => None,
1163
- } {
1164
- return Ok(method);
1165
- }
1166
- }
1167
- if let ObjectKind::NumberObject(_) = &object.kind {
1168
- match key.as_str() {
1169
- "toString" => {
1170
- return Ok(Value::BuiltinFunction(BuiltinFunction::NumberToString));
1171
- }
1172
- "valueOf" => {
1173
- return Ok(Value::BuiltinFunction(BuiltinFunction::NumberValueOf));
1174
- }
1175
- _ => {}
1176
- }
1177
- }
1178
- if let ObjectKind::BooleanObject(_) = &object.kind {
1179
- match key.as_str() {
1180
- "toString" => {
1181
- return Ok(Value::BuiltinFunction(BuiltinFunction::BooleanToString));
1182
- }
1183
- "valueOf" => {
1184
- return Ok(Value::BuiltinFunction(BuiltinFunction::BooleanValueOf));
1185
- }
1186
- _ => {}
1187
- }
1188
- }
1189
- if matches!(object.kind, ObjectKind::Intl) {
1190
- let built_in = match key.as_str() {
1191
- "DateTimeFormat" => Some(Value::BuiltinFunction(
1192
- BuiltinFunction::IntlDateTimeFormatCtor,
1193
- )),
1194
- "NumberFormat" => Some(Value::BuiltinFunction(
1195
- BuiltinFunction::IntlNumberFormatCtor,
1196
- )),
1197
- "constructor" => Some(Value::BuiltinFunction(BuiltinFunction::ObjectCtor)),
1198
- _ => None,
1199
- };
1200
- if let Some(value) = built_in {
1201
- return Ok(value);
1202
- }
1203
- }
1204
- if matches!(object.kind, ObjectKind::IntlDateTimeFormat(_)) {
1205
- let built_in = match key.as_str() {
1206
- "constructor" => Some(Value::BuiltinFunction(
1207
- BuiltinFunction::IntlDateTimeFormatCtor,
1208
- )),
1209
- "format" => Some(Value::BuiltinFunction(
1210
- BuiltinFunction::IntlDateTimeFormatFormat,
1211
- )),
1212
- "resolvedOptions" => Some(Value::BuiltinFunction(
1213
- BuiltinFunction::IntlDateTimeFormatResolvedOptions,
1214
- )),
1215
- _ => None,
1216
- };
1217
- if let Some(value) = built_in {
1218
- return Ok(value);
1219
- }
1220
- }
1221
- if matches!(object.kind, ObjectKind::IntlNumberFormat(_)) {
1222
- let built_in = match key.as_str() {
1223
- "constructor" => Some(Value::BuiltinFunction(
1224
- BuiltinFunction::IntlNumberFormatCtor,
1225
- )),
1226
- "format" => Some(Value::BuiltinFunction(
1227
- BuiltinFunction::IntlNumberFormatFormat,
1228
- )),
1229
- "resolvedOptions" => Some(Value::BuiltinFunction(
1230
- BuiltinFunction::IntlNumberFormatResolvedOptions,
1231
- )),
1232
- _ => None,
1233
- };
1234
- if let Some(value) = built_in {
1235
- return Ok(value);
1236
- }
1237
- }
1238
- if let Some(value) = object.properties.get(&key) {
1239
- return Ok(value.clone());
1240
- }
1241
- if let ObjectKind::FunctionPrototype(constructor) = &object.kind {
1242
- if key == "constructor" {
1243
- return Ok(constructor.clone());
1244
- }
1245
- if matches!(
1246
- constructor,
1247
- Value::BuiltinFunction(BuiltinFunction::DateCtor)
1248
- ) {
1249
- match key.as_str() {
1250
- "getTime" => {
1251
- return Ok(Value::BuiltinFunction(BuiltinFunction::DateGetTime));
1252
- }
1253
- "valueOf" => {
1254
- return Ok(Value::BuiltinFunction(BuiltinFunction::DateValueOf));
1255
- }
1256
- "toISOString" => {
1257
- return Ok(Value::BuiltinFunction(
1258
- BuiltinFunction::DateToISOString,
1259
- ));
1260
- }
1261
- "toJSON" => {
1262
- return Ok(Value::BuiltinFunction(BuiltinFunction::DateToJSON));
1263
- }
1264
- "getUTCFullYear" => {
1265
- return Ok(Value::BuiltinFunction(
1266
- BuiltinFunction::DateGetUTCFullYear,
1267
- ));
1268
- }
1269
- "getUTCMonth" => {
1270
- return Ok(Value::BuiltinFunction(
1271
- BuiltinFunction::DateGetUTCMonth,
1272
- ));
1273
- }
1274
- "getUTCDate" => {
1275
- return Ok(Value::BuiltinFunction(BuiltinFunction::DateGetUTCDate));
1276
- }
1277
- "getUTCHours" => {
1278
- return Ok(Value::BuiltinFunction(
1279
- BuiltinFunction::DateGetUTCHours,
1280
- ));
1281
- }
1282
- "getUTCMinutes" => {
1283
- return Ok(Value::BuiltinFunction(
1284
- BuiltinFunction::DateGetUTCMinutes,
1285
- ));
1286
- }
1287
- "getUTCSeconds" => {
1288
- return Ok(Value::BuiltinFunction(
1289
- BuiltinFunction::DateGetUTCSeconds,
1290
- ));
1291
- }
1292
- _ => {}
1293
- }
1294
- }
1295
- }
1296
- if let ObjectKind::BoundFunction(bound) = &object.kind {
1297
- match key.as_str() {
1298
- "name" => {
1299
- return Ok(Value::String(format!(
1300
- "bound {}",
1301
- self.callable_name(&bound.target)?
1302
- )));
1303
- }
1304
- "length" => {
1305
- let length = self
1306
- .callable_length(&bound.target)?
1307
- .saturating_sub(bound.args.len());
1308
- return Ok(Value::Number(length as f64));
1309
- }
1310
- "constructor" => return Ok(Self::callable_constructor()),
1311
- _ => {
1312
- if let Some(method) = Self::function_helper_method(&key) {
1313
- return Ok(method);
1314
- }
1315
- }
1316
- }
1317
- }
1318
- if let ObjectKind::StringObject(_) = &object.kind
1319
- && key == "constructor"
1320
- {
1321
- return Ok(Value::BuiltinFunction(BuiltinFunction::StringCtor));
1322
- }
1323
- if let ObjectKind::NumberObject(_) = &object.kind
1324
- && key == "constructor"
1325
- {
1326
- return Ok(Value::BuiltinFunction(BuiltinFunction::NumberCtor));
1327
- }
1328
- if let ObjectKind::BooleanObject(_) = &object.kind
1329
- && key == "constructor"
1330
- {
1331
- return Ok(Value::BuiltinFunction(BuiltinFunction::BooleanCtor));
1332
- }
1333
- if matches!(object.kind, ObjectKind::Console)
1334
- && let Some(value) = self.console_method(&key)
1335
- {
1336
- return Ok(value);
1337
- }
1338
- if key == "constructor" {
1339
- match &object.kind {
1340
- ObjectKind::Plain
1341
- | ObjectKind::Global
1342
- | ObjectKind::Math
1343
- | ObjectKind::Json
1344
- | ObjectKind::Intl
1345
- | ObjectKind::BoundFunction(_) => {
1346
- return Ok(Value::BuiltinFunction(BuiltinFunction::ObjectCtor));
1347
- }
1348
- ObjectKind::Error(name) => {
1349
- let ctor = match name.as_str() {
1350
- "TypeError" => BuiltinFunction::TypeErrorCtor,
1351
- "ReferenceError" => BuiltinFunction::ReferenceErrorCtor,
1352
- "RangeError" => BuiltinFunction::RangeErrorCtor,
1353
- "SyntaxError" => BuiltinFunction::SyntaxErrorCtor,
1354
- _ => BuiltinFunction::ErrorCtor,
1355
- };
1356
- return Ok(Value::BuiltinFunction(ctor));
1357
- }
1358
- _ => {}
1359
- }
1360
- }
1361
- Ok(Value::Undefined)
1362
- }
1363
- Value::Array(array) => {
1364
- let array = self
1365
- .arrays
1366
- .get(array)
1367
- .ok_or_else(|| MustardError::runtime("array missing"))?;
1368
- if key == "length" {
1369
- Ok(Value::Number(array.elements.len() as f64))
1370
- } else if key == "constructor" {
1371
- Ok(Value::BuiltinFunction(BuiltinFunction::ArrayCtor))
1372
- } else if let Some(index) = array_index_from_property_key(&key) {
1373
- Ok(array
1374
- .elements
1375
- .get(index)
1376
- .cloned()
1377
- .flatten()
1378
- .unwrap_or(Value::Undefined))
1379
- } else if let Some(value) = array.properties.get(&key) {
1380
- Ok(value.clone())
1381
- } else {
1382
- match key.as_str() {
1383
- "sort" => Ok(Value::BuiltinFunction(BuiltinFunction::ArraySort)),
1384
- "push" => Ok(Value::BuiltinFunction(BuiltinFunction::ArrayPush)),
1385
- "pop" => Ok(Value::BuiltinFunction(BuiltinFunction::ArrayPop)),
1386
- "slice" => Ok(Value::BuiltinFunction(BuiltinFunction::ArraySlice)),
1387
- "splice" => Ok(Value::BuiltinFunction(BuiltinFunction::ArraySplice)),
1388
- "concat" => Ok(Value::BuiltinFunction(BuiltinFunction::ArrayConcat)),
1389
- "at" => Ok(Value::BuiltinFunction(BuiltinFunction::ArrayAt)),
1390
- "join" => Ok(Value::BuiltinFunction(BuiltinFunction::ArrayJoin)),
1391
- "includes" => Ok(Value::BuiltinFunction(BuiltinFunction::ArrayIncludes)),
1392
- "indexOf" => Ok(Value::BuiltinFunction(BuiltinFunction::ArrayIndexOf)),
1393
- "lastIndexOf" => {
1394
- Ok(Value::BuiltinFunction(BuiltinFunction::ArrayLastIndexOf))
1395
- }
1396
- "reverse" => Ok(Value::BuiltinFunction(BuiltinFunction::ArrayReverse)),
1397
- "fill" => Ok(Value::BuiltinFunction(BuiltinFunction::ArrayFill)),
1398
- "values" => Ok(Value::BuiltinFunction(BuiltinFunction::ArrayValues)),
1399
- "keys" => Ok(Value::BuiltinFunction(BuiltinFunction::ArrayKeys)),
1400
- "entries" => Ok(Value::BuiltinFunction(BuiltinFunction::ArrayEntries)),
1401
- "forEach" => Ok(Value::BuiltinFunction(BuiltinFunction::ArrayForEach)),
1402
- "map" => Ok(Value::BuiltinFunction(BuiltinFunction::ArrayMap)),
1403
- "filter" => Ok(Value::BuiltinFunction(BuiltinFunction::ArrayFilter)),
1404
- "find" => Ok(Value::BuiltinFunction(BuiltinFunction::ArrayFind)),
1405
- "findIndex" => Ok(Value::BuiltinFunction(BuiltinFunction::ArrayFindIndex)),
1406
- "some" => Ok(Value::BuiltinFunction(BuiltinFunction::ArraySome)),
1407
- "every" => Ok(Value::BuiltinFunction(BuiltinFunction::ArrayEvery)),
1408
- "flat" => Ok(Value::BuiltinFunction(BuiltinFunction::ArrayFlat)),
1409
- "flatMap" => Ok(Value::BuiltinFunction(BuiltinFunction::ArrayFlatMap)),
1410
- "reduce" => Ok(Value::BuiltinFunction(BuiltinFunction::ArrayReduce)),
1411
- "reduceRight" => {
1412
- Ok(Value::BuiltinFunction(BuiltinFunction::ArrayReduceRight))
1413
- }
1414
- "findLast" => Ok(Value::BuiltinFunction(BuiltinFunction::ArrayFindLast)),
1415
- "findLastIndex" => {
1416
- Ok(Value::BuiltinFunction(BuiltinFunction::ArrayFindLastIndex))
1417
- }
1418
- _ => Ok(Value::Undefined),
1419
- }
1420
- }
1421
- }
1422
- Value::Map(map) => {
1423
- let map = self
1424
- .maps
1425
- .get(map)
1426
- .ok_or_else(|| MustardError::runtime("map missing"))?;
1427
- match key.as_str() {
1428
- "constructor" => Ok(Value::BuiltinFunction(BuiltinFunction::MapCtor)),
1429
- "size" => Ok(Value::Number(map.entries.len() as f64)),
1430
- "get" => Ok(Value::BuiltinFunction(BuiltinFunction::MapGet)),
1431
- "set" => Ok(Value::BuiltinFunction(BuiltinFunction::MapSet)),
1432
- "has" => Ok(Value::BuiltinFunction(BuiltinFunction::MapHas)),
1433
- "delete" => Ok(Value::BuiltinFunction(BuiltinFunction::MapDelete)),
1434
- "clear" => Ok(Value::BuiltinFunction(BuiltinFunction::MapClear)),
1435
- "entries" => Ok(Value::BuiltinFunction(BuiltinFunction::MapEntries)),
1436
- "keys" => Ok(Value::BuiltinFunction(BuiltinFunction::MapKeys)),
1437
- "values" => Ok(Value::BuiltinFunction(BuiltinFunction::MapValues)),
1438
- "forEach" => Ok(Value::BuiltinFunction(BuiltinFunction::MapForEach)),
1439
- _ => Ok(Value::Undefined),
1440
- }
1441
- }
1442
- Value::Set(set) => {
1443
- let set = self
1444
- .sets
1445
- .get(set)
1446
- .ok_or_else(|| MustardError::runtime("set missing"))?;
1447
- match key.as_str() {
1448
- "constructor" => Ok(Value::BuiltinFunction(BuiltinFunction::SetCtor)),
1449
- "size" => Ok(Value::Number(set.entries.len() as f64)),
1450
- "add" => Ok(Value::BuiltinFunction(BuiltinFunction::SetAdd)),
1451
- "has" => Ok(Value::BuiltinFunction(BuiltinFunction::SetHas)),
1452
- "delete" => Ok(Value::BuiltinFunction(BuiltinFunction::SetDelete)),
1453
- "clear" => Ok(Value::BuiltinFunction(BuiltinFunction::SetClear)),
1454
- "entries" => Ok(Value::BuiltinFunction(BuiltinFunction::SetEntries)),
1455
- "keys" => Ok(Value::BuiltinFunction(BuiltinFunction::SetKeys)),
1456
- "values" => Ok(Value::BuiltinFunction(BuiltinFunction::SetValues)),
1457
- "forEach" => Ok(Value::BuiltinFunction(BuiltinFunction::SetForEach)),
1458
- _ => Ok(Value::Undefined),
1459
- }
1460
- }
1461
- Value::Iterator(_) if key == "next" => {
1462
- Ok(Value::BuiltinFunction(BuiltinFunction::IteratorNext))
1463
- }
1464
- Value::Iterator(_) if key == "constructor" => {
1465
- Ok(Value::BuiltinFunction(BuiltinFunction::ObjectCtor))
1466
- }
1467
- Value::Iterator(_) => Ok(Value::Undefined),
1468
- Value::Promise(_) => match key.as_str() {
1469
- "constructor" => Ok(Value::BuiltinFunction(BuiltinFunction::PromiseCtor)),
1470
- "then" => Ok(Value::BuiltinFunction(BuiltinFunction::PromiseThen)),
1471
- "catch" => Ok(Value::BuiltinFunction(BuiltinFunction::PromiseCatch)),
1472
- "finally" => Ok(Value::BuiltinFunction(BuiltinFunction::PromiseFinally)),
1473
- _ => Ok(Value::Undefined),
1474
- },
1475
- Value::BuiltinFunction(function) => {
1476
- if let Some(value) = self.builtin_function_custom_property(function, &key)? {
1477
- return Ok(value);
1478
- }
1479
- if let Some(value) = self.builtin_function_own_property(function, &key) {
1480
- return Ok(value);
1481
- }
1482
- if key == "constructor" {
1483
- return Ok(Self::callable_constructor());
1484
- }
1485
- Ok(Self::function_helper_method(&key).unwrap_or(Value::Undefined))
1486
- }
1487
- Value::Closure(closure) => {
1488
- if let Some(value) = self.closure_own_property(closure, &key)? {
1489
- return Ok(value);
1490
- }
1491
- if key == "constructor" {
1492
- return Ok(Self::callable_constructor());
1493
- }
1494
- Ok(Self::function_helper_method(&key).unwrap_or(Value::Undefined))
1495
- }
1496
- Value::HostFunction(capability) => {
1497
- if let Some(value) = self.host_function_custom_property(&capability, &key)? {
1498
- return Ok(value);
1499
- }
1500
- match key.as_str() {
1501
- "name" => Ok(Value::String(capability)),
1502
- "length" => Ok(Value::Number(0.0)),
1503
- "constructor" => Ok(Self::callable_constructor()),
1504
- _ => Ok(Self::function_helper_method(&key).unwrap_or(Value::Undefined)),
1505
- }
1506
- }
1507
- Value::String(value) => match key.as_str() {
1508
- "length" => Ok(Value::Number(value.chars().count() as f64)),
1509
- "constructor" => Ok(Value::BuiltinFunction(BuiltinFunction::StringCtor)),
1510
- "trim" => Ok(Value::BuiltinFunction(BuiltinFunction::StringTrim)),
1511
- "trimStart" => Ok(Value::BuiltinFunction(BuiltinFunction::StringTrimStart)),
1512
- "trimEnd" => Ok(Value::BuiltinFunction(BuiltinFunction::StringTrimEnd)),
1513
- "includes" => Ok(Value::BuiltinFunction(BuiltinFunction::StringIncludes)),
1514
- "startsWith" => Ok(Value::BuiltinFunction(BuiltinFunction::StringStartsWith)),
1515
- "endsWith" => Ok(Value::BuiltinFunction(BuiltinFunction::StringEndsWith)),
1516
- "indexOf" => Ok(Value::BuiltinFunction(BuiltinFunction::StringIndexOf)),
1517
- "lastIndexOf" => Ok(Value::BuiltinFunction(BuiltinFunction::StringLastIndexOf)),
1518
- "charAt" => Ok(Value::BuiltinFunction(BuiltinFunction::StringCharAt)),
1519
- "at" => Ok(Value::BuiltinFunction(BuiltinFunction::StringAt)),
1520
- "slice" => Ok(Value::BuiltinFunction(BuiltinFunction::StringSlice)),
1521
- "substring" => Ok(Value::BuiltinFunction(BuiltinFunction::StringSubstring)),
1522
- "toLowerCase" => Ok(Value::BuiltinFunction(BuiltinFunction::StringToLowerCase)),
1523
- "toUpperCase" => Ok(Value::BuiltinFunction(BuiltinFunction::StringToUpperCase)),
1524
- "repeat" => Ok(Value::BuiltinFunction(BuiltinFunction::StringRepeat)),
1525
- "concat" => Ok(Value::BuiltinFunction(BuiltinFunction::StringConcat)),
1526
- "padStart" => Ok(Value::BuiltinFunction(BuiltinFunction::StringPadStart)),
1527
- "padEnd" => Ok(Value::BuiltinFunction(BuiltinFunction::StringPadEnd)),
1528
- "split" => Ok(Value::BuiltinFunction(BuiltinFunction::StringSplit)),
1529
- "replace" => Ok(Value::BuiltinFunction(BuiltinFunction::StringReplace)),
1530
- "replaceAll" => Ok(Value::BuiltinFunction(BuiltinFunction::StringReplaceAll)),
1531
- "search" => Ok(Value::BuiltinFunction(BuiltinFunction::StringSearch)),
1532
- "match" => Ok(Value::BuiltinFunction(BuiltinFunction::StringMatch)),
1533
- "matchAll" => Ok(Value::BuiltinFunction(BuiltinFunction::StringMatchAll)),
1534
- "toString" => Ok(Value::BuiltinFunction(BuiltinFunction::StringToString)),
1535
- "valueOf" => Ok(Value::BuiltinFunction(BuiltinFunction::StringValueOf)),
1536
- _ if array_index_from_property_key(&key)
1537
- .is_some_and(|index| value.chars().nth(index).is_some()) =>
1538
- {
1539
- let index = array_index_from_property_key(&key).expect("index already checked");
1540
- Ok(Value::String(
1541
- value
1542
- .chars()
1543
- .nth(index)
1544
- .expect("index already checked")
1545
- .to_string(),
1546
- ))
1547
- }
1548
- _ => Ok(Value::Undefined),
1549
- },
1550
- Value::Number(_) => match key.as_str() {
1551
- "constructor" => Ok(Value::BuiltinFunction(BuiltinFunction::NumberCtor)),
1552
- "toString" => Ok(Value::BuiltinFunction(BuiltinFunction::NumberToString)),
1553
- "valueOf" => Ok(Value::BuiltinFunction(BuiltinFunction::NumberValueOf)),
1554
- _ => Ok(Value::Undefined),
1555
- },
1556
- Value::Bool(_) => match key.as_str() {
1557
- "constructor" => Ok(Value::BuiltinFunction(BuiltinFunction::BooleanCtor)),
1558
- "toString" => Ok(Value::BuiltinFunction(BuiltinFunction::BooleanToString)),
1559
- "valueOf" => Ok(Value::BuiltinFunction(BuiltinFunction::BooleanValueOf)),
1560
- _ => Ok(Value::Undefined),
1561
- },
1562
- Value::Null | Value::Undefined => Err(MustardError::runtime(
1563
- "TypeError: cannot read properties of nullish value",
1564
- )),
1565
- _ => Ok(Value::Undefined),
1566
- }
1567
- }
1568
-
1569
- pub(super) fn callable_name(&self, value: &Value) -> MustardResult<String> {
1570
- Ok(match value {
1571
- Value::Closure(closure) => match self.closure_own_property(*closure, "name")? {
1572
- Some(Value::String(name)) => name,
1573
- _ => String::new(),
1574
- },
1575
- Value::BuiltinFunction(function) => Self::builtin_function_name(*function).to_string(),
1576
- Value::HostFunction(capability) => capability.clone(),
1577
- Value::Object(object) => match &self
1578
- .objects
1579
- .get(*object)
1580
- .ok_or_else(|| MustardError::runtime("object missing"))?
1581
- .kind
1582
- {
1583
- ObjectKind::BoundFunction(bound) => {
1584
- format!("bound {}", self.callable_name(&bound.target)?)
1585
- }
1586
- _ => String::new(),
1587
- },
1588
- _ => String::new(),
1589
- })
1590
- }
1591
-
1592
- fn callable_length(&self, value: &Value) -> MustardResult<usize> {
1593
- Ok(match value {
1594
- Value::Closure(closure) => match self.closure_own_property(*closure, "length")? {
1595
- Some(Value::Number(length)) => length.max(0.0) as usize,
1596
- _ => 0,
1597
- },
1598
- Value::BuiltinFunction(function) => Self::builtin_function_length(*function),
1599
- Value::HostFunction(_) => 0,
1600
- Value::Object(object) => match &self
1601
- .objects
1602
- .get(*object)
1603
- .ok_or_else(|| MustardError::runtime("object missing"))?
1604
- .kind
1605
- {
1606
- ObjectKind::BoundFunction(bound) => self
1607
- .callable_length(&bound.target)?
1608
- .saturating_sub(bound.args.len()),
1609
- _ => 0,
1610
- },
1611
- _ => 0,
1612
- })
1613
- }
1614
-
1615
- pub(super) fn set_property(
1616
- &mut self,
1617
- object: Value,
1618
- property: Value,
1619
- value: Value,
1620
- ) -> MustardResult<()> {
1621
- let key = self.to_property_key(property)?;
1622
- self.infer_closure_name(&value, &key)?;
1623
- match object {
1624
- Value::Object(object) => {
1625
- if self.is_regexp_object(object) && key == "lastIndex" {
1626
- let index = self.to_integer(value.clone())?.max(0) as usize;
1627
- self.regexp_object_mut(object)?.last_index = index;
1628
- self.refresh_object_accounting(object)?;
1629
- return Ok(());
1630
- }
1631
- self.objects
1632
- .get_mut(object)
1633
- .ok_or_else(|| MustardError::runtime("object missing"))?
1634
- .properties
1635
- .insert(key, value);
1636
- self.refresh_object_accounting(object)?;
1637
- Ok(())
1638
- }
1639
- Value::Array(array) => {
1640
- if key == "length" {
1641
- self.set_array_length(array, value)?;
1642
- return Ok(());
1643
- }
1644
- {
1645
- let array_ref = self
1646
- .arrays
1647
- .get_mut(array)
1648
- .ok_or_else(|| MustardError::runtime("array missing"))?;
1649
- if let Some(index) = array_index_from_property_key(&key) {
1650
- if index >= array_ref.elements.len() {
1651
- array_ref.elements.resize(index + 1, None);
1652
- }
1653
- array_ref.elements[index] = Some(value);
1654
- } else {
1655
- array_ref.properties.insert(key, value);
1656
- }
1657
- }
1658
- self.refresh_array_accounting(array)?;
1659
- Ok(())
1660
- }
1661
- Value::Map(_) => Err(MustardError::runtime(
1662
- "TypeError: custom properties on Map values are not supported",
1663
- )),
1664
- Value::Set(_) => Err(MustardError::runtime(
1665
- "TypeError: custom properties on Set values are not supported",
1666
- )),
1667
- Value::Closure(closure) => self.set_closure_property(closure, key, value),
1668
- Value::BuiltinFunction(function) => {
1669
- self.set_builtin_function_property(function, key, value)
1670
- }
1671
- Value::HostFunction(capability) => {
1672
- self.set_host_function_property(capability, key, value)
1673
- }
1674
- _ => Err(MustardError::runtime("TypeError: value is not an object")),
1675
- }
1676
- }
1677
-
1678
- pub(super) fn console_method(&self, key: &str) -> Option<Value> {
1679
- let capability = match key {
1680
- "log" => "console.log",
1681
- "warn" => "console.warn",
1682
- "error" => "console.error",
1683
- _ => return None,
1684
- };
1685
- self.capability_value(capability)
1686
- }
1687
- }
1688
-
1689
- pub(super) fn canonicalize_collection_key(value: Value) -> Value {
1690
- match value {
1691
- Value::Number(number) if number == 0.0 && number.is_sign_negative() => Value::Number(0.0),
1692
- other => other,
1693
- }
1694
- }
1695
-
1696
- pub(super) fn property_name_to_key(name: &PropertyName) -> String {
1697
- match name {
1698
- PropertyName::Identifier(name) | PropertyName::String(name) => name.clone(),
1699
- PropertyName::Number(number) => format_number_key(*number),
1700
- }
1701
- }
1702
-
1703
- pub(super) fn format_number_key(value: f64) -> String {
1704
- if value.fract() == 0.0 {
1705
- format!("{}", value as i64)
1706
- } else {
1707
- value.to_string()
1708
- }
1709
- }
1710
-
1711
- pub(super) fn array_index_from_property_key(key: &str) -> Option<usize> {
1712
- if key == "0" {
1713
- return Some(0);
1714
- }
1715
-
1716
- if key.is_empty() || key.starts_with('0') {
1717
- return None;
1718
- }
1719
-
1720
- let index = key.parse::<u32>().ok()?;
1721
- if index == u32::MAX {
1722
- return None;
1723
- }
1724
-
1725
- if key == index.to_string() {
1726
- Some(index as usize)
1727
- } else {
1728
- None
1729
- }
1730
- }
1731
-
1732
- pub(super) fn ordered_own_property_keys(properties: &IndexMap<String, Value>) -> Vec<String> {
1733
- ordered_own_property_keys_filtered(properties, |_, _| true)
1734
- }
1735
-
1736
- pub(super) fn ordered_own_property_keys_filtered<F>(
1737
- properties: &IndexMap<String, Value>,
1738
- mut include: F,
1739
- ) -> Vec<String>
1740
- where
1741
- F: FnMut(&str, &Value) -> bool,
1742
- {
1743
- let mut keys = Vec::with_capacity(properties.len());
1744
- let mut index_keys = properties
1745
- .iter()
1746
- .filter(|(key, value)| include(key, value))
1747
- .filter_map(|(key, _)| array_index_from_property_key(key).map(|index| (index, key.clone())))
1748
- .collect::<Vec<_>>();
1749
- index_keys.sort_unstable_by_key(|(index, _)| *index);
1750
- keys.extend(index_keys.into_iter().map(|(_, key)| key));
1751
-
1752
- keys.extend(
1753
- properties
1754
- .iter()
1755
- .filter(|(key, value)| {
1756
- include(key, value) && array_index_from_property_key(key).is_none()
1757
- })
1758
- .map(|(key, _)| key.clone()),
1759
- );
1760
-
1761
- keys
1762
- }