1use std::{
2 any::{Any, TypeId},
3 result::Result as StdResult,
4 string::String as StdString,
5 sync::{atomic::AtomicUsize, Arc, Mutex, RwLock},
6 usize,
7};
8
9#[cfg(feature = "serde_derive_state")]
10use serde::de::DeserializeState;
11
12use crate::base::{
13 ast,
14 fnv::FnvMap,
15 kind::{ArcKind, Kind, KindEnv},
16 metadata::{Metadata, MetadataEnv},
17 symbol::{Name, Symbol, SymbolRef},
18 types::{
19 Alias, AliasData, AppVec, ArcType, Generic, NullInterner, PrimitiveEnv, Type, TypeCache,
20 TypeEnv, TypeExt,
21 },
22 DebugLevel,
23};
24
25use crate::{
26 api::{OpaqueValue, ValueRef, IO},
27 compiler::{CompiledFunction, CompiledModule, CompilerEnv, Variable},
28 core::{interpreter, optimize::OptimizeEnv, CoreExpr},
29 gc::{Gc, GcPtr, GcRef, Generation, Move, Trace},
30 interner::{InternedStr, Interner},
31 lazy::Lazy,
32 macros::MacroEnv,
33 thread::ThreadInternal,
34 types::*,
35 value::{BytecodeFunction, ClosureData, ClosureDataDef},
36 Error, Result, Variants,
37};
38
39pub use crate::{
40 thread::{RootedThread, RootedValue, Status, Thread},
41 value::Userdata,
42};
43
44pub(crate) type ThreadSlab = slab::Slab<GcPtr<Thread>>;
45
46unsafe impl Trace for ThreadSlab {
47 impl_trace! { self, gc,
48 for (_, x) in self {
49 mark(x, gc);
50 }
51 }
52}
53
54fn new_bytecode<'gc>(
55 env: &dyn VmEnv<Type = ArcType>,
56 interner: &mut Interner,
57 gc: &'gc mut Gc,
58 vm: &GlobalVmState,
59 m: CompiledModule,
60) -> Result<GcRef<'gc, ClosureData>> {
61 let CompiledModule {
62 module_globals,
63 function,
64 } = m;
65 let bytecode_function = new_bytecode_function(interner, gc, vm, function)?;
66
67 let globals = module_globals
68 .into_iter()
69 .map(|index| {
70 env.get_global(index.definition_name())
71 .expect("ICE: Global is missing from environment")
72 .value
73 })
74 .collect::<Vec<_>>();
75
76 unsafe {
78 let bytecode_function = bytecode_function.unrooted();
79 gc.alloc(ClosureDataDef(
80 &bytecode_function,
81 globals.iter().map(|v| v.get_value()),
82 ))
83 }
84}
85
86fn new_bytecode_function<'gc>(
87 interner: &mut Interner,
88 gc: &'gc mut Gc,
89 vm: &GlobalVmState,
90 f: CompiledFunction,
91) -> Result<GcRef<'gc, BytecodeFunction>> {
92 let CompiledFunction {
93 id,
94 args,
95 max_stack_size,
96 instructions,
97 inner_functions,
98 strings,
99 records,
100 debug_info,
101 ..
102 } = f;
103
104 let fs: Result<_> = inner_functions
105 .into_iter()
106 .map(|inner| unsafe { Ok(new_bytecode_function(interner, gc, vm, inner)?.unrooted()) })
108 .collect();
109
110 let records: StdResult<_, _> = records
111 .into_iter()
112 .map(|vec| {
113 vec.into_iter()
114 .map(|field| Ok(interner.intern(gc, field.as_ref())?))
115 .collect::<Result<_>>()
116 })
117 .collect();
118
119 gc.alloc(Move(BytecodeFunction {
120 name: id,
121 args,
122 max_stack_size,
123 instructions,
124 inner_functions: fs?,
125 strings,
126 records: records?,
127 debug_info,
128 }))
129}
130
131#[derive(Clone, Debug)]
132#[cfg_attr(
133 feature = "serde_derive_state",
134 derive(DeserializeState, SerializeState)
135)]
136#[cfg_attr(
137 feature = "serde_derive_state",
138 serde(
139 deserialize_state = "crate::serialization::DeSeed<'gc>",
140 de_parameters = "'gc",
141 bound(deserialize = "V: DeserializeState<'de, crate::serialization::DeSeed<'gc>>")
142 )
143)]
144#[cfg_attr(
145 feature = "serde_derive_state",
146 serde(serialize_state = "crate::serialization::SeSeed")
147)]
148pub struct Global<V> {
149 #[cfg_attr(
150 feature = "serde_derive",
151 serde(state_with = "crate::serialization::symbol")
152 )]
153 pub id: Symbol,
154 #[cfg_attr(
155 feature = "serde_derive",
156 serde(state_with = "crate::serialization::borrow")
157 )]
158 pub typ: ArcType,
159 pub metadata: Arc<Metadata>,
160 #[cfg_attr(feature = "serde_derive_state", serde(state))]
161 pub value: V,
162}
163
164pub type RootedGlobal = Global<RootedValue<RootedThread>>;
165
166impl<V> Eq for Global<V> {}
167
168impl<V> PartialEq for Global<V> {
169 fn eq(&self, other: &Self) -> bool {
170 self.id == other.id
171 }
172}
173
174impl<V> std::hash::Hash for Global<V> {
175 fn hash<H>(&self, hasher: &mut H)
176 where
177 H: std::hash::Hasher,
178 {
179 self.id.hash(hasher)
180 }
181}
182
183unsafe impl<V> Trace for Global<V>
184where
185 V: Trace,
186{
187 impl_trace_fields! { self, gc; value }
188}
189
190#[cfg_attr(feature = "serde_derive", derive(DeserializeState, SerializeState))]
191#[cfg_attr(
192 feature = "serde_derive",
193 serde(
194 deserialize_state = "crate::serialization::DeSeed<'gc>",
195 de_parameters = "'gc"
196 )
197)]
198#[cfg_attr(
199 feature = "serde_derive",
200 serde(serialize_state = "crate::serialization::SeSeed")
201)]
202pub struct GlobalVmState {
203 #[cfg_attr(
204 feature = "serde_derive",
205 serde(state_with = "crate::serialization::rw_lock")
206 )]
207 env: parking_lot::RwLock<Globals>,
208 #[cfg_attr(
209 feature = "serde_derive",
210 serde(state_with = "crate::serialization::borrow")
211 )]
212 generics: RwLock<FnvMap<StdString, ArcType>>,
213
214 #[cfg_attr(feature = "serde_derive", serde(skip))]
215 typeids: RwLock<FnvMap<TypeId, ArcType>>,
216
217 #[cfg_attr(feature = "serde_derive", serde(state))]
218 interner: RwLock<Interner>,
219
220 #[cfg_attr(feature = "serde_derive", serde(skip))]
221 macros: MacroEnv,
222
223 #[cfg_attr(feature = "serde_derive", serde(skip))]
224 type_cache: TypeCache<Symbol, ArcType>,
225
226 #[cfg_attr(feature = "serde_derive", serde(state))]
228 pub gc: Mutex<Gc>,
229
230 #[cfg_attr(feature = "serde_derive", serde(skip))]
234 pub generation_0_threads: RwLock<ThreadSlab>,
235
236 #[cfg_attr(feature = "serde_derive", serde(skip))]
237 debug_level: RwLock<DebugLevel>,
238
239 #[cfg_attr(feature = "serde_derive", serde(skip))]
244 pub(crate) thread_reference_count: AtomicUsize,
245
246 #[cfg_attr(feature = "serde_derive", serde(skip))]
247 spawner: Option<Box<dyn futures::task::Spawn + Send + Sync>>,
248}
249
250unsafe impl Trace for GlobalVmState {
251 unsafe fn root(&mut self) {
252 self.macros.root();
253
254 self.interner.get_mut().unwrap().root();
256 self.generation_0_threads.get_mut().unwrap().root();
257 }
258 unsafe fn unroot(&mut self) {
259 self.macros.unroot();
260
261 self.interner.get_mut().unwrap().unroot();
263 self.generation_0_threads.get_mut().unwrap().unroot();
264 }
265
266 fn trace(&self, gc: &mut Gc) {
267 self.macros.trace(gc);
268
269 self.interner.read().unwrap().trace(gc);
271 self.generation_0_threads.read().unwrap().trace(gc);
272 }
273}
274
275#[derive(Debug, Default)]
276#[cfg_attr(feature = "serde_derive", derive(DeserializeState, SerializeState))]
277#[cfg_attr(
278 feature = "serde_derive",
279 serde(
280 deserialize_state = "crate::serialization::DeSeed<'gc>",
281 de_parameters = "'gc"
282 )
283)]
284#[cfg_attr(
285 feature = "serde_derive",
286 serde(serialize_state = "crate::serialization::SeSeed")
287)]
288pub struct Globals {
289 #[cfg_attr(feature = "serde_derive", serde(state))]
290 pub type_infos: TypeInfos,
291}
292
293pub trait VmEnv:
294 OptimizeEnv + CompilerEnv<Type = ArcType> + MetadataEnv + PrimitiveEnv + Trace
295{
296 fn get_global(&self, name: &str) -> Option<RootedGlobal>;
297}
298
299pub struct VmEnvInstance<'a> {
300 vm_envs: Vec<Box<dyn VmEnv>>,
302 globals: parking_lot::RwLockReadGuard<'a, Globals>,
303 thread: &'a Thread,
304}
305
306unsafe impl Trace for VmEnvInstance<'_> {
307 impl_trace_fields! { self, gc; vm_envs }
308}
309
310impl<'a> OptimizeEnv for VmEnvInstance<'a> {
311 fn find_expr(&self, id: &Symbol) -> Option<interpreter::Global<CoreExpr>> {
312 self.vm_envs.iter().find_map(|env| env.find_expr(id))
313 }
314}
315
316impl<'a> CompilerEnv for VmEnvInstance<'a> {
317 fn find_var(&self, id: &Symbol) -> Option<(Variable<Symbol>, ArcType)> {
318 self.vm_envs
319 .iter()
320 .filter_map(|env| env.find_var(id))
321 .next()
322 .or_else(|| self.globals.type_infos.find_var(id))
323 }
324}
325
326impl<'a> KindEnv for VmEnvInstance<'a> {
327 fn find_kind(&self, id: &SymbolRef) -> Option<ArcKind> {
328 self.vm_envs
329 .iter()
330 .filter_map(|env| env.find_kind(id))
331 .next()
332 .or_else(|| self.globals.type_infos.find_kind(id))
333 }
334}
335
336impl<'a> TypeEnv for VmEnvInstance<'a> {
337 type Type = ArcType;
338
339 fn find_type(&self, id: &SymbolRef) -> Option<ArcType> {
340 self.vm_envs
341 .iter()
342 .filter_map(|env| env.find_type(id))
343 .next()
344 .or_else(|| {
345 self.globals
346 .type_infos
347 .id_to_type
348 .values()
349 .filter_map(|alias| match **alias.unresolved_type() {
350 Type::Variant(ref row) => row
351 .row_iter()
352 .find(|field| *field.name == *id)
353 .map(|field| &field.typ),
354 _ => None,
355 })
356 .next()
357 .map(|ctor| ctor.clone())
358 })
359 }
360
361 fn find_type_info(&self, id: &SymbolRef) -> Option<Alias<Symbol, ArcType>> {
362 self.vm_envs
363 .iter()
364 .filter_map(|env| env.find_type_info(id))
365 .next()
366 .or_else(|| self.globals.type_infos.find_type_info(id))
367 }
368}
369
370impl<'a> PrimitiveEnv for VmEnvInstance<'a> {
371 fn get_bool(&self) -> ArcType {
372 self.find_type_info("std.types.Bool")
373 .expect("Missing std.types.Bool")
374 .into_type()
375 }
376}
377
378impl<'a> MetadataEnv for VmEnvInstance<'a> {
379 fn get_metadata(&self, id: &SymbolRef) -> Option<Arc<Metadata>> {
380 self.get_metadata_(id.definition_name())
381 }
382}
383
384impl<'a> VmEnv for VmEnvInstance<'a> {
385 fn get_global(&self, name: &str) -> Option<RootedGlobal> {
386 self.vm_envs
387 .iter()
388 .filter_map(|env| env.get_global(name))
389 .next()
390 }
391}
392
393impl<'a> VmEnvInstance<'a> {
394 pub fn find_type_info(&self, name: &str) -> Result<Alias<Symbol, ArcType>> {
395 let name = Name::new(name);
396
397 if let Some(alias) = self.globals.type_infos.id_to_type.get(name.as_str()) {
398 return Ok(alias.clone());
399 }
400
401 let (_, typ) = self
402 .get_binding(name.module().as_str())
403 .map_err(|mut err| {
404 if let Error::UndefinedBinding(module) = &mut err {
405 module.clear();
406 module.push_str(name.as_str());
407 }
408 err
409 })?;
410 let maybe_type_info = {
411 let field_name = name.name();
412 typ.type_field_iter()
413 .find(|field| field.name.as_str() == field_name.as_str())
414 .map(|field| &field.typ)
415 .cloned()
416 };
417 maybe_type_info.ok_or_else(move || Error::UndefinedField(typ, name.name().as_str().into()))
418 }
419
420 fn get_scoped_global<'s, 'n>(&'s self, name: &'n str) -> Option<(&'n Name, RootedGlobal)> {
421 let mut module = Name::new(name.trim_start_matches('@'));
422 let global;
423 loop {
430 if module.as_str() == "" {
431 return None;
432 }
433 if let Some(g) = self.get_global(module.as_str()) {
434 global = g;
435 break;
436 }
437 module = module.module();
438 }
439
440 let remaining_offset = ::std::cmp::min(name.len(), module.as_str().len() + 1); let remaining_fields = Name::new(&name[remaining_offset..]);
442 Some((remaining_fields, global))
443 }
444
445 #[doc(hidden)]
446 pub fn get_binding(&self, name: &str) -> Result<(RootedValue<RootedThread>, ArcType)> {
447 use crate::base::resolve;
448
449 let (remaining_fields, global) = self
450 .get_scoped_global(name)
451 .ok_or_else(|| Error::UndefinedBinding(name.into()))?;
452
453 if remaining_fields.as_str().is_empty() {
454 return Ok((global.value, global.typ));
456 }
457
458 let mut typ = global.typ;
459 let mut value = Variants::new(&global.value);
460
461 for mut field_name in remaining_fields.components() {
462 if field_name.starts_with('(') && field_name.ends_with(')') {
463 field_name = &field_name[1..field_name.len() - 1];
464 } else if field_name.contains(ast::is_operator_char) {
465 return Err(Error::Message(format!(
466 "Operators cannot be used as fields \
467 directly. To access an operator field, \
468 enclose the operator with parentheses \
469 before passing it in. (test.(+) instead of \
470 test.+)"
471 )));
472 }
473 typ = resolve::remove_aliases(self, &mut NullInterner, typ);
474 let next_type = {
476 typ.row_iter()
477 .enumerate()
478 .find(|&(_, field)| field.name.as_pretty_str() == field_name)
479 .map(|(index, field)| match value.as_ref() {
480 ValueRef::Data(data) => {
481 value = data.get_variant(index).unwrap();
482 &field.typ
483 }
484 _ => ice!("Unexpected value {:?}", value),
485 })
486 .cloned()
487 };
488 typ = next_type.ok_or_else(move || Error::UndefinedField(typ, field_name.into()))?;
489 }
490 Ok((self.thread.root_value(value), typ))
491 }
492
493 pub fn get_metadata(&self, name_str: &str) -> Result<Arc<Metadata>> {
494 self.get_metadata_(name_str)
495 .ok_or_else(|| Error::MetadataDoesNotExist(name_str.into()))
496 }
497
498 fn get_metadata_(&self, name_str: &str) -> Option<Arc<Metadata>> {
499 let (remaining, global) = self.get_scoped_global(name_str)?;
500
501 let mut metadata = &global.metadata;
502 for field_name in remaining.components() {
503 metadata = metadata.module.get(field_name)?
504 }
505 Some(metadata.clone())
506 }
507}
508
509#[derive(Default)]
510pub struct GlobalVmStateBuilder {
511 spawner: Option<Box<dyn futures::task::Spawn + Send + Sync>>,
512}
513
514impl GlobalVmStateBuilder {
515 pub fn new() -> Self {
516 Self::default()
517 }
518
519 pub fn spawner(mut self, spawner: Option<Box<dyn futures::task::Spawn + Send + Sync>>) -> Self {
520 self.spawner = spawner;
521 self
522 }
523
524 pub fn build(self) -> GlobalVmState {
525 let mut vm = GlobalVmState {
526 env: Default::default(),
527 generics: RwLock::new(FnvMap::default()),
528 typeids: RwLock::new(FnvMap::default()),
529 interner: RwLock::new(Interner::new()),
530 gc: Mutex::new(Gc::new(Generation::default(), usize::MAX)),
531 macros: MacroEnv::new(),
532 type_cache: TypeCache::default(),
533 generation_0_threads: Default::default(),
534 debug_level: RwLock::new(DebugLevel::default()),
535 thread_reference_count: Default::default(),
536 spawner: self.spawner,
537 };
538 vm.add_types().unwrap();
539 vm
540 }
541}
542
543impl GlobalVmState {
544 pub fn new() -> Self {
545 GlobalVmStateBuilder::new().build()
546 }
547
548 fn add_types(&mut self) -> StdResult<(), (TypeId, ArcType)> {
549 use crate::api::generic::A;
550 use crate::api::Generic;
551 use crate::base::types::BuiltinType;
552 fn add_builtin_type<T: Any>(self_: &mut GlobalVmState, b: BuiltinType) {
553 add_builtin_type_(self_, b, TypeId::of::<T>())
554 }
555 fn add_builtin_type_(self_: &mut GlobalVmState, b: BuiltinType, id: TypeId) {
556 let typ = self_.type_cache.builtin_type(b);
557 add_type(self_, b.to_str(), typ, id)
558 }
559 fn add_type(self_: &mut GlobalVmState, name: &str, typ: ArcType, id: TypeId) {
560 let ids = self_.typeids.get_mut().unwrap();
561 let env = self_.env.get_mut();
562 ids.insert(id, typ);
563 env.type_infos.id_to_type.insert(
565 name.into(),
566 Alias::from(AliasData::new(
567 Symbol::from(name),
568 vec![],
569 self_.type_cache.opaque(),
570 )),
571 );
572 }
573
574 {
575 let unit = self.type_cache.unit();
576 add_type(self, "()", unit, TypeId::of::<()>());
577 add_builtin_type::<VmInt>(self, BuiltinType::Int);
578 add_builtin_type::<u8>(self, BuiltinType::Byte);
579 add_builtin_type::<f32>(self, BuiltinType::Float);
580 add_builtin_type::<f64>(self, BuiltinType::Float);
581 add_builtin_type::<::std::string::String>(self, BuiltinType::String);
582 add_builtin_type::<char>(self, BuiltinType::Char)
583 }
584 self.register_type::<IO<Generic<A>>>("std.io.IO", &["a"])
585 .unwrap();
586 self.register_type::<Lazy<Generic<A>>>("std.lazy.Lazy", &["a"])
587 .unwrap();
588 self.register_type::<Thread>("std.thread.Thread", &[])
589 .unwrap();
590 Ok(())
591 }
592
593 pub fn type_cache(&self) -> &TypeCache<Symbol, ArcType> {
594 &self.type_cache
595 }
596
597 pub fn new_global_thunk(
598 &self,
599 thread: &Thread,
600 f: CompiledModule,
601 ) -> Result<OpaqueValue<RootedThread, GcPtr<ClosureData>>> {
602 let mut gc = self.gc.lock().unwrap();
603 let env = self.get_env(thread);
604 let mut interner = self.interner.write().unwrap();
605 let byte_code = new_bytecode(&env, &mut interner, &mut gc, self, f)?;
606 Ok(OpaqueValue::from_value(
607 thread.root_value(Variants::from(byte_code)),
608 ))
609 }
610
611 pub fn get_type<T: ?Sized + Any>(&self) -> Option<ArcType> {
612 let id = TypeId::of::<T>();
613 self.typeids.read().unwrap().get(&id).cloned()
614 }
615
616 pub fn get_generic(&self, name: &str) -> ArcType {
617 let mut generics = self.generics.write().unwrap();
618 if let Some(g) = generics.get(name) {
619 return g.clone();
620 }
621 let g: ArcType = Type::generic(Generic::new(Symbol::from(name), Kind::typ()));
622 generics.insert(name.into(), g.clone());
623 g
624 }
625
626 pub fn register_type<T: ?Sized + Any>(&self, name: &str, args: &[&str]) -> Result<ArcType> {
628 self.register_type_(name, args, TypeId::of::<T>())
629 }
630
631 fn register_type_(&self, name: &str, args: &[&str], id: TypeId) -> Result<ArcType> {
632 let arg_types: AppVec<_> = args.iter().map(|g| self.get_generic(g)).collect();
633 let args = arg_types
634 .iter()
635 .map(|g| match **g {
636 Type::Generic(ref g) => g.clone(),
637 _ => unreachable!(),
638 })
639 .collect();
640 let n = Symbol::from(name);
641 let alias = Alias::from(AliasData::new(n.clone(), args, self.type_cache.opaque()));
642 self.register_type_as(n, alias, id)
643 }
644
645 pub fn register_type_as(
646 &self,
647 name: Symbol,
648 alias: Alias<Symbol, ArcType>,
649 id: TypeId,
650 ) -> Result<ArcType> {
651 let mut env = self.env.write();
652 let type_infos = &mut env.type_infos;
653 self.typeids
654 .write()
655 .unwrap()
656 .insert(id, alias.clone().into_type());
657 let t = alias.clone().into_type();
658 type_infos
659 .id_to_type
660 .insert(name.definition_name().into(), alias);
661 Ok(t)
662 }
663
664 #[doc(hidden)]
665 pub fn get_cache_alias(&self, name: &str) -> Option<ArcType> {
666 let env = self.env.read();
667 env
668 .type_infos
669 .id_to_type
670 .get(name)
671 .map(|alias| alias.clone().into_type())
672 }
673
674 #[doc(hidden)]
675 pub fn cache_alias(&self, alias: Alias<Symbol, ArcType>) -> ArcType {
676 let mut env = self.env.write();
677 let type_infos = &mut env.type_infos;
678 let t = alias.clone().into_type();
679 type_infos
680 .id_to_type
681 .insert(alias.name.definition_name().into(), alias);
682 t
683 }
684
685 pub fn get_macros(&self) -> &MacroEnv {
686 &self.macros
687 }
688
689 pub fn intern(&self, s: &str) -> Result<InternedStr> {
690 let mut gc = self.gc.lock().unwrap();
691 let mut interner = self.interner.write().unwrap();
692 interner.intern(&mut *gc, s)
693 }
694
695 pub fn get_env<'t>(&'t self, thread: &'t Thread) -> VmEnvInstance<'t> {
697 let capabilities = self.macros.get_capabilities::<Box<dyn VmEnv>>(thread);
698 VmEnvInstance {
699 vm_envs: capabilities,
700 globals: self.env.read_recursive(),
701 thread,
702 }
703 }
704
705 pub fn get_capability<'t, T>(&'t self, thread: &'t Thread) -> Option<T>
706 where
707 T: Any,
708 {
709 self.macros.get_capability(thread)
710 }
711
712 #[doc(hidden)]
713 pub fn get_lookup_env<'t>(&'t self, thread: &'t Thread) -> VmEnvInstance<'t> {
714 VmEnvInstance {
715 vm_envs: Vec::new(),
716 globals: self.env.read_recursive(),
717 thread,
718 }
719 }
720
721 #[doc(hidden)]
722 pub fn get_globals(&self) -> parking_lot::RwLockReadGuard<Globals> {
723 self.env.read_recursive()
724 }
725
726 pub fn get_debug_level(&self) -> DebugLevel {
727 self.debug_level.read().unwrap().clone()
728 }
729
730 pub fn set_debug_level(&self, debug_level: DebugLevel) {
731 *self.debug_level.write().unwrap() = debug_level;
732 }
733
734 pub fn spawner(&self) -> Option<&(dyn futures::task::Spawn + Send + Sync)> {
735 self.spawner.as_ref().map(|s| &**s)
736 }
737}