HI guys! I trying to implemnent wasm2wasm pass that remove specific
function from wasm. Inspired by ExtractFunction pass I wrote this
code:

            for (auto& func : module->functions) {
                if (names.find(func->name) != names.end()) {
                    // wipe out all the contents
                    std::cerr << "wipe out contents of " << func->name
<< std::endl;
                    func->vars.clear();
                    func->body = module->allocator.alloc<Unreachable>();
                }
            }

This works perfect, but when runtime tries to call this function it
throws exception with stack that does not contains removed function
name. So for example I removed 3650 functions from wasm binary, but
some function are actually used and I can't find name of excluded
function.

Typical output is:
RuntimeError: unreachable executed
<anonymous>
__GLOBAL__sub_I_ArrayMetadata_cpp
callRuntimeCallbacks
ensureInitRuntime
run

I think I can do what I want if I replace body of function with
abort() command, then I think exception will be:
RuntimeError: abort called
<REMOVED_FUNCTION_NAME>
__GLOBAL__sub_I_ArrayMetadata_cpp
callRuntimeCallbacks
ensureInitRuntime
run

So what I want to do is replace actual function code with:
            {
               abort();
            }

Looking on other sources I think that following implemntation should work

            for (auto& func : module->functions) {
                if (names.find(func->name) != names.end()) {
                    // wipe out all the contents
                    std::cerr << "wipe out contents of " << func->name
<< std::endl;
                    func->vars.clear();
                    func->body = Builder(*module).makeCall("1", {},
none); // or unreachable
                }
            }

I use index "1" because "abort" is marked as 1 inside symbols file,
and also I checked with wasm2wat that 1 is abort:

            (import "env" "abort" (func (;1;) (type 1)))

inside wat there are a lot of calls to 1, simle like this `call 1`

So, I think it should works, but when I run wasm-opt with this code I
always had error:


[wasm-validator error in function $3491] unexpected false: call param
number must match, on
[none] (call $1)
[wasm-validator error in function $3563] unexpected false: call param
number must match, on
[none] (call $1)
[wasm-validator error in function $3897] unexpected false: call param
number must match, on
[none] (call $1)
[wasm-validator error in function $3898] unexpected false: call param
number must match, on
[none] (call $1)

Also I tried just to preped function body with abort():

            for (auto& func : module->functions) {
                if (names.find(func->name) != names.end()) {
                    // wipe out all the contents
                    std::cerr << "wipe out contents of " << func->name
<< std::endl;
                    auto* abort = Builder(*module).makeCall("1", {}, none);

                    Builder builder(*module);
                    auto* block = builder.makeBlock();
                    block->list.push_back(abort);
                    block->list.push_back(func->body);
                    block->finalize(func->body->type);
                    func->body = block;
                }
            }

Output of wasm-opt absolutely same. Please help me to understand how
to call abort() function.

Thanks a lot!

-- 
You received this message because you are subscribed to the Google Groups 
"emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to