Coder Social home page Coder Social logo

pywasm's People

Contributors

chen3feng avatar emilyhorsman avatar mohanson avatar spencerpark avatar thijstriemstra avatar zeldovich avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pywasm's Issues

Exception: pywasm: missing import env.time

大佬,这个报错是怎么回事,第一次接触wasm,不太懂

----> 1 pywasm.load('Wasm.wasm')

d:\python\lib\site-packages\pywasm\__init__.py in load(name, imps, opts)
     97     with open(name, 'rb') as f:
     98         module = binary.Module.from_reader(f)
---> 99         return Runtime(module, imps, opts)
    100
    101

d:\python\lib\site-packages\pywasm\__init__.py in __init__(self, module, imps, opts)
     26         for e in module.import_list:
     27             if e.module not in imps or e.name not in imps[e.module]:
---> 28                 raise Exception(f'pywasm: missing import {e.module}.{e.name}')
     29             if isinstance(e.desc, binary.TypeIndex):
     30                 a = execution.HostFunc(module.type_list[e.desc], imps[e.module][e.name])

Exception: pywasm: missing import env.time

加载的wasm文件 ☛ https://spa14.scrape.center/Wasm.wasm

Pywasm 1.0.4 does not install

 $  pip install pywasm==1.0.0
Collecting pywasm==1.0.0
  Downloading pywasm-1.0.0-py3-none-any.whl (27 kB)
Collecting numpy
  Using cached numpy-1.19.4-cp38-cp38-macosx_10_9_x86_64.whl (15.3 MB)
Installing collected packages: numpy, pywasm
Successfully installed numpy-1.19.4 pywasm-1.0.0

 $  pip install pywasm==1.0.4
Collecting pywasm==1.0.4
  Using cached pywasm-1.0.4.tar.gz (28 kB)
    ERROR: Command errored out with exit status 1:
     command: /Users/pprescod/code/open_source/wasm_api/.venv/bin/python3 -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/private/var/folders/0y/kdzktrn95clfn6_8cjfyqvx80000gp/T/pip-install-byir0hq3/pywasm/setup.py'"'"'; __file__='"'"'/private/var/folders/0y/kdzktrn95clfn6_8cjfyqvx80000gp/T/pip-install-byir0hq3/pywasm/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /private/var/folders/0y/kdzktrn95clfn6_8cjfyqvx80000gp/T/pip-pip-egg-info-zfgq73nm
         cwd: /private/var/folders/0y/kdzktrn95clfn6_8cjfyqvx80000gp/T/pip-install-byir0hq3/pywasm/
    Complete output (5 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/private/var/folders/0y/kdzktrn95clfn6_8cjfyqvx80000gp/T/pip-install-byir0hq3/pywasm/setup.py", line 7, in <module>
        with open(os.path.join(root, 'requirements.txt')) as f:
    FileNotFoundError: [Errno 2] No such file or directory: '/private/var/folders/0y/kdzktrn95clfn6_8cjfyqvx80000gp/T/pip-install-byir0hq3/pywasm/requirements.txt'
    ----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
WARNING: You are using pip version 20.2.1; however, version 20.3.3 is available.
You should consider upgrading via the '/Users/pprescod/code/open_source/wasm_api/.venv/bin/python3 -m pip install --upgrade pip' command.

The structure of memoryInstance.

I was confused with the structure of memoryInstance, why the type of data is bytearray? How about dict with bytearray in it? Doesn't this structure better match the addressing approach of memory?

API Documents

Are there any docs (perhaps at least auto-generated docs) describing what pywasm.Memory, pywasm.Limits, etc. are?

Reattaching imported functions

I call a runtime instance several times, but each time I need to reattach env functions (because apparently, the old ones refer to outdated data). On first try

runtime.imps = newimps

does not seem to work. Is this possible? I'd prefer to do this without having to reload the entire runtime (which would necessitate loading the .wasm binary from the filessystem again etc.)

Example code has no print to terminal

# ./test.py 
import pywasm
# pywasm.on_debug()

runtime = pywasm.load('./examples/fib.wasm')
r = runtime.exec('fib', [10])
print(r) # 55

> python3 ./test.py 

Pop out value from stack when call/invoke ends.

For performance, does not automatically pop out data when call / invoke ends, which is different from the spec, because in most case, we push the result from call / invoke into stack again.

I am going to remove this performance optimization to be exactly the same as the spec describes.

Resuming a program where it left off when it reached a resource limit

As I understand it, when a Limit is reached, an assertion triggers an exception, the execution halts and if one wants the results, the called function will have to be restarted again, with higher limits.

Would there be a way to implement suspension and resumption when this happens, so the runtime state isn't discarded, much like Stackless Python can: https://stackless.readthedocs.io/en/latest/library/stackless/pickling.html ?

One use case would be something along my https://rlc-chess.com project:

A P2P wireless environment is simulated. Nodes can send messages to other nodes within some radius. Each has a unique id and gets a special packet with the id of another node. The objective is for as many nodes as possible to deliver the packets to the right node. Participants can submit .wasm programs that are instantiated for each node and that try to route the packets correctly.

https://www.youtube.com/watch?v=Y8MvSAZ-YMk

I could do the same as with the chess competition and limit the number of instructions each node can use to process each packet it receives. But it would also be interesting for each node to divide up the time itself. If the interpreter can continue the execution at the exact same instruction and state where it left off, this could be done.

This is something the Life VM also supports: perlin-network/life#52
Not sure how hard this would be to implement.

It might look like this

class Node:
    def __init__(self):
         self.runtime = pywasm.load(...)
         self.result = None

nodes = [Node() for i in range(20)]

while True:
    for node in nodes:
        node.runtime.machine.opts.cycle_limit = 1000
        # I guess instead of raising an assertion, a "soft" return would be required
        if node.result.state == pywasm.RESOURCE_EXCEPTION:
            node.result = node.runtime.resume()
        else:
            node.result = node.runtime.exec("process", [], suspend_on_resource_exception=True)
        

This would go through each node and run it for 1000 steps each, forever. The WebAssembly code itself could contain arbitrarily complex code/loops, since the scheduling is handled this way on the outside.

Limiting the number of instruction steps

The Life WebAssembly VM supports setting instruction step ("gas") and memory allocation limits. Would this be possible to implement in pywasm too?

Use cases:

  • avoiding deliberate or accidental resource exhaustion
  • setting a limit in competitions involving .wasm executables

Pythons -O flag makes an insane difference

This is just something I noted

Running a script that spends most of its time in pywasm's exec:

$ time python main.py
real	2m0,034s
user	2m0,305s
sys	0m0,644s

And with optimizations enabled:

$ time python -O main.py
real	0m0,449s
user	0m0,908s
sys	0m0,481s

According to this -O eliminates assert statements. Not sure how much this impacts security.

Edit: ok, it seems that the code is not executed correctly, I'll have a look

I get this:

  File "main.py", line 193, in play
    runtime = pywasm.load(runtime, {
  File "/home/one/.pyenv/versions/3.8.2/lib/python3.8/site-packages/pywasm/__init__.py", line 98, in load
    module = binary.Module.from_reader(f)
  File "/home/one/.pyenv/versions/3.8.2/lib/python3.8/site-packages/pywasm/binary.py", line 1084, in from_reader
    type_section = TypeSection.from_reader(section_reader)
  File "/home/one/.pyenv/versions/3.8.2/lib/python3.8/site-packages/pywasm/binary.py", line 445, in from_reader
    o.data = [FunctionType.from_reader(r) for _ in range(n)]
  File "/home/one/.pyenv/versions/3.8.2/lib/python3.8/site-packages/pywasm/binary.py", line 445, in <listcomp>
    o.data = [FunctionType.from_reader(r) for _ in range(n)]
  File "/home/one/.pyenv/versions/3.8.2/lib/python3.8/site-packages/pywasm/binary.py", line 70, in from_reader
    o.args = ResultType.from_reader(r)
  File "/home/one/.pyenv/versions/3.8.2/lib/python3.8/site-packages/pywasm/binary.py", line 51, in from_reader
    o.data = [ValueType.from_reader(r) for i in range(n)]
  File "/home/one/.pyenv/versions/3.8.2/lib/python3.8/site-packages/pywasm/binary.py", line 51, in <listcomp>
    o.data = [ValueType.from_reader(r) for i in range(n)]
  File "/home/one/.pyenv/versions/3.8.2/lib/python3.8/site-packages/pywasm/binary.py", line 33, in from_reader
    return ValueType(ord(r.read(1)))
Exception ord() expected a character, but string of length 0 found

Ah, looking through the pywasm code it seems that the asserts have side effects, that are necessary for it to be executed correctly.

Results seem to be different from wasmer

I was playing around with wasmer and saw this implmentation I like portable stuff so i tried it.
but for some reason it doesnt behave quite the same as wasmer. I get different images.

image

image

pikchrNoImp.zip

wasmer setup

#this uses python-wasmer
from wasmer import FunctionType,Buffer,Memory,MemoryType, engine, Store, Module, Instance, Function,Value,Type
from pathlib import Path
store = Store()
module=Module(store, open('pikchrNoImp.wasm', 'rb').read())


for i in module.imports:
    print(i.name)



instance = Instance(module)#, import_object)
memory = instance.exports.memory

def write_c_string(instance,bstring:bytearray):
  ptr=instance.exports.stackAlloc(len(bstring)+1)
  mem=instance.exports.memory.int8_view()
  ptrcnt=ptr
  for c in bstring:
    mem[ptrcnt]=c
    ptrcnt+=1
  return ptr

def get_c_string(instance,ptr):
  mem = bytearray(instance.exports.memory.buffer)
  result_str = mem[ptr:].partition(b"\x00")[0] #get c string
  return str(result_str, 'UTF-8') 

in1=write_c_string(instance,b""" 
   arrow right 200% "Markdown" "Source"
   box rad 10px "Markdown" "Formatter" "(markdown.c)" fit
   arrow right 200% "HTML+SVG" "Output"
   arrow <-> down 70% from last box.s
   box same "Pikchr" "Formatter" "(pikchr.c)" fit
""")
result = instance.exports.pikchr(in1,0,0,0,0)
print(get_c_string(instance,result))

Path("wasmTest.svg").write_text(get_c_string(instance,result))

pywasm setup

#This uses python-wasmer
import pywasm
from pathlib import Path

option = pywasm.Option()
runtime = pywasm.load('PikchrNoImp.wasm')


def write_c_string(runtime,bstring:bytearray):
  ptr=runtime.exec("stackAlloc",[(len(bstring)+1)])
  mem=runtime.machine.store.mems[0].data
  ptrcnt=ptr
  for c in bstring:
    mem[ptrcnt]=c
    ptrcnt+=1
  mem[ptrcnt]=0
  return ptr

def get_c_string(runtime,ptr):
  mem = runtime.machine.store.mems[0].data
  result_str = mem[ptr:].partition(b"\x00")[0] #get c string
  return str(result_str, 'UTF-8') 

print(get_c_string(runtime,5268992))

in1=write_c_string(runtime,b""" 
   arrow right 200% "Markdown" "Source"
   box rad 10px "Markdown" "Formatter" "(markdown.c)" fit
   arrow right 200% "HTML+SVG" "Output"
   arrow <-> down 70% from last box.s
   box same "Pikchr" "Formatter" "(pikchr.c)" fit
""")

#print(dir(runtime.machine.store.mems.index()))
print(in1)
print(get_c_string(runtime,in1))


r = runtime.exec('pikchr', [in1,0,0,0,0])
print(r)
print(get_c_string(runtime,r))

Path("wasmTest.svg").write_text(get_c_string(runtime,r))

I have no idea why they would have different results? maybe math issue?

The big plan of Ancient: pywasm 1.0

In the previous period, the development of pywasm stopped, but it is now full of vitality! Yes! Yes!

To meet the pywasm 1.0, the following work is to be done

  • Rewrite leb128, and add more tests
  • Rewrite the sized-number
  • Follow the latest wasm spec
  • Follow the latest wasm tests
  • Performance test. It is too shameful now
  • Memory page
  • Maybe more.

Supplying a memory instance to a function before execution

In Python, I have a list of integers in the range 0-255, so in the uint8 range.
I want to supply them to the WebAssembly runtime before it starts execution, so the called function will be able to access it when it runs. Can I do this with pywasm?

It might look like this:

import pywasm

numbers = [1,2,3,4,5]#,...
memory = pywasm.Memory(numbers, dtype=pywasm.uint8)
runtime = pywasm.load('./examples/addlist.wasm', memories=[memory])
r = runtime.exec('addlist', [])
print(r) # 1+2+3+4+5+... = x

Issues with importing libraries

I am trying to analyse polybench suite (written in C)

Since none of your test files contain any #include, wanted to know what to do in case of such cases.

Used emscripten to comile to .c files to .wasm

On trying to load the file in pyawm using pywasm.load("filename")

Getting the following error:


Exception Traceback (most recent call last)
in
----> 1 vm = pywasm.load('polybench-c-4.1/2mm.wasm')

/usr/local/lib/python3.7/site-packages/pywasm/init.py in load(name, imps)
69 with open(name, 'rb') as f:
70 module = structure.Module.from_reader(f)
---> 71 return VirtualMachine(module, imps)
72
73

/usr/local/lib/python3.7/site-packages/pywasm/init.py in init(self, module, imps)
15 for e in self.module.imports:
16 if e.module not in imps or e.name not in imps[e.module]:
---> 17 raise Exception(f'pywasm: global import {e.module}.{e.name} not found')
18 if e.kind == convention.extern_func:
19 a = execution.HostFunc(self.module.types[e.desc], imps[e.module][e.name])

Exception: pywasm: global import env.calloc not found

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.