diff --git a/CMakeLists.txt b/CMakeLists.txt index 444e1dcd3..d911a45d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -238,6 +238,7 @@ project (Jerry CXX C ASM) function(declare_targets_for_build_mode BUILD_MODE) string(TOLOWER "${PLATFORM_EXT}" PLATFORM_L) set(TARGET_NAME ${BUILD_MODE_PREFIX_${BUILD_MODE}}.${PLATFORM_L}) + set(PLUGINS_TARGET_NAME ${BUILD_MODE_PREFIX_${BUILD_MODE}}.plugins.${PLATFORM_L}) set(LIBC_TARGET_NAME ${BUILD_MODE_PREFIX_${BUILD_MODE}}.jerry-libc.${PLATFORM_L}) function(declare_target_with_modifiers ) # modifiers are passed in ARGN implicit argument @@ -245,11 +246,13 @@ project (Jerry CXX C ASM) foreach(MODIFIER ${ARGN}) set(TARGET_NAME ${TARGET_NAME}${MODIFIER_SUFFIX_${MODIFIER}}) - set(LIBC_TARGET_NAME ${LIBC_TARGET_NAME}${MODIFIER_SUFFIX_${MODIFIER}}) set(CORE_TARGET_NAME ${CORE_TARGET_NAME}${MODIFIER_SUFFIX_${MODIFIER}}) + set(LIBC_TARGET_NAME ${LIBC_TARGET_NAME}${MODIFIER_SUFFIX_${MODIFIER}}) + set(PLUGINS_TARGET_NAME ${PLUGINS_TARGET_NAME}${MODIFIER_SUFFIX_${MODIFIER}}) endforeach() set(CORE_TARGET_NAME ${CORE_TARGET_NAME}.jerry-core) set(LIBC_TARGET_NAME ${LIBC_TARGET_NAME}.lib) + set(PLUGINS_TARGET_NAME ${PLUGINS_TARGET_NAME}.lib) set(DEFINES_JERRY ) @@ -269,7 +272,7 @@ project (Jerry CXX C ASM) PROPERTY LINK_FLAGS "${COMPILE_FLAGS_JERRY} ${CXX_FLAGS_JERRY} ${FLAGS_COMMON_${BUILD_MODE}} ${LINKER_FLAGS_COMMON} ${LINKER_FLAGS_STATIC}") target_compile_definitions(${TARGET_NAME} PRIVATE ${DEFINES_JERRY}) target_include_directories(${TARGET_NAME} PRIVATE ${INCLUDE_CORE_INTERFACE}) - target_link_libraries(${TARGET_NAME} ${CORE_TARGET_NAME} ${LIBC_TARGET_NAME} ${PREFIX_IMPORTED_LIB}libgcc) + target_link_libraries(${TARGET_NAME} ${PLUGINS_TARGET_NAME} ${CORE_TARGET_NAME} ${LIBC_TARGET_NAME} ${PREFIX_IMPORTED_LIB}libgcc) add_cppcheck_target(${TARGET_NAME}) diff --git a/jerry-core/config.h b/jerry-core/config.h index 9810b4a1c..6d39bd58f 100644 --- a/jerry-core/config.h +++ b/jerry-core/config.h @@ -155,4 +155,19 @@ */ #define CONFIG_EXTENSION_CHAR_BUFFER_SIZE 2048 +/** + * Maximum number of registered extensions + */ +#define CONFIG_EXTENSION_MAX_NUMBER_OF_EXTENSIONS 32 + +/** + * Maximum number of functions in an extension + */ +#define CONFIG_EXTENSION_MAX_FUNCTIONS_IN_EXTENSION 1024 + +/** + * Maximum number of arguments in a function + */ +#define CONFIG_EXTENSION_MAX_ARGUMENTS_IN_FUNCTION 16 + #endif /* !CONFIG_H */ diff --git a/jerry-core/ecma/base/ecma-gc.cpp b/jerry-core/ecma/base/ecma-gc.cpp index e0669f060..f475f64fd 100644 --- a/jerry-core/ecma/base/ecma-gc.cpp +++ b/jerry-core/ecma/base/ecma-gc.cpp @@ -320,6 +320,7 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */ case ECMA_INTERNAL_PROPERTY_CODE: /* an integer */ case ECMA_INTERNAL_PROPERTY_BUILT_IN_ID: /* an integer */ case ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_ID: /* an integer */ + case ECMA_INTERNAL_PROPERTY_EXTENSION_ID: /* an integer */ case ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_0_31: /* an integer (bit-mask) */ case ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_32_63: /* an integer (bit-mask) */ { diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index 5f53760f9..b38adf5b5 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -223,6 +223,9 @@ typedef enum ([[Built-in routine ID]]) */ ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_ID, + /** Identifier of implementation-defined extension object */ + ECMA_INTERNAL_PROPERTY_EXTENSION_ID, + /** * Bit-mask of non-instantiated built-in's properties (bits 0-31) */ @@ -374,6 +377,8 @@ typedef enum of ECMA-262 v5 specification */ ECMA_OBJECT_TYPE_ARGUMENTS, /**< Arguments object (10.6) */ ECMA_OBJECT_TYPE_ARRAY, /**< Array object (15.4) */ + ECMA_OBJECT_TYPE_EXTENSION, /**< Extension (implementation-defined) object + * See also: ecma_extension_instantiate */ // ECMA_OBJECT_TYPE_HOST, /**< Host object */ ECMA_OBJECT_TYPE__COUNT /**< number of object types */ } ecma_object_type_t; @@ -733,7 +738,7 @@ FIXME (Move to library that should define the type (literal.h /* ? */)) typedef uint32_t literal_index_t; /** - * Identifiers of ECMA magic string constants + * Identifiers of ECMA and implementation-defined magic string constants */ typedef enum { diff --git a/jerry-core/ecma/base/ecma-helpers-string.cpp b/jerry-core/ecma/base/ecma-helpers-string.cpp index ba5bbe4f5..3f27da91b 100644 --- a/jerry-core/ecma/base/ecma-helpers-string.cpp +++ b/jerry-core/ecma/base/ecma-helpers-string.cpp @@ -876,17 +876,18 @@ ecma_string_to_number (const ecma_string_t *str_p) /**< ecma-string */ */ ssize_t ecma_string_to_zt_string (const ecma_string_t *string_desc_p, /**< ecma-string descriptor */ - ecma_char_t *buffer_p, /**< destination buffer */ + ecma_char_t *buffer_p, /**< destination buffer pointer (can be NULL if buffer_size == 0) */ ssize_t buffer_size) /**< size of buffer */ { JERRY_ASSERT (string_desc_p != NULL); JERRY_ASSERT (string_desc_p->refs > 0); - JERRY_ASSERT (buffer_p != NULL); - JERRY_ASSERT (buffer_size > 0); + JERRY_ASSERT (buffer_p != NULL || buffer_size == 0); + JERRY_ASSERT (buffer_size >= 0); ssize_t required_buffer_size = ((ecma_string_get_length (string_desc_p) + 1) * ((ssize_t) sizeof (ecma_char_t))); - if (required_buffer_size > buffer_size) + if (required_buffer_size > buffer_size + || buffer_size == 0) { return -required_buffer_size; } diff --git a/jerry-core/ecma/base/ecma-helpers.cpp b/jerry-core/ecma/base/ecma-helpers.cpp index eebc87099..0fc9e46d3 100644 --- a/jerry-core/ecma/base/ecma-helpers.cpp +++ b/jerry-core/ecma/base/ecma-helpers.cpp @@ -787,6 +787,7 @@ ecma_free_internal_property (ecma_property_t *property_p) /**< the property */ case ECMA_INTERNAL_PROPERTY_CODE: /* an integer */ case ECMA_INTERNAL_PROPERTY_BUILT_IN_ID: /* an integer */ case ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_ID: /* an integer */ + case ECMA_INTERNAL_PROPERTY_EXTENSION_ID: /* an integer */ case ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_0_31: /* an integer (bit-mask) */ case ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_32_63: /* an integer (bit-mask) */ { diff --git a/jerry-core/ecma/operations/ecma-init-finalize.cpp b/jerry-core/ecma/base/ecma-init-finalize.cpp similarity index 97% rename from jerry-core/ecma/operations/ecma-init-finalize.cpp rename to jerry-core/ecma/base/ecma-init-finalize.cpp index e577f19e4..7e15991f5 100644 --- a/jerry-core/ecma/operations/ecma-init-finalize.cpp +++ b/jerry-core/ecma/base/ecma-init-finalize.cpp @@ -14,10 +14,10 @@ */ #include "ecma-builtins.h" -#include "ecma-helpers.h" #include "ecma-gc.h" +#include "ecma-helpers.h" +#include "ecma-init-finalize.h" #include "ecma-lcache.h" -#include "ecma-operations.h" #include "ecma-stack.h" #include "mem-allocator.h" diff --git a/jerry-core/ecma/operations/ecma-operations.h b/jerry-core/ecma/base/ecma-init-finalize.h similarity index 85% rename from jerry-core/ecma/operations/ecma-operations.h rename to jerry-core/ecma/base/ecma-init-finalize.h index 492f967fe..a002cf6e0 100644 --- a/jerry-core/ecma/operations/ecma-operations.h +++ b/jerry-core/ecma/base/ecma-init-finalize.h @@ -13,17 +13,15 @@ * limitations under the License. */ -#ifndef JERRY_ECMA_OPERATIONS_H -#define JERRY_ECMA_OPERATIONS_H - -#include "jrt.h" +#ifndef ECMA_INIT_FINALIZE_H +#define ECMA_INIT_FINALIZE_H /** \addtogroup ecma ECMA * @{ */ /** - * \addtogroup ecmainitfinalize Initialization and finalization of ECMA components + * \addtogroup ecmainitfinalize Initialization and finalization of ECMA * @{ */ @@ -35,4 +33,4 @@ extern void ecma_finalize (void); * @} */ -#endif /* JERRY_ECMA_OPERATIONS_H */ +#endif /* ECMA_INIT_FINALIZE_H */ diff --git a/jerry-core/ecma/base/ecma-magic-strings.inc.h b/jerry-core/ecma/base/ecma-magic-strings.inc.h index 6706b8639..7302fbf6e 100644 --- a/jerry-core/ecma/base/ecma-magic-strings.inc.h +++ b/jerry-core/ecma/base/ecma-magic-strings.inc.h @@ -1,4 +1,4 @@ -/* Copyright 2014 Samsung Electronics Co., Ltd. +/* Copyright 2014-2015 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ /* * List of ECMA magic strings */ - ECMA_MAGIC_STRING_DEF (ECMA_MAGIC_STRING_ARGUMENTS, "arguments") ECMA_MAGIC_STRING_DEF (ECMA_MAGIC_STRING_EVAL, "eval") ECMA_MAGIC_STRING_DEF (ECMA_MAGIC_STRING_PROTOTYPE, "prototype") @@ -208,3 +207,8 @@ ECMA_MAGIC_STRING_DEF (ECMA_MAGIC_STRING_RIGHT_SQUARE_CHAR, "]") ECMA_MAGIC_STRING_DEF (ECMA_MAGIC_STRING_COLON_CHAR, ":") ECMA_MAGIC_STRING_DEF (ECMA_MAGIC_STRING_SPACE_CHAR, " ") ECMA_MAGIC_STRING_DEF (ECMA_MAGIC_STRING__EMPTY, "") + +/* + * Implementation-defined magic strings + */ +ECMA_MAGIC_STRING_DEF (ECMA_MAGIC_STRING_JERRY_UL, "Jerry") diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-global.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-global.inc.h index c70ca9d13..4c52a18ea 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-global.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-global.inc.h @@ -124,6 +124,13 @@ OBJECT_VALUE (ECMA_MAGIC_STRING_NUMBER_UL, ECMA_PROPERTY_CONFIGURABLE) #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_NUMBER_BUILTIN */ +// Implementation-defined property for accessing the engine's extensions */ +OBJECT_VALUE (ECMA_MAGIC_STRING_JERRY_UL, + ecma_builtin_get (ECMA_BUILTIN_ID_JERRY), + ECMA_PROPERTY_NOT_WRITABLE, + ECMA_PROPERTY_NOT_ENUMERABLE, + ECMA_PROPERTY_NOT_CONFIGURABLE) + // ECMA-262 v5, 15.1.4.7 CP_UNIMPLEMENTED_VALUE (ECMA_MAGIC_STRING_DATE_UL, ecma_builtin_get (ECMA_BUILTIN_ID_DATE), diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-internal-routines-template.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-internal-routines-template.inc.h index 286d702cf..2ca40939a 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-internal-routines-template.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-internal-routines-template.inc.h @@ -167,6 +167,8 @@ TRY_TO_INSTANTIATE_PROPERTY_ROUTINE_NAME (BUILTIN_UNDERSCORED_ID) (ecma_object_t switch (id) { + JERRY_ASSERT ((uint16_t) id == id); + #define ROUTINE(name, c_function_name, args_number, length_prop_value) case name: \ { \ ecma_object_t *func_obj_p = ecma_builtin_make_function_object_for_routine (builtin_object_id, \ @@ -273,9 +275,8 @@ TRY_TO_INSTANTIATE_PROPERTY_ROUTINE_NAME (BUILTIN_UNDERSCORED_ID) (ecma_object_t * Returned value must be freed with ecma_free_completion_value. */ ecma_completion_value_t -DISPATCH_ROUTINE_ROUTINE_NAME (BUILTIN_UNDERSCORED_ID) (ecma_magic_string_id_t builtin_routine_id, /**< built-in's - routine's - name */ +DISPATCH_ROUTINE_ROUTINE_NAME (BUILTIN_UNDERSCORED_ID) (uint16_t builtin_routine_id, /**< built-in wide routine + identifier */ const ecma_value_t& this_arg_value, /**< 'this' argument value */ const ecma_value_t arguments_list [], /**< list of arguments diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-jerry.cpp b/jerry-core/ecma/builtin-objects/ecma-builtin-jerry.cpp new file mode 100644 index 000000000..c591dbdd9 --- /dev/null +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-jerry.cpp @@ -0,0 +1,499 @@ +/* Copyright 2015 Samsung Electronics Co., Ltd. + * + * 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 + +#include "ecma-alloc.h" +#include "ecma-builtins.h" +#include "ecma-exceptions.h" +#include "ecma-extension.h" +#include "ecma-gc.h" +#include "ecma-helpers.h" +#include "ecma-objects-general.h" + +#define ECMA_BUILTINS_INTERNAL +#include "ecma-builtins-internal.h" + +/** + * List of registered extensions + */ +static jerry_extension_descriptor_t *jerry_extensions_list_p = NULL; + +/** + * Index to assign to next registered extension + */ +static uint32_t jerry_extensions_next_index = 0; + +/** + * If the property's name is one of built-in properties of the built-in object + * that is not instantiated yet, instantiate the property and + * return pointer to the instantiated property. + * + * @return pointer property, if one was instantiated, + * NULL - otherwise. + */ +ecma_property_t* +ecma_builtin_jerry_try_to_instantiate_property (ecma_object_t *obj_p, /**< object */ + ecma_string_t *extension_name_p) /**< property's name */ +{ + JERRY_ASSERT (ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_JERRY)); + JERRY_ASSERT (ecma_find_named_property (obj_p, extension_name_p) == NULL); + + ssize_t req_buffer_size = ecma_string_to_zt_string (extension_name_p, NULL, 0); + JERRY_ASSERT (req_buffer_size < 0); + + ecma_property_t *prop_p = NULL; + + MEM_DEFINE_LOCAL_ARRAY (extension_name_zt_buf_p, -req_buffer_size, uint8_t); + + req_buffer_size = ecma_string_to_zt_string (extension_name_p, extension_name_zt_buf_p, -req_buffer_size); + JERRY_ASSERT (req_buffer_size > 0); + +#if CONFIG_ECMA_CHAR_ENCODING != CONFIG_ECMA_CHAR_ASCII + JERRY_UNIMPLEMENTED ("Only ASCII encoding support is implemented."); +#else /* CONFIG_ECMA_CHAR_ENCODING == CONFIG_ECMA_CHAR_ASCII */ + const char *name_p = (const char*) extension_name_zt_buf_p; + + jerry_extension_descriptor_t *desc_p; + for (desc_p = jerry_extensions_list_p; + desc_p != NULL; + desc_p = desc_p->next_p) + { + if (!strcmp (name_p, desc_p->name_p)) + { + break; + } + } + + if (desc_p == NULL) + { + /* no extension with specified name was found */ + prop_p = NULL; + } + else + { + prop_p = ecma_create_named_data_property (obj_p, + extension_name_p, + ECMA_PROPERTY_NOT_WRITABLE, + ECMA_PROPERTY_NOT_ENUMERABLE, + ECMA_PROPERTY_NOT_CONFIGURABLE); + + ecma_object_t *extension_object_p = ecma_create_object (NULL, + false, + ECMA_OBJECT_TYPE_EXTENSION); + ecma_set_object_is_builtin (extension_object_p, true); + ecma_property_t *extension_id_prop_p = ecma_create_internal_property (extension_object_p, + ECMA_INTERNAL_PROPERTY_EXTENSION_ID); + extension_id_prop_p->u.internal_property.value = desc_p->index; + + ecma_named_data_property_assign_value (obj_p, prop_p, ecma_make_object_value (extension_object_p)); + + ecma_deref_object (extension_object_p); + } +#endif /* CONFIG_ECMA_CHAR_ENCODING == CONFIG_ECMA_CHAR_ASCII */ + + MEM_FINALIZE_LOCAL_ARRAY (extension_name_zt_buf_p); + + return prop_p; +} /* ecma_builtin_jerry_try_to_instantiate_property */ + +/** + * Stub for dispatcher of the built-in's routines + * + * Warning: + * does not return (the stub should be unreachable) + */ +ecma_completion_value_t +ecma_builtin_jerry_dispatch_routine (uint16_t builtin_routine_id, /**< built-in wide identifier of routine */ + const ecma_value_t& this_arg_value __attr_unused___, /**< 'this' argument value */ + const ecma_value_t arguments_list [], /**< list of arguments + passed to routine */ + ecma_length_t arguments_number) /**< length of arguments' list */ +{ + uint32_t extension_object_index = builtin_routine_id / ECMA_EXTENSION_MAX_FUNCTIONS_IN_EXTENSION; + uint32_t function_index = builtin_routine_id % ECMA_EXTENSION_MAX_FUNCTIONS_IN_EXTENSION; + + jerry_extension_descriptor_t *desc_p; + for (desc_p = jerry_extensions_list_p; + desc_p != NULL; + desc_p = desc_p->next_p) + { + if (desc_p->index == extension_object_index) + { + break; + } + } + JERRY_ASSERT (desc_p != NULL); + + JERRY_ASSERT (function_index < desc_p->functions_count); + const jerry_extension_function_t *function_p = &desc_p->functions_p [function_index]; + + bool throw_type_error = false; + if (function_p->args_number != arguments_number) + { + throw_type_error = true; + } + else + { + uint32_t arg_index; + for (arg_index = 0; arg_index < function_p->args_number; arg_index++) + { + jerry_extension_function_arg_t *arg_p = &function_p->args_p [arg_index]; + const ecma_value_t arg_value = arguments_list [arg_index]; + + if (arg_p->type == JERRY_EXTENSION_FIELD_TYPE_BOOLEAN) + { + if (!ecma_is_value_boolean (arg_value)) + { + break; + } + else + { + arg_p->v_bool = ecma_is_value_true (arg_value); + } + } + else if (arg_p->type == JERRY_EXTENSION_FIELD_TYPE_FLOAT32 + || arg_p->type == JERRY_EXTENSION_FIELD_TYPE_FLOAT64 + || arg_p->type == JERRY_EXTENSION_FIELD_TYPE_UINT32) + { + if (!ecma_is_value_number (arg_value)) + { + break; + } + else + { + ecma_number_t num_value = *ecma_get_number_from_value (arg_value); + if (arg_p->type == JERRY_EXTENSION_FIELD_TYPE_FLOAT32) + { + arg_p->v_float32 = (float) num_value; + } + else if (arg_p->type == JERRY_EXTENSION_FIELD_TYPE_FLOAT64) + { +#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32 + JERRY_UNREACHABLE (); +#elif CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 + arg_p->v_float64 = num_value; +#endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 */ + } + else if (arg_p->type == JERRY_EXTENSION_FIELD_TYPE_UINT32) + { + arg_p->v_uint32 = ecma_number_to_uint32 (num_value); + } + } + } + else + { + JERRY_ASSERT (arg_p->type == JERRY_EXTENSION_FIELD_TYPE_STRING); + +#if CONFIG_ECMA_CHAR_ENCODING != CONFIG_ECMA_CHAR_ASCII + JERRY_UNIMPLEMENTED ("Only ASCII encoding support is implemented."); +#else /* CONFIG_ECMA_CHAR_ENCODING == CONFIG_ECMA_CHAR_ASCII */ + JERRY_UNIMPLEMENTED ("String arguments are not implemented"); +#endif /* CONFIG_ECMA_CHAR_ENCODING == CONFIG_ECMA_CHAR_ASCII */ + } + } + + if (arg_index != function_p->args_number) + { + throw_type_error = true; + } + else + { + function_p->function_wrapper_p (function_p); + } + } + + if (throw_type_error) + { + return ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE)); + } + else + { + return ecma_make_empty_completion_value (); + } +} /* ecma_builtin_jerry_dispatch_routine */ + +bool +ecma_extension_register (jerry_extension_descriptor_t *extension_desc_p) /**< extension description */ +{ + if (jerry_extensions_next_index >= ECMA_EXTENSION_MAX_NUMBER_OF_EXTENSIONS) + { + return false; + } + + if (extension_desc_p->functions_count > ECMA_EXTENSION_MAX_FUNCTIONS_IN_EXTENSION) + { + return false; + } + + /* Check names intersection */ + for (uint32_t i = 0; i < extension_desc_p->fields_count; i++) + { + for (uint32_t j = 0; j < extension_desc_p->fields_count; j++) + { + if (i != j + && !strcmp (extension_desc_p->fields_p [i].field_name_p, + extension_desc_p->fields_p [j].field_name_p)) + { + return false; + } + } + } + + for (uint32_t i = 0; i < extension_desc_p->functions_count; i++) + { + if (extension_desc_p->functions_p [i].args_number >= ECMA_EXTENSION_MAX_ARGUMENTS_IN_FUNCTION) + { + return false; + } + +#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32 + /* Check if we can represent the arguments' values */ + for (uint32_t j = 0; j < extension_desc_p->functions_p [i].args_number; j++) + { + if (extension_desc_p->functions_p[i].args_p[j].type == JERRY_EXTENSION_FIELD_TYPE_FLOAT64) + { + return false; + } + } +#endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32 */ + + for (uint32_t j = 0; j < extension_desc_p->functions_count; j++) + { + if (i != j + && !strcmp (extension_desc_p->functions_p [i].function_name_p, + extension_desc_p->functions_p [j].function_name_p)) + { + return false; + } + } + } + + for (uint32_t i = 0; i < extension_desc_p->fields_count; i++) + { +#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32 + /* Check if we can represent the field's value */ + + if (extension_desc_p->fields_p[i].type == JERRY_EXTENSION_FIELD_TYPE_FLOAT64) + { + return false; + } + + if (extension_desc_p->fields_p[i].type == JERRY_EXTENSION_FIELD_TYPE_UINT32 + && ecma_number_to_uint32 (ecma_uint32_to_number (extension_desc_p->fields_p[i].v_uint32)) + != extension_desc_p->fields_p[i].v_uint32) + { + return false; + } +#endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32 */ + + for (uint32_t j = 0; j < extension_desc_p->functions_count; j++) + { + if (!strcmp (extension_desc_p->fields_p [i].field_name_p, + extension_desc_p->functions_p [j].function_name_p)) + { + return false; + } + } + } + + for (jerry_extension_descriptor_t *desc_iter_p = jerry_extensions_list_p; + desc_iter_p != NULL; + desc_iter_p = desc_iter_p->next_p) + { + if (desc_iter_p == extension_desc_p + || !strcmp (desc_iter_p->name_p, extension_desc_p->name_p)) + { + /* The extension already registered or an extension with the same name already registered */ + return false; + } + } + + extension_desc_p->next_p = jerry_extensions_list_p; + jerry_extensions_list_p = extension_desc_p; + extension_desc_p->index = jerry_extensions_next_index++; + + return true; +} /* ecma_extension_register */ + +/** + * [[GetOwnProperty]] Implementation extension object's operation + * + * @return property descriptor + */ +ecma_property_t* +ecma_op_extension_object_get_own_property (ecma_object_t *obj_p, /**< the extension object */ + ecma_string_t *property_name_p) /**< property name */ +{ + JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_EXTENSION); + + // 1. + ecma_property_t *prop_p = ecma_op_general_object_get_own_property (obj_p, property_name_p); + + // 2. + if (prop_p != NULL) + { + return prop_p; + } + +#if CONFIG_ECMA_CHAR_ENCODING != CONFIG_ECMA_CHAR_ASCII + JERRY_UNIMPLEMENTED ("Only ASCII encoding support is implemented."); +#else /* CONFIG_ECMA_CHAR_ENCODING == CONFIG_ECMA_CHAR_ASCII */ + ssize_t req_buffer_size = ecma_string_to_zt_string (property_name_p, NULL, 0); + JERRY_ASSERT (req_buffer_size < 0); + + MEM_DEFINE_LOCAL_ARRAY (property_name_zt_buf_p, -req_buffer_size, uint8_t); + + req_buffer_size = ecma_string_to_zt_string (property_name_p, property_name_zt_buf_p, -req_buffer_size); + JERRY_ASSERT (req_buffer_size > 0); + + const char *name_p = (const char*) property_name_zt_buf_p; + + ecma_property_t *extension_id_prop_p = ecma_get_internal_property (obj_p, + ECMA_INTERNAL_PROPERTY_EXTENSION_ID); + uint32_t extension_object_index = extension_id_prop_p->u.internal_property.value; + + jerry_extension_descriptor_t *desc_p; + for (desc_p = jerry_extensions_list_p; + desc_p != NULL; + desc_p = desc_p->next_p) + { + if (desc_p->index == extension_object_index) + { + break; + } + } + JERRY_ASSERT (desc_p != NULL); + + uint32_t field_index; + for (field_index = 0; + field_index < desc_p->fields_count; + field_index++) + { + if (!strcmp (name_p, desc_p->fields_p [field_index].field_name_p)) + { + break; + } + } + + if (field_index < desc_p->fields_count) + { + const jerry_extension_field_t *field_p = &desc_p->fields_p [field_index]; + + ecma_value_t value; + prop_p = ecma_create_named_data_property (obj_p, + property_name_p, + ECMA_PROPERTY_NOT_WRITABLE, + ECMA_PROPERTY_NOT_ENUMERABLE, + ECMA_PROPERTY_NOT_CONFIGURABLE); + + switch (field_p->type) + { + case JERRY_EXTENSION_FIELD_TYPE_BOOLEAN: + { + value = ecma_make_simple_value (field_p->v_bool ? ECMA_SIMPLE_VALUE_TRUE : ECMA_SIMPLE_VALUE_FALSE); + + break; + } + case JERRY_EXTENSION_FIELD_TYPE_FLOAT32: + { + ecma_number_t *num_p = ecma_alloc_number (); + *num_p = field_p->v_float32; + value = ecma_make_number_value (num_p); + + break; + } + case JERRY_EXTENSION_FIELD_TYPE_FLOAT64: + { +#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32 + JERRY_UNREACHABLE (); +#elif CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 + ecma_number_t *num_p = ecma_alloc_number (); + *num_p = field_p->v_float64; + value = ecma_make_number_value (num_p); +#endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 */ + + break; + } + case JERRY_EXTENSION_FIELD_TYPE_UINT32: + { + ecma_number_t *num_p = ecma_alloc_number (); + *num_p = ecma_uint32_to_number (field_p->v_uint32); + JERRY_ASSERT (ecma_number_to_uint32 (*num_p) == field_p->v_uint32); + value = ecma_make_number_value (num_p); + + break; + } + case JERRY_EXTENSION_FIELD_TYPE_STRING: + { + const ecma_char_t *string_p = (const ecma_char_t*) field_p->v_string; + ecma_string_t *str_p = ecma_new_ecma_string (string_p); + value = ecma_make_string_value (str_p); + + break; + } + } + + ecma_named_data_property_assign_value (obj_p, prop_p, value); + ecma_free_value (value, true); + } + else + { + uint32_t function_index; + for (function_index = 0; + function_index < desc_p->functions_count; + function_index++) + { + if (!strcmp (name_p, desc_p->functions_p [function_index].function_name_p)) + { + break; + } + } + + if (function_index < desc_p->functions_count) + { + const jerry_extension_function_t *function_p = &desc_p->functions_p [function_index]; + + /* Currently, combined identifier of extension object and extension function should fit in uint16_t. */ + JERRY_STATIC_ASSERT (ECMA_EXTENSION_MAX_NUMBER_OF_EXTENSIONS * ECMA_EXTENSION_MAX_FUNCTIONS_IN_EXTENSION + < (1ull << (sizeof (uint16_t) * JERRY_BITSINBYTE))); + + uint32_t routine_id = desc_p->index * ECMA_EXTENSION_MAX_FUNCTIONS_IN_EXTENSION + function_index; + JERRY_ASSERT ((uint16_t) routine_id == routine_id); + JERRY_STATIC_ASSERT ((ecma_number_t) ECMA_EXTENSION_MAX_ARGUMENTS_IN_FUNCTION + == ECMA_EXTENSION_MAX_ARGUMENTS_IN_FUNCTION); + ecma_number_t args_number = ecma_uint32_to_number (function_p->args_number); + JERRY_ASSERT (function_p->args_number == ecma_number_to_uint32 (args_number)); + ecma_object_t *func_obj_p = ecma_builtin_make_function_object_for_routine (ECMA_BUILTIN_ID_JERRY, + (uint16_t) routine_id, + args_number); + + prop_p = ecma_create_named_data_property (obj_p, + property_name_p, + ECMA_PROPERTY_NOT_WRITABLE, + ECMA_PROPERTY_NOT_ENUMERABLE, + ECMA_PROPERTY_NOT_CONFIGURABLE); + + ecma_named_data_property_assign_value (obj_p, prop_p, ecma_make_object_value (func_obj_p)); + + ecma_deref_object (func_obj_p); + } + } + + MEM_FINALIZE_LOCAL_ARRAY (property_name_zt_buf_p); + + return prop_p; +#endif /* CONFIG_ECMA_CHAR_ENCODING == CONFIG_ECMA_CHAR_ASCII */ +} /* ecma_op_extension_object_get_own_property */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins-internal.h b/jerry-core/ecma/builtin-objects/ecma-builtins-internal.h index bb5e18000..966aa27f9 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins-internal.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtins-internal.h @@ -48,7 +48,7 @@ /* ecma-builtins.c */ extern ecma_object_t* ecma_builtin_make_function_object_for_routine (ecma_builtin_id_t builtin_id, - ecma_magic_string_id_t routine_id, + uint16_t routine_id, ecma_number_t length_prop_num_value); extern int32_t ecma_builtin_bin_search_for_magic_string_id_in_array (const ecma_magic_string_id_t ids[], @@ -60,6 +60,7 @@ ecma_builtin_bin_search_for_magic_string_id_in_array (const ecma_magic_string_id object_class, \ object_prototype_builtin_id, \ is_extensible, \ + is_static, \ lowercase_name) \ extern ecma_completion_value_t \ ecma_builtin_ ## lowercase_name ## _dispatch_call (const ecma_value_t *arguments_list_p, \ @@ -68,7 +69,7 @@ extern ecma_completion_value_t \ ecma_builtin_ ## lowercase_name ## _dispatch_construct (const ecma_value_t *arguments_list_p, \ ecma_length_t arguments_list_len); \ extern ecma_completion_value_t \ -ecma_builtin_ ## lowercase_name ## _dispatch_routine (ecma_magic_string_id_t builtin_routine_id, \ +ecma_builtin_ ## lowercase_name ## _dispatch_routine (uint16_t builtin_routine_id, \ const ecma_value_t& this_arg_value, \ const ecma_value_t arguments_list [], \ ecma_length_t arguments_number); \ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.cpp b/jerry-core/ecma/builtin-objects/ecma-builtins.cpp index 17800e30a..84f202a6a 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.cpp @@ -33,7 +33,7 @@ static ecma_completion_value_t ecma_builtin_dispatch_routine (ecma_builtin_id_t builtin_object_id, - ecma_magic_string_id_t builtin_routine_id, + uint16_t builtin_routine_id, const ecma_value_t& this_arg_value, const ecma_value_t arguments_list [], ecma_length_t arguments_number); @@ -186,11 +186,15 @@ ecma_instantiate_builtin (ecma_builtin_id_t id) /**< built-in id */ object_class, \ object_prototype_builtin_id, \ is_extensible, \ + is_static, \ lowercase_name) \ case builtin_id: \ { \ JERRY_ASSERT (ecma_builtin_objects [builtin_id] == NULL); \ - ecma_builtin_ ## lowercase_name ## _sort_property_names (); \ + if (is_static) \ + { \ + ecma_builtin_ ## lowercase_name ## _sort_property_names (); \ + } \ \ ecma_object_t *prototype_obj_p; \ if (object_prototype_builtin_id == ECMA_BUILTIN_ID__COUNT) \ @@ -273,6 +277,7 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object * object_class, \ object_prototype_builtin_id, \ is_extensible, \ + is_static, \ lowercase_name) \ case builtin_id: \ { \ @@ -310,8 +315,8 @@ ecma_object_t* ecma_builtin_make_function_object_for_routine (ecma_builtin_id_t builtin_id, /**< identifier of built-in object that initially contains property with the routine */ - ecma_magic_string_id_t routine_id, /**< name of the built-in - object's routine property */ + uint16_t routine_id, /**< builtin-wide identifier of the built-in + object's routine property */ ecma_number_t length_prop_num_value) /**< ecma-number - value of 'length' property of function object to create */ @@ -381,10 +386,10 @@ ecma_builtin_dispatch_call (ecma_object_t *obj_p, /**< built-in object */ uint64_t routine_id_field = jrt_extract_bit_field (packed_built_in_and_routine_id, ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_ROUTINE_ID_POS, ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_ROUTINE_ID_WIDTH); - JERRY_ASSERT (routine_id_field < ECMA_MAGIC_STRING__COUNT); + JERRY_ASSERT ((uint16_t) routine_id_field == routine_id_field); ecma_builtin_id_t built_in_id = (ecma_builtin_id_t) built_in_id_field; - ecma_magic_string_id_t routine_id = (ecma_magic_string_id_t) routine_id_field; + uint16_t routine_id = (uint16_t) routine_id_field; return ecma_builtin_dispatch_routine (built_in_id, routine_id, @@ -409,6 +414,7 @@ ecma_builtin_dispatch_call (ecma_object_t *obj_p, /**< built-in object */ object_class, \ object_prototype_builtin_id, \ is_extensible, \ + is_static, \ lowercase_name) \ case builtin_id: \ { \ @@ -471,6 +477,7 @@ ecma_builtin_dispatch_construct (ecma_object_t *obj_p, /**< built-in object */ object_class, \ object_prototype_builtin_id, \ is_extensible, \ + is_static, \ lowercase_name) \ case builtin_id: \ { \ @@ -512,8 +519,9 @@ ecma_builtin_dispatch_construct (ecma_object_t *obj_p, /**< built-in object */ */ static ecma_completion_value_t ecma_builtin_dispatch_routine (ecma_builtin_id_t builtin_object_id, /**< built-in object' identifier */ - ecma_magic_string_id_t builtin_routine_id, /**< name of the built-in object's - routine property */ + uint16_t builtin_routine_id, /**< builtin-wide identifier + * of the built-in object's + * routine property */ const ecma_value_t& this_arg_value, /**< 'this' argument value */ const ecma_value_t arguments_list [], /**< list of arguments passed to routine */ ecma_length_t arguments_number) /**< length of arguments' list */ @@ -525,6 +533,7 @@ ecma_builtin_dispatch_routine (ecma_builtin_id_t builtin_object_id, /**< built-i object_class, \ object_prototype_builtin_id, \ is_extensible, \ + is_static, \ lowercase_name) \ case builtin_id: \ { \ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.h b/jerry-core/ecma/builtin-objects/ecma-builtins.h index 554f6afbc..ad4af8e26 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.h @@ -28,6 +28,7 @@ typedef enum object_class, \ object_prototype_builtin_id, \ is_extensible, \ + is_static, \ lowercase_name) \ builtin_id, #include "ecma-builtins.inc.h" diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h index a8a0a1bac..393466fa1 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h @@ -1,4 +1,4 @@ -/* Copyright 2014 Samsung Electronics Co., Ltd. +/* Copyright 2014-2015 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ BUILTIN (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE, ECMA_MAGIC_STRING_OBJECT_UL, ECMA_BUILTIN_ID__COUNT /* no prototype */, true, + true, object_prototype) /* The Object object (15.2.1) */ @@ -30,6 +31,7 @@ BUILTIN (ECMA_BUILTIN_ID_OBJECT, ECMA_MAGIC_STRING_OBJECT_UL, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE, true, + true, object) #ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_ARRAY_BUILTIN @@ -39,6 +41,7 @@ BUILTIN (ECMA_BUILTIN_ID_ARRAY_PROTOTYPE, ECMA_MAGIC_STRING_ARRAY_UL, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE, true, + true, array_prototype) /* The Array object (15.4.1) */ @@ -47,6 +50,7 @@ BUILTIN (ECMA_BUILTIN_ID_ARRAY, ECMA_MAGIC_STRING_ARRAY_UL, ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE, true, + true, array) #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_ARRAY_BUILTIN*/ @@ -57,6 +61,7 @@ BUILTIN (ECMA_BUILTIN_ID_STRING_PROTOTYPE, ECMA_MAGIC_STRING_STRING_UL, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE, true, + true, string_prototype) /* The String object (15.5.1) */ @@ -65,6 +70,7 @@ BUILTIN (ECMA_BUILTIN_ID_STRING, ECMA_MAGIC_STRING_STRING_UL, ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE, true, + true, string) #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_STRING_BUILTIN */ @@ -75,6 +81,7 @@ BUILTIN (ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE, ECMA_MAGIC_STRING_BOOLEAN_UL, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE, true, + true, boolean_prototype) /* The Boolean object (15.6.1) */ @@ -83,6 +90,7 @@ BUILTIN (ECMA_BUILTIN_ID_BOOLEAN, ECMA_MAGIC_STRING_BOOLEAN_UL, ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE, true, + true, boolean) #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_BOOLEAN_BUILTIN */ @@ -93,6 +101,7 @@ BUILTIN (ECMA_BUILTIN_ID_NUMBER_PROTOTYPE, ECMA_MAGIC_STRING_NUMBER_UL, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE, true, + true, number_prototype) /* The Number object (15.7.1) */ @@ -101,6 +110,7 @@ BUILTIN (ECMA_BUILTIN_ID_NUMBER, ECMA_MAGIC_STRING_NUMBER_UL, ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE, true, + true, number) #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_NUMBER_BUILTIN */ @@ -110,6 +120,7 @@ BUILTIN (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE, ECMA_MAGIC_STRING_FUNCTION_UL, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE, true, + true, function_prototype) /* The Function object (15.3.1) */ @@ -118,6 +129,7 @@ BUILTIN (ECMA_BUILTIN_ID_FUNCTION, ECMA_MAGIC_STRING_FUNCTION_UL, ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE, true, + true, function) #ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_MATH_BUILTIN @@ -127,6 +139,7 @@ BUILTIN (ECMA_BUILTIN_ID_MATH, ECMA_MAGIC_STRING_MATH_UL, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE, true, + true, math) #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_MATH_BUILTIN */ @@ -137,6 +150,7 @@ BUILTIN (ECMA_BUILTIN_ID_ERROR_PROTOTYPE, ECMA_MAGIC_STRING_ERROR_UL, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE, true, + true, error_prototype) /* The Error object (15.11.1) */ @@ -145,6 +159,7 @@ BUILTIN (ECMA_BUILTIN_ID_ERROR, ECMA_MAGIC_STRING_ERROR_UL, ECMA_BUILTIN_ID_ERROR_PROTOTYPE, true, + true, error) /* The EvalError.prototype object (15.11.6.1) */ @@ -153,6 +168,7 @@ BUILTIN (ECMA_BUILTIN_ID_EVAL_ERROR_PROTOTYPE, ECMA_MAGIC_STRING_ERROR_UL, ECMA_BUILTIN_ID_ERROR_PROTOTYPE, true, + true, eval_error_prototype) /* The EvalError object (15.11.6.1) */ @@ -161,6 +177,7 @@ BUILTIN (ECMA_BUILTIN_ID_EVAL_ERROR, ECMA_MAGIC_STRING_ERROR_UL, ECMA_BUILTIN_ID_EVAL_ERROR_PROTOTYPE, true, + true, eval_error) /* The RangeError.prototype object (15.11.6.2) */ @@ -169,6 +186,7 @@ BUILTIN (ECMA_BUILTIN_ID_RANGE_ERROR_PROTOTYPE, ECMA_MAGIC_STRING_ERROR_UL, ECMA_BUILTIN_ID_ERROR_PROTOTYPE, true, + true, range_error_prototype) /* The RangeError object (15.11.6.2) */ @@ -177,6 +195,7 @@ BUILTIN (ECMA_BUILTIN_ID_RANGE_ERROR, ECMA_MAGIC_STRING_ERROR_UL, ECMA_BUILTIN_ID_RANGE_ERROR_PROTOTYPE, true, + true, range_error) /* The ReferenceError.prototype object (15.11.6.3) */ @@ -185,6 +204,7 @@ BUILTIN (ECMA_BUILTIN_ID_REFERENCE_ERROR_PROTOTYPE, ECMA_MAGIC_STRING_ERROR_UL, ECMA_BUILTIN_ID_ERROR_PROTOTYPE, true, + true, reference_error_prototype) /* The ReferenceError object (15.11.6.3) */ @@ -193,6 +213,7 @@ BUILTIN (ECMA_BUILTIN_ID_REFERENCE_ERROR, ECMA_MAGIC_STRING_ERROR_UL, ECMA_BUILTIN_ID_REFERENCE_ERROR_PROTOTYPE, true, + true, reference_error) /* The SyntaxError.prototype object (15.11.6.4) */ @@ -201,6 +222,7 @@ BUILTIN (ECMA_BUILTIN_ID_SYNTAX_ERROR_PROTOTYPE, ECMA_MAGIC_STRING_ERROR_UL, ECMA_BUILTIN_ID_ERROR_PROTOTYPE, true, + true, syntax_error_prototype) /* The SyntaxError object (15.11.6.4) */ @@ -209,6 +231,7 @@ BUILTIN (ECMA_BUILTIN_ID_SYNTAX_ERROR, ECMA_MAGIC_STRING_ERROR_UL, ECMA_BUILTIN_ID_SYNTAX_ERROR_PROTOTYPE, true, + true, syntax_error) /* The TypeError.prototype object (15.11.6.5) */ @@ -217,6 +240,7 @@ BUILTIN (ECMA_BUILTIN_ID_TYPE_ERROR_PROTOTYPE, ECMA_MAGIC_STRING_ERROR_UL, ECMA_BUILTIN_ID_ERROR_PROTOTYPE, true, + true, type_error_prototype) /* The TypeError object (15.11.6.5) */ @@ -225,6 +249,7 @@ BUILTIN (ECMA_BUILTIN_ID_TYPE_ERROR, ECMA_MAGIC_STRING_ERROR_UL, ECMA_BUILTIN_ID_TYPE_ERROR_PROTOTYPE, true, + true, type_error) /* The URIError.prototype object (15.11.6.6) */ @@ -233,6 +258,7 @@ BUILTIN (ECMA_BUILTIN_ID_URI_ERROR_PROTOTYPE, ECMA_MAGIC_STRING_ERROR_UL, ECMA_BUILTIN_ID_ERROR_PROTOTYPE, true, + true, uri_error_prototype) /* The URIError object (15.11.6.6) */ @@ -241,6 +267,7 @@ BUILTIN (ECMA_BUILTIN_ID_URI_ERROR, ECMA_MAGIC_STRING_ERROR_UL, ECMA_BUILTIN_ID_URI_ERROR_PROTOTYPE, true, + true, uri_error) #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_ERROR_BUILTINS */ @@ -250,6 +277,7 @@ BUILTIN (ECMA_BUILTIN_ID_TYPE_ERROR_THROWER, ECMA_MAGIC_STRING_FUNCTION_UL, ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE, false, + true, type_error_thrower) #ifdef CONFIG_ECMA_COMPACT_PROFILE @@ -259,6 +287,7 @@ BUILTIN (ECMA_BUILTIN_ID_COMPACT_PROFILE_ERROR, ECMA_MAGIC_STRING_COMPACT_PROFILE_ERROR_UL, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE, false, + true, compact_profile_error) #endif /* CONFIG_ECMA_COMPACT_PROFILE */ @@ -268,6 +297,16 @@ BUILTIN (ECMA_BUILTIN_ID_GLOBAL, ECMA_MAGIC_STRING_OBJECT_UL, ECMA_BUILTIN_ID__COUNT /* no prototype */, true, + true, global) +/* Jerry's dynamic extension proxy object */ +BUILTIN (ECMA_BUILTIN_ID_JERRY, + ECMA_OBJECT_TYPE_GENERAL, + ECMA_MAGIC_STRING_OBJECT_UL, + ECMA_BUILTIN_ID__COUNT, /* no prototype */ + false, + false, + jerry) + #undef BUILTIN diff --git a/jerry-core/ecma/builtin-objects/ecma-extension.h b/jerry-core/ecma/builtin-objects/ecma-extension.h new file mode 100644 index 000000000..313b3d53c --- /dev/null +++ b/jerry-core/ecma/builtin-objects/ecma-extension.h @@ -0,0 +1,40 @@ +/* Copyright 2015 Samsung Electronics Co., Ltd. + * + * 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_EXTENSION_H +#define ECMA_EXTENSION_H + +#include "ecma-globals.h" +#include "jerry-extension.h" + +/** + * Maximum number of registered extensions + */ +#define ECMA_EXTENSION_MAX_NUMBER_OF_EXTENSIONS (CONFIG_EXTENSION_MAX_NUMBER_OF_EXTENSIONS) + +/** + * Maximum number of functions in an extension + */ +#define ECMA_EXTENSION_MAX_FUNCTIONS_IN_EXTENSION (CONFIG_EXTENSION_MAX_FUNCTIONS_IN_EXTENSION) + +/** + * Maximum number of arguments in a function + */ +#define ECMA_EXTENSION_MAX_ARGUMENTS_IN_FUNCTION (CONFIG_EXTENSION_MAX_ARGUMENTS_IN_FUNCTION) + +extern bool ecma_extension_register (jerry_extension_descriptor_t *extension_desc_p); +extern ecma_property_t* ecma_op_extension_object_get_own_property (ecma_object_t*, ecma_string_t*); + +#endif /* ECMA_EXTENSION_H */ diff --git a/jerry-core/ecma/operations/ecma-get-put-value.cpp b/jerry-core/ecma/operations/ecma-get-put-value.cpp index 0858e0efa..813d56ff1 100644 --- a/jerry-core/ecma/operations/ecma-get-put-value.cpp +++ b/jerry-core/ecma/operations/ecma-get-put-value.cpp @@ -25,7 +25,6 @@ #include "ecma-objects.h" #include "ecma-function-object.h" #include "ecma-objects-general.h" -#include "ecma-operations.h" #include "ecma-try-catch-macro.h" /** \addtogroup ecma ECMA diff --git a/jerry-core/ecma/operations/ecma-objects.cpp b/jerry-core/ecma/operations/ecma-objects.cpp index 852694229..616e0f418 100644 --- a/jerry-core/ecma/operations/ecma-objects.cpp +++ b/jerry-core/ecma/operations/ecma-objects.cpp @@ -16,6 +16,7 @@ #include "ecma-array-object.h" #include "ecma-builtins.h" #include "ecma-exceptions.h" +#include "ecma-extension.h" #include "ecma-globals.h" #include "ecma-function-object.h" #include "ecma-lcache.h" @@ -58,6 +59,7 @@ ecma_op_object_get (ecma_object_t *obj_p, /**< the object */ case ECMA_OBJECT_TYPE_FUNCTION: case ECMA_OBJECT_TYPE_BOUND_FUNCTION: case ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION: + case ECMA_OBJECT_TYPE_EXTENSION: case ECMA_OBJECT_TYPE_STRING: { return ecma_op_general_object_get (obj_p, property_name_p); @@ -121,6 +123,13 @@ ecma_op_object_get_own_property_longpath (ecma_object_t *obj_p, /**< the object break; } + case ECMA_OBJECT_TYPE_EXTENSION: + { + prop_p = ecma_op_extension_object_get_own_property (obj_p, property_name_p); + + break; + } + default: { JERRY_ASSERT (false); @@ -132,7 +141,8 @@ ecma_op_object_get_own_property_longpath (ecma_object_t *obj_p, /**< the object if (unlikely (prop_p == NULL)) { if (is_builtin - && type != ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION) + && type != ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION + && type != ECMA_OBJECT_TYPE_EXTENSION) { prop_p = ecma_builtin_try_to_instantiate_property (obj_p, property_name_p); } @@ -199,6 +209,7 @@ ecma_op_object_get_property (ecma_object_t *obj_p, /**< the object */ * [ECMA_OBJECT_TYPE_FUNCTION] = &ecma_op_general_object_get_property, * [ECMA_OBJECT_TYPE_BOUND_FUNCTION] = &ecma_op_general_object_get_property, * [ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION] = &ecma_op_general_object_get_property, + * [ECMA_OBJECT_TYPE_EXTENSION] = &ecma_op_general_object_get_property, * [ECMA_OBJECT_TYPE_ARGUMENTS] = &ecma_op_general_object_get_property, * [ECMA_OBJECT_TYPE_STRING] = &ecma_op_general_object_get_property * }; @@ -240,6 +251,7 @@ ecma_op_object_put (ecma_object_t *obj_p, /**< the object */ * [ECMA_OBJECT_TYPE_FUNCTION] = &ecma_op_general_object_put, * [ECMA_OBJECT_TYPE_BOUND_FUNCTION] = &ecma_op_general_object_put, * [ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION] = &ecma_op_general_object_put, + * [ECMA_OBJECT_TYPE_EXTENSION] = &ecma_op_general_object_put, * [ECMA_OBJECT_TYPE_ARGUMENTS] = &ecma_op_general_object_put, * [ECMA_OBJECT_TYPE_STRING] = &ecma_op_general_object_put * }; @@ -279,6 +291,7 @@ ecma_op_object_can_put (ecma_object_t *obj_p, /**< the object */ * [ECMA_OBJECT_TYPE_FUNCTION] = &ecma_op_general_object_can_put, * [ECMA_OBJECT_TYPE_BOUND_FUNCTION] = &ecma_op_general_object_can_put, * [ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION] = &ecma_op_general_object_can_put, + * [ECMA_OBJECT_TYPE_EXTENSION] = &ecma_op_general_object_can_put, * [ECMA_OBJECT_TYPE_ARGUMENTS] = &ecma_op_general_object_can_put, * [ECMA_OBJECT_TYPE_STRING] = &ecma_op_general_object_can_put * }; @@ -317,6 +330,7 @@ ecma_op_object_delete (ecma_object_t *obj_p, /**< the object */ case ECMA_OBJECT_TYPE_FUNCTION: case ECMA_OBJECT_TYPE_BOUND_FUNCTION: case ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION: + case ECMA_OBJECT_TYPE_EXTENSION: case ECMA_OBJECT_TYPE_STRING: { return ecma_op_general_object_delete (obj_p, @@ -368,6 +382,7 @@ ecma_op_object_default_value (ecma_object_t *obj_p, /**< the object */ * [ECMA_OBJECT_TYPE_FUNCTION] = &ecma_op_general_object_default_value, * [ECMA_OBJECT_TYPE_BOUND_FUNCTION] = &ecma_op_general_object_default_value, * [ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION] = &ecma_op_general_object_default_value, + * [ECMA_OBJECT_TYPE_EXTENSION] = &ecma_op_general_object_default_value, * [ECMA_OBJECT_TYPE_ARGUMENTS] = &ecma_op_general_object_default_value, * [ECMA_OBJECT_TYPE_STRING] = &ecma_op_general_object_default_value * }; @@ -407,6 +422,7 @@ ecma_op_object_define_own_property (ecma_object_t *obj_p, /**< the object */ case ECMA_OBJECT_TYPE_FUNCTION: case ECMA_OBJECT_TYPE_BOUND_FUNCTION: case ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION: + case ECMA_OBJECT_TYPE_EXTENSION: case ECMA_OBJECT_TYPE_STRING: { return ecma_op_general_object_define_own_property (obj_p, @@ -461,6 +477,7 @@ ecma_op_object_has_instance (ecma_object_t *obj_p, /**< the object */ case ECMA_OBJECT_TYPE_GENERAL: case ECMA_OBJECT_TYPE_STRING: case ECMA_OBJECT_TYPE_ARGUMENTS: + case ECMA_OBJECT_TYPE_EXTENSION: { return ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE)); } diff --git a/jerry-core/ecma/operations/ecma-string-object.cpp b/jerry-core/ecma/operations/ecma-string-object.cpp index 3706fefe1..408b635f2 100644 --- a/jerry-core/ecma/operations/ecma-string-object.cpp +++ b/jerry-core/ecma/operations/ecma-string-object.cpp @@ -119,7 +119,7 @@ ecma_op_create_string_object (const ecma_value_t *arguments_list_p, /**< list of * Returned value must be freed with ecma_free_completion_value */ ecma_property_t* -ecma_op_string_object_get_own_property (ecma_object_t *obj_p, /**< the array object */ +ecma_op_string_object_get_own_property (ecma_object_t *obj_p, /**< the string object */ ecma_string_t *property_name_p) /**< property name */ { JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_STRING); diff --git a/jerry-core/jerry-extension.cpp b/jerry-core/jerry-extension.cpp deleted file mode 100644 index c12848707..000000000 --- a/jerry-core/jerry-extension.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright 2015 Samsung Electronics Co., Ltd. - * - * 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 "config.h" -#include "jerry-extension.h" -#include "jrt.h" - -/** \addtogroup jerry Jerry engine extension interface - * @{ - */ - -/** - * Buffer of character data (used for exchange between core and extensions' routines) - */ -char jerry_extension_characters_buffer [CONFIG_EXTENSION_CHAR_BUFFER_SIZE]; - -/** - * Extend Global scope with specified extension object - * - * After extension the object is accessible through non-configurable property - * with name equal to builtin_object_name converted to ecma chars. - */ -void -jerry_extend_with (const char *builtin_object_name, /**< name of the extension object */ - const jerry_extension_descriptor_t *desc_p) /**< description of the extension object */ -{ - JERRY_UNIMPLEMENTED_REF_UNUSED_VARS (builtin_object_name, desc_p); -} /* jerry_extend_with */ - -/** - * @} - */ diff --git a/jerry-core/jerry-extension.h b/jerry-core/jerry-extension.h index cdfc83b06..a2bb883fd 100644 --- a/jerry-core/jerry-extension.h +++ b/jerry-core/jerry-extension.h @@ -29,7 +29,9 @@ typedef enum { JERRY_EXTENSION_FIELD_TYPE_BOOLEAN, /**< bool */ - JERRY_EXTENSION_FIELD_TYPE_FLOAT, /**< float */ + JERRY_EXTENSION_FIELD_TYPE_FLOAT32, /**< 32-bit float */ + JERRY_EXTENSION_FIELD_TYPE_FLOAT64, /**< 64-bit float */ + JERRY_EXTENSION_FIELD_TYPE_UINT32, /**< number converted to 32-bit unsigned integer*/ JERRY_EXTENSION_FIELD_TYPE_STRING /**< chars buffer */ } jerry_extension_data_type_t; @@ -38,6 +40,8 @@ typedef enum */ typedef struct { + const char *field_name_p; /**< field name */ + jerry_extension_data_type_t type; /**< field data type */ /** @@ -45,12 +49,17 @@ typedef struct */ union { - bool v_boolean; /**< boolean */ - float v_float; /**< number */ const char* v_string; /**< string */ + bool v_bool; /**< boolean */ + float v_float32; /**< 32-bit float */ + double v_float64; /**< 64-bit float */ + uint32_t v_uint32; /**< 32-bit unsigned integer */ }; } jerry_extension_field_t; +/** + * Description of an extension function's argument + */ typedef struct { jerry_extension_data_type_t type; /**< argument data type */ @@ -59,7 +68,10 @@ typedef struct { bool v_bool; /**< boolean */ - float v_float; /**< number converted to float */ + float v_float32; /**< 32-bit float */ + double v_float64; /**< 64-bit float */ + + uint32_t v_uint32; /**< number converted 32-bit unsigned integer */ /** String copied to external characters buffer (not zero-terminated) */ struct @@ -70,13 +82,20 @@ typedef struct }; } jerry_extension_function_arg_t; +/** + * Pointer to extension function implementation + */ +typedef void (*jerry_extension_function_pointer_t) (const struct jerry_extension_function_t *function_block_p); + /** * Description of an extension object's function */ -typedef struct +typedef struct jerry_extension_function_t { const char* function_name_p; /**< name of function */ + jerry_extension_function_pointer_t function_wrapper_p; /**< pointer to function implementation */ + jerry_extension_function_arg_t *args_p; /**< arrays of the function's arguments */ uint32_t args_number; /**< number of arguments */ } jerry_extension_function_t; @@ -84,18 +103,21 @@ typedef struct /** * Description of an extention object */ -typedef struct +typedef struct jerry_extension_descriptor_t { - uint32_t fields_count; /**< number of fields */ - uint32_t functions_count; /**< number of functions */ + const uint32_t fields_count; /**< number of fields */ + const uint32_t functions_count; /**< number of functions */ - const jerry_extension_field_t *fields_p; /**< array of field descriptor */ - const jerry_extension_function_t *functions_p; /**< array of function descriptors */ + const jerry_extension_field_t* const fields_p; /**< array of field descriptor */ + const jerry_extension_function_t* const functions_p; /**< array of function descriptors */ + + const char* const name_p; /**< name of the extension */ + struct jerry_extension_descriptor_t *next_p; /**< next descriptor in list of registered extensions */ + uint32_t index; /**< global index of the extension among registered exceptions */ } jerry_extension_descriptor_t; -extern void -jerry_extend_with (const char *builtin_object_name, - const jerry_extension_descriptor_t *desc_p); +extern bool +jerry_extend_with (jerry_extension_descriptor_t *desc_p); /** * @} diff --git a/jerry-core/jerry-extension.inc.h b/jerry-core/jerry-extension.inc.h new file mode 100644 index 000000000..c3de1f723 --- /dev/null +++ b/jerry-core/jerry-extension.inc.h @@ -0,0 +1,110 @@ +/* Copyright 2015 Samsung Electronics Co., Ltd. + * + * 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 "jerry.h" + +/* Counting fields */ +enum +{ +#define EXTENSION_FIELD(_field_name, _type, _value) \ + JERRY_EXTENSION_ ## EXTENSION_NAME ## _ ## _field_name, +# include EXTENSION_DESCRIPTION_HEADER +#undef EXTENSION_FIELD + JERRY_EXTENSION_FIELDS_NUMBER +}; + +/* Counting functions */ +enum +{ +#define EXTENSION_FUNCTION(_function_name, _function_wrapper, _args_number, ... /* args */) \ + JERRY_EXTENSION_ ## EXTENSION_NAME ## _ ## _function_name, +# include EXTENSION_DESCRIPTION_HEADER +#undef EXTENSION_FUNCTION + JERRY_EXTENSION_FUNCTIONS_NUMBER +}; + +/* Fields description */ +static const jerry_extension_field_t jerry_extension_fields [JERRY_EXTENSION_FIELDS_NUMBER + 1] = +{ +#define EXTENSION_FIELD(_field_name, _type, _value) \ + { # _field_name, JERRY_EXTENSION_FIELD_TYPE_ ## _type, _value }, +# include EXTENSION_DESCRIPTION_HEADER +#undef EXTENSION_FIELD +}; + +/* Functions wrapper definitions */ +#define EXTENSION_ARG_PASS_BOOL(_arg_index) \ + args_p [_arg_index].v_bool +#define EXTENSION_ARG_PASS_FLOAT32(_arg_index) \ + args_p [_arg_index].v_float32 +#define EXTENSION_ARG_PASS_FLOAT64(_arg_index) \ + args_p [_arg_index].v_float64 +#define EXTENSION_ARG_PASS_UINT32(_arg_index) \ + args_p [_arg_index].v_uint32 +#define EXTENSION_ARG_PASS_STRING(_arg_index) \ + (const char*) args_p [_arg_index].v_string.chars_p, \ + args_p [_arg_index].v_string.length +#define EXTENSION_ARG(_arg_index, _type) EXTENSION_ARG_PASS_ ## _type(_arg_index) +#define EXTENSION_FUNCTION(_function_name, _function_to_call, _args_number, ...) \ + static void jerry_extension_ ## _function_name ## _wrapper (const jerry_extension_function_t *function_block_p) \ + { \ + const jerry_extension_function_arg_t *args_p = function_block_p->args_p; \ + _function_to_call (__VA_ARGS__); \ + } +# include EXTENSION_DESCRIPTION_HEADER +#undef EXTENSION_FUNCTION +#undef EXTENSION_ARG +#undef EXTENSION_ARG_PASS_STRING +#undef EXTENSION_ARG_PASS_UINT32 +#undef EXTENSION_ARG_PASS_FLOAT64 +#undef EXTENSION_ARG_PASS_FLOAT32 +#undef EXTENSION_ARG_PASS_BOOL + +/* Functions' arguments description */ +#define EXTENSION_ARG(_arg_index, _type) [_arg_index] = { \ + (JERRY_EXTENSION_FIELD_TYPE_ ## _type), \ + false /* just for initialization, should be overwritten upon call */ \ +} +#define EXTENSION_FUNCTION(_function_name, _function_to_call, _args_number, ...) \ + static jerry_extension_function_arg_t jerry_extension_function_ ## _function_name ## _args [_args_number] = { \ + __VA_ARGS__ \ + }; +# include EXTENSION_DESCRIPTION_HEADER +#undef EXTENSION_FUNCTION +#undef EXTENSION_ARG + +/* Functions description */ +static const jerry_extension_function_t jerry_extension_functions [JERRY_EXTENSION_FUNCTIONS_NUMBER + 1] = +{ +#define EXTENSION_FUNCTION(_function_name, _function_wrapper, _args_number, ...) \ + { \ + # _function_name, jerry_extension_ ## _function_name ## _wrapper, \ + jerry_extension_function_ ## _function_name ## _args, \ + _args_number \ + }, +# include EXTENSION_DESCRIPTION_HEADER +#undef EXTENSION_FUNCTION +}; + +static jerry_extension_descriptor_t jerry_extension +{ + JERRY_EXTENSION_FIELDS_NUMBER, + JERRY_EXTENSION_FUNCTIONS_NUMBER, + jerry_extension_fields, + jerry_extension_functions, + EXTENSION_NAME, + NULL, + 0 /* just for initialization, should be overwritten upon registration */ +}; diff --git a/jerry-core/jerry.cpp b/jerry-core/jerry.cpp index 3fc04d916..fd7f49006 100644 --- a/jerry-core/jerry.cpp +++ b/jerry-core/jerry.cpp @@ -14,7 +14,8 @@ */ #include "deserializer.h" -#include "ecma-operations.h" +#include "ecma-extension.h" +#include "ecma-init-finalize.h" #include "jerry.h" #include "jrt.h" #include "parser.h" @@ -41,6 +42,31 @@ const char *jerry_branch_name = JERRY_BRANCH_NAME; */ static jerry_flag_t jerry_flags; +/** \addtogroup jerry Jerry engine extension interface + * @{ + */ + +/** + * Buffer of character data (used for exchange between core and extensions' routines) + */ +char jerry_extension_characters_buffer [CONFIG_EXTENSION_CHAR_BUFFER_SIZE]; + +/** + * Extend Global scope with specified extension object + * + * After extension the object is accessible through non-configurable property + * with name equal to builtin_object_name converted to ecma chars. + */ +bool +jerry_extend_with (jerry_extension_descriptor_t *desc_p) /**< description of the extension object */ +{ + return ecma_extension_register (desc_p); +} /* jerry_extend_with */ + +/** + * @} + */ + /** * Jerry engine initialization */ diff --git a/jerry-core/vm/opcodes-ecma-support.h b/jerry-core/vm/opcodes-ecma-support.h index 672914a37..481a67660 100644 --- a/jerry-core/vm/opcodes-ecma-support.h +++ b/jerry-core/vm/opcodes-ecma-support.h @@ -28,7 +28,6 @@ #include "ecma-number-arithmetic.h" #include "ecma-objects.h" #include "ecma-objects-general.h" -#include "ecma-operations.h" #include "ecma-reference.h" #include "ecma-try-catch-macro.h" #include "deserializer.h" diff --git a/jerry-core/vm/vm.cpp b/jerry-core/vm/vm.cpp index 0f9d2240c..13e86c82f 100644 --- a/jerry-core/vm/vm.cpp +++ b/jerry-core/vm/vm.cpp @@ -19,7 +19,6 @@ #include "ecma-globals.h" #include "ecma-helpers.h" #include "ecma-lex-env.h" -#include "ecma-operations.h" #include "ecma-stack.h" #include "jrt.h" #include "vm.h" @@ -397,6 +396,8 @@ run_int (void) ret_code = JERRY_COMPLETION_CODE_UNHANDLED_EXCEPTION; } + ecma_free_completion_value (completion); + ecma_deref_object (glob_obj_p); ecma_deref_object (lex_env_p); diff --git a/main-linux.cpp b/main-linux.cpp index 3107625b4..093727cb8 100644 --- a/main-linux.cpp +++ b/main-linux.cpp @@ -18,6 +18,8 @@ #include "jerry.h" +#include "plugins/io/init.h" + /** * Maximum command line arguments number */ @@ -174,7 +176,26 @@ main (int argc, } else { - jerry_completion_code_t ret_code = jerry_run_simple (source_p, source_size, flags); + jerry_init (flags); + + plugin_io_init (); + + jerry_completion_code_t ret_code = JERRY_COMPLETION_CODE_OK; + + if (!jerry_parse (NULL, source_p, source_size)) + { + /* unhandled SyntaxError */ + ret_code = JERRY_COMPLETION_CODE_UNHANDLED_EXCEPTION; + } + else + { + if ((flags & JERRY_FLAG_PARSE_ONLY) == 0) + { + ret_code = jerry_run (NULL); + } + } + + jerry_cleanup (); if (ret_code == JERRY_COMPLETION_CODE_OK) { diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index f6e545d2f..bcb2807e7 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -36,6 +36,7 @@ project (Jerry_Plugins CXX ASM) # Include directories set(INCLUDE_PLUGINS + io lib-device-stm) # Third-party @@ -58,7 +59,9 @@ project (Jerry_Plugins CXX ASM) ${CMAKE_SOURCE_DIR}/third-party/STM32F4-Discovery_FW_V1.1.0) # Sources - file(GLOB SOURCE_PLUGINS lib-device-stm/*.cpp) + file(GLOB SOURCE_PLUGINS + lib-device-stm/*.cpp + io/*.cpp) # Third-party # Platform-specific @@ -80,7 +83,7 @@ project (Jerry_Plugins CXX ASM) set(DEFINES_PLUGINS ${DEFINES_PLUGINS_${PLATFORM_EXT}}) set(INCLUDE_PLUGINS ${INCLUDE_PLUGINS} ${INCLUDE_THIRD_PARTY_${PLATFORM_EXT}}) -# Targets declaration +# Targets declaration string(TOLOWER ${PLATFORM_EXT} PLATFORM_L) set(TARGET_NAME plugins.${PLATFORM_L}) @@ -88,22 +91,34 @@ project (Jerry_Plugins CXX ASM) set(TARGET_NAME ${BUILD_MODE_PREFIX_${BUILD_MODE}}.${TARGET_NAME}) set(DEFINES_PLUGINS ${DEFINES_PLUGINS} ${DEFINES_PLUGINS_${BUILD_MODE}}) - # Jerry - add_library(${TARGET_NAME}.lib STATIC ${SOURCE_PLUGINS}) - set_property(TARGET ${TARGET_NAME}.lib - PROPERTY COMPILE_FLAGS "${COMPILE_FLAGS_PLUGINS} ${FLAGS_COMMON_${BUILD_MODE}}") - target_compile_definitions(${TARGET_NAME}.lib PRIVATE ${DEFINES_PLUGINS}) - target_include_directories(${TARGET_NAME}.lib PRIVATE ${INCLUDE_PLUGINS}) + function(declare_target_with_modifiers ) # modifiers are passed in ARGN implicit argument + foreach(MODIFIER ${ARGN}) + set(TARGET_NAME ${TARGET_NAME}${MODIFIER_SUFFIX_${MODIFIER}}) + endforeach() - # Third-party MCU library - if(DEFINED SOURCE_THIRD_PARTY_${PLATFORM_EXT}) - add_library(${TARGET_NAME}${SUFFIX_THIRD_PARTY_LIB} STATIC ${SOURCE_THIRD_PARTY_${PLATFORM_EXT}}) - set_property(TARGET ${TARGET_NAME}${SUFFIX_THIRD_PARTY_LIB} - PROPERTY COMPILE_FLAGS "${FLAGS_COMMON_${BUILD_MODE}}") - target_include_directories(${TARGET_NAME}${SUFFIX_THIRD_PARTY_LIB} PRIVATE ${INCLUDE_PLUGINS}) + # Jerry + add_library(${TARGET_NAME}.lib STATIC ${SOURCE_PLUGINS}) + set_property(TARGET ${TARGET_NAME}.lib + PROPERTY COMPILE_FLAGS "${COMPILE_FLAGS_PLUGINS} ${FLAGS_COMMON_${BUILD_MODE}}") + target_compile_definitions(${TARGET_NAME}.lib PRIVATE ${DEFINES_PLUGINS}) + target_include_directories(${TARGET_NAME}.lib PRIVATE ${INCLUDE_PLUGINS} ${INCLUDE_CORE_INTERFACE}) - target_link_libraries(${TARGET_NAME}.lib ${TARGET_NAME}${SUFFIX_THIRD_PARTY_LIB}) - endif() + # Third-party MCU library + if(DEFINED SOURCE_THIRD_PARTY_${PLATFORM_EXT}) + add_library(${TARGET_NAME}${SUFFIX_THIRD_PARTY_LIB} STATIC ${SOURCE_THIRD_PARTY_${PLATFORM_EXT}}) + set_property(TARGET ${TARGET_NAME}${SUFFIX_THIRD_PARTY_LIB} + PROPERTY COMPILE_FLAGS "${FLAGS_COMMON_${BUILD_MODE}}") + target_include_directories(${TARGET_NAME}${SUFFIX_THIRD_PARTY_LIB} PRIVATE ${INCLUDE_PLUGINS}) + + target_link_libraries(${TARGET_NAME}.lib ${TARGET_NAME}${SUFFIX_THIRD_PARTY_LIB}) + endif() + endfunction() + + foreach(MODIFIERS_LIST ${MODIFIERS_LISTS}) + separate_arguments(MODIFIERS_LIST) + + declare_target_with_modifiers(${MODIFIERS_LIST}) + endforeach() endfunction() declare_targets_for_build_mode(DEBUG) diff --git a/plugins/io/init.cpp b/plugins/io/init.cpp new file mode 100644 index 000000000..51845aaf9 --- /dev/null +++ b/plugins/io/init.cpp @@ -0,0 +1,38 @@ +/* Copyright 2015 Samsung Electronics Co., Ltd. + * + * 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 + +#include "init.h" +#include "jerry.h" + +static void plugin_io_print_uint32 (uint32_t); + +#include "io-extension-description.inc.h" + +void +plugin_io_init (void) +{ + jerry_extend_with (&jerry_extension); +} /* plugin_io_init */ + +/** + * Print an uint32 number without new-line to standard output + */ +static void +plugin_io_print_uint32 (uint32_t num) /**< uint32 to print */ +{ + printf ("%lu", num); +} /* print_uint32 */ diff --git a/plugins/io/init.h b/plugins/io/init.h new file mode 100644 index 000000000..cfc2ac634 --- /dev/null +++ b/plugins/io/init.h @@ -0,0 +1,21 @@ +/* Copyright 2015 Samsung Electronics Co., Ltd. + * + * 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 INIT_H +#define INIT_H + +extern void plugin_io_init (void); + +#endif /* INIT_H */ diff --git a/plugins/io/io-extension-description.inc.h b/plugins/io/io-extension-description.inc.h new file mode 100644 index 000000000..56c4c23ff --- /dev/null +++ b/plugins/io/io-extension-description.inc.h @@ -0,0 +1,38 @@ +/* Copyright 2015 Samsung Electronics Co., Ltd. + * + * 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 IO_EXTENSION_DESCRIPTION_INC_H +#define IO_EXTENSION_DESCRIPTION_INC_H + +#define EXTENSION_NAME "io" +#define EXTENSION_DESCRIPTION_HEADER "io-extension-description.inc.h" + +#include "jerry-extension.inc.h" + +#endif /* IO_EXTENSION_DESCRIPTION_INC_H */ + +#if defined (EXTENSION_FUNCTION) +EXTENSION_FUNCTION (print_uint32, plugin_io_print_uint32, + 1, + EXTENSION_ARG (0, UINT32)) +#elif defined (EXTENSION_FIELD) +#if defined (__TARGET_HOST) +EXTENSION_FIELD (platform, STRING, "linux") +#elif defined (__TARGET_MCU_STM32F3) +EXTENSION_FIELD (platform, STRING, "mcu_stm32f3") +#elif defined (__TARGET_MCU_STM32F3) +EXTENSION_FIELD (platform, STRING, "mcu_stm32f4") +#endif /* !__TARGET_MCU_STM32F3 && __TARGET_MCU_STM32F4 */ +#endif /* !EXTENSION_FUNCTION && !EXTENSION_FIELD */ diff --git a/tests/jerry/extensions.js b/tests/jerry/extensions.js new file mode 100644 index 000000000..25803aeed --- /dev/null +++ b/tests/jerry/extensions.js @@ -0,0 +1,32 @@ +// Copyright 2015 Samsung Electronics Co., Ltd. +// +// 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. + +// TODO: Test other field types +// TODO: Test functions + +assert(Jerry.io.platform === "linux"); + +Jerry.io.print_uint32 (1); + +try +{ + // Argument type mismatch + Jerry.io.print_uint32 ('1'); + + assert (false); +} +catch (e) +{ + assert (e instanceof TypeError); +}