Skip to main content

boa_engine/bytecompiler/
module.rs

1use super::{ByteCompiler, Literal, ToJsString};
2use crate::vm::opcode::BindingOpcode;
3use boa_ast::{ModuleItem, ModuleItemList, declaration::ExportDeclaration};
4use boa_interner::Sym;
5
6impl ByteCompiler<'_> {
7    /// Compiles a [`ModuleItemList`].
8    #[inline]
9    pub fn compile_module_item_list(&mut self, list: &ModuleItemList) {
10        for node in list.items() {
11            self.compile_module_item(node);
12        }
13    }
14
15    /// Compiles a [`ModuleItem`].
16    #[inline]
17    pub fn compile_module_item(&mut self, item: &ModuleItem) {
18        match item {
19            ModuleItem::StatementListItem(stmt) => {
20                self.compile_stmt_list_item(stmt, false, false);
21            }
22            ModuleItem::ImportDeclaration(_) => {
23                // ModuleItem : ImportDeclaration
24
25                // 1. Return empty.
26            }
27            ModuleItem::ExportDeclaration(export) => {
28                #[allow(clippy::match_same_arms)]
29                match export.as_ref() {
30                    ExportDeclaration::ReExport { .. } | ExportDeclaration::List(_) => {
31                        // ExportDeclaration :
32                        //    export ExportFromClause FromClause ;
33                        //    export NamedExports ;
34                        //        1. Return empty.
35                    }
36                    ExportDeclaration::DefaultFunctionDeclaration(_)
37                    | ExportDeclaration::DefaultGeneratorDeclaration(_)
38                    | ExportDeclaration::DefaultAsyncFunctionDeclaration(_)
39                    | ExportDeclaration::DefaultAsyncGeneratorDeclaration(_) => {
40                        // Already instantiated in `initialize_environment`.
41                    }
42                    ExportDeclaration::VarStatement(var) => self.compile_var_decl(var),
43                    ExportDeclaration::Declaration(decl) => self.compile_decl(decl, false),
44                    ExportDeclaration::DefaultClassDeclaration(cl) => {
45                        self.compile_class(cl.as_ref().into(), None);
46                    }
47                    ExportDeclaration::DefaultAssignmentExpression(expr) => {
48                        let function = self.register_allocator.alloc();
49                        self.compile_expr(expr, &function);
50
51                        if expr.is_anonymous_function_definition() {
52                            let default = self
53                                .interner()
54                                .resolve_expect(Sym::DEFAULT)
55                                .into_common(false);
56                            let key = self.register_allocator.alloc();
57                            self.emit_store_literal(Literal::String(default), &key);
58                            self.bytecode.emit_set_function_name(
59                                function.variable(),
60                                key.variable(),
61                                0u32.into(),
62                            );
63                            self.register_allocator.dealloc(key);
64                        }
65
66                        let name = Sym::DEFAULT_EXPORT.to_js_string(self.interner());
67                        self.emit_binding(BindingOpcode::InitLexical, name, &function);
68                        self.register_allocator.dealloc(function);
69                    }
70                }
71            }
72        }
73    }
74}