Skip to content
This repository was archived by the owner on Jun 10, 2024. It is now read-only.

Commit 648cc11

Browse files
committed
support chain in the interpreter
1 parent d58f645 commit 648cc11

File tree

12 files changed

+3410
-130
lines changed

12 files changed

+3410
-130
lines changed

liblumen_alloc/src/erts/process/mailbox.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,40 @@ use crate::erts::term::Term;
1313
pub struct Mailbox {
1414
messages: VecDeque<Message>,
1515
seen: isize,
16+
17+
cursor: usize,
1618
}
1719

1820
impl Mailbox {
21+
// Start receive implementation for the eir interpreter
22+
pub fn recv_start(&self) {
23+
debug_assert!(self.cursor == 0);
24+
}
25+
/// Important to remember that this might return a term in a heap
26+
/// fragment, and that it needs to be copied over to the process
27+
/// heap before the message is removed from the mailbox.
28+
pub fn recv_peek(&self) -> Option<Term> {
29+
match self.messages.get(self.cursor) {
30+
None => None,
31+
Some(Message::Process(message::Process { data })) => Some(*data),
32+
Some(Message::HeapFragment(message::HeapFragment { data, .. })) => Some(*data),
33+
}
34+
}
35+
pub fn recv_last_off_heap(&self) -> bool {
36+
match &self.messages[self.cursor - 1] {
37+
Message::Process(_) => false,
38+
Message::HeapFragment(_) => true,
39+
}
40+
}
41+
pub fn recv_increment(&mut self) {
42+
self.cursor += 1;
43+
}
44+
pub fn recv_finish(&mut self, proc: &ProcessControlBlock) {
45+
self.remove(self.cursor - 1, proc);
46+
self.cursor = 0;
47+
}
48+
// End receive implementation for the eir interpreter
49+
1950
pub fn iter(&self) -> Iter<Message> {
2051
self.messages.iter()
2152
}
@@ -127,6 +158,7 @@ impl Default for Mailbox {
127158
Mailbox {
128159
messages: Default::default(),
129160
seen: -1,
161+
cursor: 0,
130162
}
131163
}
132164
}

liblumen_eir_interpreter/Cargo.toml

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,19 @@ cranelift-entity = "0.30.0"
1616
lazy_static = "1.3.0"
1717

1818
# eirproject/eir crates
19-
libeir_diagnostics = { git = "https://github.com/eirproject/eir.git" }
20-
libeir_intern = { git = "https://github.com/eirproject/eir.git" }
21-
libeir_ir = { git = "https://github.com/eirproject/eir.git" }
22-
libeir_passes = { git = "https://github.com/eirproject/eir.git" }
23-
libeir_syntax_erl = { git = "https://github.com/eirproject/eir.git" }
19+
#libeir_diagnostics = { git = "https://github.com/eirproject/eir.git" }
20+
#libeir_intern = { git = "https://github.com/eirproject/eir.git" }
21+
#libeir_ir = { git = "https://github.com/eirproject/eir.git" }
22+
#libeir_passes = { git = "https://github.com/eirproject/eir.git" }
23+
#libeir_syntax_erl = { git = "https://github.com/eirproject/eir.git" }
24+
libeir_diagnostics = { path = "../../core_erlang_3/libeir_diagnostics" }
25+
libeir_intern = { path = "../../core_erlang_3/libeir_intern" }
26+
libeir_ir = { path = "../../core_erlang_3/libeir_ir" }
27+
libeir_passes = { path = "../../core_erlang_3/libeir_passes" }
28+
libeir_syntax_erl = { path = "../../core_erlang_3/libeir_syntax_erl" }
2429

2530
# workspace crates
2631
liblumen_alloc = { path = "../liblumen_alloc" }
2732
lumen_runtime = { path = "../lumen_runtime" }
2833

34+
[patch.'https://github.com/eirproject/eir.git']
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
-file("lib/chain.ex", 1).
2+
3+
-module('Elixir.Chain').
4+
5+
-compile([no_auto_import]).
6+
7+
-export(['__info__'/1,counter/1,create_processes/1,run/1]).
8+
9+
-spec '__info__'(attributes |
10+
compile |
11+
functions |
12+
macros |
13+
md5 |
14+
module |
15+
deprecated) ->
16+
any().
17+
18+
'__info__'(module) ->
19+
'Elixir.Chain';
20+
'__info__'(functions) ->
21+
[{counter,1},{create_processes,1},{run,1}];
22+
'__info__'(macros) ->
23+
[];
24+
'__info__'(Key = attributes) ->
25+
erlang:get_module_info('Elixir.Chain', Key);
26+
'__info__'(Key = compile) ->
27+
erlang:get_module_info('Elixir.Chain', Key);
28+
'__info__'(Key = md5) ->
29+
erlang:get_module_info('Elixir.Chain', Key);
30+
'__info__'(deprecated) ->
31+
[].
32+
33+
counter(_next_pid@1) ->
34+
receive
35+
_n@1 ->
36+
erlang:send(_next_pid@1, _n@1 + 1)
37+
end.
38+
39+
create_processes(_n@1) ->
40+
_last@1 =
41+
'Elixir.Enum':reduce('Elixir.Range':new(1, _n@1),
42+
self(),
43+
fun(_, _send_to@1) ->
44+
spawn('Elixir.Chain',
45+
counter,
46+
[_send_to@1])
47+
end),
48+
erlang:send(_last@1, 0),
49+
receive
50+
_final_answer@1 when is_integer(_final_answer@1) ->
51+
<<"Result is ",
52+
('Elixir.Kernel':inspect(_final_answer@1))/binary>>
53+
end.
54+
55+
run(_n@1) ->
56+
'Elixir.IO':puts('Elixir.Kernel':inspect(timer:tc('Elixir.Chain',
57+
create_processes,
58+
[_n@1]))).
59+

0 commit comments

Comments
 (0)