This series is essentially a notebook where I document the things I learn online during my limited free time—usually early in the morning or late at night.
Today’s rabbit hole started with Deno Deploy, which powers serverless functions for services like Supabase and Netlify.
Unlike traditional serverless environments such as AWS Lambda, which rely on micro-VMs (via Firecracker) or containers, Deno Deploy uses V8 Isolates. Intrigued, I decided to dive deeper into Rusty V8—the Rust bindings for V8—and learn more about how isolates work.
Here’s the repo: github.com/denoland/rusty_v8
I’m learning Rust alongside many other interests, and I’ve found that reading codebases I’m genuinely curious about is one of the best ways to pick up a new language, explore concepts, and understand technologies.
That said, this is a rough overview of my findings so far. There might be errors, but consider this post a starting point for your own rabbit hole! 😄
Exploring the Codebase
I started exploring the rusty_v8
codebase and was impressed by how closely it mirrors the original V8 implementation. This alignment makes it easier to find relevant documentation and examples online.
The code is well-organized, and I focused on how the bindings reference the underlying V8 code.
BackingStore: Memory Behind the Scenes
One interesting discovery was the ArrayBuffer, a contiguous block of memory used to store binary data. What caught my attention was the BackingStore—an abstraction that manages the raw memory backing the ArrayBuffer.
In simpler terms, the BackingStore represents the memory area (allocated by the operating system) where the data of an ArrayBuffer is stored. V8 handles this memory, including garbage collection, ensuring efficient memory management.
Inside the V8 Engine
Curious about how V8 works at a deeper level, I turned to its official documentation. Given the complexity of the project, I decided to approach it as a "black box" and started by reading how to embed V8 into an application.
A great resource was the hello world example, which demonstrates embedding V8 in a C++ application. Rusty V8 provides a similar example:
rustCopia codicelet platform = v8::new_default_platform(0, false).make_shared();
v8::V8::initialize_platform(platform);
v8::V8::initialize();
let isolate = &mut v8::Isolate::new(Default::default());
let scope = &mut v8::HandleScope::new(isolate);
let context = v8::Context::new(scope, Default::default());
let scope = &mut v8::ContextScope::new(scope, context);
let code = v8::String::new(scope, "'Hello' + ' World!'").unwrap();
println!("JavaScript code: {}", code.to_rust_string_lossy(scope));
let script = v8::Script::compile(scope, code, None).unwrap();
let result = script.run(scope).unwrap();
let result = result.to_string(scope).unwrap();
println!("Result: {}", result.to_rust_string_lossy(scope));
This example introduces four key concepts in V8:
Platform: The environment where V8 runs. For example, a browser has a different platform implementation than Node.js.
Isolate: A memory-isolated instance of the V8 engine, designed to run untrusted JavaScript code.
Handles: References to JavaScript objects. A HandleScope acts as a container for these handles, allowing the garbage collector to efficiently free memory.
Context: The execution context, including global objects and variables, for JavaScript code.
After initializing these components, the code is compiled and executed within the isolate.
One fascinating aspect of this process is the ability to expose custom runtime functionalities to the code running inside the isolate.
Expanding the Rabbit Hole
I also explored two articles that delve into building custom runtimes:
“Roll Your Own JavaScript Runtime” explains how to use
deno_core
to create a custom runtime.“How Do Cloudflare Workers Work?” walks through creating a basic runtime with a single JavaScript function exposed to the isolate. Although the code is slightly outdated, it’s easy to adapt.
These resources sparked new questions about the relationship between libuv (which powers Node.js’s async functionality) and V8, and how this differs from Deno's architecture—definitely something for another rabbit hole!
Wrapping Up
I know this series might not be polished or easy to read, and I’m still learning as I go. But sharing my notes helps me stay organized and serves as a reference for my future self.
If you’re curious about these topics or have insights to share, let me know! Until the next rabbit hole, happy exploring! 🐇
Top comments (2)
We are kindred spirits I think, I love to learn about things (usually topics way too big for me) in a similar fashion. Thanks for this piece!
to progaming easy way with solve the all problem