Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Function calls from WASM to JS don't seem to have improved so much.

I don't know what I want more, DOM calls from WASM, or C++ modules. A web without javascript would be welcome.



> Function calls from WASM to JS don't seem to have improved so much.

Yeah, Wasm => JS calls used to be reasonably fast because we had optimized that before. The work described here made that path much nicer, though (a more unified stack layout for JIT/Wasm frames) and also a bit faster still.

JS => Wasm calls being slow was one of the big performance cliffs in SpiderMonkey and I'm really glad that's fixed now.


Timing for calls from WASM to JS went from 750ms to 450ms for 100 million calls, so from 7.5 nanoseconds per call to 4.5 nanoseconds per call.

A 3 GHz CPU would do 3 ticks per nanoseconds, doing such a bridging call in 23 or 15 CPU ticks is quite good IMHO (I just hope I didn't blunder the math, but function call overhead from WASM to JS isn't much of an issue, it was already fast after the previous round of optimizations).


> A web without javascript would be welcome.

Why? What is it that wasm or c++ provides you in making a DOM call that modern JS does not?


Well, kind of looking forward to getting back to using languages like Java, Kotlin, C#, Swift, ObjectiveC and other languages people have been using to make UIs for quite some time in a browser. It will take some time for proper frameworks to emerge. But things are moving fast. Driving the DOM via react and other js frameworks from these languages is kind of possible. But it's probably just a stepping stone for getting something a bit more appropriate to these languages.

I have high hopes for Kotlin here. With Kotlin native they are targeting native IOS and native Android. Being able drive browsers from the same code-base via WASM seems like it will be a useful feature. Also, they seem to be really serious about tool support with Kotlin; providing dom/webgl and other bindings, and having decent end to end support with IDEs and other tools.

I imagine, Microsoft might have similar plans for C#. And it wouldn't surprise me if Apple was working on some Swift WASM support either.


Wasm promises a better compiler target than JS for alternative languages. It always seems odd to me that JS is so heavily defended when pretty much everything that makes up a modern JS stack are other compile-to-js languages: JSX, Elm, TypeScript, Clojurescript, Coffeescript -- hell even ES6 is for all practical purposes a compile to JS language.

Changing the game into "browsers run WASM" and JS is a built-in JIT compiler for it promises to make everyone's lives much easier.


If you're working directly with the DOM or other JavaScript APIs it's still going to be a garbage-collected, object-oriented data model.

The JavaScript object model is likely to remain fundamental for cross-language within-browser interop, just like C api's are fundamental for foreign function calls in other environments. (Or Java API's in a JVM.)


i’d imagine that at its core, all the DOM access will be just another WASM call, and WASM has no concept of objects AFAIK? it would be up to each language to represent those bindings however it likes. i don’t think the functions would even have names per se; similar to minified JS you know some magic reference number but a human readable name is not relevant

all assumptions here


If you're willing to custom-design a new API by hand, you can do it however you like. But if you want to, say, autogenerate bindings from a typescript definition file (the defacto standard for describing Javascript API's), you're probably going to end up using or adapting their function names, type names, parameter names, and so on, or you'll confuse the developers.

It can be minified if both the web assembly and foreign code pass through the same minifier, but source code still has to be readable.


Choice

The ability to use existing non-JS code

The ability to write loops involving non-trivial computations without spamming a hundred million heap objects

etc.


> The ability to write loops involving non-trivial computations without spamming a hundred million heap objects

How does being able to call the DOM from webasm give you that? That's what webasm is for in the first place.


I think the idea is that they can't use webasm (exclusively) to do that without also being able to call the DOM from it.


wasm makes using a statically-typed language possible in web applications. For those that have embraced JS, that may not be compelling but for those of us that prefer strong, static typing it is a positive development.


I'm using typescript, so I already have a statically-typed language for my web apps. What is compelling with WASM is that it lets me provide a web-browser version of my C++ libraries, for stuff which needs decent execution speed and cannot afford a GC.


Emscripten let you do that too, compiling to asm.js. WebAssembly certainly is an improvement, but it's not like you couldn't do this at all before.

And heck, even without that, there are languages that transpile directly to JavaScript.


Look at the comment I was responding to: I wasn’t claiming there weren’t other ways to do this. I was responding to the question as to why you might use wasm over JS. I understand it was based on previous efforts like asm.js.

Also, for several languages, specifically those based on LLVM, the path to wasm is much clearer than compiling to JS.


The big thing isn't so much the performance of WASM by itself, but rather that this performance enables the use of data models which are different from Javascript.

Typescript, Coffeescript and a host of similar options have essentially the same data model. What makes other languages, like Java, Rust or Python actually useful is their way of handling data. Which is why you can't transcribe these languages to Javascript trivially.

Still, the ecosystem of javascript is a lot better than the languages which compile to WASM as of right now. I guess that will change...


The 2nd coming of Flash?


Hopefully not.

Some devs are treating WASM as an entire runtime and outputing canvas/webGL code. I think that is mostly a mistake, and I'll be very disappointed if that becomes the defacto approach for new web devs.

However, the cool thing about WASM is that it's just the code part. So you can build an app that's still normal CSS/HTML, just like every web-app should be, and then you can replace all of your JS with WASM (with the current exception of a little bit of JS-to-DOM binding code which Mozilla has promised to eventually get rid of).

In the world of Flash/Java you're essentially working in a completely separate platform, it just happens to be launched from a web browser. So shortcuts don't work, accessibility is awful, users can't customize the page, extensions are broken, etc, etc...

With WASM, you don't have to be in that position. You can say, "I'm a web developer, I treat the web like a medium, I write responsive HTML/CSS. I just use C instead of Javascript."


> In the world of Flash/Java you're essentially working in a completely separate platform, it just happens to be launched from a web browser. So shortcuts don't work, accessibility is awful, users can't customize the page, extensions are broken, etc, etc...

True, but until Web development catches up with the state of Flash and other native RAD GUI designers, it is a very attractive proposition.

One thing I hate when doing web development is playing around with CSS and tag soup while trying to make it work the same way across all target platforms required by the customer, that in native code would be a couple of graphical calls to the visualization engine and platform widgets, which also provide layout managers.

Stuff like Web Components and Houdini would make it better, but who knows when they will be widely available.


> while trying to make it work the same way across all target platforms

This goes back to what I was talking about with treating the web like a medium, not a distribution platform. Fundamentally, the web is about giving you a "controlled" way to give up control. The native paradigm is "I want control over what each individual pixel looks like", and the web paradigm is, "heck off, well-written apps don't do that."

I understand why it's attractive, and why it'll continue to be attractive. And I highly agree about Houdini being an exciting development (I don't personally think that Web Components are offering much, but whatever). I'm really looking forward to being able to polyfill CSS. But that difference you're talking about is probably not ever going to go away completely, because the web is optimizing to solve different problems than most native frameworks.

Not to say one approach is better than the other (Flash had some legitimate use cases), but I find that there is an actual cultural difference between how web-apps and native apps are designed and how they balance between user control and developer control. It's not just technology.


The sad story is that Flash was superior, but bred a whole generation of bad front-end devs who started as designers and nerver really learned to code or plan front-end architectures, creating good looking garbage in the process.

I worked with many of them and they are struggling in the post Flash world. This led to a removal of designers from the implementation and a rise of quality of applications, at least on the technical side.

Hopefully with design tools lile Pagedraw and FramerX, we will get tools as powerful as Flash, with better integration behavior and more control over the code quality.


What I am really waiting for is winform being ran and rendered in wasm/canvas!


This is one of my nightmares. But considering how much devs hate js it's inevitable. I almost see it. HTML replaced with some binary WASM bs framework.


Then someone will reimplement a dom and a script language in wasm. History is going in circles.


Not quite a circle. There'd be progress in that you could choose your "Javascript" and "DOM", which really opens up a lot of possibility for progress. No need to force eternal compatibility or put up with bad APIs- just pick a better version.


This! You will be able to implement your own browser in the browser, with your own brand new accessibility API, i18n and l17n API's, and your own bugs, of course. We can compile Chrome or WebKit into Wasm and then use them everywhere, even in Firefox!


But you'd still need a browser that supports HTML to load the WASM and display it.

Realistically, that would be not much different than current sites using JS, or Flash when that was a thing, or even Java applets. None of those deprecated or replaced HTML, and WASM won't either. At worse, it will be just another thing you can block with a script blocker.


You may have said this in jest and are getting down-voted for it but this isn't an impossible scenario. I think of this article in relation to what WebAssembly means.

https://dzone.com/articles/java-getting-back-to-the-browser


I trully believe it will happen in a couple of years, unless browser vendors change course regarding WebAssembly.

Ongoing POC of running Unity games, .NET, Go, Qt and many others already show it is the direction many are moving into.


I agree and think it's amazing. I'm looking forward to that day and when it comes. The other side is that it's also likely to open up a whole new avenue for web based security exploits.


> I'm looking forward to that day and when it comes.

That is the day where the open web is a little closer to dead. Possibly a lot closer. The move away from flash was a move towards empowering users. That did cost a little bit for developers, as they had worse tools to control the experience, but that also meant that it was more likely (eventually) that the experience they did develop would work in more cases. How many flash sites dealt with different size displays well, or dynamically resized and flowed correctly? How many worked with screen readers?

That's one of the benefits we've reaped by pushing the framework to the browser, and using open standards. Items that traditionally would haven't gotten much attention were also seen as important, and saw advances. I don't know how much some random React-like framework that just draws on the canvas would focus on screen reader support, but I suspect it wouldn't be high on their priority list. And even if it is on theirs, what about the 5 other main competitors that will be sharing market space with it?

I just hope that the sites that opt for these types of system are few and far between, and have specific operating needs that make it worthwhile. I think it's good that we can, but usually we shouldn't.


WebAssembly can't close the open web anymore than it's already closed today. The vast majority of JS in the browser today is minified jibberish. WebAssembly doesn't take away HTML and CSS.


WebAssembly makes it much more feasible to implement your own layout and display engine on top of a canvas element.


Why more feasible?


Because an application like that is both computationally expensive and expensive to ship as a runtime. WebAssembly can provide benefits in both cases (WASM binaries can be close an order of magnitude smaller than equivalent JS code, in select cases), and is quick to start.

As a simple example, it's not impossible that Adobe could literally take the flash VM code, compile to WASM with emscripten, and ship it along with an SWF file and a little setup code. This completely bypasses the need for a browser plugin for flash. Now, I suspect the flash VM might be large enough to make this noticeable, but it probably wouldn't be hard for Adobe to streamline it, and then re-purpose a lot of those tools used to build flash that everyone loves to rave about...

I believe there are financial incentives for this to happen, therefore I think it's only a matter of time until it does.


Using WebAssembly + WebGL/Canvas/whatever to basically replicate Flash is perfectly fine, for games. Using Flash for games was never a problem. Flash was a problem when it was used for non-game things. And I suppose it's possible someone could use Unity exporting to WebAssembly + WebGL to produce a crappy restaurant webpage (to name one common Flash offense), but it doesn't really seem all that likely.


Yeah, games is fine. So it some sort of demo (in the demo scene sense), or video player interface, honestly.

But I saw far to many flash websites in the past, because sometimes people really just want a powerpoint presentation for a website because they have a "vision", and usability is a foreign concept.

I think it's highly likely some service like Squarespace will deploy sites using something like this, because it both lets them more finely control some aspects and features, as well as make it harder for people to move. All marketed under "website plagiarism protection" or something similar. "Want to stop scraping? Just use this middleware package..."


WebAssembly doesn't really provide any more protection than just highly-obfuscated/minimized JavaScript.


That depend on how dynamic the site is. If your site is implemented on Canvas and doesn't even allow text selection, copying the site to make a competitor would be harder, as would scraping price/inventory lists, or any sort of scraping. That's both the selling point and the problem.


One issue regarding security is that until WebAssembly gets some kind of fat pointers or tagging, modules generated by unsafe languages can be exploited by corrupting internal state, thus changing the behaviour of exported entry points.

You can easily test it by creating a WebAssembly module in C with a function that overwrites an internal memory buffer, placed besides other data, which is used to parametrize behaviour of another function, for example a boolean stating that the user is authenticated.


WASM doesn't get raw access to host memory, so in practice this does not expose any new security risks. You can already pause Javascript, modify the internal state, and even overwrite existing functions while code is running. This is one of the reasons why you should never `eval` untrusted code.

This kind of thing is a risk for NodeJS, but that's only because NodeJS inexplicably allows host access by default. I believe Dahl is looking to address this in his next project.

> for example a boolean stating that the user is authenticated.

You should never do authentication clientside. Clients are untrustworthy.


Usually memory corruption isn't a JavaScript feature, unless there is a bug in the VM.

> You should never do authentication clientside. Clients are untrustworthy.

Nice way of picking up on my example, that was just an idea for a quick POC.


Well, sure. If there's a bug in the VM, then you have a problem. But your problem in that case is a lot bigger than this specific behavior. You don't need memory corruption to break clientside JS.

I wasn't trying to cherry-pick your example, but I see your example as indicative of the only types of bugs that are exposed by allowing unsafe memory access.

If you're writing a web app today, any unvalidated code you run on the client is a risk. WASM changes nothing about that. The only reason clientside memory access in a sandbox would ever be a security issue is if you were relying on a client not being able to access itself (ie, for stuff like authentication). And since you should never, ever trust the client anyway... I don't see why anyone should care about that class of issues. Don't run unvalidated code, and don't put any serverside logic with security implications on the client.

If you are going to run unvalidated code, you can put it in a WASM sandbox with its own dedicated chunk of memory. That's actually easier to do in WASM than it is in Javascript, since you don't need to worry about references across iframes anymore.

If you can think of a valid POC that's not already a security risk using current technologies, I'm open to it, but I can't think of one.


"Some kind of fat pointers or tagging" is exactly the sort of thing WebAssembly was created to get away from.

You can use a language that provides them and targets WebAssembly, without taking away the thing that makes the platform uniquely useful.


Right, but how can you trust a WebAssembly library?

It might have been compiled from Ada, Rust or plain C, just as an example.

Telling just to use a language we trust is not an option if one is just using other people libraries.

Thus bringing to the web the same security level as depending on regular native libraries, because a regular user is not going to check what a web page depends on.


If you're bringing in multiple separate WASM libraries, they'll run separately from each other. Don't give them access to any memory they shouldn't have access to.

Note that this is considerably better than Javascript, because without going out of your way to make an iframe, separate Javascript scripts aren't isolated from each other, so you don't know if one of them is modifying a prototype or hooking around other variables in the global scope.

By default, separate WASM modules don't have access to the same memory.


The whole point is about corrupting WASM modules INTERNAL memory via public exported functions, just because they happen to have typical out-of-bounds errors.

Linux Security Summit 2018 had a report that 68% of kernel exploits are caused by out-of-bounds errors.

User space doesn't write on kernel level, but can call syscalls, which happen to trigger such exploits.

WebAssembly is no different, regardless how they are sandboxed between modules.


If you have access to JS on the host system, why would you use such a roundabout, overcomplicated way to attack a module?

Why wouldn't you just use JS to remove the WASM module, replace it with a malicious module you wrote, and then overwrite the exported functions? Safe pointers won't protect you from a malicious host environment.

And like the original parent said, if you have code where you want safe pointers, use a language that requires them. Your module will be protected from any other WASM dependencies you bring in because they run in separate contexts and can't access each other. Don't give them access to critical memory. WASM makes this easy. You're just not protected from a compromised host environment -- but that's not new, that's the case for everything on the web.

WASM protects the page from your module, not the other way around. Imagine that I'm running Linux, and I put Windows in a VM inside of Linux. Is it a problem that Linux could compromise or mess with my Windows VM? Of course not, that's intended -- the point of a VM is not to protect the system running inside the VM, it's to protect the system running outside of it.

Maybe I don't understand what your threat model is. Are you worried about serverside code? I don't know that many people are really looking into running WASM on the serverside, and I don't see how the threat model is any different from writing a server in something like C++.


Not sharing memory is a pretty big restriction, though. For example, if you have variable-length data like a string, you can't pass it to a WASM module instance without either calling a function repeatedly for each data unit (slow) or sharing memory and passing a pointer (unsafe).


Someone can correct me if I'm wrong[0], but I believe the proposal for shared linear memory allows importing multiple chunks.

So assuming nothing changes and my understanding is correct, you'll just have to split your memory into two chunks; one that's safe to share and one that you keep private to your module.

And of course, unless you're writing WASM yourself by hand (which is possible, but I don't know how many people are doing it), your compiler should handle all of this for you -- so at the point where Rust or whatever says, "we want to allow you to split your code into multiple WASM modules instead of just bundling it all into one", it would have to come up with some kind of allocation strategy for this.

[0]: https://webassembly.org/docs/semantics/#linear-memory


That's a link to the spec, which documents the fact that every memory operator refers to a single "default" linear memory (which can be shared or private). I don't think any of the features on the roadmap (https://webassembly.org/docs/future-features/) include support for this kind of chunked memory. I agree that it would be very useful, though!


Linear memories (default or otherwise) can either be imported or defined inside the module.

...

In the MVP, linear memory cannot be shared between threads of execution. The addition of threads :unicorn: will allow this.

To me that sounds like, "define multiple linear memories, then import them after you instantiate the module." But I could be misinterpreting.


I don't think the thread proposal will change anything here. Like the existing memory instructions, the atomic instructions proposed for threads (https://github.com/WebAssembly/threads/blob/master/proposals...) don't take a linear memory parameter. That means they operate on the same default linear memory.


You are very right, dug into it a bit more and none of the memory functions (new atomic ones included) have parameters to specify a memidex. Thanks for looking into that, it's good to know.

> In the current version of WebAssembly, at most one memory may be defined or imported in a single module, and all constructs implicitly reference this memory 0. This restriction may be lifted in future versions.

But I don't get the impression that it's completely unplanned. Modules still take a vector of linear memories, not just one[0], which would be pointless if it wasn't planned to let you access the others at some point. Data segments also explicitly allow referencing a memidx[1] (even if right now 0 is the only one that's allowed).

Still, I've been under the impression that this was going in as part of threads, and I was all excited since threads were making such good progress. I'm a little disappointed to find out it's not.

It's also possible globals[2] might solve some of the same problems? But I haven't dug into them enough to know what their memory model looks like or how well they work across multiple modules, and in any case, sharing multiple globals is probably going to be less convenient than just sharing memory, so I'd still like to see the ability to import multiple chunks of memory.

[0]: https://webassembly.github.io/threads/syntax/modules.html#

[1]: https://webassembly.github.io/threads/syntax/modules.html#sy...

[2]: https://developer.mozilla.org/en-US/docs/WebAssembly/Using_t...


For what it's worth, I think I remember that .NET is still using reasonable web standards under the hood. It's a framework, but it's still using CSS/HTML for actual rendering.

If I'm remembering correctly, I wouldn't put that in the same category as Unity and Qt.


Unity is also .NET, and then there is UNO as well, UWP for WebAssembly

https://playground.platform.uno/


Blazor[0] was what I was referring to, but you're right, I shouldn't treat .NET like it's only being used in that context.

[0]: https://blogs.msdn.microsoft.com/webdev/2018/03/22/get-start...


Minified javascript does as much to obfuscate the code than wasm if your concern is the black box model.


I can reformat minified JS, then pause at a function, see it arguments, understand it purpose, rename variables, add a comment, and so on.

Can I do all that in Wasm?

For practical purposes of reverse engineering, minified JS is far better than Wasm. Wasm is the new Flash.


Hopefully without the Swiss cheese security.


At the moment I don't think there is a frontend language/framework which compiles to WASM and is actually worth using, at least from a perspective of frontend productivity. For performance or porting legacy code, WASM is already useful.

I mean, yes, there are things like Blazor or similar things for Rust or Nim, but these aren't yet compelling to me.


What would make it compelling?

(I don’t think this is where wasm will be used as much but I’m still interested!)


Something like react or vuejs in Python, with similar performance and equally or more productive.

There is something like this for Rust, I think.

But Python for the Browser is not compelling unless we both have a faithful implementation of the language and data model and a productive and beautiful frontend framework. Call it a React for Python or a Django for the frontend.

Similar goals apply for other languages which have an edge on Javascript in some regard.


Okay yeah, I wasn't sure if you were saying "the frameworks that exist are bad" or "a framework should exist". Thanks.

(And yeah, there are several of these in Rust now, but they're extremely early days, and not really ready for anything serious at all.)


I doubt we'll see that. Python just isn't that different to JS (so what's the point), and is in any case much slower than JS in all current implementations (so performance parity is unlikely).


Probably you don't know Python that well, then...

Also we don't need performance parity. We just need enough performance for such a framework to not suck. Interpreting Python bytecode in Javascript already doesn't suck that much, compiling bytecode to WASM and then to native machine code would suck even less. And there are always ways to improve the performance of critical parts.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: