Changeset 189993 in webkit
- Timestamp:
- Sep 18, 2015 4:06:47 PM (9 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 2 added
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r189984 r189993 1 2015-09-18 Sukolsak Sakshuwong <sukolsak@gmail.com> 2 3 Implement linear memory instructions in WebAssembly 4 https://bugs.webkit.org/show_bug.cgi?id=149326 5 6 Reviewed by Geoffrey Garen. 7 8 This patch implements linear memory instructions in WebAssembly.[1] To 9 use the linear memory, an ArrayBuffer must be passed to loadWebAssembly(). 10 11 Notes: 12 - We limit the ArrayBuffer's byte length to 2^31 - 1. This enables us to 13 use only one comparison (unsigned greater than) to check for 14 out-of-bounds access. 15 - There is no consensus yet on what should happen when an out-of-bounds 16 access occurs.[2] For now, we throw an error when that happens. 17 - In asm.js, a heap access looks like this: int32Array[i >> 2]. Note 18 that ">> 2" is part of the syntax and is required. pack-asmjs will 19 produce bytecodes that look something like "LoadI32, i" (not 20 "LoadI32, ShiftRightI32, i, 2"). The requirement of the shift operator 21 prevents unaligned accesses in asm.js. (There is a proposal to support 22 unaligned accesses in the future version of asm.js using DataView.[3]) 23 The WebAssembly spec allows unaligned accesses.[4] But since we use 24 asm.js for testing, we follow asm.js's behaviors for now. 25 26 [1]: https://github.com/WebAssembly/design/blob/master/AstSemantics.md#linear-memory 27 [2]: https://github.com/WebAssembly/design/blob/master/AstSemantics.md#out-of-bounds 28 [3]: https://wiki.mozilla.org/Javascript:SpiderMonkey:OdinMonkey#Possible_asm.js_extensions_that_don.27t_require_new_JS_features 29 [4]: https://github.com/WebAssembly/design/blob/master/AstSemantics.md#alignment 30 31 * jit/JITOperations.cpp: 32 * jit/JITOperations.h: 33 * jsc.cpp: 34 (GlobalObject::finishCreation): 35 (functionLoadWebAssembly): 36 * tests/stress/wasm-linear-memory.js: Added. 37 (shouldBe): 38 (shouldThrow): 39 * tests/stress/wasm/linear-memory.wasm: Added. 40 * wasm/JSWASMModule.cpp: 41 (JSC::JSWASMModule::JSWASMModule): 42 (JSC::JSWASMModule::visitChildren): 43 * wasm/JSWASMModule.h: 44 (JSC::JSWASMModule::create): 45 (JSC::JSWASMModule::arrayBuffer): 46 (JSC::JSWASMModule::JSWASMModule): Deleted. 47 * wasm/WASMConstants.h: 48 * wasm/WASMFunctionCompiler.h: 49 (JSC::sizeOfMemoryType): 50 (JSC::WASMFunctionCompiler::MemoryAddress::MemoryAddress): 51 (JSC::WASMFunctionCompiler::endFunction): 52 (JSC::WASMFunctionCompiler::buildLoad): 53 (JSC::WASMFunctionCompiler::buildStore): 54 * wasm/WASMFunctionParser.cpp: 55 (JSC::WASMFunctionParser::parseStatement): 56 (JSC::WASMFunctionParser::parseExpressionI32): 57 (JSC::WASMFunctionParser::parseExpressionF32): 58 (JSC::WASMFunctionParser::parseExpressionF64): 59 (JSC::WASMFunctionParser::parseMemoryAddress): 60 (JSC::WASMFunctionParser::parseLoad): 61 (JSC::WASMFunctionParser::parseStore): 62 * wasm/WASMFunctionParser.h: 63 * wasm/WASMFunctionSyntaxChecker.h: 64 (JSC::WASMFunctionSyntaxChecker::MemoryAddress::MemoryAddress): 65 (JSC::WASMFunctionSyntaxChecker::buildLoad): 66 (JSC::WASMFunctionSyntaxChecker::buildStore): 67 * wasm/WASMModuleParser.cpp: 68 (JSC::WASMModuleParser::WASMModuleParser): 69 (JSC::WASMModuleParser::parseModule): 70 (JSC::parseWebAssembly): 71 (JSC::WASMModuleParser::parse): Deleted. 72 * wasm/WASMModuleParser.h: 73 1 74 2015-09-18 Sukolsak Sakshuwong <sukolsak@gmail.com> 2 75 -
trunk/Source/JavaScriptCore/jit/JITOperations.cpp
r189967 r189993 106 106 vm->throwException(callerFrame, createError(callerFrame, ASCIILiteral("Division by zero or division overflow."))); 107 107 } 108 109 void JIT_OPERATION operationThrowOutOfBoundsAccessError(ExecState* exec) 110 { 111 VM* vm = &exec->vm(); 112 VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame; 113 CallFrame* callerFrame = exec->callerFrame(vmEntryFrame); 114 115 NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame); 116 ErrorHandlingScope errorScope(*vm); 117 vm->throwException(callerFrame, createError(callerFrame, ASCIILiteral("Out-of-bounds access."))); 118 } 108 119 #endif 109 120 -
trunk/Source/JavaScriptCore/jit/JITOperations.h
r189920 r189993 252 252 #if ENABLE(WEBASSEMBLY) 253 253 void JIT_OPERATION operationThrowDivideError(ExecState*) WTF_INTERNAL; 254 void JIT_OPERATION operationThrowOutOfBoundsAccessError(ExecState*) WTF_INTERNAL; 254 255 #endif 255 256 int32_t JIT_OPERATION operationCallArityCheck(ExecState*) WTF_INTERNAL; -
trunk/Source/JavaScriptCore/jsc.cpp
r189941 r189993 678 678 679 679 #if ENABLE(WEBASSEMBLY) 680 addFunction(vm, "loadWebAssembly", functionLoadWebAssembly, 2);680 addFunction(vm, "loadWebAssembly", functionLoadWebAssembly, 3); 681 681 #endif 682 682 addFunction(vm, "loadModule", functionLoadModule, 1); … … 1451 1451 SourceCode source(sourceProvider); 1452 1452 JSObject* imports = exec->argument(1).getObject(); 1453 JSArrayBuffer* arrayBuffer = jsDynamicCast<JSArrayBuffer*>(exec->argument(2)); 1453 1454 1454 1455 String errorMessage; 1455 JSWASMModule* module = parseWebAssembly(exec, source, imports, errorMessage);1456 JSWASMModule* module = parseWebAssembly(exec, source, imports, arrayBuffer, errorMessage); 1456 1457 if (!module) 1457 1458 return JSValue::encode(exec->vm().throwException(exec, createSyntaxError(exec, errorMessage))); -
trunk/Source/JavaScriptCore/wasm/JSWASMModule.cpp
r189822 r189993 29 29 #if ENABLE(WEBASSEMBLY) 30 30 31 #include "JSArrayBuffer.h" 31 32 #include "JSFunction.h" 32 33 #include "SlotVisitorInlines.h" … … 35 36 36 37 const ClassInfo JSWASMModule::s_info = { "WASMModule", &Base::s_info, 0, CREATE_METHOD_TABLE(JSWASMModule) }; 38 39 JSWASMModule::JSWASMModule(VM& vm, Structure* structure, JSArrayBuffer* arrayBuffer) 40 : Base(vm, structure) 41 { 42 if (arrayBuffer) 43 m_arrayBuffer.set(vm, this, arrayBuffer); 44 } 37 45 38 46 void JSWASMModule::destroy(JSCell* cell) … … 47 55 ASSERT_GC_OBJECT_INHERITS(thisObject, info()); 48 56 Base::visitChildren(thisObject, visitor); 57 visitor.append(&thisObject->m_arrayBuffer); 49 58 for (auto function : thisObject->m_functions) 50 59 visitor.append(&function); -
trunk/Source/JavaScriptCore/wasm/JSWASMModule.h
r189822 r189993 57 57 }; 58 58 59 static JSWASMModule* create(VM& vm, Structure* structure )59 static JSWASMModule* create(VM& vm, Structure* structure, JSArrayBuffer* arrayBuffer) 60 60 { 61 JSWASMModule* module = new (NotNull, allocateCell<JSWASMModule>(vm.heap)) JSWASMModule(vm, structure );61 JSWASMModule* module = new (NotNull, allocateCell<JSWASMModule>(vm.heap)) JSWASMModule(vm, structure, arrayBuffer); 62 62 module->finishCreation(vm); 63 63 return module; … … 84 84 Vector<WASMFunctionPointerTable>& functionPointerTables() { return m_functionPointerTables; } 85 85 86 const JSArrayBuffer* arrayBuffer() const { return m_arrayBuffer.get(); } 86 87 Vector<WriteBarrier<JSFunction>>& functions() { return m_functions; } 87 88 Vector<unsigned>& functionStartOffsetsInSource() { return m_functionStartOffsetsInSource; } … … 91 92 92 93 private: 93 JSWASMModule(VM& vm, Structure* structure) 94 : Base(vm, structure) 95 { 96 } 94 JSWASMModule(VM&, Structure*, JSArrayBuffer*); 97 95 98 96 Vector<uint32_t> m_i32Constants; … … 106 104 Vector<WASMFunctionPointerTable> m_functionPointerTables; 107 105 106 WriteBarrier<JSArrayBuffer> m_arrayBuffer; 108 107 Vector<WriteBarrier<JSFunction>> m_functions; 109 108 Vector<unsigned> m_functionStartOffsetsInSource; -
trunk/Source/JavaScriptCore/wasm/WASMConstants.h
r189984 r189993 292 292 }; 293 293 294 enum class WASMMemoryType { 295 I8, 296 I16, 297 I32, 298 F32, 299 F64 300 }; 301 302 enum class MemoryAccessOffsetMode { NoOffset, WithOffset }; 303 enum class MemoryAccessConversion { NoConversion, SignExtend, ZeroExtend }; 304 294 305 static const uint8_t hasImmediateInOpFlag = 0x80; 295 306 -
trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h
r189984 r189993 33 33 #include "JIT.h" 34 34 #include "JITOperations.h" 35 #include "JSArrayBuffer.h" 35 36 #include "LinkBuffer.h" 36 37 #include "MaxFrameExtentForSlowPathCall.h" … … 79 80 #endif 80 81 82 static size_t sizeOfMemoryType(WASMMemoryType memoryType) 83 { 84 switch (memoryType) { 85 case WASMMemoryType::I8: 86 return 1; 87 case WASMMemoryType::I16: 88 return 2; 89 case WASMMemoryType::I32: 90 case WASMMemoryType::F32: 91 return 4; 92 case WASMMemoryType::F64: 93 return 8; 94 default: 95 ASSERT_NOT_REACHED(); 96 } 97 } 98 81 99 class WASMFunctionCompiler : private CCallHelpers { 82 100 public: … … 84 102 typedef int Statement; 85 103 typedef int ExpressionList; 104 struct MemoryAddress { 105 MemoryAddress(void*) { } 106 MemoryAddress(int, uint32_t offset) 107 : offset(offset) 108 { 109 } 110 uint32_t offset; 111 }; 86 112 struct JumpTarget { 87 113 Label label; … … 198 224 setupArgumentsExecState(); 199 225 appendCallWithExceptionCheck(operationThrowDivideError); 226 } 227 228 if (!m_outOfBoundsErrorJumpList.empty()) { 229 m_outOfBoundsErrorJumpList.link(this); 230 231 setupArgumentsExecState(); 232 appendCallWithExceptionCheck(operationThrowOutOfBoundsAccessError); 200 233 } 201 234 … … 434 467 ASSERT_NOT_REACHED(); 435 468 } 469 return UNUSED; 470 } 471 472 int buildLoad(const MemoryAddress& memoryAddress, WASMExpressionType expressionType, WASMMemoryType memoryType, MemoryAccessConversion conversion) 473 { 474 const ArrayBuffer* arrayBuffer = m_module->arrayBuffer()->impl(); 475 move(TrustedImmPtr(arrayBuffer->data()), GPRInfo::regT0); 476 load32(temporaryAddress(m_tempStackTop - 1), GPRInfo::regT1); 477 if (memoryAddress.offset) 478 add32(TrustedImm32(memoryAddress.offset), GPRInfo::regT1, GPRInfo::regT1); 479 and32(TrustedImm32(~(sizeOfMemoryType(memoryType) - 1)), GPRInfo::regT1); 480 481 ASSERT(arrayBuffer->byteLength() < (unsigned)(1 << 31)); 482 if (arrayBuffer->byteLength() >= sizeOfMemoryType(memoryType)) 483 m_outOfBoundsErrorJumpList.append(branch32(Above, GPRInfo::regT1, TrustedImm32(arrayBuffer->byteLength() - sizeOfMemoryType(memoryType)))); 484 else 485 m_outOfBoundsErrorJumpList.append(jump()); 486 487 BaseIndex address = BaseIndex(GPRInfo::regT0, GPRInfo::regT1, TimesOne); 488 489 switch (expressionType) { 490 case WASMExpressionType::I32: 491 switch (memoryType) { 492 case WASMMemoryType::I8: 493 if (conversion == MemoryAccessConversion::SignExtend) 494 load8SignedExtendTo32(address, GPRInfo::regT0); 495 else { 496 ASSERT(conversion == MemoryAccessConversion::ZeroExtend); 497 load8(address, GPRInfo::regT0); 498 } 499 break; 500 case WASMMemoryType::I16: 501 if (conversion == MemoryAccessConversion::SignExtend) 502 load16SignedExtendTo32(address, GPRInfo::regT0); 503 else { 504 ASSERT(conversion == MemoryAccessConversion::ZeroExtend); 505 load16(address, GPRInfo::regT0); 506 } 507 break; 508 case WASMMemoryType::I32: 509 load32(address, GPRInfo::regT0); 510 break; 511 default: 512 ASSERT_NOT_REACHED(); 513 } 514 store32(GPRInfo::regT0, temporaryAddress(m_tempStackTop - 1)); 515 break; 516 case WASMExpressionType::F32: 517 ASSERT(memoryType == WASMMemoryType::F32 && conversion == MemoryAccessConversion::NoConversion); 518 load32(address, GPRInfo::regT0); 519 store32(GPRInfo::regT0, temporaryAddress(m_tempStackTop - 1)); 520 break; 521 case WASMExpressionType::F64: 522 ASSERT(memoryType == WASMMemoryType::F64 && conversion == MemoryAccessConversion::NoConversion); 523 loadDouble(address, FPRInfo::fpRegT0); 524 storeDouble(FPRInfo::fpRegT0, temporaryAddress(m_tempStackTop - 1)); 525 break; 526 default: 527 ASSERT_NOT_REACHED(); 528 } 529 return UNUSED; 530 } 531 532 int buildStore(const MemoryAddress& memoryAddress, WASMExpressionType expressionType, WASMMemoryType memoryType, int) 533 { 534 const ArrayBuffer* arrayBuffer = m_module->arrayBuffer()->impl(); 535 move(TrustedImmPtr(arrayBuffer->data()), GPRInfo::regT0); 536 load32(temporaryAddress(m_tempStackTop - 2), GPRInfo::regT1); 537 if (memoryAddress.offset) 538 add32(TrustedImm32(memoryAddress.offset), GPRInfo::regT1, GPRInfo::regT1); 539 and32(TrustedImm32(~(sizeOfMemoryType(memoryType) - 1)), GPRInfo::regT1); 540 541 ASSERT(arrayBuffer->byteLength() < (1u << 31)); 542 if (arrayBuffer->byteLength() >= sizeOfMemoryType(memoryType)) 543 m_outOfBoundsErrorJumpList.append(branch32(Above, GPRInfo::regT1, TrustedImm32(arrayBuffer->byteLength() - sizeOfMemoryType(memoryType)))); 544 else 545 m_outOfBoundsErrorJumpList.append(jump()); 546 547 BaseIndex address = BaseIndex(GPRInfo::regT0, GPRInfo::regT1, TimesOne); 548 549 switch (expressionType) { 550 case WASMExpressionType::I32: 551 load32(temporaryAddress(m_tempStackTop - 1), GPRInfo::regT2); 552 switch (memoryType) { 553 case WASMMemoryType::I8: 554 store8(GPRInfo::regT2, address); 555 break; 556 case WASMMemoryType::I16: 557 store16(GPRInfo::regT2, address); 558 break; 559 case WASMMemoryType::I32: 560 store32(GPRInfo::regT2, address); 561 break; 562 default: 563 ASSERT_NOT_REACHED(); 564 } 565 break; 566 case WASMExpressionType::F32: 567 ASSERT(memoryType == WASMMemoryType::F32); 568 load32(temporaryAddress(m_tempStackTop - 1), GPRInfo::regT2); 569 store32(GPRInfo::regT2, address); 570 break; 571 case WASMExpressionType::F64: 572 ASSERT(memoryType == WASMMemoryType::F64); 573 loadDouble(temporaryAddress(m_tempStackTop - 1), FPRInfo::fpRegT0); 574 storeDouble(FPRInfo::fpRegT0, address); 575 break; 576 default: 577 ASSERT_NOT_REACHED(); 578 } 579 m_tempStackTop -= 2; 436 580 return UNUSED; 437 581 } … … 1187 1331 Jump m_stackOverflow; 1188 1332 JumpList m_divideErrorJumpList; 1333 JumpList m_outOfBoundsErrorJumpList; 1189 1334 JumpList m_exceptionChecks; 1190 1335 -
trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.cpp
r189984 r189993 144 144 parseSetGlobalStatement(context); 145 145 break; 146 case WASMOpStatement::I32Store8: 147 parseStore(context, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::NoOffset); 148 break; 149 case WASMOpStatement::I32StoreWithOffset8: 150 parseStore(context, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::WithOffset); 151 break; 152 case WASMOpStatement::I32Store16: 153 parseStore(context, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::NoOffset); 154 break; 155 case WASMOpStatement::I32StoreWithOffset16: 156 parseStore(context, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::WithOffset); 157 break; 158 case WASMOpStatement::I32Store32: 159 parseStore(context, WASMExpressionType::I32, WASMMemoryType::I32, MemoryAccessOffsetMode::NoOffset); 160 break; 161 case WASMOpStatement::I32StoreWithOffset32: 162 parseStore(context, WASMExpressionType::I32, WASMMemoryType::I32, MemoryAccessOffsetMode::WithOffset); 163 break; 164 case WASMOpStatement::F32Store: 165 parseStore(context, WASMExpressionType::F32, WASMMemoryType::F32, MemoryAccessOffsetMode::NoOffset); 166 break; 167 case WASMOpStatement::F32StoreWithOffset: 168 parseStore(context, WASMExpressionType::F32, WASMMemoryType::F32, MemoryAccessOffsetMode::WithOffset); 169 break; 170 case WASMOpStatement::F64Store: 171 parseStore(context, WASMExpressionType::F64, WASMMemoryType::F64, MemoryAccessOffsetMode::NoOffset); 172 break; 173 case WASMOpStatement::F64StoreWithOffset: 174 parseStore(context, WASMExpressionType::F64, WASMMemoryType::F64, MemoryAccessOffsetMode::WithOffset); 175 break; 146 176 case WASMOpStatement::Return: 147 177 parseReturnStatement(context); … … 180 210 parseSwitchStatement(context); 181 211 break; 182 case WASMOpStatement::I32Store8:183 case WASMOpStatement::I32StoreWithOffset8:184 case WASMOpStatement::I32Store16:185 case WASMOpStatement::I32StoreWithOffset16:186 case WASMOpStatement::I32Store32:187 case WASMOpStatement::I32StoreWithOffset32:188 case WASMOpStatement::F32Store:189 case WASMOpStatement::F32StoreWithOffset:190 case WASMOpStatement::F64Store:191 case WASMOpStatement::F64StoreWithOffset:192 212 case WASMOpStatement::CallInternal: 193 213 case WASMOpStatement::CallIndirect: … … 529 549 case WASMOpExpressionI32::GetGlobal: 530 550 return parseGetGlobalExpressionI32(context); 551 case WASMOpExpressionI32::SLoad8: 552 return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::NoOffset, MemoryAccessConversion::SignExtend); 553 case WASMOpExpressionI32::SLoadWithOffset8: 554 return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::WithOffset, MemoryAccessConversion::SignExtend); 555 case WASMOpExpressionI32::ULoad8: 556 return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::NoOffset, MemoryAccessConversion::ZeroExtend); 557 case WASMOpExpressionI32::ULoadWithOffset8: 558 return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::WithOffset, MemoryAccessConversion::ZeroExtend); 559 case WASMOpExpressionI32::SLoad16: 560 return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::NoOffset, MemoryAccessConversion::SignExtend); 561 case WASMOpExpressionI32::SLoadWithOffset16: 562 return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::WithOffset, MemoryAccessConversion::SignExtend); 563 case WASMOpExpressionI32::ULoad16: 564 return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::NoOffset, MemoryAccessConversion::ZeroExtend); 565 case WASMOpExpressionI32::ULoadWithOffset16: 566 return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::WithOffset, MemoryAccessConversion::ZeroExtend); 567 case WASMOpExpressionI32::Load32: 568 return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I32, MemoryAccessOffsetMode::NoOffset); 569 case WASMOpExpressionI32::LoadWithOffset32: 570 return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I32, MemoryAccessOffsetMode::WithOffset); 531 571 case WASMOpExpressionI32::CallInternal: 532 572 return parseCallInternal(context, WASMExpressionType::I32); … … 586 626 case WASMOpExpressionI32::SetLocal: 587 627 case WASMOpExpressionI32::SetGlobal: 588 case WASMOpExpressionI32::SLoad8:589 case WASMOpExpressionI32::SLoadWithOffset8:590 case WASMOpExpressionI32::ULoad8:591 case WASMOpExpressionI32::ULoadWithOffset8:592 case WASMOpExpressionI32::SLoad16:593 case WASMOpExpressionI32::SLoadWithOffset16:594 case WASMOpExpressionI32::ULoad16:595 case WASMOpExpressionI32::ULoadWithOffset16:596 case WASMOpExpressionI32::Load32:597 case WASMOpExpressionI32::LoadWithOffset32:598 628 case WASMOpExpressionI32::Store8: 599 629 case WASMOpExpressionI32::StoreWithOffset8: … … 749 779 case WASMOpExpressionF32::GetGlobal: 750 780 return parseGetGlobalExpressionF32(context); 781 case WASMOpExpressionF32::Load: 782 return parseLoad(context, WASMExpressionType::F32, WASMMemoryType::F32, MemoryAccessOffsetMode::NoOffset); 783 case WASMOpExpressionF32::LoadWithOffset: 784 return parseLoad(context, WASMExpressionType::F32, WASMMemoryType::F32, MemoryAccessOffsetMode::WithOffset); 751 785 case WASMOpExpressionF32::CallInternal: 752 786 return parseCallInternal(context, WASMExpressionType::F32); … … 772 806 case WASMOpExpressionF32::SetLocal: 773 807 case WASMOpExpressionF32::SetGlobal: 774 case WASMOpExpressionF32::Load:775 case WASMOpExpressionF32::LoadWithOffset:776 808 case WASMOpExpressionF32::Store: 777 809 case WASMOpExpressionF32::StoreWithOffset: … … 881 913 case WASMOpExpressionF64::GetGlobal: 882 914 return parseGetGlobalExpressionF64(context); 915 case WASMOpExpressionF64::Load: 916 return parseLoad(context, WASMExpressionType::F64, WASMMemoryType::F64, MemoryAccessOffsetMode::NoOffset); 917 case WASMOpExpressionF64::LoadWithOffset: 918 return parseLoad(context, WASMExpressionType::F64, WASMMemoryType::F64, MemoryAccessOffsetMode::WithOffset); 883 919 case WASMOpExpressionF64::CallInternal: 884 920 return parseCallInternal(context, WASMExpressionType::F64); … … 895 931 case WASMOpExpressionF64::SetLocal: 896 932 case WASMOpExpressionF64::SetGlobal: 897 case WASMOpExpressionF64::Load:898 case WASMOpExpressionF64::LoadWithOffset:899 933 case WASMOpExpressionF64::Store: 900 934 case WASMOpExpressionF64::StoreWithOffset: … … 991 1025 992 1026 template <class Context> 1027 ContextMemoryAddress WASMFunctionParser::parseMemoryAddress(Context& context, MemoryAccessOffsetMode offsetMode) 1028 { 1029 uint32_t offset = 0; 1030 if (offsetMode == MemoryAccessOffsetMode::WithOffset) 1031 READ_COMPACT_UINT32_OR_FAIL(offset, "Cannot read the address offset."); 1032 ContextExpression index = parseExpressionI32(context); 1033 PROPAGATE_ERROR(); 1034 return ContextMemoryAddress(index, offset); 1035 } 1036 1037 template <class Context> 1038 ContextExpression WASMFunctionParser::parseLoad(Context& context, WASMExpressionType expressionType, WASMMemoryType memoryType, MemoryAccessOffsetMode offsetMode, MemoryAccessConversion conversion) 1039 { 1040 FAIL_IF_FALSE(m_module->arrayBuffer(), "An ArrayBuffer is not provided."); 1041 const ContextMemoryAddress& memoryAddress = parseMemoryAddress(context, offsetMode); 1042 PROPAGATE_ERROR(); 1043 return context.buildLoad(memoryAddress, expressionType, memoryType, conversion); 1044 } 1045 1046 template <class Context> 1047 ContextExpression WASMFunctionParser::parseStore(Context& context, WASMExpressionType expressionType, WASMMemoryType memoryType, MemoryAccessOffsetMode offsetMode) 1048 { 1049 FAIL_IF_FALSE(m_module->arrayBuffer(), "An ArrayBuffer is not provided."); 1050 const ContextMemoryAddress& memoryAddress = parseMemoryAddress(context, offsetMode); 1051 PROPAGATE_ERROR(); 1052 1053 ContextExpression value = parseExpression(context, expressionType); 1054 PROPAGATE_ERROR(); 1055 return context.buildStore(memoryAddress, expressionType, memoryType, value); 1056 } 1057 1058 template <class Context> 993 1059 ContextExpressionList WASMFunctionParser::parseCallArguments(Context& context, const Vector<WASMType>& arguments) 994 1060 { -
trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.h
r189984 r189993 35 35 #define ContextStatement typename Context::Statement 36 36 #define ContextExpressionList typename Context::ExpressionList 37 #define ContextMemoryAddress typename Context::MemoryAddress 37 38 #define ContextJumpTarget typename Context::JumpTarget 38 39 … … 114 115 template <class Context> ContextExpression parseGetGlobalExpressionF64(Context&); 115 116 117 template <class Context> ContextMemoryAddress parseMemoryAddress(Context&, MemoryAccessOffsetMode); 118 template <class Context> ContextExpression parseLoad(Context&, WASMExpressionType, WASMMemoryType, MemoryAccessOffsetMode, MemoryAccessConversion = MemoryAccessConversion::NoConversion); 119 template <class Context> ContextExpression parseStore(Context&, WASMExpressionType, WASMMemoryType, MemoryAccessOffsetMode); 120 116 121 template <class Context> ContextExpressionList parseCallArguments(Context&, const Vector<WASMType>& arguments); 117 122 template <class Context> ContextExpression parseCallInternal(Context&, WASMExpressionType returnType); -
trunk/Source/JavaScriptCore/wasm/WASMFunctionSyntaxChecker.h
r189984 r189993 38 38 typedef int Statement; 39 39 typedef int ExpressionList; 40 struct MemoryAddress { 41 MemoryAddress(void*) { } 42 MemoryAddress(int, uint32_t) { } 43 }; 40 44 typedef int JumpTarget; 41 45 enum class JumpCondition { Zero, NonZero }; … … 104 108 int buildConvertType(int, WASMExpressionType, WASMExpressionType, WASMTypeConversion) 105 109 { 110 return UNUSED; 111 } 112 113 int buildLoad(const MemoryAddress&, WASMExpressionType, WASMMemoryType, MemoryAccessConversion) 114 { 115 return UNUSED; 116 } 117 118 int buildStore(const MemoryAddress&, WASMExpressionType, WASMMemoryType, int) 119 { 120 m_tempStackTop -= 2; 106 121 return UNUSED; 107 122 } -
trunk/Source/JavaScriptCore/wasm/WASMModuleParser.cpp
r189892 r189993 29 29 #if ENABLE(WEBASSEMBLY) 30 30 31 #include "JSArrayBuffer.h" 31 32 #include "JSCInlines.h" 32 33 #include "JSWASMModule.h" … … 50 51 namespace JSC { 51 52 52 WASMModuleParser::WASMModuleParser(VM& vm, JSGlobalObject* globalObject, const SourceCode& source, JSObject* imports )53 WASMModuleParser::WASMModuleParser(VM& vm, JSGlobalObject* globalObject, const SourceCode& source, JSObject* imports, JSArrayBuffer* arrayBuffer) 53 54 : m_vm(vm) 54 55 , m_globalObject(vm, globalObject) … … 56 57 , m_imports(vm, imports) 57 58 , m_reader(static_cast<WebAssemblySourceProvider*>(source.provider())->data()) 59 , m_module(vm, JSWASMModule::create(vm, globalObject->wasmModuleStructure(), arrayBuffer)) 58 60 { 59 61 } … … 61 63 JSWASMModule* WASMModuleParser::parse(ExecState* exec, String& errorMessage) 62 64 { 63 m_module.set(m_vm, JSWASMModule::create(m_vm, m_globalObject->wasmModuleStructure()));64 65 parseModule(exec); 65 66 if (!m_errorMessage.isNull()) { … … 94 95 PROPAGATE_ERROR(); 95 96 parseExportSection(); 97 PROPAGATE_ERROR(); 98 99 FAIL_IF_FALSE(!m_module->arrayBuffer() || m_module->arrayBuffer()->impl()->byteLength() < (1u << 31), "The ArrayBuffer's length must be less than 2^31."); 96 100 } 97 101 … … 363 367 } 364 368 365 JSWASMModule* parseWebAssembly(ExecState* exec, const SourceCode& source, JSObject* imports, String& errorMessage)366 { 367 WASMModuleParser moduleParser(exec->vm(), exec->lexicalGlobalObject(), source, imports );369 JSWASMModule* parseWebAssembly(ExecState* exec, const SourceCode& source, JSObject* imports, JSArrayBuffer* arrayBuffer, String& errorMessage) 370 { 371 WASMModuleParser moduleParser(exec->vm(), exec->lexicalGlobalObject(), source, imports, arrayBuffer); 368 372 return moduleParser.parse(exec, errorMessage); 369 373 } -
trunk/Source/JavaScriptCore/wasm/WASMModuleParser.h
r189846 r189993 36 36 37 37 class ExecState; 38 class JSArrayBuffer; 38 39 class JSGlobalObject; 39 40 class JSWASMModule; … … 43 44 class WASMModuleParser { 44 45 public: 45 WASMModuleParser(VM&, JSGlobalObject*, const SourceCode&, JSObject* imports );46 WASMModuleParser(VM&, JSGlobalObject*, const SourceCode&, JSObject* imports, JSArrayBuffer*); 46 47 JSWASMModule* parse(ExecState*, String& errorMessage); 47 48 … … 68 69 }; 69 70 70 JS_EXPORT_PRIVATE JSWASMModule* parseWebAssembly(ExecState*, const SourceCode&, JSObject* imports, String& errorMessage);71 JS_EXPORT_PRIVATE JSWASMModule* parseWebAssembly(ExecState*, const SourceCode&, JSObject* imports, JSArrayBuffer*, String& errorMessage); 71 72 72 73 } // namespace JSC
Note: See TracChangeset
for help on using the changeset viewer.