2 * Copyright (C) 2009, 2010, 2013-2015 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
29 #include "ArityCheckMode.h"
31 #include "CodeBlockHash.h"
32 #include "CodeSpecializationKind.h"
33 #include "CompilationResult.h"
34 #include "ExecutableInfo.h"
35 #include "HandlerInfo.h"
36 #include "InferredValue.h"
38 #include "JSGlobalObject.h"
39 #include "SamplingTool.h"
40 #include "SourceCode.h"
42 #include "UnlinkedCodeBlock.h"
43 #include "UnlinkedFunctionExecutable.h"
50 class FunctionCodeBlock;
53 class LLIntOffsetsExtractor;
54 class ProgramCodeBlock;
55 class ModuleProgramCodeBlock;
57 class WebAssemblyCodeBlock;
58 class ModuleProgramCodeBlock;
62 enum CompilationKind { FirstCompilation, OptimizingCompilation };
64 inline bool isCall(CodeSpecializationKind kind)
66 if (kind == CodeForCall)
68 ASSERT(kind == CodeForConstruct);
72 class ExecutableBase : public JSCell {
76 static const int NUM_PARAMETERS_IS_HOST = 0;
77 static const int NUM_PARAMETERS_NOT_COMPILED = -1;
79 ExecutableBase(VM& vm, Structure* structure, int numParameters)
80 : JSCell(vm, structure)
81 , m_numParametersForCall(numParameters)
82 , m_numParametersForConstruct(numParameters)
86 void finishCreation(VM& vm)
88 Base::finishCreation(vm);
93 static const unsigned StructureFlags = Base::StructureFlags;
95 static const bool needsDestruction = true;
96 static void destroy(JSCell*);
98 CodeBlockHash hashFor(CodeSpecializationKind) const;
100 bool isEvalExecutable() const
102 return type() == EvalExecutableType;
104 bool isFunctionExecutable() const
106 return type() == FunctionExecutableType;
108 bool isProgramExecutable() const
110 return type() == ProgramExecutableType;
112 bool isModuleProgramExecutable()
114 return type() == ModuleProgramExecutableType;
118 bool isHostFunction() const
120 ASSERT((m_numParametersForCall == NUM_PARAMETERS_IS_HOST) == (m_numParametersForConstruct == NUM_PARAMETERS_IS_HOST));
121 return m_numParametersForCall == NUM_PARAMETERS_IS_HOST;
124 #if ENABLE(WEBASSEMBLY)
125 bool isWebAssemblyExecutable() const
127 return type() == WebAssemblyExecutableType;
131 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(CellType, StructureFlags), info()); }
138 int m_numParametersForCall;
139 int m_numParametersForConstruct;
142 PassRefPtr<JITCode> generatedJITCodeForCall()
144 ASSERT(m_jitCodeForCall);
145 return m_jitCodeForCall;
148 PassRefPtr<JITCode> generatedJITCodeForConstruct()
150 ASSERT(m_jitCodeForConstruct);
151 return m_jitCodeForConstruct;
154 PassRefPtr<JITCode> generatedJITCodeFor(CodeSpecializationKind kind)
156 if (kind == CodeForCall)
157 return generatedJITCodeForCall();
158 ASSERT(kind == CodeForConstruct);
159 return generatedJITCodeForConstruct();
162 MacroAssemblerCodePtr entrypointFor(CodeSpecializationKind kind, ArityCheckMode arity)
164 // Check if we have a cached result. We only have it for arity check because we use the
165 // no-arity entrypoint in non-virtual calls, which will "cache" this value directly in
167 if (arity == MustCheckArity) {
170 if (MacroAssemblerCodePtr result = m_jitCodeForCallWithArityCheck)
173 case CodeForConstruct:
174 if (MacroAssemblerCodePtr result = m_jitCodeForConstructWithArityCheck)
179 MacroAssemblerCodePtr result =
180 generatedJITCodeFor(kind)->addressForCall(arity);
181 if (arity == MustCheckArity) {
182 // Cache the result; this is necessary for the JIT's virtual call optimizations.
185 m_jitCodeForCallWithArityCheck = result;
187 case CodeForConstruct:
188 m_jitCodeForConstructWithArityCheck = result;
195 static ptrdiff_t offsetOfJITCodeWithArityCheckFor(
196 CodeSpecializationKind kind)
200 return OBJECT_OFFSETOF(ExecutableBase, m_jitCodeForCallWithArityCheck);
201 case CodeForConstruct:
202 return OBJECT_OFFSETOF(ExecutableBase, m_jitCodeForConstructWithArityCheck);
204 RELEASE_ASSERT_NOT_REACHED();
208 static ptrdiff_t offsetOfNumParametersFor(CodeSpecializationKind kind)
210 if (kind == CodeForCall)
211 return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForCall);
212 ASSERT(kind == CodeForConstruct);
213 return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForConstruct);
216 bool hasJITCodeForCall() const
218 return m_numParametersForCall >= 0;
221 bool hasJITCodeForConstruct() const
223 return m_numParametersForConstruct >= 0;
226 bool hasJITCodeFor(CodeSpecializationKind kind) const
228 if (kind == CodeForCall)
229 return hasJITCodeForCall();
230 ASSERT(kind == CodeForConstruct);
231 return hasJITCodeForConstruct();
234 // Intrinsics are only for calls, currently.
235 Intrinsic intrinsic() const;
237 Intrinsic intrinsicFor(CodeSpecializationKind kind) const
244 void dump(PrintStream&) const;
247 RefPtr<JITCode> m_jitCodeForCall;
248 RefPtr<JITCode> m_jitCodeForConstruct;
249 MacroAssemblerCodePtr m_jitCodeForCallWithArityCheck;
250 MacroAssemblerCodePtr m_jitCodeForConstructWithArityCheck;
253 class NativeExecutable final : public ExecutableBase {
255 friend class LLIntOffsetsExtractor;
257 typedef ExecutableBase Base;
258 static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
260 static NativeExecutable* create(VM& vm, PassRefPtr<JITCode> callThunk, NativeFunction function, PassRefPtr<JITCode> constructThunk, NativeFunction constructor, Intrinsic intrinsic)
262 NativeExecutable* executable;
263 executable = new (NotNull, allocateCell<NativeExecutable>(vm.heap)) NativeExecutable(vm, function, constructor);
264 executable->finishCreation(vm, callThunk, constructThunk, intrinsic);
268 static void destroy(JSCell*);
270 CodeBlockHash hashFor(CodeSpecializationKind) const;
272 NativeFunction function() { return m_function; }
273 NativeFunction constructor() { return m_constructor; }
275 NativeFunction nativeFunctionFor(CodeSpecializationKind kind)
277 if (kind == CodeForCall)
279 ASSERT(kind == CodeForConstruct);
280 return constructor();
283 static ptrdiff_t offsetOfNativeFunctionFor(CodeSpecializationKind kind)
285 if (kind == CodeForCall)
286 return OBJECT_OFFSETOF(NativeExecutable, m_function);
287 ASSERT(kind == CodeForConstruct);
288 return OBJECT_OFFSETOF(NativeExecutable, m_constructor);
291 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(CellType, StructureFlags), info()); }
295 Intrinsic intrinsic() const;
298 void finishCreation(VM& vm, PassRefPtr<JITCode> callThunk, PassRefPtr<JITCode> constructThunk, Intrinsic intrinsic)
300 Base::finishCreation(vm);
301 m_jitCodeForCall = callThunk;
302 m_jitCodeForConstruct = constructThunk;
303 m_intrinsic = intrinsic;
307 friend class ExecutableBase;
309 NativeExecutable(VM& vm, NativeFunction function, NativeFunction constructor)
310 : ExecutableBase(vm, vm.nativeExecutableStructure.get(), NUM_PARAMETERS_IS_HOST)
311 , m_function(function)
312 , m_constructor(constructor)
316 NativeFunction m_function;
317 NativeFunction m_constructor;
319 Intrinsic m_intrinsic;
322 class ScriptExecutable : public ExecutableBase {
324 typedef ExecutableBase Base;
325 static const unsigned StructureFlags = Base::StructureFlags;
327 static void destroy(JSCell*);
329 CodeBlockHash hashFor(CodeSpecializationKind) const;
331 const SourceCode& source() const { return m_source; }
332 intptr_t sourceID() const { return m_source.providerID(); }
333 const String& sourceURL() const { return m_source.provider()->url(); }
334 int firstLine() const { return m_firstLine; }
335 void setOverrideLineNumber(int overrideLineNumber) { m_overrideLineNumber = overrideLineNumber; }
336 bool hasOverrideLineNumber() const { return m_overrideLineNumber != -1; }
337 int overrideLineNumber() const { return m_overrideLineNumber; }
338 int lastLine() const { return m_lastLine; }
339 unsigned startColumn() const { return m_startColumn; }
340 unsigned endColumn() const { return m_endColumn; }
341 unsigned typeProfilingStartOffset() const { return m_typeProfilingStartOffset; }
342 unsigned typeProfilingEndOffset() const { return m_typeProfilingEndOffset; }
344 bool usesEval() const { return m_features & EvalFeature; }
345 bool usesArguments() const { return m_features & ArgumentsFeature; }
346 bool needsActivation() const { return m_hasCapturedVariables || m_features & (EvalFeature | WithFeature); }
347 bool isArrowFunctionContext() const { return m_isArrowFunctionContext; }
348 bool isStrictMode() const { return m_features & StrictModeFeature; }
349 bool isDerivedConstructorContext() const { return m_isDerivedConstructorContext; }
350 ECMAMode ecmaMode() const { return isStrictMode() ? StrictMode : NotStrictMode; }
352 void setNeverInline(bool value) { m_neverInline = value; }
353 void setNeverOptimize(bool value) { m_neverOptimize = value; }
354 void setDidTryToEnterInLoop(bool value) { m_didTryToEnterInLoop = value; }
355 bool neverInline() const { return m_neverInline; }
356 bool neverOptimize() const { return m_neverOptimize; }
357 bool didTryToEnterInLoop() const { return m_didTryToEnterInLoop; }
358 bool isInliningCandidate() const { return !neverInline(); }
359 bool isOkToOptimize() const { return !neverOptimize(); }
361 bool* addressOfDidTryToEnterInLoop() { return &m_didTryToEnterInLoop; }
363 CodeFeatures features() const { return m_features; }
367 void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine, unsigned startColumn, unsigned endColumn)
369 m_features = features;
370 m_hasCapturedVariables = hasCapturedVariables;
371 m_firstLine = firstLine;
372 m_lastLine = lastLine;
373 ASSERT(startColumn != UINT_MAX);
374 m_startColumn = startColumn;
375 ASSERT(endColumn != UINT_MAX);
376 m_endColumn = endColumn;
379 void installCode(CodeBlock*);
380 void installCode(VM&, CodeBlock*, CodeType, CodeSpecializationKind);
381 CodeBlock* newCodeBlockFor(CodeSpecializationKind, JSFunction*, JSScope*, JSObject*& exception);
382 CodeBlock* newReplacementCodeBlockFor(CodeSpecializationKind);
384 JSObject* prepareForExecution(ExecState* exec, JSFunction* function, JSScope* scope, CodeSpecializationKind kind)
386 if (hasJITCodeFor(kind))
388 return prepareForExecutionImpl(exec, function, scope, kind);
391 template <typename Functor> void forEachCodeBlock(Functor&&);
394 friend class ExecutableBase;
395 JSObject* prepareForExecutionImpl(ExecState*, JSFunction*, JSScope*, CodeSpecializationKind);
398 ScriptExecutable(Structure*, VM&, const SourceCode&, bool isInStrictContext, bool isInDerivedConstructorContext, bool isInArrowFunctionContext);
400 void finishCreation(VM& vm)
402 Base::finishCreation(vm);
403 vm.heap.addExecutable(this); // Balanced by Heap::deleteUnmarkedCompiledCode().
405 #if ENABLE(CODEBLOCK_SAMPLING)
406 if (SamplingTool* sampler = vm.interpreter->sampler())
407 sampler->notifyOfScope(vm, this);
412 CodeFeatures m_features;
413 bool m_hasCapturedVariables;
415 bool m_neverOptimize { false };
416 bool m_didTryToEnterInLoop;
417 bool m_isDerivedConstructorContext;
418 bool m_isArrowFunctionContext;
419 int m_overrideLineNumber;
422 unsigned m_startColumn;
423 unsigned m_endColumn;
424 unsigned m_typeProfilingStartOffset;
425 unsigned m_typeProfilingEndOffset;
428 class EvalExecutable final : public ScriptExecutable {
429 friend class LLIntOffsetsExtractor;
431 typedef ScriptExecutable Base;
432 static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
434 static void destroy(JSCell*);
436 EvalCodeBlock* codeBlock()
438 return m_evalCodeBlock.get();
441 static EvalExecutable* create(ExecState*, const SourceCode&, bool isInStrictContext, ThisTDZMode, bool isDerivedConstructorContext, bool isArrowFunctionContext, const VariableEnvironment*);
443 PassRefPtr<JITCode> generatedJITCode()
445 return generatedJITCodeForCall();
448 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
450 return Structure::create(vm, globalObject, proto, TypeInfo(EvalExecutableType, StructureFlags), info());
456 ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, SuperBinding::NotNeeded, SourceParseMode::ProgramMode, isDerivedConstructorContext(), isArrowFunctionContext()); }
458 unsigned numVariables() { return m_unlinkedEvalCodeBlock->numVariables(); }
459 unsigned numberOfFunctionDecls() { return m_unlinkedEvalCodeBlock->numberOfFunctionDecls(); }
462 friend class ExecutableBase;
463 friend class ScriptExecutable;
464 EvalExecutable(ExecState*, const SourceCode&, bool inStrictContext, bool isDerivedConstructorContext, bool isArrowFunctionContext);
466 static void visitChildren(JSCell*, SlotVisitor&);
468 WriteBarrier<EvalCodeBlock> m_evalCodeBlock;
469 WriteBarrier<UnlinkedEvalCodeBlock> m_unlinkedEvalCodeBlock;
472 class ProgramExecutable final : public ScriptExecutable {
473 friend class LLIntOffsetsExtractor;
475 typedef ScriptExecutable Base;
476 static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
478 static ProgramExecutable* create(ExecState* exec, const SourceCode& source)
480 ProgramExecutable* executable = new (NotNull, allocateCell<ProgramExecutable>(*exec->heap())) ProgramExecutable(exec, source);
481 executable->finishCreation(exec->vm());
486 JSObject* initializeGlobalProperties(VM&, CallFrame*, JSScope*);
488 static void destroy(JSCell*);
490 ProgramCodeBlock* codeBlock()
492 return m_programCodeBlock.get();
495 JSObject* checkSyntax(ExecState*);
497 PassRefPtr<JITCode> generatedJITCode()
499 return generatedJITCodeForCall();
502 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
504 return Structure::create(vm, globalObject, proto, TypeInfo(ProgramExecutableType, StructureFlags), info());
509 ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, SuperBinding::NotNeeded, SourceParseMode::ProgramMode, isDerivedConstructorContext(), false); }
512 friend class ExecutableBase;
513 friend class ScriptExecutable;
515 ProgramExecutable(ExecState*, const SourceCode&);
517 static void visitChildren(JSCell*, SlotVisitor&);
519 WriteBarrier<UnlinkedProgramCodeBlock> m_unlinkedProgramCodeBlock;
520 WriteBarrier<ProgramCodeBlock> m_programCodeBlock;
523 class ModuleProgramExecutable final : public ScriptExecutable {
524 friend class LLIntOffsetsExtractor;
526 typedef ScriptExecutable Base;
527 static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
529 static ModuleProgramExecutable* create(ExecState*, const SourceCode&);
531 static void destroy(JSCell*);
533 ModuleProgramCodeBlock* codeBlock()
535 return m_moduleProgramCodeBlock.get();
538 PassRefPtr<JITCode> generatedJITCode()
540 return generatedJITCodeForCall();
543 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
545 return Structure::create(vm, globalObject, proto, TypeInfo(ModuleProgramExecutableType, StructureFlags), info());
550 ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, SuperBinding::NotNeeded, SourceParseMode::ModuleEvaluateMode, isDerivedConstructorContext(), false); }
552 UnlinkedModuleProgramCodeBlock* unlinkedModuleProgramCodeBlock() { return m_unlinkedModuleProgramCodeBlock.get(); }
554 SymbolTable* moduleEnvironmentSymbolTable() { return m_moduleEnvironmentSymbolTable.get(); }
557 friend class ExecutableBase;
558 friend class ScriptExecutable;
560 ModuleProgramExecutable(ExecState*, const SourceCode&);
562 static void visitChildren(JSCell*, SlotVisitor&);
564 WriteBarrier<UnlinkedModuleProgramCodeBlock> m_unlinkedModuleProgramCodeBlock;
565 WriteBarrier<SymbolTable> m_moduleEnvironmentSymbolTable;
566 WriteBarrier<ModuleProgramCodeBlock> m_moduleProgramCodeBlock;
569 class FunctionExecutable final : public ScriptExecutable {
571 friend class LLIntOffsetsExtractor;
573 typedef ScriptExecutable Base;
574 static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
576 static FunctionExecutable* create(
577 VM& vm, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable,
578 unsigned firstLine, unsigned lastLine, unsigned startColumn, unsigned endColumn)
580 FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(vm.heap)) FunctionExecutable(vm, source, unlinkedExecutable, firstLine, lastLine, startColumn, endColumn);
581 executable->finishCreation(vm);
584 static FunctionExecutable* fromGlobalCode(
585 const Identifier& name, ExecState&, const SourceCode&,
586 JSObject*& exception, int overrideLineNumber);
588 static void destroy(JSCell*);
590 UnlinkedFunctionExecutable* unlinkedExecutable() const
592 return m_unlinkedExecutable.get();
595 // Returns either call or construct bytecode. This can be appropriate
596 // for answering questions that that don't vary between call and construct --
597 // for example, argumentsRegister().
598 FunctionCodeBlock* eitherCodeBlock()
600 if (m_codeBlockForCall)
601 return m_codeBlockForCall.get();
602 return m_codeBlockForConstruct.get();
605 bool isGeneratedForCall() const
607 return !!m_codeBlockForCall;
610 FunctionCodeBlock* codeBlockForCall()
612 return m_codeBlockForCall.get();
615 bool isGeneratedForConstruct() const
617 return m_codeBlockForConstruct.get();
620 FunctionCodeBlock* codeBlockForConstruct()
622 return m_codeBlockForConstruct.get();
625 bool isGeneratedFor(CodeSpecializationKind kind)
627 if (kind == CodeForCall)
628 return isGeneratedForCall();
629 ASSERT(kind == CodeForConstruct);
630 return isGeneratedForConstruct();
633 FunctionCodeBlock* codeBlockFor(CodeSpecializationKind kind)
635 if (kind == CodeForCall)
636 return codeBlockForCall();
637 ASSERT(kind == CodeForConstruct);
638 return codeBlockForConstruct();
641 FunctionCodeBlock* baselineCodeBlockFor(CodeSpecializationKind);
643 FunctionCodeBlock* profiledCodeBlockFor(CodeSpecializationKind kind)
645 return baselineCodeBlockFor(kind);
648 RefPtr<TypeSet> returnStatementTypeSet()
650 if (!m_returnStatementTypeSet)
651 m_returnStatementTypeSet = TypeSet::create();
653 return m_returnStatementTypeSet;
656 FunctionMode functionMode() { return m_unlinkedExecutable->functionMode(); }
657 bool isBuiltinFunction() const { return m_unlinkedExecutable->isBuiltinFunction(); }
658 ConstructAbility constructAbility() const { return m_unlinkedExecutable->constructAbility(); }
659 bool isArrowFunction() const { return parseMode() == SourceParseMode::ArrowFunctionMode; }
660 bool isDerivedConstructorContext() const { return m_unlinkedExecutable->isDerivedConstructorContext(); }
661 bool isClassConstructorFunction() const { return m_unlinkedExecutable->isClassConstructorFunction(); }
662 const Identifier& name() { return m_unlinkedExecutable->name(); }
663 const Identifier& inferredName() { return m_unlinkedExecutable->inferredName(); }
664 JSString* nameValue() const { return m_unlinkedExecutable->nameValue(); }
665 size_t parameterCount() const { return m_unlinkedExecutable->parameterCount(); } // Excluding 'this'!
666 SourceParseMode parseMode() const { return m_unlinkedExecutable->parseMode(); }
668 static void visitChildren(JSCell*, SlotVisitor&);
669 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
671 return Structure::create(vm, globalObject, proto, TypeInfo(FunctionExecutableType, StructureFlags), info());
674 unsigned parametersStartOffset() const { return m_parametersStartOffset; }
676 void overrideParameterAndTypeProfilingStartEndOffsets(unsigned parametersStartOffset, unsigned typeProfilingStartOffset, unsigned typeProfilingEndOffset)
678 m_parametersStartOffset = parametersStartOffset;
679 m_typeProfilingStartOffset = typeProfilingStartOffset;
680 m_typeProfilingEndOffset = typeProfilingEndOffset;
685 InferredValue* singletonFunction() { return m_singletonFunction.get(); }
688 friend class ExecutableBase;
690 VM&, const SourceCode&, UnlinkedFunctionExecutable*, unsigned firstLine,
691 unsigned lastLine, unsigned startColumn, unsigned endColumn);
693 void finishCreation(VM&);
695 friend class ScriptExecutable;
697 WriteBarrier<UnlinkedFunctionExecutable> m_unlinkedExecutable;
698 WriteBarrier<FunctionCodeBlock> m_codeBlockForCall;
699 WriteBarrier<FunctionCodeBlock> m_codeBlockForConstruct;
700 RefPtr<TypeSet> m_returnStatementTypeSet;
701 unsigned m_parametersStartOffset;
702 WriteBarrier<InferredValue> m_singletonFunction;
705 #if ENABLE(WEBASSEMBLY)
706 class WebAssemblyExecutable final : public ExecutableBase {
708 typedef ExecutableBase Base;
709 static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
711 static WebAssemblyExecutable* create(VM& vm, const SourceCode& source, JSWASMModule* module, unsigned functionIndex)
713 WebAssemblyExecutable* executable = new (NotNull, allocateCell<WebAssemblyExecutable>(vm.heap)) WebAssemblyExecutable(vm, source, module, functionIndex);
714 executable->finishCreation(vm);
718 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
720 return Structure::create(vm, globalObject, proto, TypeInfo(WebAssemblyExecutableType, StructureFlags), info());
723 static void destroy(JSCell*);
727 void prepareForExecution(ExecState*);
729 WebAssemblyCodeBlock* codeBlockForCall()
731 return m_codeBlockForCall.get();
735 friend class ExecutableBase;
736 WebAssemblyExecutable(VM&, const SourceCode&, JSWASMModule*, unsigned functionIndex);
738 static void visitChildren(JSCell*, SlotVisitor&);
741 WriteBarrier<JSWASMModule> m_module;
742 unsigned m_functionIndex;
744 WriteBarrier<WebAssemblyCodeBlock> m_codeBlockForCall;
750 #endif // Executable_h