Browse Source

refactor join() and toLocaleString() to use the same helper; implements toLocaleString(); also reorganize some functions

pull/1/head
Sami Vaarala 12 years ago
parent
commit
dd5ee0b01a
  1. 311
      src/duk_builtin_array.c

311
src/duk_builtin_array.c

@ -23,6 +23,10 @@ static unsigned int push_this_obj_len_u32(duk_context *ctx) {
return len;
}
/*
* Constructor
*/
int duk_builtin_array_constructor(duk_context *ctx) {
int nargs;
double d;
@ -55,6 +59,10 @@ int duk_builtin_array_constructor(duk_context *ctx) {
return 1;
}
/*
* isArray()
*/
int duk_builtin_array_constructor_is_array(duk_context *ctx) {
duk_hobject *h;
@ -63,6 +71,10 @@ int duk_builtin_array_constructor_is_array(duk_context *ctx) {
return 1;
}
/*
* toString()
*/
int duk_builtin_array_prototype_to_string(duk_context *ctx) {
duk_hthread *thr = (duk_hthread *) ctx;
@ -96,9 +108,9 @@ int duk_builtin_array_prototype_to_string(duk_context *ctx) {
return 1;
}
int duk_builtin_array_prototype_to_locale_string(duk_context *ctx) {
return DUK_RET_UNIMPLEMENTED_ERROR; /*FIXME*/
}
/*
* concat()
*/
int duk_builtin_array_prototype_concat(duk_context *ctx) {
int i, n;
@ -151,6 +163,10 @@ int duk_builtin_array_prototype_concat(duk_context *ctx) {
return 1;
}
/*
* join(), toLocaleString()
*/
/* Note: checking valstack is necessary, but only in the per-element loop */
/* FIXME: This placeholder does not work for a large number of elements.
@ -158,11 +174,11 @@ int duk_builtin_array_prototype_concat(duk_context *ctx) {
* them here.
*/
int duk_builtin_array_prototype_join(duk_context *ctx) {
static int array_join_helper(duk_context *ctx, int to_locale_string) {
duk_u32 len;
duk_u32 i;
DUK_ASSERT_TOP(ctx, 1); /* nargs is 1 */
DUK_ASSERT_TOP(ctx, 1);
if (duk_is_undefined(ctx, 0)) {
duk_pop(ctx);
duk_push_hstring_stridx(ctx, DUK_STRIDX_COMMA);
@ -187,7 +203,15 @@ int duk_builtin_array_prototype_join(duk_context *ctx) {
duk_pop(ctx);
duk_push_hstring_stridx(ctx, DUK_STRIDX_EMPTY_STRING);
} else {
duk_to_string(ctx, -1);
if (to_locale_string) {
duk_to_object(ctx, -1);
duk_get_prop_stridx(ctx, -1, DUK_STRIDX_TO_LOCALE_STRING);
duk_insert(ctx, -2); /* -> [ ... toLocaleString ToObject(val) ] */
duk_call_method(ctx, 0);
duk_to_string(ctx, -1);
} else {
duk_to_string(ctx, -1);
}
}
}
@ -197,6 +221,21 @@ int duk_builtin_array_prototype_join(duk_context *ctx) {
return 1;
}
int duk_builtin_array_prototype_join(duk_context *ctx) {
DUK_ASSERT_TOP(ctx, 1); /* nargs is 1 */
return array_join_helper(ctx, 0 /*to_locale_string*/);
}
int duk_builtin_array_prototype_to_locale_string(duk_context *ctx) {
DUK_ASSERT_TOP(ctx, 0); /* nargs is 0 */
duk_push_undefined(ctx); /* array_join_helper() will default to a comma */
return array_join_helper(ctx, 1 /*to_locale_string*/);
}
/*
* pop(), push()
*/
int duk_builtin_array_prototype_pop(duk_context *ctx) {
unsigned int len;
unsigned int idx;
@ -252,128 +291,6 @@ int duk_builtin_array_prototype_push(duk_context *ctx) {
return 1;
}
int duk_builtin_array_prototype_reverse(duk_context *ctx) {
unsigned int len;
unsigned int middle;
unsigned int lower, upper;
int have_lower, have_upper;
len = push_this_obj_len_u32(ctx);
middle = len / 2;
for (lower = 0; lower < middle; lower++) {
DUK_ASSERT_TOP(ctx, 2);
upper = len - lower - 1;
have_lower = duk_get_prop_index(ctx, -2, lower);
have_upper = duk_get_prop_index(ctx, -3, upper);
/* [ ToObject(this) ToUint32(length) lowerValue upperValue ] */
if (have_upper) {
duk_put_prop_index(ctx, -4, lower); /* FIXME: must Throw */
} else {
duk_del_prop_index(ctx, -4, lower);
duk_pop(ctx);
}
if (have_lower) {
duk_put_prop_index(ctx, -3, upper);
} else {
duk_del_prop_index(ctx, -3, upper);
duk_pop(ctx);
}
DUK_ASSERT_TOP(ctx, 2);
}
DUK_ASSERT_TOP(ctx, 2);
duk_pop(ctx); /* -> [ ToObject(this) ] */
return 1;
}
int duk_builtin_array_prototype_shift(duk_context *ctx) {
unsigned int len;
unsigned int i;
len = push_this_obj_len_u32(ctx);
if (len == 0) {
duk_push_int(ctx, 0);
duk_put_prop_stridx(ctx, 0, DUK_STRIDX_LENGTH); /* FIXME: needs to Throw */
return 0;
}
duk_get_prop_index(ctx, 0, 0);
/* stack[0] = object (this)
* stack[1] = ToUint32(length)
* stack[2] = elem at index 0 (retval)
*/
for (i = 1; i < len; i++) {
DUK_ASSERT_TOP(ctx, 3);
if (duk_get_prop_index(ctx, 0, i)) {
/* fromPresent = true */
duk_put_prop_index(ctx, 0, i - 1); /* FIXME: needs to Throw */
} else {
/* fromPresent = false */
duk_del_prop_index(ctx, 0, i - 1);
duk_pop(ctx);
}
}
duk_del_prop_index(ctx, 0, len - 1); /* FIXME: needs to Throw */
duk_push_number(ctx, (double) (len - 1)); /* FIXME: push uint */
duk_put_prop_stridx(ctx, 0, DUK_STRIDX_LENGTH);
DUK_ASSERT_TOP(ctx, 3);
return 1;
}
int duk_builtin_array_prototype_slice(duk_context *ctx) {
unsigned int len;
int start, end;
int idx;
int i;
len = push_this_obj_len_u32(ctx);
duk_push_new_array(ctx);
/* stack[0] = start
* stack[1] = end
* stack[2] = ToObject(this)
* stack[3] = ToUint32(length)
* stack[4] = result array
*/
start = duk_to_int_clamped(ctx, 0, -len, len); /* FIXME: does not support full 32-bit range */
if (start < 0) {
start = len + start;
}
end = duk_to_int_clamped(ctx, 1, -len, len);
if (end < 0) {
end = len + end;
}
DUK_ASSERT(start >= 0 && start <= len);
DUK_ASSERT(end >= 0 && end <= len);
idx = 0;
for (i = start; i < end; i++) {
DUK_ASSERT_TOP(ctx, 5);
if (duk_get_prop_index(ctx, 2, i)) {
duk_put_prop_index(ctx, 4, idx);
} else {
duk_pop(ctx);
}
idx++;
DUK_ASSERT_TOP(ctx, 5);
}
DUK_ASSERT_TOP(ctx, 5);
return 1;
}
/*
* sort()
*
@ -765,6 +682,144 @@ int duk_builtin_array_prototype_splice(duk_context *ctx) {
return 1;
}
/*
* reverse()
*/
int duk_builtin_array_prototype_reverse(duk_context *ctx) {
unsigned int len;
unsigned int middle;
unsigned int lower, upper;
int have_lower, have_upper;
len = push_this_obj_len_u32(ctx);
middle = len / 2;
for (lower = 0; lower < middle; lower++) {
DUK_ASSERT_TOP(ctx, 2);
upper = len - lower - 1;
have_lower = duk_get_prop_index(ctx, -2, lower);
have_upper = duk_get_prop_index(ctx, -3, upper);
/* [ ToObject(this) ToUint32(length) lowerValue upperValue ] */
if (have_upper) {
duk_put_prop_index(ctx, -4, lower); /* FIXME: must Throw */
} else {
duk_del_prop_index(ctx, -4, lower);
duk_pop(ctx);
}
if (have_lower) {
duk_put_prop_index(ctx, -3, upper);
} else {
duk_del_prop_index(ctx, -3, upper);
duk_pop(ctx);
}
DUK_ASSERT_TOP(ctx, 2);
}
DUK_ASSERT_TOP(ctx, 2);
duk_pop(ctx); /* -> [ ToObject(this) ] */
return 1;
}
/*
* slice()
*/
int duk_builtin_array_prototype_slice(duk_context *ctx) {
unsigned int len;
int start, end;
int idx;
int i;
len = push_this_obj_len_u32(ctx);
duk_push_new_array(ctx);
/* stack[0] = start
* stack[1] = end
* stack[2] = ToObject(this)
* stack[3] = ToUint32(length)
* stack[4] = result array
*/
start = duk_to_int_clamped(ctx, 0, -len, len); /* FIXME: does not support full 32-bit range */
if (start < 0) {
start = len + start;
}
end = duk_to_int_clamped(ctx, 1, -len, len);
if (end < 0) {
end = len + end;
}
DUK_ASSERT(start >= 0 && start <= len);
DUK_ASSERT(end >= 0 && end <= len);
idx = 0;
for (i = start; i < end; i++) {
DUK_ASSERT_TOP(ctx, 5);
if (duk_get_prop_index(ctx, 2, i)) {
duk_put_prop_index(ctx, 4, idx);
} else {
duk_pop(ctx);
}
idx++;
DUK_ASSERT_TOP(ctx, 5);
}
DUK_ASSERT_TOP(ctx, 5);
return 1;
}
/*
* shift()
*/
int duk_builtin_array_prototype_shift(duk_context *ctx) {
unsigned int len;
unsigned int i;
len = push_this_obj_len_u32(ctx);
if (len == 0) {
duk_push_int(ctx, 0);
duk_put_prop_stridx(ctx, 0, DUK_STRIDX_LENGTH); /* FIXME: needs to Throw */
return 0;
}
duk_get_prop_index(ctx, 0, 0);
/* stack[0] = object (this)
* stack[1] = ToUint32(length)
* stack[2] = elem at index 0 (retval)
*/
for (i = 1; i < len; i++) {
DUK_ASSERT_TOP(ctx, 3);
if (duk_get_prop_index(ctx, 0, i)) {
/* fromPresent = true */
duk_put_prop_index(ctx, 0, i - 1); /* FIXME: needs to Throw */
} else {
/* fromPresent = false */
duk_del_prop_index(ctx, 0, i - 1);
duk_pop(ctx);
}
}
duk_del_prop_index(ctx, 0, len - 1); /* FIXME: needs to Throw */
duk_push_number(ctx, (double) (len - 1)); /* FIXME: push uint */
duk_put_prop_stridx(ctx, 0, DUK_STRIDX_LENGTH);
DUK_ASSERT_TOP(ctx, 3);
return 1;
}
/*
* unshift()
*/
int duk_builtin_array_prototype_unshift(duk_context *ctx) {
int nargs;
unsigned int len;

Loading…
Cancel
Save