1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use alloc::format;
use ellie_core::defs::PlatformArchitecture;
use crate::{
heap_memory::HeapMemory,
instruction_utils::FN,
raw_type::StaticRawType,
stack::Stack,
stack_memory::StackMemory,
utils::{AddressingValues, ThreadPanicReason},
};
use super::{ExecuterPanic, ExecuterResult, StaticProgram};
impl super::InstructionExecuter for FN {
fn execute(
&self,
heap_memory: &mut HeapMemory,
program: StaticProgram,
current_stack: &mut Stack,
stack_memory: &mut StackMemory,
addressing_value: &AddressingValues,
_arch: PlatformArchitecture,
) -> Result<super::ExecuterResult, super::ExecuterPanic> {
match &addressing_value {
AddressingValues::Immediate(e) => {
let hash: usize = e.to_int() as usize;
stack_memory.set(¤t_stack.get_pos(), StaticRawType::from_function(hash));
let end_point = match &program[current_stack.pos + 1].addressing_value {
AddressingValues::Immediate(e) => e.to_int() as usize,
_ => {
return Err(ExecuterPanic {
reason: ThreadPanicReason::IllegalAddressingValue,
code_location: format!("{}:{}", file!(), line!()),
})
}
};
let parameter_count = match &program[current_stack.pos + 2].addressing_value {
AddressingValues::Immediate(e) => e.to_int() as usize,
_ => {
return Err(ExecuterPanic {
reason: ThreadPanicReason::IllegalAddressingValue,
code_location: format!("{}:{}", file!(), line!()),
})
}
};
if hash != current_stack.id {
//Reduce by one to pass the stack_pos increase in thread
current_stack.pos = end_point;
} else {
//skip the function len, the parameter count and paramaters
if parameter_count > 0 {
let previous_frame_pos = match current_stack.caller {
Some(c) => c.frame_pos,
None => 0,
};
if !current_stack.registers.X.type_id.is_int() {
return Err(ExecuterPanic {
reason: ThreadPanicReason::IllegalAddressingValue,
code_location: format!("{}:{}", file!(), line!()),
});
}
let index_start =
current_stack.registers.X.to_int() as usize + previous_frame_pos;
for i in 0..parameter_count {
let pos = current_stack.get_pos() + 3 + i;
match stack_memory.get(&(index_start + i)) {
Some(e) => {
if e.type_id.is_heap_reference() {
match heap_memory.get(&e.to_uint()) {
Some(e) => {
heap_memory.set(&pos, e.clone());
stack_memory.set(
&pos,
StaticRawType::from_heap_reference(pos),
);
}
None => {
return Err(ExecuterPanic {
reason: ThreadPanicReason::NullReference(
index_start + i,
),
code_location: format!(
"{}:{}",
file!(),
line!()
),
})
}
}
} else {
stack_memory.set(&pos, e);
}
}
None => {
return Err(ExecuterPanic {
reason: ThreadPanicReason::NullReference(index_start + i),
code_location: format!("{}:{}", file!(), line!()),
})
}
}
}
}
current_stack.pos = current_stack.pos + 2 + parameter_count;
}
}
_ => {
return Err(ExecuterPanic {
reason: ThreadPanicReason::IllegalAddressingValue,
code_location: format!("{}:{}", file!(), line!()),
})
}
};
Ok(ExecuterResult::Continue)
}
}