Browse Source

Expose internal duk_set_length() in public API

pull/1123/head
Sami Vaarala 8 years ago
parent
commit
40c9814e05
  1. 3
      src-input/duk_api_internal.h
  2. 1
      src-input/duk_api_public.h.in
  3. 41
      src-input/duk_api_stack.c
  4. 2
      src-input/duk_bi_json.c
  5. 4
      src-input/duk_hobject.h
  6. 29
      src-input/duk_hobject_props.c
  7. 14
      src-input/duk_js_compiler.c
  8. 2
      src-input/duk_js_executor.c

3
src-input/duk_api_internal.h

@ -258,9 +258,6 @@ DUK_INTERNAL_DECL void duk_xdef_prop_stridx_builtin(duk_context *ctx, duk_idx_t
DUK_INTERNAL_DECL void duk_xdef_prop_stridx_thrower(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx); /* [] -> [] */ DUK_INTERNAL_DECL void duk_xdef_prop_stridx_thrower(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx); /* [] -> [] */
/* Set object 'length'. */
DUK_INTERNAL_DECL void duk_set_length(duk_context *ctx, duk_idx_t idx, duk_size_t length);
DUK_INTERNAL_DECL void duk_pack(duk_context *ctx, duk_idx_t count); DUK_INTERNAL_DECL void duk_pack(duk_context *ctx, duk_idx_t count);
#if 0 #if 0
DUK_INTERNAL_DECL void duk_unpack(duk_context *ctx); DUK_INTERNAL_DECL void duk_unpack(duk_context *ctx);

1
src-input/duk_api_public.h.in

@ -642,6 +642,7 @@ DUK_EXTERNAL_DECL duk_c_function duk_get_c_function(duk_context *ctx, duk_idx_t
DUK_EXTERNAL_DECL duk_context *duk_get_context(duk_context *ctx, duk_idx_t idx); DUK_EXTERNAL_DECL duk_context *duk_get_context(duk_context *ctx, duk_idx_t idx);
DUK_EXTERNAL_DECL void *duk_get_heapptr(duk_context *ctx, duk_idx_t idx); DUK_EXTERNAL_DECL void *duk_get_heapptr(duk_context *ctx, duk_idx_t idx);
DUK_EXTERNAL_DECL duk_size_t duk_get_length(duk_context *ctx, duk_idx_t idx); DUK_EXTERNAL_DECL duk_size_t duk_get_length(duk_context *ctx, duk_idx_t idx);
DUK_EXTERNAL_DECL void duk_set_length(duk_context *ctx, duk_idx_t idx, duk_size_t len);
/* /*
* Require operations: no coercion, throw error if index or type * Require operations: no coercion, throw error if index or type

41
src-input/duk_api_stack.c

@ -1827,16 +1827,26 @@ DUK_EXTERNAL duk_size_t duk_get_length(duk_context *ctx, duk_idx_t idx) {
case DUK_TAG_BOOLEAN: case DUK_TAG_BOOLEAN:
case DUK_TAG_POINTER: case DUK_TAG_POINTER:
return 0; return 0;
#if defined(DUK_USE_PREFER_SIZE)
/* All of these types (besides object) have a virtual, non-configurable
* .length property which is within size_t range so we can just look it
* up without specific type checks.
*/
case DUK_TAG_STRING:
case DUK_TAG_BUFFER:
case DUK_TAG_LIGHTFUNC: {
duk_size_t ret;
duk_get_prop_stridx(ctx, idx, DUK_STRIDX_LENGTH);
ret = (duk_size_t) duk_to_number_m1(ctx);
duk_pop(ctx);
return ret;
}
#else /* DUK_USE_PREFER_SIZE */
case DUK_TAG_STRING: { case DUK_TAG_STRING: {
duk_hstring *h = DUK_TVAL_GET_STRING(tv); duk_hstring *h = DUK_TVAL_GET_STRING(tv);
DUK_ASSERT(h != NULL); DUK_ASSERT(h != NULL);
return (duk_size_t) DUK_HSTRING_GET_CHARLEN(h); return (duk_size_t) DUK_HSTRING_GET_CHARLEN(h);
} }
case DUK_TAG_OBJECT: {
duk_hobject *h = DUK_TVAL_GET_OBJECT(tv);
DUK_ASSERT(h != NULL);
return (duk_size_t) duk_hobject_get_length((duk_hthread *) ctx, h);
}
case DUK_TAG_BUFFER: { case DUK_TAG_BUFFER: {
duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv); duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);
DUK_ASSERT(h != NULL); DUK_ASSERT(h != NULL);
@ -1847,6 +1857,12 @@ DUK_EXTERNAL duk_size_t duk_get_length(duk_context *ctx, duk_idx_t idx) {
lf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv); lf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv);
return (duk_size_t) DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags); return (duk_size_t) DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags);
} }
#endif /* DUK_USE_PREFER_SIZE */
case DUK_TAG_OBJECT: {
duk_hobject *h = DUK_TVAL_GET_OBJECT(tv);
DUK_ASSERT(h != NULL);
return (duk_size_t) duk_hobject_get_length((duk_hthread *) ctx, h);
}
#if defined(DUK_USE_FASTINT) #if defined(DUK_USE_FASTINT)
case DUK_TAG_FASTINT: case DUK_TAG_FASTINT:
#endif #endif
@ -1859,7 +1875,6 @@ DUK_EXTERNAL duk_size_t duk_get_length(duk_context *ctx, duk_idx_t idx) {
DUK_UNREACHABLE(); DUK_UNREACHABLE();
} }
/* /*
* duk_known_xxx() helpers * duk_known_xxx() helpers
* *
@ -1913,18 +1928,12 @@ DUK_INTERNAL duk_hnatfunc *duk_known_hnatfunc(duk_context *ctx, duk_idx_t idx) {
return (duk_hnatfunc *) duk__known_heaphdr(ctx, idx); return (duk_hnatfunc *) duk__known_heaphdr(ctx, idx);
} }
DUK_INTERNAL void duk_set_length(duk_context *ctx, duk_idx_t idx, duk_size_t length) { DUK_EXTERNAL void duk_set_length(duk_context *ctx, duk_idx_t idx, duk_size_t len) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_hobject *h;
DUK_ASSERT_CTX_VALID(ctx); DUK_ASSERT_CTX_VALID(ctx);
h = duk_get_hobject(ctx, idx); idx = duk_normalize_index(ctx, idx);
if (!h) { duk_push_uint(ctx, (duk_uint_t) len);
return; duk_put_prop_stridx(ctx, idx, DUK_STRIDX_LENGTH);
}
duk_hobject_set_length(thr, h, (duk_uint32_t) length); /* XXX: typing */
} }
/* /*

2
src-input/duk_bi_json.c

@ -2472,7 +2472,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
goto abort_fastpath; goto abort_fastpath;
} }
arr_len = (duk_uint_fast32_t) duk_hobject_get_length(js_ctx->thr, obj); arr_len = (duk_uint_fast32_t) ((duk_harray *) obj)->length;
asize = (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(obj); asize = (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(obj);
/* Array part may be larger than 'length'; if so, iterate /* Array part may be larger than 'length'; if so, iterate
* only up to array 'length'. Array part may also be smaller * only up to array 'length'. Array part may also be smaller

4
src-input/duk_hobject.h

@ -887,9 +887,7 @@ DUK_INTERNAL_DECL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr, duk_hobje
DUK_INTERNAL_DECL duk_bool_t duk_hobject_hasprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key); DUK_INTERNAL_DECL duk_bool_t duk_hobject_hasprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key);
DUK_INTERNAL_DECL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags); DUK_INTERNAL_DECL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags);
DUK_INTERNAL_DECL void duk_hobject_define_property_internal_arridx(duk_hthread *thr, duk_hobject *obj, duk_uarridx_t arr_idx, duk_small_uint_t flags); DUK_INTERNAL_DECL void duk_hobject_define_property_internal_arridx(duk_hthread *thr, duk_hobject *obj, duk_uarridx_t arr_idx, duk_small_uint_t flags);
DUK_INTERNAL_DECL void duk_hobject_set_length(duk_hthread *thr, duk_hobject *obj, duk_uint32_t length); /* XXX: duk_uarridx_t? */ DUK_INTERNAL_DECL duk_size_t duk_hobject_get_length(duk_hthread *thr, duk_hobject *obj);
DUK_INTERNAL_DECL void duk_hobject_set_length_zero(duk_hthread *thr, duk_hobject *obj);
DUK_INTERNAL_DECL duk_uint32_t duk_hobject_get_length(duk_hthread *thr, duk_hobject *obj); /* XXX: duk_uarridx_t? */
/* helpers for defineProperty() and defineProperties() */ /* helpers for defineProperty() and defineProperties() */
DUK_INTERNAL_DECL DUK_INTERNAL_DECL

29
src-input/duk_hobject_props.c

@ -4745,26 +4745,7 @@ DUK_INTERNAL void duk_hobject_define_property_internal_arridx(duk_hthread *thr,
* Internal helpers for managing object 'length' * Internal helpers for managing object 'length'
*/ */
/* XXX: awkward helpers */ DUK_INTERNAL duk_size_t duk_hobject_get_length(duk_hthread *thr, duk_hobject *obj) {
DUK_INTERNAL void duk_hobject_set_length(duk_hthread *thr, duk_hobject *obj, duk_uint32_t length) {
duk_context *ctx = (duk_context *) thr;
duk_push_hobject(ctx, obj);
duk_push_hstring_stridx(ctx, DUK_STRIDX_LENGTH);
duk_push_u32(ctx, length);
(void) duk_hobject_putprop(thr,
DUK_GET_TVAL_NEGIDX(ctx, -3),
DUK_GET_TVAL_NEGIDX(ctx, -2),
DUK_GET_TVAL_NEGIDX(ctx, -1),
0);
duk_pop_3(ctx);
}
DUK_INTERNAL void duk_hobject_set_length_zero(duk_hthread *thr, duk_hobject *obj) {
duk_hobject_set_length(thr, obj, 0);
}
DUK_INTERNAL duk_uint32_t duk_hobject_get_length(duk_hthread *thr, duk_hobject *obj) {
duk_context *ctx = (duk_context *) thr; duk_context *ctx = (duk_context *) thr;
duk_double_t val; duk_double_t val;
@ -4785,9 +4766,11 @@ DUK_INTERNAL duk_uint32_t duk_hobject_get_length(duk_hthread *thr, duk_hobject *
val = duk_to_number_m1(ctx); val = duk_to_number_m1(ctx);
duk_pop_3(ctx); duk_pop_3(ctx);
/* XXX: better check */ /* This isn't part of Ecmascript semantics; return a value within
if (val >= 0.0 && val < DUK_DOUBLE_2TO32) { * duk_size_t range, or 0 otherwise.
return (duk_uint32_t) val; */
if (val >= 0.0 && val <= (duk_double_t) DUK_SIZE_MAX) {
return (duk_size_t) val;
} }
return 0; return 0;
} }

14
src-input/duk_js_compiler.c

@ -585,11 +585,11 @@ DUK_LOCAL void duk__reset_func_for_pass2(duk_compiler_ctx *comp_ctx) {
*/ */
DUK_BW_RESET_SIZE(thr, &func->bw_code); DUK_BW_RESET_SIZE(thr, &func->bw_code);
duk_hobject_set_length_zero(thr, func->h_consts); duk_set_length(ctx, func->consts_idx, 0);
/* keep func->h_funcs; inner functions are not reparsed to avoid O(depth^2) parsing */ /* keep func->h_funcs; inner functions are not reparsed to avoid O(depth^2) parsing */
func->fnum_next = 0; func->fnum_next = 0;
/* duk_hobject_set_length_zero(thr, func->h_funcs); */ /* duk_set_length(ctx, func->funcs_idx, 0); */
duk_hobject_set_length_zero(thr, func->h_labelnames); duk_set_length(ctx, func->labelnames_idx, 0);
duk_hbuffer_reset(thr, func->h_labelinfos); duk_hbuffer_reset(thr, func->h_labelinfos);
/* keep func->h_argnames; it is fixed for all passes */ /* keep func->h_argnames; it is fixed for all passes */
@ -2760,13 +2760,9 @@ DUK_LOCAL void duk__lookup_active_label(duk_compiler_ctx *comp_ctx, duk_hstring
DUK_LOCAL void duk__reset_labels_to_length(duk_compiler_ctx *comp_ctx, duk_int_t len) { DUK_LOCAL void duk__reset_labels_to_length(duk_compiler_ctx *comp_ctx, duk_int_t len) {
duk_hthread *thr = comp_ctx->thr; duk_hthread *thr = comp_ctx->thr;
duk_context *ctx = (duk_context *) thr; duk_context *ctx = (duk_context *) thr;
duk_size_t new_size;
/* XXX: duk_set_length */ duk_set_length(ctx, comp_ctx->curr_func.labelnames_idx, (duk_size_t) len);
new_size = sizeof(duk_labelinfo) * (duk_size_t) len; duk_hbuffer_resize(thr, comp_ctx->curr_func.h_labelinfos, sizeof(duk_labelinfo) * (duk_size_t) len);
duk_push_int(ctx, len);
duk_put_prop_stridx(ctx, comp_ctx->curr_func.labelnames_idx, DUK_STRIDX_LENGTH);
duk_hbuffer_resize(thr, comp_ctx->curr_func.h_labelinfos, new_size);
} }
/* /*

2
src-input/duk_js_executor.c

@ -4787,7 +4787,7 @@ DUK_LOCAL DUK_NOINLINE void duk__js_execute_bytecode_inner(duk_hthread *entry_th
* ToUint32() which is odd but happens now as a side effect of * ToUint32() which is odd but happens now as a side effect of
* 'arr_idx' type. * 'arr_idx' type.
*/ */
duk_hobject_set_length(thr, duk_known_hobject(ctx, obj_idx), (duk_uint32_t) arr_idx); duk_set_length(thr, obj_idx, (duk_size_t) (duk_uarridx_t) arr_idx);
break; break;
} }

Loading…
Cancel
Save