Changeset 35309 in webkit for trunk/JavaScriptCore/VM/CodeGenerator.cpp
- Timestamp:
- Jul 23, 2008, 5:49:46 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/VM/CodeGenerator.cpp
r35245 r35309 33 33 #include "JSFunction.h" 34 34 #include "Machine.h" 35 #include "ustring.h" 35 36 36 37 using namespace std; … … 1145 1146 } 1146 1147 1148 void CodeGenerator::beginSwitch(RegisterID* scrutineeRegister, SwitchInfo::SwitchType type) 1149 { 1150 SwitchInfo info = { instructions().size(), type }; 1151 switch (type) { 1152 case SwitchInfo::SwitchImmediate: 1153 emitOpcode(op_switch_imm); 1154 break; 1155 case SwitchInfo::SwitchCharacter: 1156 emitOpcode(op_switch_char); 1157 break; 1158 case SwitchInfo::SwitchString: 1159 emitOpcode(op_switch_string); 1160 break; 1161 default: 1162 ASSERT_NOT_REACHED(); 1163 } 1164 1165 instructions().append(0); // place holder for table index 1166 instructions().append(0); // place holder for default target 1167 instructions().append(scrutineeRegister->index()); 1168 m_switchContextStack.append(info); 1169 } 1170 1171 static int32_t keyForImmediateSwitch(ExpressionNode* node, int32_t min, int32_t max) 1172 { 1173 UNUSED_PARAM(max); 1174 ASSERT(node->isNumber()); 1175 double value = static_cast<NumberNode*>(node)->value(); 1176 ASSERT(JSImmediate::from(value)); 1177 int32_t key = static_cast<int32_t>(value); 1178 ASSERT(key == value); 1179 ASSERT(key >= min); 1180 ASSERT(key <= max); 1181 return key - min; 1182 } 1183 1184 static void prepareJumpTableForImmediateSwitch(SimpleJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<LabelID>* labels, ExpressionNode** nodes, int32_t min, int32_t max) 1185 { 1186 jumpTable.min = min; 1187 jumpTable.branchOffsets.resize(max - min + 1); 1188 jumpTable.branchOffsets.fill(0); 1189 for (uint32_t i = 0; i < clauseCount; ++i) { 1190 // We're emitting this after the clause labels should have been fixed, so 1191 // the labels should not be "forward" references 1192 ASSERT(!labels[i]->isForwardLabel()); 1193 jumpTable.add(keyForImmediateSwitch(nodes[i], min, max), labels[i]->offsetFrom(switchAddress)); 1194 } 1195 } 1196 1197 static int32_t keyForCharacterSwitch(ExpressionNode* node, int32_t min, int32_t max) 1198 { 1199 UNUSED_PARAM(max); 1200 ASSERT(node->isString()); 1201 UString::Rep* clause = static_cast<StringNode*>(node)->value().rep(); 1202 ASSERT(clause->size() == 1); 1203 1204 int32_t key = clause->data()[0]; 1205 ASSERT(key >= min); 1206 ASSERT(key <= max); 1207 return key - min; 1208 } 1209 1210 static void prepareJumpTableForCharacterSwitch(SimpleJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<LabelID>* labels, ExpressionNode** nodes, int32_t min, int32_t max) 1211 { 1212 jumpTable.min = min; 1213 jumpTable.branchOffsets.resize(max - min + 1); 1214 jumpTable.branchOffsets.fill(0); 1215 for (uint32_t i = 0; i < clauseCount; ++i) { 1216 // We're emitting this after the clause labels should have been fixed, so 1217 // the labels should not be "forward" references 1218 ASSERT(!labels[i]->isForwardLabel()); 1219 jumpTable.add(keyForCharacterSwitch(nodes[i], min, max), labels[i]->offsetFrom(switchAddress)); 1220 } 1221 } 1222 1223 static void prepareJumpTableForStringSwitch(StringJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<LabelID>* labels, ExpressionNode** nodes) 1224 { 1225 for (uint32_t i = 0; i < clauseCount; ++i) { 1226 // We're emitting this after the clause labels should have been fixed, so 1227 // the labels should not be "forward" references 1228 ASSERT(!labels[i]->isForwardLabel()); 1229 1230 ASSERT(nodes[i]->isString()); 1231 UString::Rep* clause = static_cast<StringNode*>(nodes[i])->value().rep(); 1232 jumpTable.add(clause, labels[i]->offsetFrom(switchAddress)); 1233 } 1234 } 1235 1236 void CodeGenerator::endSwitch(uint32_t clauseCount, RefPtr<LabelID>* labels, ExpressionNode** nodes, LabelID* defaultLabel, int32_t min, int32_t max) 1237 { 1238 SwitchInfo switchInfo = m_switchContextStack.last(); 1239 m_switchContextStack.removeLast(); 1240 if (switchInfo.switchType == SwitchInfo::SwitchImmediate) { 1241 instructions()[switchInfo.opcodeOffset + 1] = m_codeBlock->immediateSwitchJumpTables.size(); 1242 instructions()[switchInfo.opcodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.opcodeOffset + 3); 1243 1244 m_codeBlock->immediateSwitchJumpTables.append(SimpleJumpTable()); 1245 SimpleJumpTable& jumpTable = m_codeBlock->immediateSwitchJumpTables.last(); 1246 1247 prepareJumpTableForImmediateSwitch(jumpTable, switchInfo.opcodeOffset + 3, clauseCount, labels, nodes, min, max); 1248 } else if (switchInfo.switchType == SwitchInfo::SwitchCharacter) { 1249 instructions()[switchInfo.opcodeOffset + 1] = m_codeBlock->characterSwitchJumpTables.size(); 1250 instructions()[switchInfo.opcodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.opcodeOffset + 3); 1251 1252 m_codeBlock->characterSwitchJumpTables.append(SimpleJumpTable()); 1253 SimpleJumpTable& jumpTable = m_codeBlock->characterSwitchJumpTables.last(); 1254 1255 prepareJumpTableForCharacterSwitch(jumpTable, switchInfo.opcodeOffset + 3, clauseCount, labels, nodes, min, max); 1256 } else { 1257 ASSERT(switchInfo.switchType == SwitchInfo::SwitchString); 1258 instructions()[switchInfo.opcodeOffset + 1] = m_codeBlock->stringSwitchJumpTables.size(); 1259 instructions()[switchInfo.opcodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.opcodeOffset + 3); 1260 1261 m_codeBlock->stringSwitchJumpTables.append(StringJumpTable()); 1262 StringJumpTable& jumpTable = m_codeBlock->stringSwitchJumpTables.last(); 1263 1264 prepareJumpTableForStringSwitch(jumpTable, switchInfo.opcodeOffset + 3, clauseCount, labels, nodes); 1265 } 1266 } 1267 1147 1268 } // namespace KJS
Note:
See TracChangeset
for help on using the changeset viewer.