Implement DataView builtin (#2804)

New API functions:
 - jerry_create_dataview
 - jerry_value_is_dataview
 - jerry_get_dataview_buffer

JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
This commit is contained in:
Robert Fancsik
2019-04-16 08:26:39 +02:00
committed by László Langó
parent b3f4aa6816
commit 5c72d995e4
24 changed files with 1583 additions and 63 deletions
+7
View File
@@ -690,6 +690,13 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
return;
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */
#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
case LIT_MAGIC_STRING_DATAVIEW_UL:
{
ecma_dealloc_extended_object (object_p, sizeof (ecma_dataview_object_t));
return;
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) */
default:
{
/* The undefined id represents an uninitialized class. */
+12
View File
@@ -1565,6 +1565,18 @@ typedef struct
#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
/**
* Description of DataView objects.
*/
typedef struct
{
ecma_extended_object_t header; /**< header part */
ecma_object_t *buffer_p; /**< [[ViewedArrayBuffer]] internal slot */
uint32_t byte_offset; /**< [[ByteOffset]] internal slot */
} ecma_dataview_object_t;
#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */
/**
* Flag for indicating whether the symbol is a well known symbol
*
@@ -0,0 +1,215 @@
/* 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-dataview-object.h"
#include "ecma-gc.h"
#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
#ifdef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
#error "DataView builtin requires ES2015 TypedArray builtin"
#endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
/**
* This object has a custom dispatch function.
*/
#define BUILTIN_CUSTOM_DISPATCH
/**
* List of built-in routine identifiers.
*/
enum
{
ECMA_DATAVIEW_PROTOTYPE_ROUTINE_START = ECMA_BUILTIN_ID__COUNT - 1,
ECMA_DATAVIEW_PROTOTYPE_BUFFER_GETTER,
ECMA_DATAVIEW_PROTOTYPE_BYTE_LENGTH_GETTER,
ECMA_DATAVIEW_PROTOTYPE_BYTE_OFFSET_GETTER,
ECMA_DATAVIEW_PROTOTYPE_GET_INT8,
ECMA_DATAVIEW_PROTOTYPE_GET_UINT8,
ECMA_DATAVIEW_PROTOTYPE_GET_INT16,
ECMA_DATAVIEW_PROTOTYPE_GET_UINT16,
ECMA_DATAVIEW_PROTOTYPE_GET_INT32,
ECMA_DATAVIEW_PROTOTYPE_GET_UINT32,
ECMA_DATAVIEW_PROTOTYPE_GET_FLOAT32,
#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
ECMA_DATAVIEW_PROTOTYPE_GET_FLOAT64,
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
ECMA_DATAVIEW_PROTOTYPE_SET_INT8,
ECMA_DATAVIEW_PROTOTYPE_SET_UINT8,
ECMA_DATAVIEW_PROTOTYPE_SET_INT16,
ECMA_DATAVIEW_PROTOTYPE_SET_UINT16,
ECMA_DATAVIEW_PROTOTYPE_SET_INT32,
ECMA_DATAVIEW_PROTOTYPE_SET_UINT32,
ECMA_DATAVIEW_PROTOTYPE_SET_FLOAT32,
#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
ECMA_DATAVIEW_PROTOTYPE_SET_FLOAT64,
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
};
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-dataview-prototype.inc.h"
#define BUILTIN_UNDERSCORED_ID dataview_prototype
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup dataviewprototype ECMA DataView.prototype object built-in
* @{
*/
/**
* Corresponding typedarray mappings for the {get,set}{[U]int, Float}{8, 16, 32, 64} routines
*/
static const uint8_t ecma_dataview_type_mapping[] =
{
ECMA_BUILTIN_ID_INT8ARRAY,
ECMA_BUILTIN_ID_UINT8ARRAY,
ECMA_BUILTIN_ID_INT16ARRAY,
ECMA_BUILTIN_ID_UINT16ARRAY,
ECMA_BUILTIN_ID_INT32ARRAY,
ECMA_BUILTIN_ID_UINT32ARRAY,
ECMA_BUILTIN_ID_FLOAT32ARRAY,
#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
ECMA_BUILTIN_ID_FLOAT64ARRAY,
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
};
/**
* The DataView.prototype object's {buffer, byteOffset, byteLength} getters
*
* See also:
* ECMA-262 v6, 24.2.4.1
* ECMA-262 v6, 24.2.4.2
* ECMA-262 v6, 24.2.4.3
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_dataview_prototype_object_getters (ecma_value_t this_arg, /**< this argument */
uint16_t builtin_routine_id) /**< built-in wide routine identifier */
{
ecma_dataview_object_t *obj_p = ecma_op_dataview_get_object (this_arg);
if (JERRY_UNLIKELY (obj_p == NULL))
{
return ECMA_VALUE_ERROR;
}
switch (builtin_routine_id)
{
case ECMA_DATAVIEW_PROTOTYPE_BUFFER_GETTER:
{
ecma_object_t *buffer_p = obj_p->buffer_p;
ecma_ref_object (buffer_p);
return ecma_make_object_value (buffer_p);
}
case ECMA_DATAVIEW_PROTOTYPE_BYTE_LENGTH_GETTER:
{
return ecma_make_uint32_value (obj_p->header.u.class_prop.u.length);
}
default:
{
JERRY_ASSERT (builtin_routine_id == ECMA_DATAVIEW_PROTOTYPE_BYTE_OFFSET_GETTER);
return ecma_make_uint32_value (obj_p->byte_offset);
}
}
} /* ecma_builtin_dataview_prototype_object_getters */
/**
* Dispatcher of the built-in's routines
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
ecma_value_t
ecma_builtin_dataview_prototype_dispatch_routine (uint16_t builtin_routine_id, /**< built-in wide routine identifier */
ecma_value_t this_arg, /**< 'this' argument value */
const ecma_value_t arguments_list_p[], /**< list of arguments
* passed to routine */
ecma_length_t arguments_number) /**< length of arguments' list */
{
ecma_value_t byte_offset = arguments_number > 0 ? arguments_list_p[0] : ECMA_VALUE_UNDEFINED;
switch (builtin_routine_id)
{
case ECMA_DATAVIEW_PROTOTYPE_BUFFER_GETTER:
case ECMA_DATAVIEW_PROTOTYPE_BYTE_LENGTH_GETTER:
case ECMA_DATAVIEW_PROTOTYPE_BYTE_OFFSET_GETTER:
{
return ecma_builtin_dataview_prototype_object_getters (this_arg, builtin_routine_id);
}
case ECMA_DATAVIEW_PROTOTYPE_GET_FLOAT32:
#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
case ECMA_DATAVIEW_PROTOTYPE_GET_FLOAT64:
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
case ECMA_DATAVIEW_PROTOTYPE_GET_INT16:
case ECMA_DATAVIEW_PROTOTYPE_GET_INT32:
case ECMA_DATAVIEW_PROTOTYPE_GET_UINT16:
case ECMA_DATAVIEW_PROTOTYPE_GET_UINT32:
{
ecma_value_t little_endian = arguments_number > 1 ? arguments_list_p[1] : ECMA_VALUE_FALSE;
uint8_t type = ecma_dataview_type_mapping[builtin_routine_id - ECMA_DATAVIEW_PROTOTYPE_GET_INT8];
return ecma_op_dataview_get_set_view_value (this_arg, byte_offset, little_endian, ECMA_VALUE_EMPTY, type);
}
case ECMA_DATAVIEW_PROTOTYPE_SET_FLOAT32:
#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
case ECMA_DATAVIEW_PROTOTYPE_SET_FLOAT64:
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
case ECMA_DATAVIEW_PROTOTYPE_SET_INT16:
case ECMA_DATAVIEW_PROTOTYPE_SET_INT32:
case ECMA_DATAVIEW_PROTOTYPE_SET_UINT16:
case ECMA_DATAVIEW_PROTOTYPE_SET_UINT32:
{
ecma_value_t value_to_set = arguments_number > 1 ? arguments_list_p[1] : ECMA_VALUE_UNDEFINED;
ecma_value_t little_endian = arguments_number > 2 ? arguments_list_p[2] : ECMA_VALUE_FALSE;
uint8_t type = ecma_dataview_type_mapping[builtin_routine_id - ECMA_DATAVIEW_PROTOTYPE_SET_INT8];
return ecma_op_dataview_get_set_view_value (this_arg, byte_offset, little_endian, value_to_set, type);
}
case ECMA_DATAVIEW_PROTOTYPE_GET_INT8:
case ECMA_DATAVIEW_PROTOTYPE_GET_UINT8:
{
uint8_t type = ecma_dataview_type_mapping[builtin_routine_id - ECMA_DATAVIEW_PROTOTYPE_GET_INT8];
return ecma_op_dataview_get_set_view_value (this_arg, byte_offset, ECMA_VALUE_FALSE, ECMA_VALUE_EMPTY, type);
}
default:
{
JERRY_ASSERT (builtin_routine_id == ECMA_DATAVIEW_PROTOTYPE_SET_INT8
|| builtin_routine_id == ECMA_DATAVIEW_PROTOTYPE_SET_UINT8);
ecma_value_t value_to_set = arguments_number > 1 ? arguments_list_p[1] : ECMA_VALUE_UNDEFINED;
uint8_t type = ecma_dataview_type_mapping[builtin_routine_id - ECMA_DATAVIEW_PROTOTYPE_SET_INT8];
return ecma_op_dataview_get_set_view_value (this_arg, byte_offset, ECMA_VALUE_FALSE, value_to_set, type);
}
}
} /* ecma_builtin_dataview_prototype_dispatch_routine */
/**
* @}
* @}
* @}
*/
#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */
@@ -0,0 +1,79 @@
/* 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.
*/
/*
* DataView.prototype built-in description
*/
#include "ecma-builtin-helpers-macro-defines.inc.h"
#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
/* Object properties:
* (property name, object pointer getter) */
/* ECMA-262 v6, 24.2.3 */
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_DATAVIEW,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
/* ECMA-262 v6, 23.2.4.21 */
STRING_VALUE (LIT_GLOBAL_SYMBOL_TO_STRING_TAG,
LIT_MAGIC_STRING_DATAVIEW_UL,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_MAGIC_STRING_GET_FLOAT_32_UL, ECMA_DATAVIEW_PROTOTYPE_GET_FLOAT32, 2, 1)
#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
ROUTINE (LIT_MAGIC_STRING_GET_FLOAT_64_UL, ECMA_DATAVIEW_PROTOTYPE_GET_FLOAT64, 2, 1)
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
ROUTINE (LIT_MAGIC_STRING_GET_INT8_UL, ECMA_DATAVIEW_PROTOTYPE_GET_INT8, 1, 1)
ROUTINE (LIT_MAGIC_STRING_GET_INT16_UL, ECMA_DATAVIEW_PROTOTYPE_GET_INT16, 2, 1)
ROUTINE (LIT_MAGIC_STRING_GET_INT32_UL, ECMA_DATAVIEW_PROTOTYPE_GET_INT32, 2, 1)
ROUTINE (LIT_MAGIC_STRING_GET_UINT8_UL, ECMA_DATAVIEW_PROTOTYPE_GET_UINT8, 2, 1)
ROUTINE (LIT_MAGIC_STRING_GET_UINT16_UL, ECMA_DATAVIEW_PROTOTYPE_GET_UINT16, 2, 1)
ROUTINE (LIT_MAGIC_STRING_GET_UINT32_UL, ECMA_DATAVIEW_PROTOTYPE_GET_UINT32, 2, 1)
ROUTINE (LIT_MAGIC_STRING_SET_FLOAT_32_UL, ECMA_DATAVIEW_PROTOTYPE_SET_FLOAT32, 2, 1)
#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
ROUTINE (LIT_MAGIC_STRING_SET_FLOAT_64_UL, ECMA_DATAVIEW_PROTOTYPE_SET_FLOAT64, 2, 1)
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
ROUTINE (LIT_MAGIC_STRING_SET_INT8_UL, ECMA_DATAVIEW_PROTOTYPE_SET_INT8, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SET_INT16_UL, ECMA_DATAVIEW_PROTOTYPE_SET_INT16, 2, 1)
ROUTINE (LIT_MAGIC_STRING_SET_INT32_UL, ECMA_DATAVIEW_PROTOTYPE_SET_INT32, 2, 1)
ROUTINE (LIT_MAGIC_STRING_SET_UINT8_UL, ECMA_DATAVIEW_PROTOTYPE_SET_UINT8, 2, 1)
ROUTINE (LIT_MAGIC_STRING_SET_UINT16_UL, ECMA_DATAVIEW_PROTOTYPE_SET_UINT16, 2, 1)
ROUTINE (LIT_MAGIC_STRING_SET_UINT32_UL, ECMA_DATAVIEW_PROTOTYPE_SET_UINT32, 2, 1)
/* ECMA-262 v6, 24.2.4.1 */
ACCESSOR_READ_ONLY (LIT_MAGIC_STRING_BUFFER,
ECMA_DATAVIEW_PROTOTYPE_BUFFER_GETTER,
ECMA_PROPERTY_FIXED)
/* ECMA-262 v6, 24.2.4.2 */
ACCESSOR_READ_ONLY (LIT_MAGIC_STRING_BYTE_LENGTH_UL,
ECMA_DATAVIEW_PROTOTYPE_BYTE_LENGTH_GETTER,
ECMA_PROPERTY_FIXED)
/* ECMA-262 v6, 24.2.4.3 */
ACCESSOR_READ_ONLY (LIT_MAGIC_STRING_BYTE_OFFSET_UL,
ECMA_DATAVIEW_PROTOTYPE_BYTE_OFFSET_GETTER,
ECMA_PROPERTY_FIXED)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */
#include "ecma-builtin-helpers-macro-undefs.inc.h"
@@ -0,0 +1,71 @@
/* 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-dataview-object.h"
#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-dataview.inc.h"
#define BUILTIN_UNDERSCORED_ID dataview
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup dataview ECMA DataView object built-in
* @{
*/
/**
* Handle calling [[Call]] of built-in DataView object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_dataview_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 DataView requires 'new'."));
} /* ecma_builtin_dataview_dispatch_call */
/**
* Handle calling [[Construct]] of built-in DataView object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_dataview_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
return ecma_op_dataview_create (arguments_list_p, arguments_list_len);
} /* ecma_builtin_dataview_dispatch_construct */
/**
* @}
* @}
* @}
*/
#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */
@@ -0,0 +1,47 @@
/* 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.
*/
/*
* DataView built-in description
*/
#include "ecma-builtin-helpers-macro-defines.inc.h"
#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
/* Number properties:
* (property name, number value, writable, enumerable, configurable) */
/* ECMA-262 v6, 23.1.2 */
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
3,
ECMA_PROPERTY_FIXED)
/* ECMA-262 v6, 23.1 */
STRING_VALUE (LIT_MAGIC_STRING_NAME,
LIT_MAGIC_STRING_DATAVIEW_UL,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
/* Object properties:
* (property name, object pointer getter) */
/* ECMA-262 v6, 23.1.2.1 */
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_DATAVIEW_PROTOTYPE,
ECMA_PROPERTY_FIXED)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */
#include "ecma-builtin-helpers-macro-undefs.inc.h"
@@ -212,6 +212,13 @@ OBJECT_VALUE (LIT_MAGIC_STRING_SYMBOL_UL,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
/* ECMA-262 v6, 23.1.1.1 */
OBJECT_VALUE (LIT_MAGIC_STRING_DATAVIEW_UL,
ECMA_BUILTIN_ID_DATAVIEW,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
@@ -98,6 +98,13 @@ const ecma_builtin_property_descriptor_t PROPERTY_DESCRIPTOR_LIST_NAME[] =
ECMA_PROPERTY_FLAG_CONFIGURABLE, \
ECMA_ROUTINE_VALUE (ECMA_ROUTINE_ ## name ## c_function_name, length_prop_value) \
},
#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 \
},
#else /* BUILTIN_CUSTOM_DISPATCH */
#define ROUTINE(name, c_function_name, args_number, length_prop_value) \
{ \
@@ -113,6 +120,13 @@ const ecma_builtin_property_descriptor_t PROPERTY_DESCRIPTOR_LIST_NAME[] =
ECMA_PROPERTY_FLAG_CONFIGURABLE, \
ECMA_ROUTINE_VALUE (c_function_name, length_prop_value) \
},
#define ACCESSOR_READ_ONLY(name, c_getter_func_name, prop_attributes) \
{ \
name, \
ECMA_BUILTIN_PROPERTY_ACCESSOR_READ_ONLY, \
prop_attributes, \
c_getter_func_name \
},
#endif /* !BUILTIN_CUSTOM_DISPATCH */
#define OBJECT_VALUE(name, obj_builtin_id, prop_attributes) \
{ \
@@ -158,13 +172,6 @@ const ecma_builtin_property_descriptor_t PROPERTY_DESCRIPTOR_LIST_NAME[] =
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,
@@ -474,6 +474,22 @@ BUILTIN (ECMA_BUILTIN_ID_ARRAY_ITERATOR_PROTOTYPE,
array_iterator_prototype)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */
#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
/* The DataView prototype object (ECMA-262 v6, 24.2.3.1) */
BUILTIN (ECMA_BUILTIN_ID_DATAVIEW_PROTOTYPE,
ECMA_OBJECT_TYPE_GENERAL,
ECMA_BUILTIN_ID_OBJECT_PROTOTYPE,
true,
dataview_prototype)
/* The DataView routine (ECMA-262 v6, 24.2.2.1) */
BUILTIN_ROUTINE (ECMA_BUILTIN_ID_DATAVIEW,
ECMA_OBJECT_TYPE_FUNCTION,
ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE,
true,
dataview)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */
/* The Global object (15.1) */
BUILTIN (ECMA_BUILTIN_ID_GLOBAL,
ECMA_OBJECT_TYPE_GENERAL,
@@ -134,15 +134,15 @@ ecma_typedarray_helper_get_builtin_id (ecma_object_t *obj_p) /**< typedarray obj
/**
* Get the magic string of a TypedArray type.
*
* @return uint8_t
* @return lit_magic_string_id_t
*/
uint8_t
lit_magic_string_id_t
ecma_typedarray_helper_get_magic_string (uint8_t builtin_id) /**< the builtin id of the typedarray **/
{
#define TYPEDARRAY_ID_CASE(builtin_id, magic_id) \
case builtin_id: \
{ \
return magic_id; \
return (lit_magic_string_id_t) magic_id; \
}
switch (builtin_id)
@@ -29,7 +29,7 @@
bool ecma_typedarray_helper_is_typedarray (uint8_t builtin_id);
uint8_t ecma_typedarray_helper_get_shift_size (uint8_t builtin_id);
uint8_t ecma_typedarray_helper_get_builtin_id (ecma_object_t *obj_p);
uint8_t ecma_typedarray_helper_get_magic_string (uint8_t builtin_id);
lit_magic_string_id_t ecma_typedarray_helper_get_magic_string (uint8_t builtin_id);
uint8_t ecma_typedarray_helper_get_prototype_id (uint8_t builtin_id);
ecma_value_t
@@ -0,0 +1,324 @@
/* 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-arraybuffer-object.h"
#include "ecma-builtins.h"
#include "ecma-builtin-typedarray-helpers.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-helpers.h"
#include "ecma-dataview-object.h"
#include "ecma-typedarray-object.h"
#include "ecma-objects.h"
#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmadataviewobject ECMA builtin DataView helper functions
* @{
*/
/**
* Handle calling [[Construct]] of built-in DataView like objects
*
* See also:
* ECMA-262 v6, 24.2.2.1
*
* @return created DataView object as an ecma-value - if success
* raised error - otherwise
*/
ecma_value_t
ecma_op_dataview_create (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);
ecma_value_t buffer = arguments_list_len > 0 ? arguments_list_p[0] : ECMA_VALUE_UNDEFINED;
/* 2. */
if (!ecma_is_value_object (buffer))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument buffer is not an object."));
}
ecma_object_t *buffer_p = ecma_get_object_from_value (buffer);
/* 3. */
if (!ecma_object_class_is (buffer_p, LIT_MAGIC_STRING_ARRAY_BUFFER_UL))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument buffer is not an arraybuffer."));
}
/* 4 - 6. */
int32_t offset = 0;
if (arguments_list_len > 1)
{
ecma_number_t number_offset;
ecma_value_t number_offset_value = ecma_get_number (arguments_list_p[1], &number_offset);
if (ECMA_IS_VALUE_ERROR (number_offset_value))
{
return number_offset_value;
}
offset = ecma_number_to_int32 (number_offset);
/* 7. */
if (number_offset != offset || offset < 0)
{
return ecma_raise_range_error (ECMA_ERR_MSG ("Start offset is outside the bounds of the buffer."));
}
}
/* 8. TODO: Throw TypeError, when Detached ArrayBuffer will be supported. */
/* 9. */
ecma_length_t buffer_byte_length = ecma_arraybuffer_get_length (buffer_p);
/* 10. */
if ((ecma_length_t) offset > buffer_byte_length)
{
return ecma_raise_range_error (ECMA_ERR_MSG ("Start offset is outside the bounds of the buffer."));
}
/* 11 - 12. */
uint32_t viewByteLength;
if (arguments_list_len > 2)
{
/* 12.a */
ecma_number_t byte_length;
ecma_value_t byte_length_value = ecma_get_number (arguments_list_p[2], &byte_length);
/* 12.b */
if (ECMA_IS_VALUE_ERROR (byte_length_value))
{
return byte_length_value;
}
int32_t byte_length_int32 = ecma_number_to_int32 (byte_length);
if (ecma_number_is_infinity (byte_length))
{
viewByteLength = UINT32_MAX;
}
else if (byte_length_int32 <= 0)
{
viewByteLength = 0;
}
else
{
viewByteLength = JERRY_MIN ((ecma_length_t) byte_length_int32, UINT32_MAX);
}
/* 12.c */
if ((ecma_length_t) offset + viewByteLength > buffer_byte_length)
{
return ecma_raise_range_error (ECMA_ERR_MSG ("Start offset is outside the bounds of the buffer."));
}
}
else
{
/* 11.a */
viewByteLength = (uint32_t) (buffer_byte_length - (ecma_length_t) offset);
}
/* 13. */
ecma_object_t *object_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_DATAVIEW_PROTOTYPE),
sizeof (ecma_dataview_object_t),
ECMA_OBJECT_TYPE_CLASS);
ecma_dataview_object_t *dataview_obj_p = (ecma_dataview_object_t *) object_p;
dataview_obj_p->header.u.class_prop.class_id = LIT_MAGIC_STRING_DATAVIEW_UL;
dataview_obj_p->header.u.class_prop.u.length = viewByteLength;
dataview_obj_p->buffer_p = buffer_p;
dataview_obj_p->byte_offset = (uint32_t) offset;
return ecma_make_object_value (object_p);
} /* ecma_op_dataview_create */
/**
* Get the DataView object pointer
*
* Note:
* If the function returns with NULL, the error object has
* already set, and the caller must return with ECMA_VALUE_ERROR
*
* @return pointer to the dataView if this_arg is a valid dataView object
* NULL otherwise
*/
ecma_dataview_object_t *
ecma_op_dataview_get_object (ecma_value_t this_arg) /**< this argument */
{
if (ecma_is_value_object (this_arg))
{
ecma_dataview_object_t *dataview_object_p = (ecma_dataview_object_t *) ecma_get_object_from_value (this_arg);
if (ecma_get_object_type (&dataview_object_p->header.object) == ECMA_OBJECT_TYPE_CLASS
&& dataview_object_p->header.u.class_prop.class_id == LIT_MAGIC_STRING_DATAVIEW_UL)
{
return dataview_object_p;
}
}
ecma_raise_type_error (ECMA_ERR_MSG ("Expected a DataView object."));
return NULL;
} /* ecma_op_dataview_get_object */
/**
* Helper union to specify the system's endiannes
*/
typedef union
{
uint32_t number; /**< for write numeric data */
char data[sizeof (uint32_t)]; /**< for read numeric data */
} ecma_dataview_endiannes_check_t;
/**
* Helper function to check the current system endiannes
*
* @return true - if the current system has little endian byteorder
* false - otherwise
*/
static bool
ecma_dataview_check_little_endian (void)
{
ecma_dataview_endiannes_check_t checker;
checker.number = 0x01;
return checker.data[0] == 0x01;
} /* ecma_dataview_check_little_endian */
/**
* Helper function for swap bytes if the system's endiannes
* does not match with the requested endiannes.
*/
static void
ecma_dataview_swap_order (bool system_is_little_endian, /**< true - if the system has little endian byteorder
* false - otherwise */
bool is_little_endian, /**< true - if little endian byteorder is requested
* false - otherwise */
uint32_t element_size, /**< element size byte according to the Table 49.*/
lit_utf8_byte_t *block_p) /**< data block */
{
if (system_is_little_endian ^ is_little_endian)
{
for (uint32_t i = 0; i < element_size / 2; i++)
{
lit_utf8_byte_t tmp = block_p[i];
block_p[i] = block_p[element_size - i - 1];
block_p[element_size - i - 1] = tmp;
}
}
} /* ecma_dataview_swap_order */
/**
* GetViewValue and SetViewValue abstact operation
*
* See also:
* ECMA-262 v6, 24.2.1.1
* ECMA-262 v6, 24.2.1.2
*
* @return ecma value
*/
ecma_value_t
ecma_op_dataview_get_set_view_value (ecma_value_t view, /**< the operation's 'view' argument */
ecma_value_t request_index, /**< the operation's 'requestIndex' argument */
ecma_value_t is_little_endian_value, /**< the operation's
* 'isLittleEndian' argument */
ecma_value_t value_to_set, /**< the operation's 'value' argument */
uint8_t type) /**< the operation's 'type' argument */
{
/* 1 - 2. */
ecma_dataview_object_t *view_p = ecma_op_dataview_get_object (view);
if (JERRY_UNLIKELY (view_p == NULL))
{
return ECMA_VALUE_ERROR;
}
/* 3 - 5. */
ecma_number_t number_index;
ecma_value_t number_index_value = ecma_get_number (request_index, &number_index);
if (ECMA_IS_VALUE_ERROR (number_index_value))
{
return number_index_value;
}
int32_t get_index = ecma_number_to_int32 (number_index);
/* 6. */
if (number_index != get_index || get_index < 0)
{
return ecma_raise_range_error (ECMA_ERR_MSG ("Start offset is outside the bounds of the buffer."));
}
/* 7. */
bool is_little_endian = ecma_op_to_boolean (is_little_endian_value);
/* 8. TODO: Throw TypeError, when Detached ArrayBuffer will be supported. */
/* 9. */
ecma_object_t *buffer_p = view_p->buffer_p;
JERRY_ASSERT (ecma_object_class_is (buffer_p, LIT_MAGIC_STRING_ARRAY_BUFFER_UL));
/* 10. */
uint32_t view_offset = view_p->byte_offset;
/* 11. */
uint32_t view_size = view_p->header.u.class_prop.u.length;
/* 12. */
uint8_t element_size = (uint8_t) (1 << (ecma_typedarray_helper_get_shift_size (type)));
/* 13. */
if ((uint32_t) get_index + element_size > view_size)
{
return ecma_raise_range_error (ECMA_ERR_MSG ("Start offset is outside the bounds of the buffer."));
}
/* 14. */
uint32_t buffer_index = (uint32_t) get_index + view_offset;
lit_magic_string_id_t id = ecma_typedarray_helper_get_magic_string (type);
lit_utf8_byte_t *block_p = ecma_arraybuffer_get_buffer (buffer_p) + buffer_index;
bool system_is_little_endian = ecma_dataview_check_little_endian ();
if (ecma_is_value_empty (value_to_set))
{
lit_utf8_byte_t swap_block_p[element_size];
memcpy (swap_block_p, block_p, element_size * sizeof (lit_utf8_byte_t));
ecma_dataview_swap_order (system_is_little_endian, is_little_endian, element_size, swap_block_p);
return ecma_make_number_value (ecma_get_typedarray_element (swap_block_p, id));
}
if (ecma_is_value_number (value_to_set))
{
ecma_set_typedarray_element (block_p, ecma_get_number_from_value (value_to_set), id);
ecma_dataview_swap_order (system_is_little_endian, is_little_endian, element_size, block_p);
}
return ECMA_VALUE_UNDEFINED;
} /* ecma_op_dataview_get_set_view_value */
/**
* @}
* @}
*/
#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */
@@ -0,0 +1,42 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ECMA_DATAVIEW_OBJECT_H
#define ECMA_DATAVIEW_OBJECT_H
#include "ecma-globals.h"
#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmadataviewobject ECMA builtin DataView helper functions
* @{
*/
ecma_value_t ecma_op_dataview_create (const ecma_value_t *arguments_list_p, ecma_length_t arguments_list_len);
ecma_dataview_object_t *ecma_op_dataview_get_object (ecma_value_t this_arg);
ecma_value_t ecma_op_dataview_get_set_view_value (ecma_value_t view, ecma_value_t request_index,
ecma_value_t little_endian, ecma_value_t value_to_set, uint8_t type);
/**
* @}
* @}
*/
#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */
#endif /* !ECMA_DATAVIEW_OBJECT_H */
@@ -1841,6 +1841,9 @@ ecma_object_check_class_name_is_object (ecma_object_t *obj_p) /**< object */
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
|| ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_SYMBOL_PROTOTYPE)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
|| ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_DATAVIEW_PROTOTYPE)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) */
|| ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE));
#else /* JERRY_NDEBUG */
JERRY_UNUSED (obj_p);