Changeset 189582 in webkit
- Timestamp:
- Sep 10, 2015 12:01:47 PM (9 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 2 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r189577 r189582 1 2015-09-10 Sukolsak Sakshuwong <sukolsak@gmail.com> 2 3 Convert arguments to WebAssembly functions to the declared types 4 https://bugs.webkit.org/show_bug.cgi?id=149033 5 6 Reviewed by Geoffrey Garen. 7 8 This patch checks the types of arguments to WebAssembly functions and 9 converts them to the declared types. This is necessary because: 10 - For example, if a function expects an argument of type double and we 11 pass 1.0 to it, it will get a JSValue of an integer, not a double. 12 - We should follow asm.js's behavior for now, because we want to be able 13 to test WebAssembly apps against asm.js apps. asm.js does type 14 coercion on arguments by using int|0, Math.fround(float), and +double. 15 16 * jit/JITOperations.h: 17 * tests/stress/wasm-type-conversion.js: Added. 18 (shouldBe): 19 (two.valueOf): 20 * tests/stress/wasm/type-conversion.wasm: Added. 21 * wasm/WASMFunctionCompiler.h: 22 (JSC::operationConvertJSValueToInt32): 23 (JSC::operationConvertJSValueToDouble): 24 (JSC::WASMFunctionCompiler::startFunction): 25 (JSC::WASMFunctionCompiler::appendCallSetResult): 26 (JSC::WASMFunctionCompiler::callOperation): 27 (JSC::WASMFunctionCompiler::loadValueAndConvertToInt32): 28 (JSC::WASMFunctionCompiler::loadValueAndConvertToDouble): 29 1 30 2015-09-10 Yusuke Suzuki <utatane.tea@gmail.com> 2 31 -
trunk/Source/JavaScriptCore/jit/JITOperations.h
r189504 r189582 174 174 typedef int32_t JIT_OPERATION (*Z_JITOperation_EGC)(ExecState*, JSGlobalObject*, JSCell*); 175 175 typedef int32_t JIT_OPERATION (*Z_JITOperation_ESJss)(ExecState*, size_t, JSString*); 176 typedef int32_t JIT_OPERATION (*Z_JITOperation_EJ)(ExecState*, EncodedJSValue); 176 177 typedef int32_t JIT_OPERATION (*Z_JITOperation_EJZ)(ExecState*, EncodedJSValue, int32_t); 177 178 typedef int32_t JIT_OPERATION (*Z_JITOperation_EJZZ)(ExecState*, EncodedJSValue, int32_t, int32_t); -
trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h
r189563 r189582 39 39 namespace JSC { 40 40 41 static int32_t JIT_OPERATION operationConvertJSValueToInt32(ExecState* exec, EncodedJSValue value) 42 { 43 return JSValue::decode(value).toInt32(exec); 44 } 45 46 static double JIT_OPERATION operationConvertJSValueToDouble(ExecState* exec, EncodedJSValue value) 47 { 48 return JSValue::decode(value).toNumber(exec); 49 } 50 41 51 #if !CPU(X86) && !CPU(X86_64) 42 52 static int32_t JIT_OPERATION operationDiv(int32_t left, int32_t right) … … 99 109 switch (arguments[i]) { 100 110 case WASMType::I32: 101 load32(address, GPRInfo::regT0); 111 #if USE(JSVALUE64) 112 loadValueAndConvertToInt32(address, GPRInfo::regT0); 113 #else 114 loadValueAndConvertToInt32(address, GPRInfo::regT0, GPRInfo::regT1); 115 #endif 102 116 store32(GPRInfo::regT0, localAddress(localIndex++)); 103 117 break; 104 118 case WASMType::F32: 105 load64(address, GPRInfo::regT0);106 unboxDoubleWithoutAssertions(GPRInfo::regT0, FPRInfo::fpRegT0);107 convertDoubleToFloat(FPRInfo::fpRegT0, FPRInfo::fpRegT0);108 storeDouble(FPRInfo::fpRegT0, localAddress(localIndex++));109 break;110 119 case WASMType::F64: 111 load64(address, GPRInfo::regT0); 112 unboxDoubleWithoutAssertions(GPRInfo::regT0, FPRInfo::fpRegT0); 120 #if USE(JSVALUE64) 121 loadValueAndConvertToDouble(address, FPRInfo::fpRegT0, GPRInfo::regT0, GPRInfo::regT1); 122 #else 123 loadValueAndConvertToDouble(address, FPRInfo::fpRegT0, GPRInfo::regT0, GPRInfo::regT1, GPRInfo::regT2, FPRInfo::fpRegT1); 124 #endif 125 if (arguments[i] == WASMType::F32) 126 convertDoubleToFloat(FPRInfo::fpRegT0, FPRInfo::fpRegT0); 113 127 storeDouble(FPRInfo::fpRegT0, localAddress(localIndex++)); 114 128 break; … … 620 634 } 621 635 636 void appendCallSetResult(const FunctionPtr& function, GPRReg result) 637 { 638 appendCall(function); 639 move(GPRInfo::returnValueGPR, result); 640 } 641 642 #if CPU(X86) 643 void appendCallSetResult(const FunctionPtr& function, FPRReg result) 644 { 645 appendCall(function); 646 m_assembler.fstpl(0, stackPointerRegister); 647 loadDouble(stackPointerRegister, result); 648 } 649 #elif CPU(ARM) && !CPU(ARM_HARDFP) 650 void appendCallSetResult(const FunctionPtr& function, FPRReg result) 651 { 652 appendCall(function); 653 m_assembler.vmov(result, GPRInfo::returnValueGPR, GPRInfo::returnValueGPR2); 654 } 655 #else // CPU(X86_64) || (CPU(ARM) && CPU(ARM_HARDFP)) || CPU(ARM64) || CPU(MIPS) || CPU(SH4) 656 void appendCallSetResult(const FunctionPtr& function, FPRReg result) 657 { 658 appendCall(function); 659 moveDouble(FPRInfo::returnValueFPR, result); 660 } 661 #endif 662 663 #if USE(JSVALUE64) 664 void callOperation(Z_JITOperation_EJ operation, GPRReg src, GPRReg dst) 665 { 666 setupArgumentsWithExecState(src); 667 appendCallSetResult(operation, dst); 668 } 669 670 void callOperation(D_JITOperation_EJ operation, GPRReg src, FPRReg dst) 671 { 672 setupArgumentsWithExecState(src); 673 appendCallSetResult(operation, dst); 674 } 675 #else 676 void callOperation(Z_JITOperation_EJ operation, GPRReg srcTag, GPRReg srcPayload, GPRReg dst) 677 { 678 setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG srcPayload, srcTag); 679 appendCallSetResult(operation, dst); 680 } 681 682 void callOperation(D_JITOperation_EJ operation, GPRReg srcTag, GPRReg srcPayload, FPRReg dst) 683 { 684 setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG srcPayload, srcTag); 685 appendCallSetResult(operation, dst); 686 } 687 #endif 688 622 689 void callOperation(int32_t JIT_OPERATION (*operation)(int32_t, int32_t), GPRReg src1, GPRReg src2, GPRReg dst) 623 690 { 624 691 setupArguments(src1, src2); 625 appendCall(operation); 626 move(GPRInfo::returnValueGPR, dst); 692 appendCallSetResult(operation, dst); 627 693 } 628 694 … … 630 696 { 631 697 setupArguments(src1, src2); 632 appendCall(operation); 633 move(GPRInfo::returnValueGPR, dst); 698 appendCallSetResult(operation, dst); 634 699 } 635 700 … … 704 769 } 705 770 771 #if USE(JSVALUE64) 772 void loadValueAndConvertToInt32(Address address, GPRReg dst) 773 { 774 JSValueRegs tempRegs(dst); 775 loadValue(address, tempRegs); 776 Jump checkJSInt32 = branchIfInt32(tempRegs); 777 778 callOperation(operationConvertJSValueToInt32, dst, dst); 779 780 checkJSInt32.link(this); 781 } 782 783 void loadValueAndConvertToDouble(Address address, FPRReg dst, GPRReg scratch1, GPRReg scratch2) 784 { 785 JSValueRegs tempRegs(scratch1); 786 loadValue(address, tempRegs); 787 Jump checkJSInt32 = branchIfInt32(tempRegs); 788 Jump checkJSNumber = branchIfNumber(tempRegs, scratch2); 789 JumpList end; 790 791 callOperation(operationConvertJSValueToDouble, tempRegs.gpr(), dst); 792 end.append(jump()); 793 794 checkJSInt32.link(this); 795 convertInt32ToDouble(tempRegs.gpr(), dst); 796 end.append(jump()); 797 798 checkJSNumber.link(this); 799 unboxDoubleWithoutAssertions(tempRegs.gpr(), dst); 800 end.link(this); 801 } 802 #else 803 void loadValueAndConvertToInt32(Address address, GPRReg dst, GPRReg scratch) 804 { 805 JSValueRegs tempRegs(scratch, dst); 806 loadValue(address, tempRegs); 807 Jump checkJSInt32 = branchIfInt32(tempRegs); 808 809 callOperation(operationConvertJSValueToInt32, tempRegs.tagGPR(), tempRegs.payloadGPR(), dst); 810 811 checkJSInt32.link(this); 812 } 813 814 void loadValueAndConvertToDouble(Address address, FPRReg dst, GPRReg scratch1, GPRReg scratch2, GPRReg scratch3, FPRReg fpScratch) 815 { 816 JSValueRegs tempRegs(scratch2, scratch1); 817 loadValue(address, tempRegs); 818 Jump checkJSInt32 = branchIfInt32(tempRegs); 819 Jump checkJSNumber = branchIfNumber(tempRegs, scratch3); 820 JumpList end; 821 822 callOperation(operationConvertJSValueToDouble, tempRegs.tagGPR(), tempRegs.payloadGPR(), dst); 823 end.append(jump()); 824 825 checkJSInt32.link(this); 826 convertInt32ToDouble(tempRegs.payloadGPR(), dst); 827 end.append(jump()); 828 829 checkJSNumber.link(this); 830 unboxDouble(tempRegs.tagGPR(), tempRegs.payloadGPR(), dst, fpScratch) 831 end.link(this); 832 } 833 #endif 834 706 835 JSWASMModule* m_module; 707 836 unsigned m_stackHeight;
Note: See TracChangeset
for help on using the changeset viewer.