예제 #1
0
void Plan::run()
{
    if (verbose)
        dataLogLn("Starting plan.");
    {
        ModuleParser moduleParser(m_source, m_sourceLength);
        if (!moduleParser.parse()) {
            if (verbose)
                dataLogLn("Parsing module failed: ", moduleParser.errorMessage());
            m_errorMessage = moduleParser.errorMessage();
            return;
        }
        m_moduleInformation = WTFMove(moduleParser.moduleInformation());
    }
    if (verbose)
        dataLogLn("Parsed module.");

    if (!m_compiledFunctions.tryReserveCapacity(m_moduleInformation->functions.size())) {
        StringBuilder builder;
        builder.appendLiteral("Failed allocating enough space for ");
        builder.appendNumber(m_moduleInformation->functions.size());
        builder.appendLiteral(" compiled functions");
        m_errorMessage = builder.toString();
        return;
    }

    for (const FunctionInformation& info : m_moduleInformation->functions) {
        if (verbose)
            dataLogLn("Processing function starting at: ", info.start, " and ending at: ", info.end);
        const uint8_t* functionStart = m_source + info.start;
        size_t functionLength = info.end - info.start;
        ASSERT(functionLength <= m_sourceLength);

        String error = validateFunction(functionStart, functionLength, info.signature, m_moduleInformation->functions);
        if (!error.isNull()) {
            if (verbose) {
                for (unsigned i = 0; i < functionLength; ++i)
                    dataLog(RawPointer(reinterpret_cast<void*>(functionStart[i])), ", ");
                dataLogLn();
            }
            m_errorMessage = error;
            return;
        }

        m_compiledFunctions.uncheckedAppend(parseAndCompile(*m_vm, functionStart, functionLength, m_moduleInformation->memory.get(), info.signature, m_moduleInformation->functions));
    }

    // Patch the call sites for each function.
    for (std::unique_ptr<FunctionCompilation>& functionPtr : m_compiledFunctions) {
        FunctionCompilation* function = functionPtr.get();
        for (auto& call : function->unlinkedCalls)
            MacroAssembler::repatchCall(call.callLocation, CodeLocationLabel(m_compiledFunctions[call.functionIndex]->code->code()));
    }

    m_failed = false;
}
예제 #2
0
bool Plan::parseAndValidateModule()
{
    MonotonicTime startTime;
    if (verbose || Options::reportCompileTimes())
        startTime = MonotonicTime::now();

    {
        ModuleParser moduleParser(m_vm, m_source, m_sourceLength);
        auto parseResult = moduleParser.parse();
        if (!parseResult) {
            m_errorMessage = parseResult.error();
            return false;
        }
        m_moduleInformation = WTFMove(parseResult->module);
        m_functionLocationInBinary = WTFMove(parseResult->functionLocationInBinary);
        m_moduleSignatureIndicesToUniquedSignatureIndices = WTFMove(parseResult->moduleSignatureIndicesToUniquedSignatureIndices);
    }

    for (unsigned functionIndex = 0; functionIndex < m_functionLocationInBinary.size(); ++functionIndex) {
        if (verbose)
            dataLogLn("Processing function starting at: ", m_functionLocationInBinary[functionIndex].start, " and ending at: ", m_functionLocationInBinary[functionIndex].end);
        const uint8_t* functionStart = m_source + m_functionLocationInBinary[functionIndex].start;
        size_t functionLength = m_functionLocationInBinary[functionIndex].end - m_functionLocationInBinary[functionIndex].start;
        ASSERT(functionLength <= m_sourceLength);
        SignatureIndex signatureIndex = m_moduleInformation->internalFunctionSignatureIndices[functionIndex];
        const Signature* signature = SignatureInformation::get(m_vm, signatureIndex);

        auto validationResult = validateFunction(m_vm, functionStart, functionLength, signature, *m_moduleInformation, m_moduleSignatureIndicesToUniquedSignatureIndices);
        if (!validationResult) {
            if (verbose) {
                for (unsigned i = 0; i < functionLength; ++i)
                    dataLog(RawPointer(reinterpret_cast<void*>(functionStart[i])), ", ");
                dataLogLn();
            }
            m_errorMessage = makeString(validationResult.error(), ", in function at index ", String::number(functionIndex)); // FIXME make this an Expected.
            return false;
        }
    }

    if (verbose || Options::reportCompileTimes())
        dataLogLn("Took ", (MonotonicTime::now() - startTime).microseconds(), " us to validate module");
    return true;
}
예제 #3
0
JSWASMModule* parseWebAssembly(ExecState* exec, const SourceCode& source, JSObject* imports, JSArrayBuffer* arrayBuffer, String& errorMessage)
{
    WASMModuleParser moduleParser(exec->vm(), exec->lexicalGlobalObject(), source, imports, arrayBuffer);
    return moduleParser.parse(exec, errorMessage);
}