@@ -226,7 +226,135 @@ ecma_builtin_function_prototype_object_bind (ecma_value_t this_arg, /**< this ar
226226 const ecma_value_t * arguments_list_p, /* *< list of arguments */
227227 ecma_length_t arguments_number) /* *< number of arguments */
228228{
229- ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg, arguments_list_p, arguments_number);
229+ ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
230+
231+ /* 2. */
232+ if (!ecma_op_is_callable (this_arg))
233+ {
234+ ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
235+ }
236+ else
237+ {
238+ /* 4. 11. 18. */
239+ ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
240+ ecma_object_t *function_p = ecma_create_object (prototype_obj_p, true , ECMA_OBJECT_TYPE_BOUND_FUNCTION);
241+
242+ ecma_deref_object (prototype_obj_p);
243+
244+ /* 7. */
245+ ecma_property_t *target_function_prop_p;
246+ target_function_prop_p = ecma_create_internal_property (function_p,
247+ ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_TARGET_FUNCTION);
248+
249+ ecma_object_t *this_arg_obj_p = ecma_get_object_from_value (this_arg);
250+ ECMA_SET_NON_NULL_POINTER (target_function_prop_p->u .internal_property .value , this_arg_obj_p);
251+
252+ /* 8. */
253+ ecma_property_t *bound_this_prop_p;
254+ bound_this_prop_p = ecma_create_internal_property (function_p, ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_THIS);
255+ const ecma_length_t arg_count = arguments_number;
256+
257+ if (arg_count > 0 )
258+ {
259+ bound_this_prop_p->u .internal_property .value = ecma_copy_value (arguments_list_p[0 ], false );
260+ }
261+ else
262+ {
263+ bound_this_prop_p->u .internal_property .value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
264+ }
265+
266+ if (arg_count > 1 )
267+ {
268+ ecma_collection_header_t *bound_args_collection_p;
269+ bound_args_collection_p = ecma_new_values_collection (&arguments_list_p[1 ], arg_count - 1 , false );
270+
271+ ecma_property_t *bound_args_prop_p;
272+ bound_args_prop_p = ecma_create_internal_property (function_p, ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_ARGS);
273+ ECMA_SET_NON_NULL_POINTER (bound_args_prop_p->u .internal_property .value , bound_args_collection_p);
274+ }
275+
276+ /*
277+ * [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_FUNCTION type.
278+ *
279+ * See also: ecma_object_get_class_name
280+ */
281+
282+ /* 17. */
283+ ecma_number_t *length_p = ecma_alloc_number ();
284+ *length_p = 0 ;
285+
286+ ecma_property_descriptor_t length_prop_desc = ecma_make_empty_property_descriptor ();
287+ {
288+ length_prop_desc.is_value_defined = true ;
289+ length_prop_desc.value = ecma_make_number_value (length_p);
290+
291+ length_prop_desc.is_writable_defined = true ;
292+ length_prop_desc.is_writable = false ;
293+
294+ length_prop_desc.is_enumerable_defined = true ;
295+ length_prop_desc.is_enumerable = false ;
296+
297+ length_prop_desc.is_configurable_defined = true ;
298+ length_prop_desc.is_configurable = false ;
299+ }
300+ ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH);
301+ ecma_completion_value_t completion = ecma_op_object_define_own_property (function_p,
302+ magic_string_length_p,
303+ &length_prop_desc,
304+ false );
305+
306+ JERRY_ASSERT (ecma_is_completion_value_normal_true (completion)
307+ || ecma_is_completion_value_normal_false (completion));
308+
309+ ecma_deref_ecma_string (magic_string_length_p);
310+ ecma_dealloc_number (length_p);
311+
312+ /* 19-21. */
313+ ecma_object_t *thrower_p = ecma_builtin_get (ECMA_BUILTIN_ID_TYPE_ERROR_THROWER);
314+
315+ ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor ();
316+ {
317+ prop_desc.is_enumerable_defined = true ;
318+ prop_desc.is_enumerable = false ;
319+
320+ prop_desc.is_configurable_defined = true ;
321+ prop_desc.is_configurable = false ;
322+
323+ prop_desc.is_get_defined = true ;
324+ prop_desc.get_p = thrower_p;
325+
326+ prop_desc.is_set_defined = true ;
327+ prop_desc.set_p = thrower_p;
328+ }
329+
330+ ecma_string_t *magic_string_caller_p = ecma_get_magic_string (LIT_MAGIC_STRING_CALLER);
331+ completion = ecma_op_object_define_own_property (function_p,
332+ magic_string_caller_p,
333+ &prop_desc,
334+ false );
335+
336+ JERRY_ASSERT (ecma_is_completion_value_normal_true (completion)
337+ || ecma_is_completion_value_normal_false (completion));
338+
339+ ecma_deref_ecma_string (magic_string_caller_p);
340+
341+ ecma_string_t *magic_string_arguments_p = ecma_get_magic_string (LIT_MAGIC_STRING_ARGUMENTS);
342+ completion = ecma_op_object_define_own_property (function_p,
343+ magic_string_arguments_p,
344+ &prop_desc,
345+ false );
346+
347+ JERRY_ASSERT (ecma_is_completion_value_normal_true (completion)
348+ || ecma_is_completion_value_normal_false (completion));
349+
350+ ecma_deref_ecma_string (magic_string_arguments_p);
351+ ecma_deref_object (thrower_p);
352+
353+ /* 22. */
354+ ret_value = ecma_make_normal_completion_value (ecma_make_object_value (function_p));
355+ }
356+
357+ return ret_value;
230358} /* ecma_builtin_function_prototype_object_bind */
231359
232360/* *
0 commit comments