-
Notifications
You must be signed in to change notification settings - Fork 725
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
options skip_function_bodies can not work with ReadBinaryIr #2534
Comments
the bug of run in Android, I'v got the error "Can't populate more pages for size class 224", |
i think the reason is allocating too mush times. a wasm of a unity demo game, will new 14,767,201 times. here is my solution: extends BinaryReaderIR, replace [std::make_unique] refer [AppendExpr], to [spec_make_unique] before ~Module then it will run well in Android. i hopes there is an official version with override memery alloc |
with using mem pool(release big buffer at end, and each opCode save some bytes and time for avoiding manage free memory), I will make a branch for saving memory. |
i'v make a pr, solve the error of ReadBinaryIr when options.skip_function_bodies=true |
do you need the IR? why not use binary reader directly? |
A typical wasm size of an Unity game, is about 50-70M first step, i override operate new, for func expr will not delete at decode wasm, so they can be allocate solid in a big buffer. but, memory is still insufficient on low-end iOS devices. |
yeah, that happens when using the IR. why not use |
Can you explain what you are trying to do here? For example, it sounds like you are trying to run a unity game on an phone using the wabt interpreter? Is that right? |
load local wasm , and mod or inject sth in byte code. libbinaryen can process the task in low mem, but libbinaryen is a bit slowly. libwabt decode 250% faster than libbinaryen. (libbinaryen 5 second vs libwabt 2s) what i did: |
that's what we figured you were doing, and we would still recommend using ReadBinary instead. it's a streaming parser so you only need enough RAM for roughly two copies of the wasm (the original and the modded), plus you still get decoded bytecode instead of raw bytecode. |
does it means that, i impl a new BinaryReaderDelegate? so the point is, i can't decode function bodies at first step, but needs byte code of funcs for second-pass decode. here is my demo Pseudocode
in pc , we turned skip_function_bodies off, and in phone we skip_function_bodies skip_function_bodies on,
|
the webassembly binary format is mostly designed for single-pass processing, this is why imports come before anything else. so the first thing that would be decoded would be the number of imports. you'd then immediately start emitting a new webassembly binary, with the extra imports added, and then go on to process the elem id, export id, etc. no need to save the decoded forms. |
i think the read option skip_function_bodies is designed for quick analysis other blocks, but i think it should retain the ability to output again. I just enhanced the compatibility of this option, even though it won't be used in most cases. when we add a new import function, the func index must insert at the import block, this means that, every call cmd which id >= num_func_imports should add an offset (+1). steaming decode and encode can save memory, but it seems a big project, does writeModule accept an incomplete module? when On****Expr, encode and put it in an output stream, and release the Expr? so the first commit is just save original bytes when option skip_function_bodies turns on. Modifying WASM on low-memory devices may be a rare requirement, but fortunately, the amount of modification needed is not significant. |
oh wait, we don't really have a streaming module writer. hmm... (is it needed? how hard would it be to write out a module as it's being read? maybe this is something that could be improved.) |
in my case, modify wasm in stream is a bit hard for I must add all import function before i scaned the function section, and i need to save lots of context info for modifying. I wonder what dose the option skip_function_bodies usually used for ? I also think it's a bit ugly for add an virtual ExprType, maybe a spec struct is a better choice. but when I noticed that there is a lot of code that switches on (eptr->type()), creating a dedicated struct might lead to a large number of modifications. so I chose the current solution. btw, i handle wabt_expr_make_unique with a solid mem pool, it significantly improve the decoding performance of expr. |
we believe skip_function_bodies was never designed for use with ReadBinaryIr. it should probably have rejected it. (in fact, it seems to only be used by objdump.) |
Yes, |
I didn't know what this option was for at first, so i wrapped the feature in a macro, although a simple memcpy will cost only little time in DelegateNop. it can work with ReadBinaryIr when turned the macro on. when this macro is disabled, it has no side effects. |
wabt::Result errorCode = wabt::ReadBinaryIr("", wasmData, fileSize, options, &errors,
&module);
will got an assert
at function [Result BinaryReaderIR::EndFunctionBody(Index index)]
of file
[binary-reader-ir.cc]
the reason is: PushLabel at BinaryReaderIR::BeginFunctionBody, but not consume it when 'skip_function_bodies' turns on.
I think it should add a Step names SkipExpr or trans options on BeginFunctionBody.
BTW, i got another problem, when parse a big wasm in Android, it will crash randomly when parse function code, but same code work well in MacOS. when i skip_function_bodies, it works well.
i will provide detail later.
The text was updated successfully, but these errors were encountered: