wasmerio / wasmer-java

☕ WebAssembly runtime for Java
https://medium.com/wasmer/announcing-the-first-java-library-to-run-webassembly-wasmer-jni-89e319d2ac7c
MIT License
593 stars 55 forks source link

feat: Instance Imports #11

Open syrusakbary opened 4 years ago

syrusakbary commented 4 years ago

We should be able to pass imports to when instantiating a WebAssembly module, so the wasm code can call the host java functions and use their results.

syrusakbary commented 4 years ago

This is resolved in master. Closing the issue

syrusakbary commented 4 years ago

(got confused about exports, reopening)

BlakeB415 commented 4 years ago

+1 would be super useful!

sigmasoldi3r commented 4 years ago

Agree! Is there any workaround?

syrusakbary commented 4 years ago

We are working on a small refactor that will enable this very easily.

BlakeB415 commented 4 years ago

Any updates?

syrusakbary commented 4 years ago

The refactor is now publicly available (wasmer 1.0.0-alpha). We just need to update the bindings :)

SuperIceCN commented 3 years ago

@syrusakbary Can I call the host java functions and use their results from wasm code now? If so, could you tell me how to do? Thanks!

Hywan commented 3 years ago

Host functions aren't supported yet. We are going to work on it :-).

SuperIceCN commented 3 years ago

Will host funtions be supported in 2021?

Hywan commented 3 years ago

In 2021 for sure! I hope in a couple of weeks :-).

roee88 commented 3 years ago

@Hywan is this being worked on? We're particularly interested in using it for memory import

jcaesar commented 3 years ago

I had a bit of a go at implementing: https://github.com/jcaesar/wasmer-java/compare/wasmer-2...jcaesar:imports?expand=1 I can't test it because gradle, so I don't expect it to work as is.

In all honesty, wasmer-java needs a rewrite, and one without the jni crate. That's an unwinnable game of catchup with glue code of dubious safety.

ripSquid commented 2 years ago

Any new info on this?

SuperIceCN commented 2 years ago

In 2021 for sure! I hope in a couple of weeks :-).

@Hywan Hello, now it's 2022.

jcaesar commented 2 years ago

Ivan quit working for wasmerio 4 months ago. ;)

sigmasoldi3r commented 2 years ago

oh dear :v @jcaesar does this mean that this feature is frozen?

jcaesar commented 2 years ago

Well, don't ask me… but I assume it's way down the list. If someone implemented it and made a PR (well, or finished my code), I assume it would get merged and released. [Edit:] Well, who knows, it might not. The releases were on bintray after all. Nobody has taken care of that either.

beaclnd commented 2 years ago

@jcaesar I have finished your code and made a PR https://github.com/wasmerio/wasmer-java/pull/64.

EXEC-CSM commented 2 years ago

@beaclnd92 I do a windows build of your PR. It runs without any errors. But if I run my java app I got the following exception:

Exception in thread "main" java.lang.UnsatisfiedLinkError: 'long org.wasmer.Imports.nativeImportsWasi()' at org.wasmer.Imports.nativeImportsWasi(Native Method) at org.wasmer.Imports.wasi(Imports.java:90)

I want to run the mappings.wasm from https://github.com/mozilla/source-map/blob/master/lib/mappings.wasm

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.commons.io.IOUtils;
import org.wasmer.Exports;
import org.wasmer.Imports;
import org.wasmer.Imports.Spec;
import org.wasmer.Instance;
import org.wasmer.Module;
import org.wasmer.Native;

public class WASM
{
    public static void main(String[] args)
    {
        new WASM();
    }

    public class WASMMapping
    {
        public int generatedLine = 0;
        public int generatedColumn = 0;
        public Integer lastGeneratedColumn = null;
        public String source = null;
        public Integer originalLine = null;
        public Integer originalColumn = null;
        public String name = null;
    }

    public Exports exports;
    private Instance wasm;

    public WASM()
    {
        init();
    }

    private void init()
    {
        byte[] moduleBytes;
        try (InputStream is = this.getClass().getResourceAsStream("mappings.wasm");)
        {
            moduleBytes = IOUtils.toByteArray(is);
            String platform = Native.getCurrentPlatformIdentifier();
            System.out.println(platform);

            /** https://github.com/beaclnd92/wasmer-java/tree/imports/src/java/org/wasmer */
            if (Module.validate(moduleBytes))
            {
                Module m = new Module(moduleBytes);

                List<Spec> specImpList = new ArrayList<>();
                /** https://github.com/mozilla/source-map/blob/master/lib/wasm.js */
                Spec spec = new Spec("env", "mapping_callback", new java.util.function.Function<List<Number>, List<Number>>() {

                    @Override
                    public List<Number> apply(List<Number> t)
                    {
                        WASMMapping mapping = new WASMMapping();
                        t.forEach(e -> System.out.println(e));

                        return Collections.emptyList();
                    }

                }, Collections.emptyList(), Collections.emptyList());
                specImpList.add(spec);

                Imports imp = Imports.from(specImpList, 0);
                this.wasm = m.instantiate(imp);
                this.exports = this.wasm.exports;
            }
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

When I use the code above I got a java runtime error:

windows-amd64
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffc6bb1b1a3, pid=36420, tid=5736
#
# JRE version: OpenJDK Runtime Environment (11.0.6+10) (build 11.0.6+10-LTS)
# Java VM: OpenJDK 64-Bit Server VM (11.0.6+10-LTS, mixed mode, tiered, compressed oops, g1 gc, windows-amd64)
# Problematic frame:
# C  [wasmer_jni12599045650012626710.lib+0x1b1a3]
#
# No core dump will be written. Minidumps are not enabled by default on client versions of Windows
#

# An error report file with more information is saved as:
# D:\app\hs_err_pid36420.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

hs_err_pid36420.log

Any help appreciated Thanks

EXEC-CSM commented 2 years ago

Think I have unterstand how to use it. ...


import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.commons.io.IOUtils;
import org.wasmer.Exports;
import org.wasmer.Imports;
import org.wasmer.Imports.Spec;
import org.wasmer.Instance;
import org.wasmer.Module;
import org.wasmer.Native;
import org.wasmer.Type;

public class WASM extends Module
{
    public static void main(String[] args)
    {
        new WASM();
    }

    static byte[] moduleBytes;

    static
    {
        try (InputStream is = WASM.class.getResourceAsStream("mappings.wasm");)
        {
            moduleBytes = IOUtils.toByteArray(is);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    public class WASMMapping
    {
        public int generatedLine = 0;
        public int generatedColumn = 0;
        public Integer lastGeneratedColumn = null;
        public String source = null;
        public Integer originalLine = null;
        public Integer originalColumn = null;
        public String name = null;
    }

    public Exports exports;
    private Instance wasm;

    public WASM()
    {
        super(WASM.moduleBytes);
        init();
    }

    private void init()
    {
        String platform = Native.getCurrentPlatformIdentifier();
        System.out.println(platform);

        // https://github.com/beaclnd92/wasmer-java/tree/imports/src/java/org/wasmer
        if (Module.validate(moduleBytes))
        {
//              Module m = new Module(moduleBytes);
            List<Type> typeList = new ArrayList<>();
            for (int t = 0; t < 10; t++)
                typeList.add(Type.I32);

            List<Spec> specImpList = new ArrayList<>();
            // https://github.com/mozilla/source-map/blob/master/lib/wasm.js
            Spec spec = new Spec("env", "mapping_callback", new java.util.function.Function<List<Number>, List<Number>>() {

                @Override
                public List<Number> apply(List<Number> t)
                {
                    WASMMapping mapping = new WASMMapping();
                    t.forEach(e -> System.out.println(e));

//                      // JS uses 1-based line numbers, wasm uses 0-based.
//                      mapping.generatedLine = generatedLine + 1;
//                      mapping.generatedColumn = generatedColumn;
//
//                      if (hasLastGeneratedColumn)
//                      {
//                          // JS uses inclusive last generated column, wasm uses exclusive.
//                          mapping.lastGeneratedColumn = lastGeneratedColumn - 1;
//                      }
//
//                      if (hasOriginal)
//                      {
//                          mapping.source = source;
//                          // JS uses 1-based line numbers, wasm uses 0-based.
//                          mapping.originalLine = originalLine + 1;
//                          mapping.originalColumn = originalColumn;
//
//                          if (hasName)
//                          {
//                              mapping.name = name;
//                          }
//                      }

//                      callbackStack[callbackStack.length - 1](mapping);
//                      // TODO Auto-generated method stub
                    return Collections.emptyList();
                }

            }, typeList, Collections.emptyList());
            specImpList.add(spec);

            Imports imp = Imports.from(specImpList, this.modulePointer);
            this.wasm = this.instantiate(imp);
            this.exports = this.wasm.exports;
        }
//      }
//      catch (IOException e)
//      {
//          // TODO Auto-generated catch block
//          e.printStackTrace();
//      }
    }
}
beaclnd commented 2 years ago

@EXEC-CSM I just recognized it's inconvenient to use,so I have fixed the implementation. We can use it like below:

Module m = new Module(moduleBytes);
Imports imp = Imports.from(specImpList, m);
Instance i = m.instantiate(imp);
i059917 commented 2 years ago

Hello, any update of this? Will Import support function be released with next version? @beaclnd92 Btw, is there anyone can teach me how to build @beaclnd92's PR on Mac locally, maybe I can play around with it :). Thanks.

cafebabe commented 2 years ago

Hi @i059917, while waiting for this to be merged I've been successfully able to develop using imports on beaclnd92's work on Mac, works really well. Seems as simple as cloning beaclnd92 repo and checking out the imports branch.

git clone https://github.com/beaclnd92/wasmer-java
cd wasmer-java
git checkout imports

make then creates you the wasmer-jni-amd64-darwin-0.3.0.jar you need (following same instructions as for wasmer-java build). I did find I needed to run using -Dos.arch=amd64 on the JVM for it to find the JNI bindings though.

jcaesar commented 2 years ago

I somehow doubt wasmer-java is still anywhere on wasmerio's priority list… Might be best if someone with vested interest (I no longer have) forked this and put it onto Maven Central, or so?

Hywan commented 2 years ago

cc @syrusakbary

syrusakbary commented 2 years ago

I somehow doubt wasmer-java is still anywhere on wasmerio's priority list

We are prioritizing a refactor of Wasmer at the moment, but meanwhile will welcome any contributions from the community. Wasmer-Java as of right now has to be updated with the latest Wasmer API, as of now it's using the 0.x API.

This Wasmer JNI bindings were using the latest API afaik: https://github.com/Salpadding/wasmer-jni

jcaesar commented 2 years ago

https://github.com/Salpadding/wasmer-jni

Neat, that even supports instance imports.

xjq7 commented 1 year ago

@EXEC-CSM I would also like to run mappings.wasm in the Java source gallery. Did you get it to work?