Modified: trunk/Source/WebCore/contentextensions/DFABytecodeCompiler.cpp (185620 => 185621)
--- trunk/Source/WebCore/contentextensions/DFABytecodeCompiler.cpp 2015-06-16 22:18:39 UTC (rev 185620)
+++ trunk/Source/WebCore/contentextensions/DFABytecodeCompiler.cpp 2015-06-16 22:29:19 UTC (rev 185621)
@@ -43,15 +43,40 @@
*reinterpret_cast<IntType*>(&bytecode[bytecode.size() - sizeof(IntType)]) = value;
}
-inline void set32Bits(Vector<DFABytecode>& bytecode, uint32_t index, uint32_t value)
+inline void appendZeroes(Vector<DFABytecode>& bytecode, DFABytecodeJumpSize jumpSize)
{
- *reinterpret_cast<uint32_t*>(&bytecode[index]) = value;
+ switch (jumpSize) {
+ case DFABytecodeJumpSize::Int8:
+ append<int8_t>(bytecode, 0); // This value will be set when linking.
+ break;
+ case DFABytecodeJumpSize::Int16:
+ append<int16_t>(bytecode, 0); // This value will be set when linking.
+ break;
+ case DFABytecodeJumpSize::Int32:
+ append<int32_t>(bytecode, 0); // This value will be set when linking.
+ break;
+ }
}
+template <typename IntType>
+inline void setBits(Vector<DFABytecode>& bytecode, uint32_t index, IntType value)
+{
+ RELEASE_ASSERT(index + sizeof(IntType) <= bytecode.size());
+ ASSERT_WITH_MESSAGE(!*reinterpret_cast<IntType*>(&bytecode[index]), "Right now we should only be using setBits to overwrite values that were zero as a placeholder.");
+ *reinterpret_cast<IntType*>(&bytecode[index]) = value;
+}
+
+static unsigned appendActionBytecodeSize(uint64_t action)
+{
+ if (action & ActionFlagMask)
+ return sizeof(DFABytecodeInstruction) + sizeof(uint16_t) + sizeof(uint32_t);
+ return sizeof(DFABytecodeInstruction) + sizeof(uint32_t);
+}
+
void DFABytecodeCompiler::emitAppendAction(uint64_t action)
{
// High bits are used to store flags. See compileRuleList.
- if (action & 0xFFFF00000000) {
+ if (action & ActionFlagMask) {
ASSERT(!(action & DisplayNoneStyleSheetFlag));
if (action & IfDomainFlag)
append<DFABytecodeInstruction>(m_bytecode, DFABytecodeInstruction::TestFlagsAndAppendActionWithIfDomain);
@@ -71,30 +96,62 @@
}
}
-void DFABytecodeCompiler::emitJump(uint32_t destinationNodeIndex)
+int32_t DFABytecodeCompiler::longestPossibleJump(uint32_t instructionLocation, uint32_t sourceNodeIndex, uint32_t destinationNodeIndex)
{
- append<DFABytecodeInstruction>(m_bytecode, DFABytecodeInstruction::Jump);
- m_linkRecords.append(std::make_pair(m_bytecode.size(), destinationNodeIndex));
- append<uint32_t>(m_bytecode, 0); // This value will be set when linking.
+ if (m_nodeStartOffsets[destinationNodeIndex] == std::numeric_limits<uint32_t>::max()) {
+ // Jumping to a node that hasn't been compiled yet, we don't know exactly how far forward we will need to jump,
+ // so make sure we have enough room for the worst possible case, the farthest possible jump
+ // which would be the distance if there were no compacted branches between this jump and its destination.
+ ASSERT(instructionLocation >= m_nodeStartOffsets[sourceNodeIndex]);
+ ASSERT(m_maxNodeStartOffsets[destinationNodeIndex] > m_maxNodeStartOffsets[sourceNodeIndex]);
+ ASSERT(m_nodeStartOffsets[sourceNodeIndex] != std::numeric_limits<uint32_t>::max());
+ return m_maxNodeStartOffsets[destinationNodeIndex] - m_maxNodeStartOffsets[sourceNodeIndex] - (m_nodeStartOffsets[sourceNodeIndex] - instructionLocation);
+ }
+
+ // Jumping to an already compiled node, we already know exactly where we will need to jump to.
+ ASSERT(m_nodeStartOffsets[destinationNodeIndex] <= instructionLocation);
+ return m_nodeStartOffsets[destinationNodeIndex] - instructionLocation;
}
+
+void DFABytecodeCompiler::emitJump(uint32_t sourceNodeIndex, uint32_t destinationNodeIndex)
+{
+ uint32_t instructionLocation = m_bytecode.size();
+ uint32_t jumpLocation = instructionLocation + sizeof(uint8_t);
+ int32_t longestPossibleJumpDistance = longestPossibleJump(instructionLocation, sourceNodeIndex, destinationNodeIndex);
+ DFABytecodeJumpSize jumpSize = smallestPossibleJumpSize(longestPossibleJumpDistance);
+ append<uint8_t>(m_bytecode, static_cast<uint8_t>(DFABytecodeInstruction::Jump) | jumpSize);
-void DFABytecodeCompiler::emitCheckValue(uint8_t value, uint32_t destinationNodeIndex, bool caseSensitive)
+ m_linkRecords.append(LinkRecord({jumpSize, longestPossibleJumpDistance, instructionLocation, jumpLocation, destinationNodeIndex}));
+ appendZeroes(m_bytecode, jumpSize);
+}
+
+void DFABytecodeCompiler::emitCheckValue(uint8_t value, uint32_t sourceNodeIndex, uint32_t destinationNodeIndex, bool caseSensitive)
{
- append<DFABytecodeInstruction>(m_bytecode, caseSensitive ? DFABytecodeInstruction::CheckValueCaseSensitive : DFABytecodeInstruction::CheckValueCaseInsensitive);
+ uint32_t instructionLocation = m_bytecode.size();
+ uint32_t jumpLocation = instructionLocation + 2 * sizeof(uint8_t);
+ int32_t longestPossibleJumpDistance = longestPossibleJump(instructionLocation, sourceNodeIndex, destinationNodeIndex);
+ DFABytecodeJumpSize jumpSize = smallestPossibleJumpSize(longestPossibleJumpDistance);
+ DFABytecodeInstruction instruction = caseSensitive ? DFABytecodeInstruction::CheckValueCaseSensitive : DFABytecodeInstruction::CheckValueCaseInsensitive;
+ append<uint8_t>(m_bytecode, static_cast<uint8_t>(instruction) | jumpSize);
append<uint8_t>(m_bytecode, value);
- m_linkRecords.append(std::make_pair(m_bytecode.size(), destinationNodeIndex));
- append<uint32_t>(m_bytecode, 0); // This value will be set when linking.
+ m_linkRecords.append(LinkRecord({jumpSize, longestPossibleJumpDistance, instructionLocation, jumpLocation, destinationNodeIndex}));
+ appendZeroes(m_bytecode, jumpSize);
}
-void DFABytecodeCompiler::emitCheckValueRange(uint8_t lowValue, uint8_t highValue, uint32_t destinationNodeIndex, bool caseSensitive)
+void DFABytecodeCompiler::emitCheckValueRange(uint8_t lowValue, uint8_t highValue, uint32_t sourceNodeIndex, uint32_t destinationNodeIndex, bool caseSensitive)
{
ASSERT_WITH_MESSAGE(lowValue < highValue, "The instruction semantic impose lowValue is strictly less than highValue.");
- append<DFABytecodeInstruction>(m_bytecode, caseSensitive ? DFABytecodeInstruction::CheckValueRangeCaseSensitive : DFABytecodeInstruction::CheckValueRangeCaseInsensitive);
+ uint32_t instructionLocation = m_bytecode.size();
+ uint32_t jumpLocation = instructionLocation + 3 * sizeof(uint8_t);
+ int32_t longestPossibleJumpDistance = longestPossibleJump(instructionLocation, sourceNodeIndex, destinationNodeIndex);
+ DFABytecodeJumpSize jumpSize = smallestPossibleJumpSize(longestPossibleJumpDistance);
+ DFABytecodeInstruction instruction = caseSensitive ? DFABytecodeInstruction::CheckValueRangeCaseSensitive : DFABytecodeInstruction::CheckValueRangeCaseInsensitive;
+ append<uint8_t>(m_bytecode, static_cast<uint8_t>(instruction) | jumpSize);
append<uint8_t>(m_bytecode, lowValue);
append<uint8_t>(m_bytecode, highValue);
- m_linkRecords.append(std::make_pair(m_bytecode.size(), destinationNodeIndex));
- append<uint32_t>(m_bytecode, 0); // This value will be set when linking.
+ m_linkRecords.append(LinkRecord({jumpSize, longestPossibleJumpDistance, instructionLocation, jumpLocation, destinationNodeIndex}));
+ appendZeroes(m_bytecode, jumpSize);
}
void DFABytecodeCompiler::emitTerminate()
@@ -104,9 +161,11 @@
void DFABytecodeCompiler::compileNode(uint32_t index, bool root)
{
+ unsigned startSize = m_bytecode.size();
+
const DFANode& node = m_dfa.nodes[index];
if (node.isKilled()) {
- m_nodeStartOffsets[index] = std::numeric_limits<uint32_t>::max();
+ ASSERT(m_nodeStartOffsets[index] == std::numeric_limits<uint32_t>::max());
return;
}
@@ -122,10 +181,24 @@
if (root)
m_nodeStartOffsets[index] = m_bytecode.size();
- compileNodeTransitions(node);
+ compileNodeTransitions(index);
+
+ ASSERT_UNUSED(startSize, m_bytecode.size() - startSize <= compiledNodeMaxBytecodeSize(index));
}
+
+unsigned DFABytecodeCompiler::compiledNodeMaxBytecodeSize(uint32_t index)
+{
+ const DFANode& node = m_dfa.nodes[index];
+ if (node.isKilled())
+ return 0;
+ unsigned size = 0;
+ for (uint64_t action : node.actions(m_dfa))
+ size += appendActionBytecodeSize(action);
+ size += nodeTransitionsMaxBytecodeSize(node);
+ return size;
+}
-void DFABytecodeCompiler::compileNodeTransitions(const DFANode& node)
+Vector<DFABytecodeCompiler::Range> DFABytecodeCompiler::ranges(const DFANode& node)
{
uint32_t destinations[128];
memset(destinations, 0xff, sizeof(destinations));
@@ -187,52 +260,119 @@
// If a range goes to 127, there will never be values higher than it, so checking for case-insensitive ranges would always fail.
ranges.append(Range(rangeMin, 127, destinations[rangeMin], true));
}
-
- for (const auto& range : ranges)
- compileCheckForRange(range);
- if (node.hasFallbackTransition())
- emitJump(node.fallbackTransitionDestination(m_dfa));
- else
- emitTerminate();
+ return ranges;
}
+
+unsigned DFABytecodeCompiler::checkForRangeMaxBytecodeSize(const Range& range)
+{
+ if (range.min == range.max)
+ return sizeof(DFABytecodeInstruction::CheckValueCaseInsensitive) + sizeof(uint8_t) + sizeof(uint32_t);
+ return sizeof(DFABytecodeInstruction::CheckValueRangeCaseInsensitive) + 2 * sizeof(uint8_t) + sizeof(uint32_t);
+}
-void DFABytecodeCompiler::compileCheckForRange(const Range& range)
+void DFABytecodeCompiler::compileCheckForRange(uint32_t nodeIndex, const Range& range)
{
+ unsigned startSize = m_bytecode.size();
ASSERT_WITH_MESSAGE(range.max < 128, "The DFA engine only supports the ASCII alphabet.");
ASSERT(range.min <= range.max);
if (range.min == range.max)
- emitCheckValue(range.min, range.destination, range.caseSensitive);
+ emitCheckValue(range.min, nodeIndex, range.destination, range.caseSensitive);
else
- emitCheckValueRange(range.min, range.max, range.destination, range.caseSensitive);
+ emitCheckValueRange(range.min, range.max, nodeIndex, range.destination, range.caseSensitive);
+
+ ASSERT_UNUSED(startSize, m_bytecode.size() - startSize <= checkForRangeMaxBytecodeSize(range));
}
+unsigned DFABytecodeCompiler::nodeTransitionsMaxBytecodeSize(const DFANode& node)
+{
+ unsigned size = 0;
+ for (const auto& range : ranges(node))
+ size += checkForRangeMaxBytecodeSize(range);
+ if (node.hasFallbackTransition())
+ size += sizeof(DFABytecodeInstruction::Jump) + sizeof(uint32_t);
+ else
+ size += instructionSizeWithArguments(DFABytecodeInstruction::Terminate);
+ return size;
+}
+
+void DFABytecodeCompiler::compileNodeTransitions(uint32_t nodeIndex)
+{
+ const DFANode& node = m_dfa.nodes[nodeIndex];
+ unsigned startSize = m_bytecode.size();
+
+ for (const auto& range : ranges(node))
+ compileCheckForRange(nodeIndex, range);
+ if (node.hasFallbackTransition())
+ emitJump(nodeIndex, node.fallbackTransitionDestination(m_dfa));
+ else
+ emitTerminate();
+
+ ASSERT_UNUSED(startSize, m_bytecode.size() - startSize <= nodeTransitionsMaxBytecodeSize(node));
+}
+
void DFABytecodeCompiler::compile()
{
- // DFA header.
uint32_t startLocation = m_bytecode.size();
- append<uint32_t>(m_bytecode, 0);
+ append<DFAHeader>(m_bytecode, 0); // This will be set when we are finished compiling this DFA.
+
m_nodeStartOffsets.resize(m_dfa.nodes.size());
+ for (unsigned i = 0; i < m_dfa.nodes.size(); ++i)
+ m_nodeStartOffsets[i] = std::numeric_limits<uint32_t>::max();
+ // Populate m_maxNodeStartOffsets with a worst-case index of where the node would be with no branch compaction.
+ // Compacting the branches using 1-4 byte signed jump distances should only make nodes closer together than this.
+ ASSERT(m_maxNodeStartOffsets.isEmpty());
+ m_maxNodeStartOffsets.clear();
+ m_maxNodeStartOffsets.resize(m_dfa.nodes.size());
+ unsigned rootActionsSize = 0;
+ for (uint64_t action : m_dfa.nodes[m_dfa.root].actions(m_dfa))
+ rootActionsSize += appendActionBytecodeSize(action);
+ m_maxNodeStartOffsets[m_dfa.root] = sizeof(DFAHeader) + rootActionsSize;
+ unsigned nextIndex = sizeof(DFAHeader) + compiledNodeMaxBytecodeSize(m_dfa.root);
+ for (uint32_t i = 0; i < m_dfa.nodes.size(); i++) {
+ if (i != m_dfa.root) {
+ m_maxNodeStartOffsets[i] = nextIndex;
+ nextIndex += compiledNodeMaxBytecodeSize(i);
+ }
+ }
+
// Make sure the root is always at the beginning of the bytecode.
compileNode(m_dfa.root, true);
for (uint32_t i = 0; i < m_dfa.nodes.size(); i++) {
if (i != m_dfa.root)
compileNode(i, false);
}
+
+ ASSERT(m_maxNodeStartOffsets.size() == m_nodeStartOffsets.size());
+ for (unsigned i = 0; i < m_dfa.nodes.size(); ++i) {
+ if (m_nodeStartOffsets[i] != std::numeric_limits<uint32_t>::max())
+ ASSERT(m_maxNodeStartOffsets[i] >= m_nodeStartOffsets[i]);
+ }
// Link.
for (const auto& linkRecord : m_linkRecords) {
- uint32_t offset = linkRecord.first;
- ASSERT(!(*reinterpret_cast<uint32_t*>(&m_bytecode[offset])));
-
- uint32_t target = m_nodeStartOffsets[linkRecord.second];
- RELEASE_ASSERT(target != std::numeric_limits<uint32_t>::max());
- set32Bits(m_bytecode, offset, m_nodeStartOffsets[linkRecord.second]);
+ uint32_t destination = m_nodeStartOffsets[linkRecord.destinationNodeIndex];
+ RELEASE_ASSERT(destination < std::numeric_limits<int32_t>::max());
+ int32_t distance = destination - linkRecord.instructionLocation;
+ ASSERT(abs(distance) <= abs(linkRecord.longestPossibleJump));
+
+ switch (linkRecord.jumpSize) {
+ case Int8:
+ RELEASE_ASSERT(distance == static_cast<int8_t>(distance));
+ setBits<int8_t>(m_bytecode, linkRecord.jumpLocation, static_cast<int8_t>(distance));
+ break;
+ case Int16:
+ RELEASE_ASSERT(distance == static_cast<int16_t>(distance));
+ setBits<int16_t>(m_bytecode, linkRecord.jumpLocation, static_cast<int16_t>(distance));
+ break;
+ case Int32:
+ setBits<int32_t>(m_bytecode, linkRecord.jumpLocation, distance);
+ break;
+ }
}
- // Set size header.
- set32Bits(m_bytecode, startLocation, m_bytecode.size() - startLocation);
+ setBits<DFAHeader>(m_bytecode, startLocation, m_bytecode.size() - startLocation);
}
} // namespace ContentExtensions
Modified: trunk/Source/WebCore/contentextensions/DFABytecodeInterpreter.cpp (185620 => 185621)
--- trunk/Source/WebCore/contentextensions/DFABytecodeInterpreter.cpp 2015-06-16 22:18:39 UTC (rev 185620)
+++ trunk/Source/WebCore/contentextensions/DFABytecodeInterpreter.cpp 2015-06-16 22:29:19 UTC (rev 185621)
@@ -36,10 +36,10 @@
namespace ContentExtensions {
template <typename IntType>
-static inline IntType getBits(const DFABytecode* bytecode, unsigned bytecodeLength, unsigned index, Vector<bool>& pagesUsed)
+static inline IntType getBits(const DFABytecode* bytecode, uint32_t bytecodeLength, uint32_t index, Vector<bool>& pagesUsed)
{
#if CONTENT_EXTENSIONS_MEMORY_REPORTING
- unsigned page = index / CONTENT_EXTENSIONS_PAGE_SIZE;
+ uint32_t page = index / CONTENT_EXTENSIONS_PAGE_SIZE;
while (pagesUsed.size() < (bytecodeLength + CONTENT_EXTENSIONS_PAGE_SIZE - 1) / CONTENT_EXTENSIONS_PAGE_SIZE)
pagesUsed.append(false);
pagesUsed[page] = true;
@@ -49,23 +49,64 @@
ASSERT_UNUSED(bytecodeLength, index + sizeof(IntType) <= bytecodeLength);
return *reinterpret_cast<const IntType*>(&bytecode[index]);
}
-
-void DFABytecodeInterpreter::interpretAppendAction(unsigned& programCounter, Actions& actions, bool ifDomain)
+
+// FIXME: Get rid of pagesUsed. We don't need to keep track of the pages used.
+static inline DFABytecodeInstruction getInstruction(const DFABytecode* bytecode, uint32_t bytecodeLength, uint32_t index, Vector<bool>& pagesUsed)
{
- ASSERT(getBits<DFABytecodeInstruction>(m_bytecode, m_bytecodeLength, programCounter, m_pagesUsed) == DFABytecodeInstruction::AppendAction
- || getBits<DFABytecodeInstruction>(m_bytecode, m_bytecodeLength, programCounter, m_pagesUsed) == DFABytecodeInstruction::AppendActionWithIfDomain
- || getBits<DFABytecodeInstruction>(m_bytecode, m_bytecodeLength, programCounter, m_pagesUsed) == DFABytecodeInstruction::AppendActionDefaultStylesheet);
- actions.add((ifDomain ? IfDomainFlag : 0) | static_cast<uint64_t>(getBits<unsigned>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode), m_pagesUsed)));
+ return static_cast<DFABytecodeInstruction>(getBits<uint8_t>(bytecode, bytecodeLength, index, pagesUsed) & DFABytecodeInstructionMask);
+}
+
+static inline size_t jumpSizeInBytes(DFABytecodeJumpSize jumpSize)
+{
+ switch (jumpSize) {
+ case Int8:
+ return sizeof(int8_t);
+ case Int16:
+ return sizeof(int16_t);
+ case Int32:
+ return sizeof(int32_t);
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+}
+
+static inline DFABytecodeJumpSize getJumpSize(const DFABytecode* bytecode, uint32_t bytecodeLength, uint32_t index, Vector<bool>& pagesUsed)
+{
+ DFABytecodeJumpSize jumpSize = static_cast<DFABytecodeJumpSize>(getBits<uint8_t>(bytecode, bytecodeLength, index, pagesUsed) & DFABytecodeJumpSizeMask);
+ ASSERT(jumpSize == DFABytecodeJumpSize::Int32 || jumpSize == DFABytecodeJumpSize::Int16 || jumpSize == DFABytecodeJumpSize::Int8);
+ return jumpSize;
+}
+
+static inline int32_t getJumpDistance(const DFABytecode* bytecode, uint32_t bytecodeLength, uint32_t index, Vector<bool>& pagesUsed, DFABytecodeJumpSize jumpSize)
+{
+ switch (jumpSize) {
+ case Int8:
+ return getBits<int8_t>(bytecode, bytecodeLength, index, pagesUsed);
+ case Int16:
+ return getBits<int16_t>(bytecode, bytecodeLength, index, pagesUsed);
+ case Int32:
+ return getBits<int32_t>(bytecode, bytecodeLength, index, pagesUsed);
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+}
+
+void DFABytecodeInterpreter::interpretAppendAction(uint32_t& programCounter, Actions& actions, bool ifDomain)
+{
+ ASSERT(getInstruction(m_bytecode, m_bytecodeLength, programCounter, m_pagesUsed) == DFABytecodeInstruction::AppendAction
+ || getInstruction(m_bytecode, m_bytecodeLength, programCounter, m_pagesUsed) == DFABytecodeInstruction::AppendActionWithIfDomain
+ || getInstruction(m_bytecode, m_bytecodeLength, programCounter, m_pagesUsed) == DFABytecodeInstruction::AppendActionDefaultStylesheet);
+ actions.add((ifDomain ? IfDomainFlag : 0) | static_cast<uint64_t>(getBits<uint32_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecodeInstruction), m_pagesUsed)));
programCounter += instructionSizeWithArguments(DFABytecodeInstruction::AppendAction);
ASSERT(instructionSizeWithArguments(DFABytecodeInstruction::AppendAction) == instructionSizeWithArguments(DFABytecodeInstruction::AppendActionWithIfDomain));
ASSERT(instructionSizeWithArguments(DFABytecodeInstruction::AppendAction) == instructionSizeWithArguments(DFABytecodeInstruction::AppendActionDefaultStylesheet));
}
-void DFABytecodeInterpreter::interpretTestFlagsAndAppendAction(unsigned& programCounter, uint16_t flags, Actions& actions, bool ifDomain)
+void DFABytecodeInterpreter::interpretTestFlagsAndAppendAction(uint32_t& programCounter, uint16_t flags, Actions& actions, bool ifDomain)
{
- ASSERT(getBits<DFABytecodeInstruction>(m_bytecode, m_bytecodeLength, programCounter, m_pagesUsed) == DFABytecodeInstruction::TestFlagsAndAppendAction
- || getBits<DFABytecodeInstruction>(m_bytecode, m_bytecodeLength, programCounter, m_pagesUsed) == DFABytecodeInstruction::TestFlagsAndAppendActionWithIfDomain);
- uint16_t flagsToCheck = getBits<uint16_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode), m_pagesUsed);
+ ASSERT(getInstruction(m_bytecode, m_bytecodeLength, programCounter, m_pagesUsed) == DFABytecodeInstruction::TestFlagsAndAppendAction
+ || getInstruction(m_bytecode, m_bytecodeLength, programCounter, m_pagesUsed) == DFABytecodeInstruction::TestFlagsAndAppendActionWithIfDomain);
+ uint16_t flagsToCheck = getBits<uint16_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecodeInstruction), m_pagesUsed);
uint16_t loadTypeFlags = flagsToCheck & LoadTypeMask;
uint16_t ressourceTypeFlags = flagsToCheck & ResourceTypeMask;
@@ -74,7 +115,7 @@
bool ressourceTypeMatches = ressourceTypeFlags ? (ressourceTypeFlags & flags) : true;
if (loadTypeMatches && ressourceTypeMatches)
- actions.add((ifDomain ? IfDomainFlag : 0) | static_cast<uint64_t>(getBits<unsigned>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode) + sizeof(uint16_t), m_pagesUsed)));
+ actions.add((ifDomain ? IfDomainFlag : 0) | static_cast<uint64_t>(getBits<uint32_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecodeInstruction) + sizeof(uint16_t), m_pagesUsed)));
programCounter += instructionSizeWithArguments(DFABytecodeInstruction::TestFlagsAndAppendAction);
ASSERT(instructionSizeWithArguments(DFABytecodeInstruction::TestFlagsAndAppendAction) == instructionSizeWithArguments(DFABytecodeInstruction::TestFlagsAndAppendActionWithIfDomain));
}
@@ -84,11 +125,11 @@
Actions actions;
// DFA header.
- unsigned dfaBytecodeLength = getBits<unsigned>(m_bytecode, m_bytecodeLength, 0, m_pagesUsed);
- unsigned programCounter = sizeof(unsigned);
+ uint32_t dfaBytecodeLength = getBits<uint32_t>(m_bytecode, m_bytecodeLength, 0, m_pagesUsed);
+ uint32_t programCounter = sizeof(uint32_t);
while (programCounter < dfaBytecodeLength) {
- DFABytecodeInstruction instruction = static_cast<DFABytecodeInstruction>(m_bytecode[programCounter]);
+ DFABytecodeInstruction instruction = getInstruction(m_bytecode, m_bytecodeLength, programCounter, m_pagesUsed);
if (instruction == DFABytecodeInstruction::AppendActionDefaultStylesheet)
interpretAppendAction(programCounter, actions, false);
else if (instruction == DFABytecodeInstruction::AppendAction)
@@ -113,18 +154,18 @@
Actions actions;
- unsigned programCounter = 0;
+ uint32_t programCounter = 0;
while (programCounter < m_bytecodeLength) {
// DFA header.
- unsigned dfaStart = programCounter;
- unsigned dfaBytecodeLength = getBits<unsigned>(m_bytecode, m_bytecodeLength, programCounter, m_pagesUsed);
- programCounter += sizeof(unsigned);
+ uint32_t dfaStart = programCounter;
+ uint32_t dfaBytecodeLength = getBits<uint32_t>(m_bytecode, m_bytecodeLength, programCounter, m_pagesUsed);
+ programCounter += sizeof(uint32_t);
// Skip the default stylesheet actions on the DFA root. These are accessed via actionsForDefaultStylesheetFromDFARoot.
if (!dfaStart) {
while (programCounter < dfaBytecodeLength) {
- DFABytecodeInstruction instruction = static_cast<DFABytecodeInstruction>(m_bytecode[programCounter]);
+ DFABytecodeInstruction instruction = getInstruction(m_bytecode, m_bytecodeLength, programCounter, m_pagesUsed);
if (instruction == DFABytecodeInstruction::AppendActionDefaultStylesheet)
programCounter += instructionSizeWithArguments(DFABytecodeInstruction::AppendActionDefaultStylesheet);
else if (instruction == DFABytecodeInstruction::AppendAction)
@@ -137,18 +178,18 @@
if (programCounter >= m_bytecodeLength)
return actions;
} else {
- ASSERT_WITH_MESSAGE(static_cast<DFABytecodeInstruction>(m_bytecode[programCounter]) != DFABytecodeInstruction::AppendAction
- && static_cast<DFABytecodeInstruction>(m_bytecode[programCounter]) != DFABytecodeInstruction::TestFlagsAndAppendAction,
+ ASSERT_WITH_MESSAGE(getInstruction(m_bytecode, m_bytecodeLength, programCounter, m_pagesUsed) != DFABytecodeInstruction::AppendAction
+ && getInstruction(m_bytecode, m_bytecodeLength, programCounter, m_pagesUsed) != DFABytecodeInstruction::TestFlagsAndAppendAction,
"Triggers that match everything should only be in the first DFA.");
}
// Interpret the bytecode from this DFA.
// This should always terminate if interpreting correctly compiled bytecode.
- unsigned urlIndex = 0;
+ uint32_t urlIndex = 0;
bool urlIndexIsAfterEndOfString = false;
while (true) {
ASSERT(programCounter <= m_bytecodeLength);
- switch (static_cast<DFABytecodeInstruction>(m_bytecode[programCounter])) {
+ switch (getInstruction(m_bytecode, m_bytecodeLength, programCounter, m_pagesUsed)) {
case DFABytecodeInstruction::Terminate:
goto nextDFA;
@@ -159,13 +200,15 @@
// Check to see if the next character in the url is the value stored with the bytecode.
char character = url[urlIndex];
- if (character == getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode), m_pagesUsed)) {
- programCounter = dfaStart + getBits<unsigned>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode) + sizeof(uint8_t), m_pagesUsed);
+ DFABytecodeJumpSize jumpSize = getJumpSize(m_bytecode, m_bytecodeLength, programCounter, m_pagesUsed);
+ if (character == getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecodeInstruction), m_pagesUsed)) {
+ uint32_t jumpLocation = programCounter + sizeof(DFABytecodeInstruction) + sizeof(uint8_t);
+ programCounter += getJumpDistance(m_bytecode, m_bytecodeLength, jumpLocation, m_pagesUsed, jumpSize);
if (!character)
urlIndexIsAfterEndOfString = true;
urlIndex++; // This represents an edge in the DFA.
} else
- programCounter += instructionSizeWithArguments(DFABytecodeInstruction::CheckValueCaseSensitive);
+ programCounter += sizeof(DFABytecodeInstruction) + sizeof(uint8_t) + jumpSizeInBytes(jumpSize);
break;
}
@@ -175,13 +218,15 @@
// Check to see if the next character in the url is the value stored with the bytecode.
char character = toASCIILower(url[urlIndex]);
- if (character == getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode), m_pagesUsed)) {
- programCounter = dfaStart + getBits<unsigned>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode) + sizeof(uint8_t), m_pagesUsed);
+ DFABytecodeJumpSize jumpSize = getJumpSize(m_bytecode, m_bytecodeLength, programCounter, m_pagesUsed);
+ if (character == getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecodeInstruction), m_pagesUsed)) {
+ uint32_t jumpLocation = programCounter + sizeof(DFABytecodeInstruction) + sizeof(uint8_t);
+ programCounter += getJumpDistance(m_bytecode, m_bytecodeLength, jumpLocation, m_pagesUsed, jumpSize);
if (!character)
urlIndexIsAfterEndOfString = true;
urlIndex++; // This represents an edge in the DFA.
} else
- programCounter += instructionSizeWithArguments(DFABytecodeInstruction::CheckValueCaseInsensitive);
+ programCounter += sizeof(DFABytecodeInstruction) + sizeof(uint8_t) + jumpSizeInBytes(jumpSize);
break;
}
@@ -190,14 +235,16 @@
goto nextDFA;
char character = url[urlIndex];
- if (character >= getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode), m_pagesUsed)
- && character <= getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode) + sizeof(uint8_t), m_pagesUsed)) {
- programCounter = dfaStart + getBits<unsigned>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode) + sizeof(uint8_t) + sizeof(uint8_t), m_pagesUsed);
+ DFABytecodeJumpSize jumpSize = getJumpSize(m_bytecode, m_bytecodeLength, programCounter, m_pagesUsed);
+ if (character >= getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecodeInstruction), m_pagesUsed)
+ && character <= getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecodeInstruction) + sizeof(uint8_t), m_pagesUsed)) {
+ uint32_t jumpLocation = programCounter + sizeof(DFABytecodeInstruction) + 2 * sizeof(uint8_t);
+ programCounter += getJumpDistance(m_bytecode, m_bytecodeLength, jumpLocation, m_pagesUsed, jumpSize);
if (!character)
urlIndexIsAfterEndOfString = true;
urlIndex++; // This represents an edge in the DFA.
} else
- programCounter += instructionSizeWithArguments(DFABytecodeInstruction::CheckValueRangeCaseSensitive);
+ programCounter += sizeof(DFABytecodeInstruction) + 2 * sizeof(uint8_t) + jumpSizeInBytes(jumpSize);
break;
}
@@ -206,24 +253,29 @@
goto nextDFA;
char character = toASCIILower(url[urlIndex]);
- if (character >= getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode), m_pagesUsed)
- && character <= getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode) + sizeof(uint8_t), m_pagesUsed)) {
- programCounter = dfaStart + getBits<unsigned>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode) + sizeof(uint8_t) + sizeof(uint8_t), m_pagesUsed);
+ DFABytecodeJumpSize jumpSize = getJumpSize(m_bytecode, m_bytecodeLength, programCounter, m_pagesUsed);
+ if (character >= getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecodeInstruction), m_pagesUsed)
+ && character <= getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecodeInstruction) + sizeof(uint8_t), m_pagesUsed)) {
+ uint32_t jumpLocation = programCounter + sizeof(DFABytecodeInstruction) + 2 * sizeof(uint8_t);
+ programCounter += getJumpDistance(m_bytecode, m_bytecodeLength, jumpLocation, m_pagesUsed, jumpSize);
if (!character)
urlIndexIsAfterEndOfString = true;
urlIndex++; // This represents an edge in the DFA.
} else
- programCounter += instructionSizeWithArguments(DFABytecodeInstruction::CheckValueRangeCaseInsensitive);
+ programCounter += sizeof(DFABytecodeInstruction) + 2 * sizeof(uint8_t) + jumpSizeInBytes(jumpSize);
break;
}
- case DFABytecodeInstruction::Jump:
+ case DFABytecodeInstruction::Jump: {
if (!url[urlIndex] || urlIndexIsAfterEndOfString)
goto nextDFA;
- programCounter = dfaStart + getBits<unsigned>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode), m_pagesUsed);
+ uint32_t jumpLocation = programCounter + sizeof(DFABytecodeInstruction);
+ DFABytecodeJumpSize jumpSize = getJumpSize(m_bytecode, m_bytecodeLength, programCounter, m_pagesUsed);
+ programCounter += getJumpDistance(m_bytecode, m_bytecodeLength, jumpLocation, m_pagesUsed, jumpSize);
urlIndex++; // This represents an edge in the DFA.
break;
+ }
case DFABytecodeInstruction::AppendAction:
interpretAppendAction(programCounter, actions, false);