0e9c5f5bdde6c7562b66a03bc0a98c87adbd9302
[WebKit-https.git] / Source / JavaScriptCore / bytecode / UnlinkedModuleProgramCodeBlock.h
1 /*
2  * Copyright (C) 2012-2017 Apple Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #include "UnlinkedGlobalCodeBlock.h"
29
30 namespace JSC {
31
32 class UnlinkedModuleProgramCodeBlock final : public UnlinkedGlobalCodeBlock {
33 public:
34     typedef UnlinkedGlobalCodeBlock Base;
35     static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
36
37     static UnlinkedModuleProgramCodeBlock* create(VM* vm, const ExecutableInfo& info, DebuggerMode debuggerMode)
38     {
39         UnlinkedModuleProgramCodeBlock* instance = new (NotNull, allocateCell<UnlinkedModuleProgramCodeBlock>(vm->heap)) UnlinkedModuleProgramCodeBlock(vm, vm->unlinkedModuleProgramCodeBlockStructure.get(), info, debuggerMode);
40         instance->finishCreation(*vm);
41         return instance;
42     }
43
44     static void destroy(JSCell*);
45
46     // This offset represents the constant register offset to the stored symbol table that represents the layout of the
47     // module environment. This symbol table is created by the byte code generator since the module environment includes
48     // the top-most lexical captured variables inside the module code. This means that, once the module environment is
49     // allocated and instantiated from this symbol table, it is titely coupled with the specific unlinked module program
50     // code block and the stored symbol table. So before executing the module code, we should not clear the unlinked module
51     // program code block in the module executable. This requirement is met because the garbage collector only clears
52     // unlinked code in (1) unmarked executables and (2) function executables.
53     //
54     // Since the function code may be executed repeatedly and the environment of each function execution is different,
55     // the function code need to allocate and instantiate the environment in the prologue of the function code. On the
56     // other hand, the module code is executed only once. So we can instantiate the module environment outside the module
57     // code. At that time, we construct the module environment by using the symbol table that is held by the module executable.
58     // The symbol table held by the executable is the cloned one from one in the unlinked code block. Instantiating the module
59     // environment before executing and linking the module code is required to link the imported bindings between the modules.
60     //
61     // The unlinked module program code block only holds the pre-cloned symbol table in its constant register pool. It does
62     // not hold the instantiated module environment. So while the module environment requires the specific unlinked module
63     // program code block, the unlinked module code block can be used for the module environment instantiated from this
64     // unlinked code block. There is 1:N relation between the unlinked module code block and the module environments. So the
65     // unlinked module program code block can be cached.
66     //
67     // On the other hand, the linked code block for the module environment includes the resolved references to the imported
68     // bindings. The imported binding references the other module environment, so the linked code block is titly coupled
69     // with the specific set of the module environments. Thus, the linked code block should not be cached.
70     int moduleEnvironmentSymbolTableConstantRegisterOffset() { return m_moduleEnvironmentSymbolTableConstantRegisterOffset; }
71     void setModuleEnvironmentSymbolTableConstantRegisterOffset(int offset)
72     {
73         m_moduleEnvironmentSymbolTableConstantRegisterOffset = offset;
74     }
75
76 private:
77     UnlinkedModuleProgramCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info, DebuggerMode debuggerMode)
78         : Base(vm, structure, ModuleCode, info, debuggerMode)
79     {
80     }
81
82     int m_moduleEnvironmentSymbolTableConstantRegisterOffset { 0 };
83
84 public:
85     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
86     {
87         return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedModuleProgramCodeBlockType, StructureFlags), info());
88     }
89
90     DECLARE_INFO;
91 };
92
93 }