1/*
2 * Copyright (C) 2009, 2010, 2013, 2015-2016 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#include "config.h"
27
28#include "BatchedTransitionOptimizer.h"
29#include "CodeBlock.h"
30#include "CodeCache.h"
31#include "Debugger.h"
32#include "JIT.h"
33#include "JSCInlines.h"
34#include "LLIntEntrypoint.h"
35#include "ModuleProgramCodeBlock.h"
36#include "Parser.h"
37#include "TypeProfiler.h"
38#include "VMInlines.h"
39#include <wtf/CommaPrinter.h>
40
41namespace JSC {
42
43const ClassInfo ModuleProgramExecutable::s_info = { "ModuleProgramExecutable", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(ModuleProgramExecutable) };
44
45ModuleProgramExecutable::ModuleProgramExecutable(JSGlobalObject* globalObject, const SourceCode& source)
46 : Base(globalObject->vm().moduleProgramExecutableStructure.get(), globalObject->vm(), source, false, DerivedContextType::None, false, EvalContextType::None, NoIntrinsic)
47{
48 ASSERT(source.provider()->sourceType() == SourceProviderSourceType::Module);
49 VM& vm = globalObject->vm();
50 if (vm.typeProfiler() || vm.controlFlowProfiler())
51 vm.functionHasExecutedCache()->insertUnexecutedRange(sourceID(), typeProfilingStartOffset(vm), typeProfilingEndOffset(vm));
52}
53
54ModuleProgramExecutable* ModuleProgramExecutable::create(JSGlobalObject* globalObject, const SourceCode& source)
55{
56 VM& vm = globalObject->vm();
57 auto scope = DECLARE_THROW_SCOPE(vm);
58
59 ModuleProgramExecutable* executable = new (NotNull, allocateCell<ModuleProgramExecutable>(vm.heap)) ModuleProgramExecutable(globalObject, source);
60 executable->finishCreation(globalObject->vm());
61
62 ParserError error;
63 OptionSet<CodeGenerationMode> codeGenerationMode = globalObject->defaultCodeGenerationMode();
64 UnlinkedModuleProgramCodeBlock* unlinkedModuleProgramCode = vm.codeCache()->getUnlinkedModuleProgramCodeBlock(
65 vm, executable, executable->source(), codeGenerationMode, error);
66
67 if (globalObject->hasDebugger())
68 globalObject->debugger()->sourceParsed(globalObject, executable->source().provider(), error.line(), error.message());
69
70 if (error.isValid()) {
71 throwVMError(globalObject, scope, error.toErrorObject(globalObject, executable->source()));
72 return nullptr;
73 }
74
75 executable->m_unlinkedModuleProgramCodeBlock.set(globalObject->vm(), executable, unlinkedModuleProgramCode);
76
77 executable->m_moduleEnvironmentSymbolTable.set(globalObject->vm(), executable, jsCast<SymbolTable*>(unlinkedModuleProgramCode->constantRegister(unlinkedModuleProgramCode->moduleEnvironmentSymbolTableConstantRegisterOffset()).get())->cloneScopePart(globalObject->vm()));
78
79 return executable;
80}
81
82void ModuleProgramExecutable::destroy(JSCell* cell)
83{
84 static_cast<ModuleProgramExecutable*>(cell)->ModuleProgramExecutable::~ModuleProgramExecutable();
85}
86
87auto ModuleProgramExecutable::ensureTemplateObjectMap(VM&) -> TemplateObjectMap&
88{
89 return ensureTemplateObjectMapImpl(m_templateObjectMap);
90}
91
92void ModuleProgramExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor)
93{
94 ModuleProgramExecutable* thisObject = jsCast<ModuleProgramExecutable*>(cell);
95 ASSERT_GC_OBJECT_INHERITS(thisObject, info());
96 Base::visitChildren(thisObject, visitor);
97 visitor.append(thisObject->m_unlinkedModuleProgramCodeBlock);
98 visitor.append(thisObject->m_moduleEnvironmentSymbolTable);
99 visitor.append(thisObject->m_moduleProgramCodeBlock);
100 if (TemplateObjectMap* map = thisObject->m_templateObjectMap.get()) {
101 auto locker = holdLock(thisObject->cellLock());
102 for (auto& entry : *map)
103 visitor.append(entry.value);
104 }
105}
106
107} // namespace JSC
108