Merge branch 'master' into flame
This commit is contained in:
@@ -18,6 +18,7 @@ pub trait CopierTarget: IndexMut<usize, Output = HeapCellValue> {
|
||||
fn store(&self, value: HeapCellValue) -> HeapCellValue;
|
||||
fn deref(&self, value: HeapCellValue) -> HeapCellValue;
|
||||
fn push(&mut self, value: HeapCellValue);
|
||||
fn push_attr_var_queue(&mut self, attr_var_loc: usize);
|
||||
fn stack(&mut self) -> &mut Stack;
|
||||
fn threshold(&self) -> usize;
|
||||
}
|
||||
@@ -73,7 +74,6 @@ impl<T: CopierTarget> CopyTermState<T> {
|
||||
if h >= self.old_h {
|
||||
*self.value_at_scan() = list_loc_as_cell!(h);
|
||||
self.scan += 1;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -96,14 +96,19 @@ impl<T: CopierTarget> CopyTermState<T> {
|
||||
.store(self.target.deref(heap_loc_as_cell!(addr + 1)));
|
||||
|
||||
if !cdr.is_var() {
|
||||
// mark addr + 1 as a list back edge in the cdr of the list
|
||||
self.trail_list_cell(addr + 1, threshold);
|
||||
self.target[addr + 1].set_mark_bit(true);
|
||||
self.target[addr + 1].set_forwarding_bit(true);
|
||||
} else {
|
||||
let car = self
|
||||
.target
|
||||
.store(self.target.deref(heap_loc_as_cell!(addr)));
|
||||
|
||||
if !car.is_var() {
|
||||
// mark addr as a list back edge in the car of the list
|
||||
self.trail_list_cell(addr, threshold);
|
||||
self.target[addr].set_mark_bit(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,6 +183,7 @@ impl<T: CopierTarget> CopyTermState<T> {
|
||||
|
||||
for (threshold, list_loc) in iter {
|
||||
self.target[threshold] = list_loc_as_cell!(self.target.threshold());
|
||||
self.target.push_attr_var_queue(threshold - 1);
|
||||
self.copy_attr_var_list(list_loc);
|
||||
}
|
||||
}
|
||||
@@ -263,6 +269,7 @@ impl<T: CopierTarget> CopyTermState<T> {
|
||||
}
|
||||
|
||||
fn copy_var(&mut self, addr: HeapCellValue) {
|
||||
let index = addr.get_value() as usize;
|
||||
let rd = self.target.deref(addr);
|
||||
let ra = self.target.store(rd);
|
||||
|
||||
@@ -271,7 +278,20 @@ impl<T: CopierTarget> CopyTermState<T> {
|
||||
if h >= self.old_h {
|
||||
*self.value_at_scan() = ra;
|
||||
self.scan += 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
(HeapCellValueTag::Lis, h) => {
|
||||
if h >= self.old_h && self.target[index].get_mark_bit() {
|
||||
*self.value_at_scan() = heap_loc_as_cell!(
|
||||
if ra.get_forwarding_bit() {
|
||||
h + 1
|
||||
} else {
|
||||
h
|
||||
}
|
||||
);
|
||||
|
||||
self.scan += 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -356,12 +376,16 @@ impl<T: CopierTarget> CopyTermState<T> {
|
||||
}
|
||||
}
|
||||
|
||||
fn unwind_trail(&mut self) {
|
||||
for (r, value) in self.trail.drain(0..) {
|
||||
fn unwind_trail(mut self) {
|
||||
for (r, value) in self.trail {
|
||||
let index = r.get_value() as usize;
|
||||
|
||||
match r.get_tag() {
|
||||
RefTag::AttrVar | RefTag::HeapCell => self.target[index] = value,
|
||||
RefTag::AttrVar | RefTag::HeapCell => {
|
||||
self.target[index] = value;
|
||||
self.target[index].set_mark_bit(false);
|
||||
self.target[index].set_forwarding_bit(false);
|
||||
}
|
||||
RefTag::StackCell => self.target.stack()[index] = value,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,6 +208,7 @@ impl MachineState {
|
||||
l
|
||||
}
|
||||
(HeapCellValueTag::Fixnum |
|
||||
HeapCellValueTag::CutPoint |
|
||||
HeapCellValueTag::Char |
|
||||
HeapCellValueTag::F64) => {
|
||||
c
|
||||
@@ -4138,6 +4139,14 @@ impl Machine {
|
||||
try_or_throw!(self.machine_st, self.define_foreign_struct());
|
||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||
}
|
||||
&Instruction::CallJsEval => {
|
||||
try_or_throw!(self.machine_st, self.js_eval());
|
||||
step_or_fail!(self, self.machine_st.p += 1);
|
||||
}
|
||||
&Instruction::ExecuteJsEval => {
|
||||
try_or_throw!(self.machine_st, self.js_eval());
|
||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||
}
|
||||
&Instruction::CallCurrentTime => {
|
||||
self.current_time();
|
||||
step_or_fail!(self, self.machine_st.p += 1);
|
||||
|
||||
@@ -57,6 +57,7 @@ impl Machine {
|
||||
or_frame.prelude.attr_var_queue_len = 0;
|
||||
|
||||
self.machine_st.b = stub_b;
|
||||
self.machine_st.hb = self.machine_st.heap.len();
|
||||
}
|
||||
|
||||
pub fn run_query(&mut self, query: String) -> QueryResult {
|
||||
@@ -87,6 +88,7 @@ impl Machine {
|
||||
.expect("couldn't get code index")
|
||||
.local()
|
||||
.unwrap();
|
||||
self.machine_st.b0 = self.machine_st.b;
|
||||
|
||||
let var_names: IndexMap<_, _> = term_write_result
|
||||
.var_dict
|
||||
@@ -422,7 +424,6 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[ignore = "fails on windows"]
|
||||
#[test]
|
||||
fn stress_integration_test() {
|
||||
let mut machine = Machine::new_lib();
|
||||
|
||||
@@ -289,6 +289,11 @@ impl<'a> CopierTarget for CopyTerm<'a> {
|
||||
self.state.heap.push(hcv);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn push_attr_var_queue(&mut self, attr_var_loc: usize) {
|
||||
self.state.attr_var_init.attr_var_queue.push(attr_var_loc);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn store(&self, value: HeapCellValue) -> HeapCellValue {
|
||||
self.state.store(value)
|
||||
@@ -307,6 +312,7 @@ impl<'a> CopierTarget for CopyTerm<'a> {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) struct CopyBallTerm<'a> {
|
||||
attr_var_queue: &'a mut Vec<usize>,
|
||||
stack: &'a mut Stack,
|
||||
heap: &'a mut Heap,
|
||||
heap_boundary: usize,
|
||||
@@ -314,10 +320,16 @@ pub(super) struct CopyBallTerm<'a> {
|
||||
}
|
||||
|
||||
impl<'a> CopyBallTerm<'a> {
|
||||
pub(super) fn new(stack: &'a mut Stack, heap: &'a mut Heap, stub: &'a mut Heap) -> Self {
|
||||
pub(super) fn new(
|
||||
attr_var_queue: &'a mut Vec<usize>,
|
||||
stack: &'a mut Stack,
|
||||
heap: &'a mut Heap,
|
||||
stub: &'a mut Heap,
|
||||
) -> Self {
|
||||
let hb = heap.len();
|
||||
|
||||
CopyBallTerm {
|
||||
attr_var_queue,
|
||||
stack,
|
||||
heap,
|
||||
heap_boundary: hb,
|
||||
@@ -359,6 +371,11 @@ impl<'a> CopierTarget for CopyBallTerm<'a> {
|
||||
self.stub.push(value);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn push_attr_var_queue(&mut self, attr_var_loc: usize) {
|
||||
self.attr_var_queue.push(attr_var_loc);
|
||||
}
|
||||
|
||||
fn store(&self, value: HeapCellValue) -> HeapCellValue {
|
||||
read_heap_cell!(value,
|
||||
(HeapCellValueTag::Var | HeapCellValueTag::AttrVar, h) => {
|
||||
|
||||
@@ -334,7 +334,12 @@ impl MachineState {
|
||||
self.ball.boundary = self.heap.len();
|
||||
|
||||
copy_term(
|
||||
CopyBallTerm::new(&mut self.stack, &mut self.heap, &mut self.ball.stub),
|
||||
CopyBallTerm::new(
|
||||
&mut self.attr_var_init.attr_var_queue,
|
||||
&mut self.stack,
|
||||
&mut self.heap,
|
||||
&mut self.ball.stub,
|
||||
),
|
||||
addr,
|
||||
AttrVarPolicy::DeepCopy,
|
||||
);
|
||||
|
||||
@@ -159,6 +159,14 @@ impl<'a> CopierTarget for TermCopyingMockWAM<'a> {
|
||||
self.wam.machine_st.heap.push(val);
|
||||
}
|
||||
|
||||
fn push_attr_var_queue(&mut self, attr_var_loc: usize) {
|
||||
self.wam
|
||||
.machine_st
|
||||
.attr_var_init
|
||||
.attr_var_queue
|
||||
.push(attr_var_loc);
|
||||
}
|
||||
|
||||
fn stack(&mut self) -> &mut Stack {
|
||||
&mut self.wam.machine_st.stack
|
||||
}
|
||||
|
||||
@@ -827,8 +827,12 @@ impl MachineState {
|
||||
) -> usize {
|
||||
let threshold = self.lifted_heap.len() - lh_offset;
|
||||
|
||||
let mut copy_ball_term =
|
||||
CopyBallTerm::new(&mut self.stack, &mut self.heap, &mut self.lifted_heap);
|
||||
let mut copy_ball_term = CopyBallTerm::new(
|
||||
&mut self.attr_var_init.attr_var_queue,
|
||||
&mut self.stack,
|
||||
&mut self.heap,
|
||||
&mut self.lifted_heap,
|
||||
);
|
||||
|
||||
copy_ball_term.push(list_loc_as_cell!(threshold + 1));
|
||||
copy_ball_term.push(heap_loc_as_cell!(threshold + 3));
|
||||
@@ -4878,6 +4882,70 @@ impl Machine {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[inline(always)]
|
||||
pub(crate) fn js_eval(&mut self) -> CallResult {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[inline(always)]
|
||||
pub(crate) fn js_eval(&mut self) -> CallResult {
|
||||
let code = self.deref_register(1);
|
||||
let result_reg = self.deref_register(2);
|
||||
if let Some(code) = self.machine_st.value_to_str_like(code) {
|
||||
let result = match js_sys::eval(&code.as_str()) {
|
||||
Ok(result) => self.unify_js_value(result, result_reg),
|
||||
Err(result) => self.unify_js_value(result, result_reg),
|
||||
};
|
||||
return Ok(());
|
||||
}
|
||||
self.machine_st.fail = true;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
fn unify_js_value(&mut self, result: wasm_bindgen::JsValue, result_reg: HeapCellValue) {
|
||||
match result.as_bool() {
|
||||
Some(result) => match result {
|
||||
true => self.machine_st.unify_atom(atom!("true"), result_reg),
|
||||
false => self.machine_st.unify_atom(atom!("false"), result_reg),
|
||||
},
|
||||
None => match result.as_f64() {
|
||||
Some(result) => {
|
||||
let n = float_alloc!(result, self.machine_st.arena);
|
||||
self.machine_st.unify_f64(n, result_reg);
|
||||
}
|
||||
None => match result.as_string() {
|
||||
Some(result) => {
|
||||
let result = AtomTable::build_with(&self.machine_st.atom_tbl, &result);
|
||||
self.machine_st.unify_complete_string(result, result_reg);
|
||||
}
|
||||
None => {
|
||||
if result.is_null() {
|
||||
self.machine_st.unify_atom(atom!("null"), result_reg);
|
||||
} else if result.is_undefined() {
|
||||
self.machine_st.unify_atom(atom!("undefined"), result_reg);
|
||||
} else if result.is_symbol() {
|
||||
self.machine_st.unify_atom(atom!("js_symbol"), result_reg);
|
||||
} else if result.is_object() {
|
||||
self.machine_st.unify_atom(atom!("js_object"), result_reg);
|
||||
} else if result.is_array() {
|
||||
self.machine_st.unify_atom(atom!("js_array"), result_reg);
|
||||
} else if result.is_function() {
|
||||
self.machine_st.unify_atom(atom!("js_function"), result_reg);
|
||||
} else if result.is_bigint() {
|
||||
self.machine_st.unify_atom(atom!("js_bigint"), result_reg);
|
||||
} else {
|
||||
self.machine_st
|
||||
.unify_atom(atom!("js_unknown_type"), result_reg);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn current_time(&mut self) {
|
||||
let timestamp = self.systemtime_to_timestamp(SystemTime::now());
|
||||
@@ -6789,6 +6857,7 @@ impl Machine {
|
||||
|
||||
copy_term(
|
||||
CopyBallTerm::new(
|
||||
&mut self.machine_st.attr_var_init.attr_var_queue,
|
||||
&mut self.machine_st.stack,
|
||||
&mut self.machine_st.heap,
|
||||
&mut ball.stub,
|
||||
|
||||
Reference in New Issue
Block a user