@@ -2,6 +2,7 @@ use std::{
22 any:: Any ,
33 cell:: RefCell ,
44 collections:: VecDeque ,
5+ path:: PathBuf ,
56 sync:: { atomic:: Ordering , mpsc:: Receiver } ,
67} ;
78
@@ -11,17 +12,22 @@ use nova_vm::ecmascript::{
1112 agent:: { HostHooks , Job , Options } ,
1213 initialize_host_defined_realm, Agent , JsResult , Realm ,
1314 } ,
14- scripts_and_modules:: script:: { parse_script, script_evaluation} ,
15+ scripts_and_modules:: {
16+ script:: { parse_script, script_evaluation} ,
17+ ScriptOrModule ,
18+ } ,
1519 types:: { Object , Value } ,
1620} ;
1721use oxc_allocator:: Allocator ;
22+ use oxc_ast:: ast;
1823
1924use crate :: {
2025 exit_with_parse_errors, initialize_recommended_builtins, initialize_recommended_extensions,
2126 HostData , MacroTask ,
2227} ;
2328
2429pub struct RuntimeHostHooks {
30+ allocator : Allocator ,
2531 promise_job_queue : RefCell < VecDeque < Job > > ,
2632 host_data : HostData ,
2733}
@@ -33,10 +39,11 @@ impl std::fmt::Debug for RuntimeHostHooks {
3339}
3440
3541impl RuntimeHostHooks {
36- pub fn new ( host_data : HostData ) -> Self {
42+ pub fn new ( host_data : HostData , allocator : Allocator ) -> Self {
3743 Self {
3844 promise_job_queue : RefCell :: default ( ) ,
3945 host_data,
46+ allocator,
4047 }
4148 }
4249
@@ -57,6 +64,43 @@ impl HostHooks for RuntimeHostHooks {
5764 fn get_host_data ( & self ) -> & dyn Any {
5865 & self . host_data
5966 }
67+
68+ // TODO: Implement a transport abstraction.
69+ fn import_module ( & self , import : & ast:: ImportDeclaration < ' _ > , agent : & mut Agent ) {
70+ let realm_id = agent. current_realm_id ( ) ;
71+
72+ let script_or_module = agent. running_execution_context ( ) . script_or_module . unwrap ( ) ;
73+ let script_id = match script_or_module {
74+ ScriptOrModule :: Script ( script_id) => script_id,
75+ _ => todo ! ( ) ,
76+ } ;
77+ let script = & agent[ script_id] ;
78+
79+ let current_host_path = script. host_defined . as_ref ( ) . unwrap ( ) ;
80+ let mut current_host_path = current_host_path
81+ . downcast_ref :: < PathBuf > ( )
82+ . unwrap ( )
83+ . to_path_buf ( ) ;
84+ current_host_path. pop ( ) ; // Use the parent folder
85+ let current_host_path = std:: fs:: canonicalize ( & current_host_path) . unwrap ( ) ;
86+
87+ let import_path = import. source . value . as_str ( ) ;
88+ let host_path = current_host_path. join ( import_path) ;
89+ let host_path = std:: fs:: canonicalize ( host_path) . unwrap ( ) ;
90+
91+ let file = std:: fs:: read_to_string ( & host_path) . unwrap ( ) ;
92+ let script = match parse_script (
93+ & self . allocator ,
94+ file. into ( ) ,
95+ realm_id,
96+ false ,
97+ Some ( Box :: leak ( Box :: new ( host_path) ) ) ,
98+ ) {
99+ Ok ( script) => script,
100+ Err ( ( file, errors) ) => exit_with_parse_errors ( errors, import_path, & file) ,
101+ } ;
102+ script_evaluation ( agent, script) . unwrap ( ) ;
103+ }
60104}
61105
62106pub struct RuntimeConfig {
@@ -68,16 +112,16 @@ pub struct RuntimeConfig {
68112pub struct Runtime {
69113 pub config : RuntimeConfig ,
70114 pub agent : Agent ,
71- pub allocator : Allocator ,
72115 pub host_hooks : & ' static RuntimeHostHooks ,
73116 pub macro_task_rx : Receiver < MacroTask > ,
74117}
75118
76119impl Runtime {
77120 /// Create a new [Runtime] given a [RuntimeConfig]. Use [Runtime::run] to run it.
78121 pub fn new ( config : RuntimeConfig ) -> Self {
122+ let allocator = Allocator :: default ( ) ;
79123 let ( host_data, macro_task_rx) = HostData :: new ( ) ;
80- let host_hooks = RuntimeHostHooks :: new ( host_data) ;
124+ let host_hooks = RuntimeHostHooks :: new ( host_data, allocator ) ;
81125
82126 let host_hooks: & RuntimeHostHooks = & * Box :: leak ( Box :: new ( host_hooks) ) ;
83127 let mut agent = Agent :: new (
@@ -97,11 +141,9 @@ impl Runtime {
97141 Some ( initialize_recommended_extensions) ,
98142 ) ;
99143 }
100- let allocator = Allocator :: default ( ) ;
101144
102145 Self {
103146 config,
104- allocator,
105147 agent,
106148 host_hooks,
107149 macro_task_rx,
@@ -113,34 +155,37 @@ impl Runtime {
113155 let realm = self . agent . current_realm_id ( ) ;
114156
115157 // LOad the builtins js sources
116- initialize_recommended_builtins ( & self . allocator , & mut self . agent , self . config . no_strict ) ;
158+ initialize_recommended_builtins (
159+ & self . host_hooks . allocator ,
160+ & mut self . agent ,
161+ self . config . no_strict ,
162+ ) ;
117163
118164 let mut final_result = Value :: Null ;
119165
120166 // Fetch the runtime mod.ts file using a macro and add it to the paths
121167 for path in & self . config . paths {
122168 let file = std:: fs:: read_to_string ( path) . unwrap ( ) ;
169+ let host_path = PathBuf :: from ( path) ;
123170 let script = match parse_script (
124- & self . allocator ,
171+ & self . host_hooks . allocator ,
125172 file. into ( ) ,
126173 realm,
127174 !self . config . no_strict ,
128- None ,
175+ Some ( Box :: leak ( Box :: new ( host_path ) ) ) ,
129176 ) {
130177 Ok ( script) => script,
131178 Err ( ( file, errors) ) => exit_with_parse_errors ( errors, path, & file) ,
132179 } ;
133180 final_result = match script_evaluation ( & mut self . agent , script) {
134181 Ok ( v) => v,
135- err @ _ => return err,
182+ err => return err,
136183 }
137184 }
138185
139186 loop {
140187 while let Some ( job) = self . host_hooks . pop_promise_job ( ) {
141- if let Err ( err) = job. run ( & mut self . agent ) {
142- return Err ( err) ;
143- }
188+ job. run ( & mut self . agent ) ?;
144189 }
145190
146191 // If both the microtasks and macrotasks queues are empty we can end the event loop
0 commit comments