Changeset 189599 in webkit
- Timestamp:
- Sep 10, 2015 6:37:09 PM (9 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r189596 r189599 1 2015-09-10 Sukolsak Sakshuwong <sukolsak@gmail.com> 2 3 Implement switch statements in WebAssembly 4 https://bugs.webkit.org/show_bug.cgi?id=149051 5 6 Reviewed by Geoffrey Garen. 7 8 This patch implements switch statements in WebAssembly using the 9 JSC::BinarySwitch class. 10 11 * tests/stress/wasm-control-flow.js: 12 * tests/stress/wasm/control-flow.wasm: 13 * wasm/WASMFunctionCompiler.h: 14 (JSC::WASMFunctionCompiler::buildSwitch): 15 * wasm/WASMFunctionParser.cpp: 16 (JSC::WASMFunctionParser::parseSwitchStatement): 17 * wasm/WASMFunctionSyntaxChecker.h: 18 (JSC::WASMFunctionSyntaxChecker::buildSwitch): 19 1 20 2015-09-10 Filip Pizlo <fpizlo@apple.com> 2 21 -
trunk/Source/JavaScriptCore/tests/stress/wasm-control-flow.js
r189514 r189599 203 203 } 204 204 return x; 205 } 206 207 function switchCase(x) { 208 x = x | 0; 209 var y = 0; 210 switch (x) { 211 case 0: 212 y = 1; 213 break; 214 case 1: 215 y = 2; 216 break; 217 case 2: 218 y = 3; 219 break; 220 } 221 return y; 222 } 223 224 function switchFallThrough(x) { 225 x = x | 0; 226 var y = 0; 227 switch (x) { 228 case 3: 229 y = (y + 1000) | 0; 230 case 2: 231 y = (y + 100) | 0; 232 case 1: 233 y = (y + 10) | 0; 234 default: 235 y = (y + 1) | 0; 236 } 237 return y; 205 238 } 206 239 … … 223 256 labelInLabelBreakOuter: labelInLabelBreakOuter, 224 257 whileInWhileBreakOuter: whileInWhileBreakOuter, 258 switchCase: switchCase, 259 switchFallThrough: switchFallThrough, 225 260 }; 226 261 } … … 234 269 shouldBe(module.ifElseFalse(), 2); 235 270 shouldBe(module.ifInIf(), 3); 271 236 272 shouldBe(module.whileLoop(), 5); 237 273 shouldBe(module.whileBreak(), 2); 238 274 shouldBe(module.whileContinue(), 4); 239 275 shouldBe(module.whileInWhile(), 10); 276 240 277 shouldBe(module.doLoop(), 1); 241 278 shouldBe(module.doBreak(), 2); 242 279 shouldBe(module.doContinue(), 4); 280 243 281 shouldBe(module.labelBreak(), 1); 244 282 shouldBe(module.labelContinue(), 1); … … 246 284 shouldBe(module.labelInLabelBreakOuter(), 2); 247 285 shouldBe(module.whileInWhileBreakOuter(), 8); 286 287 shouldBe(module.switchCase(0), 1); 288 shouldBe(module.switchCase(1), 2); 289 shouldBe(module.switchCase(2), 3); 290 shouldBe(module.switchCase(3), 0); 291 shouldBe(module.switchFallThrough(0), 1); 292 shouldBe(module.switchFallThrough(1), 11); 293 shouldBe(module.switchFallThrough(2), 111); 294 shouldBe(module.switchFallThrough(3), 1111); 295 shouldBe(module.switchFallThrough(4), 1); -
trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h
r189584 r189599 29 29 #if ENABLE(WEBASSEMBLY) 30 30 31 #include "BinarySwitch.h" 31 32 #include "CCallHelpers.h" 32 33 #include "JIT.h" … … 635 636 } 636 637 638 void buildSwitch(int, const Vector<int64_t>& cases, Vector<JumpTarget>& targets, JumpTarget defaultTarget) 639 { 640 load32(temporaryAddress(m_tempStackTop - 1), GPRInfo::regT0); 641 m_tempStackTop--; 642 BinarySwitch binarySwitch(GPRInfo::regT0, cases, BinarySwitch::Int32); 643 while (binarySwitch.advance(*this)) { 644 unsigned index = binarySwitch.caseIndex(); 645 jump(targets[index].label); 646 } 647 binarySwitch.fallThrough().linkTo(defaultTarget.label, this); 648 } 649 637 650 private: 638 651 union StackSlot { -
trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.cpp
r189584 r189599 416 416 ContextStatement WASMFunctionParser::parseSwitchStatement(Context& context) 417 417 { 418 context.startSwitch(); 418 419 uint32_t numberOfCases; 419 420 READ_COMPACT_UINT32_OR_FAIL(numberOfCases, "Cannot read the number of cases."); 420 parseExpressionI32(context); 421 PROPAGATE_ERROR(); 421 ContextExpression expression = parseExpressionI32(context); 422 PROPAGATE_ERROR(); 423 424 ContextJumpTarget compare; 425 context.jumpToTarget(compare); 426 427 Vector<int64_t> cases; 428 Vector<ContextJumpTarget> targets; 429 cases.reserveInitialCapacity(numberOfCases); 430 targets.reserveInitialCapacity(numberOfCases); 431 bool hasDefault = false; 432 ContextJumpTarget defaultTarget; 422 433 423 434 m_breakScopeDepth++; … … 431 442 uint32_t value; 432 443 READ_COMPACT_INT32_OR_FAIL(value, "Cannot read the value of the switch case."); 444 cases.uncheckedAppend(value); 445 ContextJumpTarget target; 446 context.linkTarget(target); 447 targets.uncheckedAppend(target); 433 448 if (switchCase == WASMSwitchCase::CaseWithStatement) { 434 449 parseStatement(context); … … 444 459 case WASMSwitchCase::DefaultWithBlockStatement: { 445 460 FAIL_IF_FALSE(i == numberOfCases - 1, "The default case must be the last case."); 461 hasDefault = true; 462 context.linkTarget(defaultTarget); 446 463 if (switchCase == WASMSwitchCase::DefaultWithStatement) { 447 464 parseStatement(context); … … 457 474 } 458 475 } 476 if (!hasDefault) 477 context.linkTarget(defaultTarget); 478 459 479 m_breakScopeDepth--; 460 // FIXME: Implement this instruction. 480 481 context.jumpToTarget(context.breakTarget()); 482 context.linkTarget(compare); 483 484 context.buildSwitch(expression, cases, targets, defaultTarget); 485 486 context.linkTarget(context.breakTarget()); 487 context.endSwitch(); 461 488 return UNUSED; 462 489 } -
trunk/Source/JavaScriptCore/wasm/WASMFunctionSyntaxChecker.h
r189584 r189599 156 156 int continueLabelTarget(uint32_t) { return UNUSED; } 157 157 158 void buildSwitch(int, const Vector<int64_t>&, const Vector<int>&, const int&) 159 { 160 m_tempStackTop--; 161 } 162 158 163 unsigned stackHeight() 159 164 {
Note: See TracChangeset
for help on using the changeset viewer.