Browse Source

ENC16/DEC16/EXTSTR udata changes

Also remove mostly unused old debug code.

Debug code doesn't have access to 'heap' so it cannot decode pointers.
Cause an #error for now if both debug prints and pointer compression
are enabled at the same time.

Remove duk_debug_hobject.c from make and dist.  It was out of date and
not used in practice anymore.
pull/113/head
Sami Vaarala 10 years ago
parent
commit
36494812ed
  1. 1
      Makefile
  2. 2
      src/duk_api_buffer.c
  3. 4
      src/duk_api_object.c
  4. 23
      src/duk_api_stack.c
  5. 5
      src/duk_bi_boolean.c
  6. 5
      src/duk_bi_duktape.c
  7. 5
      src/duk_bi_json.c
  8. 2
      src/duk_bi_logger.c
  9. 5
      src/duk_bi_number.c
  10. 13
      src/duk_bi_object.c
  11. 71
      src/duk_debug.h
  12. 488
      src/duk_debug_hobject.c
  13. 4
      src/duk_debug_macros.c
  14. 36
      src/duk_debug_vsnprintf.c
  15. 3
      src/duk_error_augment.c
  16. 16
      src/duk_features.h.in
  17. 5
      src/duk_features_sanity.h.in
  18. 25
      src/duk_hbuffer.h
  19. 7
      src/duk_hbuffer_alloc.c
  20. 14
      src/duk_hbuffer_ops.c
  21. 96
      src/duk_hcompiledfunction.h
  22. 4
      src/duk_heap.h
  23. 23
      src/duk_heap_alloc.c
  24. 70
      src/duk_heap_markandsweep.c
  25. 10
      src/duk_heap_memory.c
  26. 18
      src/duk_heap_misc.c
  27. 48
      src/duk_heap_refcount.c
  28. 40
      src/duk_heap_stringtable.c
  29. 22
      src/duk_heaphdr.h
  30. 213
      src/duk_hobject.h
  31. 6
      src/duk_hobject_alloc.c
  32. 37
      src/duk_hobject_enum.c
  33. 8
      src/duk_hobject_misc.c
  34. 11
      src/duk_hobject_pc2line.c
  35. 317
      src/duk_hobject_props.c
  36. 8
      src/duk_hthread.h
  37. 9
      src/duk_hthread_alloc.c
  38. 7
      src/duk_hthread_builtins.c
  39. 20
      src/duk_hthread_stacks.c
  40. 3
      src/duk_js_bytecode.h
  41. 41
      src/duk_js_call.c
  42. 40
      src/duk_js_compiler.c
  43. 27
      src/duk_js_executor.c
  44. 8
      src/duk_js_ops.c
  45. 104
      src/duk_js_var.c
  46. 1
      util/make_dist.sh

1
Makefile

@ -76,7 +76,6 @@ DUKTAPE_SOURCES_SEPARATE = \
$(DISTSRCSEP)/duk_debug_macros.c \
$(DISTSRCSEP)/duk_debug_vsnprintf.c \
$(DISTSRCSEP)/duk_debug_heap.c \
$(DISTSRCSEP)/duk_debug_hobject.c \
$(DISTSRCSEP)/duk_debug_fixedbuffer.c \
$(DISTSRCSEP)/duk_error_macros.c \
$(DISTSRCSEP)/duk_error_longjmp.c \

2
src/duk_api_buffer.c

@ -20,5 +20,5 @@ DUK_EXTERNAL void *duk_resize_buffer(duk_context *ctx, duk_idx_t index, duk_size
/* maximum size check is handled by callee */
duk_hbuffer_resize(thr, h, new_size, new_size); /* snug */
return DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(h);
return DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h);
}

4
src/duk_api_object.c

@ -528,16 +528,18 @@ DUK_EXTERNAL duk_bool_t duk_put_global_string(duk_context *ctx, const char *key)
*/
DUK_EXTERNAL void duk_get_prototype(duk_context *ctx, duk_idx_t index) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_hobject *obj;
duk_hobject *proto;
DUK_ASSERT(ctx != NULL);
DUK_UNREF(thr);
obj = duk_require_hobject(ctx, index);
DUK_ASSERT(obj != NULL);
/* XXX: shared helper for duk_push_hobject_or_undefined()? */
proto = DUK_HOBJECT_GET_PROTOTYPE(obj);
proto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, obj);
if (proto) {
duk_push_hobject(ctx, proto);
} else {

23
src/duk_api_stack.c

@ -1178,9 +1178,11 @@ DUK_INTERNAL void *duk_get_voidptr(duk_context *ctx, duk_idx_t index) {
#endif
DUK_EXTERNAL void *duk_get_buffer(duk_context *ctx, duk_idx_t index, duk_size_t *out_size) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_tval *tv;
DUK_ASSERT(ctx != NULL);
DUK_UNREF(thr);
if (out_size != NULL) {
*out_size = 0;
@ -1193,7 +1195,7 @@ DUK_EXTERNAL void *duk_get_buffer(duk_context *ctx, duk_idx_t index, duk_size_t
if (out_size) {
*out_size = DUK_HBUFFER_GET_SIZE(h);
}
return (void *) DUK_HBUFFER_GET_DATA_PTR(h); /* may be NULL (but only if size is 0) */
return (void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h); /* may be NULL (but only if size is 0) */
}
return NULL;
@ -1220,7 +1222,7 @@ DUK_EXTERNAL void *duk_require_buffer(duk_context *ctx, duk_idx_t index, duk_siz
if (out_size) {
*out_size = DUK_HBUFFER_GET_SIZE(h);
}
return (void *) DUK_HBUFFER_GET_DATA_PTR(h); /* may be NULL (but only if size is 0) */
return (void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h); /* may be NULL (but only if size is 0) */
}
DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, DUK_STR_NOT_BUFFER);
@ -1916,9 +1918,11 @@ DUK_INTERNAL duk_int_t duk_to_int_check_range(duk_context *ctx, duk_idx_t index,
}
DUK_EXTERNAL const char *duk_to_string(duk_context *ctx, duk_idx_t index) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_tval *tv;
DUK_ASSERT(ctx != NULL);
DUK_UNREF(thr);
index = duk_require_normalize_index(ctx, index);
@ -1957,7 +1961,7 @@ DUK_EXTERNAL const char *duk_to_string(duk_context *ctx, duk_idx_t index) {
DUK_ASSERT(h != NULL);
duk_push_lstring(ctx,
(const char *) DUK_HBUFFER_GET_DATA_PTR(h),
(const char *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h),
(duk_size_t) DUK_HBUFFER_GET_SIZE(h));
break;
}
@ -2007,11 +2011,14 @@ DUK_INTERNAL duk_hstring *duk_to_hstring(duk_context *ctx, duk_idx_t index) {
}
DUK_EXTERNAL void *duk_to_buffer_raw(duk_context *ctx, duk_idx_t index, duk_size_t *out_size, duk_uint_t mode) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_hbuffer *h_buf;
const duk_uint8_t *src_data;
duk_size_t src_size;
duk_uint8_t *dst_data;
DUK_UNREF(thr);
index = duk_require_normalize_index(ctx, index);
h_buf = duk_get_hbuffer(ctx, index);
@ -2021,7 +2028,7 @@ DUK_EXTERNAL void *duk_to_buffer_raw(duk_context *ctx, duk_idx_t index, duk_size
*/
duk_uint_t tmp;
src_data = (const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(h_buf);
src_data = (const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_buf);
src_size = DUK_HBUFFER_GET_SIZE(h_buf);
tmp = (DUK_HBUFFER_HAS_DYNAMIC(h_buf) ? DUK_BUF_MODE_DYNAMIC : DUK_BUF_MODE_FIXED);
@ -2545,7 +2552,7 @@ DUK_EXTERNAL duk_errcode_t duk_get_error_code(duk_context *ctx, duk_idx_t index)
return DUK_ERR_ERROR;
}
h = DUK_HOBJECT_GET_PROTOTYPE(h);
h = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);
} while (--sanity > 0);
return DUK_ERR_NONE;
@ -3038,7 +3045,7 @@ DUK_INTERNAL duk_idx_t duk_push_object_helper(duk_context *ctx, duk_uint_t hobje
DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, thr->builtins[prototype_bidx]);
} else {
DUK_ASSERT(prototype_bidx == -1);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(h) == NULL);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h) == NULL);
}
return ret;
@ -3052,7 +3059,7 @@ DUK_INTERNAL duk_idx_t duk_push_object_helper_proto(duk_context *ctx, duk_uint_t
ret = duk_push_object_helper(ctx, hobject_flags_and_class, -1);
h = duk_get_hobject(ctx, -1);
DUK_ASSERT(h != NULL);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(h) == NULL);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h) == NULL);
DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, proto);
return ret;
}
@ -3429,7 +3436,7 @@ DUK_EXTERNAL void *duk_push_buffer_raw(duk_context *ctx, duk_size_t size, duk_bo
DUK_HBUFFER_INCREF(thr, h);
thr->valstack_top++;
return DUK_HBUFFER_GET_DATA_PTR(h);
return DUK_HBUFFER_GET_DATA_PTR(thr->heap, h);
}
DUK_EXTERNAL duk_idx_t duk_push_heapptr(duk_context *ctx, void *ptr) {

5
src/duk_bi_boolean.c

@ -44,8 +44,11 @@ DUK_INTERNAL duk_ret_t duk_bi_boolean_prototype_tostring_shared(duk_context *ctx
}
DUK_INTERNAL duk_ret_t duk_bi_boolean_constructor(duk_context *ctx) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_hobject *h_this;
DUK_UNREF(thr);
duk_to_boolean(ctx, 0);
if (duk_is_constructor_call(ctx)) {
@ -53,7 +56,7 @@ DUK_INTERNAL duk_ret_t duk_bi_boolean_constructor(duk_context *ctx) {
duk_push_this(ctx);
h_this = duk_get_hobject(ctx, -1);
DUK_ASSERT(h_this != NULL);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(h_this) == ((duk_hthread *) ctx)->builtins[DUK_BIDX_BOOLEAN_PROTOTYPE]);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_this) == thr->builtins[DUK_BIDX_BOOLEAN_PROTOTYPE]);
DUK_HOBJECT_SET_CLASS_NUMBER(h_this, DUK_HOBJECT_CLASS_BOOLEAN);

5
src/duk_bi_duktape.c

@ -18,10 +18,13 @@
* such are given so there should not be a security impact.
*/
DUK_INTERNAL duk_ret_t duk_bi_duktape_object_info(duk_context *ctx) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_tval *tv;
duk_heaphdr *h;
duk_int_t i, n;
DUK_UNREF(thr);
tv = duk_get_tval(ctx, 0);
DUK_ASSERT(tv != NULL); /* because arg count is 1 */
@ -81,7 +84,7 @@ DUK_INTERNAL duk_ret_t duk_bi_duktape_object_info(duk_context *ctx) {
duk_push_uint(ctx, (duk_uint_t) DUK_HOBJECT_GET_ASIZE(h_obj));
duk_push_uint(ctx, (duk_uint_t) DUK_HOBJECT_GET_HSIZE(h_obj));
if (DUK_HOBJECT_IS_COMPILEDFUNCTION(h_obj)) {
duk_hbuffer *h_data = (duk_hbuffer *) DUK_HCOMPILEDFUNCTION_GET_DATA((duk_hcompiledfunction *) h_obj);
duk_hbuffer *h_data = (duk_hbuffer *) DUK_HCOMPILEDFUNCTION_GET_DATA(thr->heap, (duk_hcompiledfunction *) h_obj);
if (h_data) {
duk_push_uint(ctx, (duk_uint_t) DUK_HBUFFER_GET_SIZE(h_data));
} else {

5
src/duk_bi_json.c

@ -1446,8 +1446,11 @@ DUK_LOCAL duk_bool_t duk__enc_value1(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hol
*/
DUK_LOCAL void duk__enc_value2(duk_json_enc_ctx *js_ctx) {
duk_context *ctx = (duk_context *) js_ctx->thr;
duk_hthread *thr = (duk_hthread *) ctx;
duk_tval *tv;
DUK_UNREF(thr);
DUK_DDD(DUK_DDDPRINT("duk__enc_value2: key=%!T, val=%!T",
(duk_tval *) duk_get_tval(ctx, -2),
(duk_tval *) duk_get_tval(ctx, -1)));
@ -1557,7 +1560,7 @@ DUK_LOCAL void duk__enc_value2(duk_json_enc_ctx *js_ctx) {
h = DUK_TVAL_GET_BUFFER(tv);
DUK_ASSERT(h != NULL);
p = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(h);
p = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h);
p_end = p + DUK_HBUFFER_GET_SIZE(h);
DUK__EMIT_1(js_ctx, DUK_ASC_PIPE);
while (p < p_end) {

2
src/duk_bi_logger.c

@ -252,7 +252,7 @@ DUK_INTERNAL duk_ret_t duk_bi_logger_prototype_log_shared(duk_context *ctx) {
DUK_HBUFFER_SET_SIZE((duk_hbuffer *) h_buf, tot_len);
duk_push_hbuffer(ctx, (duk_hbuffer *) h_buf);
buf = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(h_buf);
buf = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h_buf);
} else {
DUK_DDD(DUK_DDDPRINT("use a one-off large log message buffer, tot_len %ld", (long) tot_len));
buf = (duk_uint8_t *) duk_push_fixed_buffer(ctx, tot_len);

5
src/duk_bi_number.c

@ -33,9 +33,12 @@ DUK_LOCAL duk_double_t duk__push_this_number_plain(duk_context *ctx) {
}
DUK_INTERNAL duk_ret_t duk_bi_number_constructor(duk_context *ctx) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_idx_t nargs;
duk_hobject *h_this;
DUK_UNREF(thr);
/*
* The Number constructor uses ToNumber(arg) for number coercion
* (coercing an undefined argument to NaN). However, if the
@ -74,7 +77,7 @@ DUK_INTERNAL duk_ret_t duk_bi_number_constructor(duk_context *ctx) {
DUK_ASSERT(h_this != NULL);
DUK_HOBJECT_SET_CLASS_NUMBER(h_this, DUK_HOBJECT_CLASS_NUMBER);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(h_this) == ((duk_hthread *) ctx)->builtins[DUK_BIDX_NUMBER_PROTOTYPE]);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_this) == thr->builtins[DUK_BIDX_NUMBER_PROTOTYPE]);
DUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(h_this) == DUK_HOBJECT_CLASS_NUMBER);
DUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(h_this));

13
src/duk_bi_object.c

@ -43,9 +43,12 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor(duk_context *ctx) {
* https://people.mozilla.org/~jorendorff/es6-draft.html#sec-get-object.prototype.__proto__
*/
DUK_INTERNAL duk_ret_t duk_bi_object_getprototype_shared(duk_context *ctx) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_hobject *h;
duk_hobject *proto;
DUK_UNREF(thr);
/* magic: 0=getter call, 1=Object.getPrototypeOf */
if (duk_get_current_magic(ctx) == 0) {
duk_push_this_coercible_to_object(ctx);
@ -64,7 +67,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_getprototype_shared(duk_context *ctx) {
if (h == NULL) {
duk_push_hobject_bidx(ctx, DUK_BIDX_FUNCTION_PROTOTYPE);
} else {
proto = DUK_HOBJECT_GET_PROTOTYPE(h);
proto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);
if (proto) {
duk_push_hobject(ctx, proto);
} else {
@ -124,13 +127,13 @@ DUK_INTERNAL duk_ret_t duk_bi_object_setprototype_shared(duk_context *ctx) {
/* NOTE: steps 7-8 seem to be a cut-paste bug in the E6 draft */
/* TODO: implement Proxy object support here */
if (h_new_proto == DUK_HOBJECT_GET_PROTOTYPE(h_obj)) {
if (h_new_proto == DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_obj)) {
goto skip;
}
if (!DUK_HOBJECT_HAS_EXTENSIBLE(h_obj)) {
goto fail_nonextensible;
}
for (h_curr = h_new_proto; h_curr != NULL; h_curr = DUK_HOBJECT_GET_PROTOTYPE(h_curr)) {
for (h_curr = h_new_proto; h_curr != NULL; h_curr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_curr)) {
/* Loop prevention */
if (h_curr == h_obj) {
goto fail_loop;
@ -400,7 +403,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_is_sealed_frozen_shared(duk_con
duk_push_true(ctx); /* frozen and sealed */
} else {
is_frozen = duk_get_current_magic(ctx);
rc = duk_hobject_object_is_sealed_frozen_helper(h, is_frozen /*is_frozen*/);
rc = duk_hobject_object_is_sealed_frozen_helper((duk_hthread *) ctx, h, is_frozen /*is_frozen*/);
duk_push_boolean(ctx, rc);
}
return 1;
@ -578,7 +581,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_prototype_is_prototype_of(duk_context *ctx)
/* E5.1 Section 15.2.4.6, step 3.a, lookup proto once before compare.
* Prototype loops should cause an error to be thrown.
*/
duk_push_boolean(ctx, duk_hobject_prototype_chain_contains(thr, DUK_HOBJECT_GET_PROTOTYPE(h_v), h_obj, 0 /*ignore_loop*/));
duk_push_boolean(ctx, duk_hobject_prototype_chain_contains(thr, DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_v), h_obj, 0 /*ignore_loop*/));
return 1;
}

71
src/duk_debug.h

@ -109,45 +109,6 @@
#endif /* DUK_USE_VARIADIC_MACROS */
/* object dumpers */
#if 0 /*unused*/
#define DUK_DEBUG_DUMP_HEAP(x) duk_debug_dump_heap((x))
#endif
#define DUK_DEBUG_DUMP_HSTRING(x) /* XXX: unimplemented */
#define DUK_DEBUG_DUMP_HOBJECT(x) duk_debug_dump_hobject((x))
#define DUK_DEBUG_DUMP_HCOMPILEDFUNCTION(x) /* XXX: unimplemented */
#define DUK_DEBUG_DUMP_HNATIVEFUNCTION(x) /* XXX: unimplemented */
#define DUK_DEBUG_DUMP_HTHREAD(thr) duk_debug_dump_hobject((duk_hobject *) (thr))
#if 0 /*unused*/
#define DUK_DEBUG_DUMP_CALLSTACK(thr) duk_debug_dump_callstack((thr))
#define DUK_DEBUG_DUMP_ACTIVATION(thr,act) duk_debug_dump_activation((thr),(act))
#endif
/* summary macros */
#define DUK_DEBUG_SUMMARY_INIT() do { \
DUK_MEMZERO(duk_debug_summary_buf, sizeof(duk_debug_summary_buf)); \
duk_debug_summary_idx = 0; \
} while (0)
#define DUK_DEBUG_SUMMARY_CHAR(ch) do { \
duk_debug_summary_buf[duk_debug_summary_idx++] = (ch); \
if ((duk_size_t) duk_debug_summary_idx >= (duk_size_t) (sizeof(duk_debug_summary_buf) - 1)) { \
duk_debug_summary_buf[duk_debug_summary_idx++] = (char) 0; \
DUK_D(DUK_DPRINT(" %s", (const char *) duk_debug_summary_buf)); \
DUK_DEBUG_SUMMARY_INIT(); \
} \
} while (0)
#define DUK_DEBUG_SUMMARY_FINISH() do { \
if (duk_debug_summary_idx > 0) { \
duk_debug_summary_buf[duk_debug_summary_idx++] = (char) 0; \
DUK_D(DUK_DPRINT(" %s", (const char *) duk_debug_summary_buf)); \
DUK_DEBUG_SUMMARY_INIT(); \
} \
} while (0)
#else /* DUK_USE_DEBUG */
/*
@ -172,19 +133,6 @@
#endif /* DUK_USE_VARIADIC_MACROS */
#if 0 /*unused*/
#define DUK_DEBUG_DUMP_HEAP(x)
#endif
#define DUK_DEBUG_DUMP_HSTRING(x)
#define DUK_DEBUG_DUMP_HOBJECT(x)
#define DUK_DEBUG_DUMP_HCOMPILEDFUNCTION(x)
#define DUK_DEBUG_DUMP_HNATIVEFUNCTION(x)
#define DUK_DEBUG_DUMP_HTHREAD(x)
#define DUK_DEBUG_SUMMARY_INIT()
#define DUK_DEBUG_SUMMARY_CHAR(ch)
#define DUK_DEBUG_SUMMARY_FINISH()
#endif /* DUK_USE_DEBUG */
/*
@ -232,25 +180,6 @@ DUK_INTERNAL_DECL void duk_fb_sprintf(duk_fixedbuffer *fb, const char *fmt, ...)
DUK_INTERNAL_DECL void duk_fb_put_funcptr(duk_fixedbuffer *fb, duk_uint8_t *fptr, duk_size_t fptr_size);
DUK_INTERNAL_DECL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb);
#if 0 /*unused*/
DUK_INTERNAL_DECL void duk_debug_dump_heap(duk_heap *heap);
#endif
DUK_INTERNAL_DECL void duk_debug_dump_hobject(duk_hobject *obj);
#if 0 /*unimplemented*/
DUK_INTERNAL_DECL void duk_debug_dump_hthread(duk_hthread *thr);
#endif
#if 0 /*unused*/
DUK_INTERNAL_DECL void duk_debug_dump_callstack(duk_hthread *thr);
DUK_INTERNAL_DECL void duk_debug_dump_activation(duk_hthread *thr, duk_activation *act);
#endif
#define DUK_DEBUG_SUMMARY_BUF_SIZE 76
#if !defined(DUK_SINGLE_FILE)
DUK_INTERNAL_DECL char duk_debug_summary_buf[DUK_DEBUG_SUMMARY_BUF_SIZE];
DUK_INTERNAL_DECL duk_int_t duk_debug_summary_idx;
#endif /* !DUK_SINGLE_FILE */
#endif /* DUK_USE_DEBUG */
#endif /* DUK_DEBUG_H_INCLUDED */

488
src/duk_debug_hobject.c

@ -1,488 +0,0 @@
/*
* Debug dumping of duk_hobject.
*/
#include "duk_internal.h"
#ifdef DUK_USE_DEBUG
/* must match duk_hobject.h */
DUK_LOCAL const char *duk__class_names[32] = {
"unused",
"Arguments",
"Array",
"Boolean",
"Date",
"Error",
"Function",
"JSON",
"Math",
"Number",
"Object",
"RegExp",
"String",
"global",
"ObjEnv",
"DecEnv",
"Buffer",
"Pointer",
"unused",
"unused",
"unused",
"unused",
"unused",
"unused",
"unused",
"unused",
"unused",
"unused",
"unused",
"unused",
"unused",
"unused",
};
/* for thread dumping */
DUK_LOCAL char duk__get_act_summary_char(duk_activation *act) {
if (act->func) {
if (DUK_HOBJECT_IS_COMPILEDFUNCTION(act->func)) {
return 'c';
} else if (DUK_HOBJECT_IS_NATIVEFUNCTION(act->func)) {
return 'n';
} else {
/* should not happen */
return '?';
}
} else {
/* should not happen */
return '?';
}
}
/* for thread dumping */
DUK_LOCAL char duk__get_tval_summary_char(duk_tval *tv) {
switch (DUK_TVAL_GET_TAG(tv)) {
case DUK_TAG_UNDEFINED:
if (DUK_TVAL_IS_UNDEFINED_UNUSED(tv)) {
return '.';
}
return 'u';
case DUK_TAG_NULL:
return 'n';
case DUK_TAG_BOOLEAN:
return 'b';
case DUK_TAG_STRING:
return 's';
case DUK_TAG_OBJECT: {
duk_hobject *h = DUK_TVAL_GET_OBJECT(tv);
if (DUK_HOBJECT_IS_ARRAY(h)) {
return 'A';
} else if (DUK_HOBJECT_IS_COMPILEDFUNCTION(h)) {
return 'C';
} else if (DUK_HOBJECT_IS_NATIVEFUNCTION(h)) {
return 'N';
} else if (DUK_HOBJECT_IS_THREAD(h)) {
return 'T';
}
return 'O';
}
case DUK_TAG_BUFFER: {
return 'B';
}
case DUK_TAG_POINTER: {
return 'P';
}
case DUK_TAG_LIGHTFUNC: {
return 'L';
}
default:
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
return 'd';
}
DUK_UNREACHABLE();
}
/* for thread dumping */
DUK_LOCAL char duk__get_cat_summary_char(duk_catcher *catcher) {
switch (DUK_CAT_GET_TYPE(catcher)) {
case DUK_CAT_TYPE_TCF:
if (DUK_CAT_HAS_CATCH_ENABLED(catcher)) {
if (DUK_CAT_HAS_FINALLY_ENABLED(catcher)) {
return 'C'; /* catch and finally active */
} else {
return 'c'; /* only catch active */
}
} else {
if (DUK_CAT_HAS_FINALLY_ENABLED(catcher)) {
return 'f'; /* only finally active */
} else {
return 'w'; /* neither active (usually 'with') */
}
}
case DUK_CAT_TYPE_LABEL:
return 'l';
case DUK_CAT_TYPE_UNKNOWN:
default:
return '?';
}
DUK_UNREACHABLE();
}
DUK_INTERNAL void duk_debug_dump_hobject(duk_hobject *obj) {
duk_uint_fast32_t i;
const char *str_empty = "";
const char *str_excl = "!";
DUK_UNREF(str_empty);
DUK_UNREF(str_excl);
DUK_UNREF(duk__class_names);
DUK_D(DUK_DPRINT("=== hobject %p ===", (void *) obj));
if (!obj) {
return;
}
DUK_D(DUK_DPRINT(" %sextensible", (const char *) (DUK_HOBJECT_HAS_EXTENSIBLE(obj) ? str_empty : str_excl)));
DUK_D(DUK_DPRINT(" %sconstructable", (const char *) (DUK_HOBJECT_HAS_CONSTRUCTABLE(obj) ? str_empty : str_excl)));
DUK_D(DUK_DPRINT(" %sbound", (const char *) (DUK_HOBJECT_HAS_BOUND(obj) ? str_empty : str_excl)));
DUK_D(DUK_DPRINT(" %scompiledfunction", (const char *) (DUK_HOBJECT_HAS_COMPILEDFUNCTION(obj) ? str_empty : str_excl)));
DUK_D(DUK_DPRINT(" %snativefunction", (const char *) (DUK_HOBJECT_HAS_NATIVEFUNCTION(obj) ? str_empty : str_excl)));
DUK_D(DUK_DPRINT(" %sthread", (const char *) (DUK_HOBJECT_HAS_THREAD(obj) ? str_empty : str_excl)));
DUK_D(DUK_DPRINT(" %sarray_part", (const char *) (DUK_HOBJECT_HAS_ARRAY_PART(obj) ? str_empty : str_excl)));
DUK_D(DUK_DPRINT(" %sstrict", (const char *) (DUK_HOBJECT_HAS_STRICT(obj) ? str_empty : str_excl)));
DUK_D(DUK_DPRINT(" %snewenv", (const char *) (DUK_HOBJECT_HAS_NEWENV(obj) ? str_empty : str_excl)));
DUK_D(DUK_DPRINT(" %snamebinding", (const char *) (DUK_HOBJECT_HAS_NAMEBINDING(obj) ? str_empty : str_excl)));
DUK_D(DUK_DPRINT(" %screateargs", (const char *) (DUK_HOBJECT_HAS_CREATEARGS(obj) ? str_empty : str_excl)));
DUK_D(DUK_DPRINT(" %senvrecclosed", (const char *) (DUK_HOBJECT_HAS_ENVRECCLOSED(obj) ? str_empty : str_excl)));
DUK_D(DUK_DPRINT(" %sexotic_array", (const char *) (DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj) ? str_empty : str_excl)));
DUK_D(DUK_DPRINT(" %sexotic_stringobj", (const char *) (DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(obj) ? str_empty : str_excl)));
DUK_D(DUK_DPRINT(" %sexotic_arguments", (const char *) (DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj) ? str_empty : str_excl)));
DUK_D(DUK_DPRINT(" %sexotic_dukfunc", (const char *) (DUK_HOBJECT_HAS_EXOTIC_DUKFUNC(obj) ? str_empty : str_excl)));
DUK_D(DUK_DPRINT(" %sexotic_bufferobj", (const char *) (DUK_HOBJECT_HAS_EXOTIC_BUFFEROBJ(obj) ? str_empty : str_excl)));
DUK_D(DUK_DPRINT(" %sexotic_proxyobj", (const char *) (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(obj) ? str_empty : str_excl)));
DUK_D(DUK_DPRINT(" class: number %ld -> %s",
(long) DUK_HOBJECT_GET_CLASS_NUMBER(obj),
(const char *) (duk__class_names[(DUK_HOBJECT_GET_CLASS_NUMBER(obj)) & ((1 << DUK_HOBJECT_FLAG_CLASS_BITS) - 1)])));
DUK_D(DUK_DPRINT(" prototype: %p -> %!O",
(void *) DUK_HOBJECT_GET_PROTOTYPE(obj),
(duk_heaphdr *) DUK_HOBJECT_GET_PROTOTYPE(obj)));
DUK_D(DUK_DPRINT(" props: p=%p, e_size=%ld, e_next=%ld, a_size=%ld, h_size=%ld",
(void *) DUK_HOBJECT_GET_PROPS(obj),
(long) DUK_HOBJECT_GET_ESIZE(obj),
(long) DUK_HOBJECT_GET_ENEXT(obj),
(long) DUK_HOBJECT_GET_ASIZE(obj),
(long) DUK_HOBJECT_GET_HSIZE(obj)));
/*
* Object (struct layout) specific dumping. Inline code here
* instead of helpers, to ensure debug line prefix is identical.
*/
if (DUK_HOBJECT_IS_COMPILEDFUNCTION(obj)) {
duk_hcompiledfunction *h = (duk_hcompiledfunction *) obj;
duk_hbuffer *h_data;
DUK_D(DUK_DPRINT(" hcompiledfunction"));
DUK_D(DUK_DPRINT(" data: %!O", (duk_heaphdr *) DUK_HCOMPILEDFUNCTION_GET_DATA(h)));
DUK_D(DUK_DPRINT(" nregs: %ld", (long) h->nregs));
DUK_D(DUK_DPRINT(" nargs: %ld", (long) h->nargs));
h_data = (duk_hbuffer *) DUK_HCOMPILEDFUNCTION_GET_DATA(h);
if (h_data && DUK_HBUFFER_HAS_DYNAMIC(h_data) && DUK_HBUFFER_GET_DATA_PTR(h_data)) {
DUK_D(DUK_DPRINT(" consts: %p (%ld, %ld bytes)",
(void *) DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(h),
(long) DUK_HCOMPILEDFUNCTION_GET_CONSTS_COUNT(h),
(long) DUK_HCOMPILEDFUNCTION_GET_CONSTS_SIZE(h)));
DUK_D(DUK_DPRINT(" funcs: %p (%ld, %ld bytes)",
(void *) DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE(h),
(long) DUK_HCOMPILEDFUNCTION_GET_FUNCS_COUNT(h),
(long) DUK_HCOMPILEDFUNCTION_GET_FUNCS_SIZE(h)));
DUK_D(DUK_DPRINT(" bytecode: %p (%ld, %ld bytes)",
(void *) DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(h),
(long) DUK_HCOMPILEDFUNCTION_GET_CODE_COUNT(h),
(long) DUK_HCOMPILEDFUNCTION_GET_CODE_SIZE(h)));
} else {
DUK_D(DUK_DPRINT(" consts: ???"));
DUK_D(DUK_DPRINT(" funcs: ???"));
DUK_D(DUK_DPRINT(" bytecode: ???"));
}
} else if (DUK_HOBJECT_IS_NATIVEFUNCTION(obj)) {
duk_hnativefunction *h = (duk_hnativefunction *) obj;
DUK_UNREF(h);
DUK_D(DUK_DPRINT(" hnativefunction"));
/* XXX: h->func, cannot print function pointers portably */
DUK_D(DUK_DPRINT(" nargs: %ld", (long) h->nargs));
} else if (DUK_HOBJECT_IS_THREAD(obj)) {
duk_hthread *thr = (duk_hthread *) obj;
duk_tval *p;
DUK_D(DUK_DPRINT(" hthread"));
DUK_D(DUK_DPRINT(" strict: %ld", (long) thr->strict));
DUK_D(DUK_DPRINT(" state: %ld", (long) thr->state));
DUK_D(DUK_DPRINT(" valstack_max: %ld, callstack_max: %ld, catchstack_max: %ld",
(long) thr->valstack_max, (long) thr->callstack_max, (long) thr->catchstack_max));
DUK_D(DUK_DPRINT(" callstack: ptr %p, size %ld, top %ld, preventcount %ld, used size %ld entries (%ld bytes), alloc size %ld entries (%ld bytes)",
(void *) thr->callstack,
(long) thr->callstack_size,
(long) thr->callstack_top,
(long) thr->callstack_preventcount,
(long) thr->callstack_top,
(long) (thr->callstack_top * sizeof(duk_activation)),
(long) thr->callstack_size,
(long) (thr->callstack_size * sizeof(duk_activation))));
DUK_DEBUG_SUMMARY_INIT();
DUK_DEBUG_SUMMARY_CHAR('[');
for (i = 0; i <= (duk_uint_fast32_t) thr->callstack_size; i++) {
if (i == thr->callstack_top) {
DUK_DEBUG_SUMMARY_CHAR('|');
}
if (!thr->callstack) {
DUK_DEBUG_SUMMARY_CHAR('@');
} else if (i < thr->callstack_size) {
if (i < thr->callstack_top) {
/* tailcalling is nice to see immediately; other flags (e.g. strict)
* not that important.
*/
if (thr->callstack[i].flags & DUK_ACT_FLAG_TAILCALLED) {
DUK_DEBUG_SUMMARY_CHAR('/');
}
DUK_DEBUG_SUMMARY_CHAR(duk__get_act_summary_char(thr->callstack + i));
} else {
DUK_DEBUG_SUMMARY_CHAR('.');
}
}
}
DUK_DEBUG_SUMMARY_CHAR(']');
DUK_DEBUG_SUMMARY_FINISH();
DUK_D(DUK_DPRINT(" valstack: ptr %p, end %p (%ld), bottom %p (%ld), top %p (%ld), used size %ld entries (%ld bytes), alloc size %ld entries (%ld bytes)",
(void *) thr->valstack,
(void *) thr->valstack_end,
(long) (thr->valstack_end - thr->valstack),
(void *) thr->valstack_bottom,
(long) (thr->valstack_bottom - thr->valstack),
(void *) thr->valstack_top,
(long) (thr->valstack_top - thr->valstack),
(long) (thr->valstack_top - thr->valstack),
(long) (thr->valstack_top - thr->valstack) * sizeof(duk_tval),
(long) (thr->valstack_end - thr->valstack),
(long) (thr->valstack_end - thr->valstack) * sizeof(duk_tval)));
DUK_DEBUG_SUMMARY_INIT();
DUK_DEBUG_SUMMARY_CHAR('[');
p = thr->valstack;
while (p <= thr->valstack_end) {
i = (duk_uint_fast32_t) (p - thr->valstack);
if (thr->callstack &&
thr->callstack_top > 0 &&
i == (duk_size_t) (thr->callstack + thr->callstack_top - 1)->idx_bottom) {
DUK_DEBUG_SUMMARY_CHAR('>');
}
if (p == thr->valstack_top) {
DUK_DEBUG_SUMMARY_CHAR('|');
}
if (p < thr->valstack_end) {
if (p < thr->valstack_top) {
DUK_DEBUG_SUMMARY_CHAR(duk__get_tval_summary_char(p));
} else {
/* XXX: safe printer for these? would be nice, because
* we could visualize whether the values are in proper
* state.
*/
DUK_DEBUG_SUMMARY_CHAR('.');
}
}
p++;
}
DUK_DEBUG_SUMMARY_CHAR(']');
DUK_DEBUG_SUMMARY_FINISH();
DUK_D(DUK_DPRINT(" catchstack: ptr %p, size %ld, top %ld, used size %ld entries (%ld bytes), alloc size %ld entries (%ld bytes)",
(void *) thr->catchstack,
(long) thr->catchstack_size,
(long) thr->catchstack_top,
(long) thr->catchstack_top,
(long) (thr->catchstack_top * sizeof(duk_catcher)),
(long) thr->catchstack_size,
(long) (thr->catchstack_size * sizeof(duk_catcher))));
DUK_DEBUG_SUMMARY_INIT();
DUK_DEBUG_SUMMARY_CHAR('[');
for (i = 0; i <= (duk_uint_fast32_t) thr->catchstack_size; i++) {
if (i == thr->catchstack_top) {
DUK_DEBUG_SUMMARY_CHAR('|');
}
if (!thr->catchstack) {
DUK_DEBUG_SUMMARY_CHAR('@');
} else if (i < thr->catchstack_size) {
if (i < thr->catchstack_top) {
DUK_DEBUG_SUMMARY_CHAR(duk__get_cat_summary_char(thr->catchstack + i));
} else {
DUK_DEBUG_SUMMARY_CHAR('.');
}
}
}
DUK_DEBUG_SUMMARY_CHAR(']');
DUK_DEBUG_SUMMARY_FINISH();
DUK_D(DUK_DPRINT(" resumer: ptr %p", (void *) thr->resumer));
#if 0 /* worth dumping? */
for (i = 0; i < DUK_NUM_BUILTINS; i++) {
DUK_D(DUK_DPRINT(" builtins[%ld] -> %!@O", (long) i, (duk_heaphdr *) thr->builtins[i]));
}
#endif
}
if (DUK_HOBJECT_GET_PROPS(obj)) {
DUK_D(DUK_DPRINT(" props alloc size: %ld",
(long) DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE(obj),
DUK_HOBJECT_GET_ASIZE(obj),
DUK_HOBJECT_GET_HSIZE(obj))));
} else {
DUK_D(DUK_DPRINT(" props alloc size: n/a"));
}
DUK_D(DUK_DPRINT(" prop entries:"));
for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ESIZE(obj); i++) {
duk_hstring *k;
duk_propvalue *v;
k = DUK_HOBJECT_E_GET_KEY(obj, i);
v = DUK_HOBJECT_E_GET_VALUE_PTR(obj, i);
DUK_UNREF(v);
if (i >= DUK_HOBJECT_GET_ENEXT(obj)) {
DUK_D(DUK_DPRINT(" [%ld]: UNUSED", (long) i));
continue;
}
if (!k) {
DUK_D(DUK_DPRINT(" [%ld]: NULL", (long) i));
continue;
}
if (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(obj, i)) {
DUK_D(DUK_DPRINT(" [%ld]: [w=%ld e=%ld c=%ld a=%ld] %!O -> get:%p set:%p; get %!O; set %!O",
(long) i,
(long) (DUK_HOBJECT_E_SLOT_IS_WRITABLE(obj, i) ? 1 : 0),
(long) (DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(obj, i) ? 1 : 0),
(long) (DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(obj, i) ? 1 : 0),
(long) (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(obj, i) ? 1 : 0),
(duk_heaphdr *) k,
(void *) v->a.get,
(void *) v->a.set,
(duk_heaphdr *) v->a.get,
(duk_heaphdr *) v->a.set));
} else {
DUK_D(DUK_DPRINT(" [%ld]: [w=%ld e=%ld c=%ld a=%ld] %!O -> %!T",
(long) i,
(long) (DUK_HOBJECT_E_SLOT_IS_WRITABLE(obj, i) ? 1 : 0),
(long) (DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(obj, i) ? 1 : 0),
(long) (DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(obj, i) ? 1 : 0),
(long) (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(obj, i) ? 1 : 0),
(duk_heaphdr *) k,
(duk_tval *) &v->v));
}
}
DUK_D(DUK_DPRINT(" array entries:"));
for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(obj); i++) {
DUK_D(DUK_DPRINT(" [%ld]: [w=%ld e=%ld c=%ld a=%ld] %ld -> %!T",
(long) i,
(long) 1, /* implicit attributes */
(long) 1,
(long) 1,
(long) 0,
(long) i,
(duk_tval *) DUK_HOBJECT_A_GET_VALUE_PTR(obj, i)));
}
DUK_D(DUK_DPRINT(" hash entries:"));
#if defined(DUK_USE_HOBJECT_HASH_PART)
for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_HSIZE(obj); i++) {
duk_uint32_t t = DUK_HOBJECT_H_GET_INDEX(obj, i);
if (t == DUK_HOBJECT_HASHIDX_UNUSED) {
DUK_D(DUK_DPRINT(" [%ld]: unused", (long) i));
} else if (t == DUK_HOBJECT_HASHIDX_DELETED) {
DUK_D(DUK_DPRINT(" [%ld]: deleted", (long) i));
} else {
DUK_D(DUK_DPRINT(" [%ld]: %ld", (long) i, (long) t));
}
}
#endif
}
#if 0 /*unused*/
DUK_INTERNAL void duk_debug_dump_callstack(duk_hthread *thr) {
duk_uint_fast32_t i;
DUK_D(DUK_DPRINT("=== hthread %p callstack: %ld entries ===",
(void *) thr,
(thr == NULL ? (long) 0 : (long) thr->callstack_top)));
if (!thr) {
return;
}
for (i = 0; i < (duk_uint_fast32_t) thr->callstack_top; i++) {
duk_activation *act = thr->callstack + i;
duk_tval *this_binding = NULL;
this_binding = thr->valstack + act->idx_bottom - 1;
if (this_binding < thr->valstack || this_binding >= thr->valstack_top) {
this_binding = NULL;
}
DUK_D(DUK_DPRINT(" [%ld] -> flags=0x%08lx, func=%!O, var_env=%!iO, lex_env=%!iO, "
"pc=%ld, idx_bottom=%ld, idx_retval=%ld, this_binding=%!T",
(long) i,
(unsigned long) act->flags,
(duk_heaphdr *) act->func,
(duk_heaphdr *) act->var_env,
(duk_heaphdr *) act->lex_env,
(long) act->pc,
(long) act->idx_bottom,
(long) act->idx_retval,
(duk_tval *) this_binding));
}
}
#endif
#if 0 /*unused*/
DUK_INTERNAL void duk_debug_dump_activation(duk_hthread *thr, duk_activation *act) {
if (!act) {
DUK_D(DUK_DPRINT("duk_activation: NULL"));
} else {
duk_tval *this_binding = NULL;
this_binding = thr->valstack + act->idx_bottom - 1;
if (this_binding < thr->valstack || this_binding >= thr->valstack_top) {
this_binding = NULL;
}
DUK_D(DUK_DPRINT("duk_activation: %p -> flags=0x%08lx, func=%!O, var_env=%!O, "
"lex_env=%!O, pc=%ld, idx_bottom=%ld, idx_retval=%ld, this_binding=%!T",
(void *) act,
(unsigned long) act->flags,
(duk_heaphdr *) act->func,
(duk_heaphdr *) act->var_env,
(duk_heaphdr *) act->lex_env,
(long) act->pc,
(long) act->idx_bottom,
(long) act->idx_retval,
(duk_tval *) this_binding));
}
}
#endif
#endif /* DUK_USE_DEBUG */

4
src/duk_debug_macros.c

@ -14,10 +14,6 @@
#include <stdlib.h>
#include <stdarg.h>
/* for one-char summaries (usable for e.g. valstack) */
DUK_INTERNAL char duk_debug_summary_buf[DUK_DEBUG_SUMMARY_BUF_SIZE];
DUK_INTERNAL duk_int_t duk_debug_summary_idx;
#define DUK__DEBUG_BUFSIZE DUK_USE_DEBUG_BUFSIZE
DUK_LOCAL char duk__debug_buf[DUK__DEBUG_BUFSIZE];

36
src/duk_debug_vsnprintf.c

@ -173,8 +173,8 @@ DUK_LOCAL void duk__print_shared_heaphdr(duk__dprint_state *st, duk_heaphdr *h)
if (st->heavy) {
duk_fb_sprintf(fb, "[h_next=%p,h_prev=%p,h_refcount=%lu,h_flags=%08lx,type=%ld,"
"reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]",
(void *) DUK_HEAPHDR_GET_NEXT(h),
(void *) DUK_HEAPHDR_GET_PREV(h),
(void *) DUK_HEAPHDR_GET_NEXT(NULL, h),
(void *) DUK_HEAPHDR_GET_PREV(NULL, h),
(unsigned long) DUK_HEAPHDR_GET_REFCOUNT(h),
(unsigned long) DUK_HEAPHDR_GET_FLAGS(h),
(long) DUK_HEAPHDR_GET_TYPE(h),
@ -186,7 +186,7 @@ DUK_LOCAL void duk__print_shared_heaphdr(duk__dprint_state *st, duk_heaphdr *h)
#else
if (st->heavy) {
duk_fb_sprintf(fb, "[h_next=%p,h_flags=%08lx,type=%ld,reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]",
(void *) DUK_HEAPHDR_GET_NEXT(h),
(void *) DUK_HEAPHDR_GET_NEXT(NULL, h),
(unsigned long) DUK_HEAPHDR_GET_FLAGS(h),
(long) DUK_HEAPHDR_GET_TYPE(h),
(long) (DUK_HEAPHDR_HAS_REACHABLE(h) ? 1 : 0),
@ -375,7 +375,7 @@ DUK_LOCAL void duk__print_hobject(duk__dprint_state *st, duk_hobject *h) {
duk_fb_put_cstring(fb, brace1);
if (DUK_HOBJECT_GET_PROPS(h)) {
if (DUK_HOBJECT_GET_PROPS(NULL, h)) {
duk_uint32_t a_limit;
a_limit = DUK_HOBJECT_GET_ASIZE(h);
@ -387,7 +387,7 @@ DUK_LOCAL void duk__print_hobject(duk__dprint_state *st, duk_hobject *h) {
} else {
/* leave out trailing 'unused' elements */
while (a_limit > 0) {
tv = DUK_HOBJECT_A_GET_VALUE_PTR(h, a_limit - 1);
tv = DUK_HOBJECT_A_GET_VALUE_PTR(NULL, h, a_limit - 1);
if (!DUK_TVAL_IS_UNDEFINED_UNUSED(tv)) {
break;
}
@ -396,12 +396,12 @@ DUK_LOCAL void duk__print_hobject(duk__dprint_state *st, duk_hobject *h) {
}
for (i = 0; i < a_limit; i++) {
tv = DUK_HOBJECT_A_GET_VALUE_PTR(h, i);
tv = DUK_HOBJECT_A_GET_VALUE_PTR(NULL, h, i);
DUK__COMMA();
duk__print_tval(st, tv);
}
for (i = 0; i < DUK_HOBJECT_GET_ENEXT(h); i++) {
key = DUK_HOBJECT_E_GET_KEY(h, i);
key = DUK_HOBJECT_E_GET_KEY(NULL, h, i);
if (!key) {
continue;
}
@ -414,16 +414,16 @@ DUK_LOCAL void duk__print_hobject(duk__dprint_state *st, duk_hobject *h) {
DUK__COMMA();
duk__print_hstring(st, key, 0);
duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_COLON);
if (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(h, i)) {
if (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(NULL, h, i)) {
duk_fb_sprintf(fb, "[get:%p,set:%p]",
(void *) DUK_HOBJECT_E_GET_VALUE(h, i).a.get,
(void *) DUK_HOBJECT_E_GET_VALUE(h, i).a.set);
(void *) DUK_HOBJECT_E_GET_VALUE(NULL, h, i).a.get,
(void *) DUK_HOBJECT_E_GET_VALUE(NULL, h, i).a.set);
} else {
tv = &DUK_HOBJECT_E_GET_VALUE(h, i).v;
tv = &DUK_HOBJECT_E_GET_VALUE(NULL, h, i).v;
duk__print_tval(st, tv);
}
if (st->heavy) {
duk_fb_sprintf(fb, "<%02lx>", (unsigned long) DUK_HOBJECT_E_GET_FLAGS(h, i));
duk_fb_sprintf(fb, "<%02lx>", (unsigned long) DUK_HOBJECT_E_GET_FLAGS(NULL, h, i));
}
}
}
@ -522,7 +522,7 @@ DUK_LOCAL void duk__print_hobject(duk__dprint_state *st, duk_hobject *h) {
if (st->internal && DUK_HOBJECT_IS_COMPILEDFUNCTION(h)) {
duk_hcompiledfunction *f = (duk_hcompiledfunction *) h;
DUK__COMMA(); duk_fb_put_cstring(fb, "__data:");
duk__print_hbuffer(st, (duk_hbuffer *) DUK_HCOMPILEDFUNCTION_GET_DATA(f));
duk__print_hbuffer(st, (duk_hbuffer *) DUK_HCOMPILEDFUNCTION_GET_DATA(NULL, f));
DUK__COMMA(); duk_fb_sprintf(fb, "__nregs:%ld", (long) f->nregs);
DUK__COMMA(); duk_fb_sprintf(fb, "__nargs:%ld", (long) f->nargs);
} else if (st->internal && DUK_HOBJECT_IS_NATIVEFUNCTION(h)) {
@ -560,8 +560,8 @@ DUK_LOCAL void duk__print_hobject(duk__dprint_state *st, duk_hobject *h) {
}
/* prototype should be last, for readability */
if (st->follow_proto && DUK_HOBJECT_GET_PROTOTYPE(h)) {
DUK__COMMA(); duk_fb_put_cstring(fb, "__prototype:"); duk__print_hobject(st, DUK_HOBJECT_GET_PROTOTYPE(h));
if (st->follow_proto && DUK_HOBJECT_GET_PROTOTYPE(NULL, h)) {
DUK__COMMA(); duk_fb_put_cstring(fb, "__prototype:"); duk__print_hobject(st, DUK_HOBJECT_GET_PROTOTYPE(NULL, h));
}
duk_fb_put_cstring(fb, brace2);
@ -570,7 +570,7 @@ DUK_LOCAL void duk__print_hobject(duk__dprint_state *st, duk_hobject *h) {
if (st->heavy && DUK_HOBJECT_GET_HSIZE(h) > 0) {
duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LANGLE);
for (i = 0; i < DUK_HOBJECT_GET_HSIZE(h); i++) {
duk_uint_t h_idx = DUK_HOBJECT_H_GET_INDEX(h, i);
duk_uint_t h_idx = DUK_HOBJECT_H_GET_INDEX(NULL, h, i);
if (i > 0) {
duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_COMMA);
}
@ -615,7 +615,7 @@ DUK_LOCAL void duk__print_hbuffer(duk__dprint_state *st, duk_hbuffer *h) {
if (DUK_HBUFFER_HAS_DYNAMIC(h)) {
duk_hbuffer_dynamic *g = (duk_hbuffer_dynamic *) h;
duk_fb_sprintf(fb, "buffer:dynamic:%p:%ld:%ld",
(void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(g),
(void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(NULL, g),
(long) DUK_HBUFFER_DYNAMIC_GET_SIZE(g),
(long) DUK_HBUFFER_DYNAMIC_GET_ALLOC_SIZE(g));
} else {
@ -629,7 +629,7 @@ DUK_LOCAL void duk__print_hbuffer(duk__dprint_state *st, duk_hbuffer *h) {
if (st->hexdump) {
duk_fb_sprintf(fb, "=[");
n = DUK_HBUFFER_GET_SIZE(h);
p = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(h);
p = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(NULL, h);
for (i = 0; i < n; i++) {
duk_fb_sprintf(fb, "%02lx", (unsigned long) p[i]);
}

3
src/duk_error_augment.c

@ -96,7 +96,8 @@ DUK_LOCAL void duk__err_augment_user(duk_hthread *thr, duk_small_uint_t stridx_c
DUK_DD(DUK_DDPRINT("error occurred when DUK_BIDX_DUKTAPE is NULL, ignoring"));
return;
}
tv_hnd = duk_hobject_find_existing_entry_tval_ptr(thr->builtins[DUK_BIDX_DUKTAPE],
tv_hnd = duk_hobject_find_existing_entry_tval_ptr(thr->heap,
thr->builtins[DUK_BIDX_DUKTAPE],
DUK_HTHREAD_GET_STRING(thr, stridx_cb));
if (tv_hnd == NULL) {
DUK_DD(DUK_DDPRINT("error handler does not exist or is not a plain value: %!T",

16
src/duk_features.h.in

@ -2623,12 +2623,12 @@ typedef FILE duk_file;
#undef DUK_USE_EXTSTR_INTERN_CHECK
#if defined(DUK_OPT_EXTERNAL_STRINGS) && defined(DUK_OPT_EXTSTR_INTERN_CHECK)
#define DUK_USE_EXTSTR_INTERN_CHECK(ptr,len) DUK_OPT_EXTSTR_INTERN_CHECK((ptr), (len))
#define DUK_USE_EXTSTR_INTERN_CHECK(udata,ptr,len) DUK_OPT_EXTSTR_INTERN_CHECK((udata), (ptr), (len))
#endif
#undef DUK_USE_EXTSTR_FREE
#if defined(DUK_OPT_EXTERNAL_STRINGS) && defined(DUK_OPT_EXTSTR_FREE)
#define DUK_USE_EXTSTR_FREE(ptr) DUK_OPT_EXTSTR_FREE((ptr))
#define DUK_USE_EXTSTR_FREE(udata,ptr) DUK_OPT_EXTSTR_FREE((udata), (ptr))
#endif
/*
@ -2654,8 +2654,8 @@ typedef FILE duk_file;
#undef DUK_USE_HEAPPTR_DEC16
#if defined(DUK_OPT_HEAPPTR16) && defined(DUK_OPT_HEAPPTR_ENC16) && defined(DUK_OPT_HEAPPTR_DEC16)
#define DUK_USE_HEAPPTR16
#define DUK_USE_HEAPPTR_ENC16(ptr) DUK_OPT_HEAPPTR_ENC16((ptr))
#define DUK_USE_HEAPPTR_DEC16(ptr) DUK_OPT_HEAPPTR_DEC16((ptr))
#define DUK_USE_HEAPPTR_ENC16(udata,ptr) DUK_OPT_HEAPPTR_ENC16((udata),(ptr))
#define DUK_USE_HEAPPTR_DEC16(udata,ptr) DUK_OPT_HEAPPTR_DEC16((udata),(ptr))
#endif
#undef DUK_USE_DATAPTR16
@ -2663,8 +2663,8 @@ typedef FILE duk_file;
#undef DUK_USE_DATAPTR_DEC16
#if defined(DUK_OPT_DATAPTR16) && defined(DUK_OPT_DATAPTR_ENC16) && defined(DUK_OPT_DATAPTR_DEC16)
#define DUK_USE_DATAPTR16
#define DUK_USE_DATAPTR_ENC16(ptr) DUK_OPT_DATAPTR_ENC16((ptr))
#define DUK_USE_DATAPTR_DEC16(ptr) DUK_OPT_DATAPTR_DEC16((ptr))
#define DUK_USE_DATAPTR_ENC16(udata,ptr) DUK_OPT_DATAPTR_ENC16((udata),(ptr))
#define DUK_USE_DATAPTR_DEC16(udata,ptr) DUK_OPT_DATAPTR_DEC16((udata),(ptr))
#endif
#undef DUK_USE_FUNCPTR16
@ -2672,8 +2672,8 @@ typedef FILE duk_file;
#undef DUK_USE_FUNCPTR_DEC16
#if defined(DUK_OPT_FUNCPTR16) && defined(DUK_OPT_FUNCPTR_ENC16) && defined(DUK_OPT_FUNCPTR_DEC16)
#define DUK_USE_FUNCPTR16
#define DUK_USE_FUNCPTR_ENC16(ptr) DUK_OPT_FUNCPTR_ENC16((ptr))
#define DUK_USE_FUNCPTR_DEC16(ptr) DUK_OPT_FUNCPTR_DEC16((ptr))
#define DUK_USE_FUNCPTR_ENC16(udata,ptr) DUK_OPT_FUNCPTR_ENC16((udata),(ptr))
#define DUK_USE_FUNCPTR_DEC16(udata,ptr) DUK_OPT_FUNCPTR_DEC16((udata),(ptr))
#endif
#undef DUK_USE_REFCOUNT16

5
src/duk_features_sanity.h.in

@ -60,6 +60,11 @@
#error DUK_USE_DDDPRINT without DUK_USE_DEBUG
#endif
#if defined(DUK_USE_HEAPPTR16) && defined(DUK_USE_DEBUG)
/* Debug code doesn't have access to 'heap' so it cannot decode pointers. */
#error debug printing cannot currently be used with heap pointer compression
#endif
/*
* Garbage collection consistency
*/

25
src/duk_hbuffer.h

@ -24,7 +24,7 @@
#define DUK_HBUFFER_CLEAR_DYNAMIC(x) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_DYNAMIC)
#define DUK_HBUFFER_FIXED_GET_DATA_PTR(x) ((duk_uint8_t *) (((duk_hbuffer_fixed *) (x)) + 1))
#define DUK_HBUFFER_FIXED_GET_DATA_PTR(heap,x) ((duk_uint8_t *) (((duk_hbuffer_fixed *) (x)) + 1))
/*
* Misc defines
@ -106,19 +106,20 @@
(duk_size_t) (DUK_HBUFFER_DYNAMIC_GET_ALLOC_SIZE((x)) - DUK_HBUFFER_DYNAMIC_GET_SIZE((x)))
#if defined(DUK_USE_HEAPPTR16)
#define DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(x) ((void *) DUK_USE_HEAPPTR_DEC16((x)->curr_alloc16))
#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(x,v) do { \
(x)->curr_alloc16 = DUK_USE_HEAPPTR_ENC16((void *) (v)); \
#define DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap,x) \
((void *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (x)->curr_alloc16))
#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap,x,v) do { \
(x)->curr_alloc16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \
} while (0)
#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR_NULL(x) do { \
#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR_NULL(heap,x) do { \
(x)->curr_alloc16 = 0; /* assume 0 <=> NULL */ \
} while (0)
#else
#define DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(x) ((x)->curr_alloc)
#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(x,v) do { \
#define DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap,x) ((x)->curr_alloc)
#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap,x,v) do { \
(x)->curr_alloc = (void *) (v); \
} while (0)
#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR_NULL(x) do { \
#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR_NULL(heap,x) do { \
(x)->curr_alloc = (void *) NULL; \
} while (0)
#endif
@ -126,10 +127,10 @@
/* Gets the actual buffer contents which matches the current allocation size
* (may be NULL for zero size dynamic buffer).
*/
#define DUK_HBUFFER_GET_DATA_PTR(x) ( \
#define DUK_HBUFFER_GET_DATA_PTR(heap,x) ( \
DUK_HBUFFER_HAS_DYNAMIC((x)) ? \
DUK_HBUFFER_DYNAMIC_GET_DATA_PTR((duk_hbuffer_dynamic *) (x)) : \
DUK_HBUFFER_FIXED_GET_DATA_PTR((duk_hbuffer_fixed *) (x)) \
DUK_HBUFFER_DYNAMIC_GET_DATA_PTR((heap), (duk_hbuffer_dynamic *) (x)) : \
DUK_HBUFFER_FIXED_GET_DATA_PTR((heap), (duk_hbuffer_fixed *) (x)) \
)
/* Growth parameters for dynamic buffers. */
@ -264,7 +265,7 @@ struct duk_hbuffer_dynamic {
*/
DUK_INTERNAL_DECL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap, duk_size_t size, duk_bool_t dynamic);
DUK_INTERNAL_DECL void *duk_hbuffer_get_dynalloc_ptr(void *ud); /* indirect allocs */
DUK_INTERNAL_DECL void *duk_hbuffer_get_dynalloc_ptr(duk_heap *heap, void *ud); /* indirect allocs */
/* dynamic buffer ops */
DUK_INTERNAL_DECL void duk_hbuffer_resize(duk_hthread *thr, duk_hbuffer_dynamic *buf, duk_size_t new_size, duk_size_t new_alloc_size);

7
src/duk_hbuffer_alloc.c

@ -57,7 +57,7 @@ DUK_INTERNAL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap, duk_size_t size, duk
goto error;
}
DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(h, ptr);
DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap, h, ptr);
DUK_HBUFFER_DYNAMIC_SET_ALLOC_SIZE(h, size); /* snug */
} else {
#ifdef DUK_USE_EXPLICIT_NULL_INIT
@ -87,7 +87,8 @@ DUK_INTERNAL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap, duk_size_t size, duk
/* For indirect allocs. */
DUK_INTERNAL void *duk_hbuffer_get_dynalloc_ptr(void *ud) {
DUK_INTERNAL void *duk_hbuffer_get_dynalloc_ptr(duk_heap *heap, void *ud) {
duk_hbuffer_dynamic *buf = (duk_hbuffer_dynamic *) ud;
return (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(buf);
DUK_UNREF(heap);
return (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, buf);
}

14
src/duk_hbuffer_ops.c

@ -57,7 +57,7 @@ DUK_INTERNAL void duk_hbuffer_resize(duk_hthread *thr, duk_hbuffer_dynamic *buf,
/* 'res' may be NULL if new allocation size is 0. */
DUK_DDD(DUK_DDDPRINT("resized dynamic buffer %p:%ld:%ld -> %p:%ld:%ld",
(void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(buf),
(void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, buf),
(long) DUK_HBUFFER_DYNAMIC_GET_SIZE(buf),
(long) DUK_HBUFFER_DYNAMIC_GET_ALLOC_SIZE(buf),
(void *) res,
@ -84,7 +84,7 @@ DUK_INTERNAL void duk_hbuffer_resize(duk_hthread *thr, duk_hbuffer_dynamic *buf,
DUK_HBUFFER_DYNAMIC_SET_SIZE(buf, new_size);
DUK_HBUFFER_DYNAMIC_SET_ALLOC_SIZE(buf, new_alloc_size);
DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(buf, res);
DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(thr->heap, buf, res);
} else {
DUK_ERROR(thr, DUK_ERR_ALLOC_ERROR, "buffer resize failed: %ld:%ld to %ld:%ld",
(long) DUK_HBUFFER_DYNAMIC_GET_SIZE(buf),
@ -146,7 +146,7 @@ DUK_INTERNAL void duk_hbuffer_insert_bytes(duk_hthread *thr, duk_hbuffer_dynamic
}
DUK_ASSERT(DUK_HBUFFER_DYNAMIC_GET_SPARE_SIZE(buf) >= length);
p = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(buf);
p = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, buf);
if (offset < DUK_HBUFFER_GET_SIZE(buf)) {
/* not an append */
@ -316,7 +316,7 @@ DUK_INTERNAL duk_size_t duk_hbuffer_append_xutf8(duk_hthread *thr, duk_hbuffer_d
if (DUK_LIKELY(codepoint < 0x80 && DUK_HBUFFER_DYNAMIC_GET_SPARE_SIZE(buf) > 0)) {
/* fast path: ASCII and there is spare */
duk_uint8_t *p = ((duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(buf));
duk_uint8_t *p = ((duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, buf));
sz = DUK_HBUFFER_DYNAMIC_GET_SIZE(buf);
p[sz++] = (duk_uint8_t) codepoint;
DUK_HBUFFER_DYNAMIC_SET_SIZE(buf, sz);
@ -347,7 +347,7 @@ DUK_INTERNAL duk_size_t duk_hbuffer_append_cesu8(duk_hthread *thr, duk_hbuffer_d
if (DUK_LIKELY(codepoint < 0x80 && DUK_HBUFFER_DYNAMIC_GET_SPARE_SIZE(buf) > 0)) {
/* fast path: ASCII and there is spare */
duk_uint8_t *p = ((duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(buf));
duk_uint8_t *p = ((duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, buf));
sz = DUK_HBUFFER_DYNAMIC_GET_SIZE(buf);
p[sz++] = (duk_uint8_t) codepoint;
DUK_HBUFFER_DYNAMIC_SET_SIZE(buf, sz);
@ -398,7 +398,7 @@ DUK_INTERNAL void duk_hbuffer_remove_slice(duk_hthread *thr, duk_hbuffer_dynamic
return;
}
p = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(buf);
p = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, buf);
end_offset = offset + length;
@ -449,7 +449,7 @@ DUK_INTERNAL void duk_hbuffer_insert_slice(duk_hthread *thr, duk_hbuffer_dynamic
}
DUK_ASSERT(DUK_HBUFFER_DYNAMIC_GET_SPARE_SIZE(buf) >= length);
p = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(buf);
p = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, buf);
DUK_ASSERT(p != NULL); /* must be the case because length > 0, and buffer has been resized if necessary */
/*

96
src/duk_hcompiledfunction.h

@ -15,35 +15,35 @@
/* XXX: casts could be improved, especially for GET/SET DATA */
#if defined(DUK_USE_HEAPPTR16)
#define DUK_HCOMPILEDFUNCTION_GET_DATA(h) \
((duk_hbuffer_fixed *) DUK_USE_HEAPPTR_DEC16((h)->data16))
#define DUK_HCOMPILEDFUNCTION_SET_DATA(h,v) do { \
(h)->data16 = DUK_USE_HEAPPTR_ENC16((void *) (v)); \
#define DUK_HCOMPILEDFUNCTION_GET_DATA(heap,h) \
((duk_hbuffer_fixed *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->data16))
#define DUK_HCOMPILEDFUNCTION_SET_DATA(heap,h,v) do { \
(h)->data16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \
} while (0)
#define DUK_HCOMPILEDFUNCTION_GET_FUNCS(h) \
((duk_hobject **) (DUK_USE_HEAPPTR_DEC16((h)->funcs16)))
#define DUK_HCOMPILEDFUNCTION_SET_FUNCS(h,v) do { \
(h)->funcs16 = DUK_USE_HEAPPTR_ENC16((void *) (v)); \
#define DUK_HCOMPILEDFUNCTION_GET_FUNCS(heap,h) \
((duk_hobject **) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->funcs16)))
#define DUK_HCOMPILEDFUNCTION_SET_FUNCS(heap,h,v) do { \
(h)->funcs16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \
} while (0)
#define DUK_HCOMPILEDFUNCTION_GET_BYTECODE(h) \
((duk_instr_t *) (DUK_USE_HEAPPTR_DEC16((h)->bytecode16)))
#define DUK_HCOMPILEDFUNCTION_SET_BYTECODE(h,v) do { \
(h)->bytecode16 = DUK_USE_HEAPPTR_ENC16((void *) (v)); \
#define DUK_HCOMPILEDFUNCTION_GET_BYTECODE(heap,h) \
((duk_instr_t *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->bytecode16)))
#define DUK_HCOMPILEDFUNCTION_SET_BYTECODE(heap,h,v) do { \
(h)->bytecode16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \
} while (0)
#else
#define DUK_HCOMPILEDFUNCTION_GET_DATA(h) \
#define DUK_HCOMPILEDFUNCTION_GET_DATA(heap,h) \
((duk_hbuffer_fixed *) (h)->data)
#define DUK_HCOMPILEDFUNCTION_SET_DATA(h,v) do { \
#define DUK_HCOMPILEDFUNCTION_SET_DATA(heap,h,v) do { \
(h)->data = (duk_hbuffer *) (v); \
} while (0)
#define DUK_HCOMPILEDFUNCTION_GET_FUNCS(h) \
#define DUK_HCOMPILEDFUNCTION_GET_FUNCS(heap,h) \
((h)->funcs)
#define DUK_HCOMPILEDFUNCTION_SET_FUNCS(h,v) do { \
#define DUK_HCOMPILEDFUNCTION_SET_FUNCS(heap,h,v) do { \
(h)->funcs = (v); \
} while (0)
#define DUK_HCOMPILEDFUNCTION_GET_BYTECODE(h) \
#define DUK_HCOMPILEDFUNCTION_GET_BYTECODE(heap,h) \
((h)->bytecode)
#define DUK_HCOMPILEDFUNCTION_SET_BYTECODE(h,v) do { \
#define DUK_HCOMPILEDFUNCTION_SET_BYTECODE(heap,h,v) do { \
(h)->bytecode = (v); \
} while (0)
#endif
@ -53,64 +53,64 @@
*/
/* Note: assumes 'data' is always a fixed buffer */
#define DUK_HCOMPILEDFUNCTION_GET_BUFFER_BASE(h) \
DUK_HBUFFER_FIXED_GET_DATA_PTR(DUK_HCOMPILEDFUNCTION_GET_DATA((h)))
#define DUK_HCOMPILEDFUNCTION_GET_BUFFER_BASE(heap,h) \
DUK_HBUFFER_FIXED_GET_DATA_PTR((heap), DUK_HCOMPILEDFUNCTION_GET_DATA((heap), (h)))
#define DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(h) \
((duk_tval *) DUK_HCOMPILEDFUNCTION_GET_BUFFER_BASE((h)))
#define DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(heap,h) \
((duk_tval *) DUK_HCOMPILEDFUNCTION_GET_BUFFER_BASE((heap), (h)))
#define DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE(h) \
DUK_HCOMPILEDFUNCTION_GET_FUNCS((h))
#define DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE(heap,h) \
DUK_HCOMPILEDFUNCTION_GET_FUNCS((heap), (h))
#define DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(h) \
DUK_HCOMPILEDFUNCTION_GET_BYTECODE((h))
#define DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(heap,h) \
DUK_HCOMPILEDFUNCTION_GET_BYTECODE((heap), (h))
#define DUK_HCOMPILEDFUNCTION_GET_CONSTS_END(h) \
((duk_tval *) DUK_HCOMPILEDFUNCTION_GET_FUNCS((h)))
#define DUK_HCOMPILEDFUNCTION_GET_CONSTS_END(heap,h) \
((duk_tval *) DUK_HCOMPILEDFUNCTION_GET_FUNCS((heap), (h)))
#define DUK_HCOMPILEDFUNCTION_GET_FUNCS_END(h) \
((duk_hobject **) DUK_HCOMPILEDFUNCTION_GET_BYTECODE((h)))
#define DUK_HCOMPILEDFUNCTION_GET_FUNCS_END(heap,h) \
((duk_hobject **) DUK_HCOMPILEDFUNCTION_GET_BYTECODE((heap), (h)))
/* XXX: double evaluation of DUK_HCOMPILEDFUNCTION_GET_DATA() */
#define DUK_HCOMPILEDFUNCTION_GET_CODE_END(h) \
((duk_instr_t *) (DUK_HBUFFER_FIXED_GET_DATA_PTR(DUK_HCOMPILEDFUNCTION_GET_DATA((h))) + \
DUK_HBUFFER_GET_SIZE((duk_hbuffer *) DUK_HCOMPILEDFUNCTION_GET_DATA(h))))
#define DUK_HCOMPILEDFUNCTION_GET_CODE_END(heap,h) \
((duk_instr_t *) (DUK_HBUFFER_FIXED_GET_DATA_PTR((heap), DUK_HCOMPILEDFUNCTION_GET_DATA((heap), (h))) + \
DUK_HBUFFER_GET_SIZE((duk_hbuffer *) DUK_HCOMPILEDFUNCTION_GET_DATA((heap), h))))
#define DUK_HCOMPILEDFUNCTION_GET_CONSTS_SIZE(h) \
#define DUK_HCOMPILEDFUNCTION_GET_CONSTS_SIZE(heap,h) \
( \
(duk_size_t) \
( \
((const duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_CONSTS_END((h))) - \
((const duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE((h))) \
((const duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_CONSTS_END((heap), (h))) - \
((const duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE((heap), (h))) \
) \
)
#define DUK_HCOMPILEDFUNCTION_GET_FUNCS_SIZE(h) \
#define DUK_HCOMPILEDFUNCTION_GET_FUNCS_SIZE(heap,h) \
( \
(duk_size_t) \
( \
((const duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_FUNCS_END((h))) - \
((const duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE((h))) \
((const duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_FUNCS_END((heap), (h))) - \
((const duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE((heap), (h))) \
) \
)
#define DUK_HCOMPILEDFUNCTION_GET_CODE_SIZE(h) \
#define DUK_HCOMPILEDFUNCTION_GET_CODE_SIZE(heap,h) \
( \
(duk_size_t) \
( \
((const duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_CODE_END((h))) - \
((const duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_CODE_BASE((h))) \
((const duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_CODE_END((heap),(h))) - \
((const duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_CODE_BASE((heap),(h))) \
) \
)
#define DUK_HCOMPILEDFUNCTION_GET_CONSTS_COUNT(h) \
((duk_size_t) (DUK_HCOMPILEDFUNCTION_GET_CONSTS_SIZE((h)) / sizeof(duk_tval)))
#define DUK_HCOMPILEDFUNCTION_GET_CONSTS_COUNT(heap,h) \
((duk_size_t) (DUK_HCOMPILEDFUNCTION_GET_CONSTS_SIZE((heap), (h)) / sizeof(duk_tval)))
#define DUK_HCOMPILEDFUNCTION_GET_FUNCS_COUNT(h) \
((duk_size_t) (DUK_HCOMPILEDFUNCTION_GET_FUNCS_SIZE((h)) / sizeof(duk_hobject *)))
#define DUK_HCOMPILEDFUNCTION_GET_FUNCS_COUNT(heap,h) \
((duk_size_t) (DUK_HCOMPILEDFUNCTION_GET_FUNCS_SIZE((heap), (h)) / sizeof(duk_hobject *)))
#define DUK_HCOMPILEDFUNCTION_GET_CODE_COUNT(h) \
((duk_size_t) (DUK_HCOMPILEDFUNCTION_GET_CODE_SIZE((h)) / sizeof(duk_instr_t)))
#define DUK_HCOMPILEDFUNCTION_GET_CODE_COUNT(heap,h) \
((duk_size_t) (DUK_HCOMPILEDFUNCTION_GET_CODE_SIZE((heap), (h)) / sizeof(duk_instr_t)))
/*

4
src/duk_heap.h

@ -184,7 +184,7 @@
/* heap string indices are autogenerated in duk_strings.h */
#if defined(DUK_USE_HEAPPTR16)
#define DUK_HEAP_GET_STRING(heap,idx) \
((duk_hstring *) DUK_USE_HEAPPTR_DEC16((heap)->strs16[(idx)]))
((duk_hstring *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (heap)->strs16[(idx)]))
#else
#define DUK_HEAP_GET_STRING(heap,idx) \
((heap)->strs[(idx)])
@ -232,7 +232,7 @@
*/
/* callback for indirect reallocs, request for current pointer */
typedef void *(*duk_mem_getptr)(void *ud);
typedef void *(*duk_mem_getptr)(duk_heap *heap, void *ud);
#define DUK_ALLOC(heap,size) duk_heap_mem_alloc((heap), (size))
#define DUK_ALLOC_ZEROED(heap,size) duk_heap_mem_alloc_zeroed((heap), (size))

23
src/duk_heap_alloc.c

@ -25,7 +25,7 @@ DUK_INTERNAL void duk_free_hobject_inner(duk_heap *heap, duk_hobject *h) {
DUK_ASSERT(heap != NULL);
DUK_ASSERT(h != NULL);
DUK_FREE(heap, DUK_HOBJECT_GET_PROPS(h));
DUK_FREE(heap, DUK_HOBJECT_GET_PROPS(heap, h));
if (DUK_HOBJECT_IS_COMPILEDFUNCTION(h)) {
duk_hcompiledfunction *f = (duk_hcompiledfunction *) h;
@ -58,8 +58,8 @@ DUK_INTERNAL void duk_free_hbuffer_inner(duk_heap *heap, duk_hbuffer *h) {
if (DUK_HBUFFER_HAS_DYNAMIC(h)) {
duk_hbuffer_dynamic *g = (duk_hbuffer_dynamic *) h;
DUK_DDD(DUK_DDDPRINT("free dynamic buffer %p", (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(g)));
DUK_FREE(heap, DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(g));
DUK_DDD(DUK_DDDPRINT("free dynamic buffer %p", (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, g)));
DUK_FREE(heap, DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, g));
}
}
@ -74,7 +74,7 @@ DUK_INTERNAL void duk_free_hstring_inner(duk_heap *heap, duk_hstring *h) {
if (DUK_HSTRING_HAS_EXTDATA(h)) {
DUK_DDD(DUK_DDDPRINT("free extstr: hstring %!O, extdata: %p",
h, DUK_HSTRING_GET_EXTDATA((duk_hstring_external *) h)));
DUK_USE_EXTSTR_FREE((const void *) DUK_HSTRING_GET_EXTDATA((duk_hstring_external *) h));
DUK_USE_EXTSTR_FREE(heap->heap_udata, (const void *) DUK_HSTRING_GET_EXTDATA((duk_hstring_external *) h));
}
#endif
}
@ -127,7 +127,7 @@ DUK_LOCAL void duk__free_allocated(duk_heap *heap) {
DUK_DDD(DUK_DDDPRINT("FINALFREE (allocated): %!iO",
(duk_heaphdr *) curr));
next = DUK_HEAPHDR_GET_NEXT(curr);
next = DUK_HEAPHDR_GET_NEXT(heap, curr);
duk_heap_free_heaphdr_raw(heap, curr);
curr = next;
}
@ -142,7 +142,7 @@ DUK_LOCAL void duk__free_refzero_list(duk_heap *heap) {
while (curr) {
DUK_DDD(DUK_DDDPRINT("FINALFREE (refzero_list): %!iO",
(duk_heaphdr *) curr));
next = DUK_HEAPHDR_GET_NEXT(curr);
next = DUK_HEAPHDR_GET_NEXT(heap, curr);
duk_heap_free_heaphdr_raw(heap, curr);
curr = next;
}
@ -158,7 +158,7 @@ DUK_LOCAL void duk__free_markandsweep_finalize_list(duk_heap *heap) {
while (curr) {
DUK_DDD(DUK_DDDPRINT("FINALFREE (finalize_list): %!iO",
(duk_heaphdr *) curr));
next = DUK_HEAPHDR_GET_NEXT(curr);
next = DUK_HEAPHDR_GET_NEXT(heap, curr);
duk_heap_free_heaphdr_raw(heap, curr);
curr = next;
}
@ -209,7 +209,7 @@ DUK_LOCAL void duk__free_run_finalizers(duk_heap *heap) {
count_obj++;
#endif
}
curr = DUK_HEAPHDR_GET_NEXT(curr);
curr = DUK_HEAPHDR_GET_NEXT(heap, curr);
}
/* Note: count includes all objects, not only those with an actual finalizer. */
@ -353,7 +353,7 @@ DUK_LOCAL duk_bool_t duk__init_heap_strings(duk_heap *heap) {
DUK_HSTRING_INCREF(_never_referenced_, h);
#if defined(DUK_USE_HEAPPTR16)
heap->strs16[i] = DUK_USE_HEAPPTR_ENC16((void *) h);
heap->strs16[i] = DUK_USE_HEAPPTR_ENC16(heap->heap_udata, (void *) h);
#else
heap->strs[i] = h;
#endif
@ -699,8 +699,9 @@ duk_heap *duk_heap_alloc(duk_alloc_function alloc_func,
res->fatal_func = fatal_func;
#if defined(DUK_USE_HEAPPTR16)
res->heapptr_null16 = DUK_USE_HEAPPTR_ENC16((void *) NULL);
res->heapptr_deleted16 = DUK_USE_HEAPPTR_ENC16((void *) DUK_STRTAB_DELETED_MARKER(res));
/* XXX: zero assumption */
res->heapptr_null16 = DUK_USE_HEAPPTR_ENC16(res->heap_udata, (void *) NULL);
res->heapptr_deleted16 = DUK_USE_HEAPPTR_ENC16(res->heap_udata, (void *) DUK_STRTAB_DELETED_MARKER(res));
#endif
/* res->mark_and_sweep_trigger_counter == 0 -> now causes immediate GC; which is OK */

70
src/duk_heap_markandsweep.c

@ -48,26 +48,26 @@ DUK_LOCAL void duk__mark_hobject(duk_heap *heap, duk_hobject *h) {
/* XXX: use advancing pointers instead of index macros -> faster and smaller? */
for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(h); i++) {
duk_hstring *key = DUK_HOBJECT_E_GET_KEY(h, i);
duk_hstring *key = DUK_HOBJECT_E_GET_KEY(heap, h, i);
if (!key) {
continue;
}
duk__mark_heaphdr(heap, (duk_heaphdr *) key);
if (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(h, i)) {
duk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(h, i)->a.get);
duk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(h, i)->a.set);
if (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, h, i)) {
duk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.get);
duk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.set);
} else {
duk__mark_tval(heap, &DUK_HOBJECT_E_GET_VALUE_PTR(h, i)->v);
duk__mark_tval(heap, &DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->v);
}
}
for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(h); i++) {
duk__mark_tval(heap, DUK_HOBJECT_A_GET_VALUE_PTR(h, i));
duk__mark_tval(heap, DUK_HOBJECT_A_GET_VALUE_PTR(heap, h, i));
}
/* hash part is a 'weak reference' and does not contribute */
duk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HOBJECT_GET_PROTOTYPE(h));
duk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HOBJECT_GET_PROTOTYPE(heap, h));
if (DUK_HOBJECT_IS_COMPILEDFUNCTION(h)) {
duk_hcompiledfunction *f = (duk_hcompiledfunction *) h;
@ -78,17 +78,17 @@ DUK_LOCAL void duk__mark_hobject(duk_heap *heap, duk_hobject *h) {
* contains a reference.
*/
duk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HCOMPILEDFUNCTION_GET_DATA(f));
duk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HCOMPILEDFUNCTION_GET_DATA(heap, f));
tv = DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(f);
tv_end = DUK_HCOMPILEDFUNCTION_GET_CONSTS_END(f);
tv = DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(heap, f);
tv_end = DUK_HCOMPILEDFUNCTION_GET_CONSTS_END(heap, f);
while (tv < tv_end) {
duk__mark_tval(heap, tv);
tv++;
}
funcs = DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE(f);
funcs_end = DUK_HCOMPILEDFUNCTION_GET_FUNCS_END(f);
funcs = DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE(heap, f);
funcs_end = DUK_HCOMPILEDFUNCTION_GET_FUNCS_END(heap, f);
while (funcs < funcs_end) {
duk__mark_heaphdr(heap, (duk_heaphdr *) *funcs);
funcs++;
@ -227,7 +227,7 @@ DUK_LOCAL void duk__mark_refzero_list(duk_heap *heap) {
hdr = heap->refzero_list;
while (hdr) {
duk__mark_heaphdr(heap, hdr);
hdr = DUK_HEAPHDR_GET_NEXT(hdr);
hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);
}
}
#endif
@ -282,7 +282,7 @@ DUK_LOCAL void duk__mark_finalizable(duk_heap *heap) {
count_finalizable ++;
}
hdr = DUK_HEAPHDR_GET_NEXT(hdr);
hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);
}
if (count_finalizable == 0) {
@ -298,7 +298,7 @@ DUK_LOCAL void duk__mark_finalizable(duk_heap *heap) {
duk__mark_heaphdr(heap, hdr);
}
hdr = DUK_HEAPHDR_GET_NEXT(hdr);
hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);
}
/* Caller will finish the marking process if we hit a recursion limit. */
@ -320,7 +320,7 @@ DUK_LOCAL void duk__mark_finalize_list(duk_heap *heap) {
hdr = heap->finalize_list;
while (hdr) {
duk__mark_heaphdr(heap, hdr);
hdr = DUK_HEAPHDR_GET_NEXT(hdr);
hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);
#ifdef DUK_USE_DEBUG
count_finalize_list++;
#endif
@ -391,7 +391,7 @@ DUK_LOCAL void duk__mark_temproots_by_heap_scan(duk_heap *heap) {
#else
duk__handle_temproot(heap, hdr);
#endif
hdr = DUK_HEAPHDR_GET_NEXT(hdr);
hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);
}
/* must also check refzero_list */
@ -403,7 +403,7 @@ DUK_LOCAL void duk__mark_temproots_by_heap_scan(duk_heap *heap) {
#else
duk__handle_temproot(heap, hdr);
#endif
hdr = DUK_HEAPHDR_GET_NEXT(hdr);
hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);
}
#endif /* DUK_USE_REFERENCE_COUNTING */
@ -450,7 +450,7 @@ DUK_LOCAL void duk__finalize_refcounts(duk_heap *heap) {
duk_heap_refcount_finalize_heaphdr(thr, hdr);
}
hdr = DUK_HEAPHDR_GET_NEXT(hdr);
hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);
}
}
#endif /* DUK_USE_REFERENCE_COUNTING */
@ -471,7 +471,7 @@ DUK_LOCAL void duk__clear_refzero_list_flags(duk_heap *heap) {
DUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZABLE(hdr));
DUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(hdr));
DUK_ASSERT(!DUK_HEAPHDR_HAS_TEMPROOT(hdr));
hdr = DUK_HEAPHDR_GET_NEXT(hdr);
hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);
}
}
#endif /* DUK_USE_REFERENCE_COUNTING */
@ -498,7 +498,7 @@ DUK_LOCAL void duk__clear_finalize_list_flags(duk_heap *heap) {
DUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZABLE(hdr));
DUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(hdr));
DUK_ASSERT(!DUK_HEAPHDR_HAS_TEMPROOT(hdr));
hdr = DUK_HEAPHDR_GET_NEXT(hdr);
hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);
}
}
@ -519,7 +519,7 @@ DUK_LOCAL void duk__sweep_string_chain16(duk_heap *heap, duk_uint16_t *slot, duk
/* nop */
return;
}
h = (duk_hstring *) DUK_USE_HEAPPTR_DEC16(h16);
h = (duk_hstring *) DUK_USE_HEAPPTR_DEC16(heap->heap_udata, h16);
DUK_ASSERT(h != NULL);
if (DUK_HEAPHDR_HAS_REACHABLE((duk_heaphdr *) h)) {
@ -601,7 +601,7 @@ DUK_LOCAL void duk__sweep_stringtable_chain(duk_heap *heap, duk_size_t *out_coun
#endif
} else {
#if defined(DUK_USE_HEAPPTR16)
lst = (duk_uint16_t *) DUK_USE_HEAPPTR_DEC16(e->u.strlist16);
lst = (duk_uint16_t *) DUK_USE_HEAPPTR_DEC16(heap->heap_udata, e->u.strlist16);
#else
lst = e->u.strlist;
#endif
@ -716,7 +716,7 @@ DUK_LOCAL void duk__sweep_heap(duk_heap *heap, duk_int_t flags, duk_size_t *out_
/* strings are never placed on the heap allocated list */
DUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) != DUK_HTYPE_STRING);
next = DUK_HEAPHDR_GET_NEXT(curr);
next = DUK_HEAPHDR_GET_NEXT(heap, curr);
if (DUK_HEAPHDR_HAS_REACHABLE(curr)) {
/*
@ -739,11 +739,11 @@ DUK_LOCAL void duk__sweep_heap(duk_heap *heap, duk_int_t flags, duk_size_t *out_
#ifdef DUK_USE_DOUBLE_LINKED_HEAP
if (heap->finalize_list) {
DUK_HEAPHDR_SET_PREV(heap->finalize_list, curr);
DUK_HEAPHDR_SET_PREV(heap, heap->finalize_list, curr);
}
DUK_HEAPHDR_SET_PREV(curr, NULL);
DUK_HEAPHDR_SET_PREV(heap, curr, NULL);
#endif
DUK_HEAPHDR_SET_NEXT(curr, heap->finalize_list);
DUK_HEAPHDR_SET_NEXT(heap, curr, heap->finalize_list);
heap->finalize_list = curr;
#ifdef DUK_USE_DEBUG
count_finalize++;
@ -776,10 +776,10 @@ DUK_LOCAL void duk__sweep_heap(duk_heap *heap, duk_int_t flags, duk_size_t *out_
heap->heap_allocated = curr;
}
if (prev) {
DUK_HEAPHDR_SET_NEXT(prev, curr);
DUK_HEAPHDR_SET_NEXT(heap, prev, curr);
}
#ifdef DUK_USE_DOUBLE_LINKED_HEAP
DUK_HEAPHDR_SET_PREV(curr, prev);
DUK_HEAPHDR_SET_PREV(heap, curr, prev);
#endif
prev = curr;
}
@ -833,7 +833,7 @@ DUK_LOCAL void duk__sweep_heap(duk_heap *heap, duk_int_t flags, duk_size_t *out_
}
}
if (prev) {
DUK_HEAPHDR_SET_NEXT(prev, NULL);
DUK_HEAPHDR_SET_NEXT(heap, prev, NULL);
}
#ifdef DUK_USE_DEBUG
@ -879,7 +879,7 @@ DUK_LOCAL void duk__run_object_finalizers(duk_heap *heap) {
DUK_HEAPHDR_SET_FINALIZED(curr);
/* queue back to heap_allocated */
next = DUK_HEAPHDR_GET_NEXT(curr);
next = DUK_HEAPHDR_GET_NEXT(heap, curr);
DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, curr);
curr = next;
@ -956,7 +956,7 @@ DUK_LOCAL void duk__compact_object_list(duk_heap *heap, duk_hthread *thr, duk_he
#endif
next:
curr = DUK_HEAPHDR_GET_NEXT(curr);
curr = DUK_HEAPHDR_GET_NEXT(heap, curr);
#ifdef DUK_USE_DEBUG
(*p_count_check)++;
#endif
@ -1011,7 +1011,7 @@ DUK_LOCAL void duk__assert_heaphdr_flags(duk_heap *heap) {
DUK_ASSERT(!DUK_HEAPHDR_HAS_TEMPROOT(hdr));
DUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZABLE(hdr));
/* may have FINALIZED */
hdr = DUK_HEAPHDR_GET_NEXT(hdr);
hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);
}
#ifdef DUK_USE_REFERENCE_COUNTING
@ -1021,7 +1021,7 @@ DUK_LOCAL void duk__assert_heaphdr_flags(duk_heap *heap) {
DUK_ASSERT(!DUK_HEAPHDR_HAS_TEMPROOT(hdr));
DUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZABLE(hdr));
DUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(hdr));
hdr = DUK_HEAPHDR_GET_NEXT(hdr);
hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);
}
#endif /* DUK_USE_REFERENCE_COUNTING */
}
@ -1052,7 +1052,7 @@ DUK_LOCAL void duk__assert_valid_refcounts(duk_heap *heap) {
DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(hdr) > 0);
#endif
}
hdr = DUK_HEAPHDR_GET_NEXT(hdr);
hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);
}
}
#endif /* DUK_USE_REFERENCE_COUNTING */

10
src/duk_heap_memory.c

@ -272,7 +272,7 @@ DUK_INTERNAL void *duk_heap_mem_realloc_indirect(duk_heap *heap, duk_mem_getptr
goto skip_attempt;
}
#endif
res = heap->realloc_func(heap->heap_udata, cb(ud), newsize);
res = heap->realloc_func(heap->heap_udata, cb(heap, ud), newsize);
if (res || newsize == 0) {
/* for zero size allocations NULL is allowed */
return res;
@ -307,7 +307,7 @@ DUK_INTERNAL void *duk_heap_mem_realloc_indirect(duk_heap *heap, duk_mem_getptr
#endif
#ifdef DUK_USE_ASSERTIONS
ptr_pre = cb(ud);
ptr_pre = cb(heap, ud);
#endif
flags = 0;
if (i >= DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_EMERGENCY_LIMIT - 1) {
@ -317,7 +317,7 @@ DUK_INTERNAL void *duk_heap_mem_realloc_indirect(duk_heap *heap, duk_mem_getptr
rc = duk_heap_mark_and_sweep(heap, flags);
DUK_UNREF(rc);
#ifdef DUK_USE_ASSERTIONS
ptr_post = cb(ud);
ptr_post = cb(heap, ud);
if (ptr_pre != ptr_post) {
/* useful for debugging */
DUK_DD(DUK_DDPRINT("note: base pointer changed by mark-and-sweep: %p -> %p",
@ -329,7 +329,7 @@ DUK_INTERNAL void *duk_heap_mem_realloc_indirect(duk_heap *heap, duk_mem_getptr
* The pointer being reallocated may change after every mark-and-sweep.
*/
res = heap->realloc_func(heap->heap_udata, cb(ud), newsize);
res = heap->realloc_func(heap->heap_udata, cb(heap, ud), newsize);
if (res || newsize == 0) {
DUK_D(DUK_DPRINT("duk_heap_mem_realloc_indirect() succeeded after gc (pass %ld), alloc size %ld",
(long) (i + 1), (long) newsize));
@ -343,7 +343,7 @@ DUK_INTERNAL void *duk_heap_mem_realloc_indirect(duk_heap *heap, duk_mem_getptr
#else /* DUK_USE_MARK_AND_SWEEP */
/* saves a few instructions to have this wrapper (see comment on duk_heap_mem_alloc) */
DUK_INTERNAL void *duk_heap_mem_realloc_indirect(duk_heap *heap, duk_mem_getptr cb, void *ud, duk_size_t newsize) {
return heap->realloc_func(heap->heap_udata, cb(ud), newsize);
return heap->realloc_func(heap->heap_udata, cb(heap, ud), newsize);
}
#endif /* DUK_USE_MARK_AND_SWEEP */

18
src/duk_heap_misc.c

@ -11,13 +11,13 @@
DUK_INTERNAL void duk_heap_remove_any_from_heap_allocated(duk_heap *heap, duk_heaphdr *hdr) {
DUK_ASSERT(DUK_HEAPHDR_GET_TYPE(hdr) != DUK_HTYPE_STRING);
if (DUK_HEAPHDR_GET_PREV(hdr)) {
DUK_HEAPHDR_SET_NEXT(DUK_HEAPHDR_GET_PREV(hdr), DUK_HEAPHDR_GET_NEXT(hdr));
if (DUK_HEAPHDR_GET_PREV(heap, hdr)) {
DUK_HEAPHDR_SET_NEXT(heap, DUK_HEAPHDR_GET_PREV(heap, hdr), DUK_HEAPHDR_GET_NEXT(heap, hdr));
} else {
heap->heap_allocated = DUK_HEAPHDR_GET_NEXT(hdr);
heap->heap_allocated = DUK_HEAPHDR_GET_NEXT(heap, hdr);
}
if (DUK_HEAPHDR_GET_NEXT(hdr)) {
DUK_HEAPHDR_SET_PREV(DUK_HEAPHDR_GET_NEXT(hdr), DUK_HEAPHDR_GET_PREV(hdr));
if (DUK_HEAPHDR_GET_NEXT(heap, hdr)) {
DUK_HEAPHDR_SET_PREV(heap, DUK_HEAPHDR_GET_NEXT(heap, hdr), DUK_HEAPHDR_GET_PREV(heap, hdr));
} else {
;
}
@ -29,12 +29,12 @@ DUK_INTERNAL void duk_heap_insert_into_heap_allocated(duk_heap *heap, duk_heaphd
#ifdef DUK_USE_DOUBLE_LINKED_HEAP
if (heap->heap_allocated) {
DUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap->heap_allocated) == NULL);
DUK_HEAPHDR_SET_PREV(heap->heap_allocated, hdr);
DUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, heap->heap_allocated) == NULL);
DUK_HEAPHDR_SET_PREV(heap, heap->heap_allocated, hdr);
}
DUK_HEAPHDR_SET_PREV(hdr, NULL);
DUK_HEAPHDR_SET_PREV(heap, hdr, NULL);
#endif
DUK_HEAPHDR_SET_NEXT(hdr, heap->heap_allocated);
DUK_HEAPHDR_SET_NEXT(heap, hdr, heap->heap_allocated);
heap->heap_allocated = hdr;
}

48
src/duk_heap_refcount.c

@ -22,16 +22,16 @@ DUK_LOCAL void duk__queue_refzero(duk_heap *heap, duk_heaphdr *hdr) {
hdr_prev = heap->refzero_list_tail;
DUK_ASSERT(hdr_prev != NULL);
DUK_ASSERT(DUK_HEAPHDR_GET_NEXT(hdr_prev) == NULL);
DUK_ASSERT(DUK_HEAPHDR_GET_NEXT(heap, hdr_prev) == NULL);
DUK_HEAPHDR_SET_NEXT(hdr, NULL);
DUK_HEAPHDR_SET_PREV(hdr, hdr_prev);
DUK_HEAPHDR_SET_NEXT(hdr_prev, hdr);
DUK_HEAPHDR_SET_NEXT(heap, hdr, NULL);
DUK_HEAPHDR_SET_PREV(heap, hdr, hdr_prev);
DUK_HEAPHDR_SET_NEXT(heap, hdr_prev, hdr);
heap->refzero_list_tail = hdr;
} else {
DUK_ASSERT(heap->refzero_list_tail == NULL);
DUK_HEAPHDR_SET_NEXT(hdr, NULL);
DUK_HEAPHDR_SET_PREV(hdr, NULL);
DUK_HEAPHDR_SET_NEXT(heap, hdr, NULL);
DUK_HEAPHDR_SET_PREV(heap, hdr, NULL);
heap->refzero_list = hdr;
heap->refzero_list_tail = hdr;
}
@ -60,49 +60,49 @@ DUK_LOCAL void duk__refcount_finalize_hobject(duk_hthread *thr, duk_hobject *h)
/* XXX: better to get base and walk forwards? */
for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(h); i++) {
duk_hstring *key = DUK_HOBJECT_E_GET_KEY(h, i);
duk_hstring *key = DUK_HOBJECT_E_GET_KEY(thr->heap, h, i);
if (!key) {
continue;
}
duk_heap_heaphdr_decref(thr, (duk_heaphdr *) key);
if (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(h, i)) {
duk_heap_heaphdr_decref(thr, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_GETTER(h, i));
duk_heap_heaphdr_decref(thr, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_SETTER(h, i));
if (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, h, i)) {
duk_heap_heaphdr_decref(thr, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, h, i));
duk_heap_heaphdr_decref(thr, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, h, i));
} else {
duk_heap_tval_decref(thr, DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(h, i));
duk_heap_tval_decref(thr, DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, h, i));
}
}
for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(h); i++) {
duk_heap_tval_decref(thr, DUK_HOBJECT_A_GET_VALUE_PTR(h, i));
duk_heap_tval_decref(thr, DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, h, i));
}
/* hash part is a 'weak reference' and does not contribute */
duk_heap_heaphdr_decref(thr, (duk_heaphdr *) DUK_HOBJECT_GET_PROTOTYPE(h));
duk_heap_heaphdr_decref(thr, (duk_heaphdr *) DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h));
if (DUK_HOBJECT_IS_COMPILEDFUNCTION(h)) {
duk_hcompiledfunction *f = (duk_hcompiledfunction *) h;
duk_tval *tv, *tv_end;
duk_hobject **funcs, **funcs_end;
DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_DATA(f) != NULL); /* compiled functions must be created 'atomically' */
DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_DATA(thr->heap, f) != NULL); /* compiled functions must be created 'atomically' */
tv = DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(f);
tv_end = DUK_HCOMPILEDFUNCTION_GET_CONSTS_END(f);
tv = DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(thr->heap, f);
tv_end = DUK_HCOMPILEDFUNCTION_GET_CONSTS_END(thr->heap, f);
while (tv < tv_end) {
duk_heap_tval_decref(thr, tv);
tv++;
}
funcs = DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE(f);
funcs_end = DUK_HCOMPILEDFUNCTION_GET_FUNCS_END(f);
funcs = DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE(thr->heap, f);
funcs_end = DUK_HCOMPILEDFUNCTION_GET_FUNCS_END(thr->heap, f);
while (funcs < funcs_end) {
duk_heap_heaphdr_decref(thr, (duk_heaphdr *) *funcs);
funcs++;
}
duk_heap_heaphdr_decref(thr, (duk_heaphdr *) DUK_HCOMPILEDFUNCTION_GET_DATA(f));
duk_heap_heaphdr_decref(thr, (duk_heaphdr *) DUK_HCOMPILEDFUNCTION_GET_DATA(thr->heap, f));
} else if (DUK_HOBJECT_IS_NATIVEFUNCTION(h)) {
duk_hnativefunction *f = (duk_hnativefunction *) h;
DUK_UNREF(f);
@ -204,7 +204,7 @@ DUK_LOCAL void duk__refzero_free_pending(duk_hthread *thr) {
h1 = heap->refzero_list;
obj = (duk_hobject *) h1;
DUK_DD(DUK_DDPRINT("refzero processing %p: %!O", (void *) h1, (duk_heaphdr *) h1));
DUK_ASSERT(DUK_HEAPHDR_GET_PREV(h1) == NULL);
DUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, h1) == NULL);
DUK_ASSERT(DUK_HEAPHDR_GET_TYPE(h1) == DUK_HTYPE_OBJECT); /* currently, always the case */
/*
@ -258,9 +258,9 @@ DUK_LOCAL void duk__refzero_free_pending(duk_hthread *thr) {
* to traverse a complete refzero_list.
*/
h2 = DUK_HEAPHDR_GET_NEXT(h1);
h2 = DUK_HEAPHDR_GET_NEXT(heap, h1);
if (h2) {
DUK_HEAPHDR_SET_PREV(h2, NULL); /* not strictly necessary */
DUK_HEAPHDR_SET_PREV(heap, h2, NULL); /* not strictly necessary */
heap->refzero_list = h2;
} else {
heap->refzero_list = NULL;
@ -274,8 +274,8 @@ DUK_LOCAL void duk__refzero_free_pending(duk_hthread *thr) {
if (rescued) {
/* yes -> move back to heap allocated */
DUK_DD(DUK_DDPRINT("object rescued during refcount finalization: %p", (void *) h1));
DUK_HEAPHDR_SET_PREV(h1, NULL);
DUK_HEAPHDR_SET_NEXT(h1, heap->heap_allocated);
DUK_HEAPHDR_SET_PREV(heap, h1, NULL);
DUK_HEAPHDR_SET_NEXT(heap, h1, heap->heap_allocated);
heap->heap_allocated = h1;
} else {
/* no -> decref members, then free */

40
src/duk_heap_stringtable.c

@ -128,7 +128,7 @@ DUK_LOCAL duk_bool_t duk__insert_hstring_chain(duk_heap *heap, duk_hstring *h) {
duk_uint16_t *new_lst;
duk_size_t i, n;
duk_uint16_t null16 = heap->heapptr_null16;
duk_uint16_t h16 = DUK_USE_HEAPPTR_ENC16((void *) h);
duk_uint16_t h16 = DUK_USE_HEAPPTR_ENC16(heap->heap_udata, (void *) h);
DUK_ASSERT(heap != NULL);
DUK_ASSERT(h != NULL);
@ -148,12 +148,12 @@ DUK_LOCAL duk_bool_t duk__insert_hstring_chain(duk_heap *heap, duk_hstring *h) {
}
lst[0] = e->u.str16;
lst[1] = h16;
e->u.strlist16 = DUK_USE_HEAPPTR_ENC16((void *) lst);
e->u.strlist16 = DUK_USE_HEAPPTR_ENC16(heap->heap_udata, (void *) lst);
e->listlen = 2;
}
} else {
DUK_ASSERT(e->u.strlist16 != null16);
lst = (duk_uint16_t *) DUK_USE_HEAPPTR_DEC16(e->u.strlist16);
lst = (duk_uint16_t *) DUK_USE_HEAPPTR_DEC16(heap->heap_udata, e->u.strlist16);
DUK_ASSERT(lst != NULL);
for (i = 0, n = e->listlen; i < n; i++) {
if (lst[i] == null16) {
@ -172,7 +172,7 @@ DUK_LOCAL duk_bool_t duk__insert_hstring_chain(duk_heap *heap, duk_hstring *h) {
return 1; /* fail */
}
new_lst[e->listlen++] = h16;
e->u.strlist16 = DUK_USE_HEAPPTR_ENC16((void *) new_lst);
e->u.strlist16 = DUK_USE_HEAPPTR_ENC16(heap->heap_udata, (void *) new_lst);
}
return 0;
}
@ -247,7 +247,7 @@ DUK_LOCAL duk_hstring *duk__find_matching_string_chain(duk_heap *heap, const duk
e = heap->strtable + slotidx;
if (e->listlen == 0) {
if (e->u.str16 != null16) {
duk_hstring *h = (duk_hstring *) DUK_USE_HEAPPTR_DEC16(e->u.str16);
duk_hstring *h = (duk_hstring *) DUK_USE_HEAPPTR_DEC16(heap->heap_udata, e->u.str16);
DUK_ASSERT(h != NULL);
if (DUK_HSTRING_GET_BYTELEN(h) == blen &&
DUK_MEMCMP(str, DUK_HSTRING_GET_DATA(h), blen) == 0) {
@ -256,11 +256,11 @@ DUK_LOCAL duk_hstring *duk__find_matching_string_chain(duk_heap *heap, const duk
}
} else {
DUK_ASSERT(e->u.strlist16 != null16);
lst = (duk_uint16_t *) DUK_USE_HEAPPTR_DEC16(e->u.strlist16);
lst = (duk_uint16_t *) DUK_USE_HEAPPTR_DEC16(heap->heap_udata, e->u.strlist16);
DUK_ASSERT(lst != NULL);
for (i = 0, n = e->listlen; i < n; i++) {
if (lst[i] != null16) {
duk_hstring *h = (duk_hstring *) DUK_USE_HEAPPTR_DEC16(lst[i]);
duk_hstring *h = (duk_hstring *) DUK_USE_HEAPPTR_DEC16(heap->heap_udata, lst[i]);
DUK_ASSERT(h != NULL);
if (DUK_HSTRING_GET_BYTELEN(h) == blen &&
DUK_MEMCMP(str, DUK_HSTRING_GET_DATA(h), blen) == 0) {
@ -323,7 +323,7 @@ DUK_LOCAL void duk__remove_matching_hstring_chain(duk_heap *heap, duk_hstring *h
DUK_ASSERT(slotidx < DUK_STRTAB_CHAIN_SIZE);
DUK_ASSERT(h != NULL);
h16 = DUK_USE_HEAPPTR_ENC16((void *) h);
h16 = DUK_USE_HEAPPTR_ENC16(heap->heap_udata, (void *) h);
e = heap->strtable + slotidx;
if (e->listlen == 0) {
@ -333,7 +333,7 @@ DUK_LOCAL void duk__remove_matching_hstring_chain(duk_heap *heap, duk_hstring *h
}
} else {
DUK_ASSERT(e->u.strlist16 != null16);
lst = (duk_uint16_t *) DUK_USE_HEAPPTR_DEC16(e->u.strlist16);
lst = (duk_uint16_t *) DUK_USE_HEAPPTR_DEC16(heap->heap_udata, e->u.strlist16);
DUK_ASSERT(lst != NULL);
for (i = 0, n = e->listlen; i < n; i++) {
if (lst[i] == h16) {
@ -411,7 +411,7 @@ DUK_INTERNAL void duk_heap_dump_strtab(duk_heap *heap) {
} else {
used = 0;
#if defined(DUK_USE_HEAPPTR16)
lst = (duk_uint16_t *) DUK_USE_HEAPPTR_DEC16(e->u.strlist16);
lst = (duk_uint16_t *) DUK_USE_HEAPPTR_DEC16(heap->heap_udata, e->u.strlist16);
#else
lst = e->u.strlist;
#endif
@ -497,7 +497,7 @@ DUK_LOCAL void duk__insert_hstring_probe(duk_heap *heap, duk_hstring **entries,
#endif
DUK_DDD(DUK_DDDPRINT("insert hit (null): %ld", (long) i));
#if defined(DUK_USE_HEAPPTR16)
entries16[i] = DUK_USE_HEAPPTR_ENC16((void *) h);
entries16[i] = DUK_USE_HEAPPTR_ENC16(heap->heap_udata, (void *) h);
#else
entries[i] = h;
#endif
@ -511,7 +511,7 @@ DUK_LOCAL void duk__insert_hstring_probe(duk_heap *heap, duk_hstring **entries,
/* st_used remains the same, DELETED is counted as used */
DUK_DDD(DUK_DDDPRINT("insert hit (deleted): %ld", (long) i));
#if defined(DUK_USE_HEAPPTR16)
entries16[i] = DUK_USE_HEAPPTR_ENC16((void *) h);
entries16[i] = DUK_USE_HEAPPTR_ENC16(heap->heap_udata, (void *) h);
#else
entries[i] = h;
#endif
@ -540,7 +540,7 @@ DUK_LOCAL duk_hstring *duk__find_matching_string_probe(duk_heap *heap, duk_hstri
for (;;) {
duk_hstring *e;
#if defined(DUK_USE_HEAPPTR16)
e = (duk_hstring *) DUK_USE_HEAPPTR_DEC16(entries16[i]);
e = (duk_hstring *) DUK_USE_HEAPPTR_DEC16(heap->heap_udata, entries16[i]);
#else
e = entries[i];
#endif
@ -575,7 +575,7 @@ DUK_LOCAL void duk__remove_matching_hstring_probe(duk_heap *heap, duk_hstring **
duk_uint32_t hash;
#if defined(DUK_USE_HEAPPTR16)
duk_uint16_t null16 = heap->heapptr_null16;
duk_uint16_t h16 = DUK_USE_HEAPPTR_ENC16((void *) h);
duk_uint16_t h16 = DUK_USE_HEAPPTR_ENC16(heap->heap_udata, (void *) h);
#endif
DUK_ASSERT(size > 0);
@ -708,7 +708,7 @@ DUK_LOCAL duk_bool_t duk__resize_strtab_raw_probe(duk_heap *heap, duk_uint32_t n
duk_hstring *e;
#if defined(DUK_USE_HEAPPTR16)
e = (duk_hstring *) DUK_USE_HEAPPTR_DEC16(old_entries[i]);
e = (duk_hstring *) DUK_USE_HEAPPTR_DEC16(heap->heap_udata, old_entries[i]);
#else
e = old_entries[i];
#endif
@ -846,7 +846,7 @@ DUK_LOCAL duk_hstring *duk__do_intern(duk_heap *heap, const duk_uint8_t *str, du
#endif
#if defined(DUK_USE_HSTRING_EXTDATA) && defined(DUK_USE_EXTSTR_INTERN_CHECK)
extdata = (const duk_uint8_t *) DUK_USE_EXTSTR_INTERN_CHECK((void *) str, (duk_size_t) blen);
extdata = (const duk_uint8_t *) DUK_USE_EXTSTR_INTERN_CHECK(heap->heap_udata, (void *) str, (duk_size_t) blen);
#else
extdata = (const duk_uint8_t *) NULL;
#endif
@ -1027,7 +1027,7 @@ DUK_INTERNAL void duk_heap_free_strtab(duk_heap *heap) {
e = heap->strtable + i;
if (e->listlen > 0) {
#if defined(DUK_USE_HEAPPTR16)
lst = (duk_uint16_t *) DUK_USE_HEAPPTR_DEC16(e->u.strlist16);
lst = (duk_uint16_t *) DUK_USE_HEAPPTR_DEC16(heap->heap_udata, e->u.strlist16);
#else
lst = e->u.strlist;
#endif
@ -1035,7 +1035,7 @@ DUK_INTERNAL void duk_heap_free_strtab(duk_heap *heap) {
for (j = 0; j < e->listlen; j++) {
#if defined(DUK_USE_HEAPPTR16)
h = DUK_USE_HEAPPTR_DEC16(lst[j]);
h = DUK_USE_HEAPPTR_DEC16(heap->heap_udata, lst[j]);
lst[j] = null16;
#else
h = lst[j];
@ -1055,7 +1055,7 @@ DUK_INTERNAL void duk_heap_free_strtab(duk_heap *heap) {
DUK_FREE(heap, lst);
} else {
#if defined(DUK_USE_HEAPPTR16)
h = DUK_USE_HEAPPTR_DEC16(e->u.str16);
h = DUK_USE_HEAPPTR_DEC16(heap->heap_udata, e->u.str16);
e->u.str16 = null16;
#else
h = e->u.str;
@ -1083,7 +1083,7 @@ DUK_INTERNAL void duk_heap_free_strtab(duk_heap *heap) {
#endif
for (i = 0; i < (duk_uint_fast32_t) heap->st_size; i++) {
#if defined(DUK_USE_HEAPPTR16)
h = (duk_hstring *) DUK_USE_HEAPPTR_DEC16(heap->strtable16[i]);
h = (duk_hstring *) DUK_USE_HEAPPTR_DEC16(heap->heap_udata, heap->strtable16[i]);
#else
h = heap->strtable[i];
#endif

22
src/duk_heaphdr.h

@ -106,26 +106,28 @@ struct duk_heaphdr_string {
#define DUK_HTYPE_MAX 3
#if defined(DUK_USE_HEAPPTR16)
#define DUK_HEAPHDR_GET_NEXT(h) ((duk_heaphdr *) DUK_USE_HEAPPTR_DEC16((h)->h_next16))
#define DUK_HEAPHDR_SET_NEXT(h,val) do { \
(h)->h_next16 = DUK_USE_HEAPPTR_ENC16((void *) val); \
#define DUK_HEAPHDR_GET_NEXT(heap,h) \
((duk_heaphdr *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->h_next16))
#define DUK_HEAPHDR_SET_NEXT(heap,h,val) do { \
(h)->h_next16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) val); \
} while (0)
#else
#define DUK_HEAPHDR_GET_NEXT(h) ((h)->h_next)
#define DUK_HEAPHDR_SET_NEXT(h,val) do { \
#define DUK_HEAPHDR_GET_NEXT(heap,h) ((h)->h_next)
#define DUK_HEAPHDR_SET_NEXT(heap,h,val) do { \
(h)->h_next = (val); \
} while (0)
#endif
#if defined(DUK_USE_DOUBLE_LINKED_HEAP)
#if defined(DUK_USE_HEAPPTR16)
#define DUK_HEAPHDR_GET_PREV(h) ((duk_heaphdr *) DUK_USE_HEAPPTR_DEC16((h)->h_prev16))
#define DUK_HEAPHDR_SET_PREV(h,val) do { \
(h)->h_prev16 = DUK_USE_HEAPPTR_ENC16((void *) (val)); \
#define DUK_HEAPHDR_GET_PREV(heap,h) \
((duk_heaphdr *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->h_prev16))
#define DUK_HEAPHDR_SET_PREV(heap,h,val) do { \
(h)->h_prev16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (val)); \
} while (0)
#else
#define DUK_HEAPHDR_GET_PREV(h) ((h)->h_prev)
#define DUK_HEAPHDR_SET_PREV(h,val) do { \
#define DUK_HEAPHDR_GET_PREV(heap,h) ((h)->h_prev)
#define DUK_HEAPHDR_SET_PREV(heap,h,val) do { \
(h)->h_prev = (val); \
} while (0)
#endif

213
src/duk_hobject.h

@ -217,42 +217,42 @@
*/
#if defined(DUK_USE_HEAPPTR16)
#define DUK_HOBJECT_GET_PROPS(h) \
((duk_uint8_t *) DUK_USE_HEAPPTR_DEC16(((duk_heaphdr *) (h))->h_extra16))
#define DUK_HOBJECT_SET_PROPS(h,x) do { \
((duk_heaphdr *) (h))->h_extra16 = DUK_USE_HEAPPTR_ENC16((void *) (x)); \
#define DUK_HOBJECT_GET_PROPS(heap,h) \
((duk_uint8_t *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, ((duk_heaphdr *) (h))->h_extra16))
#define DUK_HOBJECT_SET_PROPS(heap,h,x) do { \
((duk_heaphdr *) (h))->h_extra16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (x)); \
} while (0)
#else
#define DUK_HOBJECT_GET_PROPS(h) \
#define DUK_HOBJECT_GET_PROPS(heap,h) \
((h)->props)
#define DUK_HOBJECT_SET_PROPS(h,x) do { \
#define DUK_HOBJECT_SET_PROPS(heap,h,x) do { \
(h)->props = (x); \
} while (0)
#endif
#if defined(DUK_USE_HOBJECT_LAYOUT_1)
/* LAYOUT 1 */
#define DUK_HOBJECT_E_GET_KEY_BASE(h) \
#define DUK_HOBJECT_E_GET_KEY_BASE(heap,h) \
((duk_hstring **) ( \
DUK_HOBJECT_GET_PROPS((h)) \
DUK_HOBJECT_GET_PROPS((heap), (h)) \
))
#define DUK_HOBJECT_E_GET_VALUE_BASE(h) \
#define DUK_HOBJECT_E_GET_VALUE_BASE(heap,h) \
((duk_propvalue *) ( \
DUK_HOBJECT_GET_PROPS((h)) + \
DUK_HOBJECT_GET_PROPS((heap), (h)) + \
DUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_hstring *) \
))
#define DUK_HOBJECT_E_GET_FLAGS_BASE(h) \
#define DUK_HOBJECT_E_GET_FLAGS_BASE(heap,h) \
((duk_uint8_t *) ( \
DUK_HOBJECT_GET_PROPS((h)) + DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue)) \
DUK_HOBJECT_GET_PROPS((heap), (h)) + DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue)) \
))
#define DUK_HOBJECT_A_GET_BASE(h) \
#define DUK_HOBJECT_A_GET_BASE(heap,h) \
((duk_tval *) ( \
DUK_HOBJECT_GET_PROPS((h)) + \
DUK_HOBJECT_GET_PROPS((heap), (h)) + \
DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) \
))
#define DUK_HOBJECT_H_GET_BASE(h) \
#define DUK_HOBJECT_H_GET_BASE(heap,h) \
((duk_uint32_t *) ( \
DUK_HOBJECT_GET_PROPS((h)) + \
DUK_HOBJECT_GET_PROPS((heap), (h)) + \
DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \
DUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \
))
@ -278,28 +278,28 @@
#else
#define DUK_HOBJECT_E_FLAG_PADDING(e_sz) 0
#endif
#define DUK_HOBJECT_E_GET_KEY_BASE(h) \
#define DUK_HOBJECT_E_GET_KEY_BASE(heap,h) \
((duk_hstring **) ( \
DUK_HOBJECT_GET_PROPS((h)) + \
DUK_HOBJECT_GET_PROPS((heap), (h)) + \
DUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_propvalue) \
))
#define DUK_HOBJECT_E_GET_VALUE_BASE(h) \
#define DUK_HOBJECT_E_GET_VALUE_BASE(heap,h) \
((duk_propvalue *) ( \
DUK_HOBJECT_GET_PROPS((h)) \
DUK_HOBJECT_GET_PROPS((heap), (h)) \
))
#define DUK_HOBJECT_E_GET_FLAGS_BASE(h) \
#define DUK_HOBJECT_E_GET_FLAGS_BASE(heap,h) \
((duk_uint8_t *) ( \
DUK_HOBJECT_GET_PROPS((h)) + DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue)) \
DUK_HOBJECT_GET_PROPS((heap), (h)) + DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue)) \
))
#define DUK_HOBJECT_A_GET_BASE(h) \
#define DUK_HOBJECT_A_GET_BASE(heap,h) \
((duk_tval *) ( \
DUK_HOBJECT_GET_PROPS((h)) + \
DUK_HOBJECT_GET_PROPS((heap), (h)) + \
DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \
DUK_HOBJECT_E_FLAG_PADDING(DUK_HOBJECT_GET_ESIZE((h))) \
))
#define DUK_HOBJECT_H_GET_BASE(h) \
#define DUK_HOBJECT_H_GET_BASE(heap,h) \
((duk_uint32_t *) ( \
DUK_HOBJECT_GET_PROPS((h)) + \
DUK_HOBJECT_GET_PROPS((heap), (h)) + \
DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \
DUK_HOBJECT_E_FLAG_PADDING(DUK_HOBJECT_GET_ESIZE((h))) + \
DUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \
@ -322,31 +322,31 @@
} while (0)
#elif defined(DUK_USE_HOBJECT_LAYOUT_3)
/* LAYOUT 3 */
#define DUK_HOBJECT_E_GET_KEY_BASE(h) \
#define DUK_HOBJECT_E_GET_KEY_BASE(heap,h) \
((duk_hstring **) ( \
DUK_HOBJECT_GET_PROPS((h)) + \
DUK_HOBJECT_GET_PROPS((heap), (h)) + \
DUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_propvalue) + \
DUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \
))
#define DUK_HOBJECT_E_GET_VALUE_BASE(h) \
#define DUK_HOBJECT_E_GET_VALUE_BASE(heap,h) \
((duk_propvalue *) ( \
DUK_HOBJECT_GET_PROPS((h)) \
DUK_HOBJECT_GET_PROPS((heap), (h)) \
))
#define DUK_HOBJECT_E_GET_FLAGS_BASE(h) \
#define DUK_HOBJECT_E_GET_FLAGS_BASE(heap,h) \
((duk_uint8_t *) ( \
DUK_HOBJECT_GET_PROPS((h)) + \
DUK_HOBJECT_GET_PROPS((heap), (h)) + \
DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_propvalue) + sizeof(duk_hstring *)) + \
DUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) + \
DUK_HOBJECT_GET_HSIZE((h)) * sizeof(duk_uint32_t) \
))
#define DUK_HOBJECT_A_GET_BASE(h) \
#define DUK_HOBJECT_A_GET_BASE(heap,h) \
((duk_tval *) ( \
DUK_HOBJECT_GET_PROPS((h)) + \
DUK_HOBJECT_GET_PROPS((heap), (h)) + \
DUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_propvalue) \
))
#define DUK_HOBJECT_H_GET_BASE(h) \
#define DUK_HOBJECT_H_GET_BASE(heap,h) \
((duk_uint32_t *) ( \
DUK_HOBJECT_GET_PROPS((h)) + \
DUK_HOBJECT_GET_PROPS((heap), (h)) + \
DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_propvalue) + sizeof(duk_hstring *)) + \
DUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \
))
@ -367,73 +367,75 @@
#error invalid hobject layout defines
#endif /* hobject property layout */
#define DUK_HOBJECT_E_ALLOC_SIZE(h) DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE((h)), DUK_HOBJECT_GET_ASIZE((h)), DUK_HOBJECT_GET_HSIZE((h)))
#define DUK_HOBJECT_E_GET_KEY(h,i) (DUK_HOBJECT_E_GET_KEY_BASE((h))[(i)])
#define DUK_HOBJECT_E_GET_KEY_PTR(h,i) (&DUK_HOBJECT_E_GET_KEY_BASE((h))[(i)])
#define DUK_HOBJECT_E_GET_VALUE(h,i) (DUK_HOBJECT_E_GET_VALUE_BASE((h))[(i)])
#define DUK_HOBJECT_E_GET_VALUE_PTR(h,i) (&DUK_HOBJECT_E_GET_VALUE_BASE((h))[(i)])
#define DUK_HOBJECT_E_GET_VALUE_TVAL(h,i) (DUK_HOBJECT_E_GET_VALUE((h),(i)).v)
#define DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(h,i) (&DUK_HOBJECT_E_GET_VALUE((h),(i)).v)
#define DUK_HOBJECT_E_GET_VALUE_GETTER(h,i) (DUK_HOBJECT_E_GET_VALUE((h),(i)).a.get)
#define DUK_HOBJECT_E_GET_VALUE_GETTER_PTR(h,i) (&DUK_HOBJECT_E_GET_VALUE((h),(i)).a.get)
#define DUK_HOBJECT_E_GET_VALUE_SETTER(h,i) (DUK_HOBJECT_E_GET_VALUE((h),(i)).a.set)
#define DUK_HOBJECT_E_GET_VALUE_SETTER_PTR(h,i) (&DUK_HOBJECT_E_GET_VALUE((h),(i)).a.set)
#define DUK_HOBJECT_E_GET_FLAGS(h,i) (DUK_HOBJECT_E_GET_FLAGS_BASE((h))[(i)])
#define DUK_HOBJECT_E_GET_FLAGS_PTR(h,i) (&DUK_HOBJECT_E_GET_FLAGS_BASE((h))[(i)])
#define DUK_HOBJECT_A_GET_VALUE(h,i) (DUK_HOBJECT_A_GET_BASE((h))[(i)])
#define DUK_HOBJECT_A_GET_VALUE_PTR(h,i) (&DUK_HOBJECT_A_GET_BASE((h))[(i)])
#define DUK_HOBJECT_H_GET_INDEX(h,i) (DUK_HOBJECT_H_GET_BASE((h))[(i)])
#define DUK_HOBJECT_H_GET_INDEX_PTR(h,i) (&DUK_HOBJECT_H_GET_BASE((h))[(i)])
#define DUK_HOBJECT_E_SET_KEY(h,i,k) do { \
DUK_HOBJECT_E_GET_KEY((h),(i)) = (k); \
#define DUK_HOBJECT_E_ALLOC_SIZE(h) \
DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE((h)), DUK_HOBJECT_GET_ASIZE((h)), DUK_HOBJECT_GET_HSIZE((h)))
#define DUK_HOBJECT_E_GET_KEY(heap,h,i) (DUK_HOBJECT_E_GET_KEY_BASE((heap), (h))[(i)])
#define DUK_HOBJECT_E_GET_KEY_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_KEY_BASE((heap), (h))[(i)])
#define DUK_HOBJECT_E_GET_VALUE(heap,h,i) (DUK_HOBJECT_E_GET_VALUE_BASE((heap), (h))[(i)])
#define DUK_HOBJECT_E_GET_VALUE_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_VALUE_BASE((heap), (h))[(i)])
#define DUK_HOBJECT_E_GET_VALUE_TVAL(heap,h,i) (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v)
#define DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v)
#define DUK_HOBJECT_E_GET_VALUE_GETTER(heap,h,i) (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get)
#define DUK_HOBJECT_E_GET_VALUE_GETTER_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get)
#define DUK_HOBJECT_E_GET_VALUE_SETTER(heap,h,i) (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set)
#define DUK_HOBJECT_E_GET_VALUE_SETTER_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set)
#define DUK_HOBJECT_E_GET_FLAGS(heap,h,i) (DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)])
#define DUK_HOBJECT_E_GET_FLAGS_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)])
#define DUK_HOBJECT_A_GET_VALUE(heap,h,i) (DUK_HOBJECT_A_GET_BASE((heap), (h))[(i)])
#define DUK_HOBJECT_A_GET_VALUE_PTR(heap,h,i) (&DUK_HOBJECT_A_GET_BASE((heap), (h))[(i)])
#define DUK_HOBJECT_H_GET_INDEX(heap,h,i) (DUK_HOBJECT_H_GET_BASE((heap), (h))[(i)])
#define DUK_HOBJECT_H_GET_INDEX_PTR(heap,h,i) (&DUK_HOBJECT_H_GET_BASE((heap), (h))[(i)])
#define DUK_HOBJECT_E_SET_KEY(heap,h,i,k) do { \
DUK_HOBJECT_E_GET_KEY((heap), (h), (i)) = (k); \
} while (0)
#define DUK_HOBJECT_E_SET_VALUE(h,i,v) do { \
DUK_HOBJECT_E_GET_VALUE((h),(i)) = (v); \
#define DUK_HOBJECT_E_SET_VALUE(heap,h,i,v) do { \
DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)) = (v); \
} while (0)
#define DUK_HOBJECT_E_SET_VALUE_TVAL(h,i,v) do { \
DUK_HOBJECT_E_GET_VALUE((h),(i)).v = (v); \
#define DUK_HOBJECT_E_SET_VALUE_TVAL(heap,h,i,v) do { \
DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v = (v); \
} while (0)
#define DUK_HOBJECT_E_SET_VALUE_GETTER(h,i,v) do { \
DUK_HOBJECT_E_GET_VALUE((h),(i)).a.get = (v); \
#define DUK_HOBJECT_E_SET_VALUE_GETTER(heap,h,i,v) do { \
DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get = (v); \
} while (0)
#define DUK_HOBJECT_E_SET_VALUE_SETTER(h,i,v) do { \
DUK_HOBJECT_E_GET_VALUE((h),(i)).a.set = (v); \
#define DUK_HOBJECT_E_SET_VALUE_SETTER(heap,h,i,v) do { \
DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set = (v); \
} while (0)
#define DUK_HOBJECT_E_SET_FLAGS(h,i,f) do { \
DUK_HOBJECT_E_GET_FLAGS((h),(i)) = (f); \
#define DUK_HOBJECT_E_SET_FLAGS(heap,h,i,f) do { \
DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) = (f); \
} while (0)
#define DUK_HOBJECT_A_SET_VALUE(h,i,v) do { \
DUK_HOBJECT_A_GET_VALUE((h),(i)) = (v); \
#define DUK_HOBJECT_A_SET_VALUE(heap,h,i,v) do { \
DUK_HOBJECT_A_GET_VALUE((heap), (h), (i)) = (v); \
} while (0)
#define DUK_HOBJECT_A_SET_VALUE_TVAL(h,i,v) DUK_HOBJECT_A_SET_VALUE((h),(i),(v)) /* alias for above */
#define DUK_HOBJECT_H_SET_INDEX(h,i,v) do { \
DUK_HOBJECT_H_GET_INDEX((h),(i)) = (v); \
#define DUK_HOBJECT_A_SET_VALUE_TVAL(heap,h,i,v) \
DUK_HOBJECT_A_SET_VALUE((heap), (h), (i), (v)) /* alias for above */
#define DUK_HOBJECT_H_SET_INDEX(heap,h,i,v) do { \
DUK_HOBJECT_H_GET_INDEX((heap), (h), (i)) = (v); \
} while (0)
#define DUK_HOBJECT_E_SET_FLAG_BITS(h,i,mask) do { \
DUK_HOBJECT_E_GET_FLAGS_BASE((h))[(i)] |= (mask); \
#define DUK_HOBJECT_E_SET_FLAG_BITS(heap,h,i,mask) do { \
DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)] |= (mask); \
} while (0)
#define DUK_HOBJECT_E_CLEAR_FLAG_BITS(h,i,mask) do { \
DUK_HOBJECT_E_GET_FLAGS_BASE((h))[(i)] &= ~(mask); \
#define DUK_HOBJECT_E_CLEAR_FLAG_BITS(heap,h,i,mask) do { \
DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)] &= ~(mask); \
} while (0)
#define DUK_HOBJECT_E_SLOT_IS_WRITABLE(h,i) ((DUK_HOBJECT_E_GET_FLAGS((h),(i)) & DUK_PROPDESC_FLAG_WRITABLE) != 0)
#define DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(h,i) ((DUK_HOBJECT_E_GET_FLAGS((h),(i)) & DUK_PROPDESC_FLAG_ENUMERABLE) != 0)
#define DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(h,i) ((DUK_HOBJECT_E_GET_FLAGS((h),(i)) & DUK_PROPDESC_FLAG_CONFIGURABLE) != 0)
#define DUK_HOBJECT_E_SLOT_IS_ACCESSOR(h,i) ((DUK_HOBJECT_E_GET_FLAGS((h),(i)) & DUK_PROPDESC_FLAG_ACCESSOR) != 0)
#define DUK_HOBJECT_E_SLOT_IS_WRITABLE(heap,h,i) ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_WRITABLE) != 0)
#define DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(heap,h,i) ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_ENUMERABLE) != 0)
#define DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(heap,h,i) ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_CONFIGURABLE) != 0)
#define DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap,h,i) ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_ACCESSOR) != 0)
#define DUK_HOBJECT_E_SLOT_SET_WRITABLE(h,i) DUK_HOBJECT_E_SET_FLAG_BITS((h),(i),DUK_PROPDESC_FLAG_WRITABLE)
#define DUK_HOBJECT_E_SLOT_SET_ENUMERABLE(h,i) DUK_HOBJECT_E_SET_FLAG_BITS((h),(i),DUK_PROPDESC_FLAG_ENUMERABLE)
#define DUK_HOBJECT_E_SLOT_SET_CONFIGURABLE(h,i) DUK_HOBJECT_E_SET_FLAG_BITS((h),(i),DUK_PROPDESC_FLAG_CONFIGURABLE)
#define DUK_HOBJECT_E_SLOT_SET_ACCESSOR(h,i) DUK_HOBJECT_E_SET_FLAG_BITS((h),(i),DUK_PROPDESC_FLAG_ACCESSOR)
#define DUK_HOBJECT_E_SLOT_SET_WRITABLE(heap,h,i) DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_WRITABLE)
#define DUK_HOBJECT_E_SLOT_SET_ENUMERABLE(heap,h,i) DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ENUMERABLE)
#define DUK_HOBJECT_E_SLOT_SET_CONFIGURABLE(heap,h,i) DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_CONFIGURABLE)
#define DUK_HOBJECT_E_SLOT_SET_ACCESSOR(heap,h,i) DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ACCESSOR)
#define DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(h,i) DUK_HOBJECT_E_CLEAR_FLAG_BITS((h),(i),DUK_PROPDESC_FLAG_WRITABLE)
#define DUK_HOBJECT_E_SLOT_CLEAR_ENUMERABLE(h,i) DUK_HOBJECT_E_CLEAR_FLAG_BITS((h),(i),DUK_PROPDESC_FLAG_ENUMERABLE)
#define DUK_HOBJECT_E_SLOT_CLEAR_CONFIGURABLE(h,i) DUK_HOBJECT_E_CLEAR_FLAG_BITS((h),(i),DUK_PROPDESC_FLAG_CONFIGURABLE)
#define DUK_HOBJECT_E_SLOT_CLEAR_ACCESSOR(h,i) DUK_HOBJECT_E_CLEAR_FLAG_BITS((h),(i),DUK_PROPDESC_FLAG_ACCESSOR)
#define DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(heap,h,i) DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_WRITABLE)
#define DUK_HOBJECT_E_SLOT_CLEAR_ENUMERABLE(heap,h,i) DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ENUMERABLE)
#define DUK_HOBJECT_E_SLOT_CLEAR_CONFIGURABLE(heap,h,i) DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_CONFIGURABLE)
#define DUK_HOBJECT_E_SLOT_CLEAR_ACCESSOR(heap,h,i) DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ACCESSOR)
#define DUK_PROPDESC_IS_WRITABLE(p) (((p)->flags & DUK_PROPDESC_FLAG_WRITABLE) != 0)
#define DUK_PROPDESC_IS_ENUMERABLE(p) (((p)->flags & DUK_PROPDESC_FLAG_ENUMERABLE) != 0)
@ -509,30 +511,21 @@
*/
#if defined(DUK_USE_HEAPPTR16)
#define DUK_HOBJECT_GET_PROTOTYPE(h) ((duk_hobject *) DUK_USE_HEAPPTR_DEC16((h)->prototype16))
#define DUK_HOBJECT_SET_PROTOTYPE(h,x) do { \
(h)->prototype16 = DUK_USE_HEAPPTR_ENC16((void *) (x)); \
#define DUK_HOBJECT_GET_PROTOTYPE(heap,h) \
((duk_hobject *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->prototype16))
#define DUK_HOBJECT_SET_PROTOTYPE(heap,h,x) do { \
(h)->prototype16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (x)); \
} while (0)
#else
#define DUK_HOBJECT_GET_PROTOTYPE(h) ((h)->prototype)
#define DUK_HOBJECT_SET_PROTOTYPE(h,x) do { \
#define DUK_HOBJECT_GET_PROTOTYPE(heap,h) \
((h)->prototype)
#define DUK_HOBJECT_SET_PROTOTYPE(heap,h,x) do { \
(h)->prototype = (x); \
} while (0)
#endif
/* note: this updates refcounts */
#define DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr,h,p) duk_hobject_set_prototype((thr),(h),(p))
/*
* Macros for Ecmascript built-in semantics
*/
#define DUK_HOBJECT_OBJECT_SEAL(thr,obj) duk_hobject_object_seal_freeze_helper((thr),(obj),0)
#define DUK_HOBJECT_OBJECT_FREEZE(htr,obj) duk_hobject_object_seal_freeze_helper((thr),(obj),1)
#define DUK_HOBJECT_OBJECT_IS_SEALED(obj) duk_hobject_object_is_sealed_frozen_helper((obj),0)
#define DUK_HOBJECT_OBJECT_IS_FROZEN(obj) duk_hobject_object_is_sealed_frozen_helper((obj),1)
#define DUK_HOBJECT_OBJECT_PREVENT_EXTENSIONS(vm,obj) DUK_HOBJECT_CLEAR_EXTENSIBLE((obj))
#define DUK_HOBJECT_OBJECT_IS_EXTENSIBLE(vm,obj) DUK_HOBJECT_HAS_EXTENSIBLE((obj))
#define DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr,h,p) duk_hobject_set_prototype((thr), (h), (p))
/*
* Resizing and hash behavior
@ -746,10 +739,10 @@ DUK_INTERNAL_DECL duk_hnativefunction *duk_hnativefunction_alloc(duk_heap *heap,
DUK_INTERNAL_DECL duk_hthread *duk_hthread_alloc(duk_heap *heap, duk_uint_t hobject_flags);
/* low-level property functions */
DUK_INTERNAL_DECL void duk_hobject_find_existing_entry(duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx);
DUK_INTERNAL_DECL duk_tval *duk_hobject_find_existing_entry_tval_ptr(duk_hobject *obj, duk_hstring *key);
DUK_INTERNAL_DECL duk_tval *duk_hobject_find_existing_entry_tval_ptr_and_attrs(duk_hobject *obj, duk_hstring *key, duk_int_t *out_attrs);
DUK_INTERNAL_DECL duk_tval *duk_hobject_find_existing_array_entry_tval_ptr(duk_hobject *obj, duk_uarridx_t i);
DUK_INTERNAL_DECL void duk_hobject_find_existing_entry(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx);
DUK_INTERNAL_DECL duk_tval *duk_hobject_find_existing_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_hstring *key);
DUK_INTERNAL_DECL duk_tval *duk_hobject_find_existing_entry_tval_ptr_and_attrs(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *out_attrs);
DUK_INTERNAL_DECL duk_tval *duk_hobject_find_existing_array_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_uarridx_t i);
/* core property functions */
DUK_INTERNAL_DECL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key);
@ -789,7 +782,7 @@ void duk_hobject_define_property_helper(duk_context *ctx,
/* Object built-in methods */
DUK_INTERNAL_DECL duk_ret_t duk_hobject_object_get_own_property_descriptor(duk_context *ctx);
DUK_INTERNAL_DECL void duk_hobject_object_seal_freeze_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_freeze);
DUK_INTERNAL_DECL duk_bool_t duk_hobject_object_is_sealed_frozen_helper(duk_hobject *obj, duk_bool_t is_frozen);
DUK_INTERNAL_DECL duk_bool_t duk_hobject_object_is_sealed_frozen_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_frozen);
DUK_INTERNAL_DECL duk_bool_t duk_hobject_object_ownprop_helper(duk_context *ctx, duk_small_uint_t required_desc_flags);
/* internal properties */

6
src/duk_hobject_alloc.c

@ -10,7 +10,7 @@
DUK_LOCAL void duk__init_object_parts(duk_heap *heap, duk_hobject *obj, duk_uint_t hobject_flags) {
#ifdef DUK_USE_EXPLICIT_NULL_INIT
DUK_HOBJECT_SET_PROPS(obj, NULL);
DUK_HOBJECT_SET_PROPS(heap, obj, NULL);
#endif
/* XXX: macro? sets both heaphdr and object flags */
@ -19,9 +19,9 @@ DUK_LOCAL void duk__init_object_parts(duk_heap *heap, duk_hobject *obj, duk_uint
#if defined(DUK_USE_HEAPPTR16)
/* Zero encoded pointer is required to match NULL */
DUK_HEAPHDR_SET_NEXT(&obj->hdr, NULL);
DUK_HEAPHDR_SET_NEXT(heap, &obj->hdr, NULL);
#if defined(DUK_USE_DOUBLE_LINKED_HEAP)
DUK_HEAPHDR_SET_PREV(&obj->hdr, NULL);
DUK_HEAPHDR_SET_PREV(heap, &obj->hdr, NULL);
#endif
#endif
DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, &obj->hdr);

37
src/duk_hobject_enum.c

@ -47,7 +47,7 @@
* (Compiles to about 160 bytes now as a stand-alone function.)
*/
DUK_LOCAL void duk__sort_array_indices(duk_hobject *h_obj) {
DUK_LOCAL void duk__sort_array_indices(duk_hthread *thr, duk_hobject *h_obj) {
duk_hstring **keys;
duk_hstring **p_curr, **p_insert, **p_end;
duk_hstring *h_curr;
@ -55,12 +55,13 @@ DUK_LOCAL void duk__sort_array_indices(duk_hobject *h_obj) {
DUK_ASSERT(h_obj != NULL);
DUK_ASSERT(DUK_HOBJECT_GET_ENEXT(h_obj) >= 2); /* control props */
DUK_UNREF(thr);
if (DUK_HOBJECT_GET_ENEXT(h_obj) <= 1 + DUK__ENUM_START_INDEX) {
return;
}
keys = DUK_HOBJECT_E_GET_KEY_BASE(h_obj);
keys = DUK_HOBJECT_E_GET_KEY_BASE(thr->heap, h_obj);
p_end = keys + DUK_HOBJECT_GET_ENEXT(h_obj);
keys += DUK__ENUM_START_INDEX;
@ -73,8 +74,8 @@ DUK_LOCAL void duk__sort_array_indices(duk_hobject *h_obj) {
for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(h_obj); i++) {
DUK_DDD(DUK_DDDPRINT("initial: %ld %p -> %!O",
(long) i,
(void *) DUK_HOBJECT_E_GET_KEY_PTR(h_obj, i),
(duk_heaphdr *) DUK_HOBJECT_E_GET_KEY(h_obj, i)));
(void *) DUK_HOBJECT_E_GET_KEY_PTR(thr->heap, h_obj, i),
(duk_heaphdr *) DUK_HOBJECT_E_GET_KEY(thr->heap, h_obj, i)));
}
}
#endif
@ -143,8 +144,8 @@ DUK_LOCAL void duk__sort_array_indices(duk_hobject *h_obj) {
for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(h_obj); i++) {
DUK_DDD(DUK_DDDPRINT("final: %ld %p -> %!O",
(long) i,
(void *) DUK_HOBJECT_E_GET_KEY_PTR(h_obj, i),
(duk_heaphdr *) DUK_HOBJECT_E_GET_KEY(h_obj, i)));
(void *) DUK_HOBJECT_E_GET_KEY_PTR(thr->heap, h_obj, i),
(duk_heaphdr *) DUK_HOBJECT_E_GET_KEY(thr->heap, h_obj, i)));
}
}
#endif
@ -347,7 +348,7 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_context *ctx, duk_small_uint
duk_hstring *k;
duk_tval *tv;
tv = DUK_HOBJECT_A_GET_VALUE_PTR(curr, i);
tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, curr, i);
if (DUK_TVAL_IS_UNDEFINED_UNUSED(tv)) {
continue;
}
@ -370,11 +371,11 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_context *ctx, duk_small_uint
for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(curr); i++) {
duk_hstring *k;
k = DUK_HOBJECT_E_GET_KEY(curr, i);
k = DUK_HOBJECT_E_GET_KEY(thr->heap, curr, i);
if (!k) {
continue;
}
if (!DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(curr, i) &&
if (!DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(thr->heap, curr, i) &&
!(enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE)) {
continue;
}
@ -387,8 +388,8 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_context *ctx, duk_small_uint
continue;
}
DUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(curr, i) ||
!DUK_TVAL_IS_UNDEFINED_UNUSED(&DUK_HOBJECT_E_GET_VALUE_PTR(curr, i)->v));
DUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, curr, i) ||
!DUK_TVAL_IS_UNDEFINED_UNUSED(&DUK_HOBJECT_E_GET_VALUE_PTR(thr->heap, curr, i)->v));
duk_push_hstring(ctx, k);
duk_push_true(ctx);
@ -403,7 +404,7 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_context *ctx, duk_small_uint
break;
}
curr = DUK_HOBJECT_GET_PROTOTYPE(curr);
curr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);
}
/* [enum_target res] */
@ -434,7 +435,7 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_context *ctx, duk_small_uint
/* XXX: may need a 'length' filter for forEach()
*/
DUK_DDD(DUK_DDDPRINT("sort array indices by caller request"));
duk__sort_array_indices(res);
duk__sort_array_indices(thr, res);
}
#if defined(DUK_USE_ES6_PROXY)
@ -502,10 +503,10 @@ DUK_INTERNAL duk_bool_t duk_hobject_enumerator_next(duk_context *ctx, duk_bool_t
}
/* we know these because enum objects are internally created */
k = DUK_HOBJECT_E_GET_KEY(e, idx);
k = DUK_HOBJECT_E_GET_KEY(thr->heap, e, idx);
DUK_ASSERT(k != NULL);
DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(e, idx));
DUK_ASSERT(!DUK_TVAL_IS_UNDEFINED_UNUSED(&DUK_HOBJECT_E_GET_VALUE(e, idx).v));
DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, e, idx));
DUK_ASSERT(!DUK_TVAL_IS_UNDEFINED_UNUSED(&DUK_HOBJECT_E_GET_VALUE(thr->heap, e, idx).v));
idx++;
@ -551,12 +552,14 @@ DUK_INTERNAL duk_bool_t duk_hobject_enumerator_next(duk_context *ctx, duk_bool_t
*/
DUK_INTERNAL duk_ret_t duk_hobject_get_enumerated_keys(duk_context *ctx, duk_small_uint_t enum_flags) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_hobject *e;
duk_uint_fast32_t i;
duk_uint_fast32_t idx;
DUK_ASSERT(ctx != NULL);
DUK_ASSERT(duk_get_hobject(ctx, -1) != NULL);
DUK_UNREF(thr);
/* Create a temporary enumerator to get the (non-duplicated) key list;
* the enumerator state is initialized without being needed, but that
@ -575,7 +578,7 @@ DUK_INTERNAL duk_ret_t duk_hobject_get_enumerated_keys(duk_context *ctx, duk_sma
for (i = DUK__ENUM_START_INDEX; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(e); i++) {
duk_hstring *k;
k = DUK_HOBJECT_E_GET_KEY(e, i);
k = DUK_HOBJECT_E_GET_KEY(thr->heap, e, i);
DUK_ASSERT(k); /* enumerator must have no keys deleted */
/* [enum_target enum res] */

8
src/duk_hobject_misc.c

@ -24,7 +24,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_prototype_chain_contains(duk_hthread *thr, d
DUK_ERROR(thr, DUK_ERR_INTERNAL_ERROR, DUK_STR_PROTOTYPE_CHAIN_LIMIT);
}
}
h = DUK_HOBJECT_GET_PROTOTYPE(h);
h = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);
} while (h);
return 0;
@ -35,13 +35,13 @@ DUK_INTERNAL void duk_hobject_set_prototype(duk_hthread *thr, duk_hobject *h, du
duk_hobject *tmp;
DUK_ASSERT(h);
tmp = DUK_HOBJECT_GET_PROTOTYPE(h);
DUK_HOBJECT_SET_PROTOTYPE(h, p);
tmp = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);
DUK_HOBJECT_SET_PROTOTYPE(thr->heap, h, p);
DUK_HOBJECT_INCREF(thr, p); /* avoid problems if p == h->prototype */
DUK_HOBJECT_DECREF(thr, tmp);
#else
DUK_ASSERT(h);
DUK_UNREF(thr);
DUK_HOBJECT_SET_PROTOTYPE(h, p);
DUK_HOBJECT_SET_PROTOTYPE(thr->heap, h, p);
#endif
}

11
src/duk_hobject_pc2line.c

@ -39,7 +39,7 @@ DUK_INTERNAL void duk_hobject_pc2line_pack(duk_hthread *thr, duk_compiler_instr
DUK_ASSERT(h_buf != NULL);
DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(h_buf));
hdr = (duk_uint32_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(h_buf);
hdr = (duk_uint32_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h_buf);
DUK_ASSERT(hdr != NULL);
hdr[0] = (duk_uint32_t) length; /* valid pc range is [0, length[ */
@ -48,7 +48,7 @@ DUK_INTERNAL void duk_hobject_pc2line_pack(duk_hthread *thr, duk_compiler_instr
new_size = (duk_size_t) (curr_offset + DUK_PC2LINE_MAX_DIFF_LENGTH);
duk_hbuffer_resize(thr, h_buf, new_size, new_size);
hdr = (duk_uint32_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(h_buf);
hdr = (duk_uint32_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h_buf);
DUK_ASSERT(hdr != NULL);
DUK_ASSERT(curr_pc < length);
hdr_index = 1 + (curr_pc / DUK_PC2LINE_SKIP) * 2;
@ -126,7 +126,7 @@ DUK_INTERNAL void duk_hobject_pc2line_pack(duk_hthread *thr, duk_compiler_instr
* it will map to a large PC which is out of bounds and causes a zero to be
* returned.
*/
DUK_LOCAL duk_uint_fast32_t duk__hobject_pc2line_query_raw(duk_hbuffer_fixed *buf, duk_uint_fast32_t pc) {
DUK_LOCAL duk_uint_fast32_t duk__hobject_pc2line_query_raw(duk_hthread *thr, duk_hbuffer_fixed *buf, duk_uint_fast32_t pc) {
duk_bitdecoder_ctx bd_ctx_alloc;
duk_bitdecoder_ctx *bd_ctx = &bd_ctx_alloc;
duk_uint32_t *hdr;
@ -139,6 +139,7 @@ DUK_LOCAL duk_uint_fast32_t duk__hobject_pc2line_query_raw(duk_hbuffer_fixed *bu
DUK_ASSERT(buf != NULL);
DUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC((duk_hbuffer *) buf));
DUK_UNREF(thr);
hdr_index = pc / DUK_PC2LINE_SKIP;
pc_base = hdr_index * DUK_PC2LINE_SKIP;
@ -149,7 +150,7 @@ DUK_LOCAL duk_uint_fast32_t duk__hobject_pc2line_query_raw(duk_hbuffer_fixed *bu
goto error;
}
hdr = (duk_uint32_t *) DUK_HBUFFER_FIXED_GET_DATA_PTR(buf);
hdr = (duk_uint32_t *) DUK_HBUFFER_FIXED_GET_DATA_PTR(thr->heap, buf);
pc_limit = hdr[0];
if (pc >= pc_limit) {
/* Note: pc is unsigned and cannot be negative */
@ -223,7 +224,7 @@ DUK_INTERNAL duk_uint_fast32_t duk_hobject_pc2line_query(duk_context *ctx, duk_i
pc2line = (duk_hbuffer_fixed *) duk_get_hbuffer(ctx, -1);
if (pc2line != NULL) {
DUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC((duk_hbuffer *) pc2line));
line = duk__hobject_pc2line_query_raw(pc2line, (duk_uint_fast32_t) pc);
line = duk__hobject_pc2line_query_raw((duk_hthread *) ctx, pc2line, (duk_uint_fast32_t) pc);
} else {
line = 0;
}

317
src/duk_hobject_props.c

@ -187,14 +187,15 @@ DUK_LOCAL duk_uint32_t duk__get_min_grow_a(duk_uint32_t a_size) {
}
/* Count actually used entry part entries (non-NULL keys). */
DUK_LOCAL duk_uint32_t duk__count_used_e_keys(duk_hobject *obj) {
DUK_LOCAL duk_uint32_t duk__count_used_e_keys(duk_hthread *thr, duk_hobject *obj) {
duk_uint_fast32_t i;
duk_uint_fast32_t n = 0;
duk_hstring **e;
DUK_ASSERT(obj != NULL);
DUK_UNREF(thr);
e = DUK_HOBJECT_E_GET_KEY_BASE(obj);
e = DUK_HOBJECT_E_GET_KEY_BASE(thr->heap, obj);
for (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {
if (*e++) {
n++;
@ -208,7 +209,7 @@ DUK_LOCAL duk_uint32_t duk__count_used_e_keys(duk_hobject *obj) {
* end and breaking out early when finding first used entry, but this is
* not needed now.
*/
DUK_LOCAL void duk__compute_a_stats(duk_hobject *obj, duk_uint32_t *out_used, duk_uint32_t *out_min_size) {
DUK_LOCAL void duk__compute_a_stats(duk_hthread *thr, duk_hobject *obj, duk_uint32_t *out_used, duk_uint32_t *out_min_size) {
duk_uint_fast32_t i;
duk_uint_fast32_t used = 0;
duk_uint_fast32_t highest_idx = (duk_uint_fast32_t) -1; /* see below */
@ -217,8 +218,9 @@ DUK_LOCAL void duk__compute_a_stats(duk_hobject *obj, duk_uint32_t *out_used, du
DUK_ASSERT(obj != NULL);
DUK_ASSERT(out_used != NULL);
DUK_ASSERT(out_min_size != NULL);
DUK_UNREF(thr);
a = DUK_HOBJECT_A_GET_BASE(obj);
a = DUK_HOBJECT_A_GET_BASE(thr->heap, obj);
for (i = 0; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {
duk_tval *tv = a++;
if (!DUK_TVAL_IS_UNDEFINED_UNUSED(tv)) {
@ -306,7 +308,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_proxy_check(duk_hthread *thr, duk_hobject *o
return 0;
}
tv_handler = duk_hobject_find_existing_entry_tval_ptr(obj, DUK_HTHREAD_STRING_INT_HANDLER(thr));
tv_handler = duk_hobject_find_existing_entry_tval_ptr(thr->heap, obj, DUK_HTHREAD_STRING_INT_HANDLER(thr));
if (!tv_handler) {
DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, DUK_STR_PROXY_REVOKED);
return 0;
@ -317,7 +319,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_proxy_check(duk_hthread *thr, duk_hobject *o
*out_handler = h_handler;
tv_handler = NULL; /* avoid issues with relocation */
tv_target = duk_hobject_find_existing_entry_tval_ptr(obj, DUK_HTHREAD_STRING_INT_TARGET(thr));
tv_target = duk_hobject_find_existing_entry_tval_ptr(thr->heap, obj, DUK_HTHREAD_STRING_INT_TARGET(thr));
if (!tv_target) {
DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, DUK_STR_PROXY_REVOKED);
return 0;
@ -453,7 +455,7 @@ void duk__realloc_props(duk_hthread *thr,
DUK_ASSERT(ctx != NULL);
DUK_ASSERT(obj != NULL);
DUK_ASSERT(!abandon_array || new_a_size == 0); /* if abandon_array, new_a_size must be 0 */
DUK_ASSERT(DUK_HOBJECT_GET_PROPS(obj) != NULL || (DUK_HOBJECT_GET_ESIZE(obj) == 0 && DUK_HOBJECT_GET_ASIZE(obj) == 0));
DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL || (DUK_HOBJECT_GET_ESIZE(obj) == 0 && DUK_HOBJECT_GET_ASIZE(obj) == 0));
DUK_ASSERT(new_h_size == 0 || new_h_size >= new_e_size); /* required to guarantee success of rehashing,
* intentionally use unadjusted new_e_size
*/
@ -502,7 +504,7 @@ void duk__realloc_props(duk_hthread *thr,
DUK_HOBJECT_GET_ASIZE(obj),
DUK_HOBJECT_GET_HSIZE(obj)),
(long) DUK_HOBJECT_P_COMPUTE_SIZE(new_e_size_adjusted, new_a_size, new_h_size),
(void *) DUK_HOBJECT_GET_PROPS(obj),
(void *) DUK_HOBJECT_GET_PROPS(thr->heap, obj),
(long) DUK_HOBJECT_GET_ESIZE(obj),
(long) DUK_HOBJECT_GET_ENEXT(obj),
(long) DUK_HOBJECT_GET_ASIZE(obj),
@ -619,9 +621,9 @@ void duk__realloc_props(duk_hthread *thr,
duk_tval *tv2;
duk_hstring *key;
DUK_ASSERT(DUK_HOBJECT_GET_PROPS(obj) != NULL);
DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL);
tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(obj, i);
tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);
if (DUK_TVAL_IS_UNDEFINED_UNUSED(tv1)) {
continue;
}
@ -677,9 +679,9 @@ void duk__realloc_props(duk_hthread *thr,
for (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {
duk_hstring *key;
DUK_ASSERT(DUK_HOBJECT_GET_PROPS(obj) != NULL);
DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL);
key = DUK_HOBJECT_E_GET_KEY(obj, i);
key = DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i);
if (!key) {
continue;
}
@ -688,8 +690,8 @@ void duk__realloc_props(duk_hthread *thr,
new_e_pv != NULL && new_e_f != NULL);
new_e_k[new_e_next] = key;
new_e_pv[new_e_next] = DUK_HOBJECT_E_GET_VALUE(obj, i);
new_e_f[new_e_next] = DUK_HOBJECT_E_GET_FLAGS(obj, i);
new_e_pv[new_e_next] = DUK_HOBJECT_E_GET_VALUE(thr->heap, obj, i);
new_e_f[new_e_next] = DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, i);
new_e_next++;
}
/* the entries [new_e_next, new_e_size_adjusted[ are left uninitialized on purpose (ok, not gc reachable) */
@ -706,9 +708,9 @@ void duk__realloc_props(duk_hthread *thr,
* the 'new_a' pointer will be invalid which is not allowed even
* when copy size is zero.
*/
DUK_ASSERT(DUK_HOBJECT_GET_PROPS(obj) != NULL);
DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL);
DUK_ASSERT(DUK_HOBJECT_GET_ASIZE(obj) > 0);
DUK_MEMCPY((void *) new_a, (void *) DUK_HOBJECT_A_GET_BASE(obj), sizeof(duk_tval) * DUK_HOBJECT_GET_ASIZE(obj));
DUK_MEMCPY((void *) new_a, (void *) DUK_HOBJECT_A_GET_BASE(thr->heap, obj), sizeof(duk_tval) * DUK_HOBJECT_GET_ASIZE(obj));
}
/* fill new entries with -unused- (required, gc reachable) */
@ -722,7 +724,7 @@ void duk__realloc_props(duk_hthread *thr,
if (!abandon_array) {
for (i = new_a_size; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {
duk_tval *tv;
tv = DUK_HOBJECT_A_GET_VALUE_PTR(obj, i);
tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);
/* current assertion is quite strong: decref's and set to unused */
DUK_ASSERT(DUK_TVAL_IS_UNDEFINED_UNUSED(tv));
@ -734,9 +736,9 @@ void duk__realloc_props(duk_hthread *thr,
* the 'new_a' pointer will be invalid which is not allowed even
* when copy size is zero.
*/
DUK_ASSERT(DUK_HOBJECT_GET_PROPS(obj) != NULL);
DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL);
DUK_ASSERT(new_a_size > 0);
DUK_MEMCPY((void *) new_a, (void *) DUK_HOBJECT_A_GET_BASE(obj), sizeof(duk_tval) * new_a_size);
DUK_MEMCPY((void *) new_a, (void *) DUK_HOBJECT_A_GET_BASE(thr->heap, obj), sizeof(duk_tval) * new_a_size);
}
}
@ -753,7 +755,7 @@ void duk__realloc_props(duk_hthread *thr,
DUK_ASSERT(new_h != NULL);
/* fill new_h with u32 0xff = UNUSED */
DUK_ASSERT(DUK_HOBJECT_GET_PROPS(obj) != NULL);
DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL);
DUK_ASSERT(new_h_size > 0);
DUK_MEMSET(new_h, 0xff, sizeof(duk_uint32_t) * new_h_size);
@ -796,7 +798,7 @@ void duk__realloc_props(duk_hthread *thr,
DUK_HOBJECT_GET_ASIZE(obj),
DUK_HOBJECT_GET_HSIZE(obj)),
(long) new_alloc_size,
(void *) DUK_HOBJECT_GET_PROPS(obj),
(void *) DUK_HOBJECT_GET_PROPS(thr->heap, obj),
(long) DUK_HOBJECT_GET_ESIZE(obj),
(long) DUK_HOBJECT_GET_ENEXT(obj),
(long) DUK_HOBJECT_GET_ASIZE(obj),
@ -813,8 +815,8 @@ void duk__realloc_props(duk_hthread *thr,
* All done, switch properties ('p') allocation to new one.
*/
DUK_FREE(thr->heap, DUK_HOBJECT_GET_PROPS(obj)); /* NULL obj->p is OK */
DUK_HOBJECT_SET_PROPS(obj, new_p);
DUK_FREE(thr->heap, DUK_HOBJECT_GET_PROPS(thr->heap, obj)); /* NULL obj->p is OK */
DUK_HOBJECT_SET_PROPS(thr->heap, obj, new_p);
DUK_HOBJECT_SET_ESIZE(obj, new_e_size_adjusted);
DUK_HOBJECT_SET_ENEXT(obj, new_e_next);
DUK_HOBJECT_SET_ASIZE(obj, new_a_size);
@ -835,7 +837,7 @@ void duk__realloc_props(duk_hthread *thr,
buf = (duk_hbuffer_dynamic *) duk_require_hbuffer(ctx, -1);
DUK_ASSERT(buf != NULL);
DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(buf));
DUK_HBUFFER_DYNAMIC_SET_DATA_PTR_NULL(buf);
DUK_HBUFFER_DYNAMIC_SET_DATA_PTR_NULL(thr->heap, buf);
DUK_HBUFFER_DYNAMIC_SET_SIZE(buf, 0); /* these size resets are not strictly necessary, but nice for consistency */
DUK_HBUFFER_DYNAMIC_SET_ALLOC_SIZE(buf, 0);
duk_pop(ctx);
@ -907,7 +909,7 @@ DUK_LOCAL void duk__grow_props_for_new_entry_item(duk_hthread *thr, duk_hobject
* the keys explicitly to compute the new entry part size.
*/
old_e_used = duk__count_used_e_keys(obj);
old_e_used = duk__count_used_e_keys(thr, obj);
new_e_size = old_e_used + duk__get_min_grow_e(old_e_used);
#if defined(DUK_USE_HOBJECT_HASH_PART)
new_h_size = duk__get_default_h_size(new_e_size);
@ -956,8 +958,8 @@ DUK_LOCAL void duk__abandon_array_checked(duk_hthread *thr, duk_hobject *obj) {
DUK_ASSERT(thr != NULL);
DUK_ASSERT(obj != NULL);
e_used = duk__count_used_e_keys(obj);
duk__compute_a_stats(obj, &a_used, &a_size);
e_used = duk__count_used_e_keys(thr, obj);
duk__compute_a_stats(thr, obj, &a_used, &a_size);
/*
* Must guarantee all actually used array entries will fit into
@ -1005,8 +1007,8 @@ DUK_INTERNAL void duk_hobject_compact_props(duk_hthread *thr, duk_hobject *obj)
DUK_ASSERT(thr != NULL);
DUK_ASSERT(obj != NULL);
e_size = duk__count_used_e_keys(obj);
duk__compute_a_stats(obj, &a_used, &a_size);
e_size = duk__count_used_e_keys(thr, obj);
duk__compute_a_stats(thr, obj, &a_used, &a_size);
DUK_DD(DUK_DDPRINT("compacting hobject, used e keys %ld, used a keys %ld, min a size %ld, "
"resized array density would be: %ld/%ld = %lf",
@ -1051,11 +1053,12 @@ DUK_INTERNAL void duk_hobject_compact_props(duk_hthread *thr, duk_hobject *obj)
* but there is no hash part, h_idx is set to -1.
*/
DUK_INTERNAL void duk_hobject_find_existing_entry(duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx) {
DUK_INTERNAL void duk_hobject_find_existing_entry(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx) {
DUK_ASSERT(obj != NULL);
DUK_ASSERT(key != NULL);
DUK_ASSERT(e_idx != NULL);
DUK_ASSERT(h_idx != NULL);
DUK_UNREF(heap);
if (DUK_LIKELY(DUK_HOBJECT_GET_HSIZE(obj) == 0))
{
@ -1069,7 +1072,7 @@ DUK_INTERNAL void duk_hobject_find_existing_entry(duk_hobject *obj, duk_hstring
duk_hstring **h_keys_base;
DUK_DDD(DUK_DDDPRINT("duk_hobject_find_existing_entry() using linear scan for lookup"));
h_keys_base = DUK_HOBJECT_E_GET_KEY_BASE(obj);
h_keys_base = DUK_HOBJECT_E_GET_KEY_BASE(heap, obj);
n = DUK_HOBJECT_GET_ENEXT(obj);
for (i = 0; i < n; i++) {
if (h_keys_base[i] == key) {
@ -1089,7 +1092,7 @@ DUK_INTERNAL void duk_hobject_find_existing_entry(duk_hobject *obj, duk_hstring
DUK_DDD(DUK_DDDPRINT("duk_hobject_find_existing_entry() using hash part for lookup"));
h_base = DUK_HOBJECT_H_GET_BASE(obj);
h_base = DUK_HOBJECT_H_GET_BASE(heap, obj);
n = DUK_HOBJECT_GET_HSIZE(obj);
i = DUK__HASH_INITIAL(DUK_HSTRING_GET_HASH(key), n);
step = DUK__HASH_PROBE_STEP(DUK_HSTRING_GET_HASH(key));
@ -1110,7 +1113,7 @@ DUK_INTERNAL void duk_hobject_find_existing_entry(duk_hobject *obj, duk_hstring
(long) i, (long) t));
} else {
DUK_ASSERT(t < DUK_HOBJECT_GET_ESIZE(obj));
if (DUK_HOBJECT_E_GET_KEY(obj, t) == key) {
if (DUK_HOBJECT_E_GET_KEY(heap, obj, t) == key) {
DUK_DDD(DUK_DDDPRINT("lookup hit i=%ld, t=%ld -> key %p",
(long) i, (long) t, (void *) key));
*e_idx = t;
@ -1134,34 +1137,36 @@ DUK_INTERNAL void duk_hobject_find_existing_entry(duk_hobject *obj, duk_hstring
}
/* For internal use: get non-accessor entry value */
DUK_INTERNAL duk_tval *duk_hobject_find_existing_entry_tval_ptr(duk_hobject *obj, duk_hstring *key) {
DUK_INTERNAL duk_tval *duk_hobject_find_existing_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_hstring *key) {
duk_int_t e_idx;
duk_int_t h_idx;
DUK_ASSERT(obj != NULL);
DUK_ASSERT(key != NULL);
DUK_UNREF(heap);
duk_hobject_find_existing_entry(obj, key, &e_idx, &h_idx);
if (e_idx >= 0 && !DUK_HOBJECT_E_SLOT_IS_ACCESSOR(obj, e_idx)) {
return DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(obj, e_idx);
duk_hobject_find_existing_entry(heap, obj, key, &e_idx, &h_idx);
if (e_idx >= 0 && !DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx)) {
return DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx);
} else {
return NULL;
}
}
/* For internal use: get non-accessor entry value and attributes */
DUK_INTERNAL duk_tval *duk_hobject_find_existing_entry_tval_ptr_and_attrs(duk_hobject *obj, duk_hstring *key, duk_int_t *out_attrs) {
DUK_INTERNAL duk_tval *duk_hobject_find_existing_entry_tval_ptr_and_attrs(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *out_attrs) {
duk_int_t e_idx;
duk_int_t h_idx;
DUK_ASSERT(obj != NULL);
DUK_ASSERT(key != NULL);
DUK_ASSERT(out_attrs != NULL);
DUK_UNREF(heap);
duk_hobject_find_existing_entry(obj, key, &e_idx, &h_idx);
if (e_idx >= 0 && !DUK_HOBJECT_E_SLOT_IS_ACCESSOR(obj, e_idx)) {
*out_attrs = DUK_HOBJECT_E_GET_FLAGS(obj, e_idx);
return DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(obj, e_idx);
duk_hobject_find_existing_entry(heap, obj, key, &e_idx, &h_idx);
if (e_idx >= 0 && !DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx)) {
*out_attrs = DUK_HOBJECT_E_GET_FLAGS(heap, obj, e_idx);
return DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx);
} else {
*out_attrs = 0;
return NULL;
@ -1169,10 +1174,11 @@ DUK_INTERNAL duk_tval *duk_hobject_find_existing_entry_tval_ptr_and_attrs(duk_ho
}
/* For internal use: get array part value */
DUK_INTERNAL duk_tval *duk_hobject_find_existing_array_entry_tval_ptr(duk_hobject *obj, duk_uarridx_t i) {
DUK_INTERNAL duk_tval *duk_hobject_find_existing_array_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_uarridx_t i) {
duk_tval *tv;
DUK_ASSERT(obj != NULL);
DUK_UNREF(heap);
if (!DUK_HOBJECT_HAS_ARRAY_PART(obj)) {
return NULL;
@ -1180,7 +1186,7 @@ DUK_INTERNAL duk_tval *duk_hobject_find_existing_array_entry_tval_ptr(duk_hobjec
if (i >= DUK_HOBJECT_GET_ASIZE(obj)) {
return NULL;
}
tv = DUK_HOBJECT_A_GET_VALUE_PTR(obj, i);
tv = DUK_HOBJECT_A_GET_VALUE_PTR(heap, obj, i);
return tv;
}
@ -1206,7 +1212,7 @@ DUK_LOCAL duk_bool_t duk__alloc_entry_checked(duk_hthread *thr, duk_hobject *obj
{
duk_uint_fast32_t i;
for (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {
DUK_ASSERT(DUK_HOBJECT_E_GET_KEY(obj, i) != key);
DUK_ASSERT(DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i) != key);
}
}
#endif
@ -1220,14 +1226,14 @@ DUK_LOCAL duk_bool_t duk__alloc_entry_checked(duk_hthread *thr, duk_hobject *obj
idx = DUK_HOBJECT_POSTINC_ENEXT(obj);
/* previous value is assumed to be garbage, so don't touch it */
DUK_HOBJECT_E_SET_KEY(obj, idx, key);
DUK_HOBJECT_E_SET_KEY(thr->heap, obj, idx, key);
DUK_HSTRING_INCREF(thr, key);
#if defined(DUK_USE_HOBJECT_HASH_PART)
if (DUK_UNLIKELY(DUK_HOBJECT_GET_HSIZE(obj) > 0)) {
duk_uint32_t n;
duk_uint32_t i, step;
duk_uint32_t *h_base = DUK_HOBJECT_H_GET_BASE(obj);
duk_uint32_t *h_base = DUK_HOBJECT_H_GET_BASE(thr->heap, obj);
n = DUK_HOBJECT_GET_HSIZE(obj);
i = DUK__HASH_INITIAL(DUK_HSTRING_GET_HASH(key), n);
@ -1282,10 +1288,10 @@ DUK_INTERNAL duk_bool_t duk_hobject_get_internal_value(duk_heap *heap, duk_hobje
DUK_TVAL_SET_UNDEFINED_UNUSED(tv_out);
/* always in entry part, no need to look up parents etc */
duk_hobject_find_existing_entry(obj, DUK_HEAP_STRING_INT_VALUE(heap), &e_idx, &h_idx);
duk_hobject_find_existing_entry(heap, obj, DUK_HEAP_STRING_INT_VALUE(heap), &e_idx, &h_idx);
if (e_idx >= 0) {
DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(obj, e_idx));
DUK_TVAL_SET_TVAL(tv_out, DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(obj, e_idx));
DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx));
DUK_TVAL_SET_TVAL(tv_out, DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx));
return 1;
}
return 0;
@ -1572,7 +1578,7 @@ DUK_LOCAL duk_bool_t duk__get_own_property_desc_raw(duk_hthread *thr, duk_hobjec
if (DUK_HOBJECT_HAS_ARRAY_PART(obj) && arr_idx != DUK__NO_ARRAY_INDEX) {
if (arr_idx < DUK_HOBJECT_GET_ASIZE(obj)) {
tv = DUK_HOBJECT_A_GET_VALUE_PTR(obj, arr_idx);
tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);
if (!DUK_TVAL_IS_UNDEFINED_UNUSED(tv)) {
DUK_DDD(DUK_DDDPRINT("-> found in array part"));
if (flags & DUK__DESC_FLAG_PUSH_VALUE) {
@ -1598,14 +1604,14 @@ DUK_LOCAL duk_bool_t duk__get_own_property_desc_raw(duk_hthread *thr, duk_hobjec
* Entries part
*/
duk_hobject_find_existing_entry(obj, key, &out_desc->e_idx, &out_desc->h_idx);
duk_hobject_find_existing_entry(thr->heap, obj, key, &out_desc->e_idx, &out_desc->h_idx);
if (out_desc->e_idx >= 0) {
duk_int_t e_idx = out_desc->e_idx;
out_desc->flags = DUK_HOBJECT_E_GET_FLAGS(obj, e_idx);
out_desc->flags = DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, e_idx);
if (out_desc->flags & DUK_PROPDESC_FLAG_ACCESSOR) {
DUK_DDD(DUK_DDDPRINT("-> found accessor property in entry part"));
out_desc->get = DUK_HOBJECT_E_GET_VALUE_GETTER(obj, e_idx);
out_desc->set = DUK_HOBJECT_E_GET_VALUE_SETTER(obj, e_idx);
out_desc->get = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, e_idx);
out_desc->set = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, e_idx);
if (flags & DUK__DESC_FLAG_PUSH_VALUE) {
/* a dummy undefined value is pushed to make valstack
* behavior uniform for caller
@ -1614,7 +1620,7 @@ DUK_LOCAL duk_bool_t duk__get_own_property_desc_raw(duk_hthread *thr, duk_hobjec
}
} else {
DUK_DDD(DUK_DDDPRINT("-> found plain property in entry part"));
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(obj, e_idx);
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx);
if (flags & DUK__DESC_FLAG_PUSH_VALUE) {
duk_push_tval(ctx, tv);
}
@ -1689,7 +1695,7 @@ DUK_LOCAL duk_bool_t duk__get_own_property_desc_raw(duk_hthread *thr, duk_hobjec
if (arr_idx < DUK_HBUFFER_GET_SIZE(h_val)) {
DUK_DDD(DUK_DDDPRINT("-> found, array index inside buffer"));
if (flags & DUK__DESC_FLAG_PUSH_VALUE) {
duk_push_int(ctx, ((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(h_val))[arr_idx]);
duk_push_int(ctx, ((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_val))[arr_idx]);
}
out_desc->flags = DUK_PROPDESC_FLAG_WRITABLE |
DUK_PROPDESC_FLAG_ENUMERABLE |
@ -1865,7 +1871,7 @@ DUK_LOCAL duk_bool_t duk__get_property_desc(duk_hthread *thr, duk_hobject *obj,
DUK_ERROR(thr, DUK_ERR_INTERNAL_ERROR, DUK_STR_PROTOTYPE_CHAIN_LIMIT);
}
}
curr = DUK_HOBJECT_GET_PROTOTYPE(curr);
curr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);
} while (curr);
/* out_desc is left untouched (possibly garbage), caller must use return
@ -1934,9 +1940,11 @@ DUK_LOCAL duk_tval *duk__shallow_fast_path_array_check_u32(duk_hobject *obj, duk
}
#endif
DUK_LOCAL duk_tval *duk__shallow_fast_path_array_check_tval(duk_hobject *obj, duk_tval *key_tv) {
DUK_LOCAL duk_tval *duk__shallow_fast_path_array_check_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *key_tv) {
duk_tval *tv;
DUK_UNREF(thr);
if (DUK_TVAL_IS_NUMBER(key_tv) &&
(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj)) &&
(!DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(obj)) &&
@ -1960,7 +1968,7 @@ DUK_LOCAL duk_tval *duk__shallow_fast_path_array_check_tval(duk_hobject *obj, du
DUK_ASSERT(idx != 0xffffffffUL);
DUK_DDD(DUK_DDDPRINT("key is a valid array index and inside array part"));
tv = DUK_HOBJECT_A_GET_VALUE_PTR(obj, idx);
tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, idx);
if (!DUK_TVAL_IS_UNDEFINED_UNUSED(tv)) {
DUK_DDD(DUK_DDDPRINT("-> fast path successful"));
return tv;
@ -2156,7 +2164,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
}
#endif /* DUK_USE_ES6_PROXY */
tmp = duk__shallow_fast_path_array_check_tval(curr, tv_key);
tmp = duk__shallow_fast_path_array_check_tval(thr, curr, tv_key);
if (tmp) {
duk_push_tval(ctx, tmp);
@ -2215,7 +2223,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
if (arr_idx != DUK__NO_ARRAY_INDEX &&
arr_idx < DUK_HBUFFER_GET_SIZE(h)) {
duk_pop_n(ctx, pop_count);
duk_push_int(ctx, ((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(h))[arr_idx]);
duk_push_int(ctx, ((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h))[arr_idx]);
DUK_DDD(DUK_DDDPRINT("-> %!T (base is buffer, key is an index inside buffer length "
"after coercion -> return byte as number)",
@ -2346,7 +2354,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
if (sanity-- == 0) {
DUK_ERROR(thr, DUK_ERR_INTERNAL_ERROR, DUK_STR_PROTOTYPE_CHAIN_LIMIT);
}
curr = DUK_HOBJECT_GET_PROTOTYPE(curr);
curr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);
} while (curr);
/*
@ -2612,7 +2620,7 @@ DUK_LOCAL duk_uint32_t duk__get_old_array_length(duk_hthread *thr, duk_hobject *
DUK_ASSERT(rc != 0); /* arrays MUST have a 'length' property */
DUK_ASSERT(temp_desc->e_idx >= 0);
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(obj, temp_desc->e_idx);
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, temp_desc->e_idx);
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv)); /* array 'length' is always a number, as we coerce it */
DUK_ASSERT(DUK_TVAL_GET_NUMBER(tv) >= 0.0);
DUK_ASSERT(DUK_TVAL_GET_NUMBER(tv) <= (double) 0xffffffffUL);
@ -2704,7 +2712,7 @@ duk_bool_t duk__handle_put_array_length_smaller(duk_hthread *thr,
while (i > new_len) {
i--;
tv = DUK_HOBJECT_A_GET_VALUE_PTR(obj, i);
tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);
DUK_TVAL_SET_TVAL(&tv_tmp, tv);
DUK_TVAL_SET_UNDEFINED_UNUSED(tv);
DUK_TVAL_DECREF(thr, &tv_tmp);
@ -2732,7 +2740,7 @@ duk_bool_t duk__handle_put_array_length_smaller(duk_hthread *thr,
goto skip_stage1;
}
for (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {
key = DUK_HOBJECT_E_GET_KEY(obj, i);
key = DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i);
if (!key) {
DUK_DDD(DUK_DDDPRINT("skip entry index %ld: null key", (long) i));
continue;
@ -2752,7 +2760,7 @@ duk_bool_t duk__handle_put_array_length_smaller(duk_hthread *thr,
(long) i, (long) arr_idx));
continue;
}
if (DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(obj, i)) {
if (DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(thr->heap, obj, i)) {
DUK_DDD(DUK_DDDPRINT("skip entry index %ld: key is a relevant array index %ld, but configurable",
(long) i, (long) arr_idx));
continue;
@ -2778,7 +2786,7 @@ duk_bool_t duk__handle_put_array_length_smaller(duk_hthread *thr,
"entries >= target_len"));
for (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {
key = DUK_HOBJECT_E_GET_KEY(obj, i);
key = DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i);
if (!key) {
DUK_DDD(DUK_DDDPRINT("skip entry index %ld: null key", (long) i));
continue;
@ -2798,7 +2806,7 @@ duk_bool_t duk__handle_put_array_length_smaller(duk_hthread *thr,
(long) i, (long) arr_idx));
continue;
}
DUK_ASSERT(force_flag || DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(obj, i)); /* stage 1 guarantees */
DUK_ASSERT(force_flag || DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(thr->heap, obj, i)); /* stage 1 guarantees */
DUK_DDD(DUK_DDDPRINT("delete entry index %ld: key is array index %ld",
(long) i, (long) arr_idx));
@ -2881,8 +2889,8 @@ DUK_LOCAL duk_bool_t duk__handle_put_array_length(duk_hthread *thr, duk_hobject
DUK_DDD(DUK_DDDPRINT("new length is higher than old length, just update length, no deletions"));
DUK_ASSERT(desc.e_idx >= 0);
DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(obj, desc.e_idx));
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(obj, desc.e_idx);
DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, desc.e_idx));
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, desc.e_idx);
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
DUK_TVAL_SET_NUMBER(tv, (duk_double_t) new_len); /* no decref needed for a number */
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
@ -2903,8 +2911,8 @@ DUK_LOCAL duk_bool_t duk__handle_put_array_length(duk_hthread *thr, duk_hobject
DUK_ASSERT(result_len >= new_len && result_len <= old_len);
DUK_ASSERT(desc.e_idx >= 0);
DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(obj, desc.e_idx));
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(obj, desc.e_idx);
DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, desc.e_idx));
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, desc.e_idx);
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
DUK_TVAL_SET_NUMBER(tv, (duk_double_t) result_len); /* no decref needed for a number */
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
@ -3129,7 +3137,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
arr_idx < DUK_HBUFFER_GET_SIZE(h)) {
duk_uint8_t *data;
DUK_DDD(DUK_DDDPRINT("writing to buffer data at index %ld", (long) arr_idx));
data = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(h);
data = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h);
duk_push_tval(ctx, tv_val);
data[arr_idx] = (duk_uint8_t) duk_to_number(ctx, -1);
pop_count++;
@ -3224,7 +3232,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_DD(DUK_DDPRINT("put to an own or inherited accessor, calling setter"));
setter = DUK_HOBJECT_E_GET_VALUE_SETTER(curr, desc.e_idx);
setter = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, curr, desc.e_idx);
if (!setter) {
goto fail_no_setter;
}
@ -3289,7 +3297,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
arr_idx < DUK_HBUFFER_GET_SIZE(h)) {
duk_uint8_t *data;
DUK_DDD(DUK_DDDPRINT("writing to buffer data at index %ld", (long) arr_idx));
data = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(h);
data = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h);
duk_push_tval(ctx, tv_val);
data[arr_idx] = (duk_uint8_t) duk_to_number(ctx, -1);
duk_pop(ctx);
@ -3311,7 +3319,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
if (sanity-- == 0) {
DUK_ERROR(thr, DUK_ERR_INTERNAL_ERROR, DUK_STR_PROTOTYPE_CHAIN_LIMIT);
}
curr = DUK_HOBJECT_GET_PROTOTYPE(curr);
curr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);
} while (curr);
/*
@ -3385,7 +3393,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
if (desc.e_idx >= 0) {
duk_tval tv_tmp;
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(orig, desc.e_idx);
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, orig, desc.e_idx);
DUK_DDD(DUK_DDDPRINT("previous entry value: %!iT", (duk_tval *) tv));
DUK_TVAL_SET_TVAL(&tv_tmp, tv);
DUK_TVAL_SET_TVAL(tv, tv_val);
@ -3402,7 +3410,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
duk_tval tv_tmp;
DUK_ASSERT(desc.a_idx >= 0);
tv = DUK_HOBJECT_A_GET_VALUE_PTR(orig, desc.a_idx);
tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, orig, desc.a_idx);
DUK_DDD(DUK_DDDPRINT("previous array value: %!iT", (duk_tval *) tv));
DUK_TVAL_SET_TVAL(&tv_tmp, tv);
DUK_TVAL_SET_TVAL(tv, tv_val);
@ -3519,7 +3527,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_DDD(DUK_DDDPRINT("=> fast check is NOT OK, do slow check for array abandon"));
duk__compute_a_stats(orig, &old_used, &old_size);
duk__compute_a_stats(thr, orig, &old_used, &old_size);
DUK_DDD(DUK_DDDPRINT("abandon check, array stats: old_used=%ld, old_size=%ld, arr_idx=%ld",
(long) old_used, (long) old_size, (long) arr_idx));
@ -3562,7 +3570,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_ASSERT(DUK_HOBJECT_HAS_ARRAY_PART(orig));
DUK_ASSERT(arr_idx < DUK_HOBJECT_GET_ASIZE(orig));
tv = DUK_HOBJECT_A_GET_VALUE_PTR(orig, arr_idx);
tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, orig, arr_idx);
/* prev value must be unused, no decref */
DUK_ASSERT(DUK_TVAL_IS_UNDEFINED_UNUSED(tv));
DUK_TVAL_SET_TVAL(tv, tv_val);
@ -3590,11 +3598,11 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
e_idx = duk__alloc_entry_checked(thr, orig, key);
DUK_ASSERT(e_idx >= 0);
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(orig, e_idx);
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, orig, e_idx);
/* prev value can be garbage, no decref */
DUK_TVAL_SET_TVAL(tv, tv_val);
DUK_TVAL_INCREF(thr, tv);
DUK_HOBJECT_E_SET_FLAGS(orig, e_idx, DUK_PROPDESC_FLAGS_WEC);
DUK_HOBJECT_E_SET_FLAGS(thr->heap, orig, e_idx, DUK_PROPDESC_FLAGS_WEC);
goto entry_updated;
entry_updated:
@ -3621,7 +3629,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_ASSERT(rc != 0);
DUK_ASSERT(desc.e_idx >= 0);
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(orig, desc.e_idx);
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, orig, desc.e_idx);
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
DUK_TVAL_SET_NUMBER(tv, (duk_double_t) new_array_length); /* no need for decref/incref because value is a number */
}
@ -3780,7 +3788,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr, duk_hobject *o
if (desc.a_idx >= 0) {
DUK_ASSERT(desc.e_idx < 0);
tv = DUK_HOBJECT_A_GET_VALUE_PTR(obj, desc.a_idx);
tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, desc.a_idx);
DUK_TVAL_SET_TVAL(&tv_tmp, tv);
DUK_TVAL_SET_UNDEFINED_UNUSED(tv);
DUK_TVAL_DECREF(thr, &tv_tmp);
@ -3791,7 +3799,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr, duk_hobject *o
/* remove hash entry (no decref) */
#if defined(DUK_USE_HOBJECT_HASH_PART)
if (desc.h_idx >= 0) {
duk_uint32_t *h_base = DUK_HOBJECT_H_GET_BASE(obj);
duk_uint32_t *h_base = DUK_HOBJECT_H_GET_BASE(thr->heap, obj);
DUK_DDD(DUK_DDDPRINT("removing hash entry at h_idx %ld", (long) desc.h_idx));
DUK_ASSERT(DUK_HOBJECT_GET_HSIZE(obj) > 0);
@ -3806,36 +3814,36 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr, duk_hobject *o
/* remove value */
DUK_DDD(DUK_DDDPRINT("before removing value, e_idx %ld, key %p, key at slot %p",
(long) desc.e_idx, (void *) key, (void *) DUK_HOBJECT_E_GET_KEY(obj, desc.e_idx)));
(long) desc.e_idx, (void *) key, (void *) DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx)));
DUK_DDD(DUK_DDDPRINT("removing value at e_idx %ld", (long) desc.e_idx));
if (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(obj, desc.e_idx)) {
if (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, desc.e_idx)) {
duk_hobject *tmp;
tmp = DUK_HOBJECT_E_GET_VALUE_GETTER(obj, desc.e_idx);
DUK_HOBJECT_E_SET_VALUE_GETTER(obj, desc.e_idx, NULL);
tmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, desc.e_idx);
DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, desc.e_idx, NULL);
DUK_UNREF(tmp);
DUK_HOBJECT_DECREF(thr, tmp);
tmp = DUK_HOBJECT_E_GET_VALUE_SETTER(obj, desc.e_idx);
DUK_HOBJECT_E_SET_VALUE_SETTER(obj, desc.e_idx, NULL);
tmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, desc.e_idx);
DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, desc.e_idx, NULL);
DUK_UNREF(tmp);
DUK_HOBJECT_DECREF(thr, tmp);
} else {
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(obj, desc.e_idx);
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, desc.e_idx);
DUK_TVAL_SET_TVAL(&tv_tmp, tv);
DUK_TVAL_SET_UNDEFINED_UNUSED(tv);
DUK_TVAL_DECREF(thr, &tv_tmp);
}
/* this is not strictly necessary because if key == NULL, value MUST be ignored */
DUK_HOBJECT_E_SET_FLAGS(obj, desc.e_idx, 0);
DUK_TVAL_SET_UNDEFINED_UNUSED(DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(obj, desc.e_idx));
DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, desc.e_idx, 0);
DUK_TVAL_SET_UNDEFINED_UNUSED(DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, desc.e_idx));
/* remove key */
DUK_DDD(DUK_DDDPRINT("before removing key, e_idx %ld, key %p, key at slot %p",
(long) desc.e_idx, (void *) key, (void *) DUK_HOBJECT_E_GET_KEY(obj, desc.e_idx)));
(long) desc.e_idx, (void *) key, (void *) DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx)));
DUK_DDD(DUK_DDDPRINT("removing key at e_idx %ld", (long) desc.e_idx));
DUK_ASSERT(key == DUK_HOBJECT_E_GET_KEY(obj, desc.e_idx));
DUK_HOBJECT_E_SET_KEY(obj, desc.e_idx, NULL);
DUK_ASSERT(key == DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx));
DUK_HOBJECT_E_SET_KEY(thr->heap, obj, desc.e_idx, NULL);
DUK_HSTRING_DECREF(thr, key);
goto success;
}
@ -4121,13 +4129,13 @@ DUK_INTERNAL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hob
goto pop_exit;
}
DUK_DDD(DUK_DDDPRINT("property already exists in the entry part -> update value and attributes"));
if (DUK_UNLIKELY(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(obj, desc.e_idx))) {
if (DUK_UNLIKELY(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, desc.e_idx))) {
DUK_D(DUK_DPRINT("existing property is an accessor, not supported"));
goto error_internal;
}
DUK_HOBJECT_E_SET_FLAGS(obj, desc.e_idx, propflags);
tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(obj, desc.e_idx);
DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, desc.e_idx, propflags);
tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, desc.e_idx);
} else if (desc.a_idx >= 0) {
if (flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) {
DUK_DDD(DUK_DDDPRINT("property already exists in the array part -> skip as requested"));
@ -4140,7 +4148,7 @@ DUK_INTERNAL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hob
goto error_internal;
}
tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(obj, desc.a_idx);
tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, desc.a_idx);
} else {
if (flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) {
DUK_DDD(DUK_DDDPRINT("property already exists but is virtual -> skip as requested"));
@ -4164,7 +4172,7 @@ DUK_INTERNAL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hob
}
DUK_ASSERT(arr_idx < DUK_HOBJECT_GET_ASIZE(obj));
tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(obj, arr_idx);
tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);
goto write_value;
}
}
@ -4172,8 +4180,8 @@ DUK_INTERNAL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hob
DUK_DDD(DUK_DDDPRINT("property does not exist, object belongs in entry part -> allocate new entry and write value and attributes"));
e_idx = duk__alloc_entry_checked(thr, obj, key); /* increases key refcount */
DUK_ASSERT(e_idx >= 0);
DUK_HOBJECT_E_SET_FLAGS(obj, e_idx, propflags);
tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(obj, e_idx);
DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, propflags);
tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx);
/* new entry: previous value is garbage; set to undefined to share write_value */
DUK_TVAL_SET_UNDEFINED_ACTUAL(tv1);
goto write_value;
@ -4238,7 +4246,7 @@ DUK_INTERNAL void duk_hobject_define_property_internal_arridx(duk_hthread *thr,
}
DUK_ASSERT(arr_idx < DUK_HOBJECT_GET_ASIZE(obj));
tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(obj, arr_idx);
tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);
tv2 = duk_require_tval(ctx, -1);
DUK_TVAL_SET_TVAL(&tv_tmp, tv1);
@ -4293,15 +4301,15 @@ DUK_INTERNAL void duk_hobject_define_accessor_internal(duk_hthread *thr, duk_hob
/* force the property to 'undefined' to create a slot for it */
duk_push_undefined(ctx);
duk_hobject_define_property_internal(thr, obj, key, propflags);
duk_hobject_find_existing_entry(obj, key, &e_idx, &h_idx);
duk_hobject_find_existing_entry(thr->heap, obj, key, &e_idx, &h_idx);
DUK_DDD(DUK_DDDPRINT("accessor slot: e_idx=%ld, h_idx=%ld", (long) e_idx, (long) h_idx));
DUK_ASSERT(e_idx >= 0);
DUK_ASSERT((duk_uint32_t) e_idx < DUK_HOBJECT_GET_ENEXT(obj));
/* no need to decref, as previous value is 'undefined' */
DUK_HOBJECT_E_SLOT_SET_ACCESSOR(obj, e_idx);
DUK_HOBJECT_E_SET_VALUE_GETTER(obj, e_idx, getter);
DUK_HOBJECT_E_SET_VALUE_SETTER(obj, e_idx, setter);
DUK_HOBJECT_E_SLOT_SET_ACCESSOR(thr->heap, obj, e_idx);
DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, e_idx, getter);
DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, e_idx, setter);
DUK_HOBJECT_INCREF(thr, getter);
DUK_HOBJECT_INCREF(thr, setter);
}
@ -4794,12 +4802,12 @@ void duk_hobject_define_property_helper(duk_context *ctx,
e_idx = duk__alloc_entry_checked(thr, obj, key);
DUK_ASSERT(e_idx >= 0);
DUK_HOBJECT_E_SET_VALUE_GETTER(obj, e_idx, get);
DUK_HOBJECT_E_SET_VALUE_SETTER(obj, e_idx, set);
DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, e_idx, get);
DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, e_idx, set);
DUK_HOBJECT_INCREF(thr, get);
DUK_HOBJECT_INCREF(thr, set);
DUK_HOBJECT_E_SET_FLAGS(obj, e_idx, new_flags);
DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, new_flags);
goto success_exotics;
} else {
duk_int_t e_idx;
@ -4846,11 +4854,11 @@ void duk_hobject_define_property_helper(duk_context *ctx,
/* write to entry part */
e_idx = duk__alloc_entry_checked(thr, obj, key);
DUK_ASSERT(e_idx >= 0);
tv2 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(obj, e_idx);
tv2 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx);
DUK_TVAL_SET_TVAL(tv2, &tv);
DUK_TVAL_INCREF(thr, tv2);
DUK_HOBJECT_E_SET_FLAGS(obj, e_idx, new_flags);
DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, new_flags);
goto success_exotics;
}
DUK_UNREACHABLE();
@ -5013,20 +5021,20 @@ void duk_hobject_define_property_helper(duk_context *ctx,
DUK_ASSERT(curr.e_idx >= 0 && curr.a_idx < 0);
}
DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(obj, curr.e_idx));
DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));
tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(obj, curr.e_idx);
tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx);
DUK_TVAL_SET_TVAL(&tv_tmp, tv1);
DUK_TVAL_SET_UNDEFINED_UNUSED(tv1);
DUK_TVAL_DECREF(thr, &tv_tmp);
DUK_HOBJECT_E_SET_VALUE_GETTER(obj, curr.e_idx, NULL);
DUK_HOBJECT_E_SET_VALUE_SETTER(obj, curr.e_idx, NULL);
DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(obj, curr.e_idx);
DUK_HOBJECT_E_SLOT_SET_ACCESSOR(obj, curr.e_idx);
DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, NULL);
DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, NULL);
DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(thr->heap, obj, curr.e_idx);
DUK_HOBJECT_E_SLOT_SET_ACCESSOR(thr->heap, obj, curr.e_idx);
DUK_DDD(DUK_DDDPRINT("flags after data->accessor conversion: 0x%02lx",
(unsigned long) DUK_HOBJECT_E_GET_FLAGS(obj, curr.e_idx)));
(unsigned long) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, curr.e_idx)));
/* re-lookup to update curr.flags
* XXX: would be faster to update directly
@ -5055,22 +5063,22 @@ void duk_hobject_define_property_helper(duk_context *ctx,
DUK_DDD(DUK_DDDPRINT("convert property to data property"));
DUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(obj, curr.e_idx));
tmp = DUK_HOBJECT_E_GET_VALUE_GETTER(obj, curr.e_idx);
DUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));
tmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, curr.e_idx);
DUK_UNREF(tmp);
DUK_HOBJECT_E_SET_VALUE_GETTER(obj, curr.e_idx, NULL);
DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, NULL);
DUK_HOBJECT_DECREF(thr, tmp);
tmp = DUK_HOBJECT_E_GET_VALUE_SETTER(obj, curr.e_idx);
tmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, curr.e_idx);
DUK_UNREF(tmp);
DUK_HOBJECT_E_SET_VALUE_SETTER(obj, curr.e_idx, NULL);
DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, NULL);
DUK_HOBJECT_DECREF(thr, tmp);
DUK_TVAL_SET_UNDEFINED_ACTUAL(DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(obj, curr.e_idx));
DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(obj, curr.e_idx);
DUK_HOBJECT_E_SLOT_CLEAR_ACCESSOR(obj, curr.e_idx);
DUK_TVAL_SET_UNDEFINED_ACTUAL(DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx));
DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(thr->heap, obj, curr.e_idx);
DUK_HOBJECT_E_SLOT_CLEAR_ACCESSOR(thr->heap, obj, curr.e_idx);
DUK_DDD(DUK_DDDPRINT("flags after accessor->data conversion: 0x%02lx",
(unsigned long) DUK_HOBJECT_E_GET_FLAGS(obj, curr.e_idx)));
(unsigned long) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, curr.e_idx)));
/* re-lookup to update curr.flags
* XXX: would be faster to update directly
@ -5160,7 +5168,7 @@ void duk_hobject_define_property_helper(duk_context *ctx,
DUK_ASSERT(!has_get);
tv2 = duk_require_tval(ctx, idx_value);
tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(obj, curr.a_idx);
tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, curr.a_idx);
DUK_TVAL_SET_TVAL(&tv_tmp, tv1);
DUK_TVAL_SET_TVAL(tv1, tv2);
DUK_TVAL_INCREF(thr, tv1);
@ -5183,17 +5191,17 @@ void duk_hobject_define_property_helper(duk_context *ctx,
DUK_ASSERT(curr.e_idx >= 0 && curr.a_idx < 0);
DUK_DDD(DUK_DDDPRINT("update existing property attributes"));
DUK_HOBJECT_E_SET_FLAGS(obj, curr.e_idx, new_flags);
DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, curr.e_idx, new_flags);
if (has_set) {
duk_hobject *tmp;
DUK_DDD(DUK_DDDPRINT("update existing property setter"));
DUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(obj, curr.e_idx));
DUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));
tmp = DUK_HOBJECT_E_GET_VALUE_SETTER(obj, curr.e_idx);
tmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, curr.e_idx);
DUK_UNREF(tmp);
DUK_HOBJECT_E_SET_VALUE_SETTER(obj, curr.e_idx, set);
DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, set);
DUK_HOBJECT_INCREF(thr, set);
DUK_HOBJECT_DECREF(thr, tmp);
}
@ -5201,11 +5209,11 @@ void duk_hobject_define_property_helper(duk_context *ctx,
duk_hobject *tmp;
DUK_DDD(DUK_DDDPRINT("update existing property getter"));
DUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(obj, curr.e_idx));
DUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));
tmp = DUK_HOBJECT_E_GET_VALUE_GETTER(obj, curr.e_idx);
tmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, curr.e_idx);
DUK_UNREF(tmp);
DUK_HOBJECT_E_SET_VALUE_GETTER(obj, curr.e_idx, get);
DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, get);
DUK_HOBJECT_INCREF(thr, get);
DUK_HOBJECT_DECREF(thr, tmp);
}
@ -5214,10 +5222,10 @@ void duk_hobject_define_property_helper(duk_context *ctx,
duk_tval tv_tmp;
DUK_DDD(DUK_DDDPRINT("update existing property value"));
DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(obj, curr.e_idx));
DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));
tv2 = duk_require_tval(ctx, idx_value);
tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(obj, curr.e_idx);
tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx);
DUK_TVAL_SET_TVAL(&tv_tmp, tv1);
DUK_TVAL_SET_TVAL(tv1, tv2);
DUK_TVAL_INCREF(thr, tv1);
@ -5261,7 +5269,7 @@ void duk_hobject_define_property_helper(duk_context *ctx,
DUK_ASSERT(rc != 0);
DUK_ASSERT(curr.e_idx >= 0);
tmp = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(obj, curr.e_idx);
tmp = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx);
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tmp));
DUK_TVAL_SET_NUMBER(tmp, (duk_double_t) arridx_new_array_length); /* no need for decref/incref because value is a number */
}
@ -5291,15 +5299,15 @@ void duk_hobject_define_property_helper(duk_context *ctx,
DUK_ASSERT(result_len >= arrlen_new_len && result_len <= arrlen_old_len);
DUK_ASSERT(curr.e_idx >= 0);
DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(obj, curr.e_idx));
tmp = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(obj, curr.e_idx);
DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));
tmp = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx);
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tmp));
DUK_TVAL_SET_NUMBER(tmp, (duk_double_t) result_len); /* no decref needed for a number */
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tmp));
if (pending_write_protect) {
DUK_DDD(DUK_DDDPRINT("setting array length non-writable (pending writability update)"));
DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(obj, curr.e_idx);
DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(thr->heap, obj, curr.e_idx);
}
/*
@ -5455,10 +5463,10 @@ DUK_INTERNAL void duk_hobject_object_seal_freeze_helper(duk_hthread *thr, duk_ho
duk_uint8_t *fp;
/* since duk__abandon_array_checked() causes a resize, there should be no gaps in keys */
DUK_ASSERT(DUK_HOBJECT_E_GET_KEY(obj, i) != NULL);
DUK_ASSERT(DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i) != NULL);
/* avoid multiple computations of flags address; bypasses macros */
fp = DUK_HOBJECT_E_GET_FLAGS_PTR(obj, i);
fp = DUK_HOBJECT_E_GET_FLAGS_PTR(thr->heap, obj, i);
if (is_freeze && !((*fp) & DUK_PROPDESC_FLAG_ACCESSOR)) {
*fp &= ~(DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_CONFIGURABLE);
} else {
@ -5486,10 +5494,11 @@ DUK_INTERNAL void duk_hobject_object_seal_freeze_helper(duk_hthread *thr, duk_ho
* need to be considered here now.
*/
DUK_INTERNAL duk_bool_t duk_hobject_object_is_sealed_frozen_helper(duk_hobject *obj, duk_bool_t is_frozen) {
DUK_INTERNAL duk_bool_t duk_hobject_object_is_sealed_frozen_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_frozen) {
duk_uint_fast32_t i;
DUK_ASSERT(obj != NULL);
DUK_UNREF(thr);
/* Note: no allocation pressure, no need to check refcounts etc */
@ -5506,12 +5515,12 @@ DUK_INTERNAL duk_bool_t duk_hobject_object_is_sealed_frozen_helper(duk_hobject *
for (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {
duk_small_uint_t flags;
if (!DUK_HOBJECT_E_GET_KEY(obj, i)) {
if (!DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i)) {
continue;
}
/* avoid multiple computations of flags address; bypasses macros */
flags = (duk_small_uint_t) DUK_HOBJECT_E_GET_FLAGS(obj, i);
flags = (duk_small_uint_t) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, i);
if (flags & DUK_PROPDESC_FLAG_CONFIGURABLE) {
return 0;
@ -5527,7 +5536,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_object_is_sealed_frozen_helper(duk_hobject *
* be configurable and writable.
*/
for (i = 0; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {
duk_tval *tv = DUK_HOBJECT_A_GET_VALUE_PTR(obj, i);
duk_tval *tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);
if (!DUK_TVAL_IS_UNDEFINED_UNUSED(tv)) {
return 0;
}
@ -5539,10 +5548,8 @@ DUK_INTERNAL duk_bool_t duk_hobject_object_is_sealed_frozen_helper(duk_hobject *
/*
* Object.preventExtensions() and Object.isExtensible() (E5 Sections 15.2.3.10, 15.2.3.13)
*
* Implemented directly in macros:
*
* DUK_HOBJECT_OBJECT_PREVENT_EXTENSIONS()
* DUK_HOBJECT_OBJECT_IS_EXTENSIBLE()
* Not needed, implemented by macros DUK_HOBJECT_{HAS,CLEAR,SET}_EXTENSIBLE
* and the Object built-in bindings.
*/
/* Undefine local defines */

8
src/duk_hthread.h

@ -122,7 +122,7 @@
#if defined(DUK_USE_HEAPPTR16)
#define DUK_HTHREAD_GET_STRING(thr,idx) \
((duk_hstring *) DUK_USE_HEAPPTR_DEC16((thr)->strs16[(idx)]))
((duk_hstring *) DUK_USE_HEAPPTR_DEC16((thr)->heap->heap_udata, (thr)->strs16[(idx)]))
#else
#define DUK_HTHREAD_GET_STRING(thr,idx) \
((thr)->strs[(idx)])
@ -292,8 +292,8 @@ DUK_INTERNAL_DECL void duk_hthread_catchstack_shrink_check(duk_hthread *thr);
DUK_INTERNAL_DECL void duk_hthread_catchstack_unwind(duk_hthread *thr, duk_size_t new_top);
DUK_INTERNAL_DECL duk_activation *duk_hthread_get_current_activation(duk_hthread *thr);
DUK_INTERNAL_DECL void *duk_hthread_get_valstack_ptr(void *ud); /* indirect allocs */
DUK_INTERNAL_DECL void *duk_hthread_get_callstack_ptr(void *ud); /* indirect allocs */
DUK_INTERNAL_DECL void *duk_hthread_get_catchstack_ptr(void *ud); /* indirect allocs */
DUK_INTERNAL_DECL void *duk_hthread_get_valstack_ptr(duk_heap *heap, void *ud); /* indirect allocs */
DUK_INTERNAL_DECL void *duk_hthread_get_callstack_ptr(duk_heap *heap, void *ud); /* indirect allocs */
DUK_INTERNAL_DECL void *duk_hthread_get_catchstack_ptr(duk_heap *heap, void *ud); /* indirect allocs */
#endif /* DUK_HTHREAD_H_INCLUDED */

9
src/duk_hthread_alloc.c

@ -73,17 +73,20 @@ DUK_INTERNAL duk_bool_t duk_hthread_init_stacks(duk_heap *heap, duk_hthread *thr
/* For indirect allocs. */
DUK_INTERNAL void *duk_hthread_get_valstack_ptr(void *ud) {
DUK_INTERNAL void *duk_hthread_get_valstack_ptr(duk_heap *heap, void *ud) {
duk_hthread *thr = (duk_hthread *) ud;
DUK_UNREF(heap);
return (void *) thr->valstack;
}
DUK_INTERNAL void *duk_hthread_get_callstack_ptr(void *ud) {
DUK_INTERNAL void *duk_hthread_get_callstack_ptr(duk_heap *heap, void *ud) {
duk_hthread *thr = (duk_hthread *) ud;
DUK_UNREF(heap);
return (void *) thr->callstack;
}
DUK_INTERNAL void *duk_hthread_get_catchstack_ptr(void *ud) {
DUK_INTERNAL void *duk_hthread_get_catchstack_ptr(duk_heap *heap, void *ud) {
duk_hthread *thr = (duk_hthread *) ud;
DUK_UNREF(heap);
return (void *) thr->catchstack;
}

7
src/duk_hthread_builtins.c

@ -643,13 +643,6 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
}
#endif
#ifdef DUK_USE_DDDPRINT /*XXX:incorrect*/
for (i = 0; i < DUK_NUM_BUILTINS; i++) {
DUK_DDD(DUK_DDDPRINT("built-in object %ld after initialization and compacting", (long) i));
DUK_DEBUG_DUMP_HOBJECT(thr->builtins[i]);
}
#endif
/*
* Pop built-ins from stack: they are now INCREF'd and
* reachable from the builtins[] array.

20
src/duk_hthread_stacks.c

@ -152,7 +152,7 @@ DUK_INTERNAL void duk_hthread_callstack_unwind(duk_hthread *thr, duk_size_t new_
duk_tval tv_tmp;
duk_hobject *h_tmp;
tv_caller = duk_hobject_find_existing_entry_tval_ptr(func, DUK_HTHREAD_STRING_CALLER(thr));
tv_caller = duk_hobject_find_existing_entry_tval_ptr(thr->heap, func, DUK_HTHREAD_STRING_CALLER(thr));
/* The act->prev_caller should only be set if the entry for 'caller'
* exists (as it is only set in that case, and the property is not
@ -226,16 +226,16 @@ DUK_INTERNAL void duk_hthread_callstack_unwind(duk_hthread *thr, duk_size_t new_
#endif
DUK_ASSERT((act->lex_env == NULL) ||
((duk_hobject_find_existing_entry_tval_ptr(act->lex_env, DUK_HTHREAD_STRING_INT_CALLEE(thr)) == NULL) &&
(duk_hobject_find_existing_entry_tval_ptr(act->lex_env, DUK_HTHREAD_STRING_INT_VARMAP(thr)) == NULL) &&
(duk_hobject_find_existing_entry_tval_ptr(act->lex_env, DUK_HTHREAD_STRING_INT_THREAD(thr)) == NULL) &&
(duk_hobject_find_existing_entry_tval_ptr(act->lex_env, DUK_HTHREAD_STRING_INT_REGBASE(thr)) == NULL)));
((duk_hobject_find_existing_entry_tval_ptr(thr->heap, act->lex_env, DUK_HTHREAD_STRING_INT_CALLEE(thr)) == NULL) &&
(duk_hobject_find_existing_entry_tval_ptr(thr->heap, act->lex_env, DUK_HTHREAD_STRING_INT_VARMAP(thr)) == NULL) &&
(duk_hobject_find_existing_entry_tval_ptr(thr->heap, act->lex_env, DUK_HTHREAD_STRING_INT_THREAD(thr)) == NULL) &&
(duk_hobject_find_existing_entry_tval_ptr(thr->heap, act->lex_env, DUK_HTHREAD_STRING_INT_REGBASE(thr)) == NULL)));
DUK_ASSERT((act->var_env == NULL) ||
((duk_hobject_find_existing_entry_tval_ptr(act->var_env, DUK_HTHREAD_STRING_INT_CALLEE(thr)) == NULL) &&
(duk_hobject_find_existing_entry_tval_ptr(act->var_env, DUK_HTHREAD_STRING_INT_VARMAP(thr)) == NULL) &&
(duk_hobject_find_existing_entry_tval_ptr(act->var_env, DUK_HTHREAD_STRING_INT_THREAD(thr)) == NULL) &&
(duk_hobject_find_existing_entry_tval_ptr(act->var_env, DUK_HTHREAD_STRING_INT_REGBASE(thr)) == NULL)));
((duk_hobject_find_existing_entry_tval_ptr(thr->heap, act->var_env, DUK_HTHREAD_STRING_INT_CALLEE(thr)) == NULL) &&
(duk_hobject_find_existing_entry_tval_ptr(thr->heap, act->var_env, DUK_HTHREAD_STRING_INT_VARMAP(thr)) == NULL) &&
(duk_hobject_find_existing_entry_tval_ptr(thr->heap, act->var_env, DUK_HTHREAD_STRING_INT_THREAD(thr)) == NULL) &&
(duk_hobject_find_existing_entry_tval_ptr(thr->heap, act->var_env, DUK_HTHREAD_STRING_INT_REGBASE(thr)) == NULL)));
skip_env_close:
@ -441,7 +441,7 @@ DUK_INTERNAL void duk_hthread_catchstack_unwind(duk_hthread *thr, duk_size_t new
env = act->lex_env; /* current lex_env of the activation (created for catcher) */
DUK_ASSERT(env != NULL); /* must be, since env was created when catcher was created */
act->lex_env = DUK_HOBJECT_GET_PROTOTYPE(env); /* prototype is lex_env before catcher created */
act->lex_env = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, env); /* prototype is lex_env before catcher created */
DUK_HOBJECT_DECREF(thr, env);
/* There is no need to decref anything else than 'env': if 'env'

3
src/duk_js_bytecode.h

@ -171,8 +171,7 @@ typedef duk_uint32_t duk_instr_t;
/* DUK_OP_EXTRA for debugging */
#define DUK_EXTRAOP_DUMPREG 128
#define DUK_EXTRAOP_DUMPREGS 129
#define DUK_EXTRAOP_DUMPTHREAD 130
#define DUK_EXTRAOP_LOGMARK 131
#define DUK_EXTRAOP_LOGMARK 130
/* DUK_OP_CALL flags in A */
#define DUK_BC_CALL_FLAG_TAILCALL (1 << 0)

41
src/duk_js_call.c

@ -448,13 +448,13 @@ void duk__handle_oldenv_for_call(duk_hthread *thr,
DUK_ASSERT(!DUK_HOBJECT_HAS_NEWENV(func));
DUK_ASSERT(!DUK_HOBJECT_HAS_CREATEARGS(func));
tv = duk_hobject_find_existing_entry_tval_ptr(func, DUK_HTHREAD_STRING_INT_LEXENV(thr));
tv = duk_hobject_find_existing_entry_tval_ptr(thr->heap, func, DUK_HTHREAD_STRING_INT_LEXENV(thr));
if (tv) {
DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv));
DUK_ASSERT(DUK_HOBJECT_IS_ENV(DUK_TVAL_GET_OBJECT(tv)));
act->lex_env = DUK_TVAL_GET_OBJECT(tv);
tv = duk_hobject_find_existing_entry_tval_ptr(func, DUK_HTHREAD_STRING_INT_VARENV(thr));
tv = duk_hobject_find_existing_entry_tval_ptr(thr->heap, func, DUK_HTHREAD_STRING_INT_VARENV(thr));
if (tv) {
DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv));
DUK_ASSERT(DUK_HOBJECT_IS_ENV(DUK_TVAL_GET_OBJECT(tv)));
@ -496,7 +496,7 @@ DUK_LOCAL void duk__update_func_caller_prop(duk_hthread *thr, duk_hobject *func)
act_caller = (thr->callstack_top >= 2 ? act_callee - 1 : NULL);
/* Backup 'caller' property and update its value. */
tv_caller = duk_hobject_find_existing_entry_tval_ptr(func, DUK_HTHREAD_STRING_CALLER(thr));
tv_caller = duk_hobject_find_existing_entry_tval_ptr(thr->heap, func, DUK_HTHREAD_STRING_CALLER(thr));
if (tv_caller) {
/* If caller is global/eval code, 'caller' should be set to
* 'null'.
@ -818,11 +818,6 @@ duk_int_t duk_handle_call(duk_hthread *thr,
* pointer quickly as valstack + offset instead of calling duk_get_tval().
*/
#if 0
DUK_D(DUK_DPRINT("callstack before call setup:"));
DUK_DEBUG_DUMP_CALLSTACK(thr);
#endif
if (idx_func < 0 || idx_args < 0) {
/*
* Since stack indices are not reliable, we can't do anything useful
@ -1187,11 +1182,6 @@ duk_int_t duk_handle_call(duk_hthread *thr,
/* [... func this arg1 ... argN] */
#if 0
DUK_D(DUK_DPRINT("pushed new activation:"));
DUK_DEBUG_DUMP_ACTIVATION(thr, thr->callstack + thr->callstack_top - 1);
#endif
/*
* Environment record creation and 'arguments' object creation.
* Named function expression name binding is handled by the
@ -1264,11 +1254,6 @@ duk_int_t duk_handle_call(duk_hthread *thr,
/* 'func' wants stack "as is" */
}
#if 0
DUK_D(DUK_DPRINT("callstack after call setup:"));
DUK_DEBUG_DUMP_CALLSTACK(thr);
#endif
/*
* Determine call type; then setup activation and call
*/
@ -1740,11 +1725,6 @@ duk_int_t duk_handle_safe_call(duk_hthread *thr,
/* [ ... | ] or [ ... | errobj (M * undefined)] where M = num_stack_rets - 1 */
#ifdef DUK_USE_DDDPRINT /*XXX:incorrect*/
DUK_DD(DUK_DDPRINT("protected safe_call error handling finished, thread dump:"));
DUK_DEBUG_DUMP_HTHREAD(thr);
#endif
retval = DUK_EXEC_ERROR;
goto shrink_and_finished;
@ -2000,11 +1980,6 @@ duk_bool_t duk_handle_ecma_call_setup(duk_hthread *thr,
(long) idx_args,
(long) entry_valstack_bottom_index));
#if 0
DUK_D(DUK_DPRINT("callstack before call setup:"));
DUK_DEBUG_DUMP_CALLSTACK(thr);
#endif
if (idx_func < 0 || idx_args < 0) {
/* XXX: assert? compiler is responsible for this never happening */
DUK_ERROR(thr, DUK_ERR_API_ERROR, DUK_STR_INVALID_CALL_ARGS);
@ -2288,11 +2263,6 @@ duk_bool_t duk_handle_ecma_call_setup(duk_hthread *thr,
* idx_args updated to match
*/
#if 0
DUK_D(DUK_DPRINT("pushed new activation:"));
DUK_DEBUG_DUMP_ACTIVATION(thr, thr->callstack + thr->callstack_top - 1);
#endif
/*
* Environment record creation and 'arguments' object creation.
* Named function expression name binding is handled by the
@ -2355,11 +2325,6 @@ duk_bool_t duk_handle_ecma_call_setup(duk_hthread *thr,
duk_set_top(ctx, idx_args + nargs); /* clamp anything above nargs */
duk_set_top(ctx, idx_args + nregs); /* extend with undefined */
#if 0
DUK_D(DUK_DPRINT("callstack after call setup:"));
DUK_DEBUG_DUMP_CALLSTACK(thr);
#endif
/*
* Shift to new valstack_bottom.
*/

40
src/duk_js_compiler.c

@ -581,12 +581,12 @@ DUK_LOCAL duk_int_t duk__cleanup_varmap(duk_compiler_ctx *comp_ctx) {
ret = 0;
e_next = DUK_HOBJECT_GET_ENEXT(h_varmap);
for (i = 0; i < e_next; i++) {
h_key = DUK_HOBJECT_E_GET_KEY(h_varmap, i);
h_key = DUK_HOBJECT_E_GET_KEY(thr->heap, h_varmap, i);
if (!h_key) {
continue;
}
DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(h_varmap, i));
DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, h_varmap, i));
/* The entries can either be register numbers or 'null' values.
* Thus, no need to DECREF them and get side effects. DECREF'ing
@ -595,11 +595,11 @@ DUK_LOCAL duk_int_t duk__cleanup_varmap(duk_compiler_ctx *comp_ctx) {
* rely on the object properties not changing from underneath us.
*/
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(h_varmap, i);
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, h_varmap, i);
if (!DUK_TVAL_IS_NUMBER(tv)) {
DUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv));
DUK_TVAL_SET_UNDEFINED_UNUSED(tv);
DUK_HOBJECT_E_SET_KEY(h_varmap, i, NULL);
DUK_HOBJECT_E_SET_KEY(thr->heap, h_varmap, i, NULL);
DUK_HSTRING_DECREF(thr, h_key);
} else {
ret++;
@ -723,13 +723,13 @@ DUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx, duk_boo
h_data = (duk_hbuffer_fixed *) duk_get_hbuffer(ctx, -1);
DUK_ASSERT(h_data != NULL);
DUK_HCOMPILEDFUNCTION_SET_DATA(h_res, (duk_hbuffer *) h_data);
DUK_HCOMPILEDFUNCTION_SET_DATA(thr->heap, h_res, (duk_hbuffer *) h_data);
DUK_HEAPHDR_INCREF(thr, h_data);
p_const = (duk_tval *) DUK_HBUFFER_FIXED_GET_DATA_PTR(h_data);
p_const = (duk_tval *) DUK_HBUFFER_FIXED_GET_DATA_PTR(thr->heap, h_data);
for (i = 0; i < consts_count; i++) {
DUK_ASSERT(i <= DUK_UARRIDX_MAX); /* const limits */
tv = duk_hobject_find_existing_array_entry_tval_ptr(func->h_consts, (duk_uarridx_t) i);
tv = duk_hobject_find_existing_array_entry_tval_ptr(thr->heap, func->h_consts, (duk_uarridx_t) i);
DUK_ASSERT(tv != NULL);
DUK_TVAL_SET_TVAL(p_const, tv);
p_const++;
@ -739,11 +739,11 @@ DUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx, duk_boo
}
p_func = (duk_hobject **) p_const;
DUK_HCOMPILEDFUNCTION_SET_FUNCS(h_res, p_func);
DUK_HCOMPILEDFUNCTION_SET_FUNCS(thr->heap, h_res, p_func);
for (i = 0; i < funcs_count; i++) {
duk_hobject *h;
DUK_ASSERT(i * 3 <= DUK_UARRIDX_MAX); /* func limits */
tv = duk_hobject_find_existing_array_entry_tval_ptr(func->h_funcs, (duk_uarridx_t) (i * 3));
tv = duk_hobject_find_existing_array_entry_tval_ptr(thr->heap, func->h_funcs, (duk_uarridx_t) (i * 3));
DUK_ASSERT(tv != NULL);
DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv));
h = DUK_TVAL_GET_OBJECT(tv);
@ -757,11 +757,11 @@ DUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx, duk_boo
}
p_instr = (duk_instr_t *) p_func;
DUK_HCOMPILEDFUNCTION_SET_BYTECODE(h_res, p_instr);
DUK_HCOMPILEDFUNCTION_SET_BYTECODE(thr->heap, h_res, p_instr);
/* copy bytecode instructions one at a time */
DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(func->h_code));
q_instr = (duk_compiler_instr *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(func->h_code);
q_instr = (duk_compiler_instr *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, func->h_code);
for (i = 0; i < code_count; i++) {
p_instr[i] = q_instr[i].ins;
}
@ -927,8 +927,8 @@ DUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx, duk_boo
duk_instr_t *p, *p_start, *p_end;
h = (duk_hcompiledfunction *) duk_get_hobject(ctx, -1);
p_start = (duk_instr_t *) DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(h);
p_end = (duk_instr_t *) DUK_HCOMPILEDFUNCTION_GET_CODE_END(h);
p_start = (duk_instr_t *) DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(thr->heap, h);
p_end = (duk_instr_t *) DUK_HCOMPILEDFUNCTION_GET_CODE_END(thr->heap, h);
p = p_start;
while (p < p_end) {
@ -1001,7 +1001,7 @@ DUK_LOCAL duk_compiler_instr *duk__get_instr_ptr(duk_compiler_ctx *comp_ctx, duk
duk_uint8_t *p;
duk_compiler_instr *code_begin, *code_end;
p = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(f->h_code);
p = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(comp_ctx->thr->heap, f->h_code);
code_begin = (duk_compiler_instr *) p;
code_end = (duk_compiler_instr *) (p + DUK_HBUFFER_GET_SIZE(f->h_code));
DUK_UNREF(code_end);
@ -1556,7 +1556,7 @@ DUK_LOCAL void duk__peephole_optimize_bytecode(duk_compiler_ctx *comp_ctx) {
DUK_ASSERT(h != NULL);
DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(h));
bc = (duk_compiler_instr *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(h);
bc = (duk_compiler_instr *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(comp_ctx->thr->heap, h);
#if defined(DUK_USE_BUFLEN16)
/* No need to assert, buffer size maximum is 0xffff. */
#else
@ -1722,7 +1722,7 @@ DUK_LOCAL duk_regconst_t duk__getconst(duk_compiler_ctx *comp_ctx) {
*/
n_check = (n > DUK__GETCONST_MAX_CONSTS_CHECK ? DUK__GETCONST_MAX_CONSTS_CHECK : n);
for (i = 0; i < n_check; i++) {
duk_tval *tv2 = DUK_HOBJECT_A_GET_VALUE_PTR(f->h_consts, i);
duk_tval *tv2 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, f->h_consts, i);
/* Strict equality is NOT enough, because we cannot use the same
* constant for e.g. +0 and -0.
@ -2305,7 +2305,7 @@ DUK_LOCAL void duk__add_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label,
* of the E5 specification, see Section 12.12.
*/
p = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(comp_ctx->curr_func.h_labelinfos);
p = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, comp_ctx->curr_func.h_labelinfos);
li_start = (duk_labelinfo *) p;
li = (duk_labelinfo *) (p + DUK_HBUFFER_GET_SIZE(comp_ctx->curr_func.h_labelinfos));
n = (duk_size_t) (li - li_start);
@ -2327,7 +2327,7 @@ DUK_LOCAL void duk__add_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label,
/* XXX: spare handling, slow now */
/* relookup after possible realloc */
p = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(comp_ctx->curr_func.h_labelinfos);
p = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, comp_ctx->curr_func.h_labelinfos);
li_start = (duk_labelinfo *) p;
DUK_UNREF(li_start); /* silence scan-build warning */
li = (duk_labelinfo *) (p + DUK_HBUFFER_GET_SIZE(comp_ctx->curr_func.h_labelinfos));
@ -2356,7 +2356,7 @@ DUK_LOCAL void duk__update_label_flags(duk_compiler_ctx *comp_ctx, duk_int_t lab
duk_uint8_t *p;
duk_labelinfo *li_start, *li;
p = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(comp_ctx->curr_func.h_labelinfos);
p = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(comp_ctx->thr->heap, comp_ctx->curr_func.h_labelinfos);
li_start = (duk_labelinfo *) p;
li = (duk_labelinfo *) (p + DUK_HBUFFER_GET_SIZE(comp_ctx->curr_func.h_labelinfos));
@ -2405,7 +2405,7 @@ DUK_LOCAL void duk__lookup_active_label(duk_compiler_ctx *comp_ctx, duk_hstring
DUK_UNREF(ctx);
p = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(comp_ctx->curr_func.h_labelinfos);
p = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, comp_ctx->curr_func.h_labelinfos);
li_start = (duk_labelinfo *) p;
li_end = (duk_labelinfo *) (p + DUK_HBUFFER_GET_SIZE(comp_ctx->curr_func.h_labelinfos));
li = li_end;

27
src/duk_js_executor.c

@ -1426,8 +1426,8 @@ DUK_LOCAL void duk__executor_interrupt(duk_hthread *thr) {
#define DUK__STRICT() (DUK_HOBJECT_HAS_STRICT(&(fun)->obj))
#define DUK__REG(x) (thr->valstack_bottom[(x)])
#define DUK__REGP(x) (&thr->valstack_bottom[(x)])
#define DUK__CONST(x) (DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(fun)[(x)])
#define DUK__CONSTP(x) (&DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(fun)[(x)])
#define DUK__CONST(x) (DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(thr->heap, fun)[(x)])
#define DUK__CONSTP(x) (&DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(thr->heap, fun)[(x)])
#define DUK__REGCONST(x) ((x) < DUK_BC_REGLIMIT ? DUK__REG((x)) : DUK__CONST((x) - DUK_BC_REGLIMIT))
#define DUK__REGCONSTP(x) ((x) < DUK_BC_REGLIMIT ? DUK__REGP((x)) : DUK__CONSTP((x) - DUK_BC_REGLIMIT))
@ -1609,7 +1609,7 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {
/* assume that thr->valstack_bottom has been set-up before getting here */
act = thr->callstack + thr->callstack_top - 1;
fun = (duk_hcompiledfunction *) DUK_ACT_GET_FUNC(act);
bcode = DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(fun);
bcode = DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(thr->heap, fun);
DUK_ASSERT(thr->valstack_top - thr->valstack_bottom >= fun->nregs);
DUK_ASSERT(thr->valstack_top - thr->valstack_bottom == fun->nregs); /* XXX: correct? */
@ -1655,8 +1655,8 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {
(long) (thr->callstack_top - 1),
(void *) fun,
(void *) bcode,
(void *) DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(fun),
(void *) DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE(fun),
(void *) DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(thr->heap, fun),
(void *) DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE(thr->heap, fun),
(long) (thr->callstack_top - 1),
(long) (thr->valstack_bottom - thr->valstack),
(long) (thr->valstack_top - thr->valstack),
@ -1702,8 +1702,8 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {
*/
act = thr->callstack + thr->callstack_top - 1;
DUK_ASSERT(bcode + act->pc >= DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(fun));
DUK_ASSERT(bcode + act->pc < DUK_HCOMPILEDFUNCTION_GET_CODE_END(fun));
DUK_ASSERT(bcode + act->pc >= DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(thr->heap, fun));
DUK_ASSERT(bcode + act->pc < DUK_HCOMPILEDFUNCTION_GET_CODE_END(thr->heap, fun));
DUK_DDD(DUK_DDDPRINT("executing bytecode: pc=%ld ins=0x%08lx, op=%ld, valstack_top=%ld/%ld --> %!I",
(long) act->pc,
@ -2243,11 +2243,11 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {
*/
DUK_DDD(DUK_DDDPRINT("CLOSURE to target register %ld, fnum %ld (count %ld)",
(long) a, (long) bc, (long) DUK_HCOMPILEDFUNCTION_GET_FUNCS_COUNT(fun)));
(long) a, (long) bc, (long) DUK_HCOMPILEDFUNCTION_GET_FUNCS_COUNT(thr->heap, fun)));
DUK_ASSERT_DISABLE(bc >= 0); /* unsigned */
DUK_ASSERT((duk_uint_t) bc < (duk_uint_t) DUK_HCOMPILEDFUNCTION_GET_FUNCS_COUNT(fun));
fun_temp = DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE(fun)[bc];
DUK_ASSERT((duk_uint_t) bc < (duk_uint_t) DUK_HCOMPILEDFUNCTION_GET_FUNCS_COUNT(thr->heap, fun));
fun_temp = DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE(thr->heap, fun)[bc];
DUK_ASSERT(fun_temp != NULL);
DUK_ASSERT(DUK_HOBJECT_IS_COMPILEDFUNCTION(fun_temp));
@ -3439,7 +3439,7 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {
prev_env = act->lex_env;
DUK_ASSERT(prev_env != NULL);
act->lex_env = DUK_HOBJECT_GET_PROTOTYPE(prev_env);
act->lex_env = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, prev_env);
DUK_CAT_CLEAR_LEXENV_ACTIVE(cat);
DUK_HOBJECT_DECREF(thr, prev_env); /* side effects */
}
@ -3588,11 +3588,6 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {
break;
}
case DUK_EXTRAOP_DUMPTHREAD: {
DUK_DEBUG_DUMP_HTHREAD(thr);
break;
}
case DUK_EXTRAOP_LOGMARK: {
DUK_D(DUK_DPRINT("LOGMARK: mark %ld at pc %ld", (long) DUK_DEC_BC(ins), (long) (act->pc - 1))); /* -1, autoinc */
break;

8
src/duk_js_ops.c

@ -567,8 +567,8 @@ DUK_INTERNAL duk_bool_t duk_js_equals_helper(duk_hthread *thr, duk_tval *tv_x, d
if (len_x != len_y) {
return 0;
}
buf_x = (void *) DUK_HBUFFER_GET_DATA_PTR(h_x);
buf_y = (void *) DUK_HBUFFER_GET_DATA_PTR(h_y);
buf_x = (void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_x);
buf_y = (void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_y);
/* if len_x == len_y == 0, buf_x and/or buf_y may
* be NULL, but that's OK.
*/
@ -655,7 +655,7 @@ DUK_INTERNAL duk_bool_t duk_js_equals_helper(duk_hthread *thr, duk_tval *tv_x, d
return 0;
}
buf_x = (void *) DUK_HSTRING_GET_DATA(h_x);
buf_y = (void *) DUK_HBUFFER_GET_DATA_PTR(h_y);
buf_y = (void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_y);
/* if len_x == len_y == 0, buf_x and/or buf_y may
* be NULL, but that's OK.
*/
@ -1053,7 +1053,7 @@ DUK_INTERNAL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_
* also the built-in Function prototype, the result is true.
*/
val = DUK_HOBJECT_GET_PROTOTYPE(val);
val = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, val);
if (!val) {
goto pop_and_false;

104
src/duk_js_var.c

@ -74,18 +74,18 @@ DUK_LOCAL void duk__inc_data_inner_refcounts(duk_hthread *thr, duk_hcompiledfunc
duk_tval *tv, *tv_end;
duk_hobject **funcs, **funcs_end;
DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_DATA(f) != NULL); /* compiled functions must be created 'atomically' */
DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_DATA(thr->heap, f) != NULL); /* compiled functions must be created 'atomically' */
DUK_UNREF(thr);
tv = DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(f);
tv_end = DUK_HCOMPILEDFUNCTION_GET_CONSTS_END(f);
tv = DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(thr->heap, f);
tv_end = DUK_HCOMPILEDFUNCTION_GET_CONSTS_END(thr->heap, f);
while (tv < tv_end) {
DUK_TVAL_INCREF(thr, tv);
tv++;
}
funcs = DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE(f);
funcs_end = DUK_HCOMPILEDFUNCTION_GET_FUNCS_END(f);
funcs = DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE(thr->heap, f);
funcs_end = DUK_HCOMPILEDFUNCTION_GET_FUNCS_END(thr->heap, f);
while (funcs < funcs_end) {
DUK_HEAPHDR_INCREF(thr, (duk_heaphdr *) *funcs);
funcs++;
@ -120,9 +120,9 @@ void duk_js_push_closure(duk_hthread *thr,
duk_uint_t len_value;
DUK_ASSERT(fun_temp != NULL);
DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_DATA(fun_temp) != NULL);
DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_FUNCS(fun_temp) != NULL);
DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_BYTECODE(fun_temp) != NULL);
DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_DATA(thr->heap, fun_temp) != NULL);
DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_FUNCS(thr->heap, fun_temp) != NULL);
DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_BYTECODE(thr->heap, fun_temp) != NULL);
DUK_ASSERT(outer_var_env != NULL);
DUK_ASSERT(outer_lex_env != NULL);
@ -132,28 +132,28 @@ void duk_js_push_closure(duk_hthread *thr,
fun_clos = (duk_hcompiledfunction *) duk_get_hcompiledfunction(ctx, -2);
DUK_ASSERT(DUK_HOBJECT_IS_COMPILEDFUNCTION((duk_hobject *) fun_clos));
DUK_ASSERT(fun_clos != NULL);
DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_DATA(fun_clos) == NULL);
DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_FUNCS(fun_clos) == NULL);
DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_BYTECODE(fun_clos) == NULL);
DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_DATA(thr->heap, fun_clos) == NULL);
DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_FUNCS(thr->heap, fun_clos) == NULL);
DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_BYTECODE(thr->heap, fun_clos) == NULL);
DUK_HCOMPILEDFUNCTION_SET_DATA(fun_clos, DUK_HCOMPILEDFUNCTION_GET_DATA(fun_temp));
DUK_HCOMPILEDFUNCTION_SET_FUNCS(fun_clos, DUK_HCOMPILEDFUNCTION_GET_FUNCS(fun_temp));
DUK_HCOMPILEDFUNCTION_SET_BYTECODE(fun_clos, DUK_HCOMPILEDFUNCTION_GET_BYTECODE(fun_temp));
DUK_HCOMPILEDFUNCTION_SET_DATA(thr->heap, fun_clos, DUK_HCOMPILEDFUNCTION_GET_DATA(thr->heap, fun_temp));
DUK_HCOMPILEDFUNCTION_SET_FUNCS(thr->heap, fun_clos, DUK_HCOMPILEDFUNCTION_GET_FUNCS(thr->heap, fun_temp));
DUK_HCOMPILEDFUNCTION_SET_BYTECODE(thr->heap, fun_clos, DUK_HCOMPILEDFUNCTION_GET_BYTECODE(thr->heap, fun_temp));
/* Note: all references inside 'data' need to get their refcounts
* upped too. This is the case because refcounts are decreased
* through every function referencing 'data' independently.
*/
DUK_HBUFFER_INCREF(thr, DUK_HCOMPILEDFUNCTION_GET_DATA(fun_clos));
DUK_HBUFFER_INCREF(thr, DUK_HCOMPILEDFUNCTION_GET_DATA(thr->heap, fun_clos));
duk__inc_data_inner_refcounts(thr, fun_temp);
fun_clos->nregs = fun_temp->nregs;
fun_clos->nargs = fun_temp->nargs;
DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_DATA(fun_clos) != NULL);
DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_FUNCS(fun_clos) != NULL);
DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_BYTECODE(fun_clos) != NULL);
DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_DATA(thr->heap, fun_clos) != NULL);
DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_FUNCS(thr->heap, fun_clos) != NULL);
DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_BYTECODE(thr->heap, fun_clos) != NULL);
/* XXX: could also copy from template, but there's no way to have any
* other value here now (used code has no access to the template).
@ -430,7 +430,7 @@ void duk_js_push_closure(duk_hthread *thr,
*/
DUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(&fun_clos->obj) == DUK_HOBJECT_CLASS_FUNCTION);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(&fun_clos->obj) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, &fun_clos->obj) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);
DUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(&fun_clos->obj));
DUK_ASSERT(duk_has_prop_stridx(ctx, -2, DUK_STRIDX_LENGTH) != 0);
DUK_ASSERT(duk_has_prop_stridx(ctx, -2, DUK_STRIDX_PROTOTYPE) != 0);
@ -475,7 +475,7 @@ duk_hobject *duk_create_activation_environment_record(duk_hthread *thr,
DUK_ASSERT(thr != NULL);
DUK_ASSERT(func != NULL);
tv = duk_hobject_find_existing_entry_tval_ptr(func, DUK_HTHREAD_STRING_INT_LEXENV(thr));
tv = duk_hobject_find_existing_entry_tval_ptr(thr->heap, func, DUK_HTHREAD_STRING_INT_LEXENV(thr));
if (tv) {
DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv));
DUK_ASSERT(DUK_HOBJECT_IS_ENV(DUK_TVAL_GET_OBJECT(tv)));
@ -534,7 +534,7 @@ void duk_js_init_activation_environment_records_delayed(duk_hthread *thr,
duk_hobject *p = env;
while (p) {
DUK_DDD(DUK_DDDPRINT(" -> %!ipO", (duk_heaphdr *) p));
p = DUK_HOBJECT_GET_PROTOTYPE(p);
p = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, p);
}
}
#endif
@ -655,12 +655,12 @@ DUK_INTERNAL void duk_js_close_environment_record(duk_hthread *thr, duk_hobject
DUK_DDD(DUK_DDDPRINT("copying bound register values, %ld bound regs", (long) DUK_HOBJECT_GET_ENEXT(varmap)));
for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(varmap); i++) {
key = DUK_HOBJECT_E_GET_KEY(varmap, i);
key = DUK_HOBJECT_E_GET_KEY(thr->heap, varmap, i);
DUK_ASSERT(key != NULL); /* assume keys are compacted */
DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(varmap, i)); /* assume plain values */
DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, varmap, i)); /* assume plain values */
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(varmap, i);
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, varmap, i);
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv)); /* assume value is a number */
regnum = (duk_uint_t) DUK_TVAL_GET_NUMBER(tv);
DUK_ASSERT_DISABLE(regnum >= 0); /* unsigned */
@ -747,12 +747,12 @@ duk_bool_t duk__getid_open_decl_env_regs(duk_hthread *thr,
DUK_ASSERT(DUK_HOBJECT_IS_DECENV(env));
tv = duk_hobject_find_existing_entry_tval_ptr(env, DUK_HTHREAD_STRING_INT_CALLEE(thr));
tv = duk_hobject_find_existing_entry_tval_ptr(thr->heap, env, DUK_HTHREAD_STRING_INT_CALLEE(thr));
if (!tv) {
/* env is closed, should be missing _Callee, _Thread, _Regbase */
DUK_ASSERT(duk_hobject_find_existing_entry_tval_ptr(env, DUK_HTHREAD_STRING_INT_CALLEE(thr)) == NULL);
DUK_ASSERT(duk_hobject_find_existing_entry_tval_ptr(env, DUK_HTHREAD_STRING_INT_THREAD(thr)) == NULL);
DUK_ASSERT(duk_hobject_find_existing_entry_tval_ptr(env, DUK_HTHREAD_STRING_INT_REGBASE(thr)) == NULL);
DUK_ASSERT(duk_hobject_find_existing_entry_tval_ptr(thr->heap, env, DUK_HTHREAD_STRING_INT_CALLEE(thr)) == NULL);
DUK_ASSERT(duk_hobject_find_existing_entry_tval_ptr(thr->heap, env, DUK_HTHREAD_STRING_INT_THREAD(thr)) == NULL);
DUK_ASSERT(duk_hobject_find_existing_entry_tval_ptr(thr->heap, env, DUK_HTHREAD_STRING_INT_REGBASE(thr)) == NULL);
return 0;
}
@ -762,7 +762,7 @@ duk_bool_t duk__getid_open_decl_env_regs(duk_hthread *thr,
env_func = DUK_TVAL_GET_OBJECT(tv);
DUK_ASSERT(env_func != NULL);
tv = duk_hobject_find_existing_entry_tval_ptr(env_func, DUK_HTHREAD_STRING_INT_VARMAP(thr));
tv = duk_hobject_find_existing_entry_tval_ptr(thr->heap, env_func, DUK_HTHREAD_STRING_INT_VARMAP(thr));
if (!tv) {
return 0;
}
@ -770,7 +770,7 @@ duk_bool_t duk__getid_open_decl_env_regs(duk_hthread *thr,
varmap = DUK_TVAL_GET_OBJECT(tv);
DUK_ASSERT(varmap != NULL);
tv = duk_hobject_find_existing_entry_tval_ptr(varmap, name);
tv = duk_hobject_find_existing_entry_tval_ptr(thr->heap, varmap, name);
if (!tv) {
return 0;
}
@ -779,7 +779,7 @@ duk_bool_t duk__getid_open_decl_env_regs(duk_hthread *thr,
DUK_ASSERT_DISABLE(reg_rel >= 0); /* unsigned */
DUK_ASSERT(reg_rel < ((duk_hcompiledfunction *) env_func)->nregs);
tv = duk_hobject_find_existing_entry_tval_ptr(env, DUK_HTHREAD_STRING_INT_THREAD(thr));
tv = duk_hobject_find_existing_entry_tval_ptr(thr->heap, env, DUK_HTHREAD_STRING_INT_THREAD(thr));
DUK_ASSERT(tv != NULL);
DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv));
DUK_ASSERT(DUK_TVAL_GET_OBJECT(tv) != NULL);
@ -791,7 +791,7 @@ duk_bool_t duk__getid_open_decl_env_regs(duk_hthread *thr,
* with what thread is used for valstack lookup.
*/
tv = duk_hobject_find_existing_entry_tval_ptr(env, DUK_HTHREAD_STRING_INT_REGBASE(thr));
tv = duk_hobject_find_existing_entry_tval_ptr(thr->heap, env, DUK_HTHREAD_STRING_INT_REGBASE(thr));
DUK_ASSERT(tv != NULL);
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
env_regbase = (duk_size_t) DUK_TVAL_GET_NUMBER(tv);
@ -836,7 +836,7 @@ duk_bool_t duk__getid_activation_regs(duk_hthread *thr,
return 0;
}
tv = duk_hobject_find_existing_entry_tval_ptr(func, DUK_HTHREAD_STRING_INT_VARMAP(thr));
tv = duk_hobject_find_existing_entry_tval_ptr(thr->heap, func, DUK_HTHREAD_STRING_INT_VARMAP(thr));
if (!tv) {
return 0;
}
@ -844,7 +844,7 @@ duk_bool_t duk__getid_activation_regs(duk_hthread *thr,
varmap = DUK_TVAL_GET_OBJECT(tv);
DUK_ASSERT(varmap != NULL);
tv = duk_hobject_find_existing_entry_tval_ptr(varmap, name);
tv = duk_hobject_find_existing_entry_tval_ptr(thr->heap, varmap, name);
if (!tv) {
return 0;
}
@ -949,12 +949,12 @@ duk_bool_t duk__get_identifier_reference(duk_hthread *thr,
DUK_ASSERT(func != NULL);
DUK_ASSERT(DUK_HOBJECT_HAS_NEWENV(func));
tv = duk_hobject_find_existing_entry_tval_ptr(func, DUK_HTHREAD_STRING_INT_LEXENV(thr));
tv = duk_hobject_find_existing_entry_tval_ptr(thr->heap, func, DUK_HTHREAD_STRING_INT_LEXENV(thr));
if (tv) {
DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv));
env = DUK_TVAL_GET_OBJECT(tv);
} else {
DUK_ASSERT(duk_hobject_find_existing_entry_tval_ptr(func, DUK_HTHREAD_STRING_INT_VARENV(thr)) == NULL);
DUK_ASSERT(duk_hobject_find_existing_entry_tval_ptr(thr->heap, func, DUK_HTHREAD_STRING_INT_VARENV(thr)) == NULL);
env = thr->builtins[DUK_BIDX_GLOBAL_ENV];
}
@ -1013,7 +1013,7 @@ duk_bool_t duk__get_identifier_reference(duk_hthread *thr,
}
skip_regs:
tv = duk_hobject_find_existing_entry_tval_ptr_and_attrs(env, name, &attrs);
tv = duk_hobject_find_existing_entry_tval_ptr_and_attrs(thr->heap, env, name, &attrs);
if (tv) {
out->value = tv;
out->attrs = attrs;
@ -1049,7 +1049,7 @@ duk_bool_t duk__get_identifier_reference(duk_hthread *thr,
DUK_ASSERT(cl == DUK_HOBJECT_CLASS_OBJENV);
tv = duk_hobject_find_existing_entry_tval_ptr(env, DUK_HTHREAD_STRING_INT_TARGET(thr));
tv = duk_hobject_find_existing_entry_tval_ptr(thr->heap, env, DUK_HTHREAD_STRING_INT_TARGET(thr));
DUK_ASSERT(tv != NULL);
DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv));
target = DUK_TVAL_GET_OBJECT(tv);
@ -1066,7 +1066,7 @@ duk_bool_t duk__get_identifier_reference(duk_hthread *thr,
if (duk_hobject_hasprop_raw(thr, target, name)) {
out->value = NULL; /* can't get value, may be accessor */
out->attrs = 0; /* irrelevant when out->value == NULL */
tv = duk_hobject_find_existing_entry_tval_ptr(env, DUK_HTHREAD_STRING_INT_THIS(thr));
tv = duk_hobject_find_existing_entry_tval_ptr(thr->heap, env, DUK_HTHREAD_STRING_INT_THIS(thr));
out->this_binding = tv; /* may be NULL */
out->env = env;
out->holder = target;
@ -1090,7 +1090,7 @@ duk_bool_t duk__get_identifier_reference(duk_hthread *thr,
if (sanity-- == 0) {
DUK_ERROR(thr, DUK_ERR_INTERNAL_ERROR, DUK_STR_PROTOTYPE_CHAIN_LIMIT);
}
env = DUK_HOBJECT_GET_PROTOTYPE(env);
env = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, env);
};
/*
@ -1615,14 +1615,14 @@ duk_bool_t duk__declvar_helper(duk_hthread *thr,
/* must be found: was found earlier, and cannot be inherited */
for (;;) {
DUK_ASSERT(holder != NULL);
duk_hobject_find_existing_entry(holder, name, &e_idx, &h_idx);
duk_hobject_find_existing_entry(thr->heap, holder, name, &e_idx, &h_idx);
if (e_idx >= 0) {
break;
}
/* SCANBUILD: NULL pointer dereference, doesn't actually trigger,
* asserted above.
*/
holder = DUK_HOBJECT_GET_PROTOTYPE(holder);
holder = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, holder);
}
DUK_ASSERT(holder != NULL);
DUK_ASSERT(e_idx >= 0);
@ -1635,7 +1635,7 @@ duk_bool_t duk__declvar_helper(duk_hthread *thr,
* conflicting property.
*/
flags = DUK_HOBJECT_E_GET_FLAGS(holder, e_idx);
flags = DUK_HOBJECT_E_GET_FLAGS(thr->heap, holder, e_idx);
if (!(flags & DUK_PROPDESC_FLAG_CONFIGURABLE)) {
if (flags & DUK_PROPDESC_FLAG_ACCESSOR) {
DUK_DDD(DUK_DDDPRINT("existing property is a non-configurable "
@ -1665,18 +1665,18 @@ duk_bool_t duk__declvar_helper(duk_hthread *thr,
if (flags & DUK_PROPDESC_FLAG_ACCESSOR) {
duk_hobject *tmp;
tmp = DUK_HOBJECT_E_GET_VALUE_GETTER(holder, e_idx);
DUK_HOBJECT_E_SET_VALUE_GETTER(holder, e_idx, NULL);
tmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, holder, e_idx);
DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, holder, e_idx, NULL);
DUK_HOBJECT_DECREF(thr, tmp);
DUK_UNREF(tmp);
tmp = DUK_HOBJECT_E_GET_VALUE_SETTER(holder, e_idx);
DUK_HOBJECT_E_SET_VALUE_SETTER(holder, e_idx, NULL);
tmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, holder, e_idx);
DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, holder, e_idx, NULL);
DUK_HOBJECT_DECREF(thr, tmp);
DUK_UNREF(tmp);
} else {
duk_tval tv_tmp;
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(holder, e_idx);
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, holder, e_idx);
DUK_TVAL_SET_TVAL(&tv_tmp, tv);
DUK_TVAL_SET_UNDEFINED_UNUSED(tv);
DUK_TVAL_DECREF(thr, &tv_tmp);
@ -1686,14 +1686,14 @@ duk_bool_t duk__declvar_helper(duk_hthread *thr,
* a value copy at the caller.
*/
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(holder, e_idx);
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, holder, e_idx);
DUK_TVAL_SET_TVAL(tv, val);
DUK_TVAL_INCREF(thr, tv);
DUK_HOBJECT_E_SET_FLAGS(holder, e_idx, prop_flags);
DUK_HOBJECT_E_SET_FLAGS(thr->heap, holder, e_idx, prop_flags);
DUK_DDD(DUK_DDDPRINT("updated global binding, final result: "
"value -> %!T, prop_flags=0x%08lx",
(duk_tval *) DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(holder, e_idx),
(duk_tval *) DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, holder, e_idx),
(unsigned long) prop_flags));
} else {
DUK_DDD(DUK_DDDPRINT("redefine, offending property in ancestor"));
@ -1720,7 +1720,7 @@ duk_bool_t duk__declvar_helper(duk_hthread *thr,
} else {
DUK_ASSERT(DUK_HOBJECT_IS_OBJENV(env));
tv = duk_hobject_find_existing_entry_tval_ptr(env, DUK_HTHREAD_STRING_INT_TARGET(thr));
tv = duk_hobject_find_existing_entry_tval_ptr(thr->heap, env, DUK_HTHREAD_STRING_INT_TARGET(thr));
DUK_ASSERT(tv != NULL);
DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv));
holder = DUK_TVAL_GET_OBJECT(tv);

1
util/make_dist.sh

@ -113,7 +113,6 @@ for i in \
duk_debug_fixedbuffer.c \
duk_debug.h \
duk_debug_heap.c \
duk_debug_hobject.c \
duk_debug_macros.c \
duk_debug_vsnprintf.c \
duk_error_augment.c \

Loading…
Cancel
Save