Changeset 189514 in webkit
- Timestamp:
- Sep 8, 2015 4:04:44 PM (9 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 2 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r189506 r189514 1 2015-09-08 Sukolsak Sakshuwong <sukolsak@gmail.com> 2 3 Implement control flow statements in WebAssembly 4 https://bugs.webkit.org/show_bug.cgi?id=148934 5 6 Reviewed by Geoffrey Garen. 7 8 This patch implements if, while, do, label, break, and continue 9 statements in WebAssembly. Switches will be implemented in a subsequent 10 patch. 11 12 * tests/stress/wasm-control-flow.js: Added. 13 (shouldBe): 14 * tests/stress/wasm/control-flow.wasm: Added. 15 * wasm/WASMFunctionCompiler.h: 16 (JSC::WASMFunctionCompiler::linkTarget): 17 (JSC::WASMFunctionCompiler::jumpToTarget): 18 (JSC::WASMFunctionCompiler::jumpToTargetIf): 19 (JSC::WASMFunctionCompiler::startLoop): 20 (JSC::WASMFunctionCompiler::endLoop): 21 (JSC::WASMFunctionCompiler::startSwitch): 22 (JSC::WASMFunctionCompiler::endSwitch): 23 (JSC::WASMFunctionCompiler::startLabel): 24 (JSC::WASMFunctionCompiler::endLabel): 25 (JSC::WASMFunctionCompiler::breakTarget): 26 (JSC::WASMFunctionCompiler::continueTarget): 27 (JSC::WASMFunctionCompiler::breakLabelTarget): 28 (JSC::WASMFunctionCompiler::continueLabelTarget): 29 * wasm/WASMFunctionParser.cpp: 30 (JSC::WASMFunctionParser::parseIfStatement): 31 (JSC::WASMFunctionParser::parseIfElseStatement): 32 (JSC::WASMFunctionParser::parseWhileStatement): 33 (JSC::WASMFunctionParser::parseDoStatement): 34 (JSC::WASMFunctionParser::parseLabelStatement): 35 (JSC::WASMFunctionParser::parseBreakStatement): 36 (JSC::WASMFunctionParser::parseBreakLabelStatement): 37 (JSC::WASMFunctionParser::parseContinueStatement): 38 (JSC::WASMFunctionParser::parseContinueLabelStatement): 39 * wasm/WASMFunctionParser.h: 40 * wasm/WASMFunctionSyntaxChecker.h: 41 (JSC::WASMFunctionSyntaxChecker::linkTarget): 42 (JSC::WASMFunctionSyntaxChecker::jumpToTarget): 43 (JSC::WASMFunctionSyntaxChecker::jumpToTargetIf): 44 (JSC::WASMFunctionSyntaxChecker::startLoop): 45 (JSC::WASMFunctionSyntaxChecker::endLoop): 46 (JSC::WASMFunctionSyntaxChecker::startSwitch): 47 (JSC::WASMFunctionSyntaxChecker::endSwitch): 48 (JSC::WASMFunctionSyntaxChecker::startLabel): 49 (JSC::WASMFunctionSyntaxChecker::endLabel): 50 (JSC::WASMFunctionSyntaxChecker::breakTarget): 51 (JSC::WASMFunctionSyntaxChecker::continueTarget): 52 (JSC::WASMFunctionSyntaxChecker::breakLabelTarget): 53 (JSC::WASMFunctionSyntaxChecker::continueLabelTarget): 54 1 55 2015-09-08 Per Arne Vollan <peavo@outlook.com> 2 56 -
trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h
r189499 r189514 64 64 typedef int Expression; 65 65 typedef int Statement; 66 struct JumpTarget { 67 Label label; 68 JumpList jumpList; 69 }; 70 enum class JumpCondition { Zero, NonZero }; 66 71 67 72 WASMFunctionCompiler(VM& vm, CodeBlock* codeBlock, unsigned stackHeight) … … 434 439 } 435 440 441 void linkTarget(JumpTarget& target) 442 { 443 target.label = label(); 444 target.jumpList.link(this); 445 } 446 447 void jumpToTarget(JumpTarget& target) 448 { 449 if (target.label.isSet()) 450 jump(target.label); 451 else 452 target.jumpList.append(jump()); 453 } 454 455 void jumpToTargetIf(JumpCondition condition, int, JumpTarget& target) 456 { 457 load32(temporaryAddress(m_tempStackTop - 1), GPRInfo::regT0); 458 m_tempStackTop--; 459 Jump taken = branchTest32((condition == JumpCondition::Zero) ? Zero : NonZero, GPRInfo::regT0); 460 if (target.label.isSet()) 461 taken.linkTo(target.label, this); 462 else 463 target.jumpList.append(taken); 464 } 465 466 void startLoop() 467 { 468 m_breakTargets.append(JumpTarget()); 469 m_continueTargets.append(JumpTarget()); 470 } 471 472 void endLoop() 473 { 474 m_breakTargets.removeLast(); 475 m_continueTargets.removeLast(); 476 } 477 478 void startSwitch() 479 { 480 m_breakTargets.append(JumpTarget()); 481 } 482 483 void endSwitch() 484 { 485 m_breakTargets.removeLast(); 486 } 487 488 void startLabel() 489 { 490 m_breakLabelTargets.append(JumpTarget()); 491 m_continueLabelTargets.append(JumpTarget()); 492 493 linkTarget(m_continueLabelTargets.last()); 494 } 495 496 void endLabel() 497 { 498 linkTarget(m_breakLabelTargets.last()); 499 500 m_breakLabelTargets.removeLast(); 501 m_continueLabelTargets.removeLast(); 502 } 503 504 JumpTarget& breakTarget() 505 { 506 return m_breakTargets.last(); 507 } 508 509 JumpTarget& continueTarget() 510 { 511 return m_continueTargets.last(); 512 } 513 514 JumpTarget& breakLabelTarget(uint32_t labelIndex) 515 { 516 return m_breakLabelTargets[labelIndex]; 517 } 518 519 JumpTarget& continueLabelTarget(uint32_t labelIndex) 520 { 521 return m_continueLabelTargets[labelIndex]; 522 } 523 436 524 private: 437 525 union StackSlot { … … 482 570 unsigned m_tempStackTop { 0 }; 483 571 572 Vector<JumpTarget> m_breakTargets; 573 Vector<JumpTarget> m_continueTargets; 574 Vector<JumpTarget> m_breakLabelTargets; 575 Vector<JumpTarget> m_continueLabelTargets; 576 484 577 Label m_beginLabel; 485 578 Jump m_stackOverflow; -
trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.cpp
r189499 r189514 254 254 ContextStatement WASMFunctionParser::parseIfStatement(Context& context) 255 255 { 256 parseExpressionI32(context); 257 PROPAGATE_ERROR(); 256 ContextJumpTarget end; 257 258 ContextExpression expression = parseExpressionI32(context); 259 PROPAGATE_ERROR(); 260 261 context.jumpToTargetIf(Context::JumpCondition::Zero, expression, end); 262 258 263 parseStatement(context); 259 // FIXME: Implement this instruction. 264 PROPAGATE_ERROR(); 265 266 context.linkTarget(end); 260 267 return UNUSED; 261 268 } … … 264 271 ContextStatement WASMFunctionParser::parseIfElseStatement(Context& context) 265 272 { 266 parseExpressionI32(context); 267 PROPAGATE_ERROR(); 273 ContextJumpTarget elseTarget; 274 ContextJumpTarget end; 275 276 ContextExpression expression = parseExpressionI32(context); 277 PROPAGATE_ERROR(); 278 279 context.jumpToTargetIf(Context::JumpCondition::Zero, expression, elseTarget); 280 268 281 parseStatement(context); 269 282 PROPAGATE_ERROR(); 283 284 context.jumpToTarget(end); 285 context.linkTarget(elseTarget); 286 270 287 parseStatement(context); 271 // FIXME: Implement this instruction. 288 PROPAGATE_ERROR(); 289 290 context.linkTarget(end); 272 291 return UNUSED; 273 292 } … … 276 295 ContextStatement WASMFunctionParser::parseWhileStatement(Context& context) 277 296 { 278 parseExpressionI32(context); 279 PROPAGATE_ERROR(); 297 context.startLoop(); 298 context.linkTarget(context.continueTarget()); 299 300 ContextExpression expression = parseExpressionI32(context); 301 PROPAGATE_ERROR(); 302 303 context.jumpToTargetIf(Context::JumpCondition::Zero, expression, context.breakTarget()); 280 304 281 305 m_breakScopeDepth++; … … 285 309 m_continueScopeDepth--; 286 310 m_breakScopeDepth--; 287 // FIXME: Implement this instruction. 311 312 context.jumpToTarget(context.continueTarget()); 313 314 context.linkTarget(context.breakTarget()); 315 context.endLoop(); 288 316 return UNUSED; 289 317 } … … 292 320 ContextStatement WASMFunctionParser::parseDoStatement(Context& context) 293 321 { 322 context.startLoop(); 323 324 ContextJumpTarget topOfLoop; 325 context.linkTarget(topOfLoop); 326 294 327 m_breakScopeDepth++; 295 328 m_continueScopeDepth++; … … 299 332 m_breakScopeDepth--; 300 333 301 parseExpressionI32(context); 302 // FIXME: Implement this instruction. 334 context.linkTarget(context.continueTarget()); 335 336 ContextExpression expression = parseExpressionI32(context); 337 PROPAGATE_ERROR(); 338 339 context.jumpToTargetIf(Context::JumpCondition::NonZero, expression, topOfLoop); 340 341 context.linkTarget(context.breakTarget()); 342 context.endLoop(); 303 343 return UNUSED; 304 344 } … … 307 347 ContextStatement WASMFunctionParser::parseLabelStatement(Context& context) 308 348 { 349 context.startLabel(); 309 350 m_labelDepth++; 310 351 parseStatement(context); 311 352 PROPAGATE_ERROR(); 312 353 m_labelDepth--; 313 // FIXME: Implement this instruction.314 return UNUSED; 315 } 316 317 template <class Context> 318 ContextStatement WASMFunctionParser::parseBreakStatement(Context& )354 context.endLabel(); 355 return UNUSED; 356 } 357 358 template <class Context> 359 ContextStatement WASMFunctionParser::parseBreakStatement(Context& context) 319 360 { 320 361 FAIL_IF_FALSE(m_breakScopeDepth, "'break' is only valid inside a switch or loop statement."); 321 // FIXME: Implement this instruction.322 return UNUSED; 323 } 324 325 template <class Context> 326 ContextStatement WASMFunctionParser::parseBreakLabelStatement(Context& )362 context.jumpToTarget(context.breakTarget()); 363 return UNUSED; 364 } 365 366 template <class Context> 367 ContextStatement WASMFunctionParser::parseBreakLabelStatement(Context& context) 327 368 { 328 369 uint32_t labelIndex; 329 370 READ_COMPACT_UINT32_OR_FAIL(labelIndex, "Cannot read the label index."); 330 371 FAIL_IF_FALSE(labelIndex < m_labelDepth, "The label index is incorrect."); 331 // FIXME: Implement this instruction.332 return UNUSED; 333 } 334 335 template <class Context> 336 ContextStatement WASMFunctionParser::parseContinueStatement(Context& )372 context.jumpToTarget(context.breakLabelTarget(labelIndex)); 373 return UNUSED; 374 } 375 376 template <class Context> 377 ContextStatement WASMFunctionParser::parseContinueStatement(Context& context) 337 378 { 338 379 FAIL_IF_FALSE(m_continueScopeDepth, "'continue' is only valid inside a loop statement."); 339 // FIXME: Implement this instruction.340 return UNUSED; 341 } 342 343 template <class Context> 344 ContextStatement WASMFunctionParser::parseContinueLabelStatement(Context& )380 context.jumpToTarget(context.continueTarget()); 381 return UNUSED; 382 } 383 384 template <class Context> 385 ContextStatement WASMFunctionParser::parseContinueLabelStatement(Context& context) 345 386 { 346 387 uint32_t labelIndex; 347 388 READ_COMPACT_UINT32_OR_FAIL(labelIndex, "Cannot read the label index."); 348 389 FAIL_IF_FALSE(labelIndex < m_labelDepth, "The label index is incorrect."); 349 // FIXME: Implement this instruction.390 context.jumpToTarget(context.continueLabelTarget(labelIndex)); 350 391 return UNUSED; 351 392 } -
trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.h
r189499 r189514 34 34 #define ContextExpression typename Context::Expression 35 35 #define ContextStatement typename Context::Statement 36 #define ContextJumpTarget typename Context::JumpTarget 36 37 37 38 namespace JSC { -
trunk/Source/JavaScriptCore/wasm/WASMFunctionSyntaxChecker.h
r189499 r189514 37 37 typedef int Expression; 38 38 typedef int Statement; 39 typedef int JumpTarget; 40 enum class JumpCondition { Zero, NonZero }; 39 41 40 42 void startFunction(const Vector<WASMType>& arguments, uint32_t numberOfI32LocalVariables, uint32_t numberOfF32LocalVariables, uint32_t numberOfF64LocalVariables) … … 97 99 } 98 100 101 void linkTarget(const int&) { } 102 void jumpToTarget(const int&) { } 103 void jumpToTargetIf(JumpCondition, int, const int&) 104 { 105 m_tempStackTop--; 106 } 107 108 void startLoop() { } 109 void endLoop() { } 110 void startSwitch() { } 111 void endSwitch() { } 112 void startLabel() { } 113 void endLabel() { } 114 115 int breakTarget() { return UNUSED; } 116 int continueTarget() { return UNUSED; } 117 int breakLabelTarget(uint32_t) { return UNUSED; } 118 int continueLabelTarget(uint32_t) { return UNUSED; } 119 99 120 unsigned stackHeight() 100 121 {
Note: See TracChangeset
for help on using the changeset viewer.