Skip to content

Commit

Permalink
Chapter 8
Browse files Browse the repository at this point in the history
  • Loading branch information
bsletten committed Dec 8, 2021
1 parent 8790efd commit c6ad5c2
Show file tree
Hide file tree
Showing 13 changed files with 2,424 additions and 0 deletions.
57 changes: 57 additions & 0 deletions ch08/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
## Chapter 7 : WebAssembly in the Server

This chapter exists the browser for Node.js and Deno. While I didn't
want to create overly complicated examples for the book itself, I will
have additional examples eventually in this repository as well.

The first example is the traditional way to extend Node.js with Add On
code. This is in the directory `node-addon`. If you enter that directory, you
can build the example with:

```
> node-gyp configure build
> node test.js
This should be eight: 8
```

In the `node` directory, there is the simple example that adds two
numbers together. If you include the `main()`, you can run it with:

```
> emcc add.c
> node a.out.js
The sum of 2 and 3 is: 5
```

Node.js has experimental support for loading WebAssembly modules as
ES6 modules. If you remove the `main()` from `add.c` and do the
following, you should be able to see this on recent versions of
Node.js:

```
> emcc add.c
> node --experimental-modules --experimental-wasm-modules index.mjs
The sum of 6 and 2 is: 8
```

In the `deno` directory, there are some examples that work with this
exciting new environment.

```
> deno run --allow-read main.ts
2 + 3 = 5
```

or

```
> deno run --allow-read --allow-net main-serve.ts
HTTP webserver running. Access it at: http://localhost:9000/
```

or

```
> deno run --allow-read --allow-write --allow-net db-serve.ts
HTTP webserver running. Access it at: http://localhost:9000/
```
Binary file added ch08/deno/a.out.wasm
Binary file not shown.
45 changes: 45 additions & 0 deletions ch08/deno/db-serve.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { DB } from "https://deno.land/x/sqlite/mod.ts";
import { serve } from "https://deno.land/[email protected]/http/server.ts";

// Create the Database. This requires write access!

const db = new DB("pl.db");
db.query(
"DROP TABLE IF EXISTS languages",
);

db.query(
"CREATE TABLE languages (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)",
);

const names = ["C", "C++", "Rust", "TypeScript"]

// Populate the database

for (const name of names) {
db.query("INSERT INTO languages (name) VALUES (?)", [name]);
}

// Close out the connection

db.close();

const server = serve({ hostname: "0.0.0.0", port: 9000 });
console.log(`HTTP webserver running. Access it at: http://localhost:9000/`);

for await (const request of server) {
// Re-open the Database

const db = new DB("pl.db");
let bodyContent = "Programming Languages that work with WebAssembly:\n\n";

for(const [name] of db.query("SELECT name FROM languages")) {
bodyContent += name + "\n";
}

bodyContent += "\n";
request.respond({ status: 200, body: bodyContent });

// Close the Database
db.close();
}
16 changes: 16 additions & 0 deletions ch08/deno/main-serve.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { serve } from "https://deno.land/[email protected]/http/server.ts";

const wasmCode = await Deno.readFile("./a.out.wasm");
const wasmModule = new WebAssembly.Module(wasmCode);
const wasmInstance = new WebAssembly.Instance(wasmModule);
const add = wasmInstance.exports.add as CallableFunction

const server = serve({ hostname: "0.0.0.0", port: 9000 });
console.log(`HTTP webserver running. Access it at: http://localhost:9000/`);

for await (const request of server) {
let bodyContent = "2 + 3 = " + add(2,3);
request.respond({ status: 200, body: bodyContent });
}


6 changes: 6 additions & 0 deletions ch08/deno/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const wasmCode = await Deno.readFile("./a.out.wasm");
const wasmModule = new WebAssembly.Module(wasmCode);
const wasmInstance = new WebAssembly.Instance(wasmModule);
const add = wasmInstance.exports.add as CallableFunction

console.log("2 + 3 = " + add(2,3));
Binary file added ch08/deno/pl.db
Binary file not shown.
54 changes: 54 additions & 0 deletions ch08/node-addon/addon.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// addon.cc
#include <node.h>

namespace demo {

using v8::Exception;
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::String;
using v8::Value;

// This is the implementation of the "add" method
// Input arguments are passed using the
// const FunctionCallbackInfo<Value>& args struct
void Add(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();

// Check the number of arguments passed.
if (args.Length() < 2) {
// Throw an Error that is passed back to JavaScript
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8(isolate,
"Wrong number of arguments").ToLocalChecked()));
return;
}

// Check the argument types
if (!args[0]->IsNumber() || !args[1]->IsNumber()) {
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8(isolate,
"Wrong arguments").ToLocalChecked()));
return;
}

// Perform the operation
double value =
args[0].As<Number>()->Value() + args[1].As<Number>()->Value();
Local<Number> num = Number::New(isolate, value);

// Set the return value (using the passed in
// FunctionCallbackInfo<Value>&)
args.GetReturnValue().Set(num);
}

void Init(Local<Object> exports) {
NODE_SET_METHOD(exports, "add", Add);
}

NODE_MODULE(NODE_GYP_MODULE_NAME, Init)

} // namespace demo
8 changes: 8 additions & 0 deletions ch08/node-addon/binding.gyp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"targets": [
{
"target_name": "addon",
"sources": [ "addon.cc" ]
}
]
}
4 changes: 4 additions & 0 deletions ch08/node-addon/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// test.js
const addon = require('./build/Release/addon');

console.log('This should be eight:', addon.add(3, 5));
Loading

0 comments on commit c6ad5c2

Please sign in to comment.