Add ES2015 feature: ArrayBuffer (#1467)

This patch implements ArrayBuffer and ArrayBuffer.prototype built-in objects.

JerryScript-DCO-1.0-Signed-off-by: Zidong Jiang zidong.jiang@intel.com
This commit is contained in:
Zidong Jiang
2016-12-07 21:04:01 +08:00
committed by Zoltan Herczeg
parent eccfc1849e
commit 29d058cec4
67 changed files with 845 additions and 59 deletions
@@ -83,4 +83,5 @@ ROUTINE (LIT_MAGIC_STRING_REDUCE_RIGHT_UL, ecma_builtin_array_prototype_object_r
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -62,4 +62,5 @@ ROUTINE (LIT_MAGIC_STRING_IS_ARRAY_UL, ecma_builtin_array_object_is_array, 1, 1)
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -0,0 +1,141 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecma-builtin-helpers.h"
#include "ecma-builtins.h"
#include "ecma-exceptions.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-objects.h"
#include "ecma-arraybuffer-object.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#include "jrt-libc-includes.h"
#ifndef CONFIG_DISABLE_ARRAYBUFFER_BUILTIN
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-arraybuffer-prototype.inc.h"
#define BUILTIN_UNDERSCORED_ID arraybuffer_prototype
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup arraybuffer prototype ECMA ArrayBuffer.prototype object built-in
* @{
*/
/**
* The ArrayBuffer.prototype.bytelength accessor
*
* See also:
* ES2015, 24.1.4.1
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_arraybuffer_prototype_bytelength_getter (ecma_value_t this_arg) /**< this argument */
{
if (ecma_is_value_object (this_arg))
{
ecma_object_t *object_p = ecma_get_object_from_value (this_arg);
if (ecma_object_class_is (object_p, LIT_MAGIC_STRING_ARRAY_BUFFER_UL))
{
ecma_length_t len = ecma_arraybuffer_get_length (object_p);
return ecma_make_uint32_value (len);
}
}
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not a ArrayBuffer object."));
} /* ecma_builtin_arraybuffer_prototype_bytelength_getter */
/**
* The ArrayBuffer.prototype object's 'slice' routine
*
* See also:
* ES2015, 24.1.4.3
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_arraybuffer_prototype_object_slice (ecma_value_t this_arg, /**< this argument */
ecma_value_t arg1, /**< routine's first argument */
ecma_value_t arg2) /**< routine's second argument */
{
if (!ecma_is_value_object (this_arg))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not object."));
}
ecma_object_t *object_p = ecma_get_object_from_value (this_arg);
if (!ecma_object_class_is (object_p, LIT_MAGIC_STRING_ARRAY_BUFFER_UL))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not an ArrayBuffer object."));
}
ecma_length_t len = ecma_arraybuffer_get_length (object_p);
ecma_length_t start = 0, end = len;
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_OP_TO_NUMBER_TRY_CATCH (start_num,
arg1,
ret_value);
start = ecma_builtin_helper_array_index_normalize (start_num, len);
if (!ecma_is_value_undefined (arg2))
{
ECMA_OP_TO_NUMBER_TRY_CATCH (end_num,
arg2,
ret_value);
end = ecma_builtin_helper_array_index_normalize (end_num, len);
ECMA_OP_TO_NUMBER_FINALIZE (end_num);
}
ECMA_OP_TO_NUMBER_FINALIZE (start_num);
JERRY_ASSERT (start <= len && end <= len);
ecma_length_t new_len = (end >= start) ? (end - start) : 0;
ecma_object_t *new_arraybuffer_p = ecma_arraybuffer_new_object (new_len);
lit_utf8_byte_t *old_buf = ecma_arraybuffer_get_buffer (object_p);
lit_utf8_byte_t *new_buf = ecma_arraybuffer_get_buffer (new_arraybuffer_p);
memcpy (new_buf, old_buf + start, new_len);
return ecma_make_object_value (new_arraybuffer_p);
} /* ecma_builtin_arraybuffer_prototype_object_slice */
/**
* @}
* @}
* @}
*/
#endif /* !CONFIG_DISABLE_ARRAYBUFFER_BUILTIN */
@@ -0,0 +1,66 @@
/* 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 OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
#ifndef ACCESSOR_READ_WRITE
# define ACCESSOR_READ_WRITE(name, c_getter_func_name, c_setter_func_name, prop_attributes)
#endif /* !ROUTINE */
#ifndef ACCESSOR_READ_ONLY
# define ACCESSOR_READ_ONLY(name, c_getter_func_name, prop_attributes)
#endif /* !ACCESSOR_READ_ONLY */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_ARRAYBUFFER_PROTOTYPE)
/* Object properties:
* (property name, object pointer getter) */
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_ARRAYBUFFER,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
/* Readonly accessor properties */
ACCESSOR_READ_ONLY (LIT_MAGIC_STRING_BYTE_LENGTH_UL,
ecma_builtin_arraybuffer_prototype_bytelength_getter,
ECMA_PROPERTY_FIXED)
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_MAGIC_STRING_SLICE, ecma_builtin_arraybuffer_prototype_object_slice, 2, 2)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -0,0 +1,103 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecma-builtins.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-arraybuffer-object.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#ifndef CONFIG_DISABLE_ARRAYBUFFER_BUILTIN
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-arraybuffer.inc.h"
#define BUILTIN_UNDERSCORED_ID arraybuffer
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup string ECMA ArrayBuffer object built-in
* @{
*/
/**
* The ArrayBuffer object's 'isView' routine
*
* See also:
* ES2015 24.1.3.1
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_arraybuffer_object_is_view (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg) /**< argument 1 */
{
JERRY_UNUSED (this_arg);
JERRY_UNUSED (arg);
/* TODO: if arg has [[ViewArrayBuffer]], return true */
return ecma_make_boolean_value (false);
} /* ecma_builtin_arraybuffer_object_is_view */
/**
* Handle calling [[Call]] of built-in ArrayBuffer object
*
* ES2015 24.1.2 ArrayBuffer is not intended to be called as
* a function and will throw an exception when called in
* that manner.
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_arraybuffer_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
return ecma_raise_type_error (ECMA_ERR_MSG ("Constructor ArrayBuffer requires 'new'"));
} /* ecma_builtin_arraybuffer_dispatch_call */
/**
* Handle calling [[Construct]] of built-in ArrayBuffer object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_arraybuffer_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
return ecma_op_create_arraybuffer_object (arguments_list_p, arguments_list_len);
} /* ecma_builtin_arraybuffer_dispatch_construct */
/**
* @}
* @}
* @}
*/
#endif /* !CONFIG_DISABLE_ARRAYBUFFER_BUILTIN */
@@ -0,0 +1,66 @@
/* 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.
*/
/*
* ArrayBuffer built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_ARRAYBUFFER)
/* Number properties:
* (property name, number value, writable, enumerable, configurable) */
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FIXED)
/* Object properties:
* (property name, object pointer getter) */
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_ARRAYBUFFER_PROTOTYPE,
ECMA_PROPERTY_FIXED)
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
/* ES2015 24.1.3.1 */
ROUTINE (LIT_MAGIC_STRING_IS_VIEW_UL, ecma_builtin_arraybuffer_object_is_view, 1, 1)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -106,9 +106,9 @@ ecma_builtin_boolean_prototype_object_value_of (ecma_value_t this_arg) /**< this
{
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
JERRY_ASSERT (ecma_is_value_boolean (ext_object_p->u.class_prop.value));
JERRY_ASSERT (ecma_is_value_boolean (ext_object_p->u.class_prop.u.value));
return ext_object_p->u.class_prop.value;
return ext_object_p->u.class_prop.u.value;
}
}
@@ -51,3 +51,5 @@ ROUTINE (LIT_MAGIC_STRING_VALUE_OF_UL, ecma_builtin_boolean_prototype_object_va
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -58,3 +58,5 @@ NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -107,7 +107,7 @@ ecma_builtin_date_prototype_to_date_string (ecma_value_t this_arg) /**< this arg
ecma_object_t *object_p = ecma_get_object_from_value (obj_this);
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
ecma_number_t *date_num_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t,
ext_object_p->u.class_prop.value);
ext_object_p->u.class_prop.u.value);
if (ecma_number_is_nan (*date_num_p))
{
@@ -153,7 +153,7 @@ ecma_builtin_date_prototype_to_time_string (ecma_value_t this_arg) /**< this arg
ecma_object_t *object_p = ecma_get_object_from_value (obj_this);
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
ecma_number_t *prim_value_num_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t,
ext_object_p->u.class_prop.value);
ext_object_p->u.class_prop.u.value);
if (ecma_number_is_nan (*prim_value_num_p))
{
@@ -252,7 +252,7 @@ ecma_builtin_date_prototype_get_time (ecma_value_t this_arg) /**< this argument
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
ecma_number_t *date_num_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t,
ext_object_p->u.class_prop.value);
ext_object_p->u.class_prop.u.value);
return ecma_make_number_value (*date_num_p);
}
}
@@ -356,7 +356,7 @@ ecma_builtin_date_prototype_set_time (ecma_value_t this_arg, /**< this argument
ecma_object_t *object_p = ecma_get_object_from_value (this_arg);
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
ecma_number_t *date_num_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t,
ext_object_p->u.class_prop.value);
ext_object_p->u.class_prop.u.value);
*date_num_p = value;
@@ -95,3 +95,5 @@ ROUTINE (LIT_MAGIC_STRING_TO_GMT_STRING_UL, ecma_builtin_date_prototype_to_utc_s
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -553,7 +553,7 @@ ecma_builtin_date_dispatch_construct (const ecma_value_t *arguments_list_p, /**<
ecma_number_t *date_num_p = ecma_alloc_number ();
*date_num_p = prim_value_num;
ECMA_SET_INTERNAL_VALUE_POINTER (ext_object_p->u.class_prop.value, date_num_p);
ECMA_SET_INTERNAL_VALUE_POINTER (ext_object_p->u.class_prop.u.value, date_num_p);
ret_value = ecma_make_object_value (obj_p);
}
@@ -56,3 +56,5 @@ ROUTINE (LIT_MAGIC_STRING_NOW, ecma_builtin_date_now, 0, 0)
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -64,3 +64,5 @@ ROUTINE (LIT_MAGIC_STRING_TO_STRING_UL, ecma_builtin_error_prototype_object_to_s
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -58,3 +58,5 @@ OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -56,3 +56,5 @@ STRING_VALUE (LIT_MAGIC_STRING_MESSAGE,
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -58,3 +58,5 @@ OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -65,3 +65,5 @@ ROUTINE (LIT_MAGIC_STRING_BIND, ecma_builtin_function_prototype_object_bind, NON
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -58,3 +58,5 @@ NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -168,6 +168,12 @@ OBJECT_VALUE (LIT_MAGIC_STRING_JSON_U,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* !CONFIG_DISABLE_JSON_BUILTIN */
#ifndef CONFIG_DISABLE_ARRAYBUFFER_BUILTIN
OBJECT_VALUE (LIT_MAGIC_STRING_ARRAY_BUFFER_UL,
ECMA_BUILTIN_ID_ARRAYBUFFER,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* !CONFIG_DISABLE_ARRAYBUFFER_BUILTIN */
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
@@ -195,3 +201,5 @@ ROUTINE (LIT_MAGIC_STRING_UNESCAPE, ecma_builtin_global_object_unescape, 1, 1)
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -875,7 +875,7 @@ ecma_date_set_internal_property (ecma_value_t this_arg, /**< this argument */
ecma_object_t *object_p = ecma_get_object_from_value (this_arg);
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
*ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t, ext_object_p->u.class_prop.value) = value;
*ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t, ext_object_p->u.class_prop.u.value) = value;
return ecma_make_number_value (value);
} /* ecma_date_set_internal_property */
@@ -1275,7 +1275,7 @@ ecma_date_get_primitive_value (ecma_value_t this_arg) /**< this argument */
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
ecma_number_t date_num = *ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t,
ext_object_p->u.class_prop.value);
ext_object_p->u.class_prop.u.value);
ret_value = ecma_make_number_value (date_num);
}
@@ -42,6 +42,11 @@
const ecma_value_t *arguments_list_p, ecma_length_t arguments_list_len
#define ROUTINE(name, c_function_name, args_number, length_prop_value) \
static ecma_value_t c_function_name (ROUTINE_ARG_LIST_ ## args_number);
#define ACCESSOR_READ_WRITE(name, c_getter_func_name, c_setter_func_name, prop_attributes) \
static ecma_value_t c_getter_func_name (ROUTINE_ARG_LIST_0); \
static ecma_value_t c_setter_func_name (ROUTINE_ARG_LIST_1);
#define ACCESSOR_READ_ONLY(name, c_getter_func_name, prop_attributes) \
static ecma_value_t c_getter_func_name (ROUTINE_ARG_LIST_0);
#include BUILTIN_INC_HEADER_NAME
#undef ROUTINE_ARG_LIST_NON_FIXED
#undef ROUTINE_ARG_LIST_3
@@ -55,6 +60,11 @@ enum
PASTE (ECMA_ROUTINE_START_, BUILTIN_UNDERSCORED_ID) = ECMA_BUILTIN_ID__COUNT - 1,
#define ROUTINE(name, c_function_name, args_number, length_prop_value) \
ECMA_ROUTINE_ ## name ## c_function_name,
#define ACCESSOR_READ_WRITE(name, c_getter_func_name, c_setter_func_name, prop_attributes) \
ECMA_ACCESSOR_ ## name ## c_getter_func_name, \
ECMA_ACCESSOR_ ## name ## c_setter_func_name,
#define ACCESSOR_READ_ONLY(name, c_getter_func_name, prop_attributes) \
ECMA_ACCESSOR_ ## name ## c_getter_func_name,
#include BUILTIN_INC_HEADER_NAME
};
@@ -98,6 +108,20 @@ const ecma_builtin_property_descriptor_t PROPERTY_DESCRIPTOR_LIST_NAME[] =
prop_attributes, \
magic_string_id \
},
#define ACCESSOR_READ_WRITE(name, c_getter_name, c_setter_name, prop_attributes) \
{ \
name, \
ECMA_BUILTIN_PROPERTY_ACCESSOR_READ_WRITE, \
prop_attributes, \
ECMA_ACCESSOR_READ_WRITE (ECMA_ACCESSOR_ ## name ## c_getter_name, ECMA_ACCESSOR_ ## name ## c_setter_name) \
},
#define ACCESSOR_READ_ONLY(name, c_getter_func_name, prop_attributes) \
{ \
name, \
ECMA_BUILTIN_PROPERTY_ACCESSOR_READ_ONLY, \
prop_attributes, \
ECMA_ACCESSOR_ ## name ## c_getter_func_name \
},
#include BUILTIN_INC_HEADER_NAME
{
LIT_MAGIC_STRING__COUNT,
@@ -142,6 +166,20 @@ DISPATCH_ROUTINE_ROUTINE_NAME (uint16_t builtin_routine_id, /**< built-in wide r
{ \
return c_function_name (this_arg_value ROUTINE_ARG_LIST_ ## args_number); \
}
#define ACCESSOR_READ_WRITE(name, c_getter_func_name, c_setter_func_name, prop_attributes) \
case ECMA_ACCESSOR_ ## name ## c_getter_func_name: \
{ \
return c_getter_func_name(this_arg_value); \
} \
case ECMA_ACCESSOR_ ## name ## c_setter_func_name: \
{ \
return c_setter_func_name(this_arg_value ROUTINE_ARG_LIST_1); \
}
#define ACCESSOR_READ_ONLY(name, c_getter_func_name, prop_attributes) \
case ECMA_ACCESSOR_ ## name ## c_getter_func_name: \
{ \
return c_getter_func_name(this_arg_value); \
}
#include BUILTIN_INC_HEADER_NAME
#undef ROUTINE_ARG
#undef ROUTINE_ARG_LIST_0
@@ -52,3 +52,5 @@ ROUTINE (LIT_MAGIC_STRING_STRINGIFY, ecma_builtin_json_stringify, 3, 3)
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -110,3 +110,5 @@ ROUTINE (LIT_MAGIC_STRING_TAN, ecma_builtin_math_object_tan, 1, 1)
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -457,9 +457,9 @@ ecma_builtin_number_prototype_object_value_of (ecma_value_t this_arg) /**< this
{
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
JERRY_ASSERT (ecma_is_value_number (ext_object_p->u.class_prop.value));
JERRY_ASSERT (ecma_is_value_number (ext_object_p->u.class_prop.u.value));
return ecma_copy_value (ext_object_p->u.class_prop.value);
return ecma_copy_value (ext_object_p->u.class_prop.u.value);
}
}
@@ -55,3 +55,5 @@ ROUTINE (LIT_MAGIC_STRING_TO_PRECISION_UL, ecma_builtin_number_prototype_object_
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -79,3 +79,5 @@ OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -55,3 +55,5 @@ ROUTINE (LIT_MAGIC_STRING_PROPERTY_IS_ENUMERABLE_UL, ecma_builtin_object_prototy
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -74,3 +74,5 @@ ROUTINE (LIT_MAGIC_STRING_DEFINE_PROPERTY_UL, ecma_builtin_object_object_define_
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -56,3 +56,5 @@ STRING_VALUE (LIT_MAGIC_STRING_MESSAGE,
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -58,3 +58,5 @@ OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -56,3 +56,5 @@ STRING_VALUE (LIT_MAGIC_STRING_MESSAGE,
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -58,3 +58,5 @@ OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -130,7 +130,7 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument
ecma_object_t *this_obj_p = ecma_get_object_from_value (obj_this);
/* Get bytecode property. */
ecma_value_t *bc_prop_p = &(((ecma_extended_object_t *) this_obj_p)->u.class_prop.value);
ecma_value_t *bc_prop_p = &(((ecma_extended_object_t *) this_obj_p)->u.class_prop.u.value);
/* TODO: We currently have to re-compile the bytecode, because
* we can't copy it without knowing its length. */
@@ -205,7 +205,7 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument
ECMA_TRY_CATCH (obj_this, ecma_op_to_object (this_arg), ret_value);
ecma_object_t *this_obj_p = ecma_get_object_from_value (obj_this);
ecma_value_t *bc_prop_p = &(((ecma_extended_object_t *) this_obj_p)->u.class_prop.value);
ecma_value_t *bc_prop_p = &(((ecma_extended_object_t *) this_obj_p)->u.class_prop.u.value);
/* Try to compile bytecode from new source. */
const re_compiled_code_t *new_bc_p = NULL;
@@ -273,7 +273,7 @@ ecma_builtin_regexp_prototype_exec (ecma_value_t this_arg, /**< this argument */
ret_value);
ecma_object_t *obj_p = ecma_get_object_from_value (obj_this);
ecma_value_t *bytecode_prop_p = &(((ecma_extended_object_t *) obj_p)->u.class_prop.value);
ecma_value_t *bytecode_prop_p = &(((ecma_extended_object_t *) obj_p)->u.class_prop.u.value);
void *bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (void, *bytecode_prop_p);
@@ -88,3 +88,5 @@ ROUTINE (LIT_MAGIC_STRING_TO_STRING_UL, ecma_builtin_regexp_prototype_to_string,
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -49,3 +49,5 @@ OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -78,9 +78,9 @@ ecma_builtin_string_prototype_object_to_string (ecma_value_t this_arg) /**< this
{
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
JERRY_ASSERT (ecma_is_value_string (ext_object_p->u.class_prop.value));
JERRY_ASSERT (ecma_is_value_string (ext_object_p->u.class_prop.u.value));
return ecma_copy_value (ext_object_p->u.class_prop.value);
return ecma_copy_value (ext_object_p->u.class_prop.u.value);
}
}
@@ -88,3 +88,5 @@ ROUTINE (LIT_MAGIC_STRING_SUBSTR, ecma_builtin_string_prototype_object_substr, 2
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -62,3 +62,5 @@ ROUTINE (LIT_MAGIC_STRING_FROM_CHAR_CODE_UL, ecma_builtin_string_object_from_cha
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -56,3 +56,5 @@ STRING_VALUE (LIT_MAGIC_STRING_MESSAGE,
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -58,3 +58,5 @@ OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -43,3 +43,5 @@ NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -56,3 +56,5 @@ STRING_VALUE (LIT_MAGIC_STRING_MESSAGE,
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -58,3 +58,5 @@ OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -56,3 +56,5 @@ STRING_VALUE (LIT_MAGIC_STRING_MESSAGE,
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -58,3 +58,5 @@ OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY
@@ -33,6 +33,8 @@ typedef enum
ECMA_BUILTIN_PROPERTY_STRING, /**< string value property */
ECMA_BUILTIN_PROPERTY_OBJECT, /**< builtin object property */
ECMA_BUILTIN_PROPERTY_ROUTINE, /**< routine property */
ECMA_BUILTIN_PROPERTY_ACCESSOR_READ_WRITE, /**< full accessor property */
ECMA_BUILTIN_PROPERTY_ACCESSOR_READ_ONLY, /**< read-only accessor property */
ECMA_BUILTIN_PROPERTY_END, /**< last property */
} ecma_builtin_property_type_t;
+80 -14
View File
@@ -162,7 +162,7 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */
ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_STRING_UL;
ecma_string_t *prim_prop_str_value_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
ext_object_p->u.class_prop.value = ecma_make_string_value (prim_prop_str_value_p);
ext_object_p->u.class_prop.u.value = ecma_make_string_value (prim_prop_str_value_p);
break;
}
#endif /* !CONFIG_DISABLE_STRING_BUILTIN */
@@ -174,7 +174,7 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p;
ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_NUMBER_UL;
ext_object_p->u.class_prop.value = ecma_make_integer_value (0);
ext_object_p->u.class_prop.u.value = ecma_make_integer_value (0);
break;
}
#endif /* !CONFIG_DISABLE_NUMBER_BUILTIN */
@@ -186,7 +186,7 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p;
ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_BOOLEAN_UL;
ext_object_p->u.class_prop.value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
ext_object_p->u.class_prop.u.value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
break;
}
#endif /* !CONFIG_DISABLE_BOOLEAN_BUILTIN */
@@ -201,7 +201,7 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */
ecma_number_t *prim_prop_num_value_p = ecma_alloc_number ();
*prim_prop_num_value_p = ecma_number_make_nan ();
ECMA_SET_INTERNAL_VALUE_POINTER (ext_object_p->u.class_prop.value, prim_prop_num_value_p);
ECMA_SET_INTERNAL_VALUE_POINTER (ext_object_p->u.class_prop.u.value, prim_prop_num_value_p);
break;
}
#endif /* !CONFIG_DISABLE_DATE_BUILTIN */
@@ -213,7 +213,7 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p;
ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_REGEXP_UL;
ext_object_p->u.class_prop.value = ECMA_NULL_POINTER;
ext_object_p->u.class_prop.u.value = ECMA_NULL_POINTER;
break;
}
#endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */
@@ -331,6 +331,32 @@ ecma_builtin_make_function_object_for_routine (ecma_builtin_id_t builtin_id, /**
return func_obj_p;
} /* ecma_builtin_make_function_object_for_routine */
/**
* Construct a Function object for specified built-in accessor getter
*
* @return pointer to constructed accessor getter Function object
*/
static ecma_object_t *
ecma_builtin_make_function_object_for_getter_accessor (ecma_builtin_id_t builtin_id, /**< id of built-in object */
uint16_t routine_id) /**< builtin-wide id of the built-in
* object's routine property */
{
return ecma_builtin_make_function_object_for_routine (builtin_id, routine_id, 0);
} /* ecma_builtin_make_function_object_for_getter_accessor */
/**
* Construct a Function object for specified built-in accessor setter
*
* @return pointer to constructed accessor getter Function object
*/
static ecma_object_t *
ecma_builtin_make_function_object_for_setter_accessor (ecma_builtin_id_t builtin_id, /**< id of built-in object */
uint16_t routine_id) /**< builtin-wide id of the built-in
* object's routine property */
{
return ecma_builtin_make_function_object_for_routine (builtin_id, routine_id, 1);
} /* ecma_builtin_make_function_object_for_setter_accessor */
typedef const ecma_builtin_property_descriptor_t *ecma_builtin_property_list_reference_t;
static const ecma_builtin_property_list_reference_t ecma_builtin_property_list_references[] =
@@ -468,6 +494,9 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
}
ecma_value_t value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
bool is_accessor = false;
ecma_object_t *getter_p = NULL;
ecma_object_t *setter_p = NULL;
switch (curr_property_p->type)
{
@@ -551,6 +580,22 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
value = ecma_make_object_value (func_obj_p);
break;
}
case ECMA_BUILTIN_PROPERTY_ACCESSOR_READ_WRITE:
{
is_accessor = true;
uint16_t getter_id = ECMA_ACCESSOR_READ_WRITE_GET_GETTER_ID (curr_property_p->value);
uint16_t setter_id = ECMA_ACCESSOR_READ_WRITE_GET_SETTER_ID (curr_property_p->value);
getter_p = ecma_builtin_make_function_object_for_getter_accessor (builtin_id, getter_id);
setter_p = ecma_builtin_make_function_object_for_setter_accessor (builtin_id, setter_id);
break;
}
case ECMA_BUILTIN_PROPERTY_ACCESSOR_READ_ONLY:
{
is_accessor = true;
getter_p = ecma_builtin_make_function_object_for_getter_accessor (builtin_id,
curr_property_p->value);
break;
}
default:
{
JERRY_UNREACHABLE ();
@@ -559,17 +604,38 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
}
ecma_property_t *prop_p;
ecma_property_value_t *prop_value_p = ecma_create_named_data_property (object_p,
string_p,
curr_property_p->attributes,
&prop_p);
prop_value_p->value = value;
/* Reference count of objects must be decreased. */
if (ecma_is_value_object (value))
if (is_accessor)
{
ecma_free_value (value);
ecma_create_named_accessor_property (object_p,
string_p,
getter_p,
setter_p,
curr_property_p->attributes,
&prop_p);
if (setter_p)
{
ecma_deref_object (setter_p);
}
if (getter_p)
{
ecma_deref_object (getter_p);
}
}
else
{
ecma_property_value_t *prop_value_p = ecma_create_named_data_property (object_p,
string_p,
curr_property_p->attributes,
&prop_p);
prop_value_p->value = value;
/* Reference count of objects must be decreased. */
if (ecma_is_value_object (value))
{
ecma_free_value (value);
}
}
return prop_p;
@@ -49,6 +49,21 @@ typedef enum
*/
#define ECMA_GET_ROUTINE_ID(value) ((uint16_t) ((value) >> 4))
/**
* Construct a fully accessor value
*/
#define ECMA_ACCESSOR_READ_WRITE(getter, setter) (((getter) << 8) | (setter))
/**
* Get accessor setter ID
*/
#define ECMA_ACCESSOR_READ_WRITE_GET_SETTER_ID(value) ((uint16_t) ((value) & 0xff))
/**
* Get accessor getter ID
*/
#define ECMA_ACCESSOR_READ_WRITE_GET_GETTER_ID(value) ((uint16_t) ((value) >> 8))
/* ecma-builtins.c */
extern void ecma_finalize_builtins (void);
@@ -298,6 +298,25 @@ BUILTIN (ECMA_BUILTIN_ID_TYPE_ERROR_THROWER,
true,
type_error_thrower)
#ifndef CONFIG_DISABLE_ARRAYBUFFER_BUILTIN
/* The ArrayBuffer.prototype object (ES2015 24.1.4) */
BUILTIN (ECMA_BUILTIN_ID_ARRAYBUFFER_PROTOTYPE,
ECMA_OBJECT_TYPE_GENERAL,
ECMA_BUILTIN_ID_OBJECT_PROTOTYPE,
true,
true,
arraybuffer_prototype)
/* The ArrayBuffer object (ES2015 24.1.2) */
BUILTIN (ECMA_BUILTIN_ID_ARRAYBUFFER,
ECMA_OBJECT_TYPE_FUNCTION,
ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE,
true,
true,
arraybuffer)
#endif /* !CONFIG_DISABLE_ARRAYBUFFER_BUILTIN */
/* The Global object (15.1) */
BUILTIN (ECMA_BUILTIN_ID_GLOBAL,
ECMA_OBJECT_TYPE_GENERAL,