/* 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. */ #ifndef ECMA_GLOBALS_H #define ECMA_GLOBALS_H #include "config.h" #include "jrt.h" #include "lit-magic-strings.h" #include "jmem.h" /** \addtogroup ecma ECMA * @{ * * \addtogroup ecmatypes ECMA types * @{ * * \addtogroup compressedpointer Compressed pointer * @{ */ /** * The NULL value for compressed pointers */ #define ECMA_NULL_POINTER JMEM_CP_NULL #if defined (JMEM_CAN_STORE_POINTER_VALUE_DIRECTLY) /** * JMEM_ALIGNMENT_LOG aligned pointers can be stored directly in ecma_value_t */ #define ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY #endif /* JMEM_CAN_STORE_POINTER_VALUE_DIRECTLY */ /** * @} */ /** * JerryScript init flags. */ typedef enum { ECMA_INIT_EMPTY = (0u), /**< empty flag set */ ECMA_INIT_SHOW_OPCODES = (1u << 0), /**< dump byte-code to log after parse */ ECMA_INIT_SHOW_REGEXP_OPCODES = (1u << 1), /**< dump regexp byte-code to log after compilation */ ECMA_INIT_MEM_STATS = (1u << 2), /**< dump memory statistics */ } ecma_init_flag_t; /** * JerryScript status flags. */ typedef enum { ECMA_STATUS_API_AVAILABLE = (1u << 0), /**< api available */ ECMA_STATUS_DIRECT_EVAL = (1u << 1), /**< eval is called directly */ #if ENABLED (JERRY_PROPRETY_HASHMAP) ECMA_STATUS_HIGH_PRESSURE_GC = (1u << 2), /**< last gc was under high pressure */ #endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ ECMA_STATUS_EXCEPTION = (1u << 3), /**< last exception is a normal exception */ ECMA_STATUS_ABORT = (1u << 4), /**< last exception is an abort */ } ecma_status_flag_t; /** * Type of ecma value */ typedef enum { ECMA_TYPE_DIRECT = 0, /**< directly encoded value, a 28 bit signed integer or a simple value */ ECMA_TYPE_STRING = 1, /**< pointer to description of a string */ ECMA_TYPE_FLOAT = 2, /**< pointer to a 64 or 32 bit floating point number */ ECMA_TYPE_OBJECT = 3, /**< pointer to description of an object */ ECMA_TYPE_SYMBOL = 4, /**< pointer to description of a symbol */ ECMA_TYPE_DIRECT_STRING = 5, /**< directly encoded string values */ ECMA_TYPE_ERROR = 7, /**< pointer to description of an error reference (only supported by C API) */ ECMA_TYPE_SNAPSHOT_OFFSET = ECMA_TYPE_ERROR, /**< offset to a snapshot number/string */ ECMA_TYPE___MAX = ECMA_TYPE_ERROR /** highest value for ecma types */ } ecma_type_t; #if ENABLED (JERRY_DEBUGGER) /** * Shift for scope chain index part in ecma_parse_opts */ #define ECMA_PARSE_CHAIN_INDEX_SHIFT 16 #endif /* ENABLED (JERRY_DEBUGGER) */ /** * Option flags for parser_parse_script and internal flags for global_status_flags in parser context. * Note: * the last 16 bits is reserved for internal parser flags, because the debugger uses these * 16 bits to encode the scope chain skip index as well (see ECMA_PARSE_CHAIN_INDEX_SHIFT) */ typedef enum { ECMA_PARSE_NO_OPTS = 0, /**< no options passed */ ECMA_PARSE_STRICT_MODE = (1u << 0), /**< enable strict mode, must be same as PARSER_IS_STRICT */ ECMA_PARSE_MODULE = (1u << 1), /**< module is parsed */ ECMA_PARSE_EVAL = (1u << 2), /**< eval is called */ ECMA_PARSE_DIRECT_EVAL = (1u << 3), /**< eval is called directly (ECMA-262 v5, 15.1.2.1.1) */ ECMA_PARSE_CLASS_CONSTRUCTOR = (1u << 4), /**< a class constructor is being parsed */ /* These four status flags must be in this order. The first three are also parser status flags. * See PARSER_SAVE_STATUS_FLAGS / PARSER_RESTORE_STATUS_FLAGS. */ ECMA_PARSE_ALLOW_SUPER = (1u << 5), /**< allow super property access */ ECMA_PARSE_ALLOW_SUPER_CALL = (1u << 6), /**< allow super constructor call */ ECMA_PARSE_ALLOW_NEW_TARGET = (1u << 7), /**< allow new.target access */ ECMA_PARSE_FUNCTION_CONTEXT = (1u << 8), /**< function context is present (ECMA_PARSE_DIRECT_EVAL must be set) */ ECMA_PARSE_GENERATOR_FUNCTION = (1u << 9), /**< generator function is parsed */ /* These flags are internally used by the parser. */ #ifndef JERRY_NDEBUG /** * This flag represents an error in for in/of statements, which cannot be set * if the parsing is completed successfully. */ ECMA_PARSE_INTERNAL_FOR_IN_OFF_CONTEXT_ERROR = (1u << 30), #endif /* !JERRY_NDEBUG */ } ecma_parse_opts_t; /** * Description of an ecma value * * Bit-field structure: type (3) | value (29) */ typedef uint32_t ecma_value_t; /** * Type for directly encoded integer numbers in JerryScript. */ typedef int32_t ecma_integer_value_t; /** * Mask for ecma types in ecma_value_t */ #define ECMA_VALUE_TYPE_MASK 0x7u /** * Shift for value part in ecma_value_t */ #define ECMA_VALUE_SHIFT 3 /** * Mask for directly encoded values */ #define ECMA_DIRECT_TYPE_MASK ((1u << ECMA_VALUE_SHIFT) | ECMA_VALUE_TYPE_MASK) /** * Ecma integer value type */ #define ECMA_DIRECT_TYPE_INTEGER_VALUE ((0u << ECMA_VALUE_SHIFT) | ECMA_TYPE_DIRECT) /** * Ecma simple value type */ #define ECMA_DIRECT_TYPE_SIMPLE_VALUE ((1u << ECMA_VALUE_SHIFT) | ECMA_TYPE_DIRECT) /** * Shift for directly encoded values in ecma_value_t */ #define ECMA_DIRECT_SHIFT 4 /** * ECMA make simple value */ #define ECMA_MAKE_VALUE(value) \ ((((ecma_value_t) (value)) << ECMA_DIRECT_SHIFT) | ECMA_DIRECT_TYPE_SIMPLE_VALUE) /** * Simple ecma values */ enum { /** * Empty value is implementation defined value, used for representing: * - empty (uninitialized) values * - immutable binding values * - special register or stack values for vm */ ECMA_VALUE_EMPTY = ECMA_MAKE_VALUE (0), /**< uninitialized value */ ECMA_VALUE_ERROR = ECMA_MAKE_VALUE (1), /**< an error is currently thrown */ ECMA_VALUE_FALSE = ECMA_MAKE_VALUE (2), /**< boolean false */ ECMA_VALUE_TRUE = ECMA_MAKE_VALUE (3), /**< boolean true */ ECMA_VALUE_UNDEFINED = ECMA_MAKE_VALUE (4), /**< undefined value */ ECMA_VALUE_NULL = ECMA_MAKE_VALUE (5), /**< null value */ ECMA_VALUE_ARRAY_HOLE = ECMA_MAKE_VALUE (6), /**< array hole, used for * initialization of an array literal */ ECMA_VALUE_NOT_FOUND = ECMA_MAKE_VALUE (7), /**< a special value returned by * ecma_op_object_find */ ECMA_VALUE_REGISTER_REF = ECMA_MAKE_VALUE (8), /**< register reference, * a special "base" value for vm */ ECMA_VALUE_RELEASE_LEX_ENV = ECMA_MAKE_VALUE (9), /**< if this error remains on the stack when an exception occours the top lexical environment of the VM frame should be popped */ ECMA_VALUE_UNINITIALIZED = ECMA_MAKE_VALUE (10), /**< a special value for uninitialized let/const declarations */ ECMA_VALUE_SPREAD_ELEMENT = ECMA_MAKE_VALUE (11), /**< a special value for spread elements in array initialization * or function call argument list */ }; #if !ENABLED (JERRY_NUMBER_TYPE_FLOAT64) /** * Maximum integer number for an ecma value */ #define ECMA_INTEGER_NUMBER_MAX 0x7fffff /** * Maximum integer number for an ecma value (shifted left with ECMA_DIRECT_SHIFT) */ #define ECMA_INTEGER_NUMBER_MAX_SHIFTED 0x7fffff0 #else /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ /** * Maximum integer number for an ecma value */ #define ECMA_INTEGER_NUMBER_MAX 0x7ffffff /** * Maximum integer number for an ecma value (shifted left with ECMA_DIRECT_SHIFT) */ #define ECMA_INTEGER_NUMBER_MAX_SHIFTED 0x7ffffff0 #endif /* !ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ #if !ENABLED (JERRY_NUMBER_TYPE_FLOAT64) /** * Minimum integer number for an ecma value */ #define ECMA_INTEGER_NUMBER_MIN -0x7fffff /** * Minimum integer number for an ecma value (shifted left with ECMA_DIRECT_SHIFT) */ #define ECMA_INTEGER_NUMBER_MIN_SHIFTED -0x7fffff0 #else /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ /** * Minimum integer number for an ecma value */ #define ECMA_INTEGER_NUMBER_MIN -0x8000000 /** * Minimum integer number for an ecma value (shifted left with ECMA_DIRECT_SHIFT) */ #define ECMA_INTEGER_NUMBER_MIN_SHIFTED (-0x7fffffff - 1) /* -0x80000000 */ #endif /* !ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ #if ECMA_DIRECT_SHIFT != 4 #error "Please update ECMA_INTEGER_NUMBER_MIN/MAX_SHIFTED according to the new value of ECMA_DIRECT_SHIFT." #endif /** * Checks whether the integer number is in the integer number range. */ #define ECMA_IS_INTEGER_NUMBER(num) \ (ECMA_INTEGER_NUMBER_MIN <= (num) && (num) <= ECMA_INTEGER_NUMBER_MAX) /** * Maximum integer number, which if squared, still fits in ecma_integer_value_t */ #if !ENABLED (JERRY_NUMBER_TYPE_FLOAT64) #define ECMA_INTEGER_MULTIPLY_MAX 0xb50 #else /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ #define ECMA_INTEGER_MULTIPLY_MAX 0x2d41 #endif /* !ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ /** * Checks whether the error flag is set. */ #define ECMA_IS_VALUE_ERROR(value) \ (JERRY_UNLIKELY ((value) == ECMA_VALUE_ERROR)) /** * Callback which tells whether the ECMAScript execution should be stopped. */ typedef ecma_value_t (*ecma_vm_exec_stop_callback_t) (void *user_p); /** * Type of an external function handler. */ typedef ecma_value_t (*ecma_external_handler_t) (const ecma_value_t function_obj, const ecma_value_t this_val, const ecma_value_t args_p[], const ecma_length_t args_count); /** * Native free callback of an object. */ typedef void (*ecma_object_native_free_callback_t) (void *native_p); /** * Type information of a native pointer. */ typedef struct { ecma_object_native_free_callback_t free_cb; /**< the free callback of the native pointer */ } ecma_object_native_info_t; /** * Representation for native pointer data. */ typedef struct ecma_native_pointer_t { void *data_p; /**< points to the data of the object */ ecma_object_native_info_t *info_p; /**< native info */ struct ecma_native_pointer_t *next_p; /**< points to the next ecma_native_pointer_t element */ } ecma_native_pointer_t; /** * Property list: * The property list of an object is a chain list of various items. * The type of each item is stored in the first byte of the item. * * The most common item is the property pair, which contains two * ecmascript properties. It is also important, that after the * first property pair, only property pair items are allowed. * * Example for other items is property name hash map, or array of items. */ /** * Property type list. */ typedef enum { ECMA_PROPERTY_TYPE_SPECIAL, /**< special purpose property (deleted / hashmap) */ ECMA_PROPERTY_TYPE_NAMEDDATA, /**< property is named data */ ECMA_PROPERTY_TYPE_NAMEDACCESSOR, /**< property is named accessor */ ECMA_PROPERTY_TYPE_INTERNAL, /**< internal property with custom data field */ ECMA_PROPERTY_TYPE_VIRTUAL = ECMA_PROPERTY_TYPE_INTERNAL, /**< property is virtual data property */ ECMA_PROPERTY_TYPE__MAX = ECMA_PROPERTY_TYPE_VIRTUAL, /**< highest value for property types. */ } ecma_property_types_t; /** * Property name listing options. */ typedef enum { ECMA_LIST_NO_OPTS = (0), /**< no options are provided */ ECMA_LIST_ARRAY_INDICES = (1 << 0), /**< exclude properties with names * that are not indices */ ECMA_LIST_ENUMERABLE = (1 << 1), /**< exclude non-enumerable properties */ ECMA_LIST_PROTOTYPE = (1 << 2), /**< list properties from prototype chain */ #if ENABLED (JERRY_ES2015) ECMA_LIST_SYMBOLS = (1 << 3), /**< list symbol properties */ ECMA_LIST_SYMBOLS_ONLY = (1 << 4), /**< list symbol properties only */ #endif /* ENABLED (JERRY_ES2015) */ ECMA_LIST_CONVERT_FAST_ARRAYS = (1 << 5), /**< after listing the properties convert * the fast access mode array back to normal array */ } ecma_list_properties_options_t; /** * List enumerable properties and include the prototype chain. */ #define ECMA_LIST_ENUMERABLE_PROTOTYPE (ECMA_LIST_ENUMERABLE | ECMA_LIST_PROTOTYPE) /** * Property type mask. */ #define ECMA_PROPERTY_TYPE_MASK 0x3 /** * Property flags base shift. */ #define ECMA_PROPERTY_FLAG_SHIFT 2 /** * Property flag list (for ECMA_PROPERTY_TYPE_NAMEDDATA * and ECMA_PROPERTY_TYPE_NAMEDACCESSOR). */ typedef enum { ECMA_PROPERTY_FLAG_CONFIGURABLE = 1u << (ECMA_PROPERTY_FLAG_SHIFT + 0), /**< property is configurable */ ECMA_PROPERTY_FLAG_ENUMERABLE = 1u << (ECMA_PROPERTY_FLAG_SHIFT + 1), /**< property is enumerable */ ECMA_PROPERTY_FLAG_WRITABLE = 1u << (ECMA_PROPERTY_FLAG_SHIFT + 2), /**< property is writable */ ECMA_PROPERTY_FLAG_LCACHED = 1u << (ECMA_PROPERTY_FLAG_SHIFT + 3), /**< property is lcached */ } ecma_property_flags_t; /** * Property flags configurable, enumerable, writable. */ #define ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE \ (ECMA_PROPERTY_FLAG_CONFIGURABLE | ECMA_PROPERTY_FLAG_ENUMERABLE | ECMA_PROPERTY_FLAG_WRITABLE) /** * Property flags configurable, enumerable. */ #define ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE \ (ECMA_PROPERTY_FLAG_CONFIGURABLE | ECMA_PROPERTY_FLAG_ENUMERABLE) /** * Property flags configurable, enumerable. */ #define ECMA_PROPERTY_CONFIGURABLE_WRITABLE \ (ECMA_PROPERTY_FLAG_CONFIGURABLE | ECMA_PROPERTY_FLAG_WRITABLE) /** * Property flags enumerable, writable. */ #define ECMA_PROPERTY_ENUMERABLE_WRITABLE \ (ECMA_PROPERTY_FLAG_ENUMERABLE | ECMA_PROPERTY_FLAG_WRITABLE) /** * No attributes can be changed for this property. */ #define ECMA_PROPERTY_FIXED 0 /** * Default flag of length property. */ #if ENABLED (JERRY_ES2015) #define ECMA_PROPERTY_FLAG_DEFAULT_LENGTH ECMA_PROPERTY_FLAG_CONFIGURABLE #else /* !ENABLED (JERRY_ES2015) */ #define ECMA_PROPERTY_FLAG_DEFAULT_LENGTH ECMA_PROPERTY_FIXED #endif /* ENABLED (JERRY_ES2015) */ /** * Shift for property name part. */ #define ECMA_PROPERTY_NAME_TYPE_SHIFT (ECMA_PROPERTY_FLAG_SHIFT + 4) /** * Convert data property to internal property. */ #define ECMA_CONVERT_DATA_PROPERTY_TO_INTERNAL_PROPERTY(property_p) \ *(property_p) = (uint8_t) (*(property_p) + (ECMA_PROPERTY_TYPE_INTERNAL - ECMA_PROPERTY_TYPE_NAMEDDATA)) /** * Convert internal property to data property. */ #define ECMA_CONVERT_INTERNAL_PROPERTY_TO_DATA_PROPERTY(property_p) \ *(property_p) = (uint8_t) (*(property_p) - (ECMA_PROPERTY_TYPE_INTERNAL - ECMA_PROPERTY_TYPE_NAMEDDATA)) /** * Special property identifiers. */ typedef enum { /* Note: when new special types are added * ECMA_PROPERTY_IS_PROPERTY_PAIR must be updated as well. */ ECMA_SPECIAL_PROPERTY_HASHMAP, /**< hashmap property */ ECMA_SPECIAL_PROPERTY_DELETED, /**< deleted property */ ECMA_SPECIAL_PROPERTY__COUNT /**< Number of special property types */ } ecma_special_property_id_t; /** * Define special property type. */ #define ECMA_SPECIAL_PROPERTY_VALUE(type) \ ((uint8_t) (ECMA_PROPERTY_TYPE_SPECIAL | ((type) << ECMA_PROPERTY_NAME_TYPE_SHIFT))) /** * Type of deleted property. */ #define ECMA_PROPERTY_TYPE_DELETED ECMA_SPECIAL_PROPERTY_VALUE (ECMA_SPECIAL_PROPERTY_DELETED) /** * Type of hash-map property. */ #define ECMA_PROPERTY_TYPE_HASHMAP ECMA_SPECIAL_PROPERTY_VALUE (ECMA_SPECIAL_PROPERTY_HASHMAP) /** * Type of property not found. */ #define ECMA_PROPERTY_TYPE_NOT_FOUND ECMA_PROPERTY_TYPE_HASHMAP /** * Type of property not found and no more searching in the proto chain. */ #define ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP ECMA_PROPERTY_TYPE_DELETED /** * Abstract property representation. * * A property is a type_and_flags byte and an ecma_value_t value pair. * This pair is represented by a single pointer in JerryScript. Although * a packed struct would only consume sizeof(ecma_value_t)+1 memory * bytes, accessing such structure is inefficient from the CPU viewpoint * because the value is not naturally aligned. To improve performance, * two type bytes and values are packed together. The memory layout is * the following: * * [type 1, type 2, unused byte 1, unused byte 2][value 1][value 2] * * The unused two bytes are used to store a compressed pointer for the * next property pair. * * The advantage of this layout is that the value reference can be computed * from the property address. However, property pointers cannot be compressed * anymore. */ typedef uint8_t ecma_property_t; /**< ecma_property_types_t (3 bit) and ecma_property_flags_t */ /** * Number of items in a property pair. */ #define ECMA_PROPERTY_PAIR_ITEM_COUNT 2 /** * Property header for all items in a property list. */ typedef struct { #if ENABLED (JERRY_CPOINTER_32_BIT) jmem_cpointer_t next_property_cp; /**< next cpointer */ #endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ ecma_property_t types[ECMA_PROPERTY_PAIR_ITEM_COUNT]; /**< two property type slot. The first represent * the type of this property (e.g. property pair) */ #if ENABLED (JERRY_CPOINTER_32_BIT) uint16_t padding; /**< an unused value */ #else /* !ENABLED (JERRY_CPOINTER_32_BIT) */ jmem_cpointer_t next_property_cp; /**< next cpointer */ #endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ } ecma_property_header_t; /** * Pair of pointers - to property's getter and setter */ typedef struct { jmem_cpointer_t getter_cp; /**< compressed pointer to getter object */ jmem_cpointer_t setter_cp; /**< compressed pointer to setter object */ } ecma_getter_setter_pointers_t; /** * Property data. */ typedef union { ecma_value_t value; /**< value of a property */ #if ENABLED (JERRY_CPOINTER_32_BIT) jmem_cpointer_t getter_setter_pair_cp; /**< cpointer to getter setter pair */ #else /* !ENABLED (JERRY_CPOINTER_32_BIT) */ ecma_getter_setter_pointers_t getter_setter_pair; /**< getter setter pair */ #endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ } ecma_property_value_t; /** * Property pair. */ typedef struct { ecma_property_header_t header; /**< header of the property */ ecma_property_value_t values[ECMA_PROPERTY_PAIR_ITEM_COUNT]; /**< property value slots */ jmem_cpointer_t names_cp[ECMA_PROPERTY_PAIR_ITEM_COUNT]; /**< property name slots */ } ecma_property_pair_t; /** * Get property type. */ #define ECMA_PROPERTY_GET_TYPE(property) \ ((ecma_property_types_t) ((property) & ECMA_PROPERTY_TYPE_MASK)) /** * Get property name type. */ #define ECMA_PROPERTY_GET_NAME_TYPE(property) \ ((property) >> ECMA_PROPERTY_NAME_TYPE_SHIFT) /** * Returns true if the property pointer is a property pair. */ #define ECMA_PROPERTY_IS_PROPERTY_PAIR(property_header_p) \ ((property_header_p)->types[0] != ECMA_PROPERTY_TYPE_HASHMAP) /** * Returns true if the property is named property. */ #define ECMA_PROPERTY_IS_NAMED_PROPERTY(property) \ (ECMA_PROPERTY_GET_TYPE (property) != ECMA_PROPERTY_TYPE_SPECIAL) /** * Add the offset part to a property for computing its property data pointer. */ #define ECMA_PROPERTY_VALUE_ADD_OFFSET(property_p) \ ((uintptr_t) ((((uint8_t *) (property_p)) + (sizeof (ecma_property_value_t) * 2 - 1)))) /** * Align the property for computing its property data pointer. */ #define ECMA_PROPERTY_VALUE_DATA_PTR(property_p) \ (ECMA_PROPERTY_VALUE_ADD_OFFSET (property_p) & ~(sizeof (ecma_property_value_t) - 1)) /** * Compute the property data pointer of a property. * The property must be part of a property pair. */ #define ECMA_PROPERTY_VALUE_PTR(property_p) \ ((ecma_property_value_t *) ECMA_PROPERTY_VALUE_DATA_PTR (property_p)) /** * Property reference. It contains the value pointer * for real, and the value itself for virtual properties. */ typedef union { ecma_property_value_t *value_p; /**< property value pointer for real properties */ ecma_value_t virtual_value; /**< property value for virtual properties */ } ecma_property_ref_t; /** * Extended property reference, which also contains the * property descriptor pointer for real properties. */ typedef struct { ecma_property_ref_t property_ref; /**< property reference */ ecma_property_t *property_p; /**< property descriptor pointer for real properties */ } ecma_extended_property_ref_t; /** * Option flags for ecma_op_object_get_property. */ typedef enum { ECMA_PROPERTY_GET_NO_OPTIONS = 0, /**< no option flags for ecma_op_object_get_property */ ECMA_PROPERTY_GET_VALUE = 1u << 0, /**< fill virtual_value field for virtual properties */ ECMA_PROPERTY_GET_EXT_REFERENCE = 1u << 1, /**< get extended reference to the property */ ECMA_PROPERTY_GET_HAS_OWN_PROP = 1u << 2, /**< internal [[HasOwnProperty]] method */ } ecma_property_get_option_bits_t; /** * Internal object types. */ typedef enum { ECMA_OBJECT_TYPE_GENERAL = 0, /**< all objects that are not belongs to the sub-types below. */ ECMA_OBJECT_TYPE_CLASS = 1, /**< Objects with class property */ ECMA_OBJECT_TYPE_ARRAY = 2, /**< Array object (15.4) */ ECMA_OBJECT_TYPE_PSEUDO_ARRAY = 3, /**< Array-like object, such as Arguments object (10.6) */ ECMA_OBJECT_TYPE_PROXY = 4, /**< Proxy object ECMAScript v6 26.2 */ /* Note: these 4 types must be in this order. See IsCallable operation. */ ECMA_OBJECT_TYPE_FUNCTION = 5, /**< Function objects (15.3), created through 13.2 routine */ ECMA_OBJECT_TYPE_BOUND_FUNCTION = 6, /**< Function objects (15.3), created through 15.3.4.5 routine */ ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION = 7, /**< External (host) function object */ /* Types between 13-15 cannot have a built-in flag. See ecma_lexical_environment_type_t. */ ECMA_OBJECT_TYPE__MAX /**< maximum value */ } ecma_object_type_t; /** * Types of objects with class property. */ typedef enum { ECMA_PSEUDO_ARRAY_ARGUMENTS = 0, /**< Arguments object (10.6) */ ECMA_PSEUDO_ARRAY_TYPEDARRAY = 1, /**< TypedArray which does NOT need extra space to store length and offset */ ECMA_PSEUDO_ARRAY_TYPEDARRAY_WITH_INFO = 2, /**< TypedArray which NEEDS extra space to store length and offset */ ECMA_PSEUDO_ARRAY_ITERATOR = 3, /**< Array iterator object (ECMAScript v6, 22.1.5.1) */ ECMA_PSEUDO_SET_ITERATOR = 4, /**< Set iterator object (ECMAScript v6, 23.2.5.1) */ ECMA_PSEUDO_MAP_ITERATOR = 5, /**< Map iterator object (ECMAScript v6, 23.1.5.1) */ ECMA_PSEUDO_STRING_ITERATOR = 6, /**< String iterator object (ECMAScript v6, 22.1.5.1) */ ECMA_PSEUDO_ARRAY__MAX = ECMA_PSEUDO_STRING_ITERATOR /**< maximum value */ } ecma_pseudo_array_type_t; /** * Types of lexical environments. */ typedef enum { /* Types between 0 - 12 are ecma_object_type_t which can have a built-in flag. */ ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE = 13, /**< declarative lexical environment */ ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND = 14, /**< object-bound lexical environment * with provideThis flag */ ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND = 15, /**< object-bound lexical environment * with provided home object reference */ ECMA_LEXICAL_ENVIRONMENT_TYPE_START = ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE, /**< first lexical * environment type */ ECMA_LEXICAL_ENVIRONMENT_TYPE__MAX = ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND /**< maximum value */ } ecma_lexical_environment_type_t; #if ENABLED (JERRY_ES2015) /** * Types of array iterators. */ typedef enum { ECMA_ITERATOR_KEYS, /**< List only key indices */ ECMA_ITERATOR_VALUES, /**< List only key values */ ECMA_ITERATOR_KEYS_VALUES, /**< List key indices and values */ } ecma_array_iterator_type_t; #endif /* ENABLED (JERRY_ES2015) */ /** * Offset for JERRY_CONTEXT (status_flags) top 8 bits. */ #define ECMA_LOCAL_PARSE_OPTS_OFFSET ((sizeof (uint32_t) - sizeof (uint8_t)) * JERRY_BITSINBYTE) /** * Set JERRY_CONTEXT (status_flags) top 8 bits to the specified 'opts'. */ #define ECMA_SET_LOCAL_PARSE_OPTS(opts) \ do \ { \ JERRY_CONTEXT (status_flags) |= ((uint32_t) opts << ECMA_LOCAL_PARSE_OPTS_OFFSET) | ECMA_STATUS_DIRECT_EVAL; \ } while (0) /** * Get JERRY_CONTEXT (status_flags) top 8 bits. */ #define ECMA_GET_LOCAL_PARSE_OPTS() \ (JERRY_CONTEXT (status_flags) >> (ECMA_LOCAL_PARSE_OPTS_OFFSET - JERRY_LOG2 (ECMA_PARSE_ALLOW_SUPER))) /** * Clear JERRY_CONTEXT (status_flags) top 8 bits. */ #define ECMA_CLEAR_LOCAL_PARSE_OPTS() \ do \ { \ JERRY_CONTEXT (status_flags) &= ((1 << ECMA_LOCAL_PARSE_OPTS_OFFSET) - 1); \ } while (0) /** * Ecma object type mask for getting the object type. */ #define ECMA_OBJECT_TYPE_MASK 0x0fu /** * Ecma object is built-in or lexical environment. When this flag is set, the object is a * - built-in, if object type is less than ECMA_LEXICAL_ENVIRONMENT_TYPES_START * - lexical environment, if object type is greater or equal than ECMA_LEXICAL_ENVIRONMENT_TYPES_START */ #define ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV 0x10 /** * Extensible object. */ #define ECMA_OBJECT_FLAG_EXTENSIBLE 0x20 /** * Non closure flag for debugger. */ #define ECMA_OBJECT_FLAG_BLOCK ECMA_OBJECT_FLAG_EXTENSIBLE /** * Bitshift index for an ecma-object reference count field */ #define ECMA_OBJECT_REF_SHIFT 6 /** * Bitmask for an ecma-object reference count field */ #define ECMA_OBJECT_REF_MASK (((1u << 10) - 1) << ECMA_OBJECT_REF_SHIFT) /** * Value for increasing or decreasing the object reference counter. */ #define ECMA_OBJECT_REF_ONE (1u << ECMA_OBJECT_REF_SHIFT) /** * Represents non-visited white object */ #define ECMA_OBJECT_NON_VISITED (0x3ffu << ECMA_OBJECT_REF_SHIFT) /** * Maximum value of the object reference counter (1022). */ #define ECMA_OBJECT_MAX_REF (ECMA_OBJECT_NON_VISITED - ECMA_OBJECT_REF_ONE) /** * Description of ECMA-object or lexical environment * (depending on is_lexical_environment). */ typedef struct { /** type : 4 bit : ecma_object_type_t or ecma_lexical_environment_type_t depending on ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV flags : 2 bit : ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV, ECMA_OBJECT_FLAG_EXTENSIBLE or ECMA_OBJECT_FLAG_BLOCK refs : 10 bit (max 1022) */ uint16_t type_flags_refs; /** next in the object chain maintained by the garbage collector */ jmem_cpointer_t gc_next_cp; /** compressed pointer to property list or bound object */ union { jmem_cpointer_t property_list_cp; /**< compressed pointer to object's * or declerative lexical environments's property list */ jmem_cpointer_t bound_object_cp; /**< compressed pointer to lexical environments's the bound object */ jmem_cpointer_t home_object_cp; /**< compressed pointer to lexical environments's the home object */ } u1; /** object prototype or outer reference */ union { jmem_cpointer_t prototype_cp; /**< compressed pointer to the object's prototype */ jmem_cpointer_t outer_reference_cp; /**< compressed pointer to the lexical environments's outer reference */ } u2; } ecma_object_t; /** * Description of built-in properties of an object. */ 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 */ 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; } u; } ecma_built_in_props_t; /** * Start position of bit set size in length_and_bitset_size field. */ #define ECMA_BUILT_IN_BITSET_SHIFT 5 /** * Description of extended ECMA-object. * * The extended object is an object with extra fields. */ typedef struct { ecma_object_t object; /**< object header */ /** * Description of extra fields. These extra fields depend on the object type. */ union { ecma_built_in_props_t built_in; /**< built-in object part */ /** * Description of objects with class. */ struct { uint16_t class_id; /**< class id of the object */ uint16_t extra_info; /**< extra information for the object * e.g. array buffer type info (external/internal) */ /** * Description of extra fields. These extra fields depend on the class_id. */ union { ecma_value_t value; /**< value of the object (e.g. boolean, number, string, etc.) */ uint32_t length; /**< length related property (e.g. length of ArrayBuffer) */ ecma_value_t target; /**< [[ProxyTarget]] internal property */ } u; } class_prop; /** * Description of function objects. */ struct { jmem_cpointer_tag_t scope_cp; /**< function scope */ ecma_value_t bytecode_cp; /**< function byte code */ } function; /** * Description of array objects. */ struct { uint32_t length; /**< length property value */ union { ecma_property_t length_prop; /**< length property */ uint32_t hole_count; /**< number of array holes in a fast access mode array * multiplied ECMA_FAST_ACCESS_HOLE_ONE */ } u; } array; /** * Description of pseudo array objects. */ struct { uint8_t type; /**< pseudo array type, e.g. Arguments, TypedArray, ArrayIterator */ uint8_t extra_info; /**< extra information about the object. * e.g. the specific builtin id for typed arrays, * [[IterationKind]] property for %Iterator% */ union { uint16_t length; /**< for arguments: length of names */ uint16_t class_id; /**< for typedarray: the specific class name id */ uint16_t iterator_index; /**< for %Iterator%: [[%Iterator%NextIndex]] property */ } u1; union { ecma_value_t lex_env_cp; /**< for arguments: lexical environment */ ecma_value_t arraybuffer; /**< for typedarray: internal arraybuffer */ ecma_value_t iterated_value; /**< for %Iterator%: [[IteratedObject]] property */ ecma_value_t spread_value; /**< for spread object: spreaded element */ } u2; } pseudo_array; /** * Description of bound function object. */ struct { jmem_cpointer_tag_t target_function; /**< target function */ ecma_value_t args_len_or_this; /**< length of arguments or this value */ } bound_function; ecma_external_handler_t external_handler_cb; /**< external function */ } u; } ecma_extended_object_t; /** * Description of built-in extended ECMA-object. */ typedef struct { ecma_extended_object_t extended_object; /**< extended object part */ ecma_built_in_props_t built_in; /**< built-in object part */ } ecma_extended_built_in_object_t; /** * Alignment for the fast access mode array length. * The real length is aligned up for allocating the underlying buffer. */ #define ECMA_FAST_ARRAY_ALIGNMENT (8) /** * Align the length of the fast mode array to get the allocated size of the underlying buffer */ #define ECMA_FAST_ARRAY_ALIGN_LENGTH(length) \ (uint32_t) ((((length)) + ECMA_FAST_ARRAY_ALIGNMENT - 1) / ECMA_FAST_ARRAY_ALIGNMENT * ECMA_FAST_ARRAY_ALIGNMENT) /** * Compiled byte code data. */ typedef struct { uint16_t size; /**< real size >> JMEM_ALIGNMENT_LOG */ uint16_t refs; /**< reference counter for the byte code */ uint16_t status_flags; /**< various status flags: * CBC_CODE_FLAGS_FUNCTION flag tells whether * the byte code is function or regular expression. * If function, the other flags must be CBC_CODE_FLAGS... * If regexp, the other flags must be RE_FLAG... */ } ecma_compiled_code_t; /** * Description of bound function objects. */ typedef struct { ecma_extended_object_t header; /**< extended object header */ #if ENABLED (JERRY_ES2015) ecma_integer_value_t target_length; /**< length of target function */ #endif /* ENABLED (JERRY_ES2015) */ } ecma_bound_function_t; #if ENABLED (JERRY_SNAPSHOT_EXEC) /** * Description of static function objects. */ typedef struct { ecma_extended_object_t header; /**< header part */ const ecma_compiled_code_t *bytecode_p; /**< real byte code pointer */ } ecma_static_function_t; #endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */ #if ENABLED (JERRY_ES2015) /** * Description of arrow function objects. */ typedef struct { ecma_extended_object_t header; /**< extended object header */ ecma_value_t this_binding; /**< value of 'this' binding */ ecma_value_t new_target; /**< value of new.target */ } ecma_arrow_function_t; #if ENABLED (JERRY_SNAPSHOT_EXEC) /** * Description of static arrow function objects. */ typedef struct { ecma_arrow_function_t header; const ecma_compiled_code_t *bytecode_p; } ecma_static_arrow_function_t; #endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */ #endif /* ENABLED (JERRY_ES2015) */ #if ENABLED (JERRY_ES2015_BUILTIN_CONTAINER) /** * Flags for container objects */ typedef enum { ECMA_CONTAINER_FLAGS_EMPTY = (0), /** empty flags */ ECMA_CONTAINER_FLAGS_WEAK = (1 << 0) /** container object is weak */ } ecma_container_flags_t; /** * Description of map collection. */ typedef struct { ecma_value_t key; /**< key value */ ecma_value_t value; /**< value of the key */ } ecma_container_pair_t; /** * Size of a single element (in ecma_value_t unit). */ #define ECMA_CONTAINER_VALUE_SIZE 1 /** * Size of a key - value pair (in ecma_value_t unit). */ #define ECMA_CONTAINER_PAIR_SIZE 2 /** * Size of the internal buffer. */ #define ECMA_CONTAINER_GET_SIZE(container_p) \ (container_p->buffer_p[0]) /** * Remove the size field of the internal buffer. */ #define ECMA_CONTAINER_SET_SIZE(container_p, size) \ (container_p->buffer_p[0] = (ecma_value_t) (size)) /** * Number of entries of the internal buffer. */ #define ECMA_CONTAINER_ENTRY_COUNT(collection_p) \ (collection_p->item_count - 1) /** * Pointer to the first entry of the internal buffer. */ #define ECMA_CONTAINER_START(collection_p) \ (collection_p->buffer_p + 1) #endif /* ENABLED (JERRY_ES2015_BUILTIN_CONTAINER) */ typedef enum { ECMA_PROP_NO_OPTS = (0), /** empty property descriptor */ ECMA_PROP_IS_GET_DEFINED = (1 << 0), /** Is [[Get]] defined? */ ECMA_PROP_IS_SET_DEFINED = (1 << 1), /** Is [[Set]] defined? */ ECMA_PROP_IS_CONFIGURABLE = (1 << 2), /** [[Configurable]] */ ECMA_PROP_IS_ENUMERABLE = (1 << 3), /** [[Enumerable]] */ ECMA_PROP_IS_WRITABLE = (1 << 4), /** [[Writable]] */ ECMA_PROP_IS_THROW = (1 << 5), /** Flag that controls failure handling */ ECMA_PROP_IS_VALUE_DEFINED = (1 << 6), /** Is [[Value]] defined? */ ECMA_PROP_IS_CONFIGURABLE_DEFINED = (1 << 7), /** Is [[Configurable]] defined? */ ECMA_PROP_IS_ENUMERABLE_DEFINED = (1 << 8), /** Is [[Enumerable]] defined? */ ECMA_PROP_IS_WRITABLE_DEFINED = (1 << 9), /** Is [[Writable]] defined? */ } ecma_property_descriptor_status_flags_t; /** * Description of ECMA property descriptor * * See also: ECMA-262 v5, 8.10. * * Note: * If a component of descriptor is undefined then corresponding * field should contain it's default value. * The struct members must be in this order or keep in sync with ecma_property_flags_t and ECMA_IS_THROW flag. */ typedef struct { /** any combination of ecma_property_descriptor_status_flags_t bits */ uint16_t flags; /** [[Value]] */ ecma_value_t value; /** [[Get]] */ ecma_object_t *get_p; /** [[Set]] */ ecma_object_t *set_p; } ecma_property_descriptor_t; /** * Bitfield which represents a namedata property options in an ecma_property_descriptor_t * Attributes: * - is_get_defined, is_set_defined : false * - is_configurable, is_writable, is_enumerable : undefined (false) * - is_throw : undefined (false) * - is_value_defined : true * - is_configurable_defined, is_writable_defined, is_enumerable_defined : true */ #define ECMA_NAME_DATA_PROPERTY_DESCRIPTOR_BITS 0x3c0 /** * Bitmask to get a the physical property flags from an ecma_property_descriptor */ #define ECMA_PROPERTY_FLAGS_MASK 0x1c /** * Flag that controls failure handling during defining property * * Note: This flags represents the [[DefineOwnProperty]] (P, Desc, Throw) 3rd argument */ #define ECMA_IS_THROW (1 << 5) #if !ENABLED (JERRY_NUMBER_TYPE_FLOAT64) /** * Description of an ecma-number */ typedef float ecma_number_t; /** * It makes possible to read/write an ecma_number_t as uint32_t without strict aliasing rule violation. */ typedef union { ecma_number_t as_ecma_number_t; uint32_t as_uint32_t; } ecma_number_accessor_t; #define DOUBLE_TO_ECMA_NUMBER_T(value) (ecma_number_t) (value) /** * Maximum number of significant digits that ecma-number can store */ #define ECMA_NUMBER_MAX_DIGITS (9) /** * Width of sign field * * See also: * IEEE-754 2008, 3.6, Table 3.5 */ #define ECMA_NUMBER_SIGN_WIDTH (1) /** * Width of biased exponent field * * See also: * IEEE-754 2008, 3.6, Table 3.5 */ #define ECMA_NUMBER_BIASED_EXP_WIDTH (8) /** * Width of fraction field * * See also: * IEEE-754 2008, 3.6, Table 3.5 */ #define ECMA_NUMBER_FRACTION_WIDTH (23) #elif ENABLED (JERRY_NUMBER_TYPE_FLOAT64) /** * Description of an ecma-number */ typedef double ecma_number_t; /** * It makes possible to read/write an ecma_number_t as uint64_t without strict aliasing rule violation. */ typedef union { ecma_number_t as_ecma_number_t; uint64_t as_uint64_t; } ecma_number_accessor_t; #define DOUBLE_TO_ECMA_NUMBER_T(value) value /** * Maximum number of significant digits that ecma-number can store */ #define ECMA_NUMBER_MAX_DIGITS (19) /** * Width of sign field * * See also: * IEEE-754 2008, 3.6, Table 3.5 */ #define ECMA_NUMBER_SIGN_WIDTH (1) /** * Width of biased exponent field * * See also: * IEEE-754 2008, 3.6, Table 3.5 */ #define ECMA_NUMBER_BIASED_EXP_WIDTH (11) /** * Width of fraction field * * See also: * IEEE-754 2008, 3.6, Table 3.5 */ #define ECMA_NUMBER_FRACTION_WIDTH (52) #endif /* !ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ /** * Value '0' of ecma_number_t */ #define ECMA_NUMBER_ZERO ((ecma_number_t) 0) /** * Value '1' of ecma_number_t */ #define ECMA_NUMBER_ONE ((ecma_number_t) 1) /** * Value '2' of ecma_number_t */ #define ECMA_NUMBER_TWO ((ecma_number_t) 2) /** * Value '0.5' of ecma_number_t */ #define ECMA_NUMBER_HALF ((ecma_number_t) 0.5f) /** * Value '-1' of ecma_number_t */ #define ECMA_NUMBER_MINUS_ONE ((ecma_number_t) -1) #if !ENABLED (JERRY_NUMBER_TYPE_FLOAT64) /** * Number.MIN_VALUE (i.e., the smallest positive value of ecma-number) * * See also: ECMA_262 v5, 15.7.3.3 */ # define ECMA_NUMBER_MIN_VALUE (FLT_MIN) /** * Number.MAX_VALUE (i.e., the maximum value of ecma-number) * * See also: ECMA_262 v5, 15.7.3.2 */ # define ECMA_NUMBER_MAX_VALUE (FLT_MAX) /** * Number.EPSILON * * See also: ECMA_262 v6, 20.1.2.1 */ # define ECMA_NUMBER_EPSILON ((ecma_number_t) 1.1920928955078125e-7) /** * Number.MAX_SAFE_INTEGER * * See also: ECMA_262 v6, 20.1.2.6 */ # define ECMA_NUMBER_MAX_SAFE_INTEGER ((ecma_number_t) 0xFFFFFF) /** * Number.MIN_SAFE_INTEGER * * See also: ECMA_262 v6, 20.1.2.8 */ # define ECMA_NUMBER_MIN_SAFE_INTEGER ((ecma_number_t) -0xFFFFFF) #elif ENABLED (JERRY_NUMBER_TYPE_FLOAT64) /** * Number.MAX_VALUE (i.e., the maximum value of ecma-number) * * See also: ECMA_262 v5, 15.7.3.2 */ # define ECMA_NUMBER_MAX_VALUE ((ecma_number_t) 1.7976931348623157e+308) /** * Number.MIN_VALUE (i.e., the smallest positive value of ecma-number) * * See also: ECMA_262 v5, 15.7.3.3 */ # define ECMA_NUMBER_MIN_VALUE ((ecma_number_t) 5e-324) /** * Number.EPSILON * * See also: ECMA_262 v6, 20.1.2.1 */ # define ECMA_NUMBER_EPSILON ((ecma_number_t) 2.2204460492503130808472633361816e-16) /** * Number.MAX_SAFE_INTEGER * * See also: ECMA_262 v6, 20.1.2.6 */ # define ECMA_NUMBER_MAX_SAFE_INTEGER ((ecma_number_t) 0x1FFFFFFFFFFFFF) /** * Number.MIN_SAFE_INTEGER * * See also: ECMA_262 v6, 20.1.2.8 */ # define ECMA_NUMBER_MIN_SAFE_INTEGER ((ecma_number_t) -0x1FFFFFFFFFFFFF) #endif /* !ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ /** * Euler number */ #define ECMA_NUMBER_E ((ecma_number_t) 2.7182818284590452354) /** * Natural logarithm of 10 */ #define ECMA_NUMBER_LN10 ((ecma_number_t) 2.302585092994046) /** * Natural logarithm of 2 */ #define ECMA_NUMBER_LN2 ((ecma_number_t) 0.6931471805599453) /** * Logarithm base 2 of the Euler number */ #define ECMA_NUMBER_LOG2E ((ecma_number_t) 1.4426950408889634) /** * Logarithm base 10 of the Euler number */ #define ECMA_NUMBER_LOG10E ((ecma_number_t) 0.4342944819032518) /** * Pi number */ #define ECMA_NUMBER_PI ((ecma_number_t) 3.1415926535897932) /** * Square root of 0.5 */ #define ECMA_NUMBER_SQRT_1_2 ((ecma_number_t) 0.7071067811865476) /** * Square root of 2 */ #define ECMA_NUMBER_SQRT2 ((ecma_number_t) 1.4142135623730951) /** * Maximum number of characters in string representation of ecma-number */ #define ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER 64 /** * Maximum number of characters in string representation of ecma-uint32 */ #define ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32 10 /** * String is not a valid array index. */ #define ECMA_STRING_NOT_ARRAY_INDEX UINT32_MAX /** * Ecma-collection: a growable list of ecma-values. */ typedef struct { uint32_t item_count; /**< number of items in the collection */ uint32_t capacity; /**< number of items can be stored in the underlying buffer */ ecma_value_t *buffer_p; /**< underlying data buffer */ } ecma_collection_t; /** * Initial capacity of an ecma-collection */ #define ECMA_COLLECTION_INITIAL_CAPACITY 4 /** * Ecma-collenction grow factor when the collection underlying buffer need to be reallocated */ #define ECMA_COLLECTION_GROW_FACTOR (ECMA_COLLECTION_INITIAL_CAPACITY * 2) /** * Compute the total allocated size of the collection based on it's capacity */ #define ECMA_COLLECTION_ALLOCATED_SIZE(capacity) \ (uint32_t) (sizeof (ecma_collection_t) + (capacity * sizeof (ecma_value_t))) /** * Initial allocated size of an ecma-collection */ #define ECMA_COLLECTION_INITIAL_SIZE ECMA_COLLECTION_ALLOCATED_SIZE (ECMA_COLLECTION_INITIAL_CAPACITY) /** * Direct string types (2 bit). */ typedef enum { ECMA_DIRECT_STRING_PTR = 0, /**< string is a string pointer, only used by property names */ ECMA_DIRECT_STRING_MAGIC = 1, /**< string is a magic string */ ECMA_DIRECT_STRING_UINT = 2, /**< string is an unsigned int */ ECMA_DIRECT_STRING_ECMA_INTEGER = 3, /**< string is an ecma-integer */ } ecma_direct_string_type_t; /** * Maximum value of the immediate part of a direct magic string. * Must be compatible with the immediate property name. */ #if ENABLED (JERRY_CPOINTER_32_BIT) #define ECMA_DIRECT_STRING_MAX_IMM 0x07ffffff #else /* !ENABLED (JERRY_CPOINTER_32_BIT) */ #define ECMA_DIRECT_STRING_MAX_IMM 0x0000ffff #endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ /** * Shift for direct string value part in ecma_value_t. */ #define ECMA_DIRECT_STRING_SHIFT (ECMA_VALUE_SHIFT + 2) /** * Full mask for direct strings. */ #define ECMA_DIRECT_STRING_MASK ((uintptr_t) (ECMA_DIRECT_TYPE_MASK | (0x3u << ECMA_VALUE_SHIFT))) /** * Create an ecma direct string. */ #define ECMA_CREATE_DIRECT_STRING(type, value) \ ((uintptr_t) (ECMA_TYPE_DIRECT_STRING | ((type) << ECMA_VALUE_SHIFT) | (value) << ECMA_DIRECT_STRING_SHIFT)) /** * Create an ecma direct string from the given number. * * Note: the given number must be less or equal than ECMA_DIRECT_STRING_MAX_IMM */ #define ECMA_CREATE_DIRECT_UINT32_STRING(uint32_number) \ ((ecma_string_t *) ECMA_CREATE_DIRECT_STRING (ECMA_DIRECT_STRING_UINT, (uintptr_t) uint32_number)) /** * Checks whether the string is direct. */ #define ECMA_IS_DIRECT_STRING(string_p) \ ((((uintptr_t) (string_p)) & 0x1) != 0) /** * Checks whether the string is direct. */ #define ECMA_IS_DIRECT_STRING_WITH_TYPE(string_p, type) \ ((((uintptr_t) (string_p)) & ECMA_DIRECT_STRING_MASK) == ECMA_CREATE_DIRECT_STRING (type, 0)) /** * Returns the type of a direct string. */ #define ECMA_GET_DIRECT_STRING_TYPE(string_p) \ ((((uintptr_t) (string_p)) >> ECMA_VALUE_SHIFT) & 0x3) /** * Shift applied to type conversions. */ #define ECMA_STRING_TYPE_CONVERSION_SHIFT (ECMA_PROPERTY_NAME_TYPE_SHIFT - ECMA_VALUE_SHIFT) /** * Converts direct string type to property name type. */ #define ECMA_DIRECT_STRING_TYPE_TO_PROP_NAME_TYPE(string_p) \ ((((uintptr_t) (string_p)) & (0x3 << ECMA_VALUE_SHIFT)) << ECMA_STRING_TYPE_CONVERSION_SHIFT) /** * Returns the value of a direct string. */ #define ECMA_GET_DIRECT_STRING_VALUE(string_p) \ (((uintptr_t) (string_p)) >> ECMA_DIRECT_STRING_SHIFT) /** * Maximum number of bytes that a long-utf8-string is able to store */ #define ECMA_STRING_SIZE_LIMIT UINT32_MAX typedef enum { ECMA_STRING_CONTAINER_HEAP_UTF8_STRING, /**< actual data is on the heap as an utf-8 (cesu8) string * maximum size is 2^16. */ ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING, /**< actual data is on the heap as an utf-8 (cesu8) string * maximum size is 2^32. */ ECMA_STRING_CONTAINER_UINT32_IN_DESC, /**< actual data is UInt32-represeneted Number stored locally in the string's descriptor */ ECMA_STRING_CONTAINER_HEAP_ASCII_STRING, /**< actual data is on the heap as an ASCII string * maximum size is 2^16. */ ECMA_STRING_CONTAINER_MAGIC_STRING_EX, /**< the ecma-string is equal to one of external magic strings */ ECMA_STRING_CONTAINER_SYMBOL, /**< the ecma-string is a symbol */ ECMA_STRING_CONTAINER__MAX = ECMA_STRING_CONTAINER_SYMBOL /**< maximum value */ } ecma_string_container_t; /** * Mask for getting the container of a string. */ #define ECMA_STRING_CONTAINER_MASK 0x7u /** * Value for increasing or decreasing the reference counter. */ #define ECMA_STRING_REF_ONE (1u << 4) /** * Maximum value of the reference counter (4294967280). */ #define ECMA_STRING_MAX_REF (0xFFFFFFF0) /** * Flag that identifies that the string is static which means it is stored in JERRY_CONTEXT (string_list_cp) */ #define ECMA_STATIC_STRING_FLAG (1 << 3) /** * Set an ecma-string as static string */ #define ECMA_SET_STRING_AS_STATIC(string_p) \ (string_p)->refs_and_container |= ECMA_STATIC_STRING_FLAG /** * Checks whether the ecma-string is static string */ #define ECMA_STRING_IS_STATIC(string_p) \ ((string_p)->refs_and_container & ECMA_STATIC_STRING_FLAG) /** * Returns with the container type of a string. */ #define ECMA_STRING_GET_CONTAINER(string_desc_p) \ ((ecma_string_container_t) ((string_desc_p)->refs_and_container & ECMA_STRING_CONTAINER_MASK)) /** * Checks whether the reference counter is 1. */ #define ECMA_STRING_IS_REF_EQUALS_TO_ONE(string_desc_p) \ (((string_desc_p)->refs_and_container >> 4) == 1) /** * ECMA string-value descriptor */ typedef struct { /** Reference counter for the string */ uint32_t refs_and_container; /** * Actual data or identifier of it's place in container (depending on 'container' field) */ union { lit_string_hash_t hash; /**< hash of the ASCII/UTF8 string */ uint32_t magic_string_ex_id; /**< identifier of an external magic string (lit_magic_string_ex_id_t) */ uint32_t uint32_number; /**< uint32-represented number placed locally in the descriptor */ } u; } ecma_string_t; /** * ECMA ASCII string-value descriptor */ typedef struct { ecma_string_t header; /**< string header */ uint16_t size; /**< size of this ASCII string in bytes */ } ecma_ascii_string_t; /** * ECMA long UTF8 string-value descriptor */ typedef struct { ecma_string_t header; /**< string header */ uint16_t size; /**< size of this utf-8 string in bytes */ uint16_t length; /**< length of this utf-8 string in bytes */ } ecma_utf8_string_t; /** * ECMA UTF8 string-value descriptor */ typedef struct { ecma_string_t header; /**< string header */ lit_utf8_size_t size; /**< size of this long utf-8 string in bytes */ lit_utf8_size_t length; /**< length of this long utf-8 string in bytes */ } ecma_long_utf8_string_t; /** * Get the start position of the string buffer of an ecma ASCII string */ #define ECMA_ASCII_STRING_GET_BUFFER(string_p) \ ((lit_utf8_byte_t *) ((lit_utf8_byte_t *) (string_p) + sizeof (ecma_ascii_string_t))) /** * Get the start position of the string buffer of an ecma UTF8 string */ #define ECMA_UTF8_STRING_GET_BUFFER(string_p) \ ((lit_utf8_byte_t *) ((lit_utf8_byte_t *) (string_p) + sizeof (ecma_utf8_string_t))) /** * Get the start position of the string buffer of an ecma long UTF8 string */ #define ECMA_LONG_UTF8_STRING_GET_BUFFER(string_p) \ ((lit_utf8_byte_t *) ((lit_utf8_byte_t *) (string_p) + sizeof (ecma_long_utf8_string_t))) /** * ECMA extended string-value descriptor */ typedef struct { ecma_string_t header; /**< string header */ union { ecma_value_t symbol_descriptor; /**< symbol descriptor string-value */ ecma_value_t value; /**< original key value corresponds to the map key string */ } u; } ecma_extended_string_t; /** * String builder header */ typedef struct { lit_utf8_size_t current_size; /**< size of the data in the buffer */ } ecma_stringbuilder_header_t; /** * Get pointer to the beginning of the stored string in the string builder */ #define ECMA_STRINGBUILDER_STRING_PTR(header_p) \ ((lit_utf8_byte_t *) (((lit_utf8_byte_t *) header_p) + sizeof (ecma_ascii_string_t))) /** * Get the size of the stored string in the string builder */ #define ECMA_STRINGBUILDER_STRING_SIZE(header_p) \ ((lit_utf8_size_t) (header_p->current_size - sizeof (ecma_ascii_string_t))) /** * String builder handle */ typedef struct { ecma_stringbuilder_header_t *header_p; /**< pointer to header */ } ecma_stringbuilder_t; /** * Abort flag for error reference. */ #define ECMA_ERROR_REF_ABORT 0x1 /** * Value for increasing or decreasing the reference counter. */ #define ECMA_ERROR_REF_ONE (1u << 1) /** * Maximum value of the reference counter. */ #define ECMA_ERROR_MAX_REF (UINT32_MAX - 1u) /** * Representation of a thrown value on API level. */ typedef struct { uint32_t refs_and_flags; /**< reference counter */ ecma_value_t value; /**< referenced value */ } ecma_error_reference_t; #if ENABLED (JERRY_PROPRETY_HASHMAP) /** * The lowest state of the ecma_prop_hashmap_alloc_state counter. * If ecma_prop_hashmap_alloc_state other other than this value, it is * disabled. */ #define ECMA_PROP_HASHMAP_ALLOC_ON 0 /** * The highest state of the ecma_prop_hashmap_alloc_state counter. */ #define ECMA_PROP_HASHMAP_ALLOC_MAX 4 #endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ /** * Number of values in a literal storage item */ #define ECMA_LIT_STORAGE_VALUE_COUNT 3 /** * Literal storage item */ typedef struct { jmem_cpointer_t next_cp; /**< cpointer ot next item */ jmem_cpointer_t values[ECMA_LIT_STORAGE_VALUE_COUNT]; /**< list of values */ } ecma_lit_storage_item_t; /** * Number storage item */ typedef struct { jmem_cpointer_t next_cp; /**< cpointer ot next item */ jmem_cpointer_t values[ECMA_LIT_STORAGE_VALUE_COUNT]; /**< list of values */ } ecma_number_storage_item_t; #if ENABLED (JERRY_LCACHE) /** * Container of an LCache entry identifier */ #if ENABLED (JERRY_CPOINTER_32_BIT) typedef uint64_t ecma_lcache_hash_entry_id_t; #else /* !ENABLED (JERRY_CPOINTER_32_BIT) */ typedef uint32_t ecma_lcache_hash_entry_id_t; #endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ /** * Entry of LCache hash table */ typedef struct { /** Pointer to a property of the object */ ecma_property_t *prop_p; /** Entry identifier in LCache */ ecma_lcache_hash_entry_id_t id; } ecma_lcache_hash_entry_t; /** * Number of rows in LCache's hash table */ #define ECMA_LCACHE_HASH_ROWS_COUNT 128 /** * Number of entries in a row of LCache's hash table */ #define ECMA_LCACHE_HASH_ROW_LENGTH 2 #endif /* ENABLED (JERRY_LCACHE) */ #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) /** * Function callback descriptor of a %TypedArray% object getter */ typedef ecma_number_t (*ecma_typedarray_getter_fn_t) (lit_utf8_byte_t *src); /** * Function callback descriptor of a %TypedArray% object setter */ typedef void (*ecma_typedarray_setter_fn_t) (lit_utf8_byte_t *src, ecma_number_t value); /** * Builtin id for the different types of TypedArray's */ typedef enum { ECMA_INT8_ARRAY, /**< Int8Array */ ECMA_UINT8_ARRAY, /**< Uint8Array */ ECMA_UINT8_CLAMPED_ARRAY, /**< Uint8ClampedArray */ ECMA_INT16_ARRAY, /**< Int16Array */ ECMA_UINT16_ARRAY, /**< Uint16Array */ ECMA_INT32_ARRAY, /**< Int32Array */ ECMA_UINT32_ARRAY, /**< Uint32Array */ ECMA_FLOAT32_ARRAY, /**< Float32Array */ ECMA_FLOAT64_ARRAY, /**< Float64Array */ } ecma_typedarray_type_t; /** * Extra information for ArrayBuffers. */ typedef enum { ECMA_ARRAYBUFFER_INTERNAL_MEMORY = 0u, /* ArrayBuffer memory is handled internally. */ ECMA_ARRAYBUFFER_EXTERNAL_MEMORY = (1u << 0), /* ArrayBuffer created via jerry_create_arraybuffer_external. */ } ecma_arraybuffer_extra_flag_t; #define ECMA_ARRAYBUFFER_HAS_EXTERNAL_MEMORY(object_p) \ ((((ecma_extended_object_t *) object_p)->u.class_prop.extra_info & ECMA_ARRAYBUFFER_EXTERNAL_MEMORY) != 0) /** * Struct to store information for ArrayBuffers with external memory. * * The following elements are stored in Jerry memory. * * buffer_p - pointer to the external memory. * free_cb - pointer to a callback function which is called when the ArrayBuffer is freed. */ typedef struct { ecma_extended_object_t extended_object; /**< extended object part */ void *buffer_p; /**< external buffer pointer */ ecma_object_native_free_callback_t free_cb; /**< the free callback for the above buffer pointer */ } ecma_arraybuffer_external_info; /** * Some internal properties of TypedArray object. * It is only used when the offset is not 0, and * the array-length is not buffer-length / element_size. */ typedef struct { ecma_extended_object_t extended_object; /**< extended object part */ ecma_length_t byte_offset; /**< the byteoffset of the above arraybuffer */ ecma_length_t array_length; /**< the array length */ } ecma_extended_typedarray_object_t; /** * General structure for query %TypedArray% object's properties. **/ typedef struct { ecma_object_t *array_buffer_p; /**< pointer to the typedArray's [[ViewedArrayBuffer]] internal slot */ lit_utf8_byte_t *buffer_p; /**< pointer to the underlying raw data buffer. * Note: * - This address is increased by the [ByteOffset]] internal property. * - This address must be used during indexed read/write operation. */ ecma_typedarray_type_t id; /**< [[TypedArrayName]] internal slot */ uint32_t length; /**< [[ByteLength]] internal slot */ ecma_length_t offset; /**< [[ByteOffset]] internal slot. */ uint8_t shift; /**< the element size shift in the typedArray */ uint8_t element_size; /**< element size based on [[TypedArrayName]] in Table 49 */ } ecma_typedarray_info_t; #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ #if ENABLED (JERRY_ES2015) /** * Executable (e.g. generator, async) object flags. */ typedef enum { ECMA_EXECUTABLE_OBJECT_COMPLETED = (1u << 0), /**< executable object is completed and cannot be resumed */ ECMA_EXECUTABLE_OBJECT_RUNNING = (1u << 1), /**< executable object is currently running */ /* Generator specific flags. */ ECMA_GENERATOR_ITERATE_AND_YIELD = (1u << 2), /**< the generator performs a yield* operation */ } ecma_executable_object_flags_t; /** * Checks whether the executable object is waiting for resuming. */ #define ECMA_EXECUTABLE_OBJECT_IS_SUSPENDED(extra_info) \ (!((extra_info) & (ECMA_EXECUTABLE_OBJECT_COMPLETED | ECMA_EXECUTABLE_OBJECT_RUNNING))) #endif /* ENABLED (JERRY_ES2015) */ #if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) /** * Description of DataView objects. */ typedef struct { ecma_extended_object_t header; /**< header part */ ecma_object_t *buffer_p; /**< [[ViewedArrayBuffer]] internal slot */ uint32_t byte_offset; /**< [[ByteOffset]] internal slot */ } ecma_dataview_object_t; #endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */ /** * Flag for indicating whether the symbol is a well known symbol * * See also: 6.1.5.1 */ #define ECMA_GLOBAL_SYMBOL_FLAG 0x01 /** * Bitshift index for indicating whether the symbol is a well known symbol * * See also: 6.1.5.1 */ #define ECMA_GLOBAL_SYMBOL_SHIFT 1 /** * Bitshift index for the symbol hash property */ #define ECMA_SYMBOL_HASH_SHIFT 2 #if (JERRY_STACK_LIMIT != 0) /** * Set the jerry context stack limit for IAR. */ #define JERRY_IAR_MEM_STACK_LIMIT (4480) // > 4136b, 3500; < 4.5 * 1024 = 4608 /** * Check the current jerry context stack usage. */ #define CHECK_JERRY_STACK_USAGE(context_p) \ do \ { \ if (ecma_get_current_stack_usage () > JERRY_IAR_MEM_STACK_LIMIT) \ { \ parser_raise_error (context_p, PARSER_ERR_JERRY_STACK_LIMIT_REACHED); \ } \ } while (0) /** * Check the current stack usage. If the limit is reached a RangeError is raised. */ #define ECMA_CHECK_STACK_USAGE() \ do \ { \ if (ecma_get_current_stack_usage () > CONFIG_MEM_STACK_LIMIT) \ { \ return ecma_raise_range_error (ECMA_ERR_MSG ("Maximum call stack size exceeded.")); \ } \ } while (0) #else /* JERRY_STACK_LIMIT == 0) */ /** * If the stack limit is unlimited, this check is an empty macro. */ #define ECMA_CHECK_STACK_USAGE() #define CHECK_JERRY_STACK_USAGE(context_p) #endif /* (JERRY_STACK_LIMIT != 0) */ /** * Invalid object pointer which represents abrupt completion */ #define ECMA_OBJECT_POINTER_ERROR ((ecma_object_t *) 0x01) #if ENABLED (JERRY_ES2015_BUILTIN_PROXY) /** * Description of Proxy objects. */ typedef struct { ecma_object_t header; /**< header part */ ecma_value_t target; /**< [[ProxyTarget]] internal slot */ ecma_value_t handler; /**< [[ProxyHandler]] internal slot */ } ecma_proxy_object_t; /** * Description of Proxy objects. */ typedef struct { ecma_extended_object_t header; /**< header part */ ecma_value_t proxy; /**< [[RevocableProxy]] internal slot */ } ecma_revocable_proxy_object_t; #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ /** * @} * @} */ #endif /* !ECMA_GLOBALS_H */