|
14 | 14 | use crate::{ |
15 | 15 | builtins::{ |
16 | 16 | array::Array, |
17 | | - object::{Object, ObjectInternalMethods, ObjectKind, INSTANCE_PROTOTYPE, PROTOTYPE}, |
| 17 | + object::{Object, ObjectData, ObjectInternalMethods, INSTANCE_PROTOTYPE, PROTOTYPE}, |
18 | 18 | property::Property, |
19 | 19 | value::{ResultValue, Value}, |
20 | 20 | }, |
@@ -55,7 +55,7 @@ pub enum FunctionBody { |
55 | 55 | impl Debug for FunctionBody { |
56 | 56 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
57 | 57 | match self { |
58 | | - Self::BuiltIn(_) => write!(f, "native code"), |
| 58 | + Self::BuiltIn(_) => write!(f, "[native]"), |
59 | 59 | Self::Ordinary(statements) => write!(f, "{:?}", statements), |
60 | 60 | } |
61 | 61 | } |
@@ -158,19 +158,19 @@ impl Function { |
158 | 158 | /// <https://tc39.es/ecma262/#sec-ecmascript-function-objects-call-thisargument-argumentslist> |
159 | 159 | pub fn call( |
160 | 160 | &self, |
161 | | - this: &mut Value, // represents a pointer to this function object wrapped in a GC (not a `this` JS object) |
| 161 | + function: Value, // represents a pointer to this function object wrapped in a GC (not a `this` JS object) |
| 162 | + this: &mut Value, |
162 | 163 | args_list: &[Value], |
163 | 164 | interpreter: &mut Interpreter, |
164 | | - this_obj: &mut Value, |
165 | 165 | ) -> ResultValue { |
166 | 166 | if self.callable { |
167 | 167 | match self.body { |
168 | | - FunctionBody::BuiltIn(func) => func(this_obj, args_list, interpreter), |
| 168 | + FunctionBody::BuiltIn(func) => func(this, args_list, interpreter), |
169 | 169 | FunctionBody::Ordinary(ref body) => { |
170 | 170 | // Create a new Function environment who's parent is set to the scope of the function declaration (self.environment) |
171 | 171 | // <https://tc39.es/ecma262/#sec-prepareforordinarycall> |
172 | 172 | let local_env = new_function_environment( |
173 | | - this.clone(), |
| 173 | + function, |
174 | 174 | None, |
175 | 175 | Some(self.environment.as_ref().unwrap().clone()), |
176 | 176 | BindingStatus::Uninitialized, |
@@ -216,23 +216,23 @@ impl Function { |
216 | 216 | /// <https://tc39.es/ecma262/#sec-ecmascript-function-objects-construct-argumentslist-newtarget> |
217 | 217 | pub fn construct( |
218 | 218 | &self, |
219 | | - this: &mut Value, // represents a pointer to this function object wrapped in a GC (not a `this` JS object) |
| 219 | + function: Value, // represents a pointer to this function object wrapped in a GC (not a `this` JS object) |
| 220 | + this: &mut Value, |
220 | 221 | args_list: &[Value], |
221 | 222 | interpreter: &mut Interpreter, |
222 | | - this_obj: &mut Value, |
223 | 223 | ) -> ResultValue { |
224 | 224 | if self.constructable { |
225 | 225 | match self.body { |
226 | 226 | FunctionBody::BuiltIn(func) => { |
227 | | - func(this_obj, args_list, interpreter).unwrap(); |
228 | | - Ok(this_obj.clone()) |
| 227 | + func(this, args_list, interpreter)?; |
| 228 | + Ok(this.clone()) |
229 | 229 | } |
230 | 230 | FunctionBody::Ordinary(ref body) => { |
231 | 231 | // Create a new Function environment who's parent is set to the scope of the function declaration (self.environment) |
232 | 232 | // <https://tc39.es/ecma262/#sec-prepareforordinarycall> |
233 | 233 | let local_env = new_function_environment( |
234 | | - this.clone(), |
235 | | - Some(this_obj.clone()), |
| 234 | + function, |
| 235 | + Some(this.clone()), |
236 | 236 | Some(self.environment.as_ref().unwrap().clone()), |
237 | 237 | BindingStatus::Initialized, |
238 | 238 | ); |
@@ -368,7 +368,10 @@ pub fn create_unmapped_arguments_object(arguments_list: &[Value]) -> Value { |
368 | 368 | /// |
369 | 369 | // This gets called when a new Function() is created. |
370 | 370 | pub fn make_function(this: &mut Value, _: &[Value], _: &mut Interpreter) -> ResultValue { |
371 | | - this.set_kind(ObjectKind::Function); |
| 371 | + this.set_data(ObjectData::Function(Function::builtin( |
| 372 | + Vec::new(), |
| 373 | + |_, _, _| Ok(Value::undefined()), |
| 374 | + ))); |
372 | 375 | Ok(this.clone()) |
373 | 376 | } |
374 | 377 |
|
@@ -399,8 +402,7 @@ pub fn make_constructor_fn( |
399 | 402 | let func_prototype = global.get_field("Function").get_field(PROTOTYPE); |
400 | 403 |
|
401 | 404 | // Create the function object and point its instance prototype to Function.prototype |
402 | | - let mut constructor_obj = Object::function(); |
403 | | - constructor_obj.set_func(constructor_fn); |
| 405 | + let mut constructor_obj = Object::function(constructor_fn); |
404 | 406 |
|
405 | 407 | constructor_obj.set_internal_slot(INSTANCE_PROTOTYPE, func_prototype); |
406 | 408 | let constructor_val = Value::from(constructor_obj); |
@@ -433,12 +435,9 @@ pub fn make_builtin_fn<N>(function: NativeFunctionData, name: N, parent: &Value, |
433 | 435 | where |
434 | 436 | N: Into<String>, |
435 | 437 | { |
436 | | - let func = Function::builtin(Vec::new(), function); |
| 438 | + let func = Object::function(Function::builtin(Vec::new(), function)); |
437 | 439 |
|
438 | | - let mut new_func = Object::function(); |
439 | | - new_func.set_func(func); |
440 | | - |
441 | | - let new_func_obj = Value::from(new_func); |
| 440 | + let new_func_obj = Value::from(func); |
442 | 441 | new_func_obj.set_field("length", length); |
443 | 442 |
|
444 | 443 | parent.set_field(name.into(), new_func_obj); |
|
0 commit comments