Skip to content

add ES6 feature: ArrayBuffer #1467

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 7, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions jerry-core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ set(JERRY_CORE_NAME jerry-core)
project (${JERRY_CORE_NAME} C)

# Optional features
set(FEATURE_PROFILE "full" CACHE STRING "Profile types: full, minimal")
set(FEATURE_PROFILE "es5.1" CACHE STRING "Profile types: es5.1, minimal, es2015-subset")
set(FEATURE_ERROR_MESSAGES OFF CACHE BOOL "Enable error messages?")
set(FEATURE_VALGRIND OFF CACHE BOOL "Enable Valgrind support?")
set(FEATURE_VALGRIND_FREYA OFF CACHE BOOL "Enable Valgrind-Freya support?")
Expand Down Expand Up @@ -118,9 +118,12 @@ if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
endif()

# Profile modes
set(CONFIG_DISABLE_ES2015
CONFIG_DISABLE_ARRAYBUFFER_BUILTIN)
# Minimal profile
if(FEATURE_PROFILE STREQUAL "minimal")
set(DEFINES_JERRY ${DEFINES_JERRY}
${CONFIG_DISABLE_ES2015}
CONFIG_DISABLE_NUMBER_BUILTIN
CONFIG_DISABLE_STRING_BUILTIN
CONFIG_DISABLE_BOOLEAN_BUILTIN
Expand All @@ -131,7 +134,10 @@ if(FEATURE_PROFILE STREQUAL "minimal")
CONFIG_DISABLE_DATE_BUILTIN
CONFIG_DISABLE_REGEXP_BUILTIN
CONFIG_DISABLE_ANNEXB_BUILTIN)
elseif(NOT FEATURE_PROFILE STREQUAL "full")
elseif(FEATURE_PROFILE STREQUAL "es5.1")
set(DEFINES_JERRY ${DEFINES_JERRY}
${CONFIG_DISABLE_ES2015})
elseif(NOT FEATURE_PROFILE STREQUAL "es2015-subset")
message(FATAL_ERROR "FEATURE_PROFILE='${FEATURE_PROFILE}' isn't supported")
endif()

Expand Down
16 changes: 12 additions & 4 deletions jerry-core/ecma/base/ecma-gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -424,29 +424,37 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */
case LIT_MAGIC_STRING_STRING_UL:
case LIT_MAGIC_STRING_NUMBER_UL:
{
ecma_free_value (ext_object_p->u.class_prop.value);
ecma_free_value (ext_object_p->u.class_prop.u.value);
break;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a built-in array buffer? If not, we can just free the object here. Furthermore we need guards, since array-buffer might be disabled at compile time.

}

case LIT_MAGIC_STRING_DATE_UL:
{
ecma_number_t *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);
ecma_dealloc_number (num_p);
break;
}

case LIT_MAGIC_STRING_REGEXP_UL:
{
ecma_compiled_code_t *bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
ext_object_p->u.class_prop.value);
ext_object_p->u.class_prop.u.value);
if (bytecode_p != NULL)
{
ecma_bytecode_deref (bytecode_p);
}
break;
}

#ifndef CONFIG_DISABLE_ARRAYBUFFER_BUILTIN
case LIT_MAGIC_STRING_ARRAY_BUFFER_UL:
{
ecma_length_t arraybuffer_length = ext_object_p->u.class_prop.u.length;
size_t size = sizeof (ecma_extended_object_t) + arraybuffer_length;
ecma_dealloc_extended_object ((ecma_extended_object_t *) object_p, size);
return;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't remove this newline.

#endif /* CONFIG_DISABLE_ARRAYBUFFER_BUILTIN */
default:
{
JERRY_UNREACHABLE ();
Expand Down
9 changes: 8 additions & 1 deletion jerry-core/ecma/base/ecma-globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,14 @@ typedef struct
struct
{
uint16_t class_id; /**< class id of the object */
ecma_value_t value; /**< value of the object (e.g. boolean, number, string, etc.) */
/*
* Description of extra fields. These extra fields depends on the class_id.
*/
union
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The union also needs a comment. See the union above. E.g:

Description of extra fields. These extra fields depends on the class_id.

{
ecma_value_t value; /**< value of the object (e.g. boolean, number, string, etc.) */
uint32_t length; /**< length related property (e.g. length of ArrayBuffer) */
} u;
} class_prop;

/*
Expand Down
6 changes: 4 additions & 2 deletions jerry-core/ecma/base/ecma-helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,9 @@ ecma_create_named_accessor_property (ecma_object_t *object_p, /**< object */
ecma_string_t *name_p, /**< property name */
ecma_object_t *get_p, /**< getter */
ecma_object_t *set_p, /**< setter */
uint8_t prop_attributes) /**< property attributes */
uint8_t prop_attributes, /**< property attributes */
ecma_property_t **out_prop_p) /**< [out] the property is also returned
* if this field is non-NULL */
{
JERRY_ASSERT (object_p != NULL && name_p != NULL);
JERRY_ASSERT (ecma_find_named_property (object_p, name_p) == NULL);
Expand All @@ -650,7 +652,7 @@ ecma_create_named_accessor_property (ecma_object_t *object_p, /**< object */
ECMA_SET_POINTER (value.getter_setter_pair.setter_p, set_p);
#endif /* JERRY_CPOINTER_32_BIT */

return ecma_create_property (object_p, name_p, type_and_flags, value, NULL);
return ecma_create_property (object_p, name_p, type_and_flags, value, out_prop_p);
} /* ecma_create_named_accessor_property */

/**
Expand Down
3 changes: 2 additions & 1 deletion jerry-core/ecma/base/ecma-helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,8 @@ extern ecma_value_t *ecma_get_internal_property (ecma_object_t *, ecma_internal_
extern ecma_property_value_t *
ecma_create_named_data_property (ecma_object_t *, ecma_string_t *, uint8_t, ecma_property_t **);
extern ecma_property_value_t *
ecma_create_named_accessor_property (ecma_object_t *, ecma_string_t *, ecma_object_t *, ecma_object_t *, uint8_t);
ecma_create_named_accessor_property (ecma_object_t *, ecma_string_t *, ecma_object_t *,
ecma_object_t *, uint8_t, ecma_property_t **);
extern ecma_property_t *
ecma_find_named_property (ecma_object_t *, ecma_string_t *);
extern ecma_property_value_t *
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure, but do you remove the newline at the end of the file? If so, please put it back everywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, each file should be end with a new line

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this file ended with double newlines? Or why that line is deleted?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, should I revert to 2 newlines?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course not! I just didn't understand the change here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and I just noticed the original files ends with 2 newline :)

#undef ACCESSOR_READ_ONLY
3 changes: 2 additions & 1 deletion jerry-core/ecma/builtin-objects/ecma-builtin-array.inc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
141 changes: 141 additions & 0 deletions jerry-core/ecma/builtin-objects/ecma-builtin-arraybuffer-prototype.c
Original file line number Diff line number Diff line change
@@ -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"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this include to the top

#include "ecma-try-catch-macro.h"
#include "jrt.h"
#include "jrt-libc-includes.h"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need all of these includes? E.g. ecma-function-object.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))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps you could add a newline before this if. Not mandatory id you don't want.

{
ecma_length_t len = ecma_arraybuffer_get_length (object_p);

return ecma_make_uint32_value (len);
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete the newline above, and add a newline after this }.


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);
Copy link
Member

@zherczeg zherczeg Dec 5, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Complie time assert? Shouldn't an error (perhaps rangeerror) be thrown?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"start <= len && end <= len" should be ensured by ecma_builtin_helper_array_index_normalize

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok.

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 */
Original file line number Diff line number Diff line change
@@ -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 */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not strictly a style issue but these comments suggests that ROUTINE properties first, ACCESSOR properties after. This is not true. These lists must follow the property list in the standard because if you execute a for-in loop in JavaScript the names must also follow the same order.

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
Loading