You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过V8引擎从C++获取JS字节码及虚拟机状态

Great questions! Working with V8's internal bytecode and VM state via C++ requires leveraging its low-level API, so let's walk through exactly how to do this.

1. 获取JavaScript字节码(C++ + V8引擎)

First off, you'll need to set up your V8 development environment—either compile V8 from source or use prebuilt libraries. Once that's sorted, here's a practical implementation to fetch bytecode from any JavaScript source:

#include <v8.h>
#include <iostream>
#include <memory>

int main() {
  // Initialize V8's core components
  v8::V8::InitializeICUDefaultLocation(nullptr);
  v8::V8::InitializeExternalStartupData(nullptr);
  std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
  v8::V8::InitializePlatform(platform.get());
  v8::V8::Initialize();

  // Create an Isolate (V8's VM instance) and Context (execution context)
  v8::Isolate::CreateParams create_params;
  create_params.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
  v8::Isolate* isolate = v8::Isolate::New(create_params);
  
  {
    v8::Isolate::Scope isolate_scope(isolate);
    v8::HandleScope handle_scope(isolate);
    v8::Local<v8::Context> context = v8::Context::New(isolate);
    v8::Context::Scope context_scope(context);

    // Your target JavaScript source code
    const char* js_source = "class Contract { constructor() { this.str = ''; this.count = 0; } update(_value){ this.str = _value; this.count++; } }";
    v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, js_source, v8::NewStringType::kNormal).ToLocalChecked();

    // Compile the script into a V8 Script object
    v8::ScriptCompiler::Source script_source(source);
    v8::Local<v8::Script> script = v8::ScriptCompiler::Compile(context, &script_source).ToLocalChecked();

    // Fetch the bytecode array from the compiled script
    v8::Local<v8::Object> bytecode_array = script->GetBytecodeArray().ToLocalChecked();
    v8::Local<v8::Uint8Array> uint8_bytecode = v8::Uint8Array::Cast(bytecode_array);

    // Extract and print the bytecode data
    uint8_t* bytecode_bytes = reinterpret_cast<uint8_t*>(uint8_bytecode->Buffer()->GetBackingStore()->Data());
    size_t bytecode_length = uint8_bytecode->Length();

    std::cout << "Compiled script bytecode length: " << bytecode_length << "\n";
    std::cout << "Bytecode (hex): ";
    for (size_t i = 0; i < bytecode_length; ++i) {
      std::cout << std::hex << static_cast<int>(bytecode_bytes[i]) << " ";
    }
    std::cout << std::dec << "\n";
  }

  // Clean up V8 resources
  isolate->Dispose();
  v8::V8::Dispose();
  v8::V8::ShutdownPlatform();
  delete create_params.array_buffer_allocator;
  return 0;
}

Key Notes:

  • The GetBytecodeArray() method returns a V8 Uint8Array containing the raw bytecode for the compiled script.
  • You'll need to link against V8's libraries (like v8.lib on Windows or libv8.so on Linux) when compiling this code.
2. 获取Contract类对应的字节码及虚拟机状态

Let's tailor the approach to your specific Contract class, covering both bytecode for individual methods and VM state tracking.

Fetch Bytecode for the update Method

After compiling the script, you can target specific functions (like update) to get their bytecode:

// Inside the Isolate/Context scope (after compiling the script)
v8::Local<v8::Value> contract_class_val = script->Run(context).ToLocalChecked();
v8::Local<v8::Function> contract_constructor = v8::Function::Cast(*contract_class_val);

// Get the `update` method from the class prototype
v8::Local<v8::String> prototype_key = v8::String::NewFromUtf8(isolate, "prototype").ToLocalChecked();
v8::Local<v8::Object> prototype_obj = contract_constructor->Get(context, prototype_key).ToLocalChecked()->ToObject(context).ToLocalChecked();

v8::Local<v8::String> update_key = v8::String::NewFromUtf8(isolate, "update").ToLocalChecked();
v8::Local<v8::Function> update_func = v8::Function::Cast(*prototype_obj->Get(context, update_key).ToLocalChecked());

// Fetch and print the `update` method's bytecode
v8::Local<v8::Object> update_bytecode = update_func->GetBytecodeArray().ToLocalChecked();
v8::Local<v8::Uint8Array> update_uint8 = v8::Uint8Array::Cast(update_bytecode);

uint8_t* update_bytes = reinterpret_cast<uint8_t*>(update_uint8->Buffer()->GetBackingStore()->Data());
size_t update_length = update_uint8->Length();

std::cout << "\n`update` method bytecode length: " << update_length << "\n";
std::cout << "`update` bytecode (hex): ";
for (size_t i = 0; i < update_length; ++i) {
  std::cout << std::hex << static_cast<int>(update_bytes[i]) << " ";
}
std::cout << std::dec << "\n";

Track Virtual Machine State

V8 provides APIs to access various VM metrics and object state:

1. Heap Memory Statistics

Get insights into V8's heap usage:

v8::HeapStatistics heap_stats;
isolate->GetHeapStatistics(&heap_stats);

std::cout << "\nVM Heap Statistics:\n";
std::cout << "- Total heap size: " << heap_stats.total_heap_size() << " bytes\n";
std::cout << "- Used heap size: " << heap_stats.used_heap_size() << " bytes\n";
std::cout << "- Heap size limit: " << heap_stats.heap_size_limit() << " bytes\n";

2. Contract Instance State

If you create an instance of Contract, you can inspect its runtime properties:

// Create a Contract instance
v8::Local<v8::Object> contract_instance = contract_constructor->NewInstance(context).ToLocalChecked();

// Call the `update` method with a test value
v8::Local<v8::Value> args[] = { v8::String::NewFromUtf8(isolate, "Hello V8").ToLocalChecked() };
contract_instance->CallAsFunction(context, contract_instance, 1, args).ToLocalChecked();

// Fetch and print instance properties
v8::Local<v8::String> str_key = v8::String::NewFromUtf8(isolate, "str").ToLocalChecked();
v8::Local<v8::String> count_key = v8::String::NewFromUtf8(isolate, "count").ToLocalChecked();

v8::String::Utf8Value str_val(isolate, contract_instance->Get(context, str_key).ToLocalChecked());
int count_val = contract_instance->Get(context, count_key).ToLocalChecked()->Int32Value(context).ToChecked();

std::cout << "\nContract Instance State:\n";
std::cout << "- str: " << *str_val << "\n";
std::cout << "- count: " << count_val << "\n";

内容的提问来源于stack exchange,提问作者Lilit Zakaryan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:18:49