d637d68af5ad631558ea93b3b86b9da04cb83175
[WebKit-https.git] / Source / JavaScriptCore / bytecode / UnlinkedFunctionExecutable.h
1 /*
2  * Copyright (C) 2012-2018 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 "CodeSpecializationKind.h"
29 #include "ConstructAbility.h"
30 #include "ExecutableInfo.h"
31 #include "ExpressionRangeInfo.h"
32 #include "Identifier.h"
33 #include "Intrinsic.h"
34 #include "JSCast.h"
35 #include "ParserModes.h"
36 #include "RegExp.h"
37 #include "SourceCode.h"
38 #include "VariableEnvironment.h"
39
40 namespace JSC {
41
42 class Decoder;
43 class FunctionMetadataNode;
44 class FunctionExecutable;
45 class ParserError;
46 class SourceProvider;
47 class UnlinkedFunctionCodeBlock;
48 class CachedFunctionExecutable;
49
50 enum UnlinkedFunctionKind {
51     UnlinkedNormalFunction,
52     UnlinkedBuiltinFunction,
53 };
54
55 class UnlinkedFunctionExecutable final : public JSCell {
56 public:
57     friend class CodeCache;
58     friend class VM;
59     friend CachedFunctionExecutable;
60
61     typedef JSCell Base;
62     static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
63
64     template<typename CellType>
65     static IsoSubspace* subspaceFor(VM& vm)
66     {
67         return &vm.unlinkedFunctionExecutableSpace.space;
68     }
69
70     static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionMetadataNode* node, UnlinkedFunctionKind unlinkedFunctionKind, ConstructAbility constructAbility, JSParserScriptMode scriptMode, VariableEnvironment& parentScopeTDZVariables, DerivedContextType derivedContextType, bool isBuiltinDefaultClassConstructor = false)
71     {
72         UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap))
73             UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, node, unlinkedFunctionKind, constructAbility, scriptMode, parentScopeTDZVariables, derivedContextType, isBuiltinDefaultClassConstructor);
74         instance->finishCreation(*vm);
75         return instance;
76     }
77
78     const Identifier& name() const { return m_name; }
79     const Identifier& ecmaName() const { return m_ecmaName; }
80     void setEcmaName(const Identifier& name) { m_ecmaName = name; }
81     const Identifier& inferredName() const { return m_inferredName; }
82     unsigned parameterCount() const { return m_parameterCount; }; // Excluding 'this'!
83     SourceParseMode parseMode() const { return static_cast<SourceParseMode>(m_sourceParseMode); };
84
85     const SourceCode& classSource() const { return m_classSource; };
86     void setClassSource(const SourceCode& source) { m_classSource = source; };
87
88     bool isInStrictContext() const { return m_isInStrictContext; }
89     FunctionMode functionMode() const { return static_cast<FunctionMode>(m_functionMode); }
90     ConstructorKind constructorKind() const { return static_cast<ConstructorKind>(m_constructorKind); }
91     SuperBinding superBinding() const { return static_cast<SuperBinding>(m_superBinding); }
92
93     unsigned lineCount() const { return m_lineCount; }
94     unsigned linkedStartColumn(unsigned parentStartColumn) const { return m_unlinkedBodyStartColumn + (!m_firstLineOffset ? parentStartColumn : 1); }
95     unsigned linkedEndColumn(unsigned startColumn) const { return m_unlinkedBodyEndColumn + (!m_lineCount ? startColumn : 1); }
96
97     unsigned unlinkedFunctionNameStart() const { return m_unlinkedFunctionNameStart; }
98     unsigned unlinkedBodyStartColumn() const { return m_unlinkedBodyStartColumn; }
99     unsigned unlinkedBodyEndColumn() const { return m_unlinkedBodyEndColumn; }
100     unsigned startOffset() const { return m_startOffset; }
101     unsigned sourceLength() { return m_sourceLength; }
102     unsigned parametersStartOffset() const { return m_parametersStartOffset; }
103     unsigned typeProfilingStartOffset() const { return m_typeProfilingStartOffset; }
104     unsigned typeProfilingEndOffset() const { return m_typeProfilingEndOffset; }
105     void setInvalidTypeProfilingOffsets();
106
107     UnlinkedFunctionCodeBlock* unlinkedCodeBlockFor(CodeSpecializationKind);
108
109     UnlinkedFunctionCodeBlock* unlinkedCodeBlockFor(
110         VM&, const SourceCode&, CodeSpecializationKind, DebuggerMode,
111         ParserError&, SourceParseMode);
112
113     static UnlinkedFunctionExecutable* fromGlobalCode(
114         const Identifier&, ExecState&, const SourceCode&, JSObject*& exception, 
115         int overrideLineNumber, Optional<int> functionConstructorParametersEndPosition);
116
117     JS_EXPORT_PRIVATE FunctionExecutable* link(VM&, const SourceCode& parentSource, Optional<int> overrideLineNumber = WTF::nullopt, Intrinsic = NoIntrinsic);
118
119     void clearCode(VM& vm)
120     {
121         m_unlinkedCodeBlockForCall.clear();
122         m_unlinkedCodeBlockForConstruct.clear();
123         vm.unlinkedFunctionExecutableSpace.clearableCodeSet.remove(this);
124     }
125
126     void recordParse(CodeFeatures features, bool hasCapturedVariables)
127     {
128         m_features = features;
129         m_hasCapturedVariables = hasCapturedVariables;
130     }
131
132     CodeFeatures features() const { return m_features; }
133     bool hasCapturedVariables() const { return m_hasCapturedVariables; }
134
135     static const bool needsDestruction = true;
136     static void destroy(JSCell*);
137
138     bool isBuiltinFunction() const { return m_isBuiltinFunction; }
139     ConstructAbility constructAbility() const { return static_cast<ConstructAbility>(m_constructAbility); }
140     JSParserScriptMode scriptMode() const { return static_cast<JSParserScriptMode>(m_scriptMode); }
141     bool isClassConstructorFunction() const { return constructorKind() != ConstructorKind::None; }
142     VariableEnvironment parentScopeTDZVariables() const { return m_parentScopeTDZVariables.environment().toVariableEnvironment(); }
143     
144     bool isArrowFunction() const { return isArrowFunctionParseMode(parseMode()); }
145
146     JSC::DerivedContextType derivedContextType() const {return static_cast<JSC::DerivedContextType>(m_derivedContextType); }
147
148     const String& sourceURLDirective() const { return m_sourceURLDirective; }
149     const String& sourceMappingURLDirective() const { return m_sourceMappingURLDirective; }
150     void setSourceURLDirective(const String& sourceURL) { m_sourceURLDirective = sourceURL; }
151     void setSourceMappingURLDirective(const String& sourceMappingURL) { m_sourceMappingURLDirective = sourceMappingURL; }
152
153 private:
154     UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, FunctionMetadataNode*, UnlinkedFunctionKind, ConstructAbility, JSParserScriptMode, VariableEnvironment&,  JSC::DerivedContextType, bool isBuiltinDefaultClassConstructor);
155     UnlinkedFunctionExecutable(Decoder&, VariableEnvironment&, const CachedFunctionExecutable&);
156
157     unsigned m_firstLineOffset;
158     unsigned m_lineCount;
159     unsigned m_unlinkedFunctionNameStart;
160     unsigned m_unlinkedBodyStartColumn;
161     unsigned m_unlinkedBodyEndColumn;
162     unsigned m_startOffset;
163     unsigned m_sourceLength;
164     unsigned m_parametersStartOffset;
165     unsigned m_typeProfilingStartOffset;
166     unsigned m_typeProfilingEndOffset;
167     unsigned m_parameterCount;
168     CodeFeatures m_features;
169     SourceParseMode m_sourceParseMode;
170     unsigned m_isInStrictContext : 1;
171     unsigned m_hasCapturedVariables : 1;
172     unsigned m_isBuiltinFunction : 1;
173     unsigned m_isBuiltinDefaultClassConstructor : 1;
174     unsigned m_constructAbility: 1;
175     unsigned m_constructorKind : 2;
176     unsigned m_functionMode : 2; // FunctionMode
177     unsigned m_scriptMode: 1; // JSParserScriptMode
178     unsigned m_superBinding : 1;
179     unsigned m_derivedContextType: 2;
180
181     WriteBarrier<UnlinkedFunctionCodeBlock> m_unlinkedCodeBlockForCall;
182     WriteBarrier<UnlinkedFunctionCodeBlock> m_unlinkedCodeBlockForConstruct;
183
184     Identifier m_name;
185     Identifier m_ecmaName;
186     Identifier m_inferredName;
187     SourceCode m_classSource;
188
189     String m_sourceURLDirective;
190     String m_sourceMappingURLDirective;
191
192     CompactVariableMap::Handle m_parentScopeTDZVariables;
193
194 protected:
195     static void visitChildren(JSCell*, SlotVisitor&);
196
197 public:
198     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
199     {
200         return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedFunctionExecutableType, StructureFlags), info());
201     }
202
203     DECLARE_EXPORT_INFO;
204 };
205
206 } // namespace JSC