diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray.c b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray.c index 613c8522c..afb9f6f3f 100644 --- a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray.c +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray.c @@ -13,6 +13,7 @@ * limitations under the License. */ +#include "ecma-typedarray-object.h" #include "ecma-builtins.h" #include "ecma-exceptions.h" #include "ecma-gc.h" @@ -127,13 +128,57 @@ ecma_builtin_typedarray_of (ecma_value_t this_arg, /**< 'this' argument */ const ecma_value_t *arguments_list_p, /**< arguments list */ ecma_length_t arguments_list_len) /**< number of arguments */ { - JERRY_UNUSED (this_arg); - JERRY_UNUSED (arguments_list_p); - JERRY_UNUSED (arguments_list_len); + if (!ecma_is_constructor (this_arg)) + { + return ecma_raise_type_error (ECMA_ERR_MSG ("'this' is not a constructor.")); + } - /* TODO: implement 'of' */ + ecma_object_t *obj_p = ecma_get_object_from_value (this_arg); + const uint8_t builtin_id = ecma_get_object_builtin_id (obj_p); - return ECMA_VALUE_UNDEFINED; + if (!ecma_typedarray_helper_is_typedarray (builtin_id)) + { + return ecma_raise_type_error (ECMA_ERR_MSG ("'this' is not a typedarray constructor")); + } + + ecma_typedarray_type_t typedarray_id = ecma_typedarray_helper_builtin_to_typedarray_id (builtin_id); + + ecma_object_t *proto_p = ecma_builtin_get (ecma_typedarray_helper_get_prototype_id (typedarray_id)); + const uint8_t element_size_shift = ecma_typedarray_helper_get_shift_size (typedarray_id); + + ecma_value_t ret_val = ecma_typedarray_create_object_with_length (arguments_list_len, + proto_p, + element_size_shift, + typedarray_id); + + if (ECMA_IS_VALUE_ERROR (ret_val)) + { + return ret_val; + } + + uint32_t k = 0; + ecma_object_t *ret_obj_p = ecma_get_object_from_value (ret_val); + ecma_typedarray_info_t info = ecma_typedarray_get_info (ret_obj_p); + ecma_typedarray_setter_fn_t setter_cb = ecma_get_typedarray_setter_fn (info.id); + + while (k < arguments_list_len) + { + ecma_number_t num; + ecma_value_t next_val = ecma_get_number (arguments_list_p[k], &num); + + if (ECMA_IS_VALUE_ERROR (next_val)) + { + ecma_deref_object (ret_obj_p); + return next_val; + } + + setter_cb (info.buffer_p, num); + + k++; + info.buffer_p += info.element_size; + } + + return ret_val; } /* ecma_builtin_typedarray_of */ /** diff --git a/tests/jerry/es2015/typedarray-of.js b/tests/jerry/es2015/typedarray-of.js new file mode 100644 index 000000000..7735b6467 --- /dev/null +++ b/tests/jerry/es2015/typedarray-of.js @@ -0,0 +1,131 @@ +/* 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. + */ + +var int_typedarrays = [ + Uint8ClampedArray, + Uint8Array, + Uint16Array, + Uint32Array, + Int8Array, + Int16Array, + Int32Array +]; + +var float_typedarrays = [ + Float32Array, + Float64Array, +]; + +var obj = { + 0: 0, + 1: 1 +}; + +int_typedarrays.forEach(function(e){ + try { + e.of.call(undefined); + assert (false); + } catch (err) { + assert (err instanceof TypeError); + } + + try { + e.of.call(obj); + assert (false); + } catch (err) { + assert (err instanceof TypeError); + } + + // Test with regulat inputs + assert(e.of(1,2,3).toString() === "1,2,3"); + assert(e.of(12,4,5,0).toString() === "12,4,5,0"); + assert(e.of(23).toString() === "23"); + + // Test with string inputs + assert(e.of("12",4).toString() === "12,4"); + assert(e.of(1,2,"foo").toString() === "1,2,0"); + + // Test with undefined + assert(e.of(undefined).toString() === "0"); + + // Test with object + assert(e.of(obj).toString() === "0"); + + // Test with NaN + assert(e.of(NaN).toString() === "0"); +}); + +float_typedarrays.forEach(function(e){ + try { + e.of.call(undefined); + assert (false); + } catch (err) { + assert (err instanceof TypeError); + } + + try { + e.of.call(obj); + assert (false); + } catch (err) { + assert (err instanceof TypeError); + } + + // Test with regulat inputs + assert(e.of(1,2,3).toString() === "1,2,3"); + assert(e.of(12,4,5,0).toString() === "12,4,5,0"); + assert(e.of(23).toString() === "23"); + + // Test with string inputs + assert(e.of("12",4).toString() === "12,4"); + assert(e.of(1,2,"foo").toString() === "1,2,NaN"); + assert(e.of("-12").toString() === "-12"); + + // Test with undefined + assert(e.of(undefined).toString() === "NaN"); + + // Test with object + assert(e.of(obj).toString() === "NaN"); + + // Test with NaN + assert(e.of(NaN).toString() === "NaN"); +}); + +// Test with negative inputs +var a = Uint8ClampedArray.of(-8); +assert(a.toString() === "0"); + +a = Uint8Array.of(-8); +assert(a.toString() === "248"); + +a = Uint16Array.of(-8); +assert(a.toString() === "65528"); + +a = Uint32Array.of(-8); +assert(a.toString() === "4294967288"); + +a = Int8Array.of(-8); +assert(a.toString() === "-8"); + +a = Int16Array.of(-8); +assert(a.toString() === "-8"); + +a = Int32Array.of(-8); +assert(a.toString() === "-8"); + +a = Float32Array.of(-8); +assert(a.toString() === "-8"); + +a = Float64Array.of(-8); +assert(a.toString() === "-8");