3030#define ECMA_BUILTINS_INTERNAL
3131#include "ecma-builtins-internal.h"
3232
33+ /**
34+ * This object has a custom dispatch function.
35+ */
36+ #define BUILTIN_CUSTOM_DISPATCH
37+
38+ /**
39+ * List of built-in routine identifiers.
40+ */
41+ enum
42+ {
43+ /* Note: these 6 routines must be in this order */
44+ ECMA_OBJECT_PROTOTYPE_ROUTINE_START = ECMA_BUILTIN_ID__COUNT - 1 ,
45+ ECMA_OBJECT_PROTOTYPE_TO_STRING ,
46+ ECMA_OBJECT_PROTOTYPE_VALUE_OF ,
47+ ECMA_OBJECT_PROTOTYPE_TO_LOCALE_STRING ,
48+ ECMA_OBJECT_PROTOTYPE_IS_PROTOTYPE_OF ,
49+ ECMA_OBJECT_PROTOTYPE_HAS_OWN_PROPERTY ,
50+ ECMA_OBJECT_PROTOTYPE_PROPERTY_IS_ENUMERABLE ,
51+ };
52+
53+
3354#define BUILTIN_INC_HEADER_NAME "ecma-builtin-object-prototype.inc.h"
3455#define BUILTIN_UNDERSCORED_ID object_prototype
3556#include "ecma-builtin-internal-routines-template.inc.h"
@@ -84,37 +105,30 @@ ecma_builtin_object_prototype_object_value_of (ecma_value_t this_arg) /**< this
84105 * Returned value must be freed with ecma_free_value.
85106 */
86107static ecma_value_t
87- ecma_builtin_object_prototype_object_to_locale_string (ecma_value_t this_arg ) /**< this argument */
108+ ecma_builtin_object_prototype_object_to_locale_string (ecma_object_t * obj_p ) /**< this argument */
88109{
89- ecma_value_t return_value = ECMA_VALUE_EMPTY ;
90- /* 1. */
91- ECMA_TRY_CATCH (obj_val ,
92- ecma_op_to_object (this_arg ),
93- return_value );
94-
95- ecma_object_t * obj_p = ecma_get_object_from_value (obj_val );
96-
97110 /* 2. */
98- ECMA_TRY_CATCH (to_string_val ,
99- ecma_op_object_get_by_magic_id (obj_p , LIT_MAGIC_STRING_TO_STRING_UL ),
100- return_value );
111+ ecma_value_t to_string_val = ecma_op_object_get_by_magic_id (obj_p , LIT_MAGIC_STRING_TO_STRING_UL );
101112
102- /* 3. */
103- if (!ecma_op_is_callable (to_string_val ))
113+ if (ECMA_IS_VALUE_ERROR (to_string_val ))
104114 {
105- return_value = ecma_raise_type_error ( ECMA_ERR_MSG ( "'toString is missing or not a function.'" )) ;
115+ return to_string_val ;
106116 }
107- else
117+
118+ /* 3. */
119+ if (!ecma_op_is_callable (to_string_val ))
108120 {
109- /* 4. */
110- ecma_object_t * to_string_func_obj_p = ecma_get_object_from_value (to_string_val );
111- return_value = ecma_op_function_call (to_string_func_obj_p , this_arg , NULL , 0 );
121+ ecma_free_value (to_string_val );
122+ return ecma_raise_type_error (ECMA_ERR_MSG ("'toString is missing or not a function.'" ));
112123 }
113124
114- ECMA_FINALIZE (to_string_val );
115- ECMA_FINALIZE (obj_val );
125+ /* 4. */
126+ ecma_object_t * to_string_func_obj_p = ecma_get_object_from_value (to_string_val );
127+ ecma_value_t ret_value = ecma_op_function_call (to_string_func_obj_p , ecma_make_object_value (obj_p ), NULL , 0 );
128+
129+ ecma_deref_object (to_string_func_obj_p );
116130
117- return return_value ;
131+ return ret_value ;
118132} /* ecma_builtin_object_prototype_object_to_locale_string */
119133
120134/**
@@ -127,33 +141,10 @@ ecma_builtin_object_prototype_object_to_locale_string (ecma_value_t this_arg) /*
127141 * Returned value must be freed with ecma_free_value.
128142 */
129143static ecma_value_t
130- ecma_builtin_object_prototype_object_has_own_property (ecma_value_t this_arg , /**< this argument */
131- ecma_value_t arg ) /**< first argument */
144+ ecma_builtin_object_prototype_object_has_own_property (ecma_object_t * obj_p , /**< this argument */
145+ ecma_string_t * prop_name_p ) /**< first argument */
132146{
133- ecma_value_t return_value = ECMA_VALUE_EMPTY ;
134-
135- /* 1. */
136- ECMA_TRY_CATCH (to_string_val ,
137- ecma_op_to_string (arg ),
138- return_value );
139-
140- /* 2. */
141- ECMA_TRY_CATCH (obj_val ,
142- ecma_op_to_object (this_arg ),
143- return_value );
144-
145- ecma_string_t * property_name_string_p = ecma_get_string_from_value (to_string_val );
146-
147- ecma_object_t * obj_p = ecma_get_object_from_value (obj_val );
148-
149- /* 3. */
150- return_value = ecma_make_boolean_value (ecma_op_object_has_own_property (obj_p , property_name_string_p ));
151-
152- ECMA_FINALIZE (obj_val );
153-
154- ECMA_FINALIZE (to_string_val );
155-
156- return return_value ;
147+ return ecma_make_boolean_value (ecma_op_object_has_own_property (obj_p , prop_name_p ));
157148} /* ecma_builtin_object_prototype_object_has_own_property */
158149
159150/**
@@ -166,38 +157,24 @@ ecma_builtin_object_prototype_object_has_own_property (ecma_value_t this_arg, /*
166157 * Returned value must be freed with ecma_free_value.
167158 */
168159static ecma_value_t
169- ecma_builtin_object_prototype_object_is_prototype_of (ecma_value_t this_arg , /**< this argument */
160+ ecma_builtin_object_prototype_object_is_prototype_of (ecma_object_t * obj_p , /**< this argument */
170161 ecma_value_t arg ) /**< routine's first argument */
171162{
172- /* 1. Is the argument an object? */
173- if (!ecma_is_value_object (arg ))
163+ /* 3. Compare prototype to object */
164+ ecma_value_t v_obj_value = ecma_op_to_object (arg );
165+
166+ if (ECMA_IS_VALUE_ERROR (v_obj_value ))
174167 {
175- return ECMA_VALUE_FALSE ;
168+ return v_obj_value ;
176169 }
177170
178- ecma_value_t return_value = ECMA_VALUE_EMPTY ;
179-
180- /* 2. ToObject(this) */
181- ECMA_TRY_CATCH (obj_value ,
182- ecma_op_to_object (this_arg ),
183- return_value );
184-
185- ecma_object_t * obj_p = ecma_get_object_from_value (obj_value );
186-
187- /* 3. Compare prototype to object */
188- ECMA_TRY_CATCH (v_obj_value ,
189- ecma_op_to_object (arg ),
190- return_value );
191-
192171 ecma_object_t * v_obj_p = ecma_get_object_from_value (v_obj_value );
193172
194- bool is_prototype_of = ecma_op_object_is_prototype_of (obj_p , v_obj_p );
195- return_value = ecma_make_boolean_value (is_prototype_of );
196- ECMA_FINALIZE (v_obj_value );
173+ ecma_value_t ret_value = ecma_make_boolean_value (ecma_op_object_is_prototype_of (obj_p , v_obj_p ));
197174
198- ECMA_FINALIZE ( obj_value );
175+ ecma_deref_object ( v_obj_p );
199176
200- return return_value ;
177+ return ret_value ;
201178} /* ecma_builtin_object_prototype_object_is_prototype_of */
202179
203180/**
@@ -210,49 +187,124 @@ ecma_builtin_object_prototype_object_is_prototype_of (ecma_value_t this_arg, /**
210187 * Returned value must be freed with ecma_free_value.
211188 */
212189static ecma_value_t
213- ecma_builtin_object_prototype_object_property_is_enumerable (ecma_value_t this_arg , /**< this argument */
214- ecma_value_t arg ) /**< routine's first argument */
190+ ecma_builtin_object_prototype_object_property_is_enumerable (ecma_object_t * obj_p , /**< this argument */
191+ ecma_string_t * prop_name_p ) /**< first argument */
215192{
216- ecma_value_t return_value = ECMA_VALUE_EMPTY ;
217-
218- /* 1. */
219- ECMA_TRY_CATCH (to_string_val ,
220- ecma_op_to_string (arg ),
221- return_value );
222-
223- /* 2. */
224- ECMA_TRY_CATCH (obj_val ,
225- ecma_op_to_object (this_arg ),
226- return_value );
227-
228- ecma_string_t * property_name_string_p = ecma_get_string_from_value (to_string_val );
229-
230- ecma_object_t * obj_p = ecma_get_object_from_value (obj_val );
231-
232193 /* 3. */
233194 ecma_property_t property = ecma_op_object_get_own_property (obj_p ,
234- property_name_string_p ,
195+ prop_name_p ,
235196 NULL ,
236197 ECMA_PROPERTY_GET_NO_OPTIONS );
237198
238199 /* 4. */
239200 if (property != ECMA_PROPERTY_TYPE_NOT_FOUND && property != ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP )
240201 {
241- bool is_enumerable = ecma_is_property_enumerable (property );
202+ return ecma_make_boolean_value (ecma_is_property_enumerable (property ));
203+ }
204+
205+ return ECMA_VALUE_FALSE ;
206+ } /* ecma_builtin_object_prototype_object_property_is_enumerable */
207+
208+ /**
209+ * Dispatcher of the built-in's routines
210+ *
211+ * @return ecma value
212+ * Returned value must be freed with ecma_free_value.
213+ */
214+ ecma_value_t
215+ ecma_builtin_object_prototype_dispatch_routine (uint16_t builtin_routine_id , /**< built-in wide routine
216+ * identifier */
217+ ecma_value_t this_arg , /**< 'this' argument value */
218+ const ecma_value_t arguments_list_p [], /**< list of arguments
219+ * passed to routine */
220+ ecma_length_t arguments_number ) /**< length of arguments' list */
221+ {
222+ JERRY_UNUSED (arguments_number );
223+
224+ /* no specialization */
225+ if (builtin_routine_id <= ECMA_OBJECT_PROTOTYPE_VALUE_OF )
226+ {
227+ if (builtin_routine_id == ECMA_OBJECT_PROTOTYPE_TO_STRING )
228+ {
229+ return ecma_builtin_object_prototype_object_to_string (this_arg );
230+ }
242231
243- return_value = ecma_make_boolean_value (is_enumerable );
232+ JERRY_ASSERT (builtin_routine_id <= ECMA_OBJECT_PROTOTYPE_VALUE_OF );
233+
234+ return ecma_builtin_object_prototype_object_value_of (this_arg );
244235 }
245- else
236+
237+ if (builtin_routine_id <= ECMA_OBJECT_PROTOTYPE_IS_PROTOTYPE_OF )
246238 {
247- return_value = ECMA_VALUE_FALSE ;
239+ if (builtin_routine_id == ECMA_OBJECT_PROTOTYPE_IS_PROTOTYPE_OF )
240+ {
241+ /* 15.2.4.6.1. */
242+ if (!ecma_is_value_object (arguments_list_p [0 ]))
243+ {
244+ return ECMA_VALUE_FALSE ;
245+ }
246+ }
247+
248+ ecma_value_t to_object = ecma_op_to_object (this_arg );
249+
250+ if (ECMA_IS_VALUE_ERROR (to_object ))
251+ {
252+ return to_object ;
253+ }
254+
255+ ecma_object_t * obj_p = ecma_get_object_from_value (to_object );
256+
257+ ecma_value_t ret_value ;
258+
259+ if (builtin_routine_id == ECMA_OBJECT_PROTOTYPE_IS_PROTOTYPE_OF )
260+ {
261+ ret_value = ecma_builtin_object_prototype_object_is_prototype_of (obj_p , arguments_list_p [0 ]);
262+ }
263+ else
264+ {
265+ ret_value = ecma_builtin_object_prototype_object_to_locale_string (obj_p );
266+ }
267+
268+ ecma_deref_object (obj_p );
269+
270+ return ret_value ;
248271 }
249272
250- ECMA_FINALIZE ( obj_val );
273+ JERRY_ASSERT ( builtin_routine_id >= ECMA_OBJECT_PROTOTYPE_HAS_OWN_PROPERTY );
251274
252- ECMA_FINALIZE ( to_string_val );
275+ ecma_string_t * prop_name_p = ecma_op_to_prop_name ( arguments_list_p [ 0 ] );
253276
254- return return_value ;
255- } /* ecma_builtin_object_prototype_object_property_is_enumerable */
277+ if (prop_name_p == NULL )
278+ {
279+ return ECMA_VALUE_ERROR ;
280+ }
281+
282+ ecma_value_t to_object = ecma_op_to_object (this_arg );
283+
284+ if (ECMA_IS_VALUE_ERROR (to_object ))
285+ {
286+ ecma_deref_ecma_string (prop_name_p );
287+ return to_object ;
288+ }
289+
290+ ecma_object_t * obj_p = ecma_get_object_from_value (to_object );
291+
292+ ecma_value_t ret_value ;
293+
294+ if (builtin_routine_id == ECMA_OBJECT_PROTOTYPE_HAS_OWN_PROPERTY )
295+ {
296+ ret_value = ecma_builtin_object_prototype_object_has_own_property (obj_p , prop_name_p );
297+ }
298+ else
299+ {
300+ ret_value = ecma_builtin_object_prototype_object_property_is_enumerable (obj_p , prop_name_p );
301+ }
302+
303+ ecma_deref_ecma_string (prop_name_p );
304+ ecma_deref_object (obj_p );
305+
306+ return ret_value ;
307+ } /* ecma_builtin_object_prototype_dispatch_routine */
256308
257309/**
258310 * @}
0 commit comments