#![allow(clippy::all)]
use std::collections::HashMap;
use std::sync::Once;
use std::sync::{Mutex, OnceLock};
use std::time::Instant;
use rusty_v8 as v8;
use std::hash::Hash;
#[cfg(feature = "benchmarks")]
pub mod benchmarks;
#[cfg(feature = "benchmarks")]
pub mod performance_analyzer;
#[cfg(feature = "benchmarks")]
pub mod performance_comparison;
#[cfg(feature = "benchmarks")]
pub mod performance_regression;
#[cfg(feature = "benchmarks")]
pub mod performance_reporter;
pub mod agent; pub mod event_loop;
pub mod isolate_prewarmer; pub mod mcp; pub mod nodejs_core; pub mod package_manager; pub mod permissions;
pub mod runtime; pub mod runtime_minimal; pub mod v8_snapshot; pub mod watcher; pub mod watcher_websocket; pub mod web_api;
pub mod ecosystem_lite;
#[cfg(feature = "enterprise")]
pub mod security;
#[cfg(feature = "multilang")]
pub mod multilang;
#[cfg(feature = "multilang")]
pub mod platform;
#[cfg(feature = "cloudnative")]
pub mod cloud_native;
pub mod ai_engine; pub mod bus; pub mod capability; pub mod checkpoint; pub mod database; pub mod error; pub mod fallback; pub mod ffi; pub mod grammar; pub mod kv; pub mod memory; pub mod napi; pub mod pool; pub mod repl; pub mod replay; pub mod sandbox; pub mod sockets; pub mod std_lib; pub mod task_runner; pub mod testing; pub mod tooling; pub mod tools; pub mod types_export; pub mod typescript;
pub mod wasm; pub mod weights;
pub use repl::{Repl, ReplConfig};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum OptimizeMode {
Speed,
Size,
Auto,
}
pub use isolate_prewarmer::{global_prewarmer, IsolatePrewarmer, PrewarmConfig, PrewarmStats};
pub use runtime_minimal::MinimalRuntime;
#[derive(Debug, Clone)]
pub struct TestSuite {
pub name: String,
pub passed: u32,
pub failed: u32,
pub skipped: u32,
pub duration_ms: u64,
pub file: Option<String>,
pub total_duration: Option<std::time::Duration>,
}
#[derive(Debug, Clone)]
pub struct Server {
port: u16,
}
impl Server {
pub fn new(port: u16) -> Self {
Self { port }
}
pub fn port(&self) -> u16 {
self.port
}
}
use anyhow::{anyhow, Result};
static V8_INIT_RESULT: std::sync::OnceLock<std::result::Result<(), String>> =
std::sync::OnceLock::new();
pub fn initialize_v8() -> Result<()> {
let init_result = V8_INIT_RESULT.get_or_init(|| {
use rusty_v8 as v8;
let mut v8_flags: Vec<String> = vec![
"--opt".to_string(), "--turbo-inlining".to_string(), "--concurrent-recompilation".to_string(), "--max-old-space-size=4096".to_string(), "--min-semi-space-size=16".to_string(), "--max-semi-space-size=64".to_string(), "--turbo-fast-api-calls".to_string(), "--harmony".to_string(), "--turbo-inline-array-builtins".to_string(), "--maglev-inlining".to_string(), "--maglev-optimistic-peeled-loops".to_string(), "--turbo-loop-peeling".to_string(), "--turbo-loop-rotation".to_string(), "--turbo-loop-variable".to_string(), "--turbo-allocation-folding".to_string(), "--invocation-count-for-feedback-allocation=2".to_string(), "--invocation-count-for-early-optimization=4".to_string(), "--invocation-count-for-maglev=16".to_string(), "--invocation-count-for-maglev-osr=16".to_string(), "--invocation-count-for-osr=32".to_string(), "--invocation-count-for-turbofan=64".to_string(), ];
if let Ok(extra) = std::env::var("V8_FLAGS") {
v8_flags.push(extra);
}
if let Ok(extra) = std::env::var("AMBER_V8_FLAGS") {
v8_flags.push(extra);
}
let v8_flags_str: _ = v8_flags.join(" ");
v8::V8::set_flags_from_string(&v8_flags_str);
let platform = v8::new_default_platform(0, false).make_shared();
v8::V8::initialize_platform(platform);
v8::V8::initialize();
Ok(())
});
init_result
.as_ref()
.map(|_| ())
.map_err(|message| anyhow!(message.clone()))
}
pub fn is_v8_initialized() -> bool {
matches!(V8_INIT_RESULT.get(), Some(Ok(())))
}
pub fn is_v8_available() -> bool {
static CHECK: Once = Once::new();
static mut AVAILABLE: bool = true;
CHECK.call_once(|| {
if let Err(_) = initialize_v8() {
unsafe {
AVAILABLE = false;
}
}
});
unsafe { AVAILABLE }
}
#[derive(Debug, Clone)]
pub struct PerformanceConfig {
pub pool_size: usize,
pub max_memory: usize,
pub enable_optimization: bool,
pub performance_monitoring: bool,
}
impl Default for PerformanceConfig {
fn default() -> Self {
Self {
pool_size: num_cpus::get(),
max_memory: 1024 * 1024 * 1024, enable_optimization: true,
performance_monitoring: true,
}
}
}
pub struct Runtime {
config: PerformanceConfig,
_verbose: bool,
lite_runtime: std::cell::RefCell<Option<MinimalRuntime>>,
}
impl Runtime {
pub fn new(
pool_size: usize,
max_memory: usize,
enable_optimization: bool,
verbose: bool,
) -> Self {
Self {
config: PerformanceConfig {
pool_size,
max_memory,
enable_optimization,
performance_monitoring: true,
},
_verbose: verbose,
lite_runtime: std::cell::RefCell::new(None),
}
}
pub fn new_default() -> Self {
Self::new(num_cpus::get(), 1024 * 1024 * 1024, true, false)
}
pub fn new_with_optimization(
pool_size: usize,
max_memory: usize,
optimize_mode: OptimizeMode,
verbose: bool,
) -> Self {
let enable_optimization: _ = match optimize_mode {
OptimizeMode::Speed => true,
OptimizeMode::Size => false,
OptimizeMode::Auto => true,
};
Self::new(pool_size, max_memory, enable_optimization, verbose)
}
pub fn run_benchmarks(&self) -> Vec<()> {
vec![]
}
pub fn get_config(&self) -> &PerformanceConfig {
&self.config
}
pub fn context(self, _msg: &str) -> Result<Self, anyhow::Error> {
Ok(self)
}
pub fn execute_code(&self, code: &str) -> Result<String> {
let mut runtime_ref = self.lite_runtime.borrow_mut();
let runtime = runtime_ref.get_or_insert_with(|| {
crate::runtime_minimal::MinimalRuntime::new().expect("Failed to create MinimalRuntime")
});
runtime.execute_code(code)
}
pub fn execute_file(&self, path: &std::path::Path) -> Result<String> {
let code: _ = std::fs::read_to_string(path)
.map_err(|e| anyhow!("Failed to read file {}: {}", path.display(), e))?;
let dir_path = path
.parent()
.map(|p| p.to_string_lossy().to_string())
.unwrap_or_else(|| String::from("."));
let file_path = path.to_string_lossy().to_string();
let wrapped_code = format!(
"(function() {{ globalThis.__dirname = '{}'; globalThis.__filename = '{}'; }})();\n{}",
dir_path.replace("\\", "\\\\"),
file_path.replace("\\", "\\\\"),
code
);
let mut runtime_ref = self.lite_runtime.borrow_mut();
let runtime = runtime_ref.get_or_insert_with(|| {
crate::runtime_minimal::MinimalRuntime::new().expect("Failed to create MinimalRuntime")
});
runtime.set_main_module_path(path);
runtime.execute_code(&wrapped_code)
}
}
pub fn get_smart_runtime(
_code: Option<&str>,
_stack_size: usize,
max_heap: usize,
verbose: bool,
optimize_mode: OptimizeMode,
) -> Result<Runtime> {
if verbose {
println!("[amberjs] Initializing smart runtime...");
}
let enable_optimization: _ = match optimize_mode {
OptimizeMode::Speed => true,
OptimizeMode::Size => false,
OptimizeMode::Auto => true,
};
Ok(Runtime::new(
num_cpus::get(),
max_heap,
enable_optimization,
verbose,
))
}
pub fn get_global_runtime(
stack_size: usize,
max_heap: usize,
verbose: bool,
optimize_mode: OptimizeMode,
) -> Result<Runtime> {
if verbose {
println!("[amberjs] Initializing global runtime...");
}
get_smart_runtime(None, stack_size, max_heap, verbose, optimize_mode)
}
pub fn run_performance_suite() -> Result<(), Box<dyn std::error::Error>> {
println!("⚠️ Performance suite is temporarily disabled");
Ok(())
}
pub fn generate_performance_report(
_results: &[()],
format: &str,
) -> Result<std::path::PathBuf, Box<dyn std::error::Error>> {
let output_dir = std::path::PathBuf::from("performance_reports");
std::fs::create_dir_all(&output_dir)?;
let report_path = output_dir.join(format!("report.{}.txt", format));
std::fs::write(&report_path, "Report generation temporarily disabled")?;
Ok(report_path)
}
pub fn console_log_callback(
_scope: &mut v8::PinScope,
args: v8::FunctionCallbackArguments,
_rv: v8::ReturnValue,
) {
let mut output = String::new();
for i in 0..args.length() {
if i > 0 {
output.push(' ');
}
let arg: _ = args.get(i);
let arg_str: _ = arg
.to_string(_scope)
.unwrap_or_else(|| v8::String::new(_scope, "<unknown>").unwrap());
output.push_str(&arg_str.to_rust_string_lossy(_scope));
}
println!("{}", output);
}
fn format_console_args(scope: &mut v8::PinScope, args: &v8::FunctionCallbackArguments) -> String {
let mut output = String::new();
for i in 0..args.length() {
if i > 0 {
output.push(' ');
}
let arg = args.get(i);
if arg.is_native_error() {
let stack_key = v8::String::new(scope, "stack").unwrap();
if let Some(obj) = arg.to_object(scope) {
if let Some(stack_val) = obj.get(scope, stack_key.into()) {
if !stack_val.is_undefined() {
output.push_str(&stack_val.to_rust_string_lossy(scope));
continue;
}
}
}
}
let arg_str = arg
.to_string(scope)
.unwrap_or_else(|| v8::String::new(scope, "<unknown>").unwrap());
output.push_str(&arg_str.to_rust_string_lossy(scope));
}
output
}
pub fn console_error_callback(
scope: &mut v8::PinScope,
args: v8::FunctionCallbackArguments,
_rv: v8::ReturnValue,
) {
eprintln!("{}", format_console_args(scope, &args));
}
pub fn console_warn_callback(
scope: &mut v8::PinScope,
args: v8::FunctionCallbackArguments,
_rv: v8::ReturnValue,
) {
eprintln!("{}", format_console_args(scope, &args));
}
pub fn console_info_callback(
scope: &mut v8::PinScope,
args: v8::FunctionCallbackArguments,
_rv: v8::ReturnValue,
) {
println!("{}", format_console_args(scope, &args));
}
pub fn console_debug_callback(
scope: &mut v8::PinScope,
args: v8::FunctionCallbackArguments,
_rv: v8::ReturnValue,
) {
println!("{}", format_console_args(scope, &args));
}
pub fn console_table_callback(
scope: &mut v8::PinScope,
args: v8::FunctionCallbackArguments,
_rv: v8::ReturnValue,
) {
if args.length() == 0 {
println!("console.table: no data provided");
return;
}
let data = args.get(0);
let columns: Vec<String> = if args.length() > 1 {
let cols_arg = args.get(1);
if cols_arg.is_array() {
let cols_arr = v8::Local::<v8::Array>::try_from(cols_arg).unwrap();
let cols_len = cols_arr.length();
let mut cols = Vec::new();
for i in 0..cols_len {
if let Some(col) = cols_arr.get_index(scope, i) {
let col_str = col.to_string(scope).unwrap().to_rust_string_lossy(scope);
cols.push(col_str);
}
}
cols
} else {
Vec::new()
}
} else {
Vec::new()
};
let use_columns = !columns.is_empty();
if data.is_null_or_undefined() {
println!("console.table: null");
return;
}
if data.is_array() {
let arr = v8::Local::<v8::Array>::try_from(data).unwrap();
let length = arr.length();
if length == 0 {
println!("console.table: []");
return;
}
let first_item = arr.get_index(scope, 0).unwrap();
if first_item.is_object() {
if use_columns {
println!("┌─────────────────────────────────┐");
println!("│ Console Table │");
println!("├─────────────────────────────────┤");
for i in 0..length {
if let Some(item) = arr.get_index(scope, i) {
let obj = v8::Local::<v8::Object>::try_from(item).unwrap();
let mut row = String::new();
for (j, col_name) in columns.iter().enumerate() {
let key = v8::String::new(scope, col_name).unwrap().into();
let value = obj.get(scope, key);
let value_str = match value {
Some(v) => v.to_string(scope).unwrap().to_rust_string_lossy(scope),
None => String::from("undefined"),
};
row.push_str(&format!("{}: {}", col_name, value_str));
if j < columns.len() - 1 {
row.push_str(", ");
}
}
println!("│ {}", format!("{:<33}", row));
}
}
println!("└─────────────────────────────────┘");
} else {
println!("┌─────────────────────────────────┐");
println!("│ Console Table │");
println!("├─────────────────────────────────┤");
for i in 0..length {
if let Some(item) = arr.get_index(scope, i) {
let obj = v8::Local::<v8::Object>::try_from(item).unwrap();
let keys = obj
.get_own_property_names(scope, Default::default())
.unwrap();
let key_count = keys.length();
let mut row = String::new();
for j in 0..key_count {
let key = keys.get_index(scope, j).unwrap();
let key_str = key.to_string(scope).unwrap().to_rust_string_lossy(scope);
let value = obj.get(scope, key).unwrap();
let value_str =
value.to_string(scope).unwrap().to_rust_string_lossy(scope);
row.push_str(&format!("{}: {}", key_str, value_str));
if j < key_count - 1 {
row.push_str(", ");
}
}
println!("│ {}", format!("{:<33}", row));
}
}
println!("└─────────────────────────────────┘");
}
} else {
println!("┌─────────┐");
println!("│ Index │ Value");
println!("├─────────┤");
for i in 0..length {
if let Some(item) = arr.get_index(scope, i) {
let value_str = item.to_string(scope).unwrap().to_rust_string_lossy(scope);
println!("│ {:>6} │ {}", i, value_str);
}
}
println!("└─────────┘");
}
} else if data.is_object() {
let obj = v8::Local::<v8::Object>::try_from(data).unwrap();
let keys = obj
.get_own_property_names(scope, Default::default())
.unwrap();
let length = keys.length();
println!("┌──────────────────┬───────────────┐");
println!("│ Key │ Value │");
println!("├──────────────────┼───────────────┤");
for i in 0..length {
let key = keys.get_index(scope, i).unwrap();
let key_str = key.to_string(scope).unwrap().to_rust_string_lossy(scope);
if use_columns && !columns.contains(&key_str) {
continue;
}
let value = obj.get(scope, key).unwrap();
let value_str = value.to_string(scope).unwrap().to_rust_string_lossy(scope);
println!("│ {:<16} │ {:<13} │", key_str, value_str);
}
println!("└──────────────────┴───────────────┘");
} else {
let value_str = data.to_string(scope).unwrap().to_rust_string_lossy(scope);
println!("console.table: {}", value_str);
}
}
static TIMER_STORAGE: OnceLock<Mutex<HashMap<String, Instant>>> = OnceLock::new();
fn get_timer_storage() -> &'static Mutex<HashMap<String, Instant>> {
TIMER_STORAGE.get_or_init(|| Mutex::new(HashMap::new()))
}
static COUNTER_STORAGE: OnceLock<Mutex<HashMap<String, u32>>> = OnceLock::new();
fn get_counter_storage() -> &'static Mutex<HashMap<String, u32>> {
COUNTER_STORAGE.get_or_init(|| Mutex::new(HashMap::new()))
}
pub fn console_time_callback(
_scope: &mut v8::PinScope,
args: v8::FunctionCallbackArguments,
_rv: v8::ReturnValue,
) {
let label = if args.length() > 0 {
let arg = args.get(0);
arg.to_string(_scope).unwrap().to_rust_string_lossy(_scope)
} else {
"default".to_string()
};
let storage = get_timer_storage();
let mut timers = storage.lock().unwrap();
timers.insert(label.clone(), Instant::now());
println!("console.time: {}", label);
}
pub fn console_time_end_callback(
_scope: &mut v8::PinScope,
args: v8::FunctionCallbackArguments,
_rv: v8::ReturnValue,
) {
let label = if args.length() > 0 {
let arg = args.get(0);
arg.to_string(_scope).unwrap().to_rust_string_lossy(_scope)
} else {
"default".to_string()
};
let storage = get_timer_storage();
let mut timers = storage.lock().unwrap();
let elapsed = if let Some(start_time) = timers.remove(&label) {
let duration = start_time.elapsed();
duration.as_secs_f64() * 1000.0 } else {
0.0
};
println!("console.timeEnd: {}: {:.2}ms", label, elapsed);
}
pub fn console_count_callback(
_scope: &mut v8::PinScope,
args: v8::FunctionCallbackArguments,
_rv: v8::ReturnValue,
) {
let label = if args.length() > 0 {
let arg = args.get(0);
arg.to_string(_scope).unwrap().to_rust_string_lossy(_scope)
} else {
"default".to_string()
};
let counter_storage = get_counter_storage();
let mut counters = counter_storage.lock().unwrap();
let count = counters.entry(label.clone()).or_insert(0);
*count += 1;
println!("console.count: {} {}", label, count);
}
pub fn console_count_reset_callback(
_scope: &mut v8::PinScope,
args: v8::FunctionCallbackArguments,
_rv: v8::ReturnValue,
) {
let label = if args.length() > 0 {
let arg = args.get(0);
arg.to_string(_scope).unwrap().to_rust_string_lossy(_scope)
} else {
"default".to_string()
};
let counter_storage = get_counter_storage();
let mut counters = counter_storage.lock().unwrap();
counters.insert(label.clone(), 0);
println!("console.countReset: {}", label);
}
pub fn console_group_callback(
_scope: &mut v8::PinScope,
args: v8::FunctionCallbackArguments,
_rv: v8::ReturnValue,
) {
let label = if args.length() > 0 {
let arg = args.get(0);
arg.to_string(_scope).unwrap().to_rust_string_lossy(_scope)
} else {
"console.group".to_string()
};
println!("▼ {}", label);
}
pub fn console_group_end_callback(
_scope: &mut v8::PinScope,
_args: v8::FunctionCallbackArguments,
_rv: v8::ReturnValue,
) {
println!("▲ group ended");
}
pub fn console_trace_callback(
_scope: &mut v8::PinScope,
args: v8::FunctionCallbackArguments,
_rv: v8::ReturnValue,
) {
let message = if args.length() > 0 {
let arg = args.get(0);
arg.to_string(_scope).unwrap().to_rust_string_lossy(_scope)
} else {
"console.trace".to_string()
};
println!("Trace: {}", message);
println!(" at <anonymous>");
}
pub fn console_assert_callback(
scope: &mut v8::PinScope,
args: v8::FunctionCallbackArguments,
_rv: v8::ReturnValue,
) {
if args.length() == 0 {
return;
}
let assertion = args.get(0);
let is_truthy = assertion.is_true();
if !is_truthy {
let mut message = "Assertion failed".to_string();
for i in 1..args.length() {
let arg = args.get(i);
let arg_str = arg.to_string(scope).unwrap().to_rust_string_lossy(scope);
message.push_str(&format!(": {}", arg_str));
}
println!("{}", message);
}
}
pub fn console_dir_callback(
scope: &mut v8::PinScope,
args: v8::FunctionCallbackArguments,
_rv: v8::ReturnValue,
) {
if args.length() == 0 {
println!("console.dir: no object provided");
return;
}
let obj = args.get(0);
if obj.is_object() {
let obj_local = v8::Local::<v8::Object>::try_from(obj).unwrap();
let keys = obj_local
.get_own_property_names(scope, Default::default())
.unwrap();
let length = keys.length();
println!("{{");
for i in 0..length {
let key = keys.get_index(scope, i).unwrap();
let key_str = key.to_string(scope).unwrap().to_rust_string_lossy(scope);
let value = obj_local.get(scope, key).unwrap();
let value_str = value.to_string(scope).unwrap().to_rust_string_lossy(scope);
println!(" {}: {},", key_str, value_str);
}
println!("}}");
} else {
let value_str = obj.to_string(scope).unwrap().to_rust_string_lossy(scope);
println!("{}", value_str);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[serial_test::serial]
fn test_minimal_runtime_creation() {
let runtime = crate::runtime_minimal::MinimalRuntime::new();
assert!(runtime.is_ok());
}
#[test]
#[serial_test::serial]
fn test_minimal_js_execution() {
let mut runtime = crate::runtime_minimal::MinimalRuntime::new().unwrap();
let result = runtime.execute_code("1 + 1");
assert!(result.is_ok());
assert_eq!(result.unwrap().trim(), "2");
}
#[test]
#[serial_test::serial]
fn test_minimal_js_function() {
let mut runtime = crate::runtime_minimal::MinimalRuntime::new().unwrap();
let result = runtime.execute_code("let x = 5; let y = 10; x + y;");
assert!(result.is_ok());
assert_eq!(result.unwrap().trim(), "15");
}
#[test]
fn test_runtime_creation() {
let runtime: _ = Runtime::new(4, 512 * 1024 * 1024, true, false);
assert_eq!(runtime.get_config().pool_size, 4);
assert_eq!(runtime.get_config().max_memory, 512 * 1024 * 1024);
}
}