|
|
@ -1487,6 +1487,20 @@ int duk_is_dynamic(duk_context *ctx, int index) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
int duk_is_fixed(duk_context *ctx, int index) { |
|
|
|
duk_tval *tv; |
|
|
|
|
|
|
|
DUK_ASSERT(ctx != NULL); |
|
|
|
|
|
|
|
tv = duk_get_tval(ctx, index); |
|
|
|
if (DUK_TVAL_IS_BUFFER(tv)) { |
|
|
|
duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv); |
|
|
|
DUK_ASSERT(h != NULL); |
|
|
|
return (DUK_HBUFFER_HAS_DYNAMIC(h) ? 0 : 1); |
|
|
|
} |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
int duk_is_primitive(duk_context *ctx, int index) { |
|
|
|
return !duk_is_object(ctx, index); |
|
|
|
} |
|
|
@ -2388,4 +2402,66 @@ int duk_strict_equals(duk_context *ctx, int index1, int index2) { |
|
|
|
return duk_js_strict_equals(tv1, tv2); |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
|
* Heap creation |
|
|
|
*/ |
|
|
|
|
|
|
|
duk_context *duk_create_heap(duk_alloc_function alloc_func, |
|
|
|
duk_realloc_function realloc_func, |
|
|
|
duk_free_function free_func, |
|
|
|
void *alloc_udata, |
|
|
|
duk_fatal_function fatal_handler) { |
|
|
|
duk_heap *heap = NULL; |
|
|
|
duk_context *ctx; |
|
|
|
|
|
|
|
/* Assume that either all memory funcs are NULL or non-NULL, mixed
|
|
|
|
* cases will now be unsafe. |
|
|
|
*/ |
|
|
|
|
|
|
|
/* FIXME: just assert non-NULL values here and make caller arguments
|
|
|
|
* do the defaulting to the default implementations (smaller code)? |
|
|
|
*/ |
|
|
|
|
|
|
|
if (!alloc_func) { |
|
|
|
DUK_ASSERT(realloc_func == NULL); |
|
|
|
DUK_ASSERT(free_func == NULL); |
|
|
|
alloc_func = duk_default_alloc_function; |
|
|
|
realloc_func = duk_default_realloc_function; |
|
|
|
free_func = duk_default_free_function; |
|
|
|
} else { |
|
|
|
DUK_ASSERT(realloc_func != NULL); |
|
|
|
DUK_ASSERT(free_func != NULL); |
|
|
|
} |
|
|
|
|
|
|
|
if (!fatal_handler) { |
|
|
|
fatal_handler = duk_default_fatal_handler; |
|
|
|
} |
|
|
|
|
|
|
|
DUK_ASSERT(alloc_func != NULL); |
|
|
|
DUK_ASSERT(realloc_func != NULL); |
|
|
|
DUK_ASSERT(free_func != NULL); |
|
|
|
DUK_ASSERT(fatal_handler != NULL); |
|
|
|
|
|
|
|
heap = duk_heap_alloc(alloc_func, realloc_func, free_func, alloc_udata, fatal_handler); |
|
|
|
if (!heap) { |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
ctx = (duk_context *) heap->heap_thread; |
|
|
|
DUK_ASSERT(ctx != NULL); |
|
|
|
DUK_ASSERT(((duk_hthread *) ctx)->heap != NULL); |
|
|
|
return ctx; |
|
|
|
} |
|
|
|
|
|
|
|
void duk_destroy_heap(duk_context *ctx) { |
|
|
|
duk_hthread *thr = (duk_hthread *) ctx; |
|
|
|
duk_heap *heap; |
|
|
|
|
|
|
|
if (!ctx) { |
|
|
|
return; |
|
|
|
} |
|
|
|
heap = thr->heap; |
|
|
|
DUK_ASSERT(heap != NULL); |
|
|
|
|
|
|
|
duk_heap_free(heap); |
|
|
|
} |
|
|
|
|
|
|
|