/*
 * Copyright (C) 2016 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

import * as assert from './assert.js';
import * as BuildWebAssembly from './Builder_WebAssemblyBinary.js';
import * as LLB from './LowLevelBinary.js';
import * as WASM from './WASM.js';
import * as util from './utilities.js';

const _isValidValue = (value, type) => {
    switch (type) {
    // We allow both signed and unsigned numbers.
    case "i32": return Math.round(value) === value && LLB.varint32Min <= value && value <= LLB.varuint32Max;
    case "externref": return true;
    case "i64": return true; // FIXME https://bugs.webkit.org/show_bug.cgi?id=163420 64-bit values
    case "f32": return typeof(value) === "number" && isFinite(value);
    case "f64": return typeof(value) === "number" && isFinite(value);
    default: throw new Error(`Implementation problem: unknown type ${type}`);
    }
};
const _unknownSectionId = 0;

const _normalizeFunctionSignature = (params, ret) => {
    assert.isArray(params);
    for (const p of params)
        assert.truthy(WASM.isValidValueType(p) || p === "void", `Type parameter ${p} needs a valid value type`);
    if (typeof(ret) === "undefined")
        ret = "void";
    assert.isNotArray(ret, `Multiple return values not supported by WebAssembly yet`);
    assert.truthy(WASM.isValidBlockType(ret), `Type return ${ret} must be valid block type`);
    return [params, ret];
};

const _errorHandlingProxyFor = builder => builder["__isProxy"] ? builder : new Proxy(builder, {
    get: (target, property, receiver) => {
        if (property === "__isProxy")
            return true;
        if (target[property] === undefined)
            throw new Error(`WebAssembly builder received unknown property '${property}'`);
        return target[property];
    }
});

const _maybeRegisterType = (builder, type) => {
    const typeSection = builder._getSection("Type");
    if (typeof(type) === "number") {
        // Type numbers already refer to the type section, no need to register them.
        if (builder._checked) {
            assert.isNotUndef(typeSection, `Can not use type ${type} if a type section is not present`);
            assert.isNotUndef(typeSection.data[type], `Type ${type} does not exist in type section`);
        }
        return type;
    }
    assert.hasObjectProperty(type, "params", `Expected type to be a number or object with 'params' and optionally 'ret' fields`);
    const [params, ret] = _normalizeFunctionSignature(type.params, type.ret);
    assert.isNotUndef(typeSection, `Can not add type if a type section is not present`);
    // Try reusing an equivalent type from the type section.
    types:
    for (let i = 0; i !== typeSection.data.length; ++i) {
        const t = typeSection.data[i];
        if (t.ret === ret && params.length === t.params.length) {
            for (let j = 0; j !== t.params.length; ++j) {
                if (params[j] !== t.params[j])
                    continue types;
            }
            type = i;
            break;
        }
    }
    if (typeof(type) !== "number") {
        // Couldn't reuse a pre-existing type, register this type in the type section.
        typeSection.data.push({ params: params, ret: ret });
        type = typeSection.data.length - 1;
    }
    return type;
};

const _importFunctionContinuation = (builder, section, nextBuilder) => {
    return (module, field, type) => {
        assert.isString(module, `Import function module should be a string, got "${module}"`);
        assert.isString(field, `Import function field should be a string, got "${field}"`);
        const typeSection = builder._getSection("Type");
        type = _maybeRegisterType(builder, type);
        section.data.push({ field: field, type: type, kind: "Function", module: module });
        // Imports also count in the function index space. Map them as objects to avoid clashing with Code functions' names.
        builder._registerFunctionToIndexSpace({ module: module, field: field });
        return _errorHandlingProxyFor(nextBuilder);
    };
};

const _importMemoryContinuation = (builder, section, nextBuilder) => {
    return (module, field, {initial, maximum, shared = false}) => {
        assert.isString(module, `Import Memory module should be a string, got "${module}"`);
        assert.isString(field, `Import Memory field should be a string, got "${field}"`);
        section.data.push({module, field, kind: "Memory", memoryDescription: {initial, maximum, shared}});
        return _errorHandlingProxyFor(nextBuilder);
    };
};

const _importTableContinuation = (builder, section, nextBuilder) => {
    return (module, field, {initial, maximum, element}) => {
        assert.isString(module, `Import Table module should be a string, got "${module}"`);
        assert.isString(field, `Import Table field should be a string, got "${field}"`);
        section.data.push({module, field, kind: "Table", tableDescription: {initial, maximum, element}});
        return _errorHandlingProxyFor(nextBuilder);
    };
};

const _importExceptionContinuation = (builder, section, nextBuilder) => {
    return (module, field, type) => {
        assert.isString(module, `Import function module should be a string, got "${module}"`);
        assert.isString(field, `Import function field should be a string, got "${field}"`);
        const typeSection = builder._getSection("Type");
        type = _maybeRegisterType(builder, type);
        const tag = 0;
        section.data.push({ field, type, tag, kind: "Exception", module });
        return _errorHandlingProxyFor(nextBuilder);
    }
};

const _exportFunctionContinuation = (builder, section, nextBuilder) => {
    return (field, index, type) => {
        assert.isString(field, `Export function field should be a string, got "${field}"`);
        const typeSection = builder._getSection("Type");
        if (typeof(type) !== "undefined") {
            // Exports can leave the type unspecified, letting the Code builder patch them up later.
            type = _maybeRegisterType(builder, type);
        }

        // We can't check much about "index" here because the Code section succeeds the Export section. More work is done at Code().End() time.
        switch (typeof(index)) {
        case "string": break; // Assume it's a function name which will be revealed in the Code section.
        case "number": break; // Assume it's a number in the "function index space".
        case "object":
            // Re-exporting an import.
            assert.hasObjectProperty(index, "module", `Re-exporting "${field}" from an import`);
            assert.hasObjectProperty(index, "field", `Re-exporting "${field}" from an import`);
            break;
        case "undefined":
            // Assume it's the same as the field (i.e. it's not being renamed).
            index = field;
            break;
        default: throw new Error(`Export section's index must be a string or a number, got ${index}`);
        }

        const correspondingImport = builder._getFunctionFromIndexSpace(index);
        const importSection = builder._getSection("Import");
        if (typeof(index) === "object") {
            // Re-exporting an import using its module+field name.
            assert.isNotUndef(correspondingImport, `Re-exporting "${field}" couldn't find import from module "${index.module}" field "${index.field}"`);
            index = correspondingImport;
            if (typeof(type) === "undefined")
                type = importSection.data[index].type;
            if (builder._checked)
                assert.eq(type, importSection.data[index].type, `Re-exporting import "${importSection.data[index].field}" as "${field}" has mismatching type`);
        } else if (typeof(correspondingImport) !== "undefined") {
            // Re-exporting an import using its index.
            let exportedImport;
            for (const i of importSection.data) {
                if (i.module === correspondingImport.module && i.field === correspondingImport.field) {
                    exportedImport = i;
                    break;
                }
            }
            if (typeof(type) === "undefined")
                type = exportedImport.type;
            if (builder._checked)
                assert.eq(type, exportedImport.type, `Re-exporting import "${exportedImport.field}" as "${field}" has mismatching type`);
        }
        section.data.push({ field: field, type: type, kind: "Function", index: index });
        return _errorHandlingProxyFor(nextBuilder);
    };
};

const _normalizeMutability = (mutability) => {
    if (mutability === "mutable")
        return 1;
    else if (mutability === "immutable")
        return 0;
    else
        throw new Error(`mutability should be either "mutable" or "immutable", but got ${mutability}`);
};

const _exportGlobalContinuation = (builder, section, nextBuilder) => {
    return (field, index) => {
        assert.isNumber(index, `Global exports only support number indices right now`);
        section.data.push({ field, kind: "Global", index });
        return _errorHandlingProxyFor(nextBuilder);
    }
};

const _exportMemoryContinuation = (builder, section, nextBuilder) => {
    return (field, index) => {
        assert.isNumber(index, `Memory exports only support number indices`);
        section.data.push({field, kind: "Memory", index});
        return _errorHandlingProxyFor(nextBuilder);
    }
};

const _exportTableContinuation = (builder, section, nextBuilder) => {
    return (field, index) => {
        assert.isNumber(index, `Table exports only support number indices`);
        section.data.push({field, kind: "Table", index});
        return _errorHandlingProxyFor(nextBuilder);
    }
};

const _exportExceptionContinuation = (builder, section, nextBuilder) => {
    return (field, index) => {
        assert.isNumber(index, `Exception exports only support number indices`);
        section.data.push({field, kind: "Exception", index});
        return _errorHandlingProxyFor(nextBuilder);
    }
};

const _importGlobalContinuation = (builder, section, nextBuilder) => {
    return () => {
        const globalBuilder = {
            End: () => nextBuilder
        };
        for (let op of WASM.description.value_type) {
            globalBuilder[util.toJavaScriptName(op)] = (module, field, mutability) => {
                assert.isString(module, `Import global module should be a string, got "${module}"`);
                assert.isString(field, `Import global field should be a string, got "${field}"`);
                assert.isString(mutability, `Import global mutability should be a string, got "${mutability}"`);
                section.data.push({ globalDescription: { type: op, mutability: _normalizeMutability(mutability) }, module, field, kind: "Global" });
                return _errorHandlingProxyFor(globalBuilder);
            };
        }
        return _errorHandlingProxyFor(globalBuilder);
    };
};

const _checkStackArgs = (op, param) => {
    for (let expect of param) {
        if (WASM.isValidType(expect)) {
            // FIXME implement stack checks for arguments. https://bugs.webkit.org/show_bug.cgi?id=163421
        } else {
            // Handle our own meta-types.
            switch (expect) {
            case "addr": break; // FIXME implement addr. https://bugs.webkit.org/show_bug.cgi?id=163421
            case "any": break; // FIXME implement any. https://bugs.webkit.org/show_bug.cgi?id=163421
            case "bool": break; // FIXME implement bool. https://bugs.webkit.org/show_bug.cgi?id=163421
            case "call": break; // FIXME implement call stack argument checks based on function signature. https://bugs.webkit.org/show_bug.cgi?id=163421
            case "global": break; // FIXME implement global. https://bugs.webkit.org/show_bug.cgi?id=163421
            case "local": break; // FIXME implement local. https://bugs.webkit.org/show_bug.cgi?id=163421
            case "prev": break; // FIXME implement prev, checking for whetever the previous value was. https://bugs.webkit.org/show_bug.cgi?id=163421
            case "size": break; // FIXME implement size. https://bugs.webkit.org/show_bug.cgi?id=163421
            default: throw new Error(`Implementation problem: unhandled meta-type "${expect}" on "${op}"`);
            }
        }
    }
}

const _checkStackReturn = (op, ret) => {
    for (let expect of ret) {
        if (WASM.isValidType(expect)) {
            // FIXME implement stack checks for return. https://bugs.webkit.org/show_bug.cgi?id=163421
        } else {
            // Handle our own meta-types.
            switch (expect) {
            case "any": break;
            case "bool": break; // FIXME implement bool. https://bugs.webkit.org/show_bug.cgi?id=163421
            case "call": break; // FIXME implement call stack return check based on function signature. https://bugs.webkit.org/show_bug.cgi?id=163421
            case "control": break; // FIXME implement control. https://bugs.webkit.org/show_bug.cgi?id=163421
            case "global": break; // FIXME implement global. https://bugs.webkit.org/show_bug.cgi?id=163421
            case "local": break; // FIXME implement local. https://bugs.webkit.org/show_bug.cgi?id=163421
            case "prev": break; // FIXME implement prev, checking for whetever the parameter type was. https://bugs.webkit.org/show_bug.cgi?id=163421
            case "size": break; // FIXME implement size. https://bugs.webkit.org/show_bug.cgi?id=163421
            default: throw new Error(`Implementation problem: unhandled meta-type "${expect}" on "${op}"`);
            }
        }
    }
};

const _checkImms = (op, imms, expectedImms, ret) => {
    const minExpectedImms = expectedImms.filter(i => i.type.slice(-1) !== '*').length;
    if (minExpectedImms !== expectedImms.length)
        assert.ge(imms.length, minExpectedImms, `"${op}" expects at least ${minExpectedImms} immediate${minExpectedImms !== 1 ? 's' : ''}, got ${imms.length}`);
    else
         assert.eq(imms.length, minExpectedImms, `"${op}" expects exactly ${minExpectedImms} immediate${minExpectedImms !== 1 ? 's' : ''}, got ${imms.length}`);
    for (let idx = 0; idx !== expectedImms.length; ++idx) {
        const got = imms[idx];
        const expect = expectedImms[idx];
        switch (expect.name) {
        case "function_index":
            assert.truthy(_isValidValue(got, "i32") && got >= 0, `Invalid value on ${op}: got "${got}", expected non-negative i32`);
            // FIXME check function indices. https://bugs.webkit.org/show_bug.cgi?id=163421
            break;
        case "local_index": break; // improve checking https://bugs.webkit.org/show_bug.cgi?id=163421
        case "global_index": break; // improve checking https://bugs.webkit.org/show_bug.cgi?id=163421
        case "type_index": break; // improve checking https://bugs.webkit.org/show_bug.cgi?id=163421
        case "value":
            assert.truthy(_isValidValue(got, ret[0]), `Invalid value on ${op}: got "${got}", expected ${ret[0]}`);
            break;
        case "flags": break; // improve checking https://bugs.webkit.org/show_bug.cgi?id=163421
        case "offset": break; // improve checking https://bugs.webkit.org/show_bug.cgi?id=163421
            // Control:
        case "default_target": break; // improve checking https://bugs.webkit.org/show_bug.cgi?id=163421
        case "relative_depth": break; // improve checking https://bugs.webkit.org/show_bug.cgi?id=163421
        case "sig":
            assert.truthy(WASM.isValidBlockType(imms[idx]), `Invalid block type on ${op}: "${imms[idx]}"`);
            break;
        case "target_count": break; // improve checking https://bugs.webkit.org/show_bug.cgi?id=163421
        case "target_table": break; // improve checking https://bugs.webkit.org/show_bug.cgi?id=163421
        case "reserved": break; // improve checking https://bugs.webkit.org/show_bug.cgi?id=163421
        case "table_index": break; // improve checking https://bugs.webkit.org/show_bug.cgi?id=163421
        case "exn": break;
        case "reftype":
            assert.truthy(WASM.isValidRefType(imms[idx]), `Invalid ref type on ${op}: "${imms[idx]}"`);
            break;
        default: throw new Error(`Implementation problem: unhandled immediate "${expect.name}" on "${op}"`);
        }
    }
};

const _createFunctionBuilder = (func, builder, previousBuilder) => {
    let functionBuilder = {};
    for (const op in WASM.description.opcode) {
        const name = util.toJavaScriptName(op);
        const value = WASM.description.opcode[op].value;
        const ret = WASM.description.opcode[op]["return"];
        const param = WASM.description.opcode[op].parameter;
        const imm = WASM.description.opcode[op].immediate;

        const checkStackArgs = builder._checked ? _checkStackArgs : () => {};
        const checkStackReturn = builder._checked ? _checkStackReturn : () => {};
        const checkImms = builder._checked ? _checkImms : () => {};

        functionBuilder[name] = (...args) => {
            let nextBuilder;
            switch (name) {
            default:
                nextBuilder = functionBuilder;
                break;
            case "End":
            case "Delegate":
                nextBuilder = previousBuilder;
                break;
            case "Block":
            case "Loop":
            case "If":
            case "Try":
                nextBuilder = _createFunctionBuilder(func, builder, functionBuilder);
                break;
            }

            // Passing a function as the argument is a way to nest blocks lexically.
            const continuation = args[args.length - 1];
            const hasContinuation = typeof(continuation) === "function";
            const imms = hasContinuation ? args.slice(0, -1) : args; // FIXME: allow passing in stack values, as-if code were a stack machine. Just check for a builder to this function, and drop. https://bugs.webkit.org/show_bug.cgi?id=163422
            checkImms(op, imms, imm, ret);
            checkStackArgs(op, param);
            checkStackReturn(op, ret);
            const stackArgs = []; // FIXME https://bugs.webkit.org/show_bug.cgi?id=162706
            func.code.push({ name: op, value: value, arguments: stackArgs, immediates: imms });
            if (hasContinuation)
                return _errorHandlingProxyFor(continuation(nextBuilder).End());
            return _errorHandlingProxyFor(nextBuilder);
        };
    };

    return _errorHandlingProxyFor(functionBuilder);
}

const _createFunction = (section, builder, previousBuilder) => {
    return (...args) => {
        const nameOffset = (typeof(args[0]) === "string") >>> 0;
        const functionName = nameOffset ? args[0] : undefined;
        let signature = args[0 + nameOffset];
        const locals = args[1 + nameOffset] === undefined ? [] : args[1 + nameOffset];
        for (const local of locals)
            assert.truthy(WASM.isValidValueType(local), `Type of local: ${local} needs to be a valid value type`);

        if (typeof(signature) === "undefined")
            signature = { params: [] };

        let type;
        let params;
        if (typeof signature === "object") {
            assert.hasObjectProperty(signature, "params", `Expect function signature to be an object with a "params" field, got "${signature}"`);
            let ret;
            ([params, ret] = _normalizeFunctionSignature(signature.params, signature.ret));
            signature = {params, ret};
            type = _maybeRegisterType(builder, signature);
        } else {
            assert.truthy(typeof signature === "number");
            const typeSection = builder._getSection("Type");
            assert.truthy(!!typeSection);
            // FIXME: we should allow indices that exceed this to be able to
            // test JSCs validator is correct. https://bugs.webkit.org/show_bug.cgi?id=165786
            assert.truthy(signature < typeSection.data.length);
            type = signature;
            signature = typeSection.data[signature];
            assert.hasObjectProperty(signature, "params", `Expect function signature to be an object with a "params" field, got "${signature}"`);
            params = signature.params;
        }

        const func = {
            name: functionName,
            type,
            signature: signature,
            locals: params.concat(locals), // Parameters are the first locals.
            parameterCount: params.length,
            code: []
        };

        const functionSection = builder._getSection("Function");
        if (functionSection)
            functionSection.data.push(func.type);

        section.data.push(func);
        builder._registerFunctionToIndexSpace(functionName);

        return _createFunctionBuilder(func, builder, previousBuilder);
    }
};

export default class Builder {
    constructor() {
        this.setChecked(true);
        let preamble = {};
        for (const p of WASM.description.preamble)
            preamble[p.name] = p.value;
        this.setPreamble(preamble);
        this._sections = [];
        this._functionIndexSpace = new Map();
        this._functionIndexSpaceCount = 0;
        this._registerSectionBuilders();
    }
    setChecked(checked) {
        this._checked = checked;
        return this;
    }
    setPreamble(p) {
        this._preamble = Object.assign(this._preamble || {}, p);
        return this;
    }
    _functionIndexSpaceKeyHash(obj) {
        // We don't need a full hash, just something that has a defined order for Map. Objects we insert aren't nested.
        if (typeof(obj) !== 'object')
            return obj;
        const keys = Object.keys(obj).sort();
        let entries = [];
        for (let k in keys)
            entries.push([k, obj[k]]);
        return JSON.stringify(entries);
    }
    _registerFunctionToIndexSpace(name) {
        if (typeof(name) === "undefined") {
            // Registering a nameless function still adds it to the function index space. Register it as something that can't normally be registered.
            name = {};
        }
        const value = this._functionIndexSpaceCount++;
        // Collisions are fine: we'll simply count the function and forget the previous one.
        this._functionIndexSpace.set(this._functionIndexSpaceKeyHash(name), value);
        // Map it both ways, the number space is distinct from the name space.
        this._functionIndexSpace.set(this._functionIndexSpaceKeyHash(value), name);
    }
    _getFunctionFromIndexSpace(name) {
        return this._functionIndexSpace.get(this._functionIndexSpaceKeyHash(name));
    }
    _registerSectionBuilders() {
        for (const section in WASM.description.section) {
            switch (section) {
            case "Type":
                this[section] = function() {
                    const s = this._addSection(section);
                    const builder = this;
                    const typeBuilder = {
                        End: () => builder,
                        Func: (params, ret) => {
                            [params, ret] = _normalizeFunctionSignature(params, ret);
                            s.data.push({ params: params, ret: ret });
                            return _errorHandlingProxyFor(typeBuilder);
                        },
                    };
                    return _errorHandlingProxyFor(typeBuilder);
                };
                break;

            case "Import":
                this[section] = function() {
                    const s = this._addSection(section);
                    const importBuilder = {
                        End: () => this,
                    };
                    importBuilder.Global = _importGlobalContinuation(this, s, importBuilder);
                    importBuilder.Function = _importFunctionContinuation(this, s, importBuilder);
                    importBuilder.Memory = _importMemoryContinuation(this, s, importBuilder);
                    importBuilder.Table = _importTableContinuation(this, s, importBuilder);
                    importBuilder.Exception = _importExceptionContinuation(this, s, importBuilder);
                    return _errorHandlingProxyFor(importBuilder);
                };
                break;

            case "Function":
                this[section] = function() {
                    const s = this._addSection(section);
                    const functionBuilder = {
                        End: () => this
                        // FIXME: add ability to add this with whatever.
                    };
                    return _errorHandlingProxyFor(functionBuilder);
                };
                break;

            case "Table":
                this[section] = function() {
                    const s = this._addSection(section);
                    const tableBuilder = {
                        End: () => this,
                        Table: ({initial, maximum, element}) => {
                            s.data.push({tableDescription: {initial, maximum, element}});
                            return _errorHandlingProxyFor(tableBuilder);
                        }
                    };
                    return _errorHandlingProxyFor(tableBuilder);
                };
                break;

            case "Memory":
                this[section] = function() {
                    const s = this._addSection(section);
                    const memoryBuilder = {
                        End: () => this,
                        InitialMaxPages: (initial, maximum, shared = false) => {
                            s.data.push({ initial, maximum, shared });
                            return _errorHandlingProxyFor(memoryBuilder);
                        }
                    };
                    return _errorHandlingProxyFor(memoryBuilder);
                };
                break;

            case "Exception": {
                this[section] = function() {
                    const s = this._addSection(section);
                    const dataBuilder = {
                        End: () => this,
                        Signature: (signature) => {
                            let type = _maybeRegisterType(this, signature);
                            s.data.push({ tag: 0, type });
                            return _errorHandlingProxyFor(dataBuilder);
                        },
                        // If we add tags with non-zero value then we can add a new member.
                    };
                    return _errorHandlingProxyFor(dataBuilder);
                };
                break;
            }

            case "Global":
                this[section] = function() {
                    const s = this._addSection(section);
                    const globalBuilder = {
                        End: () => this,
                        GetGlobal: (type, initValue, mutability) => {
                            s.data.push({ type, op: "get_global", mutability: _normalizeMutability(mutability), initValue });
                            return _errorHandlingProxyFor(globalBuilder);
                        },
                        RefFunc: (type, initValue, mutability) => {
                            s.data.push({ type, op: "ref.func", mutability: _normalizeMutability(mutability), initValue });
                            return _errorHandlingProxyFor(globalBuilder);
                        },
                        RefNull: (type, mutability) => {
                            s.data.push({ type, op: "ref.null", mutability: _normalizeMutability(mutability), reftype: type});
                            return _errorHandlingProxyFor(globalBuilder);
                        }
                    };
                    for (let op of WASM.description.value_type) {
                        globalBuilder[util.toJavaScriptName(op)] = (initValue, mutability) => {
                            s.data.push({ type: op, op: op + ".const", mutability: _normalizeMutability(mutability), initValue });
                            return _errorHandlingProxyFor(globalBuilder);
                        };
                    }
                    return _errorHandlingProxyFor(globalBuilder);
                };
                break;

            case "Export":
                this[section] = function() {
                    const s = this._addSection(section);
                    const exportBuilder = {
                        End: () => this,
                    };
                    exportBuilder.Global = _exportGlobalContinuation(this, s, exportBuilder);
                    exportBuilder.Function = _exportFunctionContinuation(this, s, exportBuilder);
                    exportBuilder.Memory = _exportMemoryContinuation(this, s, exportBuilder);
                    exportBuilder.Table = _exportTableContinuation(this, s, exportBuilder);
                    exportBuilder.Exception = _exportExceptionContinuation(this, s, exportBuilder);
                    return _errorHandlingProxyFor(exportBuilder);
                };
                break;

            case "Start":
                this[section] = function(functionIndexOrName) {
                    const s = this._addSection(section);
                    const startBuilder = {
                        End: () => this,
                    };
                    if (typeof(functionIndexOrName) !== "number" && typeof(functionIndexOrName) !== "string")
                        throw new Error(`Start section's function index  must either be a number or a string`);
                    s.data.push(functionIndexOrName);
                    return _errorHandlingProxyFor(startBuilder);
                };
                break;

            case "Element":
                this[section] = function(...args) {
                    if (args.length !== 0 && this._checked)
                        throw new Error("You're doing it wrong. This element does not take arguments. You must chain the call with another Element()");

                    const s = this._addSection(section);
                    const elementBuilder = {
                        End: () => this,
                        Element: ({tableIndex = 0, offset, elemkind = 0, functionIndices}) => {
                            s.data.push({tableIndex, offset, elemkind, functionIndices});
                            return _errorHandlingProxyFor(elementBuilder);
                        }
                    };

                    return _errorHandlingProxyFor(elementBuilder);
                };
                break;

            case "Code":
                this[section] = function() {
                    const s = this._addSection(section);
                    const builder = this;
                    const codeBuilder =  {
                        End: () => {
                            // We now have enough information to remap the export section's "type" and "index" according to the Code section we are currently ending.
                            const typeSection = builder._getSection("Type");
                            const importSection = builder._getSection("Import");
                            const exportSection = builder._getSection("Export");
                            const startSection = builder._getSection("Start");
                            const codeSection = s;
                            if (exportSection) {
                                for (const e of exportSection.data) {
                                    if (e.kind !== "Function" || typeof(e.type) !== "undefined")
                                        continue;
                                    switch (typeof(e.index)) {
                                    default: throw new Error(`Unexpected export index "${e.index}"`);
                                    case "string": {
                                        const index = builder._getFunctionFromIndexSpace(e.index);
                                        assert.isNumber(index, `Export section contains undefined function "${e.index}"`);
                                        e.index = index;
                                    } // Fallthrough.
                                    case "number": {
                                        const index = builder._getFunctionFromIndexSpace(e.index);
                                        if (builder._checked)
                                            assert.isNotUndef(index, `Export "${e.field}" does not correspond to a defined value in the function index space`);
                                    } break;
                                    case "undefined":
                                        throw new Error(`Unimplemented: Function().End() with undefined export index`); // FIXME
                                    }
                                    if (typeof(e.type) === "undefined") {
                                        // This must be a function export from the Code section (re-exports were handled earlier).
                                        let functionIndexSpaceOffset = 0;
                                        if (importSection) {
                                            for (const {kind} of importSection.data) {
                                                if (kind === "Function")
                                                    ++functionIndexSpaceOffset;
                                            }
                                        }
                                        const functionIndex = e.index - functionIndexSpaceOffset;
                                        e.type = codeSection.data[functionIndex].type;
                                    }
                                }
                            }
                            if (startSection) {
                                const start = startSection.data[0];
                                let mapped = builder._getFunctionFromIndexSpace(start);
                                if (!builder._checked) {
                                    if (typeof(mapped) === "undefined")
                                        mapped = start; // In unchecked mode, simply use what was provided if it's nonsensical.
                                    assert.isA(start, "number"); // It can't be too nonsensical, otherwise we can't create a binary.
                                    startSection.data[0] = start;
                                } else {
                                    if (typeof(mapped) === "undefined")
                                        throw new Error(`Start section refers to non-existant function '${start}'`);
                                    if (typeof(start) === "string" || typeof(start) === "object")
                                        startSection.data[0] = mapped;
                                    // FIXME in checked mode, test that the type is acceptable for start function. We probably want _registerFunctionToIndexSpace to also register types per index. https://bugs.webkit.org/show_bug.cgi?id=165658
                                }
                            }
                            return _errorHandlingProxyFor(builder);
                        },

                    };
                    codeBuilder.Function = _createFunction(s, builder, codeBuilder);
                    return _errorHandlingProxyFor(codeBuilder);
                };
                break;

            case "Data":
                this[section] = function() {
                    const s = this._addSection(section);
                    const dataBuilder = {
                        End: () => this,
                        Segment: data => {
                            assert.isArray(data);
                            for (const datum of data) {
                                assert.isNumber(datum);
                                assert.ge(datum, 0);
                                assert.le(datum, 0xff);
                            }
                            s.data.push({ data: data, index: 0, offset: 0 });
                            let thisSegment = s.data[s.data.length - 1];
                            const segmentBuilder = {
                                End: () => dataBuilder,
                                Index: index => {
                                    assert.eq(index, 0); // Linear memory index must be zero in MVP.
                                    thisSegment.index = index;
                                    return _errorHandlingProxyFor(segmentBuilder);
                                },
                                Offset: offset => {
                                    // FIXME allow complex init_expr here. https://bugs.webkit.org/show_bug.cgi?id=165700
                                    assert.isNumber(offset);
                                    thisSegment.offset = offset;
                                    return _errorHandlingProxyFor(segmentBuilder);
                                },
                            };
                            return _errorHandlingProxyFor(segmentBuilder);
                        },
                    };
                    return _errorHandlingProxyFor(dataBuilder);
                };
                break;

            default:
                this[section] = () => { throw new Error(`Unknown section type "${section}"`); };
                break;
            }
        }

        this.Unknown = function(name) {
            const s = this._addSection(name);
            const builder = this;
            const unknownBuilder =  {
                End: () => builder,
                Byte: b => {
                    assert.eq(b & 0xFF, b, `Unknown section expected byte, got: "${b}"`);
                    s.data.push(b);
                    return _errorHandlingProxyFor(unknownBuilder);
                }
            };
            return _errorHandlingProxyFor(unknownBuilder);
        };
    }
    _addSection(nameOrNumber, extraObject) {
        const name = typeof(nameOrNumber) === "string" ? nameOrNumber : "";
        const number = typeof(nameOrNumber) === "number" ? nameOrNumber : (WASM.description.section[name] ? WASM.description.section[name].value : _unknownSectionId);
        if (this._checked) {
            // Check uniqueness.
            for (const s of this._sections)
                if (number !== _unknownSectionId)
                    assert.falsy(s.name === name && s.id === number, `Cannot have two sections with the same name "${name}" and ID ${number}`);
        }
        const s = Object.assign({ name: name, id: number, data: [] }, extraObject || {});
        this._sections.push(s);
        return s;
    }
    _getSection(nameOrNumber) {
        switch (typeof(nameOrNumber)) {
        default: throw new Error(`Implementation problem: can not get section "${nameOrNumber}"`);
        case "string":
            for (const s of this._sections)
                if (s.name === nameOrNumber)
                    return s;
            return undefined;
        case "number":
            for (const s of this._sections)
                if (s.id === nameOrNumber)
                    return s;
            return undefined;
        }
    }
    optimize() {
        // FIXME Add more optimizations. https://bugs.webkit.org/show_bug.cgi?id=163424
        return this;
    }
    json() {
        const obj = {
            preamble: this._preamble,
            section: this._sections
        };
        // JSON.stringify serializes -0.0 as 0.0.
        const replacer = (key, value) => {
            if (value === 0.0 && 1.0 / value === -Infinity)
                return "NEGATIVE_ZERO";
            return value;
        };
        return JSON.stringify(obj, replacer);
    }
    AsmJS() {
        "use asm"; // For speed.
        // FIXME Create an asm.js equivalent string which can be eval'd. https://bugs.webkit.org/show_bug.cgi?id=163425
        throw new Error("asm.js not implemented yet");
    }
    WebAssembly() { return BuildWebAssembly.Binary(this._preamble, this._sections); }
};
