Add C API to query the type of a JS value (#2195)
New API function: * jerry_value_get_type JerryScript-DCO-1.0-Signed-off-by: Peter Gal pgal.u-szeged@partner.samsung.com
This commit is contained in:
@@ -11,6 +11,19 @@ Enum that contains the following elements:
|
||||
- JERRY_INIT_MEM_STATS_SEPARATE - dump memory statistics and reset peak values after parse
|
||||
- JERRY_INIT_DEBUGGER - deprecated, an unused placeholder now
|
||||
|
||||
## jerry_type_t
|
||||
|
||||
Enum that contains a set of elements to represent JavaScript type:
|
||||
|
||||
- JERRY_TYPE_NONE - no type information
|
||||
- JERRY_TYPE_UNDEFINED - undefined value
|
||||
- JERRY_TYPE_NULL - null value
|
||||
- JERRY_TYPE_BOOLEAN - boolean value
|
||||
- JERRY_TYPE_NUMBER - number value
|
||||
- JERRY_TYPE_STRING - string value
|
||||
- JERRY_TYPE_OBJECT - object value
|
||||
- JERRY_TYPE_FUNCTION - function value
|
||||
|
||||
## jerry_error_t
|
||||
|
||||
Possible types of an error:
|
||||
@@ -1447,6 +1460,44 @@ jerry_value_is_undefined (const jerry_value_t value)
|
||||
|
||||
- [jerry_release_value](#jerry_release_value)
|
||||
|
||||
## jerry_value_get_type
|
||||
|
||||
**Summary**
|
||||
|
||||
Returns the JavaScript type
|
||||
for a given value as a [jerry_type_t](#jerry_type_t) enum value.
|
||||
|
||||
This is a similar operation as the 'typeof' operator
|
||||
in the standard with an exception that the 'null'
|
||||
value has its own enum value.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
jerry_type_t
|
||||
jerry_value_get_type (const jerry_value_t value);
|
||||
```
|
||||
|
||||
**Example**
|
||||
|
||||
```c
|
||||
{
|
||||
jerry_value_t number = jerry_create_number (3.3);
|
||||
|
||||
jerry_type_t type_info = jerry_value_get_type (number);
|
||||
|
||||
if (type_info == JERRY_TYPE_NUMBER)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
jerry_value_release (number);
|
||||
}
|
||||
```
|
||||
|
||||
**See also**
|
||||
- [jerry_type_t](#jerry_type_t)
|
||||
|
||||
## jerry_is_feature_enabled
|
||||
|
||||
**Summary**
|
||||
|
||||
@@ -766,6 +766,60 @@ jerry_value_is_undefined (const jerry_value_t value) /**< api value */
|
||||
return ecma_is_value_undefined (jerry_get_arg_value (value));
|
||||
} /* jerry_value_is_undefined */
|
||||
|
||||
/**
|
||||
* Perform the base type of the JavaScript value.
|
||||
*
|
||||
* @return jerry_type_t value
|
||||
*/
|
||||
jerry_type_t
|
||||
jerry_value_get_type (const jerry_value_t value) /**< input value to check */
|
||||
{
|
||||
jerry_assert_api_available ();
|
||||
|
||||
jerry_value_t argument = jerry_get_arg_value (value);
|
||||
lit_magic_string_id_t lit_id = ecma_get_typeof_lit_id (argument);
|
||||
|
||||
JERRY_ASSERT (lit_id != LIT_MAGIC_STRING__EMPTY);
|
||||
|
||||
switch (lit_id)
|
||||
{
|
||||
case LIT_MAGIC_STRING_UNDEFINED:
|
||||
{
|
||||
return JERRY_TYPE_UNDEFINED;
|
||||
}
|
||||
case LIT_MAGIC_STRING_BOOLEAN:
|
||||
{
|
||||
return JERRY_TYPE_BOOLEAN;
|
||||
}
|
||||
case LIT_MAGIC_STRING_NUMBER:
|
||||
{
|
||||
return JERRY_TYPE_NUMBER;
|
||||
}
|
||||
case LIT_MAGIC_STRING_STRING:
|
||||
{
|
||||
return JERRY_TYPE_STRING;
|
||||
}
|
||||
case LIT_MAGIC_STRING_FUNCTION:
|
||||
{
|
||||
return JERRY_TYPE_FUNCTION;
|
||||
}
|
||||
case LIT_MAGIC_STRING_OBJECT:
|
||||
{
|
||||
/* Based on the ECMA 262 5.1 standard the 'null' value is an object.
|
||||
* Thus we'll do an extra check for 'null' here.
|
||||
*/
|
||||
return ecma_is_value_null (argument) ? JERRY_TYPE_NULL : JERRY_TYPE_OBJECT;
|
||||
}
|
||||
default:
|
||||
{
|
||||
JERRY_UNREACHABLE ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return JERRY_TYPE_NONE;
|
||||
} /* jerry_value_get_type */
|
||||
|
||||
/**
|
||||
* Check if the specified feature is enabled.
|
||||
*
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include "jrt-bit-fields.h"
|
||||
#include "vm-defines.h"
|
||||
|
||||
#include "ecma-function-object.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
@@ -917,6 +919,55 @@ ecma_free_value_if_not_object (ecma_value_t value) /**< value description */
|
||||
}
|
||||
} /* ecma_free_value_if_not_object */
|
||||
|
||||
/**
|
||||
* Get the literal id associated with the given ecma_value type.
|
||||
* This operation is equivalent to the JavaScript 'typeof' operator.
|
||||
*
|
||||
* @returns one of the following value:
|
||||
* - LIT_MAGIC_STRING_UNDEFINED
|
||||
* - LIT_MAGIC_STRING_OBJECT
|
||||
* - LIT_MAGIC_STRING_BOOLEAN
|
||||
* - LIT_MAGIC_STRING_NUMBER
|
||||
* - LIT_MAGIC_STRING_STRING
|
||||
* - LIT_MAGIC_STRING_FUNCTION
|
||||
*/
|
||||
lit_magic_string_id_t
|
||||
ecma_get_typeof_lit_id (ecma_value_t value) /**< input ecma value */
|
||||
{
|
||||
lit_magic_string_id_t ret_value = LIT_MAGIC_STRING__EMPTY;
|
||||
|
||||
if (ecma_is_value_undefined (value))
|
||||
{
|
||||
ret_value = LIT_MAGIC_STRING_UNDEFINED;
|
||||
}
|
||||
else if (ecma_is_value_null (value))
|
||||
{
|
||||
ret_value = LIT_MAGIC_STRING_OBJECT;
|
||||
}
|
||||
else if (ecma_is_value_boolean (value))
|
||||
{
|
||||
ret_value = LIT_MAGIC_STRING_BOOLEAN;
|
||||
}
|
||||
else if (ecma_is_value_number (value))
|
||||
{
|
||||
ret_value = LIT_MAGIC_STRING_NUMBER;
|
||||
}
|
||||
else if (ecma_is_value_string (value))
|
||||
{
|
||||
ret_value = LIT_MAGIC_STRING_STRING;
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_object (value));
|
||||
|
||||
ret_value = ecma_op_is_callable (value) ? LIT_MAGIC_STRING_FUNCTION : LIT_MAGIC_STRING_OBJECT;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (ret_value != LIT_MAGIC_STRING__EMPTY);
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_get_typeof_lit_id */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
|
||||
@@ -187,6 +187,7 @@ void ecma_value_assign_number (ecma_value_t *value_p, ecma_number_t ecma_number)
|
||||
void ecma_free_value (ecma_value_t value);
|
||||
void ecma_fast_free_value (ecma_value_t value);
|
||||
void ecma_free_value_if_not_object (ecma_value_t value);
|
||||
lit_magic_string_id_t ecma_get_typeof_lit_id (ecma_value_t value);
|
||||
|
||||
/* ecma-helpers-string.c */
|
||||
ecma_string_t *ecma_new_ecma_string_from_utf8 (const lit_utf8_byte_t *string_p, lit_utf8_size_t string_size);
|
||||
|
||||
@@ -286,6 +286,23 @@ bool jerry_value_is_promise (const jerry_value_t value);
|
||||
bool jerry_value_is_string (const jerry_value_t value);
|
||||
bool jerry_value_is_undefined (const jerry_value_t value);
|
||||
|
||||
/**
|
||||
* JerryScript API value type information.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
JERRY_TYPE_NONE = 0u, /**< no type information */
|
||||
JERRY_TYPE_UNDEFINED, /**< undefined type */
|
||||
JERRY_TYPE_NULL, /**< null type */
|
||||
JERRY_TYPE_BOOLEAN, /**< boolean type */
|
||||
JERRY_TYPE_NUMBER, /**< number type */
|
||||
JERRY_TYPE_STRING, /**< string type */
|
||||
JERRY_TYPE_OBJECT, /**< object type */
|
||||
JERRY_TYPE_FUNCTION, /**< function type */
|
||||
} jerry_type_t;
|
||||
|
||||
jerry_type_t jerry_value_get_type (const jerry_value_t value);
|
||||
|
||||
/**
|
||||
* Checker function of whether the specified compile feature is enabled.
|
||||
*/
|
||||
|
||||
+2
-41
@@ -92,47 +92,8 @@ opfunc_logical_not (ecma_value_t left_value) /**< left value */
|
||||
ecma_value_t
|
||||
opfunc_typeof (ecma_value_t left_value) /**< left value */
|
||||
{
|
||||
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
|
||||
|
||||
ecma_string_t *type_str_p = NULL;
|
||||
|
||||
if (ecma_is_value_undefined (left_value))
|
||||
{
|
||||
type_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_UNDEFINED);
|
||||
}
|
||||
else if (ecma_is_value_null (left_value))
|
||||
{
|
||||
type_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_OBJECT);
|
||||
}
|
||||
else if (ecma_is_value_boolean (left_value))
|
||||
{
|
||||
type_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_BOOLEAN);
|
||||
}
|
||||
else if (ecma_is_value_number (left_value))
|
||||
{
|
||||
type_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_NUMBER);
|
||||
}
|
||||
else if (ecma_is_value_string (left_value))
|
||||
{
|
||||
type_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_STRING);
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_object (left_value));
|
||||
|
||||
if (ecma_op_is_callable (left_value))
|
||||
{
|
||||
type_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_FUNCTION);
|
||||
}
|
||||
else
|
||||
{
|
||||
type_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_OBJECT);
|
||||
}
|
||||
}
|
||||
|
||||
ret_value = ecma_make_string_value (type_str_p);
|
||||
|
||||
return ret_value;
|
||||
ecma_string_t *type_str_p = ecma_get_magic_string (ecma_get_typeof_lit_id (left_value));
|
||||
return ecma_make_string_value (type_str_p);
|
||||
} /* opfunc_typeof */
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-port.h"
|
||||
#include "jerryscript-port-default.h"
|
||||
#include "test-common.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
jerry_type_t type_info;
|
||||
jerry_value_t value;
|
||||
} test_entry_t;
|
||||
|
||||
#define ENTRY(TYPE, VALUE) { TYPE, VALUE }
|
||||
|
||||
static jerry_value_t
|
||||
test_ext_function (const jerry_value_t function_obj, /**< function object */
|
||||
const jerry_value_t this_val, /**< function this value */
|
||||
const jerry_value_t args_p[], /**< array of arguments */
|
||||
const jerry_length_t args_cnt) /**< number of arguments */
|
||||
{
|
||||
(void) function_obj;
|
||||
(void) this_val;
|
||||
(void) args_p;
|
||||
(void) args_cnt;
|
||||
return jerry_create_boolean (true);
|
||||
} /* test_ext_function */
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
TEST_INIT ();
|
||||
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
|
||||
jerry_char_t test_eval_function[] = "function demo(a) { return a + 1; }; demo";
|
||||
|
||||
test_entry_t entries[] =
|
||||
{
|
||||
ENTRY (JERRY_TYPE_NUMBER, jerry_create_number (-33.0)),
|
||||
ENTRY (JERRY_TYPE_NUMBER, jerry_create_number (3)),
|
||||
ENTRY (JERRY_TYPE_NUMBER, jerry_create_number_nan ()),
|
||||
ENTRY (JERRY_TYPE_NUMBER, jerry_create_number_infinity (false)),
|
||||
ENTRY (JERRY_TYPE_NUMBER, jerry_create_number_infinity (true)),
|
||||
|
||||
ENTRY (JERRY_TYPE_BOOLEAN, jerry_create_boolean (true)),
|
||||
ENTRY (JERRY_TYPE_BOOLEAN, jerry_create_boolean (false)),
|
||||
|
||||
ENTRY (JERRY_TYPE_UNDEFINED, jerry_create_undefined ()),
|
||||
|
||||
ENTRY (JERRY_TYPE_OBJECT, jerry_create_object ()),
|
||||
ENTRY (JERRY_TYPE_OBJECT, jerry_create_array (10)),
|
||||
ENTRY (JERRY_TYPE_OBJECT, jerry_create_error (JERRY_ERROR_TYPE, (const jerry_char_t *) "error")),
|
||||
|
||||
ENTRY (JERRY_TYPE_NULL, jerry_create_null ()),
|
||||
|
||||
ENTRY (JERRY_TYPE_FUNCTION, jerry_eval (test_eval_function, strlen ((char *) test_eval_function), false)),
|
||||
ENTRY (JERRY_TYPE_FUNCTION, jerry_create_external_function (test_ext_function)),
|
||||
|
||||
ENTRY (JERRY_TYPE_STRING, jerry_create_string (test_eval_function)),
|
||||
ENTRY (JERRY_TYPE_STRING, jerry_create_string ((jerry_char_t *) "")),
|
||||
};
|
||||
|
||||
for (size_t idx = 0; idx < sizeof (entries) / sizeof (entries[0]); idx++)
|
||||
{
|
||||
jerry_type_t type_info = jerry_value_get_type (entries[idx].value);
|
||||
|
||||
TEST_ASSERT (type_info != JERRY_TYPE_NONE);
|
||||
TEST_ASSERT (type_info == entries[idx].type_info);
|
||||
|
||||
jerry_release_value (entries[idx].value);
|
||||
}
|
||||
|
||||
jerry_cleanup ();
|
||||
|
||||
return 0;
|
||||
} /* main */
|
||||
Reference in New Issue
Block a user