@@ -7,22 +7,17 @@ mod apply_3;
77mod elixir;
88mod start;
99
10- use std:: convert:: TryInto ;
11-
12- use liblumen_alloc:: erts:: exception;
1310use liblumen_alloc:: erts:: process:: code:: stack:: frame:: Placement ;
14- use liblumen_alloc:: erts:: process:: { heap, next_heap_size, Status } ;
11+ use liblumen_alloc:: erts:: process:: { heap, next_heap_size} ;
1512
1613use lumen_runtime:: scheduler:: Scheduler ;
17- use lumen_runtime:: system;
1814
1915use lumen_web:: wait;
2016
2117use wasm_bindgen:: prelude:: * ;
2218
2319use crate :: elixir:: chain:: { console_1, dom_1} ;
2420use crate :: start:: * ;
25- use liblumen_alloc:: erts:: term:: atom_unchecked;
2621
2722// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
2823// allocator.
@@ -34,15 +29,16 @@ static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
3429pub fn start ( ) {
3530 set_panic_hook ( ) ;
3631 set_apply_fn ( ) ;
32+ lumen_web:: start ( ) ;
3733}
3834
3935#[ wasm_bindgen]
40- pub fn log_to_console ( count : usize ) -> usize {
36+ pub fn log_to_console ( count : usize ) -> js_sys :: Promise {
4137 run ( count, Output :: Console )
4238}
4339
4440#[ wasm_bindgen]
45- pub fn log_to_dom ( count : usize ) -> usize {
41+ pub fn log_to_dom ( count : usize ) -> js_sys :: Promise {
4642 run ( count, Output :: Dom )
4743}
4844
@@ -51,160 +47,34 @@ enum Output {
5147 Dom ,
5248}
5349
54- fn run ( count : usize , output : Output ) -> usize {
50+ fn run ( count : usize , output : Output ) -> js_sys :: Promise {
5551 let arc_scheduler = Scheduler :: current ( ) ;
5652 // Don't register, so that tests can run concurrently
5753 let parent_arc_process = arc_scheduler. spawn_init ( 0 ) . unwrap ( ) ;
5854
59- // if not enough memory here, resize `spawn_init` heap
60- let count_term = parent_arc_process. integer ( count) . unwrap ( ) ;
61-
6255 let heap_size = next_heap_size ( 79 + count * 5 ) ;
6356 // if this fails the entire tab is out-of-memory
6457 let heap = heap ( heap_size) . unwrap ( ) ;
6558
66- let run_arc_process = wait:: with_return_0:: spawn (
59+ wait:: with_return_0:: spawn (
6760 & parent_arc_process,
6861 heap,
69- heap_size
70- )
71- // if this fails use a bigger sized heap
72- . unwrap ( ) ;
73-
74- match output {
75- Output :: Console => {
76- // if this fails use a bigger sized heap
77- console_1:: place_frame_with_arguments ( & run_arc_process, Placement :: Push , count_term)
78- . unwrap ( )
79- }
80- Output :: Dom => {
81- // if this fails use a bigger sized heap
82- dom_1:: place_frame_with_arguments ( & run_arc_process, Placement :: Push , count_term)
83- . unwrap ( )
84- }
85- } ;
86-
87- let mut option_return_usize: Option < usize > = None ;
88-
89- loop {
90- let ran = Scheduler :: current ( ) . run_through ( & run_arc_process) ;
91-
92- let waiting = match * run_arc_process. status . read ( ) {
93- Status :: Exiting ( ref exception) => match exception {
94- exception:: runtime:: Exception {
95- class : exception:: runtime:: Class :: Exit ,
96- reason,
97- ..
98- } => {
99- if * reason != atom_unchecked ( "normal" ) {
100- panic ! ( "ProcessControlBlock exited: {:?}" , reason) ;
101- } else {
102- break ;
103- }
62+ heap_size,
63+ |child_process| {
64+ let count_term = child_process. integer ( count) ?;
65+
66+ match output {
67+ Output :: Console => {
68+
69+ // if this fails use a bigger sized heap
70+ console_1:: place_frame_with_arguments ( child_process, Placement :: Push , count_term)
10471 }
105- _ => {
106- panic ! (
107- "ProcessControlBlock exception: {:?}\n {:?}" ,
108- exception,
109- run_arc_process. stacktrace( )
110- ) ;
72+ Output :: Dom => {
73+ // if this fails use a bigger sized heap
74+ dom_1:: place_frame_with_arguments ( child_process, Placement :: Push , count_term)
11175 }
112- } ,
113- Status :: Waiting => true ,
114- Status :: Runnable => false ,
115- Status :: Running => {
116- system:: io:: puts ( & format ! (
117- "RUNNING Run queues len = {:?}" ,
118- Scheduler :: current( ) . run_queues_len( )
119- ) ) ;
120-
121- false
12276 }
123- } ;
124-
125- // separate so we don't hold read lock on status as it may need to be written
126- if waiting {
127- if ran {
128- system:: io:: puts ( & format ! (
129- "WAITING Run queues len = {:?}" ,
130- Scheduler :: current( ) . run_queues_len( )
131- ) ) ;
132- } else {
133- use wait:: with_return_0:: Error :: * ;
134-
135- match wait:: with_return_0:: pop_return ( & run_arc_process) {
136- Ok ( popped_return) => {
137- option_return_usize = Some ( popped_return. try_into ( ) . unwrap ( ) ) ;
138- wait:: with_return_0:: stop ( & run_arc_process) ;
139- } ,
140- Err ( NoModuleFunctionArity ) => panic ! ( "{:?} doesn't have a current module function arity" , run_arc_process) ,
141- Err ( WrongModuleFunctionArity ( current_module_function_arity) ) => panic ! (
142- "{:?} is not waiting with a return and instead did not run while waiting in {}. Deadlock likely in {:#?}" ,
143- run_arc_process,
144- current_module_function_arity,
145- Scheduler :: current( )
146- ) ,
147- Err ( NoReturn ) => panic ! ( "{:?} is waiting, but nothing was returned to it. Bug likely in {:#?}" , run_arc_process, Scheduler :: current( ) ) ,
148- Err ( TooManyReturns ( returns) ) => panic ! ( "{:?} got multiple returns: {:?}. Stack is not being properly managed." , run_arc_process, returns)
149- }
150- }
151- }
152- }
153-
154- option_return_usize. unwrap ( )
155- }
156-
157- #[ cfg( test) ]
158- mod tests {
159- use super :: * ;
160-
161- use std:: sync:: Once ;
162-
163- mod log_to_console {
164- use super :: * ;
165-
166- #[ test]
167- fn with_1 ( ) {
168- start_once ( ) ;
169- assert_eq ! ( log_to_console( 1 ) , 1 ) ;
170- }
171-
172- #[ test]
173- fn with_2 ( ) {
174- start_once ( ) ;
175- assert_eq ! ( log_to_console( 2 ) , 2 ) ;
176- }
177-
178- #[ test]
179- fn with_4 ( ) {
180- start_once ( ) ;
181- assert_eq ! ( log_to_console( 4 ) , 4 ) ;
182- }
183-
184- #[ test]
185- fn with_8 ( ) {
186- start_once ( ) ;
187- assert_eq ! ( log_to_console( 8 ) , 8 ) ;
188- }
189-
190- #[ test]
191- fn with_16 ( ) {
192- start_once ( ) ;
193- assert_eq ! ( log_to_console( 16 ) , 16 ) ;
194- }
195-
196- #[ test]
197- fn with_32 ( ) {
198- start_once ( ) ;
199- assert_eq ! ( log_to_console( 32 ) , 32 ) ;
200- }
201- }
202-
203- static START : Once = Once :: new ( ) ;
204-
205- fn start_once ( ) {
206- START . call_once ( || {
207- start ( ) ;
20877 } )
209- }
78+ // if this fails use a bigger sized heap
79+ . unwrap ( )
21080}
0 commit comments