Introduce new API functions to obtain detailed object type information (#4162)
- jerry_object_get_type - jerry_function_get_type - jerry_iterator_get_type - jerry_value_is_async_function JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
This commit is contained in:
@@ -738,6 +738,41 @@ jerry_value_is_function (const jerry_value_t value) /**< api value */
|
||||
return ecma_op_is_callable (value);
|
||||
} /* jerry_value_is_function */
|
||||
|
||||
/**
|
||||
* Check if the specified value is an async function object value.
|
||||
*
|
||||
* @return true - if the specified value is an async function,
|
||||
* false - otherwise
|
||||
*/
|
||||
bool
|
||||
jerry_value_is_async_function (const jerry_value_t value) /**< api value */
|
||||
{
|
||||
jerry_assert_api_available ();
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
if (ecma_is_value_object (value))
|
||||
{
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (value);
|
||||
|
||||
if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION
|
||||
&& !ecma_get_object_is_builtin (obj_p))
|
||||
{
|
||||
const ecma_compiled_code_t *bytecode_data_p;
|
||||
bytecode_data_p = ecma_op_function_get_compiled_code ((ecma_extended_object_t *) obj_p);
|
||||
uint16_t type = CBC_FUNCTION_GET_TYPE (bytecode_data_p->status_flags);
|
||||
|
||||
return (type == CBC_FUNCTION_ASYNC
|
||||
|| type == CBC_FUNCTION_ASYNC_ARROW
|
||||
|| type == CBC_FUNCTION_ASYNC_GENERATOR);
|
||||
}
|
||||
}
|
||||
#else /* !ENABLED (JERRY_ESNEXT) */
|
||||
JERRY_UNUSED (value);
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
return false;
|
||||
} /* jerry_value_is_async_function */
|
||||
|
||||
/**
|
||||
* Check if the specified value is number.
|
||||
*
|
||||
@@ -943,6 +978,274 @@ jerry_value_get_type (const jerry_value_t value) /**< input value to check */
|
||||
}
|
||||
} /* jerry_value_get_type */
|
||||
|
||||
/**
|
||||
* Get the object type of the given value
|
||||
*
|
||||
* @return JERRY_OBJECT_TYPE_NONE - if the given value is not an object
|
||||
* jerry_object_type_t value - otherwise
|
||||
*/
|
||||
jerry_object_type_t
|
||||
jerry_object_get_type (const jerry_value_t value) /**< input value to check */
|
||||
{
|
||||
jerry_assert_api_available ();
|
||||
|
||||
if (!ecma_is_value_object (value))
|
||||
{
|
||||
return JERRY_OBJECT_TYPE_NONE;
|
||||
}
|
||||
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (value);
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
|
||||
|
||||
switch (ecma_get_object_type (obj_p))
|
||||
{
|
||||
case ECMA_OBJECT_TYPE_FUNCTION:
|
||||
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
|
||||
case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
|
||||
{
|
||||
return JERRY_OBJECT_TYPE_FUNCTION;
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_ARRAY:
|
||||
{
|
||||
return JERRY_OBJECT_TYPE_ARRAY;
|
||||
}
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
case ECMA_OBJECT_TYPE_PROXY:
|
||||
{
|
||||
return JERRY_OBJECT_TYPE_PROXY;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
case ECMA_OBJECT_TYPE_PSEUDO_ARRAY:
|
||||
{
|
||||
switch (ext_obj_p->u.pseudo_array.type)
|
||||
{
|
||||
case ECMA_PSEUDO_ARRAY_ARGUMENTS:
|
||||
{
|
||||
return JERRY_OBJECT_TYPE_ARGUMENTS;
|
||||
}
|
||||
#if ENABLED (JERRY_BUILTIN_TYPEDARRAY)
|
||||
case ECMA_PSEUDO_ARRAY_TYPEDARRAY:
|
||||
case ECMA_PSEUDO_ARRAY_TYPEDARRAY_WITH_INFO:
|
||||
{
|
||||
return JERRY_OBJECT_TYPE_TYPEDARRAY;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_BUILTIN_TYPEDARRAY) */
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
case ECMA_PSEUDO_STRING_ITERATOR:
|
||||
case ECMA_PSEUDO_ARRAY_ITERATOR:
|
||||
#if ENABLED (JERRY_BUILTIN_MAP)
|
||||
case ECMA_PSEUDO_MAP_ITERATOR:
|
||||
#endif /* ENABLED (JERRY_BUILTIN_MAP) */
|
||||
#if ENABLED (JERRY_BUILTIN_SET)
|
||||
case ECMA_PSEUDO_SET_ITERATOR:
|
||||
#endif /* ENABLED (JERRY_BUILTIN_SET) */
|
||||
{
|
||||
return JERRY_OBJECT_TYPE_ITERATOR;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_CLASS:
|
||||
{
|
||||
switch (ext_obj_p->u.class_prop.class_id)
|
||||
{
|
||||
case LIT_MAGIC_STRING_ARGUMENTS_UL:
|
||||
{
|
||||
return JERRY_OBJECT_TYPE_ARGUMENTS;
|
||||
}
|
||||
case LIT_MAGIC_STRING_BOOLEAN_UL:
|
||||
{
|
||||
return JERRY_OBJECT_TYPE_BOOLEAN;
|
||||
}
|
||||
case LIT_MAGIC_STRING_DATE_UL:
|
||||
{
|
||||
return JERRY_OBJECT_TYPE_DATE;
|
||||
}
|
||||
case LIT_MAGIC_STRING_NUMBER_UL:
|
||||
{
|
||||
return JERRY_OBJECT_TYPE_NUMBER;
|
||||
}
|
||||
case LIT_MAGIC_STRING_REGEXP_UL:
|
||||
{
|
||||
return JERRY_OBJECT_TYPE_REGEXP;
|
||||
}
|
||||
case LIT_MAGIC_STRING_STRING_UL:
|
||||
{
|
||||
return JERRY_OBJECT_TYPE_STRING;
|
||||
}
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
case LIT_MAGIC_STRING_SYMBOL_UL:
|
||||
{
|
||||
return JERRY_OBJECT_TYPE_SYMBOL;
|
||||
}
|
||||
case LIT_MAGIC_STRING_GENERATOR_UL:
|
||||
{
|
||||
return JERRY_OBJECT_TYPE_GENERATOR;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
#if ENABLED (JERRY_BUILTIN_BIGINT)
|
||||
case LIT_MAGIC_STRING_BIGINT_UL:
|
||||
{
|
||||
return JERRY_OBJECT_TYPE_BIGINT;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */
|
||||
#if ENABLED (JERRY_BUILTIN_CONTAINER)
|
||||
#if ENABLED (JERRY_BUILTIN_MAP)
|
||||
case LIT_MAGIC_STRING_MAP_UL:
|
||||
#endif /* ENABLED (JERRY_BUILTIN_MAP) */
|
||||
#if ENABLED (JERRY_BUILTIN_SET)
|
||||
case LIT_MAGIC_STRING_SET_UL:
|
||||
#endif /* ENABLED (JERRY_BUILTIN_SET) */
|
||||
#if ENABLED (JERRY_BUILTIN_WEAKMAP)
|
||||
case LIT_MAGIC_STRING_WEAKMAP_UL:
|
||||
#endif /* ENABLED (JERRY_BUILTIN_WEAKMAP) */
|
||||
#if ENABLED (JERRY_BUILTIN_WEAKSET)
|
||||
case LIT_MAGIC_STRING_WEAKSET_UL:
|
||||
#endif /* ENABLED (JERRY_BUILTIN_WEAKSET) */
|
||||
{
|
||||
return JERRY_OBJECT_TYPE_CONTAINER;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_BUILTIN_CONTAINER) */
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return JERRY_OBJECT_TYPE_GENERIC;
|
||||
} /* jerry_object_get_type */
|
||||
|
||||
/**
|
||||
* Get the function type of the given value
|
||||
*
|
||||
* @return JERRY_FUNCTION_TYPE_NONE - if the given value is not a function object
|
||||
* jerry_function_type_t value - otherwise
|
||||
*/
|
||||
jerry_function_type_t
|
||||
jerry_function_get_type (const jerry_value_t value) /**< input value to check */
|
||||
{
|
||||
jerry_assert_api_available ();
|
||||
|
||||
if (ecma_is_value_object (value))
|
||||
{
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (value);
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
|
||||
|
||||
switch (ecma_get_object_type (obj_p))
|
||||
{
|
||||
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
|
||||
{
|
||||
return JERRY_FUNCTION_TYPE_BOUND;
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
|
||||
{
|
||||
return JERRY_FUNCTION_TYPE_GENERIC;
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_FUNCTION:
|
||||
{
|
||||
if (!ecma_get_object_is_builtin (obj_p))
|
||||
{
|
||||
const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_obj_p);
|
||||
|
||||
switch (CBC_FUNCTION_GET_TYPE (bytecode_data_p->status_flags))
|
||||
{
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
case CBC_FUNCTION_ARROW:
|
||||
case CBC_FUNCTION_ASYNC_ARROW:
|
||||
{
|
||||
return JERRY_FUNCTION_TYPE_ARROW;
|
||||
}
|
||||
case CBC_FUNCTION_GENERATOR:
|
||||
case CBC_FUNCTION_ASYNC_GENERATOR:
|
||||
{
|
||||
return JERRY_FUNCTION_TYPE_GENERATOR;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
case CBC_FUNCTION_ACCESSOR:
|
||||
{
|
||||
return JERRY_FUNCTION_TYPE_ACCESSOR;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return JERRY_FUNCTION_TYPE_GENERIC;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return JERRY_FUNCTION_TYPE_NONE;
|
||||
} /* jerry_function_get_type */
|
||||
|
||||
/**
|
||||
* Get the itearator type of the given value
|
||||
*
|
||||
* @return JERRY_ITERATOR_TYPE_NONE - if the given value is not an iterator object
|
||||
* jerry_iterator_type_t value - otherwise
|
||||
*/
|
||||
jerry_iterator_type_t
|
||||
jerry_iterator_get_type (const jerry_value_t value) /**< input value to check */
|
||||
{
|
||||
jerry_assert_api_available ();
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
if (ecma_is_value_object (value))
|
||||
{
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (value);
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
|
||||
|
||||
if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_PSEUDO_ARRAY)
|
||||
{
|
||||
switch (ext_obj_p->u.pseudo_array.type)
|
||||
{
|
||||
case ECMA_PSEUDO_ARRAY_ITERATOR:
|
||||
{
|
||||
return JERRY_ITERATOR_TYPE_ARRAY;
|
||||
}
|
||||
case ECMA_PSEUDO_STRING_ITERATOR:
|
||||
{
|
||||
return JERRY_ITERATOR_TYPE_STRING;
|
||||
}
|
||||
#if ENABLED (JERRY_BUILTIN_MAP)
|
||||
case ECMA_PSEUDO_MAP_ITERATOR:
|
||||
{
|
||||
return JERRY_ITERATOR_TYPE_MAP;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_BUILTIN_MAP) */
|
||||
#if ENABLED (JERRY_BUILTIN_SET)
|
||||
case ECMA_PSEUDO_SET_ITERATOR:
|
||||
{
|
||||
return JERRY_ITERATOR_TYPE_SET;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_BUILTIN_SET) */
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else /* !ENABLED (JERRY_ESNEXT) */
|
||||
JERRY_UNUSED (value);
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
return JERRY_ITERATOR_TYPE_NONE;
|
||||
} /* jerry_iterator_get_type */
|
||||
|
||||
/**
|
||||
* Check if the specified feature is enabled.
|
||||
*
|
||||
|
||||
@@ -381,6 +381,7 @@ bool jerry_value_is_boolean (const jerry_value_t value);
|
||||
bool jerry_value_is_constructor (const jerry_value_t value);
|
||||
bool jerry_value_is_error (const jerry_value_t value);
|
||||
bool jerry_value_is_function (const jerry_value_t value);
|
||||
bool jerry_value_is_async_function (const jerry_value_t value);
|
||||
bool jerry_value_is_number (const jerry_value_t value);
|
||||
bool jerry_value_is_null (const jerry_value_t value);
|
||||
bool jerry_value_is_object (const jerry_value_t value);
|
||||
@@ -408,7 +409,60 @@ typedef enum
|
||||
JERRY_TYPE_SYMBOL, /**< symbol type */
|
||||
} jerry_type_t;
|
||||
|
||||
/**
|
||||
* JerryScript object type information.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
JERRY_OBJECT_TYPE_NONE = 0u, /**< Non object type */
|
||||
JERRY_OBJECT_TYPE_GENERIC, /**< Generic JavaScript object without any internal property */
|
||||
JERRY_OBJECT_TYPE_ARRAY, /**< Array object */
|
||||
JERRY_OBJECT_TYPE_PROXY, /**< Proxy object */
|
||||
JERRY_OBJECT_TYPE_FUNCTION, /**< Function object (see jerry_function_get_type) */
|
||||
JERRY_OBJECT_TYPE_TYPEDARRAY, /**< %TypedArray% object (see jerry_get_typedarray_type) */
|
||||
JERRY_OBJECT_TYPE_ITERATOR, /**< Iterator object (see jerry_iterator_get_type) */
|
||||
JERRY_OBJECT_TYPE_CONTAINER, /**< Container object (see jerry_container_get_type) */
|
||||
|
||||
JERRY_OBJECT_TYPE_ARGUMENTS, /**< Arguments object */
|
||||
JERRY_OBJECT_TYPE_BOOLEAN, /**< Boolean object */
|
||||
JERRY_OBJECT_TYPE_DATE, /**< Date object */
|
||||
JERRY_OBJECT_TYPE_NUMBER, /**< Number object */
|
||||
JERRY_OBJECT_TYPE_REGEXP, /**< RegExp object */
|
||||
JERRY_OBJECT_TYPE_STRING, /**< String object */
|
||||
JERRY_OBJECT_TYPE_SYMBOL, /**< Symbol object */
|
||||
JERRY_OBJECT_TYPE_GENERATOR, /**< Generator object */
|
||||
JERRY_OBJECT_TYPE_BIGINT, /**< BigInt object */
|
||||
} jerry_object_type_t;
|
||||
|
||||
/**
|
||||
* JerryScript function object type information.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
JERRY_FUNCTION_TYPE_NONE = 0u, /**< Non function type */
|
||||
JERRY_FUNCTION_TYPE_GENERIC, /**< Generic JavaScript function */
|
||||
JERRY_FUNCTION_TYPE_ACCESSOR, /**< Accessor function */
|
||||
JERRY_FUNCTION_TYPE_BOUND, /**< Bound function */
|
||||
JERRY_FUNCTION_TYPE_ARROW, /**< Arrow fuction */
|
||||
JERRY_FUNCTION_TYPE_GENERATOR, /**< Generator function */
|
||||
} jerry_function_type_t;
|
||||
|
||||
/**
|
||||
* JerryScript iterator object type information.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
JERRY_ITERATOR_TYPE_NONE = 0u, /**< Non iterator type */
|
||||
JERRY_ITERATOR_TYPE_ARRAY, /**< Array iterator */
|
||||
JERRY_ITERATOR_TYPE_STRING, /**< String iterator */
|
||||
JERRY_ITERATOR_TYPE_MAP, /**< Map iterator */
|
||||
JERRY_ITERATOR_TYPE_SET, /**< Set iterator */
|
||||
} jerry_iterator_type_t;
|
||||
|
||||
jerry_type_t jerry_value_get_type (const jerry_value_t value);
|
||||
jerry_object_type_t jerry_object_get_type (const jerry_value_t value);
|
||||
jerry_function_type_t jerry_function_get_type (const jerry_value_t value);
|
||||
jerry_iterator_type_t jerry_iterator_get_type (const jerry_value_t value);
|
||||
|
||||
/**
|
||||
* Checker function of whether the specified compile feature is enabled.
|
||||
|
||||
@@ -1313,12 +1313,7 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
byte_code_p = (uint8_t *) compiled_code_p;
|
||||
compiled_code_p->size = (uint16_t) (total_size >> JMEM_ALIGNMENT_LOG);
|
||||
compiled_code_p->refs = 1;
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
compiled_code_p->status_flags = 0;
|
||||
#else /* !ENABLED (JERRY_ESNEXT) */
|
||||
compiled_code_p->status_flags = CBC_FUNCTION_TO_TYPE_BITS (CBC_FUNCTION_NORMAL);
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
if (context_p->status_flags & PARSER_FUNCTION_HAS_REST_PARAM)
|
||||
@@ -1396,13 +1391,13 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
compiled_code_p->status_flags |= CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED;
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
uint16_t function_type = CBC_FUNCTION_TO_TYPE_BITS (CBC_FUNCTION_NORMAL);
|
||||
|
||||
if (context_p->status_flags & (PARSER_IS_PROPERTY_GETTER | PARSER_IS_PROPERTY_SETTER))
|
||||
{
|
||||
function_type = CBC_FUNCTION_TO_TYPE_BITS (CBC_FUNCTION_ACCESSOR);
|
||||
}
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
else if (context_p->status_flags & PARSER_IS_ARROW_FUNCTION)
|
||||
{
|
||||
if (context_p->status_flags & PARSER_IS_ASYNC_FUNCTION)
|
||||
@@ -1442,8 +1437,6 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
function_type = CBC_FUNCTION_TO_TYPE_BITS (CBC_FUNCTION_NORMAL);
|
||||
}
|
||||
|
||||
compiled_code_p->status_flags |= function_type;
|
||||
|
||||
if (context_p->status_flags & PARSER_FUNCTION_HAS_REST_PARAM)
|
||||
{
|
||||
compiled_code_p->status_flags |= CBC_CODE_FLAGS_REST_PARAMETER;
|
||||
@@ -1461,6 +1454,8 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
compiled_code_p->status_flags |= function_type;
|
||||
|
||||
literal_pool_p = ((ecma_value_t *) byte_code_p) - context_p->register_count;
|
||||
byte_code_p += literal_length;
|
||||
dst_p = byte_code_p;
|
||||
|
||||
Reference in New Issue
Block a user