Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

WASM Crate Architecture

Gyubong edited this pageSep 10, 2022 ·8 revisions

WASMVirtualMachine

The core of therustpython_wasm crate is theWASMVirtualMachine class. Allit contains a singleid field:

structWASMVirtualMachine{id:String,}

It has a few methods, most notablyeval(),exec(), andexecSingle(), whicheach takes a source string and corresponds to the different compilation modesEval,Exec, andSingle. There's alsosetStdout(), which takes a JSfunction or the string"console" and sets theprint() function in the Pythonbuiltin module to either call that function or print usingconsole.log().There'saddToScope(), which takes an identifier string and a JS value and setsthat name to that value. Lastly, there'sinjectModule(), which takes a modulename string and a JS object and injects that object as a module into thestdlib_inits on the VM.

But where is the VM? All thatWASMVirtualMachine stores is an id string. Well,what id corresponds to a key in a static[1]HashMapSTORED_VMS.

staticSTORED_VMS:RefCell<HashMap<String,Rc<StoredVirtualMachine>>>

Yeah, four closing braces at the end, yikes. You may notice that the innermostvalue type isn't arustpython_vm::VirtualMachine, it's aStoredVirtualMachine. That's defined as such:

structStoredVirtualMachine{pubvm:VirtualMachine,pubscope:RefCell<Scope>,held_objects:RefCell<Vec<PyObjectRef>>,}

There's therustpython_vm::VirtualMachine!held_rcs I'll come back to later,but why is theScope necessary to be stored with a WASM VM?

In RustPython, scopes are stored separately from the VM, so if we want to have apersistent acrossvm.exec() calls, we need to store that scope somewhere. Ifwe wanted to, we could store a Vec or HashMap of scopes, and allow JS users tochoose which scope they want to execute in for a givenexec(), but this isfine for now.

So, when we call one of the WASMVM methods from JS, it makes sure that thereis a VM for that id (in case the VM had been deleted since the JS caller gotthe VM), gets that VM, manipulates its scope or itsVirtualMachine, andreturns.

Converting from JS to Python

This functionality is in the fnconvert::js_to_py, inwasm/lib/convert.rs.

Strings, numbers, arrays,null,undefined, and TypedArrays can all be mappedone-to-one to Python types. Functions are garbage collected, so all that'snecessary is to convert each of the arguments to the Python function that'sbeing called, and make the kwargs thethis argument. Objects are sort oftricky, because in JS they can be used as maps, classes, "modules",or what haveyou, so just converting it to a Python dict as we are right now probably isn'tthe easiest way to use objects from Python

Converting from Python to JS

This functionality is in the fnconvert::py_to_js, inwasm/lib/convert.rs.

This is mostly the same as JS to Python for dicts, numbers, bytes, etc. The onespot this is more tricky is for functions. I'd recommend reading thewasm-bindgen documentation for passing closures to JSbefore continuing with this section, to give you a background on the pitfallswith this. Essentially, we have to create awasm_bindgen::closure::Closurethat contains inside a reference to thePyObjectRef for the function and areference to a VM in order to execute that function. The first part is prettyeasy, and we use theheld_rcs field in StoredVirtualMachine from before whilekeeping a Weak reference in order to ensure that the reference to the functionobject is only held until the VM it belongs to is deallocated. We also keep aWeak reference to theStoredVirtualMachine, so that if the VM is deletedfrom JS while the closure is active, and then it's called, there's no catastrophicfailure: we just throw an error and we're done.


[1]: It's actually a thread_local variable, so that the borrow checker doesn'tcomplain about VirtualMachine not beingSend + Sync as is necessary for astatic

Clone this wiki locally

[8]ページ先頭

©2009-2025 Movatter.jp