Skip to content

Commit 0b1b102

Browse files
Zsolt Borbélygalpeter
authored andcommitted
Implement String.prototype.slice()
JerryScript-DCO-1.0-Signed-off-by: Zsolt Borbély [email protected]
1 parent ac87616 commit 0b1b102

File tree

2 files changed

+194
-1
lines changed

2 files changed

+194
-1
lines changed

jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.cpp

Lines changed: 135 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
2+
* Copyright 2015 University of Szeged.
23
*
34
* Licensed under the Apache License, Version 2.0 (the "License");
45
* you may not use this file except in compliance with the License.
@@ -258,7 +259,140 @@ ecma_builtin_string_prototype_object_slice (ecma_value_t this_arg, /**< this arg
258259
ecma_value_t arg1, /**< routine's first argument */
259260
ecma_value_t arg2) /**< routine's second argument */
260261
{
261-
ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg, arg1, arg2);
262+
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
263+
264+
/* 1. */
265+
ECMA_TRY_CATCH (check_coercible_val,
266+
ecma_op_check_object_coercible (this_arg),
267+
ret_value);
268+
269+
/* 2. */
270+
ECMA_TRY_CATCH (to_string_val,
271+
ecma_op_to_string (this_arg),
272+
ret_value);
273+
274+
/* 3. */
275+
ecma_string_t *get_string_val = ecma_get_string_from_value (to_string_val);
276+
277+
JERRY_ASSERT (ecma_string_get_length (get_string_val) >= 0);
278+
279+
const uint32_t len = (uint32_t) ecma_string_get_length (get_string_val);
280+
281+
/* 4. */
282+
uint32_t start = 0, end = len;
283+
284+
ECMA_OP_TO_NUMBER_TRY_CATCH (start_num,
285+
arg1,
286+
ret_value);
287+
288+
if (!ecma_number_is_nan (start_num))
289+
{
290+
291+
if (ecma_number_is_infinity (start_num))
292+
{
293+
start = ecma_number_is_negative (start_num) ? 0 : len;
294+
}
295+
else
296+
{
297+
const int int_start = ecma_number_to_int32 (start_num);
298+
299+
if (int_start < 0)
300+
{
301+
const uint32_t start_abs = (uint32_t) - int_start;
302+
start = start_abs > len ? 0 : len - start_abs;
303+
}
304+
else
305+
{
306+
start = (uint32_t) int_start;
307+
308+
if (start > len)
309+
{
310+
start = len;
311+
}
312+
}
313+
}
314+
}
315+
else
316+
{
317+
start = 0;
318+
}
319+
320+
/* 5. */
321+
if (ecma_is_value_undefined (arg2))
322+
{
323+
end = len;
324+
}
325+
else
326+
{
327+
ECMA_OP_TO_NUMBER_TRY_CATCH (end_num,
328+
arg2,
329+
ret_value);
330+
331+
if (!ecma_number_is_nan (end_num))
332+
{
333+
334+
if (ecma_number_is_infinity (end_num))
335+
{
336+
end = ecma_number_is_negative (end_num) ? 0 : len;
337+
}
338+
else
339+
{
340+
const int32_t int_end = ecma_number_to_int32 (end_num);
341+
342+
if (int_end < 0)
343+
{
344+
const uint32_t end_abs = (uint32_t) - int_end;
345+
end = end_abs > len ? 0 : len - end_abs;
346+
}
347+
else
348+
{
349+
end = (uint32_t) int_end;
350+
351+
if (end > len)
352+
{
353+
end = len;
354+
}
355+
}
356+
}
357+
}
358+
else
359+
{
360+
end = 0;
361+
}
362+
363+
ECMA_OP_TO_NUMBER_FINALIZE (end_num);
364+
}
365+
366+
ECMA_OP_TO_NUMBER_FINALIZE (start_num);
367+
368+
JERRY_ASSERT (start <= len && end <= len);
369+
370+
if (ecma_is_completion_value_empty (ret_value))
371+
{
372+
/* 8. */
373+
const uint32_t span = (start > end) ? 0 : end - start;
374+
const uint32_t new_str_size = (uint32_t) sizeof (ecma_char_t) * (span + 1);
375+
376+
MEM_DEFINE_LOCAL_ARRAY (new_str_buffer, new_str_size, ecma_char_t);
377+
378+
/* 9. */
379+
for (uint32_t idx = 0; idx < span; idx++)
380+
{
381+
new_str_buffer[idx] = ecma_string_get_char_at_pos (get_string_val, start + idx);
382+
}
383+
384+
new_str_buffer[span] = '\0';
385+
ecma_string_t* new_str = ecma_new_ecma_string ((ecma_char_t *) new_str_buffer);
386+
387+
ret_value = ecma_make_normal_completion_value (ecma_make_string_value (new_str));
388+
389+
MEM_FINALIZE_LOCAL_ARRAY (new_str_buffer);
390+
}
391+
392+
ECMA_FINALIZE (to_string_val);
393+
ECMA_FINALIZE (check_coercible_val);
394+
395+
return ret_value;
262396
} /* ecma_builtin_string_prototype_object_slice */
263397

264398
/**
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright 2015 Samsung Electronics Co., Ltd.
2+
// Copyright 2015 University of Szeged.
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
var str = "universe";
17+
var res;
18+
19+
res = str.slice();
20+
assert (res === "universe");
21+
22+
res = str.slice(1, 6);
23+
assert (res === "niver");
24+
25+
res = str.slice("a", "-4");
26+
assert (res === "univ");
27+
28+
res = str.slice(-5);
29+
assert (res === "verse");
30+
31+
res = str.slice(-12, undefined);
32+
assert (res === "universe");
33+
34+
res = str.slice(undefined, -20);
35+
assert (res === "");
36+
37+
res = str.slice(undefined, undefined);
38+
assert (res === "universe");
39+
40+
res = str.slice(Infinity, NaN);
41+
assert (res === "");
42+
43+
res = str.slice(-Infinity, Infinity);
44+
assert (res === "universe");
45+
46+
res = str.slice(NaN, -Infinity);
47+
assert (res === "");
48+
49+
res = str.slice(false, true);
50+
assert (res === "u");
51+
52+
var x;
53+
res = str.slice(x, x);
54+
assert (res === "universe");
55+
56+
var obj = {y: "foo"};
57+
var arr = [x, x];
58+
res = str.slice(obj, arr);
59+
assert (res === "");

0 commit comments

Comments
 (0)