Changeset 188808 in webkit
- Timestamp:
- Aug 21, 2015 5:49:20 PM (9 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r188803 r188808 1 2015-08-21 Sukolsak Sakshuwong <sukolsak@gmail.com> 2 3 Parse control flow statements in WebAssembly 4 https://bugs.webkit.org/show_bug.cgi?id=148333 5 6 Reviewed by Geoffrey Garen. 7 8 Parse control flow statements in WebAssembly files generated by pack-asmjs 9 <https://github.com/WebAssembly/polyfill-prototype-1>. 10 11 * wasm/WASMConstants.h: 12 * wasm/WASMFunctionParser.cpp: 13 (JSC::WASMFunctionParser::parseStatement): 14 (JSC::WASMFunctionParser::parseIfStatement): 15 (JSC::WASMFunctionParser::parseIfElseStatement): 16 (JSC::WASMFunctionParser::parseWhileStatement): 17 (JSC::WASMFunctionParser::parseDoStatement): 18 (JSC::WASMFunctionParser::parseLabelStatement): 19 (JSC::WASMFunctionParser::parseBreakStatement): 20 (JSC::WASMFunctionParser::parseBreakLabelStatement): 21 (JSC::WASMFunctionParser::parseContinueStatement): 22 (JSC::WASMFunctionParser::parseContinueLabelStatement): 23 (JSC::WASMFunctionParser::parseSwitchStatement): 24 * wasm/WASMFunctionParser.h: 25 (JSC::WASMFunctionParser::WASMFunctionParser): 26 * wasm/WASMReader.cpp: 27 (JSC::WASMReader::readCompactInt32): 28 (JSC::WASMReader::readSwitchCase): 29 * wasm/WASMReader.h: 30 1 31 2015-08-21 Geoffrey Garen <ggaren@apple.com> 2 32 -
trunk/Source/JavaScriptCore/wasm/WASMConstants.h
r188778 r188808 183 183 }; 184 184 185 enum class WASMSwitchCase : uint8_t { 186 CaseWithNoStatements, 187 CaseWithStatement, 188 CaseWithBlockStatement, 189 DefaultWithNoStatements, 190 DefaultWithStatement, 191 DefaultWithBlockStatement, 192 NumberOfSwitchCases 193 }; 194 185 195 enum class WASMExportFormat : uint8_t { 186 196 Default, -
trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.cpp
r188778 r188808 34 34 #define PROPAGATE_ERROR() do { if (!m_errorMessage.isNull()) return 0; } while (0) 35 35 #define FAIL_WITH_MESSAGE(errorMessage) do { m_errorMessage = errorMessage; return 0; } while (0) 36 #define READ_COMPACT_INT32_OR_FAIL(result, errorMessage) do { if (!m_reader.readCompactInt32(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0) 36 37 #define READ_COMPACT_UINT32_OR_FAIL(result, errorMessage) do { if (!m_reader.readCompactUInt32(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0) 37 38 #define READ_OP_STATEMENT_OR_FAIL(hasImmediate, op, opWithImmediate, immediate, errorMessage) do { if (!m_reader.readOpStatement(hasImmediate, op, opWithImmediate, immediate)) FAIL_WITH_MESSAGE(errorMessage); } while (0) 38 39 #define READ_OP_EXPRESSION_I32_OR_FAIL(hasImmediate, op, opWithImmediate, immediate, errorMessage) do { if (!m_reader.readOpExpressionI32(hasImmediate, op, opWithImmediate, immediate)) FAIL_WITH_MESSAGE(errorMessage); } while (0) 39 40 #define READ_VARIABLE_TYPES_OR_FAIL(hasImmediate, variableTypes, variableTypesWithImmediate, immediate, errorMessage) do { if (!m_reader.readVariableTypes(hasImmediate, variableTypes, variableTypesWithImmediate, immediate)) FAIL_WITH_MESSAGE(errorMessage); } while (0) 41 #define READ_SWITCH_CASE_OR_FAIL(result, errorMessage) do { if (!m_reader.readSwitchCase(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0) 40 42 #define FAIL_IF_FALSE(condition, errorMessage) do { if (!(condition)) FAIL_WITH_MESSAGE(errorMessage); } while (0) 41 43 … … 124 126 parseBlockStatement(context); 125 127 break; 128 case WASMOpStatement::If: 129 parseIfStatement(context); 130 break; 131 case WASMOpStatement::IfElse: 132 parseIfElseStatement(context); 133 break; 134 case WASMOpStatement::While: 135 parseWhileStatement(context); 136 break; 137 case WASMOpStatement::Do: 138 parseDoStatement(context); 139 break; 140 case WASMOpStatement::Label: 141 parseLabelStatement(context); 142 break; 143 case WASMOpStatement::Break: 144 parseBreakStatement(context); 145 break; 146 case WASMOpStatement::BreakLabel: 147 parseBreakLabelStatement(context); 148 break; 149 case WASMOpStatement::Continue: 150 parseContinueStatement(context); 151 break; 152 case WASMOpStatement::ContinueLabel: 153 parseContinueLabelStatement(context); 154 break; 155 case WASMOpStatement::Switch: 156 parseSwitchStatement(context); 157 break; 126 158 case WASMOpStatement::SetGlobal: 127 case WASMOpStatement::If:128 case WASMOpStatement::IfElse:129 case WASMOpStatement::While:130 case WASMOpStatement::Do:131 case WASMOpStatement::Label:132 case WASMOpStatement::Break:133 case WASMOpStatement::BreakLabel:134 case WASMOpStatement::Continue:135 case WASMOpStatement::ContinueLabel:136 case WASMOpStatement::Switch:137 159 case WASMOpStatement::I32Store8: 138 160 case WASMOpStatement::I32StoreWithOffset8: … … 204 226 PROPAGATE_ERROR(); 205 227 } 228 return UNUSED; 229 } 230 231 template <class Context> 232 ContextStatement WASMFunctionParser::parseIfStatement(Context& context) 233 { 234 parseExpressionI32(context); 235 PROPAGATE_ERROR(); 236 parseStatement(context); 237 // FIXME: Implement this instruction. 238 return UNUSED; 239 } 240 241 template <class Context> 242 ContextStatement WASMFunctionParser::parseIfElseStatement(Context& context) 243 { 244 parseExpressionI32(context); 245 PROPAGATE_ERROR(); 246 parseStatement(context); 247 PROPAGATE_ERROR(); 248 parseStatement(context); 249 // FIXME: Implement this instruction. 250 return UNUSED; 251 } 252 253 template <class Context> 254 ContextStatement WASMFunctionParser::parseWhileStatement(Context& context) 255 { 256 parseExpressionI32(context); 257 PROPAGATE_ERROR(); 258 259 m_breakScopeDepth++; 260 m_continueScopeDepth++; 261 parseStatement(context); 262 PROPAGATE_ERROR(); 263 m_continueScopeDepth--; 264 m_breakScopeDepth--; 265 // FIXME: Implement this instruction. 266 return UNUSED; 267 } 268 269 template <class Context> 270 ContextStatement WASMFunctionParser::parseDoStatement(Context& context) 271 { 272 m_breakScopeDepth++; 273 m_continueScopeDepth++; 274 parseStatement(context); 275 PROPAGATE_ERROR(); 276 m_continueScopeDepth--; 277 m_breakScopeDepth--; 278 279 parseExpressionI32(context); 280 // FIXME: Implement this instruction. 281 return UNUSED; 282 } 283 284 template <class Context> 285 ContextStatement WASMFunctionParser::parseLabelStatement(Context& context) 286 { 287 m_labelDepth++; 288 parseStatement(context); 289 PROPAGATE_ERROR(); 290 m_labelDepth--; 291 // FIXME: Implement this instruction. 292 return UNUSED; 293 } 294 295 template <class Context> 296 ContextStatement WASMFunctionParser::parseBreakStatement(Context&) 297 { 298 FAIL_IF_FALSE(m_breakScopeDepth, "'break' is only valid inside a switch or loop statement."); 299 // FIXME: Implement this instruction. 300 return UNUSED; 301 } 302 303 template <class Context> 304 ContextStatement WASMFunctionParser::parseBreakLabelStatement(Context&) 305 { 306 uint32_t labelIndex; 307 READ_COMPACT_UINT32_OR_FAIL(labelIndex, "Cannot read the label index."); 308 FAIL_IF_FALSE(labelIndex < m_labelDepth, "The label index is incorrect."); 309 // FIXME: Implement this instruction. 310 return UNUSED; 311 } 312 313 template <class Context> 314 ContextStatement WASMFunctionParser::parseContinueStatement(Context&) 315 { 316 FAIL_IF_FALSE(m_continueScopeDepth, "'continue' is only valid inside a loop statement."); 317 // FIXME: Implement this instruction. 318 return UNUSED; 319 } 320 321 template <class Context> 322 ContextStatement WASMFunctionParser::parseContinueLabelStatement(Context&) 323 { 324 uint32_t labelIndex; 325 READ_COMPACT_UINT32_OR_FAIL(labelIndex, "Cannot read the label index."); 326 FAIL_IF_FALSE(labelIndex < m_labelDepth, "The label index is incorrect."); 327 // FIXME: Implement this instruction. 328 return UNUSED; 329 } 330 331 template <class Context> 332 ContextStatement WASMFunctionParser::parseSwitchStatement(Context& context) 333 { 334 uint32_t numberOfCases; 335 READ_COMPACT_UINT32_OR_FAIL(numberOfCases, "Cannot read the number of cases."); 336 parseExpressionI32(context); 337 PROPAGATE_ERROR(); 338 339 m_breakScopeDepth++; 340 for (uint32_t i = 0; i < numberOfCases; ++i) { 341 WASMSwitchCase switchCase; 342 READ_SWITCH_CASE_OR_FAIL(switchCase, "Cannot read the switch case."); 343 switch (switchCase) { 344 case WASMSwitchCase::CaseWithNoStatements: 345 case WASMSwitchCase::CaseWithStatement: 346 case WASMSwitchCase::CaseWithBlockStatement: { 347 uint32_t value; 348 READ_COMPACT_INT32_OR_FAIL(value, "Cannot read the value of the switch case."); 349 if (switchCase == WASMSwitchCase::CaseWithStatement) { 350 parseStatement(context); 351 PROPAGATE_ERROR(); 352 } else if (switchCase == WASMSwitchCase::CaseWithBlockStatement) { 353 parseBlockStatement(context); 354 PROPAGATE_ERROR(); 355 } 356 break; 357 } 358 case WASMSwitchCase::DefaultWithNoStatements: 359 case WASMSwitchCase::DefaultWithStatement: 360 case WASMSwitchCase::DefaultWithBlockStatement: { 361 FAIL_IF_FALSE(i == numberOfCases - 1, "The default case must be the last case."); 362 if (switchCase == WASMSwitchCase::DefaultWithStatement) { 363 parseStatement(context); 364 PROPAGATE_ERROR(); 365 } else if (switchCase == WASMSwitchCase::DefaultWithBlockStatement) { 366 parseBlockStatement(context); 367 PROPAGATE_ERROR(); 368 } 369 break; 370 } 371 default: 372 ASSERT_NOT_REACHED(); 373 } 374 } 375 m_breakScopeDepth--; 376 // FIXME: Implement this instruction. 206 377 return UNUSED; 207 378 } -
trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.h
r188778 r188808 48 48 , m_reader(static_cast<WebAssemblySourceProvider*>(source.provider())->data()) 49 49 , m_functionIndex(functionIndex) 50 , m_breakScopeDepth(0) 51 , m_continueScopeDepth(0) 52 , m_labelDepth(0) 50 53 { 51 54 } … … 59 62 template <class Context> ContextStatement parseReturnStatement(Context&); 60 63 template <class Context> ContextStatement parseBlockStatement(Context&); 64 template <class Context> ContextStatement parseIfStatement(Context&); 65 template <class Context> ContextStatement parseIfElseStatement(Context&); 66 template <class Context> ContextStatement parseWhileStatement(Context&); 67 template <class Context> ContextStatement parseDoStatement(Context&); 68 template <class Context> ContextStatement parseLabelStatement(Context&); 69 template <class Context> ContextStatement parseBreakStatement(Context&); 70 template <class Context> ContextStatement parseBreakLabelStatement(Context&); 71 template <class Context> ContextStatement parseContinueStatement(Context&); 72 template <class Context> ContextStatement parseContinueLabelStatement(Context&); 73 template <class Context> ContextStatement parseSwitchStatement(Context&); 61 74 62 75 template <class Context> ContextExpression parseExpression(Context&, WASMExpressionType); … … 76 89 uint32_t m_numberOfF32LocalVariables; 77 90 uint32_t m_numberOfF64LocalVariables; 91 92 unsigned m_breakScopeDepth; 93 unsigned m_continueScopeDepth; 94 unsigned m_labelDepth; 78 95 }; 79 96 -
trunk/Source/JavaScriptCore/wasm/WASMReader.cpp
r188778 r188808 94 94 m_cursor += 8; 95 95 return true; 96 } 97 98 bool WASMReader::readCompactInt32(uint32_t& result) 99 { 100 uint32_t sum = 0; 101 unsigned shift = 0; 102 do { 103 CHECK_READ(1); 104 uint8_t byte = *m_cursor++; 105 if (byte < 0x80) { 106 sum |= byte << shift; 107 int signExtend = (32 - 7) - shift; 108 if (signExtend > 0) 109 result = int32_t(sum) << signExtend >> signExtend; 110 else 111 result = int32_t(sum); 112 return true; 113 } 114 sum |= (byte & firstSevenBitsMask) << shift; 115 shift += 7; 116 } while (shift < 35); 117 return false; 96 118 } 97 119 … … 198 220 } 199 221 222 bool WASMReader::readSwitchCase(WASMSwitchCase& result) 223 { 224 return readByte<WASMSwitchCase>(result, static_cast<uint8_t>(WASMSwitchCase::NumberOfSwitchCases)); 225 } 226 200 227 } // namespace JSC 201 228 -
trunk/Source/JavaScriptCore/wasm/WASMReader.h
r188778 r188808 49 49 bool readFloat(float& result); 50 50 bool readDouble(double& result); 51 bool readCompactInt32(uint32_t& result); 51 52 bool readCompactUInt32(uint32_t& result); 52 53 bool readString(String& result); … … 57 58 bool readOpExpressionI32(bool& hasImmediate, WASMOpExpressionI32&, WASMOpExpressionI32WithImmediate&, uint8_t& immediate); 58 59 bool readVariableTypes(bool& hasImmediate, WASMVariableTypes&, WASMVariableTypesWithImmediate&, uint8_t& immediate); 60 bool readSwitchCase(WASMSwitchCase& result); 59 61 60 62 private:
Note: See TracChangeset
for help on using the changeset viewer.