Rework built-in processing of JerryScript (#4347)

- All built-ins are native functions now
- Native handlers have a built-in id: ECMA_BUILTIN_ID_HANDLER
- Built-in routine identifiers start from 1
- Built-in routines have an own flag set
- Name property of routines is resolved dynamically
- Style fixes

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2020-12-01 11:37:08 +01:00
committed by GitHub
parent 577a605ead
commit c0fc67f5bd
39 changed files with 441 additions and 442 deletions
+74 -69
View File
@@ -802,41 +802,42 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
}
case ECMA_OBJECT_TYPE_FUNCTION:
{
if (!ecma_get_object_is_builtin (object_p))
{
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t,
ext_func_p->u.function.scope_cp));
JERRY_ASSERT (!ecma_get_object_is_builtin (object_p));
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t,
ext_func_p->u.function.scope_cp));
#if ENABLED (JERRY_ESNEXT)
const ecma_compiled_code_t *byte_code_p = ecma_op_function_get_compiled_code (ext_func_p);
const ecma_compiled_code_t *byte_code_p = ecma_op_function_get_compiled_code (ext_func_p);
if (CBC_FUNCTION_IS_ARROW (byte_code_p->status_flags))
if (CBC_FUNCTION_IS_ARROW (byte_code_p->status_flags))
{
ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) object_p;
if (ecma_is_value_object (arrow_func_p->this_binding))
{
ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) object_p;
if (ecma_is_value_object (arrow_func_p->this_binding))
{
ecma_gc_set_object_visited (ecma_get_object_from_value (arrow_func_p->this_binding));
}
if (ecma_is_value_object (arrow_func_p->new_target))
{
ecma_gc_set_object_visited (ecma_get_object_from_value (arrow_func_p->new_target));
}
ecma_gc_set_object_visited (ecma_get_object_from_value (arrow_func_p->this_binding));
}
if (ecma_is_value_object (arrow_func_p->new_target))
{
ecma_gc_set_object_visited (ecma_get_object_from_value (arrow_func_p->new_target));
}
#endif /* ENABLED (JERRY_ESNEXT) */
}
#endif /* ENABLED (JERRY_ESNEXT) */
break;
}
#if ENABLED (JERRY_ESNEXT)
case ECMA_OBJECT_TYPE_NATIVE_FUNCTION:
{
if (ecma_get_object_is_builtin (object_p))
{
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
switch (ext_func_p->u.native_handler.id)
if (ecma_get_object_is_builtin (object_p)
&& ext_func_p->u.built_in.id == ECMA_BUILTIN_ID_HANDLER)
{
switch (ext_func_p->u.built_in.routine_id)
{
case ECMA_NATIVE_HANDLER_PROMISE_RESOLVE:
case ECMA_NATIVE_HANDLER_PROMISE_REJECT:
@@ -1282,68 +1283,72 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
{
uint8_t length_and_bitset_size;
if (object_type == ECMA_OBJECT_TYPE_CLASS
|| object_type == ECMA_OBJECT_TYPE_ARRAY)
if (object_type == ECMA_OBJECT_TYPE_CLASS || object_type == ECMA_OBJECT_TYPE_ARRAY)
{
ext_object_size = sizeof (ecma_extended_built_in_object_t);
length_and_bitset_size = ((ecma_extended_built_in_object_t *) object_p)->built_in.length_and_bitset_size;
ext_object_size += (2 * sizeof (uint32_t)) * (length_and_bitset_size >> ECMA_BUILT_IN_BITSET_SHIFT);
length_and_bitset_size = ((ecma_extended_built_in_object_t *) object_p)->built_in.u.length_and_bitset_size;
ext_object_size += sizeof (uint64_t) * (length_and_bitset_size >> ECMA_BUILT_IN_BITSET_SHIFT);
}
else
{
#if ENABLED (JERRY_ESNEXT)
if (object_type == ECMA_OBJECT_TYPE_NATIVE_FUNCTION)
if (object_type == ECMA_OBJECT_TYPE_NATIVE_FUNCTION
&& ecma_builtin_function_is_routine (object_p))
{
#if ENABLED (JERRY_ESNEXT)
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
switch (ext_obj_p->u.native_handler.id)
if (ext_obj_p->u.built_in.id == ECMA_BUILTIN_ID_HANDLER)
{
case ECMA_NATIVE_HANDLER_PROMISE_RESOLVE:
case ECMA_NATIVE_HANDLER_PROMISE_REJECT:
switch (ext_obj_p->u.built_in.routine_id)
{
ext_object_size = sizeof (ecma_promise_resolver_t);
break;
}
case ECMA_NATIVE_HANDLER_PROMISE_THEN_FINALLY:
case ECMA_NATIVE_HANDLER_PROMISE_CATCH_FINALLY:
{
ext_object_size = sizeof (ecma_promise_finally_function_t);
break;
}
case ECMA_NATIVE_HANDLER_PROMISE_CAPABILITY_EXECUTOR:
{
ext_object_size = sizeof (ecma_promise_capability_executor_t);
break;
}
case ECMA_NATIVE_HANDLER_PROMISE_ALL_HELPER:
{
ext_object_size = sizeof (ecma_promise_all_executor_t);
break;
}
case ECMA_NATIVE_HANDLER_PROMISE_RESOLVE:
case ECMA_NATIVE_HANDLER_PROMISE_REJECT:
{
ext_object_size = sizeof (ecma_promise_resolver_t);
break;
}
case ECMA_NATIVE_HANDLER_PROMISE_THEN_FINALLY:
case ECMA_NATIVE_HANDLER_PROMISE_CATCH_FINALLY:
{
ext_object_size = sizeof (ecma_promise_finally_function_t);
break;
}
case ECMA_NATIVE_HANDLER_PROMISE_CAPABILITY_EXECUTOR:
{
ext_object_size = sizeof (ecma_promise_capability_executor_t);
break;
}
case ECMA_NATIVE_HANDLER_PROMISE_ALL_HELPER:
{
ext_object_size = sizeof (ecma_promise_all_executor_t);
break;
}
#if ENABLED (JERRY_BUILTIN_PROXY)
case ECMA_NATIVE_HANDLER_PROXY_REVOKE:
{
ext_object_size = sizeof (ecma_revocable_proxy_object_t);
break;
}
case ECMA_NATIVE_HANDLER_PROXY_REVOKE:
{
ext_object_size = sizeof (ecma_revocable_proxy_object_t);
break;
}
#endif /* ENABLED (JERRY_BUILTIN_PROXY) */
case ECMA_NATIVE_HANDLER_VALUE_THUNK:
case ECMA_NATIVE_HANDLER_VALUE_THROWER:
{
ecma_free_value_if_not_object (((ecma_promise_value_thunk_t *) object_p)->value);
ext_object_size = sizeof (ecma_promise_value_thunk_t);
break;
}
default:
{
JERRY_UNREACHABLE ();
case ECMA_NATIVE_HANDLER_VALUE_THUNK:
case ECMA_NATIVE_HANDLER_VALUE_THROWER:
{
ecma_free_value_if_not_object (((ecma_promise_value_thunk_t *) object_p)->value);
ext_object_size = sizeof (ecma_promise_value_thunk_t);
break;
}
default:
{
JERRY_UNREACHABLE ();
}
}
}
#endif /* ENABLED (JERRY_ESNEXT) */
}
else
#endif /* ENABLED (JERRY_ESNEXT) */
{
length_and_bitset_size = ((ecma_extended_object_t *) object_p)->u.built_in.length_and_bitset_size;
ext_object_size += (2 * sizeof (uint32_t)) * (length_and_bitset_size >> ECMA_BUILT_IN_BITSET_SHIFT);
length_and_bitset_size = ((ecma_extended_object_t *) object_p)->u.built_in.u.length_and_bitset_size;
ext_object_size += sizeof (uint64_t) * (length_and_bitset_size >> ECMA_BUILT_IN_BITSET_SHIFT);
}
ecma_gc_free_properties (object_p);
+16 -18
View File
@@ -851,20 +851,27 @@ typedef struct
typedef struct
{
uint8_t id; /**< built-in id */
uint8_t length_and_bitset_size; /**< length for built-in functions and
* bit set size for all built-ins */
uint16_t routine_id; /**< routine id for built-in functions */
uint8_t routine_id; /**< routine id for built-in functions */
/** built-in specific field */
union
{
uint32_t instantiated_bitset[1]; /**< bit set for instantiated properties */
struct
{
uint16_t name; /**< name of the built-in functions */
uint16_t bitset; /**< bit set for instantiated properties of builtin functions */
} builtin_routine;
uint8_t length_and_bitset_size; /**< length and bit set size for generic built-ins */
uint8_t routine_index; /**< property descriptor index for built-in routines */
} u;
/** extra built-in info */
union
{
uint8_t instantiated_bitset[1]; /**< instantiated property bit set for generic built-ins */
uint8_t routine_flags; /**< flags for built-in routines */
} u2;
uint32_t continue_instantiated_bitset[1]; /**< bit set for instantiated properties */
} ecma_built_in_props_t;
/**
* Number of bits available in the instantiated bitset without allocation
*/
#define ECMA_BUILTIN_INSTANTIATED_BITSET_MIN_SIZE (8 + 32)
/**
* Builtin routine function object status flags
*/
@@ -977,15 +984,6 @@ typedef struct
ecma_value_t args_len_or_this; /**< length of arguments or this value */
} bound_function;
/**
* Description of a built-in native handler object.
*/
struct
{
uint32_t id; /**< handler id */
uint32_t flags; /**< handler flags */
} native_handler;
ecma_native_handler_t external_handler_cb; /**< external function */
} u;
} ecma_extended_object_t;