Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 49 additions & 63 deletions libs/jsruntime/src/backend/bridge.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use jsgc::Handle;
use jsgc::HandleMut;

use crate::Error;
use crate::Runtime;
use crate::lambda::LambdaKind;
use crate::logger;
Expand Down Expand Up @@ -192,46 +193,35 @@ pub(crate) extern "C" fn runtime_to_object<X>(
retv: &mut Value,
) -> Status {
logger::debug!(event = "runtime_to_object", ?value);
runtime.value_to_object(value, retv)
match runtime.value_to_object(value) {
Ok(value) => {
*retv = value;
Status::Normal
}
Err(err) => {
*retv = runtime.create_exception(err);
Status::Exception
}
}
}

impl<X> Runtime<X> {
pub(crate) fn value_to_object(&mut self, value: &Value, retv: &mut Value) -> Status {
pub(crate) fn value_to_object(&mut self, value: &Value) -> Result<Value, Error> {
logger::debug!(event = "to_object", ?value);
match value {
Value::None => unreachable!("Value::None"),
Value::Undefined | Value::Null => {
*retv = Value::Object(self.create_type_error(None));
Status::Exception
Value::Undefined | Value::Null => type_error!(),
Value::Boolean(_value) => {
runtime_todo!("ToObject: not yet implemented for Boolean values")
}
Value::Number(_value) => {
runtime_todo!("ToObject: not yet implemented for Number values")
}
Value::Boolean(_value) => runtime_todo!(
self,
"ToObject: not yet implemented for Boolean values",
retv
),
Value::Number(_value) => runtime_todo!(
self,
"ToObject: not yet implemented for Number values",
retv
),
Value::String(value) => {
// TODO(refactor): rewrite using `new String(value)`
match self.create_string_object(None, &[Value::String(*value)], true) {
Ok(Value::Object(object)) => {
*retv = Value::Object(object);
Status::Normal
}
Ok(_) => unreachable!(),
Err(err) => {
*retv = self.create_exception(err);
Status::Exception
}
}
}
Value::Object(_) => {
*retv = value.clone();
Status::Normal
self.create_string_object(None, &[Value::String(*value)], true)
}
Value::Object(_) => Ok(value.clone()),
}
}
}
Expand Down Expand Up @@ -368,7 +358,7 @@ pub(crate) extern "C" fn runtime_create_string<X>(
pub(crate) extern "C" fn runtime_create_capture<X>(
runtime: &mut Runtime<X>,
target: *mut Value,
) -> *mut Capture {
) -> HandleMut<Capture> {
logger::debug!(event = "runtime_create_capture", ?target);

debug_assert!(
Expand All @@ -386,33 +376,27 @@ pub(crate) extern "C" fn runtime_create_capture<X>(
)
};

let handle = runtime
.heap
.alloc_layout_mut::<Capture, _>(LAYOUT, move |ptr| {
// SAFETY: `ptr` is a non-null pointer to a `Capture`.
let capture = unsafe { ptr.cast::<Capture>().as_mut() };
capture.target = target;
// `capture.escaped` will be filled with an actual value.
});

handle.as_ptr()
runtime.heap.alloc_layout_mut(LAYOUT, move |ptr| {
// SAFETY: `ptr` is a non-null pointer to a `Capture`.
let capture = unsafe { ptr.cast::<Capture>().as_mut() };
capture.target = target;
// `capture.escaped` will be filled with an actual value.
})
}

pub(crate) extern "C" fn runtime_create_closure<X>(
runtime: &mut Runtime<X>,
lambda: Lambda<X>,
lambda_id: u32,
num_captures: u16,
) -> *mut Closure {
) -> HandleMut<Closure> {
logger::debug!(
event = "runtime_create_closure",
?lambda,
lambda_id,
num_captures
);
runtime
.create_closure(lambda, lambda_id.into(), num_captures)
.as_ptr()
runtime.create_closure(lambda, lambda_id.into(), num_captures)
}

pub(crate) extern "C" fn runtime_create_coroutine<X>(
Expand All @@ -421,7 +405,7 @@ pub(crate) extern "C" fn runtime_create_coroutine<X>(
num_locals: u16,
scratch_buffer_len: u16,
capture_buffer_len: u16,
) -> *mut Coroutine {
) -> HandleMut<Coroutine> {
logger::debug!(
event = "runtime_create_coroutine",
?closure,
Expand All @@ -430,9 +414,7 @@ pub(crate) extern "C" fn runtime_create_coroutine<X>(
capture_buffer_len,
);
let closure = HandleMut::from_ptr(closure).expect("closure must be a non-null pointer");
runtime
.create_coroutine(closure, num_locals, scratch_buffer_len, capture_buffer_len)
.as_ptr()
runtime.create_coroutine(closure, num_locals, scratch_buffer_len, capture_buffer_len)
}

pub(crate) extern "C" fn runtime_create_promise<X>(
Expand Down Expand Up @@ -462,26 +444,30 @@ pub(crate) extern "C" fn runtime_emit_promise_resolved<X>(
pub(crate) extern "C" fn runtime_create_object<X>(
runtime: &mut Runtime<X>,
prototype: *mut Object,
) -> *mut Object {
let prototype = HandleMut::from_ptr(prototype);
runtime.create_object(prototype).as_ptr()
) -> HandleMut<Object> {
let prototype = HandleMut::from_ptr(prototype).unwrap();
let mut object = runtime.create_object();
object.set_prototype(prototype);
object
}

pub(crate) extern "C" fn runtime_create_reference_error<X>(
runtime: &mut Runtime<X>,
) -> *mut Object {
runtime.create_reference_error(None).as_ptr()
) -> HandleMut<Object> {
runtime.create_reference_error(None)
}

pub(crate) extern "C" fn runtime_create_type_error<X>(runtime: &mut Runtime<X>) -> *mut Object {
runtime.create_type_error(None).as_ptr()
pub(crate) extern "C" fn runtime_create_type_error<X>(
runtime: &mut Runtime<X>,
) -> HandleMut<Object> {
runtime.create_type_error(None)
}

pub(crate) extern "C" fn runtime_create_internal_error<X>(
runtime: &mut Runtime<X>,
message: Handle<String>,
) -> *mut Object {
runtime.create_internal_error(Some(message)).as_ptr()
) -> HandleMut<Object> {
runtime.create_internal_error(Some(message))
}

pub(crate) extern "C" fn runtime_get_value_by_symbol<X>(
Expand Down Expand Up @@ -551,7 +537,7 @@ pub(crate) extern "C" fn runtime_get_value_by_value<X>(
let key = match runtime.make_property_key(key) {
Ok(key) => key,
Err(err) => {
*retv = err;
*retv = runtime.create_exception(err);
return Status::Exception;
}
};
Expand Down Expand Up @@ -611,7 +597,7 @@ pub(crate) extern "C" fn runtime_set_value_by_value<X>(
let key = match runtime.make_property_key(key) {
Ok(key) => key,
Err(err) => {
*retv = err;
*retv = runtime.create_exception(err);
return Status::Exception;
}
};
Expand Down Expand Up @@ -694,7 +680,7 @@ pub(crate) extern "C" fn runtime_create_data_property_by_value<X>(
let key = match runtime.make_property_key(key) {
Ok(key) => key,
Err(err) => {
*retv = err;
*retv = runtime.create_exception(err);
return Status::Exception;
}
};
Expand Down Expand Up @@ -748,8 +734,8 @@ pub(crate) extern "C" fn runtime_push_value<X>(
*retv = Value::None;
Status::Normal
}
Err(exception) => {
*retv = exception;
Err(err) => {
*retv = runtime.create_exception(err);
Status::Exception
}
}
Expand Down
42 changes: 21 additions & 21 deletions libs/jsruntime/src/backend/clir/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,17 +170,17 @@ pub fn compile<X>(
let program = &runtime.programs[program_id.index()];
for func in program.functions.iter() {
let mut session = {
let global_object = runtime.global_object.as_handle();
let global_object = runtime.builtins.global_object;
Session {
pref: &runtime.pref,
program,
symbol_registry: &mut runtime.symbol_registry,
lambda_registry: &mut runtime.lambda_registry,
code_registry: &mut runtime.code_registry,
global_object,
object_prototype: runtime.object_prototype.unwrap(),
function_prototype: runtime.function_prototype.unwrap(),
promise_prototype: runtime.promise_prototype.unwrap(),
object_prototype: runtime.builtins.object_prototype,
function_prototype: runtime.builtins.function_prototype,
promise_prototype: runtime.builtins.promise_prototype,
}
};
context.compile_function(func, &mut session, &program.scope_tree);
Expand Down Expand Up @@ -215,17 +215,17 @@ pub fn compile_function<X>(
let func = &program.functions[function_index];

let mut session = {
let global_object = runtime.global_object.as_handle();
let global_object = runtime.builtins.global_object;
Session {
pref: &runtime.pref,
program,
symbol_registry: &mut runtime.symbol_registry,
lambda_registry: &mut runtime.lambda_registry,
code_registry: &mut runtime.code_registry,
global_object,
object_prototype: runtime.object_prototype.unwrap(),
function_prototype: runtime.function_prototype.unwrap(),
promise_prototype: runtime.promise_prototype.unwrap(),
object_prototype: runtime.builtins.object_prototype,
function_prototype: runtime.builtins.function_prototype,
promise_prototype: runtime.builtins.promise_prototype,
}
};

Expand Down Expand Up @@ -440,7 +440,7 @@ where
self.editor
.put_branch(too_deep, then_block, &[], merge_block, &[]);
self.editor.switch_to_block(then_block);
self.emit_throw_internal_error(const_string!("Call stack too deep"));
self.emit_throw_internal_error(const_string_handle!("Call stack too deep"));
self.editor.put_jump(merge_block, &[]);
self.editor.switch_to_block(merge_block);
}
Expand Down Expand Up @@ -1168,7 +1168,7 @@ where
fn process_call(&mut self, argc: u16) {
// TODO: dynamic allocation
if argc > 8 {
self.emit_throw_internal_error(const_string!("TODO: too many arguments"));
self.emit_throw_internal_error(const_string_handle!("TODO: too many arguments"));
let len = self.operand_stack.len() - (argc as usize) - 1;
self.operand_stack.truncate(len);
self.operand_stack.push(Operand::Undefined); // TODO: dummy
Expand Down Expand Up @@ -1226,7 +1226,7 @@ where
fn process_new(&mut self, argc: u16) {
// TODO: dynamic allocation
if argc > 8 {
self.emit_throw_internal_error(const_string!("TODO: too many arguments"));
self.emit_throw_internal_error(const_string_handle!("TODO: too many arguments"));
let len = self.operand_stack.len() - (argc as usize) - 1;
self.operand_stack.truncate(len);
self.operand_stack.push(Operand::Undefined); // TODO: dummy
Expand Down Expand Up @@ -1424,7 +1424,7 @@ where
.put_runtime_number_to_string(self.support, *value),
Operand::String(value, _) => *value,
Operand::Object(_) => {
self.emit_throw_internal_error(const_string!("TODO: ToString(object)"));
self.emit_throw_internal_error(const_string_handle!("TODO: ToString(object)"));
self.editor.put_create_string(self.support, &[])
}
Operand::Any(value, _) => self.editor.put_runtime_to_string(self.support, *value),
Expand Down Expand Up @@ -1612,7 +1612,7 @@ where
// 13.5.1.2 Runtime Semantics: Evaluation
fn process_delete(&mut self) {
let (_operand, ..) = self.dereference();
self.emit_throw_internal_error(const_string!("TODO: delete operator"));
self.emit_throw_internal_error(const_string_handle!("TODO: delete operator"));
self.process_boolean(true);
}

Expand Down Expand Up @@ -2057,15 +2057,15 @@ where
fn process_instanceof(&mut self) {
let (_lhs, ..) = self.dereference();
let (_rhs, ..) = self.dereference();
self.emit_throw_internal_error(const_string!("TODO: instanceof operator"));
self.emit_throw_internal_error(const_string_handle!("TODO: instanceof operator"));
self.process_boolean(false);
}

// 13.10.1 Runtime Semantics: Evaluation
fn process_in(&mut self) {
let (_lhs, ..) = self.dereference();
let (_rhs, ..) = self.dereference();
self.emit_throw_internal_error(const_string!("TODO: in operator"));
self.emit_throw_internal_error(const_string_handle!("TODO: in operator"));
self.process_boolean(false);
}

Expand Down Expand Up @@ -2286,15 +2286,15 @@ where
None
}
PropertyOwner::Boolean(_) => {
self.emit_throw_internal_error(const_string!("TODO: ToObject(boolean)"));
self.emit_throw_internal_error(const_string_handle!("TODO: ToObject(boolean)"));
None
}
PropertyOwner::Number(_) => {
self.emit_throw_internal_error(const_string!("TODO: ToObject(number)"));
self.emit_throw_internal_error(const_string_handle!("TODO: ToObject(number)"));
None
}
PropertyOwner::String(_) => {
self.emit_throw_internal_error(const_string!("TODO: ToObject(string)"));
self.emit_throw_internal_error(const_string_handle!("TODO: ToObject(string)"));
None
}
PropertyOwner::Object(value) => Some(*value),
Expand Down Expand Up @@ -3192,7 +3192,7 @@ where
Operand::Boolean(value, ..) => *value,
Operand::Number(value, ..) => self.editor.put_number_to_boolean(*value),
Operand::String(..) => {
self.emit_throw_internal_error(const_string!("TODO: ToBoolean(string)"));
self.emit_throw_internal_error(const_string_handle!("TODO: ToBoolean(string)"));
self.editor.put_boolean(false)
}
Operand::Object(_) => self.editor.put_boolean(true),
Expand All @@ -3216,11 +3216,11 @@ where
Operand::Boolean(value, ..) => self.editor.put_boolean_to_number(*value),
Operand::Number(value, ..) => *value,
Operand::String(..) => {
self.emit_throw_internal_error(const_string!("TODO: ToNumber(string)"));
self.emit_throw_internal_error(const_string_handle!("TODO: ToNumber(string)"));
self.editor.put_number(f64::NAN)
}
Operand::Object(_) => {
self.emit_throw_internal_error(const_string!("TODO: ToNumber(object)"));
self.emit_throw_internal_error(const_string_handle!("TODO: ToNumber(object)"));
self.editor.put_number(f64::NAN)
}
Operand::Any(value, ..) => self.editor.put_runtime_to_numeric(self.support, *value),
Expand Down
3 changes: 3 additions & 0 deletions libs/jsruntime/src/builtins/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
/error/mod.rs
/eval_error/imp.rs
/eval_error/mod.rs
/function/mod.rs
/global/mod.rs
/internal_error/imp.rs
/internal_error/mod.rs
/object/mod.rs
/promise/mod.rs
/range_error/imp.rs
/range_error/mod.rs
Expand Down
Loading
Loading