Skip to content
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

Try to fix #2296 and support to get wasm file through http protocol #2297

Merged
merged 16 commits into from
Jun 18, 2021

Conversation

juzi5201314
Copy link
Contributor

Fix #2296

@alexcrichton
Copy link
Contributor

Thanks! Looks like the deno CI is failing though?

@juzi5201314
Copy link
Contributor Author

Thanks! Looks like the deno CI is failing though?

Yes, I made a stupid mistake. Now it has been fixed and passed ci.

@juzi5201314 juzi5201314 changed the title Try to fix #2296 Try to fix #2296 and support to get wasm file through http protocol Aug 27, 2020
@juzi5201314
Copy link
Contributor Author

In deno, the usual method is to get the library directly from remote.
e.g. import {...} from'https://deno.land/x/lib/mod.ts',
But Deno.readFileSync can only read wasm files from the local file system.
So I use fetch to complete the support for getting wasm files from http.

@alexcrichton
Copy link
Contributor

cc @jakobhellermann mind taking a look at this?

console.error(`Unsupported protocol: ${{url.protocol}}`)
Deno.exit(0)
}}
const wasmModule = new WebAssembly.Module(wasmCode);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should almost never use synchronous constructors, as they can be very slow for large Wasm. Instead, use await WebAssembly.instantiate(wasmCode, imports).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^ this issue still stands. (I'm not a maintainer, but I don't think we should ever block)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok! f71515d

@zebp
Copy link
Contributor

zebp commented Jun 7, 2021

Can this get some movement? This issue makes it almost impossible to publish a Deno library that uses wasm-bindgen without modifying the generated output.

@RReverser
Copy link
Member

I'll admit I don't fully understand the original issue. Given that Deno supports all the required Web APIs, doesn't --target web just work in Deno?

@zebp
Copy link
Contributor

zebp commented Jun 7, 2021

I'll admit I don't fully understand the original issue. Given that Deno supports all the required Web APIs, doesn't --target web just work in Deno?

It almost works with the web target. Deno's fetch doesn't support fetching local files, so it can't fetch the wasm binary.

Also calling the load function directly is inconvenient.

@RReverser
Copy link
Member

Deno's fetch doesn't support fetching local files, so it can't fetch the wasm binary.

Oh I see, that's unfortunate.

@juzi5201314
Copy link
Contributor Author

Glad someone saw this problem. Is there any resistance to this problem at the moment?
How can I help?

@zebp
Copy link
Contributor

zebp commented Jun 14, 2021

It'd be great to get some movement on this PR, this issue is a blocking one for me.

"const url = new URL(import.meta.url)

let wasmCode = ''
if (url.protocol.includes('file')) {{
Copy link
Member

@RReverser RReverser Jun 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: better to check protocols explicitly instead of "includes". Maybe change this to a switch-case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -341,8 +341,7 @@ impl<'a> Context<'a> {
console.error(`Unsupported protocol: ${{url.protocol}}`)
Deno.exit(0)
}}
const wasmModule = new WebAssembly.Module(wasmCode);
const wasmInstance = new WebAssembly.Instance(wasmModule, imports);
const wasmInstance = await WebAssembly.instantiate(await WebAssembly.compile(wasmCode), imports);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need compile separately.

Suggested change
const wasmInstance = await WebAssembly.instantiate(await WebAssembly.compile(wasmCode), imports);
const wasmInstance = (await WebAssembly.instantiate(wasmCode, imports)).instance;

}}
wasmCode = await Deno.readFile(file);
break
case 'http:':
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming you want it to work for https too?

Suggested change
case 'http:':
case 'http:':
case 'https:':

Comment on lines 344 to 345
console.error(`Unsupported protocol: ${{url.protocol}}`);
Deno.exit(0);
Copy link
Member

@RReverser RReverser Jun 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to just throw an error and give a caller a chance to handle it, rather than forcefully close the whole program.

break
case 'https:':
case 'http:':
const wasm_url = import.meta.url.substring(0, import.meta.url.lastIndexOf('/') + 1) + '{module_name}_bg.wasm';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's more reliable to use real URL resolution instead of string manipulation. You can probably reuse this code:

input = new URL('{stem}_bg.wasm', import.meta.url);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry and thank you.
I'm a newbie, I didn't know that URL has this kind of usage before this. So some codes used bad methods to try to get the _bg.wasm file in the same directory.
Now the code has become clean🎉

if (file.startsWith('/')) file = file.substr(1);
file = await Deno.realPath(file + '/../{module_name}_bg.wasm');
}} else {{
file = file.substring(0, file.lastIndexOf('/') + 1) + '{module_name}_bg.wasm';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here about URL manipulation.

let file = new URL(import.meta.url).pathname;
if (Deno.build.os === 'windows') {{
if (file.startsWith('/')) file = file.substr(1);
file = await Deno.realPath(file + '/../{module_name}_bg.wasm');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we use ../ on Windows but not elsewhere?

@alexcrichton
Copy link
Contributor

Thanks for this1

@alexcrichton alexcrichton merged commit 80da105 into rustwasm:master Jun 18, 2021
@RReverser
Copy link
Member

@juzi5201314 Didn't see the updates following the last round of reviews, thanks, code looks a lot better!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Deno target on windows error.
4 participants