Changeset 189494 in webkit


Ignore:
Timestamp:
Sep 8, 2015 10:39:35 AM (9 years ago)
Author:
commit-queue@webkit.org
Message:

Add initial support for doubles in WebAssembly
https://bugs.webkit.org/show_bug.cgi?id=148913

Patch by Sukolsak Sakshuwong <Sukolsak Sakshuwong> on 2015-09-08
Reviewed by Filip Pizlo.

Implement the ConstantPoolIndex, Immediate, and GetLocal instructions
for doubles (float64) in WebAssembly.

  • tests/stress/wasm-arithmetic-float64.js: Added.

(shouldBe):

  • tests/stress/wasm/arithmetic-float64.wasm: Added.
  • wasm/WASMConstants.h:
  • wasm/WASMFunctionCompiler.h:

(JSC::WASMFunctionCompiler::buildSetLocal):
(JSC::WASMFunctionCompiler::buildReturn):
(JSC::WASMFunctionCompiler::buildImmediateI32):
(JSC::WASMFunctionCompiler::buildImmediateF64):
(JSC::WASMFunctionCompiler::buildGetLocal):

  • wasm/WASMFunctionParser.cpp:

(JSC::WASMFunctionParser::parseExpression):
(JSC::WASMFunctionParser::parseExpressionF64):
(JSC::WASMFunctionParser::parseConstantPoolIndexExpressionF64):
(JSC::WASMFunctionParser::parseImmediateExpressionF64):
(JSC::WASMFunctionParser::parseGetLocalExpressionF64):

  • wasm/WASMFunctionParser.h:
  • wasm/WASMFunctionSyntaxChecker.h:

(JSC::WASMFunctionSyntaxChecker::buildImmediateF64):

  • wasm/WASMReader.cpp:

(JSC::WASMReader::readOpExpressionF64):

  • wasm/WASMReader.h:
Location:
trunk/Source/JavaScriptCore
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r189493 r189494  
     12015-09-08  Sukolsak Sakshuwong  <sukolsak@gmail.com>
     2
     3        Add initial support for doubles in WebAssembly
     4        https://bugs.webkit.org/show_bug.cgi?id=148913
     5
     6        Reviewed by Filip Pizlo.
     7
     8        Implement the ConstantPoolIndex, Immediate, and GetLocal instructions
     9        for doubles (float64) in WebAssembly.
     10
     11        * tests/stress/wasm-arithmetic-float64.js: Added.
     12        (shouldBe):
     13        * tests/stress/wasm/arithmetic-float64.wasm: Added.
     14        * wasm/WASMConstants.h:
     15        * wasm/WASMFunctionCompiler.h:
     16        (JSC::WASMFunctionCompiler::buildSetLocal):
     17        (JSC::WASMFunctionCompiler::buildReturn):
     18        (JSC::WASMFunctionCompiler::buildImmediateI32):
     19        (JSC::WASMFunctionCompiler::buildImmediateF64):
     20        (JSC::WASMFunctionCompiler::buildGetLocal):
     21        * wasm/WASMFunctionParser.cpp:
     22        (JSC::WASMFunctionParser::parseExpression):
     23        (JSC::WASMFunctionParser::parseExpressionF64):
     24        (JSC::WASMFunctionParser::parseConstantPoolIndexExpressionF64):
     25        (JSC::WASMFunctionParser::parseImmediateExpressionF64):
     26        (JSC::WASMFunctionParser::parseGetLocalExpressionF64):
     27        * wasm/WASMFunctionParser.h:
     28        * wasm/WASMFunctionSyntaxChecker.h:
     29        (JSC::WASMFunctionSyntaxChecker::buildImmediateF64):
     30        * wasm/WASMReader.cpp:
     31        (JSC::WASMReader::readOpExpressionF64):
     32        * wasm/WASMReader.h:
     33
    1342015-09-06  Filip Pizlo  <fpizlo@apple.com>
    235
  • trunk/Source/JavaScriptCore/wasm/WASMConstants.h

    r188808 r189494  
    171171};
    172172
     173enum class WASMOpExpressionF64 : uint8_t {
     174    ConstantPoolIndex,
     175    Immediate,
     176    GetLocal,
     177    GetGlobal,
     178    SetLocal,
     179    SetGlobal,
     180    Load,
     181    LoadWithOffset,
     182    Store,
     183    StoreWithOffset,
     184    CallInternal,
     185    CallIndirect,
     186    CallImport,
     187    Conditional,
     188    Comma,
     189    FromS32,
     190    FromU32,
     191    FromF32,
     192    Negate,
     193    Add,
     194    Sub,
     195    Mul,
     196    Div,
     197    Mod,
     198    Min,
     199    Max,
     200    Abs,
     201    Ceil,
     202    Floor,
     203    Sqrt,
     204    Cos,
     205    Sin,
     206    Tan,
     207    ACos,
     208    ASin,
     209    ATan,
     210    ATan2,
     211    Exp,
     212    Ln,
     213    Pow,
     214    NumberOfWASMOpExpressionF64s
     215};
     216
     217enum class WASMOpExpressionF64WithImmediate : uint8_t {
     218    ConstantPoolIndex,
     219    GetLocal,
     220    NumberOfWASMOpExpressionF64WithImmediates
     221};
     222
    173223enum class WASMVariableTypes : uint8_t {
    174224    I32 = 1 << 0,
  • trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h

    r189458 r189494  
    184184            store32(GPRInfo::regT0, localAddress(localIndex));
    185185            break;
     186        case WASMType::F64:
     187            loadDouble(temporaryAddress(m_tempStackTop - 1), FPRInfo::fpRegT0);
     188            m_tempStackTop--;
     189            storeDouble(FPRInfo::fpRegT0, localAddress(localIndex));
     190            break;
    186191        default:
    187192            ASSERT_NOT_REACHED();
     
    194199        case WASMExpressionType::I32:
    195200            load32(temporaryAddress(m_tempStackTop - 1), GPRInfo::returnValueGPR);
     201#if USE(JSVALUE64)
    196202            or64(GPRInfo::tagTypeNumberRegister, GPRInfo::returnValueGPR);
     203#else
     204            move(TrustedImm32(JSValue::Int32Tag), GPRInfo::returnValueGPR2);
     205#endif
     206            m_tempStackTop--;
     207            break;
     208        case WASMExpressionType::F64:
     209            loadDouble(temporaryAddress(m_tempStackTop - 1), FPRInfo::fpRegT0);
     210#if USE(JSVALUE64)
     211            boxDouble(FPRInfo::fpRegT0, GPRInfo::returnValueGPR);
     212#else
     213            boxDouble(FPRInfo::fpRegT0, GPRInfo::returnValueGPR2, GPRInfo::returnValueGPR);
     214#endif
    197215            m_tempStackTop--;
    198216            break;
     
    209227    int buildImmediateI32(uint32_t immediate)
    210228    {
    211         store32(TrustedImm32(immediate), temporaryAddress(m_tempStackTop++));
     229        store32(Imm32(immediate), temporaryAddress(m_tempStackTop++));
     230        return UNUSED;
     231    }
     232
     233    int buildImmediateF64(double immediate)
     234    {
     235#if USE(JSVALUE64)
     236        store64(Imm64(bitwise_cast<int64_t>(immediate)), temporaryAddress(m_tempStackTop++));
     237#else
     238        union {
     239            double doubleValue;
     240            int32_t int32Values[2];
     241        } u = { immediate };
     242        m_tempStackTop++;
     243        store32(Imm32(u.int32Values[0]), temporaryAddress(m_tempStackTop - 1));
     244        store32(Imm32(u.int32Values[1]), temporaryAddress(m_tempStackTop - 1).withOffset(4));
     245#endif
    212246        return UNUSED;
    213247    }
     
    218252        case WASMType::I32:
    219253            load32(localAddress(localIndex), GPRInfo::regT0);
    220             m_tempStackTop++;
    221             store32(GPRInfo::regT0, temporaryAddress(m_tempStackTop - 1));
     254            store32(GPRInfo::regT0, temporaryAddress(m_tempStackTop++));
     255            break;
     256        case WASMType::F64:
     257            loadDouble(localAddress(localIndex), FPRInfo::fpRegT0);
     258            storeDouble(FPRInfo::fpRegT0, temporaryAddress(m_tempStackTop++));
    222259            break;
    223260        default:
  • trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.cpp

    r189458 r189494  
    3535#define PROPAGATE_ERROR() do { if (!m_errorMessage.isNull()) return 0; } while (0)
    3636#define FAIL_WITH_MESSAGE(errorMessage) do {  m_errorMessage = errorMessage; return 0; } while (0)
     37#define READ_DOUBLE_OR_FAIL(result, errorMessage) do { if (!m_reader.readDouble(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
    3738#define READ_COMPACT_INT32_OR_FAIL(result, errorMessage) do { if (!m_reader.readCompactInt32(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
    3839#define READ_COMPACT_UINT32_OR_FAIL(result, errorMessage) do { if (!m_reader.readCompactUInt32(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
    3940#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)
    4041#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)
     42#define READ_OP_EXPRESSION_F64_OR_FAIL(hasImmediate, op, opWithImmediate, immediate, errorMessage) do { if (!m_reader.readOpExpressionF64(hasImmediate, op, opWithImmediate, immediate)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
    4143#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)
    4244#define READ_SWITCH_CASE_OR_FAIL(result, errorMessage) do { if (!m_reader.readSwitchCase(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
     
    404406    case WASMExpressionType::I32:
    405407        return parseExpressionI32(context);
     408    case WASMExpressionType::F64:
     409        return parseExpressionF64(context);
    406410    case WASMExpressionType::F32:
    407     case WASMExpressionType::F64:
    408411    case WASMExpressionType::Void:
    409412        // FIXME: Implement these instructions.
     
    588591}
    589592
     593template <class Context>
     594ContextExpression WASMFunctionParser::parseExpressionF64(Context& context)
     595{
     596    bool hasImmediate;
     597    WASMOpExpressionF64 op;
     598    WASMOpExpressionF64WithImmediate opWithImmediate;
     599    uint8_t immediate;
     600    READ_OP_EXPRESSION_F64_OR_FAIL(hasImmediate, op, opWithImmediate, immediate, "Cannot read the float64 expression opcode.");
     601    if (!hasImmediate) {
     602        switch (op) {
     603        case WASMOpExpressionF64::ConstantPoolIndex:
     604            return parseConstantPoolIndexExpressionF64(context);
     605        case WASMOpExpressionF64::Immediate:
     606            return parseImmediateExpressionF64(context);
     607        case WASMOpExpressionF64::GetLocal:
     608            return parseGetLocalExpressionF64(context);
     609        case WASMOpExpressionF64::GetGlobal:
     610        case WASMOpExpressionF64::SetLocal:
     611        case WASMOpExpressionF64::SetGlobal:
     612        case WASMOpExpressionF64::Load:
     613        case WASMOpExpressionF64::LoadWithOffset:
     614        case WASMOpExpressionF64::Store:
     615        case WASMOpExpressionF64::StoreWithOffset:
     616        case WASMOpExpressionF64::CallInternal:
     617        case WASMOpExpressionF64::CallIndirect:
     618        case WASMOpExpressionF64::CallImport:
     619        case WASMOpExpressionF64::Conditional:
     620        case WASMOpExpressionF64::Comma:
     621        case WASMOpExpressionF64::FromS32:
     622        case WASMOpExpressionF64::FromU32:
     623        case WASMOpExpressionF64::FromF32:
     624        case WASMOpExpressionF64::Negate:
     625        case WASMOpExpressionF64::Add:
     626        case WASMOpExpressionF64::Sub:
     627        case WASMOpExpressionF64::Mul:
     628        case WASMOpExpressionF64::Div:
     629        case WASMOpExpressionF64::Mod:
     630        case WASMOpExpressionF64::Min:
     631        case WASMOpExpressionF64::Max:
     632        case WASMOpExpressionF64::Abs:
     633        case WASMOpExpressionF64::Ceil:
     634        case WASMOpExpressionF64::Floor:
     635        case WASMOpExpressionF64::Sqrt:
     636        case WASMOpExpressionF64::Cos:
     637        case WASMOpExpressionF64::Sin:
     638        case WASMOpExpressionF64::Tan:
     639        case WASMOpExpressionF64::ACos:
     640        case WASMOpExpressionF64::ASin:
     641        case WASMOpExpressionF64::ATan:
     642        case WASMOpExpressionF64::ATan2:
     643        case WASMOpExpressionF64::Exp:
     644        case WASMOpExpressionF64::Ln:
     645        case WASMOpExpressionF64::Pow:
     646            // FIXME: Implement these instructions.
     647            FAIL_WITH_MESSAGE("Unsupported instruction.");
     648        default:
     649            ASSERT_NOT_REACHED();
     650        }
     651    } else {
     652        switch (opWithImmediate) {
     653        case WASMOpExpressionF64WithImmediate::ConstantPoolIndex:
     654            return parseConstantPoolIndexExpressionF64(context, immediate);
     655        case WASMOpExpressionF64WithImmediate::GetLocal:
     656            return parseGetLocalExpressionF64(context, immediate);
     657        default:
     658            ASSERT_NOT_REACHED();
     659        }
     660    }
     661    return 0;
     662}
     663
     664template <class Context>
     665ContextExpression WASMFunctionParser::parseConstantPoolIndexExpressionF64(Context& context, uint32_t constantIndex)
     666{
     667    FAIL_IF_FALSE(constantIndex < m_module->f64Constants().size(), "The constant index is incorrect.");
     668    return context.buildImmediateF64(m_module->f64Constants()[constantIndex]);
     669}
     670
     671template <class Context>
     672ContextExpression WASMFunctionParser::parseConstantPoolIndexExpressionF64(Context& context)
     673{
     674    uint32_t constantIndex;
     675    READ_COMPACT_UINT32_OR_FAIL(constantIndex, "Cannot read the constant index.");
     676    return parseConstantPoolIndexExpressionF64(context, constantIndex);
     677}
     678
     679template <class Context>
     680ContextExpression WASMFunctionParser::parseImmediateExpressionF64(Context& context)
     681{
     682    double immediate;
     683    READ_DOUBLE_OR_FAIL(immediate, "Cannot read the immediate.");
     684    return context.buildImmediateF64(immediate);
     685}
     686
     687template <class Context>
     688ContextExpression WASMFunctionParser::parseGetLocalExpressionF64(Context& context, uint32_t localIndex)
     689{
     690    FAIL_IF_FALSE(localIndex < m_localTypes.size(), "The local variable index is incorrect.");
     691    FAIL_IF_FALSE(m_localTypes[localIndex] == WASMType::F64, "Expected a local variable of type float64.");
     692    return context.buildGetLocal(localIndex, WASMType::F64);
     693}
     694
     695template <class Context>
     696ContextExpression WASMFunctionParser::parseGetLocalExpressionF64(Context& context)
     697{
     698    uint32_t localIndex;
     699    READ_COMPACT_UINT32_OR_FAIL(localIndex, "Cannot read the local index.");
     700    return parseGetLocalExpressionF64(context, localIndex);
     701}
     702
    590703} // namespace JSC
    591704
  • trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.h

    r189458 r189494  
    8888    template <class Context> ContextExpression parseRelationalI32ExpressionI32(Context&, WASMOpExpressionI32);
    8989
     90    template <class Context> ContextExpression parseExpressionF64(Context&);
     91    template <class Context> ContextExpression parseConstantPoolIndexExpressionF64(Context&, uint32_t constantIndex);
     92    template <class Context> ContextExpression parseConstantPoolIndexExpressionF64(Context&);
     93    template <class Context> ContextExpression parseImmediateExpressionF64(Context&);
     94    template <class Context> ContextExpression parseGetLocalExpressionF64(Context&, uint32_t localIndex);
     95    template <class Context> ContextExpression parseGetLocalExpressionF64(Context&);
     96
    9097    JSWASMModule* m_module;
    9198    WASMReader m_reader;
  • trunk/Source/JavaScriptCore/wasm/WASMFunctionSyntaxChecker.h

    r189458 r189494  
    6666    }
    6767
     68    int buildImmediateF64(uint32_t)
     69    {
     70        m_tempStackTop++;
     71        updateTempStackHeight();
     72        return UNUSED;
     73    }
     74
    6875    int buildGetLocal(uint32_t, WASMType)
    6976    {
  • trunk/Source/JavaScriptCore/wasm/WASMReader.cpp

    r188808 r189494  
    190190}
    191191
     192bool WASMReader::readOpExpressionF64(bool& hasImmediate, WASMOpExpressionF64& op, WASMOpExpressionF64WithImmediate& opWithImmediate, uint8_t& immediate)
     193{
     194    return readOp(hasImmediate, op, opWithImmediate, immediate,
     195        static_cast<uint8_t>(WASMOpExpressionF64::NumberOfWASMOpExpressionF64s),
     196        static_cast<uint8_t>(WASMOpExpressionF64WithImmediate::NumberOfWASMOpExpressionF64WithImmediates));
     197}
     198
    192199bool WASMReader::readVariableTypes(bool& hasImmediate, WASMVariableTypes& variableTypes, WASMVariableTypesWithImmediate& variableTypesWithImmediate, uint8_t& immediate)
    193200{
  • trunk/Source/JavaScriptCore/wasm/WASMReader.h

    r188808 r189494  
    5757    bool readOpStatement(bool& hasImmediate, WASMOpStatement&, WASMOpStatementWithImmediate&, uint8_t& immediate);
    5858    bool readOpExpressionI32(bool& hasImmediate, WASMOpExpressionI32&, WASMOpExpressionI32WithImmediate&, uint8_t& immediate);
     59    bool readOpExpressionF64(bool& hasImmediate, WASMOpExpressionF64&, WASMOpExpressionF64WithImmediate&, uint8_t& immediate);
    5960    bool readVariableTypes(bool& hasImmediate, WASMVariableTypes&, WASMVariableTypesWithImmediate&, uint8_t& immediate);
    6061    bool readSwitchCase(WASMSwitchCase& result);
Note: See TracChangeset for help on using the changeset viewer.