Changeset 209934 in webkit


Ignore:
Timestamp:
Dec 16, 2016 1:36:40 PM (7 years ago)
Author:
keith_miller@apple.com
Message:

Add missing cases to parseUnreachableExpression and cleanup FunctionParser
https://bugs.webkit.org/show_bug.cgi?id=165966

Reviewed by Saam Barati.

This patch adds a number of missing cases to the Wasm FunctionParser's unreachable
code decoder. It also, removes unneeded OpType namespaces where they were not
needed and has the unary / binary macros cover all the cases rather than
just the simple cases.

  • wasm/WasmFunctionParser.h:
Location:
trunk/Source/JavaScriptCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r209929 r209934  
     12016-12-16  Keith Miller  <keith_miller@apple.com>
     2
     3        Add missing cases to parseUnreachableExpression and cleanup FunctionParser
     4        https://bugs.webkit.org/show_bug.cgi?id=165966
     5
     6        Reviewed by Saam Barati.
     7
     8        This patch adds a number of missing cases to the Wasm FunctionParser's unreachable
     9        code decoder. It also, removes unneeded OpType namespaces where they were not
     10        needed and has the unary / binary macros cover all the cases rather than
     11        just the simple cases.
     12
     13        * wasm/WasmFunctionParser.h:
     14
    1152016-12-16  Mark Lam  <mark.lam@apple.com>
    216
  • trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h

    r209923 r209934  
    137137        }
    138138
    139         if (op == OpType::End && !m_controlStack.size()) {
     139        if (op == End && !m_controlStack.size()) {
    140140            if (m_unreachableBlocks)
    141141                return { };
     
    202202    switch (op) {
    203203#define CREATE_CASE(name, id, b3op, inc) case OpType::name: return binaryCase<OpType::name>();
    204     FOR_EACH_WASM_SIMPLE_BINARY_OP(CREATE_CASE)
     204    FOR_EACH_WASM_BINARY_OP(CREATE_CASE)
    205205#undef CREATE_CASE
    206206
    207     case OpType::F32ConvertUI64: return unaryCase<OpType::F32ConvertUI64>();
    208     case OpType::F64ConvertUI64: return unaryCase<OpType::F64ConvertUI64>();
    209     case OpType::F32Nearest: return unaryCase<OpType::F32Nearest>();
    210     case OpType::F64Nearest: return unaryCase<OpType::F64Nearest>();
    211     case OpType::F32Trunc: return unaryCase<OpType::F32Trunc>();
    212     case OpType::F64Trunc: return unaryCase<OpType::F64Trunc>();
    213     case OpType::I32Ctz: return unaryCase<OpType::I32Ctz>();
    214     case OpType::I64Ctz: return unaryCase<OpType::I64Ctz>();
    215     case OpType::I32Popcnt: return unaryCase<OpType::I32Popcnt>();
    216     case OpType::I64Popcnt: return unaryCase<OpType::I64Popcnt>();
    217     case OpType::I32TruncSF32: return unaryCase<OpType::I32TruncSF32>();
    218     case OpType::I32TruncUF32: return unaryCase<OpType::I32TruncUF32>();
    219     case OpType::I32TruncSF64: return unaryCase<OpType::I32TruncSF64>();
    220     case OpType::I32TruncUF64: return unaryCase<OpType::I32TruncUF64>();
    221     case OpType::I64TruncSF32: return unaryCase<OpType::I64TruncSF32>();
    222     case OpType::I64TruncUF32: return unaryCase<OpType::I64TruncUF32>();
    223     case OpType::I64TruncSF64: return unaryCase<OpType::I64TruncSF64>();
    224     case OpType::I64TruncUF64: return unaryCase<OpType::I64TruncUF64>();
    225207#define CREATE_CASE(name, id, b3op, inc) case OpType::name: return unaryCase<OpType::name>();
    226     FOR_EACH_WASM_SIMPLE_UNARY_OP(CREATE_CASE)
     208    FOR_EACH_WASM_UNARY_OP(CREATE_CASE)
    227209#undef CREATE_CASE
    228210
    229     case OpType::Select: {
     211    case Select: {
    230212        ExpressionType condition;
    231213        ExpressionType zero;
     
    271253#undef CREATE_CASE
    272254
    273     case OpType::F32Const: {
     255    case F32Const: {
    274256        uint32_t constant;
    275257        WASM_PARSER_FAIL_IF(!parseUInt32(constant), "can't parse 32-bit floating-point constant");
     
    278260    }
    279261
    280     case OpType::I32Const: {
     262    case I32Const: {
    281263        int32_t constant;
    282264        WASM_PARSER_FAIL_IF(!parseVarInt32(constant), "can't parse 32-bit constant");
     
    285267    }
    286268
    287     case OpType::F64Const: {
     269    case F64Const: {
    288270        uint64_t constant;
    289271        WASM_PARSER_FAIL_IF(!parseUInt64(constant), "can't parse 64-bit floating-point constant");
     
    292274    }
    293275
    294     case OpType::I64Const: {
     276    case I64Const: {
    295277        int64_t constant;
    296278        WASM_PARSER_FAIL_IF(!parseVarInt64(constant), "can't parse 64-bit constant");
     
    299281    }
    300282
    301     case OpType::GetLocal: {
     283    case GetLocal: {
    302284        uint32_t index;
    303285        ExpressionType result;
     
    308290    }
    309291
    310     case OpType::SetLocal: {
     292    case SetLocal: {
    311293        uint32_t index;
    312294        ExpressionType value;
     
    317299    }
    318300
    319     case OpType::TeeLocal: {
     301    case TeeLocal: {
    320302        uint32_t index;
    321303        WASM_PARSER_FAIL_IF(!parseVarUInt32(index), "can't get index for tee_local");
     
    325307    }
    326308
    327     case OpType::GetGlobal: {
     309    case GetGlobal: {
    328310        uint32_t index;
    329311        ExpressionType result;
     
    334316    }
    335317
    336     case OpType::SetGlobal: {
     318    case SetGlobal: {
    337319        uint32_t index;
    338320        ExpressionType value;
     
    343325    }
    344326
    345     case OpType::Call: {
     327    case Call: {
    346328        uint32_t functionIndex;
    347329        WASM_PARSER_FAIL_IF(!parseVarUInt32(functionIndex), "can't parse call's function index");
     
    367349    }
    368350
    369     case OpType::CallIndirect: {
     351    case CallIndirect: {
    370352        uint32_t signatureIndex;
    371353        uint8_t reserved;
     
    396378    }
    397379
    398     case OpType::Block: {
     380    case Block: {
    399381        Type inlineSignature;
    400382        WASM_PARSER_FAIL_IF(!parseResultType(inlineSignature), "can't get block's inline signature");
     
    404386    }
    405387
    406     case OpType::Loop: {
     388    case Loop: {
    407389        Type inlineSignature;
    408390        WASM_PARSER_FAIL_IF(!parseResultType(inlineSignature), "can't get loop's inline signature");
     
    412394    }
    413395
    414     case OpType::If: {
     396    case If: {
    415397        Type inlineSignature;
    416398        ExpressionType condition;
     
    424406    }
    425407
    426     case OpType::Else: {
     408    case Else: {
    427409        WASM_PARSER_FAIL_IF(m_controlStack.isEmpty(), "can't use else block at the top-level of a function");
    428410        WASM_TRY_ADD_TO_CONTEXT(addElse(m_controlStack.last().controlData, m_expressionStack));
     
    431413    }
    432414
    433     case OpType::Br:
    434     case OpType::BrIf: {
     415    case Br:
     416    case BrIf: {
    435417        uint32_t target;
    436418        ExpressionType condition = Context::emptyExpression;
    437419        WASM_PARSER_FAIL_IF(!parseVarUInt32(target), "can't get br / br_if's target");
    438420        WASM_PARSER_FAIL_IF(target >= m_controlStack.size(), "br / br_if's target ", target, " exceeds control stack size ", m_controlStack.size());
    439         if (op == OpType::BrIf)
     421        if (op == BrIf)
    440422            WASM_TRY_POP_EXPRESSION_STACK_INTO(condition, "br / br_if condition");
    441423        else
     
    448430    }
    449431
    450     case OpType::BrTable: {
     432    case BrTable: {
    451433        uint32_t numberOfTargets;
    452434        ExpressionType condition;
     
    473455    }
    474456
    475     case OpType::Return: {
     457    case Return: {
    476458        return addReturn();
    477459    }
    478460
    479     case OpType::End: {
     461    case End: {
    480462        ControlEntry data = m_controlStack.takeLast();
    481463        // FIXME: This is a little weird in that it will modify the expressionStack for the result of the block.
     
    487469    }
    488470
    489     case OpType::Unreachable: {
     471    case Unreachable: {
    490472        WASM_TRY_ADD_TO_CONTEXT(addUnreachable());
    491473        m_unreachableBlocks = 1;
     
    493475    }
    494476
    495     case OpType::Drop: {
     477    case Drop: {
    496478        WASM_PARSER_FAIL_IF(!m_expressionStack.size(), "can't drop on empty stack");
    497479        m_expressionStack.takeLast();
     
    499481    }
    500482
    501     case OpType::Nop: {
    502         return { };
    503     }
    504 
    505     case OpType::GrowMemory:
     483    case Nop: {
     484        return { };
     485    }
     486
     487    case GrowMemory:
    506488        return fail("not yet implemented: grow_memory"); // FIXME: Not yet implemented.
    507489
    508     case OpType::CurrentMemory:
     490    case CurrentMemory:
    509491        return fail("not yet implemented: current_memory"); // FIXME: Not yet implemented.
    510492
     
    514496}
    515497
     498// FIXME: We should try to use the same decoder function for both unreachable and reachable code. https://bugs.webkit.org/show_bug.cgi?id=165965
    516499template<typename Context>
    517500auto FunctionParser<Context>::parseUnreachableExpression(OpType op) -> PartialResult
    518501{
    519502    ASSERT(m_unreachableBlocks);
     503#define CREATE_CASE(name, id, b3op, inc) case OpType::name:
    520504    switch (op) {
    521     case OpType::Else: {
     505    case Else: {
    522506        if (m_unreachableBlocks > 1)
    523507            return { };
     
    530514    }
    531515
    532     case OpType::End: {
     516    case End: {
    533517        if (m_unreachableBlocks == 1) {
    534518            ControlEntry data = m_controlStack.takeLast();
     
    540524    }
    541525
    542     case OpType::Loop:
    543     case OpType::If:
    544     case OpType::Block: {
     526    case Loop:
     527    case If:
     528    case Block: {
    545529        m_unreachableBlocks++;
    546         return { };
    547     }
     530        int8_t unused;
     531        WASM_PARSER_FAIL_IF(!parseInt7(unused), "can't get inline type for ", op, " in unreachable context");
     532        return { };
     533    }
     534
     535    case BrTable: {
     536        uint32_t numberOfTargets;
     537        uint32_t unused;
     538        WASM_PARSER_FAIL_IF(!parseVarUInt32(numberOfTargets), "can't get the number of targets for br_table in unreachable context");
     539        WASM_PARSER_FAIL_IF(numberOfTargets == std::numeric_limits<uint32_t>::max(), "br_table's number of targets is too big ", numberOfTargets);
     540
     541        for (uint32_t i = 0; i < numberOfTargets; ++i)
     542            WASM_PARSER_FAIL_IF(!parseVarUInt32(unused), "can't get ", i, "th target for br_table in unreachable context");
     543
     544        WASM_PARSER_FAIL_IF(!parseVarUInt32(unused), "can't get default target for br_table in unreachable context");
     545        return { };
     546    }
     547
    548548
    549549    // two immediate cases
    550     case OpType::Br:
    551     case OpType::BrIf: {
     550    FOR_EACH_WASM_MEMORY_LOAD_OP(CREATE_CASE)
     551    FOR_EACH_WASM_MEMORY_STORE_OP(CREATE_CASE)
     552    case Br:
     553    case BrIf:
     554    case CallIndirect: {
    552555        uint32_t unused;
    553         WASM_PARSER_FAIL_IF(!parseVarUInt32(unused), "can't get br / br_if in unreachable context");
    554         WASM_PARSER_FAIL_IF(!parseVarUInt32(unused), "can't get br / br_if in unreachable context");
     556        WASM_PARSER_FAIL_IF(!parseVarUInt32(unused), "can't get first immediate for ", op, " in unreachable context");
     557        WASM_PARSER_FAIL_IF(!parseVarUInt32(unused), "can't get second immediate for ", op, " in unreachable context");
    555558        return { };
    556559    }
    557560
    558561    // one immediate cases
    559     case OpType::F32Const:
    560     case OpType::I32Const:
    561     case OpType::F64Const:
    562     case OpType::I64Const:
    563     case OpType::SetLocal:
    564     case OpType::GetLocal: {
     562    case F32Const:
     563    case I32Const:
     564    case F64Const:
     565    case I64Const:
     566    case SetLocal:
     567    case GetLocal:
     568    case TeeLocal:
     569    case GetGlobal:
     570    case SetGlobal:
     571    case Call: {
    565572        uint32_t unused;
    566         WASM_PARSER_FAIL_IF(!parseVarUInt32(unused), "can't get const / local in unreachable context");
    567         return { };
    568     }
    569 
    570     default:
    571         break;
    572     }
    573     return { };
     573        WASM_PARSER_FAIL_IF(!parseVarUInt32(unused), "can't get immediate for ", op, " in unreachable context");
     574        return { };
     575    }
     576
     577    // no immediate cases
     578    FOR_EACH_WASM_BINARY_OP(CREATE_CASE)
     579    FOR_EACH_WASM_UNARY_OP(CREATE_CASE)
     580    case Unreachable:
     581    case Nop:
     582    case Return:
     583    case Select:
     584    case Drop:
     585    case GrowMemory:
     586    case CurrentMemory: {
     587        return { };
     588    }
     589    }
     590#undef CREATE_CASE
     591    RELEASE_ASSERT_NOT_REACHED();
    574592}
    575593
Note: See TracChangeset for help on using the changeset viewer.