e053dad977b1a6246ebdf94042cdc038e4a9ba54
[WebKit-https.git] / Source / JavaScriptCore / bytecode / UnlinkedCodeBlock.cpp
1 /*
2  * Copyright (C) 2012, 2013, 2015 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 "UnlinkedCodeBlock.h"
29
30 #include "BytecodeGenerator.h"
31 #include "ClassInfo.h"
32 #include "CodeCache.h"
33 #include "Executable.h"
34 #include "FunctionOverrides.h"
35 #include "JSString.h"
36 #include "JSCInlines.h"
37 #include "Parser.h"
38 #include "SourceProvider.h"
39 #include "Structure.h"
40 #include "SymbolTable.h"
41 #include "UnlinkedInstructionStream.h"
42 #include <wtf/DataLog.h>
43
44 namespace JSC {
45
46 static_assert(sizeof(UnlinkedFunctionExecutable) <= 256, "UnlinkedFunctionExecutable should fit in a 256-byte cell.");
47
48 const ClassInfo UnlinkedFunctionExecutable::s_info = { "UnlinkedFunctionExecutable", 0, 0, CREATE_METHOD_TABLE(UnlinkedFunctionExecutable) };
49 const ClassInfo UnlinkedCodeBlock::s_info = { "UnlinkedCodeBlock", 0, 0, CREATE_METHOD_TABLE(UnlinkedCodeBlock) };
50 const ClassInfo UnlinkedGlobalCodeBlock::s_info = { "UnlinkedGlobalCodeBlock", &Base::s_info, 0, CREATE_METHOD_TABLE(UnlinkedGlobalCodeBlock) };
51 const ClassInfo UnlinkedProgramCodeBlock::s_info = { "UnlinkedProgramCodeBlock", &Base::s_info, 0, CREATE_METHOD_TABLE(UnlinkedProgramCodeBlock) };
52 const ClassInfo UnlinkedEvalCodeBlock::s_info = { "UnlinkedEvalCodeBlock", &Base::s_info, 0, CREATE_METHOD_TABLE(UnlinkedEvalCodeBlock) };
53 const ClassInfo UnlinkedFunctionCodeBlock::s_info = { "UnlinkedFunctionCodeBlock", &Base::s_info, 0, CREATE_METHOD_TABLE(UnlinkedFunctionCodeBlock) };
54
55 static UnlinkedFunctionCodeBlock* generateFunctionCodeBlock(
56     VM& vm, UnlinkedFunctionExecutable* executable, const SourceCode& source,
57     CodeSpecializationKind kind, DebuggerMode debuggerMode, ProfilerMode profilerMode,
58     UnlinkedFunctionKind functionKind, ParserError& error)
59 {
60     JSParserBuiltinMode builtinMode = executable->isBuiltinFunction() ? JSParserBuiltinMode::Builtin : JSParserBuiltinMode::NotBuiltin;
61     JSParserStrictMode strictMode = executable->isInStrictContext() ? JSParserStrictMode::Strict : JSParserStrictMode::NotStrict;
62     std::unique_ptr<FunctionNode> function = parse<FunctionNode>(
63         &vm, source, executable->name(), builtinMode, strictMode, 
64         JSParserCodeType::Function, error, nullptr, executable->parseMode());
65
66     if (!function) {
67         ASSERT(error.isValid());
68         return nullptr;
69     }
70
71     function->finishParsing(executable->name(), executable->functionMode());
72     executable->recordParse(function->features(), function->hasCapturedVariables());
73     
74     UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(&vm, FunctionCode,
75         ExecutableInfo(function->needsActivation(), function->usesEval(), function->isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction, executable->constructorKind()));
76     auto generator(std::make_unique<BytecodeGenerator>(vm, function.get(), result, debuggerMode, profilerMode, executable->parentScopeTDZVariables()));
77     error = generator->generate();
78     if (error.isValid())
79         return nullptr;
80     return result;
81 }
82
83 UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* structure, const SourceCode& source, RefPtr<SourceProvider>&& sourceOverride, FunctionBodyNode* node, UnlinkedFunctionKind kind, VariableEnvironment& parentScopeTDZVariables)
84     : Base(*vm, structure)
85     , m_name(node->ident())
86     , m_inferredName(node->inferredName())
87     , m_sourceOverride(WTF::move(sourceOverride))
88     , m_firstLineOffset(node->firstLine() - source.firstLine())
89     , m_lineCount(node->lastLine() - node->firstLine())
90     , m_unlinkedFunctionNameStart(node->functionNameStart() - source.startOffset())
91     , m_unlinkedBodyStartColumn(node->startColumn())
92     , m_unlinkedBodyEndColumn(m_lineCount ? node->endColumn() : node->endColumn() - node->startColumn())
93     , m_startOffset(node->source().startOffset() - source.startOffset())
94     , m_sourceLength(node->source().length())
95     , m_parametersStartOffset(node->parametersStart())
96     , m_typeProfilingStartOffset(node->functionKeywordStart())
97     , m_typeProfilingEndOffset(node->startStartOffset() + node->source().length() - 1)
98     , m_parameterCount(node->parameterCount())
99     , m_parseMode(node->parseMode())
100     , m_features(0)
101     , m_isInStrictContext(node->isInStrictContext())
102     , m_hasCapturedVariables(false)
103     , m_isBuiltinFunction(kind == UnlinkedBuiltinFunction)
104     , m_constructorKind(static_cast<unsigned>(node->constructorKind()))
105     , m_functionMode(node->functionMode())
106 {
107     ASSERT(m_constructorKind == static_cast<unsigned>(node->constructorKind()));
108     m_parentScopeTDZVariables.swap(parentScopeTDZVariables);
109 }
110
111 void UnlinkedFunctionExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor)
112 {
113     UnlinkedFunctionExecutable* thisObject = jsCast<UnlinkedFunctionExecutable*>(cell);
114     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
115     Base::visitChildren(thisObject, visitor);
116     visitor.append(&thisObject->m_codeBlockForCall);
117     visitor.append(&thisObject->m_codeBlockForConstruct);
118     visitor.append(&thisObject->m_nameValue);
119 }
120
121 FunctionExecutable* UnlinkedFunctionExecutable::link(VM& vm, const SourceCode& ownerSource, int overrideLineNumber)
122 {
123     SourceCode source = m_sourceOverride ? SourceCode(m_sourceOverride) : ownerSource;
124     unsigned firstLine = source.firstLine() + m_firstLineOffset;
125     unsigned startOffset = source.startOffset() + m_startOffset;
126     unsigned lineCount = m_lineCount;
127
128     // Adjust to one-based indexing.
129     bool startColumnIsOnFirstSourceLine = !m_firstLineOffset;
130     unsigned startColumn = m_unlinkedBodyStartColumn + (startColumnIsOnFirstSourceLine ? source.startColumn() : 1);
131     bool endColumnIsOnStartLine = !lineCount;
132     unsigned endColumn = m_unlinkedBodyEndColumn + (endColumnIsOnStartLine ? startColumn : 1);
133
134     SourceCode code(source.provider(), startOffset, startOffset + m_sourceLength, firstLine, startColumn);
135     FunctionOverrides::OverrideInfo overrideInfo;
136     bool hasFunctionOverride = false;
137
138     if (UNLIKELY(Options::functionOverrides())) {
139         hasFunctionOverride = FunctionOverrides::initializeOverrideFor(code, overrideInfo);
140         if (hasFunctionOverride) {
141             firstLine = overrideInfo.firstLine;
142             lineCount = overrideInfo.lineCount;
143             startColumn = overrideInfo.startColumn;
144             endColumn = overrideInfo.endColumn;
145             code = overrideInfo.sourceCode;
146         }
147     }
148
149     FunctionExecutable* result = FunctionExecutable::create(vm, code, this, firstLine, firstLine + lineCount, startColumn, endColumn);
150     if (overrideLineNumber != -1)
151         result->setOverrideLineNumber(overrideLineNumber);
152
153     if (UNLIKELY(hasFunctionOverride)) {
154         result->overrideParameterAndTypeProfilingStartEndOffsets(
155             overrideInfo.parametersStartOffset,
156             overrideInfo.typeProfilingStartOffset,
157             overrideInfo.typeProfilingEndOffset);
158     }
159
160     return result;
161 }
162
163 UnlinkedFunctionExecutable* UnlinkedFunctionExecutable::fromGlobalCode(
164     const Identifier& name, ExecState& exec, const SourceCode& source, 
165     JSObject*& exception, int overrideLineNumber)
166 {
167     ParserError error;
168     VM& vm = exec.vm();
169     CodeCache* codeCache = vm.codeCache();
170     UnlinkedFunctionExecutable* executable = codeCache->getFunctionExecutableFromGlobalCode(vm, name, source, error);
171
172     auto& globalObject = *exec.lexicalGlobalObject();
173     if (globalObject.hasDebugger())
174         globalObject.debugger()->sourceParsed(&exec, source.provider(), error.line(), error.message());
175
176     if (error.isValid()) {
177         exception = error.toErrorObject(&globalObject, source, overrideLineNumber);
178         return nullptr;
179     }
180
181     return executable;
182 }
183
184 UnlinkedFunctionCodeBlock* UnlinkedFunctionExecutable::codeBlockFor(
185     VM& vm, const SourceCode& source, CodeSpecializationKind specializationKind, 
186     DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
187 {
188     switch (specializationKind) {
189     case CodeForCall:
190         if (UnlinkedFunctionCodeBlock* codeBlock = m_codeBlockForCall.get())
191             return codeBlock;
192         break;
193     case CodeForConstruct:
194         if (UnlinkedFunctionCodeBlock* codeBlock = m_codeBlockForConstruct.get())
195             return codeBlock;
196         break;
197     }
198
199     UnlinkedFunctionCodeBlock* result = generateFunctionCodeBlock(
200         vm, this, source, specializationKind, debuggerMode, profilerMode, 
201         isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, 
202         error);
203     
204     if (error.isValid())
205         return nullptr;
206
207     switch (specializationKind) {
208     case CodeForCall:
209         m_codeBlockForCall.set(vm, this, result);
210         break;
211     case CodeForConstruct:
212         m_codeBlockForConstruct.set(vm, this, result);
213         break;
214     }
215     return result;
216 }
217
218 UnlinkedCodeBlock::UnlinkedCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info)
219     : Base(*vm, structure)
220     , m_numVars(0)
221     , m_numCalleeRegisters(0)
222     , m_numParameters(0)
223     , m_vm(vm)
224     , m_globalObjectRegister(VirtualRegister())
225     , m_needsFullScopeChain(info.needsActivation())
226     , m_usesEval(info.usesEval())
227     , m_isStrictMode(info.isStrictMode())
228     , m_isConstructor(info.isConstructor())
229     , m_hasCapturedVariables(false)
230     , m_isBuiltinFunction(info.isBuiltinFunction())
231     , m_constructorKind(static_cast<unsigned>(info.constructorKind()))
232     , m_firstLine(0)
233     , m_lineCount(0)
234     , m_endColumn(UINT_MAX)
235     , m_features(0)
236     , m_codeType(codeType)
237     , m_arrayProfileCount(0)
238     , m_arrayAllocationProfileCount(0)
239     , m_objectAllocationProfileCount(0)
240     , m_valueProfileCount(0)
241     , m_llintCallLinkInfoCount(0)
242 #if ENABLE(BYTECODE_COMMENTS)
243     , m_bytecodeCommentIterator(0)
244 #endif
245 {
246     for (auto& constantRegisterIndex : m_linkTimeConstants)
247         constantRegisterIndex = 0;
248     ASSERT(m_constructorKind == static_cast<unsigned>(info.constructorKind()));
249 }
250
251 void UnlinkedCodeBlock::visitChildren(JSCell* cell, SlotVisitor& visitor)
252 {
253     UnlinkedCodeBlock* thisObject = jsCast<UnlinkedCodeBlock*>(cell);
254     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
255     Base::visitChildren(thisObject, visitor);
256     visitor.append(&thisObject->m_symbolTable);
257     for (FunctionExpressionVector::iterator ptr = thisObject->m_functionDecls.begin(), end = thisObject->m_functionDecls.end(); ptr != end; ++ptr)
258         visitor.append(ptr);
259     for (FunctionExpressionVector::iterator ptr = thisObject->m_functionExprs.begin(), end = thisObject->m_functionExprs.end(); ptr != end; ++ptr)
260         visitor.append(ptr);
261     visitor.appendValues(thisObject->m_constantRegisters.data(), thisObject->m_constantRegisters.size());
262     if (thisObject->m_rareData) {
263         for (size_t i = 0, end = thisObject->m_rareData->m_regexps.size(); i != end; i++)
264             visitor.append(&thisObject->m_rareData->m_regexps[i]);
265     }
266 }
267
268 int UnlinkedCodeBlock::lineNumberForBytecodeOffset(unsigned bytecodeOffset)
269 {
270     ASSERT(bytecodeOffset < instructions().count());
271     int divot;
272     int startOffset;
273     int endOffset;
274     unsigned line;
275     unsigned column;
276     expressionRangeForBytecodeOffset(bytecodeOffset, divot, startOffset, endOffset, line, column);
277     return line;
278 }
279
280 inline void UnlinkedCodeBlock::getLineAndColumn(ExpressionRangeInfo& info,
281     unsigned& line, unsigned& column)
282 {
283     switch (info.mode) {
284     case ExpressionRangeInfo::FatLineMode:
285         info.decodeFatLineMode(line, column);
286         break;
287     case ExpressionRangeInfo::FatColumnMode:
288         info.decodeFatColumnMode(line, column);
289         break;
290     case ExpressionRangeInfo::FatLineAndColumnMode: {
291         unsigned fatIndex = info.position;
292         ExpressionRangeInfo::FatPosition& fatPos = m_rareData->m_expressionInfoFatPositions[fatIndex];
293         line = fatPos.line;
294         column = fatPos.column;
295         break;
296     }
297     } // switch
298 }
299
300 #ifndef NDEBUG
301 static void dumpLineColumnEntry(size_t index, const UnlinkedInstructionStream& instructionStream, unsigned instructionOffset, unsigned line, unsigned column)
302 {
303     const auto& instructions = instructionStream.unpackForDebugging();
304     OpcodeID opcode = instructions[instructionOffset].u.opcode;
305     const char* event = "";
306     if (opcode == op_debug) {
307         switch (instructions[instructionOffset + 1].u.operand) {
308         case WillExecuteProgram: event = " WillExecuteProgram"; break;
309         case DidExecuteProgram: event = " DidExecuteProgram"; break;
310         case DidEnterCallFrame: event = " DidEnterCallFrame"; break;
311         case DidReachBreakpoint: event = " DidReachBreakpoint"; break;
312         case WillLeaveCallFrame: event = " WillLeaveCallFrame"; break;
313         case WillExecuteStatement: event = " WillExecuteStatement"; break;
314         }
315     }
316     dataLogF("  [%zu] pc %u @ line %u col %u : %s%s\n", index, instructionOffset, line, column, opcodeNames[opcode], event);
317 }
318
319 void UnlinkedCodeBlock::dumpExpressionRangeInfo()
320 {
321     Vector<ExpressionRangeInfo>& expressionInfo = m_expressionInfo;
322
323     size_t size = m_expressionInfo.size();
324     dataLogF("UnlinkedCodeBlock %p expressionRangeInfo[%zu] {\n", this, size);
325     for (size_t i = 0; i < size; i++) {
326         ExpressionRangeInfo& info = expressionInfo[i];
327         unsigned line;
328         unsigned column;
329         getLineAndColumn(info, line, column);
330         dumpLineColumnEntry(i, instructions(), info.instructionOffset, line, column);
331     }
332     dataLog("}\n");
333 }
334 #endif
335
336 void UnlinkedCodeBlock::expressionRangeForBytecodeOffset(unsigned bytecodeOffset,
337     int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column)
338 {
339     ASSERT(bytecodeOffset < instructions().count());
340
341     if (!m_expressionInfo.size()) {
342         startOffset = 0;
343         endOffset = 0;
344         divot = 0;
345         line = 0;
346         column = 0;
347         return;
348     }
349
350     Vector<ExpressionRangeInfo>& expressionInfo = m_expressionInfo;
351
352     int low = 0;
353     int high = expressionInfo.size();
354     while (low < high) {
355         int mid = low + (high - low) / 2;
356         if (expressionInfo[mid].instructionOffset <= bytecodeOffset)
357             low = mid + 1;
358         else
359             high = mid;
360     }
361
362     if (!low)
363         low = 1;
364
365     ExpressionRangeInfo& info = expressionInfo[low - 1];
366     startOffset = info.startOffset;
367     endOffset = info.endOffset;
368     divot = info.divotPoint;
369     getLineAndColumn(info, line, column);
370 }
371
372 void UnlinkedCodeBlock::addExpressionInfo(unsigned instructionOffset,
373     int divot, int startOffset, int endOffset, unsigned line, unsigned column)
374 {
375     if (divot > ExpressionRangeInfo::MaxDivot) {
376         // Overflow has occurred, we can only give line number info for errors for this region
377         divot = 0;
378         startOffset = 0;
379         endOffset = 0;
380     } else if (startOffset > ExpressionRangeInfo::MaxOffset) {
381         // If the start offset is out of bounds we clear both offsets
382         // so we only get the divot marker. Error message will have to be reduced
383         // to line and charPosition number.
384         startOffset = 0;
385         endOffset = 0;
386     } else if (endOffset > ExpressionRangeInfo::MaxOffset) {
387         // The end offset is only used for additional context, and is much more likely
388         // to overflow (eg. function call arguments) so we are willing to drop it without
389         // dropping the rest of the range.
390         endOffset = 0;
391     }
392
393     unsigned positionMode =
394         (line <= ExpressionRangeInfo::MaxFatLineModeLine && column <= ExpressionRangeInfo::MaxFatLineModeColumn) 
395         ? ExpressionRangeInfo::FatLineMode
396         : (line <= ExpressionRangeInfo::MaxFatColumnModeLine && column <= ExpressionRangeInfo::MaxFatColumnModeColumn)
397         ? ExpressionRangeInfo::FatColumnMode
398         : ExpressionRangeInfo::FatLineAndColumnMode;
399
400     ExpressionRangeInfo info;
401     info.instructionOffset = instructionOffset;
402     info.divotPoint = divot;
403     info.startOffset = startOffset;
404     info.endOffset = endOffset;
405
406     info.mode = positionMode;
407     switch (positionMode) {
408     case ExpressionRangeInfo::FatLineMode:
409         info.encodeFatLineMode(line, column);
410         break;
411     case ExpressionRangeInfo::FatColumnMode:
412         info.encodeFatColumnMode(line, column);
413         break;
414     case ExpressionRangeInfo::FatLineAndColumnMode: {
415         createRareDataIfNecessary();
416         unsigned fatIndex = m_rareData->m_expressionInfoFatPositions.size();
417         ExpressionRangeInfo::FatPosition fatPos = { line, column };
418         m_rareData->m_expressionInfoFatPositions.append(fatPos);
419         info.position = fatIndex;
420     }
421     } // switch
422
423     m_expressionInfo.append(info);
424 }
425
426 bool UnlinkedCodeBlock::typeProfilerExpressionInfoForBytecodeOffset(unsigned bytecodeOffset, unsigned& startDivot, unsigned& endDivot)
427 {
428     static const bool verbose = false;
429     auto iter = m_typeProfilerInfoMap.find(bytecodeOffset);
430     if (iter == m_typeProfilerInfoMap.end()) {
431         if (verbose)
432             dataLogF("Don't have assignment info for offset:%u\n", bytecodeOffset);
433         startDivot = UINT_MAX;
434         endDivot = UINT_MAX;
435         return false;
436     }
437     
438     TypeProfilerExpressionRange& range = iter->value;
439     startDivot = range.m_startDivot;
440     endDivot = range.m_endDivot;
441     return true;
442 }
443
444 void UnlinkedCodeBlock::addTypeProfilerExpressionInfo(unsigned instructionOffset, unsigned startDivot, unsigned endDivot)
445 {
446     TypeProfilerExpressionRange range;
447     range.m_startDivot = startDivot;
448     range.m_endDivot = endDivot;
449     m_typeProfilerInfoMap.set(instructionOffset, range);  
450 }
451
452 void UnlinkedProgramCodeBlock::visitChildren(JSCell* cell, SlotVisitor& visitor)
453 {
454     UnlinkedProgramCodeBlock* thisObject = jsCast<UnlinkedProgramCodeBlock*>(cell);
455     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
456     Base::visitChildren(thisObject, visitor);
457 }
458
459 UnlinkedCodeBlock::~UnlinkedCodeBlock()
460 {
461 }
462
463 void UnlinkedProgramCodeBlock::destroy(JSCell* cell)
464 {
465     jsCast<UnlinkedProgramCodeBlock*>(cell)->~UnlinkedProgramCodeBlock();
466 }
467
468 void UnlinkedEvalCodeBlock::destroy(JSCell* cell)
469 {
470     jsCast<UnlinkedEvalCodeBlock*>(cell)->~UnlinkedEvalCodeBlock();
471 }
472
473 void UnlinkedFunctionCodeBlock::destroy(JSCell* cell)
474 {
475     jsCast<UnlinkedFunctionCodeBlock*>(cell)->~UnlinkedFunctionCodeBlock();
476 }
477
478 void UnlinkedFunctionExecutable::destroy(JSCell* cell)
479 {
480     jsCast<UnlinkedFunctionExecutable*>(cell)->~UnlinkedFunctionExecutable();
481 }
482
483 void UnlinkedCodeBlock::setInstructions(std::unique_ptr<UnlinkedInstructionStream> instructions)
484 {
485     m_unlinkedInstructions = WTF::move(instructions);
486 }
487
488 const UnlinkedInstructionStream& UnlinkedCodeBlock::instructions() const
489 {
490     ASSERT(m_unlinkedInstructions.get());
491     return *m_unlinkedInstructions;
492 }
493
494 }
495