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(ExecState* exec, const SourceCode& source)
46 : Base(exec->vm().moduleProgramExecutableStructure.get(), exec->vm(), source, false, DerivedContextType::None, false, EvalContextType::None, NoIntrinsic)
47{
48 ASSERT(source.provider()->sourceType() == SourceProviderSourceType::Module);
49 VM& vm = exec->vm();
50 if (vm.typeProfiler() || vm.controlFlowProfiler())
51 vm.functionHasExecutedCache()->insertUnexecutedRange(sourceID(), typeProfilingStartOffset(vm), typeProfilingEndOffset(vm));
52}
53
54ModuleProgramExecutable* ModuleProgramExecutable::create(ExecState* exec, const SourceCode& source)
55{
56 VM& vm = exec->vm();
57 auto scope = DECLARE_THROW_SCOPE(vm);
58
59 JSGlobalObject* globalObject = exec->lexicalGlobalObject();
60 ModuleProgramExecutable* executable = new (NotNull, allocateCell<ModuleProgramExecutable>(vm.heap)) ModuleProgramExecutable(exec, source);
61 executable->finishCreation(exec->vm());
62
63 ParserError error;
64 OptionSet<CodeGenerationMode> codeGenerationMode = globalObject->defaultCodeGenerationMode();
65 UnlinkedModuleProgramCodeBlock* unlinkedModuleProgramCode = vm.codeCache()->getUnlinkedModuleProgramCodeBlock(
66 vm, executable, executable->source(), codeGenerationMode, error);
67
68 if (globalObject->hasDebugger())
69 globalObject->debugger()->sourceParsed(exec, executable->source().provider(), error.line(), error.message());
70
71 if (error.isValid()) {
72 throwVMError(exec, scope, error.toErrorObject(globalObject, executable->source()));
73 return nullptr;
74 }
75
76 executable->m_unlinkedModuleProgramCodeBlock.set(exec->vm(), executable, unlinkedModuleProgramCode);
77
78 executable->m_moduleEnvironmentSymbolTable.set(exec->vm(), executable, jsCast<SymbolTable*>(unlinkedModuleProgramCode->constantRegister(unlinkedModuleProgramCode->moduleEnvironmentSymbolTableConstantRegisterOffset()).get())->cloneScopePart(exec->vm()));
79
80 return executable;
81}
82
83void ModuleProgramExecutable::destroy(JSCell* cell)
84{
85 static_cast<ModuleProgramExecutable*>(cell)->ModuleProgramExecutable::~ModuleProgramExecutable();
86}
87
88auto ModuleProgramExecutable::ensureTemplateObjectMap(VM&) -> TemplateObjectMap&
89{
90 return ensureTemplateObjectMapImpl(m_templateObjectMap);
91}
92
93void ModuleProgramExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor)
94{
95 ModuleProgramExecutable* thisObject = jsCast<ModuleProgramExecutable*>(cell);
96 ASSERT_GC_OBJECT_INHERITS(thisObject, info());
97 Base::visitChildren(thisObject, visitor);
98 visitor.append(thisObject->m_unlinkedModuleProgramCodeBlock);
99 visitor.append(thisObject->m_moduleEnvironmentSymbolTable);
100 visitor.append(thisObject->m_moduleProgramCodeBlock);
101 if (TemplateObjectMap* map = thisObject->m_templateObjectMap.get()) {
102 auto locker = holdLock(thisObject->cellLock());
103 for (auto& entry : *map)
104 visitor.append(entry.value);
105 }
106}
107
108} // namespace JSC
109