wasmer-java icon indicating copy to clipboard operation
wasmer-java copied to clipboard

feat: Instance Imports

Open syrusakbary opened this issue 5 years ago • 29 comments

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 avatar Jan 30 '20 03:01 syrusakbary

This is resolved in master. Closing the issue

syrusakbary avatar May 14 '20 15:05 syrusakbary

(got confused about exports, reopening)

syrusakbary avatar May 14 '20 15:05 syrusakbary

+1 would be super useful!

BlakeB415 avatar May 21 '20 21:05 BlakeB415

Agree! Is there any workaround?

sigmasoldi3r avatar May 26 '20 14:05 sigmasoldi3r

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

syrusakbary avatar May 27 '20 19:05 syrusakbary

Any updates?

BlakeB415 avatar Oct 02 '20 03:10 BlakeB415

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

syrusakbary avatar Oct 02 '20 06:10 syrusakbary

@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!

SuperIceCN avatar Nov 29 '20 14:11 SuperIceCN

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

Hywan avatar Nov 30 '20 13:11 Hywan

Will host funtions be supported in 2021?

SuperIceCN avatar Jan 15 '21 12:01 SuperIceCN

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

Hywan avatar Mar 02 '21 12:03 Hywan

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

roee88 avatar May 05 '21 06:05 roee88

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.

jcaesar avatar Sep 05 '21 08:09 jcaesar

Any new info on this?

ripSquid avatar Jan 22 '22 23:01 ripSquid

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

@Hywan Hello, now it's 2022.

SuperIceCN avatar Jan 26 '22 00:01 SuperIceCN

Ivan quit working for wasmerio 4 months ago. ;)

jcaesar avatar Jan 26 '22 00:01 jcaesar

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

sigmasoldi3r avatar Jan 27 '22 10:01 sigmasoldi3r

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.

jcaesar avatar Jan 28 '22 01:01 jcaesar

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

beaclnd avatar Feb 20 '22 08:02 beaclnd

@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 avatar Mar 14 '22 08:03 EXEC-CSM

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();
//		}
	}
}

EXEC-CSM avatar Mar 14 '22 10:03 EXEC-CSM

@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);

beaclnd avatar Mar 16 '22 06:03 beaclnd

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.

i059917 avatar May 05 '22 02:05 i059917

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.

cafebabe avatar May 09 '22 13:05 cafebabe

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?

jcaesar avatar May 10 '22 08:05 jcaesar

cc @syrusakbary

Hywan avatar May 10 '22 11:05 Hywan

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

syrusakbary avatar May 10 '22 23:05 syrusakbary

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

Neat, that even supports instance imports.

jcaesar avatar May 13 '22 11:05 jcaesar

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

xjq7 avatar Aug 21 '23 03:08 xjq7