Beispiel #1
0
 def from_reader(cls, r: typing.BinaryIO):
     o = ElementSegment()
     o.tableidx = common.read_count(r, 32)
     o.expr = Expression.from_reader(r)
     n = common.read_count(r, 32)
     o.init = [common.read_count(r, 32) for _ in range(n)]
     return o
Beispiel #2
0
 def from_reader(cls, r: typing.BinaryIO):
     code_byte = r.read(1)
     if not code_byte:
         return None
     code = ord(code_byte)
     code_size = convention.opcodes[code][1]
     if code_size == '':
         immediate_arguments = None
     elif code_size == 'u8':
         immediate_arguments = common.read_count(r, 8)
     elif code_size == 'u32':
         immediate_arguments = common.read_count(r, 32)
     elif code_size == 'i32':
         immediate_arguments = num.int2i32(common.read_count(r, 32, signed=True))
     elif code_size == 'i64':
         immediate_arguments = num.int2i64(common.read_count(r, 64, signed=True))
     elif code_size == 'f32':
         immediate_arguments = num.LittleEndian.f32(r.read(4))
     elif code_size == 'f64':
         immediate_arguments = num.LittleEndian.f64(r.read(8))
     elif code_size == 'u32,u8':
         immediate_arguments = [common.read_count(r, 32), common.read_count(r, 8)]
     elif code_size == 'u32,u32':
         immediate_arguments = [common.read_count(r, 32) for _ in range(2)]
     elif code == convention.br_table:
         n = common.read_count(r, 32)
         a = [common.read_count(r, 32) for _ in range(n)]
         b = common.read_count(r, 32)
         immediate_arguments = [a, b]
     else:
         raise Exception('pywasm: invalid code size')
     return Instruction(code, immediate_arguments)
Beispiel #3
0
 def from_reader(cls, r: typing.BinaryIO):
     o = Code()
     n = common.read_count(r, 32)
     n = common.read_count(r, 32)
     for _ in range(n):
         l = Locals.from_reader(r)
         o.locals.extend([l.valtype for _ in range(l.n)])
     o.expr = Expression.from_reader(r)
     return o
Beispiel #4
0
 def from_reader(cls, r: typing.BinaryIO):
     o = Import()
     o.module = common.read_bytes(r, 32).decode()
     o.name = common.read_bytes(r, 32).decode()
     o.kind = ord(r.read(1))
     if o.kind == convention.extern_func:
         o.desc = common.read_count(r, 32)
     elif o.kind == convention.extern_table:
         o.desc = TableType.from_reader(r)
     elif o.kind == convention.extern_mem:
         o.desc = MemoryType.from_reader(r)
     elif o.kind == convention.extern_global:
         o.desc = GlobalType.from_reader(r)
     else:
         raise Exception('pywasm: malformed')
     return o
Beispiel #5
0
    def from_reader(cls, r: typing.BinaryIO) -> 'Module':
        if list(r.read(4)) != [0x00, 0x61, 0x73, 0x6d]:
            raise Exception('pywasm: invalid magic number')
        if list(r.read(4)) != [0x01, 0x00, 0x00, 0x00]:
            raise Exception('pywasm: invalid version')
        mod = Module()
        log.debugln('Sections:')
        log.debugln()
        while True:
            section_id_byte = r.read(1)
            if not section_id_byte:
                break
            section_id = ord(section_id_byte)
            n = common.read_count(r, 32)
            data = r.read(n)
            if len(data) != n:
                raise Exception('pywasm: invalid section size')
            if section_id == convention.custom_section:
                custom_section = CustomSection.from_reader(io.BytesIO(data))
                log.debugln(
                    f'{convention.section[section_id][0]:>9} {custom_section.name}'
                )
            elif section_id == convention.type_section:
                type_section = TypeSection.from_reader(io.BytesIO(data))
                for i, e in enumerate(type_section.vec):
                    log.debugln(
                        f'{convention.section[section_id][0]:>9}[{i}] {e}')
                mod.types = type_section.vec
            elif section_id == convention.import_section:
                import_section = ImportSection.from_reader(io.BytesIO(data))
                for i, e in enumerate(import_section.vec):
                    log.debugln(
                        f'{convention.section[section_id][0]:>9}[{i}] {e}')
                mod.imports = import_section.vec
            elif section_id == convention.function_section:
                function_section = FunctionSection.from_reader(
                    io.BytesIO(data))
                num_imported_funcs = sum(1 for _ in filter(
                    lambda i: i.kind == convention.extern_func, mod.imports))
                for i, e in enumerate(function_section.vec):
                    log.debugln(
                        f'{convention.section[section_id][0]:>9}[{i}] func={num_imported_funcs+i} sig={e}'
                    )
            elif section_id == convention.table_section:
                table_section = TableSection.from_reader(io.BytesIO(data))
                for i, e in enumerate(table_section.vec):
                    log.debugln(
                        f'{convention.section[section_id][0]:>9}[{i}] {e}')
                mod.tables = table_section.vec
            elif section_id == convention.memory_section:
                memory_section = MemorySection.from_reader(io.BytesIO(data))
                for i, e in enumerate(memory_section.vec):
                    log.debugln(
                        f'{convention.section[section_id][0]:>9}[{i}] {e}')
                mod.mems = memory_section.vec
            elif section_id == convention.global_section:
                global_section = GlobalSection.from_reader(io.BytesIO(data))
                for i, e in enumerate(global_section.vec):
                    log.debugln(
                        f'{convention.section[section_id][0]:>9}[{i}] {e}')
                mod.globals = global_section.vec
            elif section_id == convention.export_section:
                export_section = ExportSection.from_reader(io.BytesIO(data))
                for i, e in enumerate(export_section.vec):
                    log.debugln(
                        f'{convention.section[section_id][0]:>9}[{i}] {e}')
                mod.exports = export_section.vec
            elif section_id == convention.start_section:
                start_section = StartSection.from_reader(io.BytesIO(data))
                log.debugln(
                    f'{convention.section[section_id][0]:>12} {start_section.start_function}'
                )
                mod.start = start_section.start_function.funcidx
            elif section_id == convention.element_section:
                element_section = ElementSection.from_reader(io.BytesIO(data))
                for i, e in enumerate(element_section.vec):
                    log.debugln(
                        f'{convention.section[section_id][0]:>9}[{i}] {e}')
                mod.elem = element_section.vec
            elif section_id == convention.code_section:
                code_section = CodeSection.from_reader(io.BytesIO(data))

                def printex(instrs: typing.List[Instruction], prefix=0):
                    for e in instrs:
                        a = f'           | {" " * prefix}{convention.opcodes[e.code][0]}'
                        if e.code in [
                                convention.block, convention.loop,
                                convention.if_
                        ]:
                            log.debugln(
                                f'{a} {convention.blocktype[e.immediate_arguments][0]}'
                            )
                            prefix += 2
                        elif e.code == convention.end:
                            prefix -= 2
                            a = f'           | {" " * prefix}{convention.opcodes[e.code][0]}'
                            log.debugln(f'{a}')
                        elif e.immediate_arguments is None:
                            log.debugln(f'{a}')
                        elif isinstance(e.immediate_arguments, list):
                            log.debugln(
                                f'{a} {" ".join([str(e) for e in e.immediate_arguments])}'
                            )
                        else:
                            log.debugln(f'{a} {e.immediate_arguments}')

                num_imported_funcs = sum(1 for _ in filter(
                    lambda i: i.kind == convention.extern_func, mod.imports))
                for i, e in enumerate(code_section.vec):
                    log.debugln(
                        f'{convention.section[section_id][0]:>9}[{i}] func={num_imported_funcs+i} {e}'
                    )
                    printex(e.expr.data)
                    func = Function()
                    func.typeidx = function_section.vec[i]
                    func.locals = e.locals
                    func.expr = e.expr
                    mod.funcs.append(func)
            elif section_id == convention.data_section:
                data_section = DataSection.from_reader(io.BytesIO(data))
                for i, e in enumerate(data_section.vec):
                    log.debugln(
                        f'{convention.section[section_id][0]:>9}[{i}] {e}')
                mod.data = data_section.vec
            else:
                raise Exception('pywasm: invalid section id')
        log.debugln('')
        return mod
Beispiel #6
0
 def from_reader(cls, r: typing.BinaryIO):
     o = DataSection()
     n = common.read_count(r, 32)
     o.vec = [DataSegment.from_reader(r) for _ in range(n)]
     return o
Beispiel #7
0
 def from_reader(cls, r: typing.BinaryIO):
     o = GlobalSection()
     n = common.read_count(r, 32)
     o.vec = [Global.from_reader(r) for _ in range(n)]
     return o
Beispiel #8
0
 def from_reader(cls, r: typing.BinaryIO):
     o = FunctionSection()
     n = common.read_count(r, 32)
     o.vec = [common.read_count(r, 32) for _ in range(n)]
     return o
Beispiel #9
0
 def from_reader(cls, r: typing.BinaryIO):
     flag = ord(r.read(1))
     minimum = common.read_count(r)
     maximum = common.read_count(r) if flag else None
     return Limits(minimum, maximum)
Beispiel #10
0
 def from_reader(cls, r: typing.BinaryIO):
     o = CustomSection()
     n = common.read_count(r, 32)
     o.name = r.read(n).decode()
     o.data = bytearray(r.read(-1))
     return o
Beispiel #11
0
 def from_reader(cls, r: typing.BinaryIO):
     o = Export()
     o.name = common.read_bytes(r, 32).decode()
     o.kind = ord(r.read(1))
     o.desc = common.read_count(r, 32)
     return o
Beispiel #12
0
 def from_reader(cls, r: typing.BinaryIO):
     o = StartFunction()
     o.funcidx = common.read_count(r, 32)
     return o
Beispiel #13
0
 def from_reader(cls, r: typing.BinaryIO):
     o = DataSegment()
     o.memidx = common.read_count(r, 32)
     o.expr = Expression.from_reader(r)
     o.init = bytearray(common.read_bytes(r, 32))
     return o
Beispiel #14
0
 def from_reader(cls, r: typing.BinaryIO):
     o = Locals()
     o.n = common.read_count(r, 32)
     o.valtype = ord(r.read(1))
     return o