 We're still here, we're next because Frank, for the round of applause. Okay, okay, so welcome to everybody. My name is Frank Rehberg, so I'm living in Berlin, I'm a software consultant, and some time ago I got attracted by Rust, and so I assume everybody here knows Rust, just to repeat it, so its key features are support for concurrency, memory safety, performance, and especially memory management, deterministic management of resources. There is no garbage collector built-in, which is a very important feature. Its favor stack allocation, no implicit boxing, so there is no hidden allocation of heap memory and causing delays in processing. So and I asked myself, so if we want to, or did you ask yourself, did you ever ask, if I've got such a cool system, how could I integrate customizable features that perform some scripting and so allow me to change behavior during runtime without restarts, without reprogramming. So I thought about a small message broker, which should be customizable. So we would need byte-level manipulation, deterministic management of resources, of course, because we don't want to get a step back, back to the system. So if I want to have a heap allocation, I could use Java, whatever, or JavaScript from the beginning and implement everything in JavaScript. So this is a very important feature for me. Small footprint, security, safety, and customizable. And so I had to look around, so what's available? What could I use? And so I had to look at Lua, Python, and JavaScript as interpreters. And there is always a high complexity, dynamic heap allocation. It's always involved, so we can't get out of it. There's an execution overhead and similar with JavaScript VH. So there is even a higher complexity because it's jitting everything during startup, and then the benefit is there is a lower overhead, execution overhead during runtime. But none of these really allow me to do deterministic resource management. They all kick in, they all bring in a garbage collector, and in fact they destroy the benefits of the Rust environment or the application executing this execution engine. And so I had to look finally at fourth, and I stumbled across WebAssembly, which is very low level, has low overhead or almost no overhead. And the difference is that the other concepts, they always incorporate a full parser, parsing, abstract syntax tree, optimizing the code, getting intermediate representation, and then if it's jitted, getting some execution code. But still JavaScript still is based, so it doesn't favor stack allocation. JavaScript favors heap allocation. So we always end up with a system allocating a lot of memory and I don't want this. So that was my red line. So having a look at WebAssembly, where does it come from and what is it intended for? So WebAssembly came up in 2015 and it's not a replacement of JavaScript. So it's a complement of JavaScript. So every time the problem with JavaScript is that it's always heap oriented and it's doing a lot of even mathematical operations requiring heap operations. And so the idea is we introduce some kind of assembly code which will called by the JavaScript to speed up performing critical operations. And so if we've got a JavaScript code and we have got the flow here, so there might be an operation which kicks into the WebAssembly code doing the performance critical computation and then getting back and continuing JavaScript. And so WebAssembly incorporates a portable stack machine. The notation is a binary notation, but it also provides a text-based representation. And you can use C++ or Rust to create a binary code, a WebAssembly binary code which will be glued with JavaScript into an HTML page and then executed in the browser. And the idea or the question now was would I be able to get away with JavaScript and would it be a solution just to use WebAssembly, just to use the execution engine here and instead of JavaScript interacting with the execution engine directly interacting from Rust to WebAssembly engine and getting all the benefits. So it's widespread, so there is a community using WebAssembly. There are good compilers. I can do my compilation on a high level language, compile it to WebAssembly and execute it in a small lightweight stack machine. So for C++ and Rust, WebAssembly is a build target. So we've got the binary format, WebAssembly, the text representation, S expressions are called VST. WebAssembly supports only a few scalar types. So integer 32, 64, floating 32 and floating 64. And there is no support, so there is no native support of unsigned integers. So everything is mapped onto these types. The WebAssembly stack machine supports less than or has fewer than 256 operations or instructions. So it's very compact and these operations can be mapped or could be mapped easily onto up-to-date architecture, CPU architecture. So it's sandboxed, it's using linear memory. So it hasn't direct access to the global memory of your application. It's using tables and all the memory access, every memory access is bound checked if we stay in the linear memory and so on. So pointers are just indices into the linear memory. And so when we do a just-in-time compilation, it's possible to get a 1.5 factor of native code speed. So how would it look like? So we have seen the picture before with a JavaScript and WebAssembly execution engine. So with Rust, it wouldn't look like this one. We've got the controller setting up or allocating some memory, which will be assigned to the WebAssembly instance. We've got the WebAssembly file, which will be loaded into the context of the Rust application executable and which represents the module. We have got a table where we can register callbacks, which these callbacks are the functions the module depends on, has got to import. So anytime we've got an external function here and loaded as a module, we have got to provide a table which will provide the functionality of the function to call in, in direct call, to call this Rust implementation. We've got the stack machine and so this is the box WebAssembly is running in and so it's quite secure execution environment. So how does it look like? I tried with, as I said, we can use Rust or C++ to create WebAssembly code, binary code. And so for example if we use Rust, if we use Rust, we declare a function and we declare some parameters in a return point, a return value. And as you can see here, this is an integer 32 and in fact this one would be a pointer into linear memory and this would be mapped onto an index of type integer 32 as well. I can show you later. And so we would do the, I would iterate over the memory, over this buffer and check for all characters E or I and replace it by O. So compiling this was cargo, nightly. I get a file transform, worsen of size 57 kilobytes and which is quite big. So Rust compiles into a lot of additional meta information for the panic, panicking. So in case there is an fault in the application, there's also all the integers and error messages inside that are written to the console. And so far I didn't manage to get this, to optimize it and get rid of these strings. So name mangling, so within the module the operation would be called transform. That would be the method name. That's important because if we look at the C++ implementation, similar, return type integer, integer first parameter, we've got the pointer to an array, the same logic and so this will be compiled with an M script, right? And the result is just 296 bytes because it doesn't contain all the error strings. Rust is compiling. The drawback is that the compiler is doing name mangling and the name within the module would be underline transform, but that's just... And I didn't manage to get this away, so I didn't manage to get the underline away. So if anybody has got a clue, the binary code looks like this. This are the 296 bytes and the text form would look like this. And here you can see the first parameter, this is the first parameter and this is the second parameter pointing to the location of the array within the linear memory. And calling it, we would create a linear memory, place our byte message into the linear memory at index 0 and then calling this function with the length of the array and index 0. And this way we would tell the web assembly where in the linear memory the array is located. So the credits to this implementation prototype I did is based on the WebAssembly interpreter done by Nick Wolf, formerly at Parity Wasm at GitHub. And this one has been renamed now to Wasm interpreter. Alex Christian for Tokyo I.O. and Karl Erche for Mio. These are the three important modules my prototype is based on, just as a proof of concept. So I've got the code here and as you can see here, can you read it? This one is the method I declare, this is the file I'm loading. Then I declare environment object here and then I create the memory, linear memory. This one is the place where the buffer, the message buffer is placed into the linear memory. And then there's execution is performed. These are the parameters. And here is the invoke export, I invoke an exported operation of the module and I get a return value and then I've got to evaluate the return value. So 10 minutes left. I've got a small showcase. So I'm starting the application. So it's listening, it's a UDP based application listening for UDP packets. So I've got this client and if I send a hello e, it responds. So it receives the message, it's processed by WebAssembly, replacing all the I's by O's and sending back the message just to demonstrate. So it works even with longer strings and that's it. So what I can do now is I can change, so all I's shall be replaced by Y's and I recompile the wasm and now when I send, so I get a Y. Hey, hooray, it works. So I did not check for performance. I did not, so it's a proof of concept. So every time every message loads the wasm file, creating the WebAssembly instance, the module instance, executing it and then throwing it away. So don't ask me about performance. So another aspect is it's interpreted. So the wasm I is interpreting WebAssembly. So there would be possible to create some kind of JIT compiler, compiling the module directly to native code and probably that would be much faster. But that would be the next step and maybe I could make use of existing modules for Mozilla Firefox or other web browsers and just reusing those WebAssembly execution engines. Okay, are there any questions? Requires to make a simple WebAssembly interpreter? This interpreter... The question is how much code does it require to create a WebAssembly interpreter? I can't tell you a number of lines. But it's a small project at GitHub. So I can't answer the question. Sorry, it's a small module. And when I strip this application, which is not ideal, so this is 800K. So the application containing all the Tokyo logic, as in Kronos.io and the interpreter wasm interpreter is 800K statically linked against the local libraries. So that's not much. And probably it could be even reduced. Yes, please. Yes, you can. The question is, is it possible to declare... to access functions in the Rust environment from the WebAssembly? Yes. There is a good... There is this one. This is the callback table for... or the table. This table here. This contains... So you define in your C++ code or Rust code, you define a signature of a method which is external. You use it in your code, you call it in your code, the compiler will realize it's an external function and it will be declared as external function here, which needs to be imported. And these functions are accessed using the table. So when you load the wasm file, the module, and resolve all the dependencies, it will check for the existence of specific functions. And so it will call the function which is registered here and call in here. Yes. I don't know... Well, it's a question if we can stack up. So I would... I didn't try this, but I don't see... I don't see why this shouldn't be possible. So it might be... Well, I don't know how... Well, I've got to check the WebAssembly interpreter how this... the calling the exported function, if there is any restriction, that there should be only one call to an exported function at any time. I don't know. That's the question I didn't check this. You mentioned that WebAssembly only supports if we're doing a stream manipulation. Could you talk a bit about how you interface with the interpreter to tell it about the strings? That's... So right now, strings are a problem because strings... So if we talk about WebAssembly, WebAssembly is something which has been established in a JavaScript world. And so JavaScript strings look different to Rust strings. But there is some... There is... There are... What is it? There are some people are working on it to get some kind of... to get a kind of standard to access strings. So the idea is to use... to register strings in here. So let's assume we have got a function and we want to call the function and hand over a string. So the string could be... would be registered here and the stack machine or the module could verify what kind of string is it and then perform the correct interpretation of the string. So it could be zero-terminated string. It could be a length-encoded string. It could be whatever string. So that's the problem. Some people are using the linear memory more or less to serialize the data into the linear memory and then call the stack machine. So right now a stack machine should be... So if you define a boundary between Rust and WebAssembly you should use the boundary where you deal with binary data. For example, if you receive a message from the network and you want to process it, that would be easy to put into the linear memory and then process it using WebAssembly. If you've got a complex DOM tree internally that's not a good idea. But people are working on this and the JavaScript or the JavaScript community is working on this too. So getting DOM trees handed over to the WebAssembly engine and we've got to check how we would be able from Rust to do the same. But we always have got to... First of all, it's a JavaScript standard, a web standard. It's not defined by the Rust community. So we are always second and we have got to check out how we could incorporate using the technology. Yes. Okay.