Changeset 190062 in webkit
- Timestamp:
- Sep 21, 2015 11:47:38 AM (9 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r190043 r190062 1 2015-09-21 Sukolsak Sakshuwong <sukolsak@gmail.com> 2 3 Implement Store expressions in WebAssembly 4 https://bugs.webkit.org/show_bug.cgi?id=149395 5 6 Reviewed by Geoffrey Garen. 7 8 The Store instruction in WebAssembly stores a value in the linear memory 9 at the given index. It can be both a statement and an expression. When 10 it is an expression, it returns the assigned value. This patch 11 implements Store as an expression. 12 13 Since Store uses two operands, which are the index and the value, we 14 need to pop the two operands from the stack and push the value back to 15 the stack. We can simply implement this by copying the value to where 16 the index is in the stack. 17 18 * tests/stress/wasm-linear-memory.js: 19 * wasm/WASMFunctionCompiler.h: 20 (JSC::WASMFunctionCompiler::buildStore): 21 * wasm/WASMFunctionParser.cpp: 22 (JSC::WASMFunctionParser::parseStatement): 23 (JSC::WASMFunctionParser::parseExpressionI32): 24 (JSC::WASMFunctionParser::parseExpressionF32): 25 (JSC::WASMFunctionParser::parseExpressionF64): 26 (JSC::WASMFunctionParser::parseStore): 27 * wasm/WASMFunctionParser.h: 28 * wasm/WASMFunctionSyntaxChecker.h: 29 (JSC::WASMFunctionSyntaxChecker::buildStore): 30 1 31 2015-09-20 Sukolsak Sakshuwong <sukolsak@gmail.com> 2 32 -
trunk/Source/JavaScriptCore/tests/stress/wasm-linear-memory.js
r189993 r190062 111 111 } 112 112 113 function setInt8Expression(i, x) { 114 i = i | 0; 115 x = x | 0; 116 return (int8Array[i] = x) | 0; 117 } 118 119 function setUint8Expression(i, x) { 120 i = i | 0; 121 x = x | 0; 122 return (uint8Array[i] = x) | 0; 123 } 124 125 function setInt16Expression(i, x) { 126 i = i | 0; 127 x = x | 0; 128 return (int16Array[i >> 1] = x) | 0; 129 } 130 131 function setUint16Expression(i, x) { 132 i = i | 0; 133 x = x | 0; 134 return (uint16Array[i >> 1] = x) | 0; 135 } 136 137 function setInt32Expression(i, x) { 138 i = i | 0; 139 x = x | 0; 140 return (int32Array[i >> 2] = x) | 0; 141 } 142 143 function setFloat32Expression(i, x) { 144 i = i | 0; 145 x = fround(x); 146 return float32Array[i >> 2] = x; 147 } 148 149 function setFloat64Expression(i, x) { 150 i = i | 0; 151 x = +x; 152 return float64Array[i >> 3] = x; 153 } 154 113 155 return { 114 156 getInt8: getInt8, … … 119 161 getFloat32: getFloat32, 120 162 getFloat64: getFloat64, 163 121 164 setInt8: setInt8, 122 165 setUint8: setUint8, … … 126 169 setFloat32: setFloat32, 127 170 setFloat64: setFloat64, 171 172 setInt8Expression: setInt8Expression, 173 setUint8Expression: setUint8Expression, 174 setInt16Expression: setInt16Expression, 175 setUint16Expression: setUint16Expression, 176 setInt32Expression: setInt32Expression, 177 setFloat32Expression: setFloat32Expression, 178 setFloat64Expression: setFloat64Expression, 128 179 }; 129 180 } … … 203 254 module.setInt32(8, 6); 204 255 shouldBe(int32Array[0] == 1 && int32Array[1] == 5 && int32Array[2] == 6, true); 256 257 // Store expressions. 258 shouldBe(module.setInt8Expression(0, 1), 1); 259 shouldBe(module.getInt8(0), 1); 260 shouldBe(module.setUint8Expression(0, -1), -1); 261 shouldBe(module.getUint8(0), 255); 262 shouldBe(module.setInt16Expression(0, 2), 2); 263 shouldBe(module.getInt16(0), 2); 264 shouldBe(module.setUint16Expression(0, -1), -1); 265 shouldBe(module.getUint16(0), 65535); 266 shouldBe(module.setInt32Expression(0, 3), 3); 267 shouldBe(module.getInt32(0), 3); 268 shouldBe(module.setFloat32Expression(0, 4.2), 4.199999809265137); 269 shouldBe(module.getFloat32(0), 4.199999809265137); 270 shouldBe(module.setFloat64Expression(0, 4.2), 4.2); 271 shouldBe(module.getFloat64(0), 4.2); -
trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h
r190043 r190062 533 533 } 534 534 535 int buildStore( const MemoryAddress& memoryAddress, WASMExpressionType expressionType, WASMMemoryType memoryType, int)535 int buildStore(WASMOpKind opKind, const MemoryAddress& memoryAddress, WASMExpressionType expressionType, WASMMemoryType memoryType, int) 536 536 { 537 537 const ArrayBuffer* arrayBuffer = m_module->arrayBuffer()->impl(); … … 581 581 } 582 582 m_tempStackTop -= 2; 583 584 if (opKind == WASMOpKind::Expression) { 585 switch (expressionType) { 586 case WASMExpressionType::I32: 587 case WASMExpressionType::F32: 588 store32(GPRInfo::regT2, temporaryAddress(m_tempStackTop++)); 589 break; 590 case WASMExpressionType::F64: 591 storeDouble(FPRInfo::fpRegT0, temporaryAddress(m_tempStackTop++)); 592 break; 593 default: 594 ASSERT_NOT_REACHED(); 595 } 596 } 583 597 return UNUSED; 584 598 } -
trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.cpp
r190055 r190062 159 159 break; 160 160 case WASMOpStatement::I32Store8: 161 parseStore(context, WASM ExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::NoOffset);161 parseStore(context, WASMOpKind::Statement, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::NoOffset); 162 162 break; 163 163 case WASMOpStatement::I32StoreWithOffset8: 164 parseStore(context, WASM ExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::WithOffset);164 parseStore(context, WASMOpKind::Statement, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::WithOffset); 165 165 break; 166 166 case WASMOpStatement::I32Store16: 167 parseStore(context, WASM ExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::NoOffset);167 parseStore(context, WASMOpKind::Statement, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::NoOffset); 168 168 break; 169 169 case WASMOpStatement::I32StoreWithOffset16: 170 parseStore(context, WASM ExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::WithOffset);170 parseStore(context, WASMOpKind::Statement, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::WithOffset); 171 171 break; 172 172 case WASMOpStatement::I32Store32: 173 parseStore(context, WASM ExpressionType::I32, WASMMemoryType::I32, MemoryAccessOffsetMode::NoOffset);173 parseStore(context, WASMOpKind::Statement, WASMExpressionType::I32, WASMMemoryType::I32, MemoryAccessOffsetMode::NoOffset); 174 174 break; 175 175 case WASMOpStatement::I32StoreWithOffset32: 176 parseStore(context, WASM ExpressionType::I32, WASMMemoryType::I32, MemoryAccessOffsetMode::WithOffset);176 parseStore(context, WASMOpKind::Statement, WASMExpressionType::I32, WASMMemoryType::I32, MemoryAccessOffsetMode::WithOffset); 177 177 break; 178 178 case WASMOpStatement::F32Store: 179 parseStore(context, WASM ExpressionType::F32, WASMMemoryType::F32, MemoryAccessOffsetMode::NoOffset);179 parseStore(context, WASMOpKind::Statement, WASMExpressionType::F32, WASMMemoryType::F32, MemoryAccessOffsetMode::NoOffset); 180 180 break; 181 181 case WASMOpStatement::F32StoreWithOffset: 182 parseStore(context, WASM ExpressionType::F32, WASMMemoryType::F32, MemoryAccessOffsetMode::WithOffset);182 parseStore(context, WASMOpKind::Statement, WASMExpressionType::F32, WASMMemoryType::F32, MemoryAccessOffsetMode::WithOffset); 183 183 break; 184 184 case WASMOpStatement::F64Store: 185 parseStore(context, WASM ExpressionType::F64, WASMMemoryType::F64, MemoryAccessOffsetMode::NoOffset);185 parseStore(context, WASMOpKind::Statement, WASMExpressionType::F64, WASMMemoryType::F64, MemoryAccessOffsetMode::NoOffset); 186 186 break; 187 187 case WASMOpStatement::F64StoreWithOffset: 188 parseStore(context, WASM ExpressionType::F64, WASMMemoryType::F64, MemoryAccessOffsetMode::WithOffset);188 parseStore(context, WASMOpKind::Statement, WASMExpressionType::F64, WASMMemoryType::F64, MemoryAccessOffsetMode::WithOffset); 189 189 break; 190 190 case WASMOpStatement::Return: … … 549 549 case WASMOpExpressionI32::LoadWithOffset32: 550 550 return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I32, MemoryAccessOffsetMode::WithOffset); 551 case WASMOpExpressionI32::Store8: 552 return parseStore(context, WASMOpKind::Expression, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::NoOffset); 553 case WASMOpExpressionI32::StoreWithOffset8: 554 return parseStore(context, WASMOpKind::Expression, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::WithOffset); 555 case WASMOpExpressionI32::Store16: 556 return parseStore(context, WASMOpKind::Expression, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::NoOffset); 557 case WASMOpExpressionI32::StoreWithOffset16: 558 return parseStore(context, WASMOpKind::Expression, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::WithOffset); 559 case WASMOpExpressionI32::Store32: 560 return parseStore(context, WASMOpKind::Expression, WASMExpressionType::I32, WASMMemoryType::I32, MemoryAccessOffsetMode::NoOffset); 561 case WASMOpExpressionI32::StoreWithOffset32: 562 return parseStore(context, WASMOpKind::Expression, WASMExpressionType::I32, WASMMemoryType::I32, MemoryAccessOffsetMode::WithOffset); 551 563 case WASMOpExpressionI32::CallInternal: 552 564 return parseCallInternal(context, WASMExpressionType::I32); … … 604 616 case WASMOpExpressionI32::GreaterThanOrEqualF64: 605 617 return parseRelationalF64ExpressionI32(context, op); 606 case WASMOpExpressionI32::Store8:607 case WASMOpExpressionI32::StoreWithOffset8:608 case WASMOpExpressionI32::Store16:609 case WASMOpExpressionI32::StoreWithOffset16:610 case WASMOpExpressionI32::Store32:611 case WASMOpExpressionI32::StoreWithOffset32:612 618 case WASMOpExpressionI32::Conditional: 613 619 case WASMOpExpressionI32::Comma: … … 739 745 case WASMOpExpressionF32::LoadWithOffset: 740 746 return parseLoad(context, WASMExpressionType::F32, WASMMemoryType::F32, MemoryAccessOffsetMode::WithOffset); 747 case WASMOpExpressionF32::Store: 748 return parseStore(context, WASMOpKind::Expression, WASMExpressionType::F32, WASMMemoryType::F32, MemoryAccessOffsetMode::NoOffset); 749 case WASMOpExpressionF32::StoreWithOffset: 750 return parseStore(context, WASMOpKind::Expression, WASMExpressionType::F32, WASMMemoryType::F32, MemoryAccessOffsetMode::WithOffset); 741 751 case WASMOpExpressionF32::CallInternal: 742 752 return parseCallInternal(context, WASMExpressionType::F32); … … 760 770 case WASMOpExpressionF32::Div: 761 771 return parseBinaryExpressionF32(context, op); 762 case WASMOpExpressionF32::Store:763 case WASMOpExpressionF32::StoreWithOffset:764 772 case WASMOpExpressionF32::Conditional: 765 773 case WASMOpExpressionF32::Comma: … … 849 857 case WASMOpExpressionF64::LoadWithOffset: 850 858 return parseLoad(context, WASMExpressionType::F64, WASMMemoryType::F64, MemoryAccessOffsetMode::WithOffset); 859 case WASMOpExpressionF64::Store: 860 return parseStore(context, WASMOpKind::Expression, WASMExpressionType::F64, WASMMemoryType::F64, MemoryAccessOffsetMode::NoOffset); 861 case WASMOpExpressionF64::StoreWithOffset: 862 return parseStore(context, WASMOpKind::Expression, WASMExpressionType::F64, WASMMemoryType::F64, MemoryAccessOffsetMode::WithOffset); 851 863 case WASMOpExpressionF64::CallInternal: 852 864 return parseCallInternal(context, WASMExpressionType::F64); … … 883 895 case WASMOpExpressionF64::Pow: 884 896 return parseBinaryExpressionF64(context, op); 885 case WASMOpExpressionF64::Store:886 case WASMOpExpressionF64::StoreWithOffset:887 897 case WASMOpExpressionF64::Conditional: 888 898 case WASMOpExpressionF64::Comma: … … 1035 1045 1036 1046 template <class Context> 1037 ContextExpression WASMFunctionParser::parseStore(Context& context, WASM ExpressionType expressionType, WASMMemoryType memoryType, MemoryAccessOffsetMode offsetMode)1047 ContextExpression WASMFunctionParser::parseStore(Context& context, WASMOpKind opKind, WASMExpressionType expressionType, WASMMemoryType memoryType, MemoryAccessOffsetMode offsetMode) 1038 1048 { 1039 1049 FAIL_IF_FALSE(m_module->arrayBuffer(), "An ArrayBuffer is not provided."); … … 1043 1053 ContextExpression value = parseExpression(context, expressionType); 1044 1054 PROPAGATE_ERROR(); 1045 return context.buildStore( memoryAddress, expressionType, memoryType, value);1055 return context.buildStore(opKind, memoryAddress, expressionType, memoryType, value); 1046 1056 } 1047 1057 -
trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.h
r190043 r190062 113 113 template <class Context> ContextMemoryAddress parseMemoryAddress(Context&, MemoryAccessOffsetMode); 114 114 template <class Context> ContextExpression parseLoad(Context&, WASMExpressionType, WASMMemoryType, MemoryAccessOffsetMode, MemoryAccessConversion = MemoryAccessConversion::NoConversion); 115 template <class Context> ContextExpression parseStore(Context&, WASM ExpressionType, WASMMemoryType, MemoryAccessOffsetMode);115 template <class Context> ContextExpression parseStore(Context&, WASMOpKind, WASMExpressionType, WASMMemoryType, MemoryAccessOffsetMode); 116 116 template <class Context> ContextExpressionList parseCallArguments(Context&, const Vector<WASMType>& arguments); 117 117 template <class Context> ContextExpression parseCallInternal(Context&, WASMExpressionType returnType); -
trunk/Source/JavaScriptCore/wasm/WASMFunctionSyntaxChecker.h
r190043 r190062 120 120 } 121 121 122 int buildStore( const MemoryAddress&, WASMExpressionType, WASMMemoryType, int)122 int buildStore(WASMOpKind opKind, const MemoryAddress&, WASMExpressionType, WASMMemoryType, int) 123 123 { 124 124 m_tempStackTop -= 2; 125 if (opKind == WASMOpKind::Expression) 126 m_tempStackTop++; 125 127 return UNUSED; 126 128 }
Note: See TracChangeset
for help on using the changeset viewer.