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.
- package/Cargo.lock +1579 -0
- package/Cargo.toml +40 -0
- package/LICENSE +201 -0
- package/README.md +828 -0
- package/SECURITY.md +34 -0
- package/crates/mustard/Cargo.toml +31 -0
- package/crates/mustard/src/cancellation.rs +28 -0
- package/crates/mustard/src/diagnostic.rs +145 -0
- package/crates/mustard/src/ir.rs +435 -0
- package/crates/mustard/src/lib.rs +21 -0
- package/crates/mustard/src/limits.rs +22 -0
- package/crates/mustard/src/parser/expressions.rs +723 -0
- package/crates/mustard/src/parser/mod.rs +115 -0
- package/crates/mustard/src/parser/operators.rs +105 -0
- package/crates/mustard/src/parser/patterns.rs +123 -0
- package/crates/mustard/src/parser/scope.rs +107 -0
- package/crates/mustard/src/parser/statements.rs +298 -0
- package/crates/mustard/src/parser/tests/acceptance.rs +339 -0
- package/crates/mustard/src/parser/tests/mod.rs +2 -0
- package/crates/mustard/src/parser/tests/rejections.rs +107 -0
- package/crates/mustard/src/runtime/accounting.rs +613 -0
- package/crates/mustard/src/runtime/api.rs +192 -0
- package/crates/mustard/src/runtime/async_runtime/mod.rs +5 -0
- package/crates/mustard/src/runtime/async_runtime/promises.rs +246 -0
- package/crates/mustard/src/runtime/async_runtime/reactions.rs +400 -0
- package/crates/mustard/src/runtime/async_runtime/scheduler.rs +224 -0
- package/crates/mustard/src/runtime/builtins/arrays.rs +1205 -0
- package/crates/mustard/src/runtime/builtins/collections.rs +573 -0
- package/crates/mustard/src/runtime/builtins/install.rs +501 -0
- package/crates/mustard/src/runtime/builtins/intl.rs +553 -0
- package/crates/mustard/src/runtime/builtins/mod.rs +25 -0
- package/crates/mustard/src/runtime/builtins/objects.rs +405 -0
- package/crates/mustard/src/runtime/builtins/primitives.rs +859 -0
- package/crates/mustard/src/runtime/builtins/promises.rs +335 -0
- package/crates/mustard/src/runtime/builtins/regexp.rs +356 -0
- package/crates/mustard/src/runtime/builtins/strings.rs +803 -0
- package/crates/mustard/src/runtime/builtins/support.rs +561 -0
- package/crates/mustard/src/runtime/bytecode.rs +123 -0
- package/crates/mustard/src/runtime/compiler/assignments.rs +690 -0
- package/crates/mustard/src/runtime/compiler/bindings.rs +92 -0
- package/crates/mustard/src/runtime/compiler/context.rs +46 -0
- package/crates/mustard/src/runtime/compiler/control.rs +342 -0
- package/crates/mustard/src/runtime/compiler/expressions.rs +372 -0
- package/crates/mustard/src/runtime/compiler/mod.rs +173 -0
- package/crates/mustard/src/runtime/compiler/statements.rs +459 -0
- package/crates/mustard/src/runtime/conversions/boundary.rs +293 -0
- package/crates/mustard/src/runtime/conversions/coercions.rs +217 -0
- package/crates/mustard/src/runtime/conversions/errors.rs +118 -0
- package/crates/mustard/src/runtime/conversions/mod.rs +14 -0
- package/crates/mustard/src/runtime/conversions/operators.rs +334 -0
- package/crates/mustard/src/runtime/env.rs +355 -0
- package/crates/mustard/src/runtime/exceptions.rs +377 -0
- package/crates/mustard/src/runtime/gc.rs +595 -0
- package/crates/mustard/src/runtime/mod.rs +318 -0
- package/crates/mustard/src/runtime/properties.rs +1762 -0
- package/crates/mustard/src/runtime/serialization.rs +127 -0
- package/crates/mustard/src/runtime/shared.rs +108 -0
- package/crates/mustard/src/runtime/snapshot_validation_tests.rs +93 -0
- package/crates/mustard/src/runtime/state.rs +652 -0
- package/crates/mustard/src/runtime/tests/async_host.rs +104 -0
- package/crates/mustard/src/runtime/tests/collections.rs +50 -0
- package/crates/mustard/src/runtime/tests/diagnostics.rs +36 -0
- package/crates/mustard/src/runtime/tests/exceptions.rs +122 -0
- package/crates/mustard/src/runtime/tests/execution.rs +553 -0
- package/crates/mustard/src/runtime/tests/gc.rs +533 -0
- package/crates/mustard/src/runtime/tests/mod.rs +56 -0
- package/crates/mustard/src/runtime/tests/serialization.rs +170 -0
- package/crates/mustard/src/runtime/validation/bytecode.rs +484 -0
- package/crates/mustard/src/runtime/validation/mod.rs +14 -0
- package/crates/mustard/src/runtime/validation/policy.rs +94 -0
- package/crates/mustard/src/runtime/validation/snapshot.rs +406 -0
- package/crates/mustard/src/runtime/validation/walk.rs +206 -0
- package/crates/mustard/src/runtime/vm.rs +1016 -0
- package/crates/mustard/src/span.rs +22 -0
- package/crates/mustard/src/structured.rs +107 -0
- package/crates/mustard-bridge/Cargo.toml +17 -0
- package/crates/mustard-bridge/src/codec.rs +46 -0
- package/crates/mustard-bridge/src/dto.rs +99 -0
- package/crates/mustard-bridge/src/lib.rs +12 -0
- package/crates/mustard-bridge/src/operations.rs +142 -0
- package/crates/mustard-node/Cargo.toml +24 -0
- package/crates/mustard-node/build.rs +3 -0
- package/crates/mustard-node/src/lib.rs +236 -0
- package/crates/mustard-sidecar/Cargo.toml +21 -0
- package/crates/mustard-sidecar/src/lib.rs +134 -0
- package/crates/mustard-sidecar/src/main.rs +36 -0
- package/dist/index.js +20 -0
- package/dist/install.js +117 -0
- package/dist/lib/cancellation.js +124 -0
- package/dist/lib/errors.js +46 -0
- package/dist/lib/executor.js +555 -0
- package/dist/lib/policy.js +292 -0
- package/dist/lib/progress.js +356 -0
- package/dist/lib/runtime.js +109 -0
- package/dist/lib/structured.js +286 -0
- package/dist/native-loader.js +227 -0
- package/index.d.ts +23 -0
- package/mustard.d.ts +220 -0
- package/package.json +97 -0
package/SECURITY.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Scope
|
|
4
|
+
|
|
5
|
+
Security issues include:
|
|
6
|
+
|
|
7
|
+
- Guest escapes from the intended language boundary
|
|
8
|
+
- Host value validation failures that permit unsafe object transfer
|
|
9
|
+
- Snapshot or sidecar deserialization bugs
|
|
10
|
+
- Limit enforcement bugs that break documented containment guarantees
|
|
11
|
+
|
|
12
|
+
## Important Notes
|
|
13
|
+
|
|
14
|
+
- Addon mode is not a hard isolation boundary.
|
|
15
|
+
- Sidecar mode is stronger, but hostile deployments still require OS-level controls.
|
|
16
|
+
|
|
17
|
+
## Reporting
|
|
18
|
+
|
|
19
|
+
Report vulnerabilities through GitHub Security Advisories:
|
|
20
|
+
|
|
21
|
+
- https://github.com/keppoai/mustardscript/security/advisories/new
|
|
22
|
+
|
|
23
|
+
Do not open public GitHub issues for unpatched security reports.
|
|
24
|
+
|
|
25
|
+
## Supported Versions
|
|
26
|
+
|
|
27
|
+
- The latest published npm release
|
|
28
|
+
- `main` before the next release is cut
|
|
29
|
+
|
|
30
|
+
## Response Expectations
|
|
31
|
+
|
|
32
|
+
- Initial triage acknowledgment target: 5 business days
|
|
33
|
+
- Coordinated disclosure and fix timing will be handled through the advisory
|
|
34
|
+
thread
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "mustard"
|
|
3
|
+
version.workspace = true
|
|
4
|
+
edition.workspace = true
|
|
5
|
+
license.workspace = true
|
|
6
|
+
authors.workspace = true
|
|
7
|
+
repository.workspace = true
|
|
8
|
+
description = "Sandboxed subset-JavaScript runtime core for MustardScript"
|
|
9
|
+
|
|
10
|
+
[dependencies]
|
|
11
|
+
anyhow.workspace = true
|
|
12
|
+
bincode.workspace = true
|
|
13
|
+
futures.workspace = true
|
|
14
|
+
indexmap.workspace = true
|
|
15
|
+
num-bigint.workspace = true
|
|
16
|
+
num-traits.workspace = true
|
|
17
|
+
oxc_allocator.workspace = true
|
|
18
|
+
oxc_ast.workspace = true
|
|
19
|
+
oxc_parser.workspace = true
|
|
20
|
+
oxc_span.workspace = true
|
|
21
|
+
oxc_syntax.workspace = true
|
|
22
|
+
serde.workspace = true
|
|
23
|
+
serde_json.workspace = true
|
|
24
|
+
slotmap.workspace = true
|
|
25
|
+
thiserror.workspace = true
|
|
26
|
+
regex.workspace = true
|
|
27
|
+
rand.workspace = true
|
|
28
|
+
time.workspace = true
|
|
29
|
+
|
|
30
|
+
[dev-dependencies]
|
|
31
|
+
proptest = "1.9.0"
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
use std::sync::{
|
|
2
|
+
Arc,
|
|
3
|
+
atomic::{AtomicBool, Ordering},
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
#[derive(Debug, Clone, Default)]
|
|
7
|
+
pub struct CancellationToken {
|
|
8
|
+
state: Arc<AtomicBool>,
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
impl CancellationToken {
|
|
12
|
+
pub fn new() -> Self {
|
|
13
|
+
Self::default()
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
pub fn cancel(&self) {
|
|
17
|
+
self.state.store(true, Ordering::SeqCst);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
pub fn is_cancelled(&self) -> bool {
|
|
21
|
+
self.state.load(Ordering::SeqCst)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
#[doc(hidden)]
|
|
25
|
+
pub fn from_shared(state: Arc<AtomicBool>) -> Self {
|
|
26
|
+
Self { state }
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
use std::fmt;
|
|
2
|
+
|
|
3
|
+
use crate::span::SourceSpan;
|
|
4
|
+
|
|
5
|
+
pub type MustardResult<T> = Result<T, MustardError>;
|
|
6
|
+
|
|
7
|
+
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
8
|
+
pub enum DiagnosticKind {
|
|
9
|
+
Parse,
|
|
10
|
+
Validation,
|
|
11
|
+
Runtime,
|
|
12
|
+
Limit,
|
|
13
|
+
Serialization,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
17
|
+
pub struct Diagnostic {
|
|
18
|
+
pub kind: DiagnosticKind,
|
|
19
|
+
pub message: String,
|
|
20
|
+
pub span: Option<SourceSpan>,
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
24
|
+
pub struct TraceFrame {
|
|
25
|
+
pub function_name: Option<String>,
|
|
26
|
+
pub span: SourceSpan,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
impl Diagnostic {
|
|
30
|
+
pub fn parse(message: impl Into<String>, span: Option<SourceSpan>) -> Self {
|
|
31
|
+
Self {
|
|
32
|
+
kind: DiagnosticKind::Parse,
|
|
33
|
+
message: message.into(),
|
|
34
|
+
span,
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
pub fn validation(message: impl Into<String>, span: Option<SourceSpan>) -> Self {
|
|
39
|
+
Self {
|
|
40
|
+
kind: DiagnosticKind::Validation,
|
|
41
|
+
message: message.into(),
|
|
42
|
+
span,
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
#[derive(Debug, Clone)]
|
|
48
|
+
pub enum MustardError {
|
|
49
|
+
Diagnostics(Vec<Diagnostic>),
|
|
50
|
+
Message {
|
|
51
|
+
kind: DiagnosticKind,
|
|
52
|
+
message: String,
|
|
53
|
+
span: Option<SourceSpan>,
|
|
54
|
+
traceback: Vec<TraceFrame>,
|
|
55
|
+
},
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
impl MustardError {
|
|
59
|
+
pub fn validation(message: impl Into<String>, span: Option<SourceSpan>) -> Self {
|
|
60
|
+
Self::Message {
|
|
61
|
+
kind: DiagnosticKind::Validation,
|
|
62
|
+
message: message.into(),
|
|
63
|
+
span,
|
|
64
|
+
traceback: Vec::new(),
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
pub fn runtime(message: impl Into<String>) -> Self {
|
|
69
|
+
Self::Message {
|
|
70
|
+
kind: DiagnosticKind::Runtime,
|
|
71
|
+
message: message.into(),
|
|
72
|
+
span: None,
|
|
73
|
+
traceback: Vec::new(),
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
pub fn runtime_at(message: impl Into<String>, span: SourceSpan) -> Self {
|
|
78
|
+
Self::Message {
|
|
79
|
+
kind: DiagnosticKind::Runtime,
|
|
80
|
+
message: message.into(),
|
|
81
|
+
span: Some(span),
|
|
82
|
+
traceback: Vec::new(),
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
pub fn with_traceback(mut self, frames: Vec<TraceFrame>) -> Self {
|
|
87
|
+
if frames.is_empty() {
|
|
88
|
+
return self;
|
|
89
|
+
}
|
|
90
|
+
if let Self::Message {
|
|
91
|
+
span, traceback, ..
|
|
92
|
+
} = &mut self
|
|
93
|
+
{
|
|
94
|
+
if span.is_none() {
|
|
95
|
+
*span = frames.first().map(|frame| frame.span);
|
|
96
|
+
}
|
|
97
|
+
if traceback.is_empty() {
|
|
98
|
+
*traceback = frames;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
self
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
impl fmt::Display for MustardError {
|
|
106
|
+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
107
|
+
match self {
|
|
108
|
+
Self::Diagnostics(items) => {
|
|
109
|
+
for (index, item) in items.iter().enumerate() {
|
|
110
|
+
if index > 0 {
|
|
111
|
+
writeln!(f)?;
|
|
112
|
+
}
|
|
113
|
+
write!(f, "{:?}: {}", item.kind, item.message)?;
|
|
114
|
+
if let Some(span) = item.span {
|
|
115
|
+
write!(f, " [{}..{}]", span.start, span.end)?;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
Ok(())
|
|
119
|
+
}
|
|
120
|
+
Self::Message {
|
|
121
|
+
kind,
|
|
122
|
+
message,
|
|
123
|
+
span,
|
|
124
|
+
traceback,
|
|
125
|
+
} => {
|
|
126
|
+
write!(f, "{kind:?}: {message}")?;
|
|
127
|
+
if let Some(span) = span {
|
|
128
|
+
write!(f, " [{}..{}]", span.start, span.end)?;
|
|
129
|
+
}
|
|
130
|
+
for frame in traceback {
|
|
131
|
+
write!(
|
|
132
|
+
f,
|
|
133
|
+
"\n at {} [{}..{}]",
|
|
134
|
+
frame.function_name.as_deref().unwrap_or("<script>"),
|
|
135
|
+
frame.span.start,
|
|
136
|
+
frame.span.end
|
|
137
|
+
)?;
|
|
138
|
+
}
|
|
139
|
+
Ok(())
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
impl std::error::Error for MustardError {}
|
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
use serde::{Deserialize, Serialize};
|
|
2
|
+
|
|
3
|
+
use crate::span::SourceSpan;
|
|
4
|
+
|
|
5
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
6
|
+
pub struct CompiledProgram {
|
|
7
|
+
pub source: String,
|
|
8
|
+
pub script: Script,
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
12
|
+
pub struct Script {
|
|
13
|
+
pub span: SourceSpan,
|
|
14
|
+
pub body: Vec<Stmt>,
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
18
|
+
pub enum Stmt {
|
|
19
|
+
Block {
|
|
20
|
+
span: SourceSpan,
|
|
21
|
+
body: Vec<Stmt>,
|
|
22
|
+
},
|
|
23
|
+
VariableDecl {
|
|
24
|
+
span: SourceSpan,
|
|
25
|
+
kind: BindingKind,
|
|
26
|
+
declarators: Vec<Declarator>,
|
|
27
|
+
},
|
|
28
|
+
FunctionDecl {
|
|
29
|
+
span: SourceSpan,
|
|
30
|
+
function: FunctionExpr,
|
|
31
|
+
},
|
|
32
|
+
Expression {
|
|
33
|
+
span: SourceSpan,
|
|
34
|
+
expression: Expr,
|
|
35
|
+
},
|
|
36
|
+
If {
|
|
37
|
+
span: SourceSpan,
|
|
38
|
+
test: Expr,
|
|
39
|
+
consequent: Box<Stmt>,
|
|
40
|
+
alternate: Option<Box<Stmt>>,
|
|
41
|
+
},
|
|
42
|
+
While {
|
|
43
|
+
span: SourceSpan,
|
|
44
|
+
test: Expr,
|
|
45
|
+
body: Box<Stmt>,
|
|
46
|
+
},
|
|
47
|
+
DoWhile {
|
|
48
|
+
span: SourceSpan,
|
|
49
|
+
body: Box<Stmt>,
|
|
50
|
+
test: Expr,
|
|
51
|
+
},
|
|
52
|
+
For {
|
|
53
|
+
span: SourceSpan,
|
|
54
|
+
init: Option<ForInit>,
|
|
55
|
+
test: Option<Expr>,
|
|
56
|
+
update: Option<Expr>,
|
|
57
|
+
body: Box<Stmt>,
|
|
58
|
+
},
|
|
59
|
+
ForOf {
|
|
60
|
+
span: SourceSpan,
|
|
61
|
+
await_each: bool,
|
|
62
|
+
head: ForOfHead,
|
|
63
|
+
iterable: Expr,
|
|
64
|
+
body: Box<Stmt>,
|
|
65
|
+
},
|
|
66
|
+
ForIn {
|
|
67
|
+
span: SourceSpan,
|
|
68
|
+
head: ForOfHead,
|
|
69
|
+
object: Expr,
|
|
70
|
+
body: Box<Stmt>,
|
|
71
|
+
},
|
|
72
|
+
Break {
|
|
73
|
+
span: SourceSpan,
|
|
74
|
+
},
|
|
75
|
+
Continue {
|
|
76
|
+
span: SourceSpan,
|
|
77
|
+
},
|
|
78
|
+
Return {
|
|
79
|
+
span: SourceSpan,
|
|
80
|
+
value: Option<Expr>,
|
|
81
|
+
},
|
|
82
|
+
Throw {
|
|
83
|
+
span: SourceSpan,
|
|
84
|
+
value: Expr,
|
|
85
|
+
},
|
|
86
|
+
Try {
|
|
87
|
+
span: SourceSpan,
|
|
88
|
+
body: Box<Stmt>,
|
|
89
|
+
catch: Option<CatchClause>,
|
|
90
|
+
finally: Option<Box<Stmt>>,
|
|
91
|
+
},
|
|
92
|
+
Switch {
|
|
93
|
+
span: SourceSpan,
|
|
94
|
+
discriminant: Expr,
|
|
95
|
+
cases: Vec<SwitchCase>,
|
|
96
|
+
},
|
|
97
|
+
Empty {
|
|
98
|
+
span: SourceSpan,
|
|
99
|
+
},
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
103
|
+
pub enum ForInit {
|
|
104
|
+
VariableDecl {
|
|
105
|
+
kind: BindingKind,
|
|
106
|
+
declarators: Vec<Declarator>,
|
|
107
|
+
},
|
|
108
|
+
Expression(Expr),
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
112
|
+
pub enum ForOfHead {
|
|
113
|
+
Binding { kind: BindingKind, pattern: Pattern },
|
|
114
|
+
Assignment { target: AssignTarget },
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
118
|
+
pub struct Declarator {
|
|
119
|
+
pub span: SourceSpan,
|
|
120
|
+
pub pattern: Pattern,
|
|
121
|
+
pub initializer: Option<Expr>,
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
|
125
|
+
pub enum BindingKind {
|
|
126
|
+
Let,
|
|
127
|
+
Const,
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
131
|
+
pub struct CatchClause {
|
|
132
|
+
pub span: SourceSpan,
|
|
133
|
+
pub parameter: Option<Pattern>,
|
|
134
|
+
pub body: Box<Stmt>,
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
138
|
+
pub struct SwitchCase {
|
|
139
|
+
pub span: SourceSpan,
|
|
140
|
+
pub test: Option<Expr>,
|
|
141
|
+
pub consequent: Vec<Stmt>,
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
145
|
+
pub enum Pattern {
|
|
146
|
+
Identifier {
|
|
147
|
+
span: SourceSpan,
|
|
148
|
+
name: String,
|
|
149
|
+
},
|
|
150
|
+
Object {
|
|
151
|
+
span: SourceSpan,
|
|
152
|
+
properties: Vec<ObjectPatternProperty>,
|
|
153
|
+
rest: Option<Box<Pattern>>,
|
|
154
|
+
},
|
|
155
|
+
Array {
|
|
156
|
+
span: SourceSpan,
|
|
157
|
+
elements: Vec<Option<Pattern>>,
|
|
158
|
+
rest: Option<Box<Pattern>>,
|
|
159
|
+
},
|
|
160
|
+
Default {
|
|
161
|
+
span: SourceSpan,
|
|
162
|
+
target: Box<Pattern>,
|
|
163
|
+
default_value: Expr,
|
|
164
|
+
},
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
168
|
+
pub struct ObjectPatternProperty {
|
|
169
|
+
pub span: SourceSpan,
|
|
170
|
+
pub key: PropertyName,
|
|
171
|
+
pub value: Pattern,
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
175
|
+
pub enum PropertyName {
|
|
176
|
+
Identifier(String),
|
|
177
|
+
String(String),
|
|
178
|
+
Number(f64),
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
182
|
+
pub struct FunctionExpr {
|
|
183
|
+
pub span: SourceSpan,
|
|
184
|
+
pub name: Option<String>,
|
|
185
|
+
pub length: usize,
|
|
186
|
+
pub display_source: String,
|
|
187
|
+
pub params: Vec<Pattern>,
|
|
188
|
+
pub rest: Option<Pattern>,
|
|
189
|
+
pub param_init: Vec<Stmt>,
|
|
190
|
+
pub body: Vec<Stmt>,
|
|
191
|
+
pub is_async: bool,
|
|
192
|
+
pub is_arrow: bool,
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
196
|
+
pub enum Expr {
|
|
197
|
+
Undefined {
|
|
198
|
+
span: SourceSpan,
|
|
199
|
+
},
|
|
200
|
+
Null {
|
|
201
|
+
span: SourceSpan,
|
|
202
|
+
},
|
|
203
|
+
Bool {
|
|
204
|
+
span: SourceSpan,
|
|
205
|
+
value: bool,
|
|
206
|
+
},
|
|
207
|
+
Number {
|
|
208
|
+
span: SourceSpan,
|
|
209
|
+
value: f64,
|
|
210
|
+
},
|
|
211
|
+
BigInt {
|
|
212
|
+
span: SourceSpan,
|
|
213
|
+
value: String,
|
|
214
|
+
},
|
|
215
|
+
String {
|
|
216
|
+
span: SourceSpan,
|
|
217
|
+
value: String,
|
|
218
|
+
},
|
|
219
|
+
RegExp {
|
|
220
|
+
span: SourceSpan,
|
|
221
|
+
pattern: String,
|
|
222
|
+
flags: String,
|
|
223
|
+
},
|
|
224
|
+
Identifier {
|
|
225
|
+
span: SourceSpan,
|
|
226
|
+
name: String,
|
|
227
|
+
},
|
|
228
|
+
This {
|
|
229
|
+
span: SourceSpan,
|
|
230
|
+
},
|
|
231
|
+
Array {
|
|
232
|
+
span: SourceSpan,
|
|
233
|
+
elements: Vec<ArrayElement>,
|
|
234
|
+
},
|
|
235
|
+
Object {
|
|
236
|
+
span: SourceSpan,
|
|
237
|
+
properties: Vec<ObjectProperty>,
|
|
238
|
+
},
|
|
239
|
+
Function(Box<FunctionExpr>),
|
|
240
|
+
Unary {
|
|
241
|
+
span: SourceSpan,
|
|
242
|
+
operator: UnaryOp,
|
|
243
|
+
argument: Box<Expr>,
|
|
244
|
+
},
|
|
245
|
+
Binary {
|
|
246
|
+
span: SourceSpan,
|
|
247
|
+
operator: BinaryOp,
|
|
248
|
+
left: Box<Expr>,
|
|
249
|
+
right: Box<Expr>,
|
|
250
|
+
},
|
|
251
|
+
Sequence {
|
|
252
|
+
span: SourceSpan,
|
|
253
|
+
expressions: Vec<Expr>,
|
|
254
|
+
},
|
|
255
|
+
Logical {
|
|
256
|
+
span: SourceSpan,
|
|
257
|
+
operator: LogicalOp,
|
|
258
|
+
left: Box<Expr>,
|
|
259
|
+
right: Box<Expr>,
|
|
260
|
+
},
|
|
261
|
+
Conditional {
|
|
262
|
+
span: SourceSpan,
|
|
263
|
+
test: Box<Expr>,
|
|
264
|
+
consequent: Box<Expr>,
|
|
265
|
+
alternate: Box<Expr>,
|
|
266
|
+
},
|
|
267
|
+
Assignment {
|
|
268
|
+
span: SourceSpan,
|
|
269
|
+
target: Box<AssignTarget>,
|
|
270
|
+
operator: AssignOp,
|
|
271
|
+
value: Box<Expr>,
|
|
272
|
+
},
|
|
273
|
+
Update {
|
|
274
|
+
span: SourceSpan,
|
|
275
|
+
target: Box<AssignTarget>,
|
|
276
|
+
operator: UpdateOp,
|
|
277
|
+
prefix: bool,
|
|
278
|
+
},
|
|
279
|
+
Member {
|
|
280
|
+
span: SourceSpan,
|
|
281
|
+
object: Box<Expr>,
|
|
282
|
+
property: MemberProperty,
|
|
283
|
+
optional: bool,
|
|
284
|
+
},
|
|
285
|
+
Call {
|
|
286
|
+
span: SourceSpan,
|
|
287
|
+
callee: Box<Expr>,
|
|
288
|
+
arguments: Vec<CallArgument>,
|
|
289
|
+
optional: bool,
|
|
290
|
+
},
|
|
291
|
+
New {
|
|
292
|
+
span: SourceSpan,
|
|
293
|
+
callee: Box<Expr>,
|
|
294
|
+
arguments: Vec<CallArgument>,
|
|
295
|
+
},
|
|
296
|
+
Template {
|
|
297
|
+
span: SourceSpan,
|
|
298
|
+
quasis: Vec<String>,
|
|
299
|
+
expressions: Vec<Expr>,
|
|
300
|
+
},
|
|
301
|
+
Await {
|
|
302
|
+
span: SourceSpan,
|
|
303
|
+
value: Box<Expr>,
|
|
304
|
+
},
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
308
|
+
pub enum ArrayElement {
|
|
309
|
+
Value(Expr),
|
|
310
|
+
Hole { span: SourceSpan },
|
|
311
|
+
Spread { span: SourceSpan, value: Expr },
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
315
|
+
pub enum ObjectProperty {
|
|
316
|
+
Property {
|
|
317
|
+
span: SourceSpan,
|
|
318
|
+
key: ObjectPropertyKey,
|
|
319
|
+
value: Expr,
|
|
320
|
+
},
|
|
321
|
+
Spread {
|
|
322
|
+
span: SourceSpan,
|
|
323
|
+
value: Expr,
|
|
324
|
+
},
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
328
|
+
pub enum ObjectPropertyKey {
|
|
329
|
+
Static(PropertyName),
|
|
330
|
+
Computed(Box<Expr>),
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
334
|
+
pub enum MemberProperty {
|
|
335
|
+
Static(PropertyName),
|
|
336
|
+
Computed(Box<Expr>),
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
340
|
+
pub enum CallArgument {
|
|
341
|
+
Value(Expr),
|
|
342
|
+
Spread { span: SourceSpan, value: Expr },
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
346
|
+
pub enum AssignTarget {
|
|
347
|
+
Identifier {
|
|
348
|
+
span: SourceSpan,
|
|
349
|
+
name: String,
|
|
350
|
+
},
|
|
351
|
+
Member {
|
|
352
|
+
span: SourceSpan,
|
|
353
|
+
object: Box<Expr>,
|
|
354
|
+
property: MemberProperty,
|
|
355
|
+
optional: bool,
|
|
356
|
+
},
|
|
357
|
+
Array {
|
|
358
|
+
span: SourceSpan,
|
|
359
|
+
elements: Vec<Option<AssignTarget>>,
|
|
360
|
+
rest: Option<Box<AssignTarget>>,
|
|
361
|
+
},
|
|
362
|
+
Object {
|
|
363
|
+
span: SourceSpan,
|
|
364
|
+
properties: Vec<AssignTargetProperty>,
|
|
365
|
+
rest: Option<Box<AssignTarget>>,
|
|
366
|
+
},
|
|
367
|
+
Default {
|
|
368
|
+
span: SourceSpan,
|
|
369
|
+
target: Box<AssignTarget>,
|
|
370
|
+
default_value: Box<Expr>,
|
|
371
|
+
},
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
375
|
+
pub struct AssignTargetProperty {
|
|
376
|
+
pub span: SourceSpan,
|
|
377
|
+
pub key: PropertyName,
|
|
378
|
+
pub value: AssignTarget,
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
|
382
|
+
pub enum UpdateOp {
|
|
383
|
+
Increment,
|
|
384
|
+
Decrement,
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
|
388
|
+
pub enum UnaryOp {
|
|
389
|
+
Plus,
|
|
390
|
+
Minus,
|
|
391
|
+
Not,
|
|
392
|
+
Typeof,
|
|
393
|
+
Void,
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
|
397
|
+
pub enum BinaryOp {
|
|
398
|
+
Add,
|
|
399
|
+
Sub,
|
|
400
|
+
Mul,
|
|
401
|
+
Div,
|
|
402
|
+
Rem,
|
|
403
|
+
Pow,
|
|
404
|
+
In,
|
|
405
|
+
Instanceof,
|
|
406
|
+
Eq,
|
|
407
|
+
NotEq,
|
|
408
|
+
StrictEq,
|
|
409
|
+
StrictNotEq,
|
|
410
|
+
LessThan,
|
|
411
|
+
LessThanEq,
|
|
412
|
+
GreaterThan,
|
|
413
|
+
GreaterThanEq,
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
|
417
|
+
pub enum LogicalOp {
|
|
418
|
+
And,
|
|
419
|
+
Or,
|
|
420
|
+
NullishCoalesce,
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
|
424
|
+
pub enum AssignOp {
|
|
425
|
+
Assign,
|
|
426
|
+
AddAssign,
|
|
427
|
+
SubAssign,
|
|
428
|
+
MulAssign,
|
|
429
|
+
DivAssign,
|
|
430
|
+
RemAssign,
|
|
431
|
+
PowAssign,
|
|
432
|
+
OrAssign,
|
|
433
|
+
AndAssign,
|
|
434
|
+
NullishAssign,
|
|
435
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
pub mod cancellation;
|
|
2
|
+
pub mod diagnostic;
|
|
3
|
+
pub mod ir;
|
|
4
|
+
pub mod limits;
|
|
5
|
+
pub mod parser;
|
|
6
|
+
pub mod runtime;
|
|
7
|
+
pub mod span;
|
|
8
|
+
pub mod structured;
|
|
9
|
+
|
|
10
|
+
pub use cancellation::CancellationToken;
|
|
11
|
+
pub use diagnostic::{Diagnostic, DiagnosticKind, MustardError, MustardResult};
|
|
12
|
+
pub use ir::CompiledProgram;
|
|
13
|
+
pub use limits::RuntimeLimits;
|
|
14
|
+
pub use parser::compile;
|
|
15
|
+
pub use runtime::{
|
|
16
|
+
BytecodeProgram, ExecutionOptions, ExecutionSnapshot, ExecutionStep, HostError, ResumeOptions,
|
|
17
|
+
ResumePayload, SnapshotInspection, SnapshotPolicy, Suspension, canonical_snapshot_auth_bytes,
|
|
18
|
+
dump_program, dump_snapshot, execute, inspect_snapshot, load_program, load_snapshot,
|
|
19
|
+
lower_to_bytecode, resume, resume_with_options, start, start_bytecode,
|
|
20
|
+
};
|
|
21
|
+
pub use structured::StructuredValue;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
use serde::{Deserialize, Serialize};
|
|
2
|
+
|
|
3
|
+
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
|
4
|
+
pub struct RuntimeLimits {
|
|
5
|
+
pub instruction_budget: usize,
|
|
6
|
+
pub heap_limit_bytes: usize,
|
|
7
|
+
pub allocation_budget: usize,
|
|
8
|
+
pub call_depth_limit: usize,
|
|
9
|
+
pub max_outstanding_host_calls: usize,
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
impl Default for RuntimeLimits {
|
|
13
|
+
fn default() -> Self {
|
|
14
|
+
Self {
|
|
15
|
+
instruction_budget: 1_000_000,
|
|
16
|
+
heap_limit_bytes: 8 * 1024 * 1024,
|
|
17
|
+
allocation_budget: 250_000,
|
|
18
|
+
call_depth_limit: 256,
|
|
19
|
+
max_outstanding_host_calls: 128,
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|