pub(crate) mod bc;
pub(crate) mod compiler;
pub(crate) mod runtime;
use std::collections::HashMap;
use std::mem;
use std::time::Instant;
use dupe::Dupe;
pub use runtime::arguments::Arguments;
pub use runtime::before_stmt::BeforeStmtFuncDyn;
pub use runtime::evaluator::Evaluator;
pub use runtime::file_loader::FileLoader;
pub use runtime::file_loader::ReturnFileLoader;
pub use runtime::params::ParametersParser;
pub use runtime::params::ParametersSpec;
pub use runtime::params::ParametersSpecBuilder;
pub use runtime::profile::data::ProfileData;
pub use runtime::profile::ProfileMode;
pub use starlark_syntax::call_stack::CallStack;
use starlark_syntax::slice_vec_ext::SliceExt;
use starlark_syntax::syntax::module::AstModule;
use starlark_syntax::syntax::module::AstModuleFields;
use crate::collections::symbol_map::Symbol;
use crate::docs::DocString;
use crate::environment::Globals;
use crate::eval::compiler::def::DefInfo;
use crate::eval::compiler::scope::scope_resolver_globals::ScopeResolverGlobals;
use crate::eval::compiler::scope::ModuleScopes;
use crate::eval::compiler::scope::ScopeId;
use crate::eval::compiler::Compiler;
use crate::eval::runtime::arguments::ArgNames;
use crate::eval::runtime::arguments::ArgumentsFull;
use crate::eval::runtime::evaluator;
use crate::syntax::DialectTypes;
use crate::values::Value;
impl<'v, 'a> Evaluator<'v, 'a> {
pub fn eval_module(&mut self, ast: AstModule, globals: &Globals) -> crate::Result<Value<'v>> {
let start = Instant::now();
let (codemap, statement, dialect, typecheck) = ast.into_parts();
let codemap = self
.module_env
.frozen_heap()
.alloc_any_display_from_debug(codemap.dupe());
let globals = self
.module_env
.frozen_heap()
.alloc_any_display_from_type_name(globals.dupe());
if let Some(docstring) = DocString::extract_raw_starlark_docstring(&statement) {
self.module_env.set_docstring(docstring)
}
let ModuleScopes {
cst,
module_slot_count,
scope_data,
top_level_stmt_count,
} = ModuleScopes::check_module_err(
self.module_env.mutable_names(),
self.module_env.frozen_heap(),
&HashMap::new(),
statement,
ScopeResolverGlobals {
globals: Some(globals),
},
codemap,
&dialect,
)?;
let scope_names = scope_data.get_scope(ScopeId::module());
let local_names = self
.frozen_heap()
.alloc_any_slice_display_from_debug(&scope_names.used);
self.module_env.slots().ensure_slots(module_slot_count);
let old_def_info = mem::replace(
&mut self.module_def_info,
self.module_env.frozen_heap().alloc_any(DefInfo::for_module(
codemap,
local_names,
self.module_env
.frozen_heap()
.alloc_any_slice_display_from_debug(&scope_names.parent),
globals,
)),
);
self.call_stack.alloc_if_needed(
self.max_callstack_size
.unwrap_or(evaluator::DEFAULT_STACK_SIZE),
)?;
self.call_stack.push(Value::new_none(), None).unwrap();
let mut compiler = Compiler {
scope_data,
locals: Vec::new(),
globals,
codemap,
eval: self,
check_types: dialect.enable_types == DialectTypes::Enable,
top_level_stmt_count,
typecheck,
};
let res = compiler.eval_module(cst, local_names);
self.call_stack.pop();
self.module_def_info = old_def_info;
self.module_env.add_eval_duration(start.elapsed());
res.map_err(|e| e.into_error())
}
pub fn eval_function(
&mut self,
function: Value<'v>,
positional: &[Value<'v>],
named: &[(&str, Value<'v>)],
) -> crate::Result<Value<'v>> {
let names = named.map(|(s, _)| (Symbol::new(s), self.heap().alloc_str(s)));
let named = named.map(|x| x.1);
let params = Arguments(ArgumentsFull {
pos: positional,
named: &named,
names: ArgNames::new(&names),
args: None,
kwargs: None,
});
self.call_stack.alloc_if_needed(
self.max_callstack_size
.unwrap_or(evaluator::DEFAULT_STACK_SIZE),
)?;
self.with_call_stack(Value::new_none(), None, |this| {
function.invoke(¶ms, this)
})
.map_err(Into::into)
}
}