From bc61769c2b162b0a312557655bc09892bf6f5050 Mon Sep 17 00:00:00 2001 From: y21 <30553356+y21@users.noreply.github.com> Date: Tue, 29 Oct 2024 21:20:25 +0100 Subject: [PATCH] add `name` property to functions --- crates/dash_vm/src/js_std/generator.rs | 6 +-- crates/dash_vm/src/value/function/async.rs | 6 +-- .../dash_vm/src/value/function/generator.rs | 6 +-- crates/dash_vm/src/value/function/mod.rs | 48 +++++++------------ 4 files changed, 23 insertions(+), 43 deletions(-) diff --git a/crates/dash_vm/src/js_std/generator.rs b/crates/dash_vm/src/js_std/generator.rs index 8afa6288..eddabb26 100644 --- a/crates/dash_vm/src/js_std/generator.rs +++ b/crates/dash_vm/src/js_std/generator.rs @@ -2,7 +2,6 @@ use std::mem; use crate::dispatch::HandleResult; use crate::frame::Frame; -use dash_middle::interner::sym; use crate::localscope::LocalScope; use crate::throw; use crate::value::function::generator::{GeneratorIterator, GeneratorState}; @@ -11,6 +10,7 @@ use crate::value::function::{Function, FunctionKind}; use crate::value::object::{NamedObject, Object, PropertyValue}; use crate::value::root_ext::RootErrExt; use crate::value::{Root, Unpack, Value, ValueContext}; +use dash_middle::interner::sym; pub fn next(cx: CallContext) -> Result { let generator = cx.this.unpack(); @@ -36,8 +36,8 @@ pub fn next(cx: CallContext) -> Result { .downcast_ref::() .map(|fun| fun.kind()) { - Some(FunctionKind::Generator(gen)) => gen.function(), - Some(FunctionKind::Async(fun)) => fun.inner().function(), + Some(FunctionKind::Generator(gen)) => &gen.function, + Some(FunctionKind::Async(fun)) => &fun.inner.function, _ => throw!(cx.scope, TypeError, "Incompatible generator function"), }; diff --git a/crates/dash_vm/src/value/function/async.rs b/crates/dash_vm/src/value/function/async.rs index eae484ae..cbb2fe76 100644 --- a/crates/dash_vm/src/value/function/async.rs +++ b/crates/dash_vm/src/value/function/async.rs @@ -15,7 +15,7 @@ use super::user::UserFunction; #[derive(Debug, Trace)] pub struct AsyncFunction { /// The properties of generator functions are very similar to async functions, so we can build upon generators - inner: GeneratorFunction, + pub inner: GeneratorFunction, } impl AsyncFunction { @@ -92,10 +92,6 @@ impl AsyncFunction { } } } - - pub fn inner(&self) -> &GeneratorFunction { - &self.inner - } } /// A callable object that is passed to `.then()` on awaited promises. diff --git a/crates/dash_vm/src/value/function/generator.rs b/crates/dash_vm/src/value/function/generator.rs index 89664b0b..6b234599 100644 --- a/crates/dash_vm/src/value/function/generator.rs +++ b/crates/dash_vm/src/value/function/generator.rs @@ -17,7 +17,7 @@ use super::user::UserFunction; #[derive(Debug, Trace)] pub struct GeneratorFunction { - function: UserFunction, + pub function: UserFunction, } impl GeneratorFunction { @@ -25,10 +25,6 @@ impl GeneratorFunction { Self { function } } - pub fn function(&self) -> &UserFunction { - &self.function - } - pub(crate) fn handle_function_call( &self, scope: &mut LocalScope, diff --git a/crates/dash_vm/src/value/function/mod.rs b/crates/dash_vm/src/value/function/mod.rs index 4abeed21..8e6d06eb 100755 --- a/crates/dash_vm/src/value/function/mod.rs +++ b/crates/dash_vm/src/value/function/mod.rs @@ -53,36 +53,6 @@ unsafe impl Trace for FunctionKind { } } -impl FunctionKind { - pub fn as_native(&self) -> Option<&NativeFunction> { - match self { - Self::Native(f) => Some(f), - _ => None, - } - } - - pub fn as_user(&self) -> Option<&UserFunction> { - match self { - Self::User(f) => Some(f), - _ => None, - } - } - - pub fn as_generator(&self) -> Option<&GeneratorFunction> { - match self { - Self::Generator(f) => Some(f), - _ => None, - } - } - - pub fn as_async(&self) -> Option<&AsyncFunction> { - match self { - Self::Async(f) => Some(f), - _ => None, - } - } -} - impl fmt::Debug for FunctionKind { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { @@ -154,6 +124,16 @@ impl Function { let this = scope.register(NamedObject::with_prototype_and_constructor(prototype, this_handle)); Ok(this) } + + pub fn inner_user_function(&self) -> Option<&UserFunction> { + match &self.kind { + FunctionKind::User(function) => Some(function), + FunctionKind::Generator(generator) => Some(&generator.function), + FunctionKind::Async(function) => Some(&function.inner.function), + FunctionKind::Closure(closure) => Some(&closure.fun), + FunctionKind::Native(_) => None, + } + } } fn handle_call( @@ -207,6 +187,14 @@ impl Object for Function { descriptor: PropertyDataDescriptor::CONFIGURABLE, })); } + sym::length => { + if let Some(function) = self.inner_user_function() { + return Ok(Some(PropertyValue { + kind: PropertyValueKind::Static(Value::number(function.inner().params as f64)), + descriptor: PropertyDataDescriptor::CONFIGURABLE, + })); + } + } sym::prototype => { let prototype = self.get_or_set_prototype(sc); return Ok(Some(PropertyValue::static_empty(Value::object(prototype))));