@@ -69,7 +69,7 @@ class ByteCodeParser {
6969
7070private:
7171 // Parse a single basic block of bytecode instructions.
72- bool parseBlock ();
72+ bool parseBlock (unsigned limit );
7373
7474 // Get/Set the operands/result of a bytecode instruction.
7575 NodeIndex get (int operand)
@@ -150,7 +150,7 @@ class ByteCodeParser {
150150 m_parseFailed = true ;
151151 return constantUndefined ();
152152 }
153- void setTemporary (int operand, NodeIndex value)
153+ void setTemporary (unsigned operand, NodeIndex value)
154154 {
155155 m_temporaries[operand] = value;
156156 }
@@ -447,6 +447,15 @@ class ByteCodeParser {
447447 m_graph.ref (resultIndex);
448448 return resultIndex;
449449 }
450+ NodeIndex addToGraph (NodeType op, OpInfo info1, OpInfo info2, NodeIndex child1 = NoNode, NodeIndex child2 = NoNode, NodeIndex child3 = NoNode)
451+ {
452+ NodeIndex resultIndex = (NodeIndex)m_graph.size ();
453+ m_graph.append (Node (op, m_currentIndex, info1, info2, child1, child2, child3));
454+
455+ if (op & NodeMustGenerate)
456+ m_graph.ref (resultIndex);
457+ return resultIndex;
458+ }
450459
451460 JSGlobalData* m_globalData;
452461 CodeBlock* m_codeBlock;
@@ -517,13 +526,31 @@ class ByteCodeParser {
517526 m_currentIndex += OPCODE_LENGTH(name); \
518527 return !m_parseFailed
519528
520- bool ByteCodeParser::parseBlock ()
529+ bool ByteCodeParser::parseBlock (unsigned limit )
521530{
531+ // No need to reset state initially, since it has been set by the constructor.
532+ if (m_currentIndex) {
533+ for (unsigned i = 0 ; i < m_constants.size (); ++i)
534+ m_constants[i] = ConstantRecord ();
535+ for (unsigned i = 0 ; i < m_variables.size (); ++i)
536+ m_variables[i] = VariableRecord ();
537+ for (unsigned i = 0 ; i < m_arguments.size (); ++i)
538+ m_arguments[i] = VariableRecord ();
539+ for (unsigned i = 0 ; i < m_temporaries.size (); ++i)
540+ m_temporaries[i] = NoNode;
541+ }
542+
522543 AliasTracker aliases (m_graph);
523544
524545 Interpreter* interpreter = m_globalData->interpreter ;
525546 Instruction* instructionsBegin = m_codeBlock->instructions ().begin ();
526547 while (true ) {
548+ // Don't extend over jump destinations.
549+ if (m_currentIndex == limit) {
550+ addToGraph (Jump, OpInfo (m_currentIndex));
551+ return !m_parseFailed;
552+ }
553+
527554 // Switch on the current bytecode opcode.
528555 Instruction* currentInstruction = instructionsBegin + m_currentIndex;
529556 switch (interpreter->getOpcodeID (currentInstruction->u .opcode )) {
@@ -843,6 +870,116 @@ bool ByteCodeParser::parseBlock()
843870
844871 // === Block terminators. ===
845872
873+ case op_jmp: {
874+ unsigned relativeOffset = currentInstruction[1 ].u .operand ;
875+ addToGraph (Jump, OpInfo (m_currentIndex + relativeOffset));
876+ LAST_OPCODE (op_jmp);
877+ }
878+
879+ case op_loop: {
880+ unsigned relativeOffset = currentInstruction[1 ].u .operand ;
881+ addToGraph (Jump, OpInfo (m_currentIndex + relativeOffset));
882+ LAST_OPCODE (op_loop);
883+ }
884+
885+ case op_jtrue: {
886+ unsigned relativeOffset = currentInstruction[2 ].u .operand ;
887+ NodeIndex condition = get (currentInstruction[1 ].u .operand );
888+ addToGraph (Branch, OpInfo (m_currentIndex + relativeOffset), OpInfo (m_currentIndex + OPCODE_LENGTH (op_jtrue)), condition);
889+ LAST_OPCODE (op_jtrue);
890+ }
891+
892+ case op_jfalse: {
893+ unsigned relativeOffset = currentInstruction[2 ].u .operand ;
894+ NodeIndex condition = get (currentInstruction[1 ].u .operand );
895+ addToGraph (Branch, OpInfo (m_currentIndex + OPCODE_LENGTH (op_jfalse)), OpInfo (m_currentIndex + relativeOffset), condition);
896+ LAST_OPCODE (op_jfalse);
897+ }
898+
899+ case op_loop_if_true: {
900+ unsigned relativeOffset = currentInstruction[2 ].u .operand ;
901+ NodeIndex condition = get (currentInstruction[1 ].u .operand );
902+ addToGraph (Branch, OpInfo (m_currentIndex + relativeOffset), OpInfo (m_currentIndex + OPCODE_LENGTH (op_loop_if_true)), condition);
903+ LAST_OPCODE (op_loop_if_true);
904+ }
905+
906+ case op_loop_if_false: {
907+ unsigned relativeOffset = currentInstruction[2 ].u .operand ;
908+ NodeIndex condition = get (currentInstruction[1 ].u .operand );
909+ addToGraph (Branch, OpInfo (m_currentIndex + OPCODE_LENGTH (op_loop_if_false)), OpInfo (m_currentIndex + relativeOffset), condition);
910+ LAST_OPCODE (op_loop_if_false);
911+ }
912+
913+ case op_jeq_null: {
914+ unsigned relativeOffset = currentInstruction[2 ].u .operand ;
915+ NodeIndex value = get (currentInstruction[1 ].u .operand );
916+ NodeIndex condition = addToGraph (CompareEq, value, constantNull ());
917+ addToGraph (Branch, OpInfo (m_currentIndex + relativeOffset), OpInfo (m_currentIndex + OPCODE_LENGTH (op_jeq_null)), condition);
918+ LAST_OPCODE (op_jeq_null);
919+ }
920+
921+ case op_jneq_null: {
922+ unsigned relativeOffset = currentInstruction[2 ].u .operand ;
923+ NodeIndex value = get (currentInstruction[1 ].u .operand );
924+ NodeIndex condition = addToGraph (CompareEq, value, constantNull ());
925+ addToGraph (Branch, OpInfo (m_currentIndex + OPCODE_LENGTH (op_jneq_null)), OpInfo (m_currentIndex + relativeOffset), condition);
926+ LAST_OPCODE (op_jneq_null);
927+ }
928+
929+ case op_jnless: {
930+ unsigned relativeOffset = currentInstruction[3 ].u .operand ;
931+ NodeIndex op1 = get (currentInstruction[1 ].u .operand );
932+ NodeIndex op2 = get (currentInstruction[2 ].u .operand );
933+ NodeIndex condition = addToGraph (CompareLess, op1, op2);
934+ addToGraph (Branch, OpInfo (m_currentIndex + OPCODE_LENGTH (op_jnless)), OpInfo (m_currentIndex + relativeOffset), condition);
935+ LAST_OPCODE (op_jnless);
936+ }
937+
938+ case op_jnlesseq: {
939+ unsigned relativeOffset = currentInstruction[3 ].u .operand ;
940+ NodeIndex op1 = get (currentInstruction[1 ].u .operand );
941+ NodeIndex op2 = get (currentInstruction[2 ].u .operand );
942+ NodeIndex condition = addToGraph (CompareLessEq, op1, op2);
943+ addToGraph (Branch, OpInfo (m_currentIndex + OPCODE_LENGTH (op_jnlesseq)), OpInfo (m_currentIndex + relativeOffset), condition);
944+ LAST_OPCODE (op_jnlesseq);
945+ }
946+
947+ case op_jless: {
948+ unsigned relativeOffset = currentInstruction[3 ].u .operand ;
949+ NodeIndex op1 = get (currentInstruction[1 ].u .operand );
950+ NodeIndex op2 = get (currentInstruction[2 ].u .operand );
951+ NodeIndex condition = addToGraph (CompareLess, op1, op2);
952+ addToGraph (Branch, OpInfo (m_currentIndex + relativeOffset), OpInfo (m_currentIndex + OPCODE_LENGTH (op_jless)), condition);
953+ LAST_OPCODE (op_jless);
954+ }
955+
956+ case op_jlesseq: {
957+ unsigned relativeOffset = currentInstruction[3 ].u .operand ;
958+ NodeIndex op1 = get (currentInstruction[1 ].u .operand );
959+ NodeIndex op2 = get (currentInstruction[2 ].u .operand );
960+ NodeIndex condition = addToGraph (CompareLessEq, op1, op2);
961+ addToGraph (Branch, OpInfo (m_currentIndex + relativeOffset), OpInfo (m_currentIndex + OPCODE_LENGTH (op_jlesseq)), condition);
962+ LAST_OPCODE (op_jlesseq);
963+ }
964+
965+ case op_loop_if_less: {
966+ unsigned relativeOffset = currentInstruction[3 ].u .operand ;
967+ NodeIndex op1 = get (currentInstruction[1 ].u .operand );
968+ NodeIndex op2 = get (currentInstruction[2 ].u .operand );
969+ NodeIndex condition = addToGraph (CompareLess, op1, op2);
970+ addToGraph (Branch, OpInfo (m_currentIndex + relativeOffset), OpInfo (m_currentIndex + OPCODE_LENGTH (op_loop_if_less)), condition);
971+ LAST_OPCODE (op_loop_if_less);
972+ }
973+
974+ case op_loop_if_lesseq: {
975+ unsigned relativeOffset = currentInstruction[3 ].u .operand ;
976+ NodeIndex op1 = get (currentInstruction[1 ].u .operand );
977+ NodeIndex op2 = get (currentInstruction[2 ].u .operand );
978+ NodeIndex condition = addToGraph (CompareLessEq, op1, op2);
979+ addToGraph (Branch, OpInfo (m_currentIndex + relativeOffset), OpInfo (m_currentIndex + OPCODE_LENGTH (op_loop_if_lesseq)), condition);
980+ LAST_OPCODE (op_loop_if_lesseq);
981+ }
982+
846983 case op_ret: {
847984 addToGraph (Return, get (currentInstruction[1 ].u .operand ));
848985
@@ -866,8 +1003,31 @@ bool ByteCodeParser::parseBlock()
8661003
8671004bool ByteCodeParser::parse ()
8681005{
869- if (!parseBlock ())
870- return false ;
1006+ // Set during construction.
1007+ ASSERT (!m_currentIndex);
1008+
1009+ for (unsigned jumpTargetIndex = 0 ; jumpTargetIndex <= m_codeBlock->numberOfJumpTargets (); ++jumpTargetIndex) {
1010+ // The maximum bytecode offset to go into the current basicblock is either the next jump target, or the end of the instructions.
1011+ unsigned limit = jumpTargetIndex < m_codeBlock->numberOfJumpTargets () ? m_codeBlock->jumpTarget (jumpTargetIndex) : m_codeBlock->instructions ().size ();
1012+ ASSERT (m_currentIndex < limit);
1013+
1014+ // Loop until we reach the current limit (i.e. next jump target).
1015+ do {
1016+ unsigned bytecodeBegin = m_currentIndex;
1017+ NodeIndex begin = m_graph.size ();
1018+
1019+ if (!parseBlock (limit))
1020+ return false ;
1021+ // We should not have gone beyond the limit.
1022+ ASSERT (m_currentIndex <= limit);
1023+
1024+ NodeIndex end = m_graph.size ();
1025+ m_graph.m_blocks .append (BasicBlock (bytecodeBegin, begin, end));
1026+ } while (m_currentIndex < limit);
1027+ }
1028+
1029+ // Should have reached the end of the instructions.
1030+ ASSERT (m_currentIndex == m_codeBlock->instructions ().size ());
8711031
8721032 // Assign VirtualRegisters.
8731033 ScoreBoard scoreBoard (m_graph, m_variables.size ());
0 commit comments