Example #1
0
void WASMModuleParser::parseConstantPoolSection()
{
    uint32_t numberOfI32Constants;
    uint32_t numberOfF32Constants;
    uint32_t numberOfF64Constants;
    READ_COMPACT_UINT32_OR_FAIL(numberOfI32Constants, "Cannot read the number of int32 constants.");
    READ_COMPACT_UINT32_OR_FAIL(numberOfF32Constants, "Cannot read the number of float32 constants.");
    READ_COMPACT_UINT32_OR_FAIL(numberOfF64Constants, "Cannot read the number of float64 constants.");
    m_module->i32Constants().reserveInitialCapacity(numberOfI32Constants);
    m_module->f32Constants().reserveInitialCapacity(numberOfF32Constants);
    m_module->f64Constants().reserveInitialCapacity(numberOfF64Constants);

    for (uint32_t i = 0; i < numberOfI32Constants; ++i) {
        uint32_t constant;
        READ_COMPACT_UINT32_OR_FAIL(constant, "Cannot read an int32 constant.");
        m_module->i32Constants().uncheckedAppend(constant);
    }
    for (uint32_t i = 0; i < numberOfF32Constants; ++i) {
        float constant;
        READ_FLOAT_OR_FAIL(constant, "Cannot read a float32 constant.");
        m_module->f32Constants().uncheckedAppend(constant);
    }
    for (uint32_t i = 0; i < numberOfF64Constants; ++i) {
        double constant;
        READ_DOUBLE_OR_FAIL(constant, "Cannot read a float64 constant.");
        m_module->f64Constants().uncheckedAppend(constant);
    }
}
Example #2
0
void WASMModuleParser::parseFunctionImportSection()
{
    uint32_t numberOfFunctionImports;
    uint32_t numberOfFunctionImportSignatures;
    READ_COMPACT_UINT32_OR_FAIL(numberOfFunctionImports, "Cannot read the number of function imports.");
    READ_COMPACT_UINT32_OR_FAIL(numberOfFunctionImportSignatures, "Cannot read the number of function import signatures.");
    m_module->functionImports().reserveInitialCapacity(numberOfFunctionImports);
    m_module->functionImportSignatures().reserveInitialCapacity(numberOfFunctionImportSignatures);

    for (uint32_t functionImportIndex = 0; functionImportIndex < numberOfFunctionImports; ++functionImportIndex) {
        WASMFunctionImport functionImport;
        READ_STRING_OR_FAIL(functionImport.functionName, "Cannot read the function import name.");
        m_module->functionImports().uncheckedAppend(functionImport);

        uint32_t numberOfSignatures;
        READ_COMPACT_UINT32_OR_FAIL(numberOfSignatures, "Cannot read the number of signatures.");
        FAIL_IF_FALSE(numberOfSignatures <= numberOfFunctionImportSignatures - m_module->functionImportSignatures().size(), "The number of signatures is incorrect.");

        for (uint32_t i = 0; i < numberOfSignatures; ++i) {
            WASMFunctionImportSignature functionImportSignature;
            READ_COMPACT_UINT32_OR_FAIL(functionImportSignature.signatureIndex, "Cannot read the signature index.");
            FAIL_IF_FALSE(functionImportSignature.signatureIndex < m_module->signatures().size(), "The signature index is incorrect.");
            functionImportSignature.functionImportIndex = functionImportIndex;
            m_module->functionImportSignatures().uncheckedAppend(functionImportSignature);
        }
    }
    FAIL_IF_FALSE(m_module->functionImportSignatures().size() == numberOfFunctionImportSignatures, "The number of function import signatures is incorrect.");
}
Example #3
0
void WASMModuleParser::parseExportSection()
{
    WASMExportFormat exportFormat;
    READ_EXPORT_FORMAT_OR_FAIL(exportFormat, "Cannot read the export format.");
    switch (exportFormat) {
    case WASMExportFormat::Default: {
        uint32_t functionIndex;
        READ_COMPACT_UINT32_OR_FAIL(functionIndex, "Cannot read the function index.");
        FAIL_IF_FALSE(functionIndex < m_module->functionDeclarations().size(), "The function index is incorrect.");
        // FIXME: Export the function.
        break;
    }
    case WASMExportFormat::Record: {
        uint32_t numberOfExports;
        READ_COMPACT_UINT32_OR_FAIL(numberOfExports, "Cannot read the number of exports.");
        for (uint32_t exportIndex = 0; exportIndex < numberOfExports; ++exportIndex) {
            String exportName;
            READ_STRING_OR_FAIL(exportName, "Cannot read the function export name.");
            // FIXME: Check that exportName is legal.
            uint32_t functionIndex;
            READ_COMPACT_UINT32_OR_FAIL(functionIndex, "Cannot read the function index.");
            FAIL_IF_FALSE(functionIndex < m_module->functionDeclarations().size(), "The function index is incorrect.");
            // FIXME: Export the function.
        }
        break;
    }
    default:
        ASSERT_NOT_REACHED();
    }
}
Example #4
0
void WASMModuleParser::parseFunctionDeclarationSection()
{
    uint32_t numberOfFunctionDeclarations;
    READ_COMPACT_UINT32_OR_FAIL(numberOfFunctionDeclarations, "Cannot read the number of function declarations.");
    m_module->functionDeclarations().reserveInitialCapacity(numberOfFunctionDeclarations);
    for (uint32_t i = 0; i < numberOfFunctionDeclarations; ++i) {
        WASMFunctionDeclaration functionDeclaration;
        READ_COMPACT_UINT32_OR_FAIL(functionDeclaration.signatureIndex, "Cannot read the signature index.");
        FAIL_IF_FALSE(functionDeclaration.signatureIndex < m_module->signatures().size(), "The signature index is incorrect.");
        m_module->functionDeclarations().uncheckedAppend(functionDeclaration);
    }
}
Example #5
0
ContextStatement WASMFunctionParser::parseContinueLabelStatement(Context&)
{
    uint32_t labelIndex;
    READ_COMPACT_UINT32_OR_FAIL(labelIndex, "Cannot read the label index.");
    FAIL_IF_FALSE(labelIndex < m_labelDepth, "The label index is incorrect.");
    // FIXME: Implement this instruction.
    return UNUSED;
}
Example #6
0
void WASMModuleParser::parseSignatureSection()
{
    uint32_t numberOfSignatures;
    READ_COMPACT_UINT32_OR_FAIL(numberOfSignatures, "Cannot read the number of signatures.");
    m_module->signatures().reserveInitialCapacity(numberOfSignatures);
    for (uint32_t signatureIndex = 0; signatureIndex < numberOfSignatures; ++signatureIndex) {
        WASMSignature signature;
        READ_EXPRESSION_TYPE_OR_FAIL(signature.returnType, "Cannot read the return type.");
        uint32_t argumentCount;
        READ_COMPACT_UINT32_OR_FAIL(argumentCount, "Cannot read the number of arguments.");
        signature.arguments.reserveInitialCapacity(argumentCount);
        for (uint32_t argumentIndex = 0; argumentIndex < argumentCount; ++argumentIndex) {
            WASMType type;
            READ_TYPE_OR_FAIL(type, "Cannot read the type of an argument.");
            signature.arguments.uncheckedAppend(type);
        }
        m_module->signatures().uncheckedAppend(signature);
    }
}
Example #7
0
ContextStatement WASMFunctionParser::parseBlockStatement(Context& context)
{
    uint32_t numberOfStatements;
    READ_COMPACT_UINT32_OR_FAIL(numberOfStatements, "Cannot read the number of statements.");
    for (uint32_t i = 0; i < numberOfStatements; ++i) {
        parseStatement(context);
        PROPAGATE_ERROR();
    }
    return UNUSED;
}
Example #8
0
void WASMModuleParser::parseFunctionPointerTableSection()
{
    uint32_t numberOfFunctionPointerTables;
    READ_COMPACT_UINT32_OR_FAIL(numberOfFunctionPointerTables, "Cannot read the number of function pointer tables.");
    m_module->functionPointerTables().reserveInitialCapacity(numberOfFunctionPointerTables);
    for (uint32_t i = 0; i < numberOfFunctionPointerTables; ++i) {
        WASMFunctionPointerTable functionPointerTable;
        READ_COMPACT_UINT32_OR_FAIL(functionPointerTable.signatureIndex, "Cannot read the signature index.");
        FAIL_IF_FALSE(functionPointerTable.signatureIndex < m_module->signatures().size(), "The signature index is incorrect.");
        uint32_t numberOfElements;
        READ_COMPACT_UINT32_OR_FAIL(numberOfElements, "Cannot read the number of elements of a function pointer table.");
        FAIL_IF_FALSE(hasOneBitSet(numberOfElements), "The number of elements must be a power of two.");
        functionPointerTable.elements.reserveInitialCapacity(numberOfElements);
        for (uint32_t j = 0; j < numberOfElements; ++j) {
            uint32_t element;
            READ_COMPACT_UINT32_OR_FAIL(element, "Cannot read an element of a function pointer table.");
            functionPointerTable.elements.uncheckedAppend(element);
        }
        m_module->functionPointerTables().uncheckedAppend(functionPointerTable);
    }
}
Example #9
0
bool WASMFunctionParser::parseLocalVariables()
{
    m_numberOfI32LocalVariables = 0;
    m_numberOfF32LocalVariables = 0;
    m_numberOfF64LocalVariables = 0;

    bool hasImmediate;
    WASMVariableTypes variableTypes;
    WASMVariableTypesWithImmediate variableTypesWithImmediate;
    uint8_t immediate;
    READ_VARIABLE_TYPES_OR_FAIL(hasImmediate, variableTypes, variableTypesWithImmediate, immediate, "Cannot read the types of local variables.");
    if (!hasImmediate) {
        if (static_cast<uint8_t>(variableTypes) & static_cast<uint8_t>(WASMVariableTypes::I32))
            READ_COMPACT_UINT32_OR_FAIL(m_numberOfI32LocalVariables, "Cannot read the number of int32 local variables.");
        if (static_cast<uint8_t>(variableTypes) & static_cast<uint8_t>(WASMVariableTypes::F32))
            READ_COMPACT_UINT32_OR_FAIL(m_numberOfF32LocalVariables, "Cannot read the number of float32 local variables.");
        if (static_cast<uint8_t>(variableTypes) & static_cast<uint8_t>(WASMVariableTypes::F64))
            READ_COMPACT_UINT32_OR_FAIL(m_numberOfF64LocalVariables, "Cannot read the number of float64 local variables.");
    } else
        m_numberOfI32LocalVariables = immediate;
    return true;
}
Example #10
0
void WASMModuleParser::parseFunctionPointerTableSection()
{
    uint32_t numberOfFunctionPointerTables;
    READ_COMPACT_UINT32_OR_FAIL(numberOfFunctionPointerTables, "Cannot read the number of function pointer tables.");
    m_module->functionPointerTables().reserveInitialCapacity(numberOfFunctionPointerTables);
    for (uint32_t i = 0; i < numberOfFunctionPointerTables; ++i) {
        WASMFunctionPointerTable functionPointerTable;
        READ_COMPACT_UINT32_OR_FAIL(functionPointerTable.signatureIndex, "Cannot read the signature index.");
        FAIL_IF_FALSE(functionPointerTable.signatureIndex < m_module->signatures().size(), "The signature index is incorrect.");
        uint32_t numberOfFunctions;
        READ_COMPACT_UINT32_OR_FAIL(numberOfFunctions, "Cannot read the number of functions of a function pointer table.");
        FAIL_IF_FALSE(hasOneBitSet(numberOfFunctions), "The number of functions must be a power of two.");
        functionPointerTable.functionIndices.reserveInitialCapacity(numberOfFunctions);
        functionPointerTable.functions.reserveInitialCapacity(numberOfFunctions);
        for (uint32_t j = 0; j < numberOfFunctions; ++j) {
            uint32_t functionIndex;
            READ_COMPACT_UINT32_OR_FAIL(functionIndex, "Cannot read a function index of a function pointer table.");
            FAIL_IF_FALSE(functionIndex < m_module->functionDeclarations().size(), "The function index is incorrect.");
            FAIL_IF_FALSE(m_module->functionDeclarations()[functionIndex].signatureIndex == functionPointerTable.signatureIndex, "The signature of the function doesn't match that of the function pointer table.");
            functionPointerTable.functionIndices.uncheckedAppend(functionIndex);
        }
        m_module->functionPointerTables().uncheckedAppend(functionPointerTable);
    }
}
Example #11
0
void WASMModuleParser::parseFunctionImportSection(ExecState* exec)
{
    uint32_t numberOfFunctionImports;
    uint32_t numberOfFunctionImportSignatures;
    READ_COMPACT_UINT32_OR_FAIL(numberOfFunctionImports, "Cannot read the number of function imports.");
    READ_COMPACT_UINT32_OR_FAIL(numberOfFunctionImportSignatures, "Cannot read the number of function import signatures.");
    m_module->functionImports().reserveInitialCapacity(numberOfFunctionImports);
    m_module->functionImportSignatures().reserveInitialCapacity(numberOfFunctionImportSignatures);
    m_module->importedFunctions().reserveInitialCapacity(numberOfFunctionImports);

    for (uint32_t functionImportIndex = 0; functionImportIndex < numberOfFunctionImports; ++functionImportIndex) {
        WASMFunctionImport functionImport;
        READ_STRING_OR_FAIL(functionImport.functionName, "Cannot read the function import name.");
        m_module->functionImports().uncheckedAppend(functionImport);

        uint32_t numberOfSignatures;
        READ_COMPACT_UINT32_OR_FAIL(numberOfSignatures, "Cannot read the number of signatures.");
        FAIL_IF_FALSE(numberOfSignatures <= numberOfFunctionImportSignatures - m_module->functionImportSignatures().size(), "The number of signatures is incorrect.");

        for (uint32_t i = 0; i < numberOfSignatures; ++i) {
            WASMFunctionImportSignature functionImportSignature;
            READ_COMPACT_UINT32_OR_FAIL(functionImportSignature.signatureIndex, "Cannot read the signature index.");
            FAIL_IF_FALSE(functionImportSignature.signatureIndex < m_module->signatures().size(), "The signature index is incorrect.");
            functionImportSignature.functionImportIndex = functionImportIndex;
            m_module->functionImportSignatures().uncheckedAppend(functionImportSignature);
        }

        JSValue value;
        getImportedValue(exec, functionImport.functionName, value);
        PROPAGATE_ERROR();
        FAIL_IF_FALSE(value.isFunction(), "\"" + functionImport.functionName + "\" is not a function.");
        JSFunction* function = jsCast<JSFunction*>(value.asCell());
        m_module->importedFunctions().uncheckedAppend(WriteBarrier<JSFunction>(m_vm, m_module.get(), function));
    }
    FAIL_IF_FALSE(m_module->functionImportSignatures().size() == numberOfFunctionImportSignatures, "The number of function import signatures is incorrect.");
}
Example #12
0
ContextStatement WASMFunctionParser::parseSwitchStatement(Context& context)
{
    uint32_t numberOfCases;
    READ_COMPACT_UINT32_OR_FAIL(numberOfCases, "Cannot read the number of cases.");
    parseExpressionI32(context);
    PROPAGATE_ERROR();

    m_breakScopeDepth++;
    for (uint32_t i = 0; i < numberOfCases; ++i) {
        WASMSwitchCase switchCase;
        READ_SWITCH_CASE_OR_FAIL(switchCase, "Cannot read the switch case.");
        switch (switchCase) {
        case WASMSwitchCase::CaseWithNoStatements:
        case WASMSwitchCase::CaseWithStatement:
        case WASMSwitchCase::CaseWithBlockStatement: {
            uint32_t value;
            READ_COMPACT_INT32_OR_FAIL(value, "Cannot read the value of the switch case.");
            if (switchCase == WASMSwitchCase::CaseWithStatement) {
                parseStatement(context);
                PROPAGATE_ERROR();
            } else if (switchCase == WASMSwitchCase::CaseWithBlockStatement) {
                parseBlockStatement(context);
                PROPAGATE_ERROR();
            }
            break;
        }
        case WASMSwitchCase::DefaultWithNoStatements:
        case WASMSwitchCase::DefaultWithStatement:
        case WASMSwitchCase::DefaultWithBlockStatement: {
            FAIL_IF_FALSE(i == numberOfCases - 1, "The default case must be the last case.");
            if (switchCase == WASMSwitchCase::DefaultWithStatement) {
                parseStatement(context);
                PROPAGATE_ERROR();
            } else if (switchCase == WASMSwitchCase::DefaultWithBlockStatement) {
                parseBlockStatement(context);
                PROPAGATE_ERROR();
            }
            break;
        }
        default:
            ASSERT_NOT_REACHED();
        }
    }
    m_breakScopeDepth--;
    // FIXME: Implement this instruction.
    return UNUSED;
}
Example #13
0
void WASMModuleParser::parseGlobalSection()
{
    uint32_t numberOfInternalI32GlobalVariables;
    uint32_t numberOfInternalF32GlobalVariables;
    uint32_t numberOfInternalF64GlobalVariables;
    uint32_t numberOfImportedI32GlobalVariables;
    uint32_t numberOfImportedF32GlobalVariables;
    uint32_t numberOfImportedF64GlobalVariables;
    READ_COMPACT_UINT32_OR_FAIL(numberOfInternalI32GlobalVariables, "Cannot read the number of internal int32 global variables.");
    READ_COMPACT_UINT32_OR_FAIL(numberOfInternalF32GlobalVariables, "Cannot read the number of internal float32 global variables.");
    READ_COMPACT_UINT32_OR_FAIL(numberOfInternalF64GlobalVariables, "Cannot read the number of internal float64 global variables.");
    READ_COMPACT_UINT32_OR_FAIL(numberOfImportedI32GlobalVariables, "Cannot read the number of imported int32 global variables.");
    READ_COMPACT_UINT32_OR_FAIL(numberOfImportedF32GlobalVariables, "Cannot read the number of imported float32 global variables.");
    READ_COMPACT_UINT32_OR_FAIL(numberOfImportedF64GlobalVariables, "Cannot read the number of imported float64 global variables.");
    uint32_t numberOfGlobalVariables = numberOfInternalI32GlobalVariables + numberOfInternalF32GlobalVariables + numberOfInternalF64GlobalVariables +
        numberOfImportedI32GlobalVariables + numberOfImportedF32GlobalVariables + numberOfImportedF64GlobalVariables;

    Vector<WASMType>& globalVariableTypes = m_module->globalVariableTypes();
    globalVariableTypes.reserveInitialCapacity(numberOfGlobalVariables);
    for (uint32_t i = 0; i < numberOfInternalI32GlobalVariables; ++i)
        globalVariableTypes.uncheckedAppend(WASMType::I32);
    for (uint32_t i = 0; i < numberOfInternalF32GlobalVariables; ++i)
        globalVariableTypes.uncheckedAppend(WASMType::F32);
    for (uint32_t i = 0; i < numberOfInternalF64GlobalVariables; ++i)
        globalVariableTypes.uncheckedAppend(WASMType::F64);
    for (uint32_t i = 0; i < numberOfImportedI32GlobalVariables; ++i) {
        String importName;
        READ_STRING_OR_FAIL(importName, "Cannot read the import name of an int32 global variable.");
        globalVariableTypes.uncheckedAppend(WASMType::I32);
    }
    for (uint32_t i = 0; i < numberOfImportedF32GlobalVariables; ++i) {
        String importName;
        READ_STRING_OR_FAIL(importName, "Cannot read the import name of a float32 global variable.");
        globalVariableTypes.uncheckedAppend(WASMType::F32);
    }
    for (uint32_t i = 0; i < numberOfImportedF64GlobalVariables; ++i) {
        String importName;
        READ_STRING_OR_FAIL(importName, "Cannot read the import name of a float64 global variable.");
        globalVariableTypes.uncheckedAppend(WASMType::F64);
    }
}
Example #14
0
void WASMModuleParser::parseGlobalSection(ExecState* exec)
{
    uint32_t numberOfInternalI32GlobalVariables;
    uint32_t numberOfInternalF32GlobalVariables;
    uint32_t numberOfInternalF64GlobalVariables;
    uint32_t numberOfImportedI32GlobalVariables;
    uint32_t numberOfImportedF32GlobalVariables;
    uint32_t numberOfImportedF64GlobalVariables;
    READ_COMPACT_UINT32_OR_FAIL(numberOfInternalI32GlobalVariables, "Cannot read the number of internal int32 global variables.");
    READ_COMPACT_UINT32_OR_FAIL(numberOfInternalF32GlobalVariables, "Cannot read the number of internal float32 global variables.");
    READ_COMPACT_UINT32_OR_FAIL(numberOfInternalF64GlobalVariables, "Cannot read the number of internal float64 global variables.");
    READ_COMPACT_UINT32_OR_FAIL(numberOfImportedI32GlobalVariables, "Cannot read the number of imported int32 global variables.");
    READ_COMPACT_UINT32_OR_FAIL(numberOfImportedF32GlobalVariables, "Cannot read the number of imported float32 global variables.");
    READ_COMPACT_UINT32_OR_FAIL(numberOfImportedF64GlobalVariables, "Cannot read the number of imported float64 global variables.");
    uint32_t numberOfGlobalVariables = numberOfInternalI32GlobalVariables + numberOfInternalF32GlobalVariables + numberOfInternalF64GlobalVariables +
        numberOfImportedI32GlobalVariables + numberOfImportedF32GlobalVariables + numberOfImportedF64GlobalVariables;

    Vector<WASMType>& globalVariableTypes = m_module->globalVariableTypes();
    globalVariableTypes.reserveInitialCapacity(numberOfGlobalVariables);
    Vector<JSWASMModule::GlobalVariable>& globalVariables = m_module->globalVariables();
    globalVariables.reserveInitialCapacity(numberOfGlobalVariables);
    for (uint32_t i = 0; i < numberOfInternalI32GlobalVariables; ++i) {
        globalVariableTypes.uncheckedAppend(WASMType::I32);
        globalVariables.uncheckedAppend(JSWASMModule::GlobalVariable(0));
    }
    for (uint32_t i = 0; i < numberOfInternalF32GlobalVariables; ++i) {
        globalVariableTypes.uncheckedAppend(WASMType::F32);
        globalVariables.uncheckedAppend(JSWASMModule::GlobalVariable(0.0f));
    }
    for (uint32_t i = 0; i < numberOfInternalF64GlobalVariables; ++i) {
        globalVariableTypes.uncheckedAppend(WASMType::F64);
        globalVariables.uncheckedAppend(JSWASMModule::GlobalVariable(0.0));
    }
    for (uint32_t i = 0; i < numberOfImportedI32GlobalVariables; ++i) {
        String importName;
        READ_STRING_OR_FAIL(importName, "Cannot read the import name of an int32 global variable.");
        globalVariableTypes.uncheckedAppend(WASMType::I32);
        JSValue value;
        getImportedValue(exec, importName, value);
        PROPAGATE_ERROR();
        FAIL_IF_FALSE(value.isPrimitive() && !value.isSymbol(), "\"" + importName + "\" is not a primitive or is a Symbol.");
        globalVariables.uncheckedAppend(JSWASMModule::GlobalVariable(value.toInt32(exec)));
    }
    for (uint32_t i = 0; i < numberOfImportedF32GlobalVariables; ++i) {
        String importName;
        READ_STRING_OR_FAIL(importName, "Cannot read the import name of a float32 global variable.");
        globalVariableTypes.uncheckedAppend(WASMType::F32);
        JSValue value;
        getImportedValue(exec, importName, value);
        PROPAGATE_ERROR();
        FAIL_IF_FALSE(value.isPrimitive() && !value.isSymbol(), "\"" + importName + "\" is not a primitive or is a Symbol.");
        globalVariables.uncheckedAppend(JSWASMModule::GlobalVariable(static_cast<float>(value.toNumber(exec))));
    }
    for (uint32_t i = 0; i < numberOfImportedF64GlobalVariables; ++i) {
        String importName;
        READ_STRING_OR_FAIL(importName, "Cannot read the import name of a float64 global variable.");
        globalVariableTypes.uncheckedAppend(WASMType::F64);
        JSValue value;
        getImportedValue(exec, importName, value);
        PROPAGATE_ERROR();
        FAIL_IF_FALSE(value.isPrimitive() && !value.isSymbol(), "\"" + importName + "\" is not a primitive or is a Symbol.");
        globalVariables.uncheckedAppend(JSWASMModule::GlobalVariable(value.toNumber(exec)));
    }
}
Example #15
0
ContextExpression WASMFunctionParser::parseImmediateExpressionI32(Context& context)
{
    uint32_t immediate;
    READ_COMPACT_UINT32_OR_FAIL(immediate, "Cannot read the immediate.");
    return parseImmediateExpressionI32(context, immediate);
}
Example #16
0
ContextStatement WASMFunctionParser::parseSetLocalStatement(Context& context)
{
    uint32_t localIndex;
    READ_COMPACT_UINT32_OR_FAIL(localIndex, "Cannot read the local index.");
    return parseSetLocalStatement(context, localIndex);
}