# Path: wasmfun/components.py
# class Module(WASMComponent):
#     """ Class to represent a WASM module; the toplevel unit of code.
#     The subcomponents of a module are objects that derive from `Section`.
#     It is recommended to provide `Function` and `ImportedFunction` objects,
#     from which the module will polulate the function-related sections, and
#     handle the binding of the function index space.
#     """
#     
#     __slots__ = ['sections', 'func_id_to_index']
#     
#     def __init__(self, *sections):
#         # Process sections, filter out high-level functions
#         self.sections = []
#         has_lowlevel_funcs = False
#         functions = []
#         start_section = None
#         import_section = None
#         export_section = None
#         for section in sections:
#             if isinstance(section, (Function, ImportedFuncion)):
#                 functions.append(section)
#             elif isinstance(section, Section):
#                 self.sections.append(section)
#                 if isinstance(section, (TypeSection, CodeSection)):
#                     has_lowlevel_funcs = True
#                 elif isinstance(section, StartSection):
#                     start_section = section
#                 elif isinstance(section, ImportSection):
#                     import_section = section
#                 elif isinstance(section, ExportSection):
#                     export_section = section
#             else:
#                 raise TypeError('Module expects a Function, ImportedFunction, or a Section.')
#         
#         # Process high level function desctiptions?
#         if functions and has_lowlevel_funcs:
#             raise TypeError('Module cannot have both Functions/ImportedFunctions and FunctionDefs/FunctionSigs.')
#         elif functions:
#             self._process_functions(functions, start_section, import_section, export_section)
#         
#         # Sort the sections
#         self.sections.sort(key=lambda x: x.id)
#         
#         # Prepare functiondefs
#         for section in reversed(self.sections):
#             if isinstance(section, CodeSection):
#                 for funcdef in section.functiondefs:
#                     funcdef.module = self
#                 break 
#     
#     def _process_functions(self, functions, start_section, import_section, export_section):
#         
#         # Prepare processing functions. In the order of imported and then defined,
#         # because that's the order of the function index space. We use the function
#         # index also for the signature index, though that's not strictly necessary
#         # (e.g. functions can share a signature).
#         # Function index space is used in, calls, exports, elementes, start function.
#         auto_sigs = []
#         auto_defs = []
#         auto_imports = []
#         auto_exports = []
#         auto_start = None
#         function_index = 0
#         self.func_id_to_index = {}
#         # Process imported functions
#         for func in functions:
#             if isinstance(func, ImportedFuncion):
#                 auto_sigs.append(FunctionSig(func.params, func.returns))
#                 auto_imports.append(Import(func.modname, func.fieldname, 'function', function_index))
#                 if func.export:
#                     auto_exports.append((func.idname, 'function', function_index))
#                 self.func_id_to_index[func.idname] = function_index
#                 function_index += 1
#         # Process defined functions
#         for func in functions:
#             if isinstance(func, Function):
#                 auto_sigs.append(FunctionSig(func.params, func.returns))
#                 auto_defs.append(FunctionDef(func.locals, *func.instructions))
#                 if func.export:
#                     auto_exports.append((func.idname, 'function', function_index))
#                 if func.idname == '$main' and start_section is None:
#                     auto_start = StartSection(function_index)
#                 self.func_id_to_index[func.idname] = function_index
#                 function_index += 1
#         
#         # Insert auto-generated function sigs and defs
#         self.sections.append(TypeSection(*auto_sigs))
#         self.sections.append(CodeSection(*auto_defs))
#         # Insert auto-generated imports
#         if import_section is None:
#             import_section = ImportSection()
#             self.sections.append(import_section)
#         import_section.imports.extend(auto_imports)
#         # Insert auto-generated exports
#         if export_section is None:
#             export_section = ExportSection()
#             self.sections.append(export_section)
#         export_section.exports.extend(auto_exports)
#         # Insert function section
#         self.sections.append(FunctionSection(*range(len(auto_imports), function_index)))
#         # Insert start section
#         if auto_start is not None:
#             self.sections.append(auto_start)
#     
#     def to_text(self):
#         return 'Module(\n' + self._get_sub_text(self.sections, True) + '\n)'
#     
#     def to_file(self, f):
#         f.write(b'\x00asm')
#         f.write(packu32(1))  # version, must be 1 for now
#         for section in self.sections:
#             section.to_file(f)


import os
import tempfile
import subprocess
from .components import Module
    from IPython.display import display, HTML, Javascript


def inspect_bytes_at(bb, offset):
    """ Inspect bytes at the specified offset.
    """
    start = max(0, offset - 16)
    end = offset + 16
    bytes2show = bb[start:end]
    bytes2skip = bb[start:offset]
    text_offset = len(repr(bytes2skip))
    print(bytes2show)
    print('|'.rjust(text_offset))


def hexdump(bb):
    """ Do a hexdump of the given bytes.
    """
    i = 0
    line = 0
    while i < len(bb):
        ints = [hex(j)[2:].rjust(2, '0') for j in bb[i:i+16]]
        print(str(line).rjust(8, '0'), *ints, sep=' ')
        i += 16
        line += 1


def export_wasm_example(filename, code, wasm):
    """ Generate an html file for the given code and wasm module.
    """
    

# Path: wasmfun/components.py
# class Module(WASMComponent):
#     """ Class to represent a WASM module; the toplevel unit of code.
#     The subcomponents of a module are objects that derive from `Section`.
#     It is recommended to provide `Function` and `ImportedFunction` objects,
#     from which the module will polulate the function-related sections, and
#     handle the binding of the function index space.
#     """
#     
#     __slots__ = ['sections', 'func_id_to_index']
#     
#     def __init__(self, *sections):
#         # Process sections, filter out high-level functions
#         self.sections = []
#         has_lowlevel_funcs = False
#         functions = []
#         start_section = None
#         import_section = None
#         export_section = None
#         for section in sections:
#             if isinstance(section, (Function, ImportedFuncion)):
#                 functions.append(section)
#             elif isinstance(section, Section):
#                 self.sections.append(section)
#                 if isinstance(section, (TypeSection, CodeSection)):
#                     has_lowlevel_funcs = True
#                 elif isinstance(section, StartSection):
#                     start_section = section
#                 elif isinstance(section, ImportSection):
#                     import_section = section
#                 elif isinstance(section, ExportSection):
#                     export_section = section
#             else:
#                 raise TypeError('Module expects a Function, ImportedFunction, or a Section.')
#         
#         # Process high level function desctiptions?
#         if functions and has_lowlevel_funcs:
#             raise TypeError('Module cannot have both Functions/ImportedFunctions and FunctionDefs/FunctionSigs.')
#         elif functions:
#             self._process_functions(functions, start_section, import_section, export_section)
#         
#         # Sort the sections
#         self.sections.sort(key=lambda x: x.id)
#         
#         # Prepare functiondefs
#         for section in reversed(self.sections):
#             if isinstance(section, CodeSection):
#                 for funcdef in section.functiondefs:
#                     funcdef.module = self
#                 break 
#     
#     def _process_functions(self, functions, start_section, import_section, export_section):
#         
#         # Prepare processing functions. In the order of imported and then defined,
#         # because that's the order of the function index space. We use the function
#         # index also for the signature index, though that's not strictly necessary
#         # (e.g. functions can share a signature).
#         # Function index space is used in, calls, exports, elementes, start function.
#         auto_sigs = []
#         auto_defs = []
#         auto_imports = []
#         auto_exports = []
#         auto_start = None
#         function_index = 0
#         self.func_id_to_index = {}
#         # Process imported functions
#         for func in functions:
#             if isinstance(func, ImportedFuncion):
#                 auto_sigs.append(FunctionSig(func.params, func.returns))
#                 auto_imports.append(Import(func.modname, func.fieldname, 'function', function_index))
#                 if func.export:
#                     auto_exports.append((func.idname, 'function', function_index))
#                 self.func_id_to_index[func.idname] = function_index
#                 function_index += 1
#         # Process defined functions
#         for func in functions:
#             if isinstance(func, Function):
#                 auto_sigs.append(FunctionSig(func.params, func.returns))
#                 auto_defs.append(FunctionDef(func.locals, *func.instructions))
#                 if func.export:
#                     auto_exports.append((func.idname, 'function', function_index))
#                 if func.idname == '$main' and start_section is None:
#                     auto_start = StartSection(function_index)
#                 self.func_id_to_index[func.idname] = function_index
#                 function_index += 1
#         
#         # Insert auto-generated function sigs and defs
#         self.sections.append(TypeSection(*auto_sigs))
#         self.sections.append(CodeSection(*auto_defs))
#         # Insert auto-generated imports
#         if import_section is None:
#             import_section = ImportSection()
#             self.sections.append(import_section)
#         import_section.imports.extend(auto_imports)
#         # Insert auto-generated exports
#         if export_section is None:
#             export_section = ExportSection()
#             self.sections.append(export_section)
#         export_section.exports.extend(auto_exports)
#         # Insert function section
#         self.sections.append(FunctionSection(*range(len(auto_imports), function_index)))
#         # Insert start section
#         if auto_start is not None:
#             self.sections.append(auto_start)
#     
#     def to_text(self):
#         return 'Module(\n' + self._get_sub_text(self.sections, True) + '\n)'
#     
#     def to_file(self, f):
#         f.write(b'\x00asm')
#         f.write(packu32(1))  # version, must be 1 for now
#         for section in self.sections:
#             section.to_file(f)


# Path: wasmfun/util.py
import os
import tempfile
import subprocess
from .components import Module
    from IPython.display import display, HTML, Javascript



def inspect_bytes_at(bb, offset):
    """ Inspect bytes at the specified offset.
    """
    start = max(0, offset - 16)
    end = offset + 16
    bytes2show = bb[start:end]
    bytes2skip = bb[start:offset]
    text_offset = len(repr(bytes2skip))
    print(bytes2show)
    print('|'.rjust(text_offset))


def hexdump(bb):
    """ Do a hexdump of the given bytes.
    """
    i = 0
    line = 0
    while i < len(bb):
        ints = [hex(j)[2:].rjust(2, '0') for j in bb[i:i+16]]
        print(str(line).rjust(8, '0'), *ints, sep=' ')
        i += 16
        line += 1


def export_wasm_example(filename, code, wasm):
    """ Generate an html file for the given code and wasm module.
    """
    

    if isinstance(wasm, Module):