83 lines
2.6 KiB
Rust
83 lines
2.6 KiB
Rust
use gc_arena::{Gc, Mutation, RefLock};
|
|
|
|
use crate::{BytecodeReader, StepResult, ThunkState, Value};
|
|
|
|
impl<'gc> crate::Vm<'gc> {
|
|
#[inline(always)]
|
|
pub(crate) fn op_make_thunk(&mut self, reader: &mut BytecodeReader<'_>, mc: &Mutation<'gc>) -> StepResult<'gc> {
|
|
let entry_point = reader.read_u32();
|
|
let thunk = Gc::new(
|
|
mc,
|
|
RefLock::new(ThunkState::Pending {
|
|
ip: entry_point as usize,
|
|
env: self.env,
|
|
with_env: self.with_env,
|
|
}),
|
|
);
|
|
self.push_stack(Value::new_gc(thunk));
|
|
StepResult::Continue
|
|
}
|
|
|
|
#[inline(always)]
|
|
pub(crate) fn op_make_closure(&mut self, reader: &mut BytecodeReader<'_>, mc: &Mutation<'gc>) -> StepResult<'gc> {
|
|
let entry_point = reader.read_u32();
|
|
let n_locals = reader.read_u32();
|
|
let closure = Gc::new(
|
|
mc,
|
|
crate::Closure {
|
|
ip: entry_point,
|
|
n_locals,
|
|
env: self.env,
|
|
pattern: None,
|
|
},
|
|
);
|
|
self.push_stack(Value::new_gc(closure));
|
|
StepResult::Continue
|
|
}
|
|
|
|
#[inline(always)]
|
|
pub(crate) fn op_make_pattern_closure(&mut self, reader: &mut BytecodeReader<'_>, mc: &Mutation<'gc>) -> StepResult<'gc> {
|
|
let entry_point = reader.read_u32();
|
|
let n_locals = reader.read_u32();
|
|
let req_count = reader.read_u16() as usize;
|
|
let opt_count = reader.read_u16() as usize;
|
|
let has_ellipsis = reader.read_u8() != 0;
|
|
|
|
let mut required = smallvec::SmallVec::new();
|
|
for _ in 0..req_count {
|
|
required.push(reader.read_string_id());
|
|
}
|
|
let mut optional = smallvec::SmallVec::new();
|
|
for _ in 0..opt_count {
|
|
optional.push(reader.read_string_id());
|
|
}
|
|
let total = req_count + opt_count;
|
|
let mut param_spans = Vec::with_capacity(total);
|
|
for _ in 0..total {
|
|
let name = reader.read_string_id();
|
|
let span_id = reader.read_u32();
|
|
param_spans.push((name, span_id));
|
|
}
|
|
|
|
let pattern = Gc::new(
|
|
mc,
|
|
crate::PatternInfo {
|
|
required,
|
|
optional,
|
|
ellipsis: has_ellipsis,
|
|
param_spans: param_spans.into_boxed_slice(),
|
|
},
|
|
);
|
|
let closure = Gc::new(
|
|
mc,
|
|
crate::Closure {
|
|
ip: entry_point,
|
|
n_locals,
|
|
env: self.env,
|
|
pattern: Some(pattern),
|
|
},
|
|
);
|
|
self.push_stack(Value::new_gc(closure));
|
|
StepResult::Continue
|
|
}
|
|
} |