Skip to content

Commit

Permalink
rename PrimitiveCapabilities to InternalSlots and more misc fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
y21 committed Sep 9, 2024
1 parent 2e874ff commit 8a79a8d
Show file tree
Hide file tree
Showing 17 changed files with 180 additions and 288 deletions.
14 changes: 2 additions & 12 deletions crates/dash_vm/src/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1226,12 +1226,7 @@ mod handlers {
let offset = cx.fetchw_and_inc_ip() as i16;
let value = cx.pop_stack_rooted();

let jump = match value {
Value::Undefined(..) => true,
Value::Object(obj) => obj.as_primitive_capable().map(|p| p.is_undefined()).unwrap_or_default(),
Value::External(obj) => obj.as_primitive_capable().map(|p| p.is_undefined()).unwrap_or_default(),
_ => false,
};
let jump = matches!(value, Value::Undefined(_));

#[cfg(feature = "jit")]
cx.record_conditional_jump(ip, jump);
Expand All @@ -1255,12 +1250,7 @@ mod handlers {
let offset = cx.fetchw_and_inc_ip() as i16;
let value = cx.peek_stack();

let jump = match value {
Value::Undefined(..) => true,
Value::Object(obj) => obj.as_primitive_capable().map(|p| p.is_undefined()).unwrap_or_default(),
Value::External(obj) => obj.as_primitive_capable().map(|p| p.is_undefined()).unwrap_or_default(),
_ => false,
};
let jump = matches!(value, Value::Null(_));

#[cfg(feature = "jit")]
cx.record_conditional_jump(ip, jump);
Expand Down
4 changes: 2 additions & 2 deletions crates/dash_vm/src/gc/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use bitflags::bitflags;

use crate::localscope::LocalScope;
use crate::value::object::{PropertyKey, PropertyValue};
use crate::value::primitive::PrimitiveCapabilities;
use crate::value::primitive::InternalSlots;
use crate::value::{Typeof, Unrooted, Value};

use super::trace::{Trace, TraceCtxt};
Expand Down Expand Up @@ -77,7 +77,7 @@ pub struct ObjectVTable {
pub(crate) js_construct:
unsafe fn(*const (), &mut LocalScope<'_>, Handle, Value, Vec<Value>) -> Result<Unrooted, Unrooted>,
pub(crate) js_as_any: unsafe fn(*const ()) -> *const dyn Any,
pub(crate) js_as_primitive_capable: unsafe fn(*const ()) -> Option<*const dyn PrimitiveCapabilities>,
pub(crate) js_internal_slots: unsafe fn(*const ()) -> Option<*const dyn InternalSlots>,
pub(crate) js_own_keys: unsafe fn(*const (), sc: &mut LocalScope<'_>) -> Result<Vec<Value>, Value>,
pub(crate) js_type_of: unsafe fn(*const ()) -> Typeof,
}
Expand Down
6 changes: 3 additions & 3 deletions crates/dash_vm/src/gc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,9 @@ macro_rules! register_gc {
<$ty as Object>::construct(&*(ptr.cast::<$ty>()), scope, callee, this, args)
},
js_as_any: |ptr| unsafe { <$ty as Object>::as_any(&*(ptr.cast::<$ty>())) },
js_as_primitive_capable: |ptr| unsafe {
<$ty as Object>::as_primitive_capable(&*(ptr.cast::<$ty>()))
.map(|v| v as *const dyn crate::value::primitive::PrimitiveCapabilities)
js_internal_slots: |ptr| unsafe {
<$ty as Object>::internal_slots(&*(ptr.cast::<$ty>()))
.map(|v| v as *const dyn crate::value::primitive::InternalSlots)
},
js_own_keys: |ptr, scope| unsafe { <$ty as Object>::own_keys(&*(ptr.cast::<$ty>()), scope) },
js_type_of: |ptr| unsafe { <$ty as Object>::type_of(&*(ptr.cast::<$ty>())) },
Expand Down
2 changes: 1 addition & 1 deletion crates/dash_vm/src/js_std/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::localscope::LocalScope;
use crate::throw;
use crate::value::array::{Array, ArrayIterator};
use crate::value::function::native::CallContext;
use crate::value::object::PropertyValue;
use crate::value::object::{Object as _, PropertyValue};
use crate::value::ops::conversions::ValueConversion;
use crate::value::ops::equality::strict_eq;
use crate::value::root_ext::RootErrExt;
Expand Down
27 changes: 19 additions & 8 deletions crates/dash_vm/src/js_std/boolean.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::gc::interner::sym;
use crate::throw;
use crate::value::function::native::CallContext;
use crate::value::object::Object;
use crate::value::ops::conversions::ValueConversion;
use crate::value::primitive::InternalSlots;
use crate::value::{boxed, Value, ValueContext};

pub fn constructor(cx: CallContext) -> Result<Value, Value> {
Expand All @@ -15,18 +17,27 @@ pub fn constructor(cx: CallContext) -> Result<Value, Value> {
}

pub fn to_string(cx: CallContext) -> Result<Value, Value> {
if let Value::Boolean(b) = cx.this {
let s = b.then(|| sym::true_.into()).unwrap_or_else(|| sym::false_.into());

Ok(Value::String(s))
if let Some(value) = cx.this.internal_slots().and_then(InternalSlots::boolean_value) {
Ok(Value::String(
value.then(|| sym::true_.into()).unwrap_or_else(|| sym::false_.into()),
))
} else {
todo!()
throw!(
cx.scope,
TypeError,
"Boolean.prototype.toString called on non-boolean value"
)
}
}

pub fn value_of(cx: CallContext) -> Result<Value, Value> {
match cx.this {
Value::Boolean(b) => Ok(Value::Boolean(b)),
_ => throw!(cx.scope, TypeError, "Boolean.valueOf called on non-boolean"),
if let Some(value) = cx.this.internal_slots().and_then(InternalSlots::boolean_value) {
Ok(Value::Boolean(value))
} else {
throw!(
cx.scope,
TypeError,
"Boolean.prototype.valueOf called on non-boolean value"
)
}
}
25 changes: 21 additions & 4 deletions crates/dash_vm/src/js_std/number.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::throw;
use crate::util::intern_f64;
use crate::value::function::native::CallContext;
use crate::value::object::Object;
use crate::value::ops::conversions::ValueConversion;
use crate::value::primitive::{Number, MAX_SAFE_INTEGER, MIN_SAFE_INTEGER};
use crate::value::primitive::{InternalSlots, Number, MAX_SAFE_INTEGER, MIN_SAFE_INTEGER};
use crate::value::{boxed, Value, ValueContext};

pub fn constructor(cx: CallContext) -> Result<Value, Value> {
Expand All @@ -25,8 +26,12 @@ pub fn to_string(cx: CallContext) -> Result<Value, Value> {
.map(|n| n as u8)
.unwrap_or(10);

let Value::Number(Number(num)) = cx.this else {
throw!(cx.scope, TypeError, "Number.prototype.toString called on non-number")
let Some(num) = cx.this.internal_slots().and_then(InternalSlots::number_value) else {
throw!(
cx.scope,
TypeError,
"Number.prototype.toString called on non-number value"
)
};

let re = match radix {
Expand All @@ -39,6 +44,18 @@ pub fn to_string(cx: CallContext) -> Result<Value, Value> {
Ok(Value::String(re.into()))
}

pub fn value_of(cx: CallContext) -> Result<Value, Value> {
if let Some(num) = cx.this.internal_slots().and_then(InternalSlots::number_value) {
Ok(Value::number(num))
} else {
throw!(
cx.scope,
TypeError,
"Number.prototype.valueOf called on non-number value"
)
}
}

pub fn is_finite(cx: CallContext) -> Result<Value, Value> {
let num = match cx.args.first() {
Some(Value::Number(Number(n))) => n,
Expand All @@ -58,7 +75,7 @@ pub fn is_nan(cx: CallContext) -> Result<Value, Value> {
}

fn as_integer(f: f64) -> Option<i64> {
(f.trunc() == f && f.is_finite()).then(|| f as i64)
(f.trunc() == f && f.is_finite()).then_some(f as i64)
}

pub fn is_safe_integer(cx: CallContext) -> Result<Value, Value> {
Expand Down
12 changes: 10 additions & 2 deletions crates/dash_vm/src/js_std/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::throw;
use crate::value::array::{Array, ArrayIterator};
use crate::value::boxed::String as BoxedString;
use crate::value::function::native::CallContext;
use crate::value::object::PropertyValue;
use crate::value::object::{Object, PropertyValue};
use crate::value::ops::conversions::ValueConversion;
use crate::value::{Value, ValueContext};
use std::cmp;
Expand All @@ -25,7 +25,15 @@ pub fn constructor(cx: CallContext) -> Result<Value, Value> {
}

pub fn to_string(cx: CallContext) -> Result<Value, Value> {
Ok(cx.this)
if let Some(value) = cx.this.internal_slots().and_then(|prim| prim.string_value()) {
Ok(Value::String(value))
} else {
throw!(
cx.scope,
TypeError,
"String.prototype.toString called on non-string value"
)
}
}

fn create_html(
Expand Down
1 change: 1 addition & 0 deletions crates/dash_vm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ impl Vm {
number_ctor.clone(),
[
(sym::toString, scope.statics.number_tostring.clone()),
(sym::valueOf, scope.statics.number_valueof.clone()),
(sym::toFixed, scope.statics.number_to_fixed.clone()),
],
[],
Expand Down
2 changes: 2 additions & 0 deletions crates/dash_vm/src/statics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ pub struct Statics {
pub number_ctor: Handle,
pub number_prototype: Handle,
pub number_tostring: Handle,
pub number_valueof: Handle,
pub number_is_finite: Handle,
pub number_is_nan: Handle,
pub number_is_safe_integer: Handle,
Expand Down Expand Up @@ -311,6 +312,7 @@ impl Statics {
number_ctor: function(gc, sym::Number, js_std::number::constructor),
number_prototype: builtin_object(gc, BoxedNumber::with_obj(0.0, NamedObject::null())),
number_tostring: function(gc, sym::toString, js_std::number::to_string),
number_valueof: function(gc, sym::valueOf, js_std::number::value_of),
boolean_ctor: function(gc, sym::Boolean, js_std::boolean::constructor),
boolean_tostring: function(gc, sym::toString, js_std::boolean::to_string),
boolean_prototype: builtin_object(gc, BoxedBoolean::with_obj(false, NamedObject::null())),
Expand Down
34 changes: 9 additions & 25 deletions crates/dash_vm/src/value/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use dash_proc_macro::Trace;
use std::any::Any;

use super::object::{NamedObject, Object};
use super::primitive::{PrimitiveCapabilities, Symbol as PrimitiveSymbol};
use super::primitive::{InternalSlots, Symbol as PrimitiveSymbol};
use super::Value;

macro_rules! boxed_primitive {
Expand Down Expand Up @@ -63,7 +63,7 @@ macro_rules! boxed_primitive {
self
}

fn as_primitive_capable(&self) -> Option<&dyn PrimitiveCapabilities> {
fn internal_slots(&self) -> Option<&dyn InternalSlots> {
Some(self)
}
}
Expand Down Expand Up @@ -104,38 +104,22 @@ boxed_primitive! {
Symbol symbol_prototype symbol_ctor PrimitiveSymbol
}

impl PrimitiveCapabilities for Number {
fn as_number(&self) -> Option<f64> {
impl InternalSlots for Number {
fn number_value(&self) -> Option<f64> {
Some(self.inner)
}

fn unbox(&self) -> Value {
Value::number(self.inner)
}
}

impl PrimitiveCapabilities for Boolean {
fn as_bool(&self) -> Option<bool> {
impl InternalSlots for Boolean {
fn boolean_value(&self) -> Option<bool> {
Some(self.inner)
}

fn unbox(&self) -> Value {
Value::Boolean(self.inner)
}
}

impl PrimitiveCapabilities for String {
fn as_string(&self) -> Option<JsString> {
impl InternalSlots for String {
fn string_value(&self) -> Option<JsString> {
Some(self.inner)
}

fn unbox(&self) -> Value {
Value::String(self.inner)
}
}

impl PrimitiveCapabilities for Symbol {
fn unbox(&self) -> Value {
Value::Symbol(self.inner.clone())
}
}
impl InternalSlots for Symbol {}
Loading

0 comments on commit 8a79a8d

Please sign in to comment.