本文整理汇总了C++中DUK_DPRINT函数的典型用法代码示例。如果您正苦于以下问题:C++ DUK_DPRINT函数的具体用法?C++ DUK_DPRINT怎么用?C++ DUK_DPRINT使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了DUK_DPRINT函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: duk__refcount_run_torture_finalizer
DUK_LOCAL void duk__refcount_run_torture_finalizer(duk_hthread *thr, duk_hobject *obj) {
duk_context *ctx;
duk_int_t rc;
DUK_ASSERT(thr != NULL);
DUK_ASSERT(obj != NULL);
ctx = (duk_context *) thr;
/* Avoid fake finalization for the duk__refcount_fake_finalizer function
* itself, otherwise we're in infinite recursion.
*/
if (DUK_HOBJECT_HAS_NATFUNC(obj)) {
if (((duk_hnatfunc *) obj)->func == duk__refcount_fake_finalizer) {
DUK_DD(DUK_DDPRINT("avoid fake torture finalizer for duk__refcount_fake_finalizer itself"));
return;
}
}
/* Avoid fake finalization when callstack limit has been reached.
* Otherwise a callstack limit error will be created, then refzero'ed,
* and we're in an infinite loop.
*/
if (thr->heap->call_recursion_depth >= thr->heap->call_recursion_limit ||
thr->callstack_size + 2 * DUK_CALLSTACK_GROW_STEP >= thr->callstack_max /*approximate*/) {
DUK_D(DUK_DPRINT("call recursion depth reached, avoid fake torture finalizer"));
return;
}
/* Run fake finalizer. Avoid creating new refzero queue entries
* so that we are not forced into a forever loop.
*/
duk_push_c_function(ctx, duk__refcount_fake_finalizer, 1 /*nargs*/);
duk_push_hobject(ctx, obj);
rc = duk_pcall(ctx, 1);
DUK_UNREF(rc); /* ignored */
duk_pop(ctx);
}
示例2: duk__duplicate_ram_global_object
DUK_LOCAL void duk__duplicate_ram_global_object(duk_hthread *thr) {
duk_context *ctx;
duk_hobject *h1;
#if defined(DUK_USE_ROM_GLOBAL_CLONE)
duk_hobject *h2;
duk_uint8_t *props;
duk_size_t alloc_size;
#endif
ctx = (duk_context *) thr;
/* XXX: refactor into internal helper, duk_clone_hobject() */
#if defined(DUK_USE_ROM_GLOBAL_INHERIT)
/* Inherit from ROM-based global object: less RAM usage, less transparent. */
duk_push_object_helper(ctx,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_GLOBAL),
DUK_BIDX_GLOBAL);
h1 = duk_get_hobject(ctx, -1);
DUK_ASSERT(h1 != NULL);
#elif defined(DUK_USE_ROM_GLOBAL_CLONE)
/* Clone the properties of the ROM-based global object to create a
* fully RAM-based global object. Uses more memory than the inherit
* model but more compliant.
*/
duk_push_object_helper(ctx,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_GLOBAL),
DUK_BIDX_OBJECT_PROTOTYPE);
h1 = duk_get_hobject(ctx, -1);
DUK_ASSERT(h1 != NULL);
h2 = thr->builtins[DUK_BIDX_GLOBAL];
DUK_ASSERT(h2 != NULL);
/* Copy the property table verbatim; this handles attributes etc.
* For ROM objects it's not necessary (or possible) to update
* refcounts so leave them as is.
*/
alloc_size = DUK_HOBJECT_P_ALLOC_SIZE(h2);
DUK_ASSERT(alloc_size > 0);
props = DUK_ALLOC(thr->heap, alloc_size);
if (!props) {
DUK_ERROR_ALLOC_FAILED(thr);
return;
}
DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, h2) != NULL);
DUK_MEMCPY((void *) props, (const void *) DUK_HOBJECT_GET_PROPS(thr->heap, h2), alloc_size);
/* XXX: keep property attributes or tweak them here?
* Properties will now be non-configurable even when they're
* normally configurable for the global object.
*/
DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, h1) == NULL);
DUK_HOBJECT_SET_PROPS(thr->heap, h1, props);
DUK_HOBJECT_SET_ESIZE(h1, DUK_HOBJECT_GET_ESIZE(h2));
DUK_HOBJECT_SET_ENEXT(h1, DUK_HOBJECT_GET_ENEXT(h2));
DUK_HOBJECT_SET_ASIZE(h1, DUK_HOBJECT_GET_ASIZE(h2));
DUK_HOBJECT_SET_HSIZE(h1, DUK_HOBJECT_GET_HSIZE(h2));
#else
#error internal error in defines
#endif
duk_hobject_compact_props(thr, h1);
DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);
DUK_ASSERT(!DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE((duk_heaphdr *) thr->builtins[DUK_BIDX_GLOBAL])); /* no need to decref */
thr->builtins[DUK_BIDX_GLOBAL] = h1;
DUK_HOBJECT_INCREF(thr, h1);
DUK_D(DUK_DPRINT("duplicated global object: %!O", h1));
/* Create a fresh object environment for the global scope. This is
* needed so that the global scope points to the newly created RAM-based
* global object.
*/
duk_push_object_helper(ctx,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV),
-1); /* no prototype */
h1 = duk_get_hobject(ctx, -1);
DUK_ASSERT(h1 != NULL);
duk_dup(ctx, -2);
duk_dup(ctx, -1); /* -> [ ... new_global new_globalenv new_global new_global ] */
duk_xdef_prop_stridx(thr, -3, DUK_STRIDX_INT_TARGET, DUK_PROPDESC_FLAGS_NONE);
duk_xdef_prop_stridx(thr, -2, DUK_STRIDX_INT_THIS, DUK_PROPDESC_FLAGS_NONE); /* always provideThis=true */
duk_hobject_compact_props(thr, h1);
DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL_ENV] != NULL);
DUK_ASSERT(!DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE((duk_heaphdr *) thr->builtins[DUK_BIDX_GLOBAL_ENV])); /* no need to decref */
thr->builtins[DUK_BIDX_GLOBAL_ENV] = h1;
DUK_HOBJECT_INCREF(thr, h1);
DUK_D(DUK_DPRINT("duplicated global env: %!O", h1));
duk_pop_2(ctx);
}
示例3: duk_err_longjmp
DUK_INTERNAL void duk_err_longjmp(duk_hthread *thr) {
DUK_ASSERT(thr != NULL);
DUK_ASSERT(thr->heap != NULL);
DUK_DD(DUK_DDPRINT("longjmp error: type=%d iserror=%d value1=%!T value2=%!T",
(int) thr->heap->lj.type, (int) thr->heap->lj.iserror,
&thr->heap->lj.value1, &thr->heap->lj.value2));
/* Prevent finalizer execution during error handling. All error
* handling sites will process pending finalizers once error handling
* is complete and we're ready for the side effects. Does not prevent
* refzero freeing or mark-and-sweep during error handling.
*
* NOTE: when we come here some calling code may have used DECREF
* NORZ macros without an explicit DUK_REFZERO_CHECK_xxx() call.
* We don't want to do it here because it would just check for
* pending finalizers and we prevent that explicitly. Instead,
* the error catcher will run the finalizers once error handling
* is complete.
*/
DUK_ASSERT_LJSTATE_SET(thr->heap);
thr->heap->pf_prevent_count++;
DUK_ASSERT(thr->heap->pf_prevent_count != 0); /* Wrap. */
#if defined(DUK_USE_ASSERTIONS)
/* XXX: set this immediately when longjmp state is set */
DUK_ASSERT(thr->heap->error_not_allowed == 0); /* Detect error within critical section. */
thr->heap->error_not_allowed = 1;
#endif
DUK_DD(DUK_DDPRINT("about to longjmp, pf_prevent_count=%ld", (long) thr->heap->pf_prevent_count));
#if !defined(DUK_USE_CPP_EXCEPTIONS)
/* If we don't have a jmpbuf_ptr, there is little we can do except
* cause a fatal error. The caller's expectation is that we never
* return.
*
* With C++ exceptions we now just propagate an uncaught error
* instead of invoking the fatal error handler. Because there's
* a dummy jmpbuf for C++ exceptions now, this could be changed.
*/
if (!thr->heap->lj.jmpbuf_ptr) {
DUK_D(DUK_DPRINT("uncaught error: type=%d iserror=%d value1=%!T value2=%!T",
(int) thr->heap->lj.type, (int) thr->heap->lj.iserror,
&thr->heap->lj.value1, &thr->heap->lj.value2));
#if defined(DUK_USE_PREFER_SIZE)
duk__uncaught_minimal(thr);
#else
duk__uncaught_error_aware(thr);
#endif
DUK_UNREACHABLE();
}
#endif /* DUK_USE_CPP_EXCEPTIONS */
#if defined(DUK_USE_CPP_EXCEPTIONS)
{
duk_internal_exception exc; /* dummy */
throw exc;
}
#else /* DUK_USE_CPP_EXCEPTIONS */
DUK_LONGJMP(thr->heap->lj.jmpbuf_ptr->jb);
#endif /* DUK_USE_CPP_EXCEPTIONS */
DUK_UNREACHABLE();
}
示例4: DUK_ASSERT
DUK_INTERNAL void *duk_heap_mem_realloc_indirect(duk_heap *heap, duk_mem_getptr cb, void *ud, duk_size_t newsize) {
void *res;
duk_bool_t rc;
duk_small_int_t i;
DUK_ASSERT(heap != NULL);
DUK_ASSERT_DISABLE(newsize >= 0);
/*
* Voluntary periodic GC (if enabled)
*/
DUK__VOLUNTARY_PERIODIC_GC(heap);
/*
* First attempt
*/
#if defined(DUK_USE_GC_TORTURE)
/* simulate alloc failure on every realloc (except when mark-and-sweep is running) */
if (!DUK_HEAP_HAS_MARKANDSWEEP_RUNNING(heap)) {
DUK_DDD(DUK_DDDPRINT("gc torture enabled, pretend that first indirect realloc attempt fails"));
res = NULL;
DUK_UNREF(res);
goto skip_attempt;
}
#endif
res = heap->realloc_func(heap->heap_udata, cb(heap, ud), newsize);
if (res || newsize == 0) {
/* for zero size allocations NULL is allowed */
return res;
}
#if defined(DUK_USE_GC_TORTURE)
skip_attempt:
#endif
DUK_D(DUK_DPRINT("first indirect realloc attempt failed, attempt to gc and retry"));
/*
* Avoid a GC if GC is already running. See duk_heap_mem_alloc().
*/
if (DUK_HEAP_HAS_MARKANDSWEEP_RUNNING(heap)) {
DUK_D(DUK_DPRINT("duk_heap_mem_realloc_indirect() failed, gc in progress (gc skipped), alloc size %ld", (long) newsize));
return NULL;
}
/*
* Retry with several GC attempts. Initial attempts are made without
* emergency mode; later attempts use emergency mode which minimizes
* memory allocations forcibly.
*/
for (i = 0; i < DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_LIMIT; i++) {
duk_small_uint_t flags;
#if defined(DUK_USE_ASSERTIONS)
void *ptr_pre; /* ptr before mark-and-sweep */
void *ptr_post;
#endif
#if defined(DUK_USE_ASSERTIONS)
ptr_pre = cb(heap, ud);
#endif
flags = 0;
if (i >= DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_EMERGENCY_LIMIT - 1) {
flags |= DUK_MS_FLAG_EMERGENCY;
}
rc = duk_heap_mark_and_sweep(heap, flags);
DUK_UNREF(rc);
#if defined(DUK_USE_ASSERTIONS)
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",
(void *) ptr_pre, (void *) ptr_post));
}
#endif
/* Note: key issue here is to re-lookup the base pointer on every attempt.
* The pointer being reallocated may change after every mark-and-sweep.
*/
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));
return res;
}
}
DUK_D(DUK_DPRINT("duk_heap_mem_realloc_indirect() failed even after gc, alloc size %ld", (long) newsize));
return NULL;
}
示例5: DUK_D
duk_heap *duk_heap_alloc(duk_alloc_function alloc_func,
duk_realloc_function realloc_func,
duk_free_function free_func,
void *alloc_udata,
duk_fatal_function fatal_func) {
duk_heap *res = NULL;
DUK_D(DUK_DPRINT("allocate heap"));
/* Debug dump type sizes */
#ifdef DUK_USE_DEBUG
duk__dump_type_sizes();
#endif
/* If selftests enabled, run them as early as possible. */
#ifdef DUK_USE_SELF_TESTS
DUK_D(DUK_DPRINT("running self tests"));
duk_selftest_run_tests();
DUK_D(DUK_DPRINT("self tests passed"));
#endif
#ifdef DUK_USE_COMPUTED_NAN
do {
/* Workaround for some exotic platforms where NAN is missing
* and the expression (0.0 / 0.0) does NOT result in a NaN.
* Such platforms use the global 'duk_computed_nan' which must
* be initialized at runtime. Use 'volatile' to ensure that
* the compiler will actually do the computation and not try
* to do constant folding which might result in the original
* problem.
*/
volatile double dbl1 = 0.0;
volatile double dbl2 = 0.0;
duk_computed_nan = dbl1 / dbl2;
} while (0);
#endif
#ifdef DUK_USE_COMPUTED_INFINITY
do {
/* Similar workaround for INFINITY. */
volatile double dbl1 = 1.0;
volatile double dbl2 = 0.0;
duk_computed_infinity = dbl1 / dbl2;
} while (0);
#endif
/* use a raw call, all macros expect the heap to be initialized */
res = (duk_heap *) alloc_func(alloc_udata, sizeof(duk_heap));
if (!res) {
goto error;
}
/* zero everything */
DUK_MEMZERO(res, sizeof(*res));
/* explicit NULL inits */
#ifdef DUK_USE_EXPLICIT_NULL_INIT
res->alloc_udata = NULL;
res->heap_allocated = NULL;
#ifdef DUK_USE_REFERENCE_COUNTING
res->refzero_list = NULL;
res->refzero_list_tail = NULL;
#endif
#ifdef DUK_USE_MARK_AND_SWEEP
res->finalize_list = NULL;
#endif
res->heap_thread = NULL;
res->curr_thread = NULL;
res->heap_object = NULL;
res->log_buffer = NULL;
res->st = NULL;
{
int i;
for (i = 0; i < DUK_HEAP_NUM_STRINGS; i++) {
res->strs[i] = NULL;
}
}
#endif
/* initialize the structure, roughly in order */
res->alloc_func = alloc_func;
res->realloc_func = realloc_func;
res->free_func = free_func;
res->alloc_udata = alloc_udata;
res->fatal_func = fatal_func;
/* res->mark_and_sweep_trigger_counter == 0 -> now causes immediate GC; which is OK */
res->call_recursion_depth = 0;
res->call_recursion_limit = DUK_HEAP_DEFAULT_CALL_RECURSION_LIMIT;
/* FIXME: use the pointer as a seed for now: mix in time at least */
/* cast through C99 intptr_t to avoid GCC warning:
*
* warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
*/
res->hash_seed = (duk_uint32_t) (duk_intptr_t) res;
res->rnd_state = (duk_uint32_t) (duk_intptr_t) res;
//.........这里部分代码省略.........
示例6: DUK_ASSERT
/* Allocate a new duk_hbuffer of a certain type and return a pointer to it
* (NULL on error). Write buffer data pointer to 'out_bufdata' (only if
* allocation successful).
*/
DUK_INTERNAL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap, duk_size_t size, duk_small_uint_t flags, void **out_bufdata) {
duk_hbuffer *res = NULL;
duk_size_t header_size;
duk_size_t alloc_size;
DUK_ASSERT(heap != NULL);
DUK_ASSERT(out_bufdata != NULL);
DUK_DDD(DUK_DDDPRINT("allocate hbuffer"));
/* Size sanity check. Should not be necessary because caller is
* required to check this, but we don't want to cause a segfault
* if the size wraps either in duk_size_t computation or when
* storing the size in a 16-bit field.
*/
if (size > DUK_HBUFFER_MAX_BYTELEN) {
DUK_D(DUK_DPRINT("hbuffer alloc failed: size too large: %ld", (long) size));
return NULL; /* no need to write 'out_bufdata' */
}
if (flags & DUK_BUF_FLAG_EXTERNAL) {
header_size = sizeof(duk_hbuffer_external);
alloc_size = sizeof(duk_hbuffer_external);
} else if (flags & DUK_BUF_FLAG_DYNAMIC) {
header_size = sizeof(duk_hbuffer_dynamic);
alloc_size = sizeof(duk_hbuffer_dynamic);
} else {
header_size = sizeof(duk_hbuffer_fixed);
alloc_size = sizeof(duk_hbuffer_fixed) + size;
DUK_ASSERT(alloc_size >= sizeof(duk_hbuffer_fixed)); /* no wrapping */
}
res = (duk_hbuffer *) DUK_ALLOC(heap, alloc_size);
if (DUK_UNLIKELY(res == NULL)) {
goto alloc_error;
}
/* zero everything unless requested not to do so */
#if defined(DUK_USE_ZERO_BUFFER_DATA)
DUK_MEMZERO((void *) res,
(flags & DUK_BUF_FLAG_NOZERO) ? header_size : alloc_size);
#else
DUK_MEMZERO((void *) res, header_size);
#endif
if (flags & DUK_BUF_FLAG_EXTERNAL) {
duk_hbuffer_external *h;
h = (duk_hbuffer_external *) res;
DUK_UNREF(h);
*out_bufdata = NULL;
#if defined(DUK_USE_EXPLICIT_NULL_INIT)
#if defined(DUK_USE_HEAPPTR16)
/* the compressed pointer is zeroed which maps to NULL, so nothing to do. */
#else
DUK_HBUFFER_EXTERNAL_SET_DATA_PTR(heap, h, NULL);
#endif
#endif
DUK_ASSERT(DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(heap, h) == NULL);
} else if (flags & DUK_BUF_FLAG_DYNAMIC) {
duk_hbuffer_dynamic *h = (duk_hbuffer_dynamic *) res;
void *ptr;
if (size > 0) {
DUK_ASSERT(!(flags & DUK_BUF_FLAG_EXTERNAL)); /* alloc external with size zero */
DUK_DDD(DUK_DDDPRINT("dynamic buffer with nonzero size, alloc actual buffer"));
#if defined(DUK_USE_ZERO_BUFFER_DATA)
ptr = DUK_ALLOC_ZEROED(heap, size);
#else
ptr = DUK_ALLOC(heap, size);
#endif
if (DUK_UNLIKELY(ptr == NULL)) {
/* Because size > 0, NULL check is correct */
goto alloc_error;
}
*out_bufdata = ptr;
DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap, h, ptr);
} else {
*out_bufdata = NULL;
#if defined(DUK_USE_EXPLICIT_NULL_INIT)
#if defined(DUK_USE_HEAPPTR16)
/* the compressed pointer is zeroed which maps to NULL, so nothing to do. */
#else
DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap, h, NULL);
#endif
#endif
DUK_ASSERT(DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, h) == NULL);
}
} else {
*out_bufdata = (void *) ((duk_hbuffer_fixed *) res + 1);
}
DUK_HBUFFER_SET_SIZE(res, size);
DUK_HEAPHDR_SET_TYPE(&res->hdr, DUK_HTYPE_BUFFER);
if (flags & DUK_BUF_FLAG_DYNAMIC) {
//.........这里部分代码省略.........
示例7: duk__mark_hobject
DUK_LOCAL void duk__mark_hobject(duk_heap *heap, duk_hobject *h) {
duk_uint_fast32_t i;
DUK_DDD(DUK_DDDPRINT("duk__mark_hobject: %p", (void *) h));
DUK_ASSERT(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(heap, h, i);
if (!key) {
continue;
}
duk__mark_heaphdr(heap, (duk_heaphdr *) key);
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(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(heap, h, i));
}
/* hash part is a 'weak reference' and does not contribute */
duk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HOBJECT_GET_PROTOTYPE(heap, h));
/* XXX: rearrange bits to allow a switch case to be used here? */
/* XXX: add a fast path for objects (and arrays)? */
/* DUK_HOBJECT_IS_ARRAY(h): needs no special handling now as there are
* no extra fields in need of marking.
*/
if (DUK_HOBJECT_IS_COMPFUNC(h)) {
duk_hcompfunc *f = (duk_hcompfunc *) h;
duk_tval *tv, *tv_end;
duk_hobject **fn, **fn_end;
/* 'data' is reachable through every compiled function which
* contains a reference.
*/
duk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HCOMPFUNC_GET_DATA(heap, f));
duk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HCOMPFUNC_GET_LEXENV(heap, f));
duk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HCOMPFUNC_GET_VARENV(heap, f));
if (DUK_HCOMPFUNC_GET_DATA(heap, f) != NULL) {
tv = DUK_HCOMPFUNC_GET_CONSTS_BASE(heap, f);
tv_end = DUK_HCOMPFUNC_GET_CONSTS_END(heap, f);
while (tv < tv_end) {
duk__mark_tval(heap, tv);
tv++;
}
fn = DUK_HCOMPFUNC_GET_FUNCS_BASE(heap, f);
fn_end = DUK_HCOMPFUNC_GET_FUNCS_END(heap, f);
while (fn < fn_end) {
duk__mark_heaphdr(heap, (duk_heaphdr *) *fn);
fn++;
}
} else {
/* May happen in some out-of-memory corner cases. */
DUK_D(DUK_DPRINT("duk_hcompfunc 'data' is NULL, skipping marking"));
}
} else if (DUK_HOBJECT_IS_NATFUNC(h)) {
duk_hnatfunc *f = (duk_hnatfunc *) h;
DUK_UNREF(f);
/* nothing to mark */
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
} else if (DUK_HOBJECT_IS_BUFOBJ(h)) {
duk_hbufobj *b = (duk_hbufobj *) h;
duk__mark_heaphdr(heap, (duk_heaphdr *) b->buf);
duk__mark_heaphdr(heap, (duk_heaphdr *) b->buf_prop);
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
} else if (DUK_HOBJECT_IS_THREAD(h)) {
duk_hthread *t = (duk_hthread *) h;
duk_tval *tv;
tv = t->valstack;
while (tv < t->valstack_top) {
duk__mark_tval(heap, tv);
tv++;
}
for (i = 0; i < (duk_uint_fast32_t) t->callstack_top; i++) {
duk_activation *act = t->callstack + i;
duk__mark_heaphdr(heap, (duk_heaphdr *) DUK_ACT_GET_FUNC(act));
duk__mark_heaphdr(heap, (duk_heaphdr *) act->var_env);
duk__mark_heaphdr(heap, (duk_heaphdr *) act->lex_env);
#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)
duk__mark_heaphdr(heap, (duk_heaphdr *) act->prev_caller);
#endif
}
#if 0 /* nothing now */
for (i = 0; i < (duk_uint_fast32_t) t->catchstack_top; i++) {
duk_catcher *cat = t->catchstack + i;
//.........这里部分代码省略.........
示例8: duk__dump_type_sizes
DUK_LOCAL void duk__dump_type_sizes(void) {
DUK_D(DUK_DPRINT("sizeof()"));
/* basic platform types */
DUK__DUMPSZ(char);
DUK__DUMPSZ(short);
DUK__DUMPSZ(int);
DUK__DUMPSZ(long);
DUK__DUMPSZ(double);
DUK__DUMPSZ(void *);
DUK__DUMPSZ(size_t);
/* basic types from duk_features.h */
DUK__DUMPSZ(duk_uint8_t);
DUK__DUMPSZ(duk_int8_t);
DUK__DUMPSZ(duk_uint16_t);
DUK__DUMPSZ(duk_int16_t);
DUK__DUMPSZ(duk_uint32_t);
DUK__DUMPSZ(duk_int32_t);
DUK__DUMPSZ(duk_uint64_t);
DUK__DUMPSZ(duk_int64_t);
DUK__DUMPSZ(duk_uint_least8_t);
DUK__DUMPSZ(duk_int_least8_t);
DUK__DUMPSZ(duk_uint_least16_t);
DUK__DUMPSZ(duk_int_least16_t);
DUK__DUMPSZ(duk_uint_least32_t);
DUK__DUMPSZ(duk_int_least32_t);
#if defined(DUK_USE_64BIT_OPS)
DUK__DUMPSZ(duk_uint_least64_t);
DUK__DUMPSZ(duk_int_least64_t);
#endif
DUK__DUMPSZ(duk_uint_fast8_t);
DUK__DUMPSZ(duk_int_fast8_t);
DUK__DUMPSZ(duk_uint_fast16_t);
DUK__DUMPSZ(duk_int_fast16_t);
DUK__DUMPSZ(duk_uint_fast32_t);
DUK__DUMPSZ(duk_int_fast32_t);
#if defined(DUK_USE_64BIT_OPS)
DUK__DUMPSZ(duk_uint_fast64_t);
DUK__DUMPSZ(duk_int_fast64_t);
#endif
DUK__DUMPSZ(duk_uintptr_t);
DUK__DUMPSZ(duk_intptr_t);
DUK__DUMPSZ(duk_uintmax_t);
DUK__DUMPSZ(duk_intmax_t);
DUK__DUMPSZ(duk_double_t);
/* important chosen base types */
DUK__DUMPSZ(duk_int_t);
DUK__DUMPSZ(duk_uint_t);
DUK__DUMPSZ(duk_int_fast_t);
DUK__DUMPSZ(duk_uint_fast_t);
DUK__DUMPSZ(duk_small_int_t);
DUK__DUMPSZ(duk_small_uint_t);
DUK__DUMPSZ(duk_small_int_fast_t);
DUK__DUMPSZ(duk_small_uint_fast_t);
/* some derived types */
DUK__DUMPSZ(duk_codepoint_t);
DUK__DUMPSZ(duk_ucodepoint_t);
DUK__DUMPSZ(duk_idx_t);
DUK__DUMPSZ(duk_errcode_t);
DUK__DUMPSZ(duk_uarridx_t);
/* tval */
DUK__DUMPSZ(duk_double_union);
DUK__DUMPSZ(duk_tval);
/* structs from duk_forwdecl.h */
DUK__DUMPSZ(duk_jmpbuf);
DUK__DUMPSZ(duk_heaphdr);
DUK__DUMPSZ(duk_heaphdr_string);
DUK__DUMPSZ(duk_hstring);
DUK__DUMPSZ(duk_hstring_external);
DUK__DUMPSZ(duk_hobject);
DUK__DUMPSZ(duk_hcompiledfunction);
DUK__DUMPSZ(duk_hnativefunction);
DUK__DUMPSZ(duk_hthread);
DUK__DUMPSZ(duk_hbuffer);
DUK__DUMPSZ(duk_hbuffer_fixed);
DUK__DUMPSZ(duk_hbuffer_dynamic);
DUK__DUMPSZ(duk_propaccessor);
DUK__DUMPSZ(duk_propvalue);
DUK__DUMPSZ(duk_propdesc);
DUK__DUMPSZ(duk_heap);
#if defined(DUK_USE_STRTAB_CHAIN)
DUK__DUMPSZ(duk_strtab_entry);
#endif
DUK__DUMPSZ(duk_activation);
DUK__DUMPSZ(duk_catcher);
DUK__DUMPSZ(duk_strcache);
DUK__DUMPSZ(duk_ljstate);
DUK__DUMPSZ(duk_fixedbuffer);
DUK__DUMPSZ(duk_bitdecoder_ctx);
DUK__DUMPSZ(duk_bitencoder_ctx);
DUK__DUMPSZ(duk_token);
DUK__DUMPSZ(duk_re_token);
DUK__DUMPSZ(duk_lexer_point);
DUK__DUMPSZ(duk_lexer_ctx);
DUK__DUMPSZ(duk_compiler_instr);
//.........这里部分代码省略.........
示例9: duk_err_create_and_throw
DUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code, const char *msg, const char *filename, duk_int_t line) {
#else
DUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code) {
#endif
duk_context *ctx = (duk_context *) thr;
duk_bool_t double_error = thr->heap->handling_error;
#ifdef DUK_USE_VERBOSE_ERRORS
DUK_DD(DUK_DDPRINT("duk_err_create_and_throw(): code=%ld, msg=%s, filename=%s, line=%ld",
(long) code, (const char *) msg,
(const char *) filename, (long) line));
#else
DUK_DD(DUK_DDPRINT("duk_err_create_and_throw(): code=%ld", (long) code));
#endif
DUK_ASSERT(thr != NULL);
DUK_ASSERT(ctx != NULL);
thr->heap->handling_error = 1;
/*
* Create and push an error object onto the top of stack.
* If a "double error" occurs, use a fixed error instance
* to avoid further trouble.
*/
/* XXX: if attempt to push beyond allocated valstack, this double fault
* handling fails miserably. We should really write the double error
* directly to thr->heap->lj.value1 and avoid valstack use entirely.
*/
if (double_error) {
if (thr->builtins[DUK_BIDX_DOUBLE_ERROR]) {
DUK_D(DUK_DPRINT("double fault detected -> push built-in fixed 'double error' instance"));
duk_push_hobject_bidx(ctx, DUK_BIDX_DOUBLE_ERROR);
} else {
DUK_D(DUK_DPRINT("double fault detected; there is no built-in fixed 'double error' instance "
"-> push the error code as a number"));
duk_push_int(ctx, (duk_int_t) code);
}
} else {
/* Error object is augmented at its creation here. */
duk_require_stack(ctx, 1);
/* XXX: unnecessary '%s' formatting here, but cannot use
* 'msg' as a format string directly.
*/
#ifdef DUK_USE_VERBOSE_ERRORS
duk_push_error_object_raw(ctx,
code | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,
filename,
line,
"%s",
(const char *) msg);
#else
duk_push_error_object_raw(ctx,
code | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,
NULL,
0,
NULL);
#endif
}
/*
* Augment error (throw time), unless alloc/double error
*/
if (double_error || code == DUK_ERR_ALLOC_ERROR) {
DUK_D(DUK_DPRINT("alloc or double error: skip throw augmenting to avoid further trouble"));
} else {
#if defined(DUK_USE_AUGMENT_ERROR_THROW)
DUK_DDD(DUK_DDDPRINT("THROW ERROR (INTERNAL): %!iT (before throw augment)",
(duk_tval *) duk_get_tval(ctx, -1)));
duk_err_augment_error_throw(thr);
#endif
}
/*
* Finally, longjmp
*/
thr->heap->handling_error = 0;
duk_err_setup_heap_ljstate(thr, DUK_LJ_TYPE_THROW);
DUK_DDD(DUK_DDDPRINT("THROW ERROR (INTERNAL): %!iT, %!iT (after throw augment)",
(duk_tval *) &thr->heap->lj.value1, (duk_tval *) &thr->heap->lj.value2));
duk_err_longjmp(thr);
DUK_UNREACHABLE();
}
示例10: DUK_ASSERT
void *duk_heap_mem_realloc(duk_heap *heap, void *ptr, size_t newsize) {
void *res;
int rc;
int i;
DUK_ASSERT(heap != NULL);
/* ptr may be NULL */
DUK_ASSERT_DISABLE(newsize >= 0);
/*
* Voluntary periodic GC (if enabled)
*/
DUK__VOLUNTARY_PERIODIC_GC(heap);
/*
* First attempt
*/
#ifdef DUK_USE_GC_TORTURE
/* simulate alloc failure on every realloc (except when mark-and-sweep is running) */
if (!DUK_HEAP_HAS_MARKANDSWEEP_RUNNING(heap)) {
DUK_DDD(DUK_DDDPRINT("gc torture enabled, pretend that first realloc attempt fails"));
res = NULL;
DUK_UNREF(res);
goto skip_attempt;
}
#endif
res = heap->realloc_func(heap->alloc_udata, ptr, newsize);
if (res || newsize == 0) {
/* for zero size allocations NULL is allowed */
return res;
}
#ifdef DUK_USE_GC_TORTURE
skip_attempt:
#endif
DUK_D(DUK_DPRINT("first realloc attempt failed, attempt to gc and retry"));
/*
* Avoid a GC if GC is already running. See duk_heap_mem_alloc().
*/
if (DUK_HEAP_HAS_MARKANDSWEEP_RUNNING(heap)) {
DUK_D(DUK_DPRINT("duk_heap_mem_realloc() failed, gc in progress (gc skipped), alloc size %d", newsize));
return NULL;
}
/*
* Retry with several GC attempts. Initial attempts are made without
* emergency mode; later attempts use emergency mode which minimizes
* memory allocations forcibly.
*/
for (i = 0; i < DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_LIMIT; i++) {
int flags;
flags = 0;
if (i >= DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_EMERGENCY_LIMIT - 1) {
flags |= DUK_MS_FLAG_EMERGENCY;
}
rc = duk_heap_mark_and_sweep(heap, flags);
DUK_UNREF(rc);
res = heap->realloc_func(heap->alloc_udata, ptr, newsize);
if (res) {
DUK_D(DUK_DPRINT("duk_heap_mem_realloc() succeeded after gc (pass %d), alloc size %d",
i + 1, newsize));
return res;
}
}
DUK_D(DUK_DPRINT("duk_heap_mem_realloc() failed even after gc, alloc size %d", newsize));
return NULL;
}
示例11: duk_regexp_compile
DUK_INTERNAL void duk_regexp_compile(duk_hthread *thr) {
duk_context *ctx = (duk_context *) thr;
duk_re_compiler_ctx re_ctx;
duk_lexer_point lex_point;
duk_hstring *h_pattern;
duk_hstring *h_flags;
duk__re_disjunction_info ign_disj;
DUK_ASSERT(thr != NULL);
DUK_ASSERT(ctx != NULL);
/*
* Args validation
*/
/* TypeError if fails */
h_pattern = duk_require_hstring(ctx, -2);
h_flags = duk_require_hstring(ctx, -1);
/*
* Create normalized 'source' property (E5 Section 15.10.3).
*/
/* [ ... pattern flags ] */
duk__create_escaped_source(thr, -2);
/* [ ... pattern flags escaped_source ] */
/*
* Init compilation context
*/
/* [ ... pattern flags escaped_source buffer ] */
DUK_MEMZERO(&re_ctx, sizeof(re_ctx));
DUK_LEXER_INITCTX(&re_ctx.lex); /* duplicate zeroing, expect for (possible) NULL inits */
re_ctx.thr = thr;
re_ctx.lex.thr = thr;
re_ctx.lex.input = DUK_HSTRING_GET_DATA(h_pattern);
re_ctx.lex.input_length = DUK_HSTRING_GET_BYTELEN(h_pattern);
re_ctx.lex.token_limit = DUK_RE_COMPILE_TOKEN_LIMIT;
re_ctx.recursion_limit = DUK_USE_REGEXP_COMPILER_RECLIMIT;
re_ctx.re_flags = duk__parse_regexp_flags(thr, h_flags);
DUK_BW_INIT_PUSHBUF(thr, &re_ctx.bw, DUK__RE_INITIAL_BUFSIZE);
DUK_DD(DUK_DDPRINT("regexp compiler ctx initialized, flags=0x%08lx, recursion_limit=%ld",
(unsigned long) re_ctx.re_flags, (long) re_ctx.recursion_limit));
/*
* Init lexer
*/
lex_point.offset = 0; /* expensive init, just want to fill window */
lex_point.line = 1;
DUK_LEXER_SETPOINT(&re_ctx.lex, &lex_point);
/*
* Compilation
*/
DUK_D(DUK_DPRINT("starting regexp compilation"));
duk__append_u32(&re_ctx, DUK_REOP_SAVE);
duk__append_u32(&re_ctx, 0);
duk__parse_disjunction(&re_ctx, 1 /*expect_eof*/, &ign_disj);
duk__append_u32(&re_ctx, DUK_REOP_SAVE);
duk__append_u32(&re_ctx, 1);
duk__append_u32(&re_ctx, DUK_REOP_MATCH);
/*
* Check for invalid backreferences; note that it is NOT an error
* to back-reference a capture group which has not yet been introduced
* in the pattern (as in /\1(foo)/); in fact, the backreference will
* always match! It IS an error to back-reference a capture group
* which will never be introduced in the pattern. Thus, we can check
* for such references only after parsing is complete.
*/
if (re_ctx.highest_backref > re_ctx.captures) {
DUK_ERROR(thr, DUK_ERR_SYNTAX_ERROR, DUK_STR_INVALID_BACKREFS);
}
/*
* Emit compiled regexp header: flags, ncaptures
* (insertion order inverted on purpose)
*/
duk__insert_u32(&re_ctx, 0, (re_ctx.captures + 1) * 2);
duk__insert_u32(&re_ctx, 0, re_ctx.re_flags);
/* [ ... pattern flags escaped_source buffer ] */
DUK_BW_COMPACT(thr, &re_ctx.bw);
duk_to_string(ctx, -1); /* coerce to string */
/* [ ... pattern flags escaped_source bytecode ] */
/*
//.........这里部分代码省略.........
示例12: duk__free_stringtable
DUK_LOCAL void duk__free_stringtable(duk_heap *heap) {
duk_uint_fast32_t i;
/* strings are only tracked by stringtable */
#if defined(DUK_USE_HEAPPTR16)
if (heap->strtable16) {
#else
if (heap->strtable) {
#endif
for (i = 0; i < (duk_uint_fast32_t) heap->st_size; i++) {
duk_hstring *e;
#if defined(DUK_USE_HEAPPTR16)
e = (duk_hstring *) DUK_USE_HEAPPTR_DEC16(heap->strtable16[i]);
#else
e = heap->strtable[i];
#endif
if (e == NULL || e == DUK_STRTAB_DELETED_MARKER(heap)) {
continue;
}
DUK_ASSERT(e != NULL);
/* strings may have inner refs (extdata) in some cases */
duk_free_hstring_inner(heap, (duk_hstring *) e);
DUK_DDD(DUK_DDDPRINT("FINALFREE (string): %!iO",
(duk_heaphdr *) e));
DUK_FREE(heap, e);
#if 0 /* not strictly necessary */
heap->strtable[i] = NULL;
#endif
}
#if defined(DUK_USE_HEAPPTR16)
DUK_FREE(heap, heap->strtable16);
#else
DUK_FREE(heap, heap->strtable);
#endif
#if 0 /* not strictly necessary */
heap->strtable = NULL;
#endif
}
}
DUK_LOCAL void duk__free_run_finalizers(duk_heap *heap) {
duk_hthread *thr;
duk_heaphdr *curr;
#ifdef DUK_USE_DEBUG
duk_size_t count_obj = 0;
#endif
DUK_ASSERT(heap != NULL);
DUK_ASSERT(heap->heap_thread != NULL);
#ifdef DUK_USE_REFERENCE_COUNTING
DUK_ASSERT(heap->refzero_list == NULL); /* refzero not running -> must be empty */
#endif
#ifdef DUK_USE_MARK_AND_SWEEP
DUK_ASSERT(heap->finalize_list == NULL); /* mark-and-sweep not running -> must be empty */
#endif
/* XXX: here again finalizer thread is the heap_thread which needs
* to be coordinated with finalizer thread fixes.
*/
thr = heap->heap_thread;
DUK_ASSERT(thr != NULL);
curr = heap->heap_allocated;
while (curr) {
if (DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT) {
/* Only objects in heap_allocated may have finalizers. Check that
* the object itself has a _Finalizer property so that we don't
* execute finalizers for e.g. Proxy objects.
*/
DUK_ASSERT(thr != NULL);
DUK_ASSERT(curr != NULL);
if (duk_hobject_hasprop_raw(thr, (duk_hobject *) curr, DUK_HTHREAD_STRING_INT_FINALIZER(thr))) {
duk_hobject_run_finalizer(thr, (duk_hobject *) curr);
}
#ifdef DUK_USE_DEBUG
count_obj++;
#endif
}
curr = DUK_HEAPHDR_GET_NEXT(curr);
}
/* Note: count includes all objects, not only those with an actual finalizer. */
#ifdef DUK_USE_DEBUG
DUK_D(DUK_DPRINT("checked %ld objects for finalizers before freeing heap", (long) count_obj));
#endif
}
示例13: duk__sweep_stringtable_probe
DUK_LOCAL void duk__sweep_stringtable_probe(duk_heap *heap, duk_size_t *out_count_keep) {
duk_hstring *h;
duk_uint_fast32_t i;
#ifdef DUK_USE_DEBUG
duk_size_t count_free = 0;
#endif
duk_size_t count_keep = 0;
DUK_DD(DUK_DDPRINT("duk__sweep_stringtable: %p", (void *) heap));
for (i = 0; i < heap->st_size; i++) {
#if defined(DUK_USE_HEAPPTR16)
h = (duk_hstring *) DUK_USE_HEAPPTR_DEC16(heap->heap_udata, heap->strtable16[i]);
#else
h = heap->strtable[i];
#endif
if (h == NULL || h == DUK_STRTAB_DELETED_MARKER(heap)) {
continue;
} else if (DUK_HEAPHDR_HAS_REACHABLE((duk_heaphdr *) h)) {
DUK_HEAPHDR_CLEAR_REACHABLE((duk_heaphdr *) h);
count_keep++;
continue;
}
#ifdef DUK_USE_DEBUG
count_free++;
#endif
#if defined(DUK_USE_REFERENCE_COUNTING)
/* Non-zero refcounts should not happen for unreachable strings,
* because we refcount finalize all unreachable objects which
* should have decreased unreachable string refcounts to zero
* (even for cycles).
*/
DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) == 0);
#endif
DUK_DDD(DUK_DDDPRINT("sweep string, not reachable: %p", (void *) h));
/* deal with weak references first */
duk_heap_strcache_string_remove(heap, (duk_hstring *) h);
/* remove the string (mark DELETED), could also call
* duk_heap_string_remove() but that would be slow and
* pointless because we already know the slot.
*/
#if defined(DUK_USE_HEAPPTR16)
heap->strtable16[i] = heap->heapptr_deleted16;
#else
heap->strtable[i] = DUK_STRTAB_DELETED_MARKER(heap);
#endif
/* free inner references (these exist e.g. when external
* strings are enabled)
*/
duk_free_hstring_inner(heap, (duk_hstring *) h);
/* finally free the struct itself */
DUK_FREE(heap, h);
}
#ifdef DUK_USE_DEBUG
DUK_D(DUK_DPRINT("mark-and-sweep sweep stringtable: %ld freed, %ld kept",
(long) count_free, (long) count_keep));
#endif
*out_count_keep = count_keep;
}
示例14: duk_hthread_create_builtin_objects
DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
duk_context *ctx = (duk_context *) thr;
duk_bitdecoder_ctx bd_ctx;
duk_bitdecoder_ctx *bd = &bd_ctx; /* convenience */
duk_hobject *h;
duk_small_uint_t i, j;
DUK_D(DUK_DPRINT("INITBUILTINS BEGIN"));
DUK_MEMZERO(&bd_ctx, sizeof(bd_ctx));
bd->data = (const duk_uint8_t *) duk_builtins_data;
bd->length = (duk_size_t) DUK_BUILTINS_DATA_LENGTH;
/*
* First create all built-in bare objects on the empty valstack.
* During init, their indices will correspond to built-in indices.
*
* Built-ins will be reachable from both valstack and thr->builtins.
*/
/* XXX: there is no need to resize valstack because builtin count
* is much less than the default space; assert for it.
*/
DUK_DD(DUK_DDPRINT("create empty built-ins"));
DUK_ASSERT_TOP(ctx, 0);
for (i = 0; i < DUK_NUM_BUILTINS; i++) {
duk_small_uint_t class_num;
duk_small_int_t len = -1; /* must be signed */
class_num = (duk_small_uint_t) duk_bd_decode(bd, DUK__CLASS_BITS);
len = (duk_small_int_t) duk_bd_decode_flagged(bd, DUK__LENGTH_PROP_BITS, (duk_int32_t) -1 /*def_value*/);
if (class_num == DUK_HOBJECT_CLASS_FUNCTION) {
duk_small_uint_t natidx;
duk_small_uint_t stridx;
duk_int_t c_nargs; /* must hold DUK_VARARGS */
duk_c_function c_func;
duk_int16_t magic;
DUK_DDD(DUK_DDDPRINT("len=%ld", (long) len));
DUK_ASSERT(len >= 0);
natidx = (duk_small_uint_t) duk_bd_decode(bd, DUK__NATIDX_BITS);
stridx = (duk_small_uint_t) duk_bd_decode(bd, DUK__STRIDX_BITS);
c_func = duk_bi_native_functions[natidx];
c_nargs = (duk_small_uint_t) duk_bd_decode_flagged(bd, DUK__NARGS_BITS, len /*def_value*/);
if (c_nargs == DUK__NARGS_VARARGS_MARKER) {
c_nargs = DUK_VARARGS;
}
/* XXX: set magic directly here? (it could share the c_nargs arg) */
duk_push_c_function_noexotic(ctx, c_func, c_nargs);
h = duk_require_hobject(ctx, -1);
DUK_ASSERT(h != NULL);
/* Currently all built-in native functions are strict.
* duk_push_c_function() now sets strict flag, so
* assert for it.
*/
DUK_ASSERT(DUK_HOBJECT_HAS_STRICT(h));
/* XXX: function properties */
duk_push_hstring_stridx(ctx, stridx);
duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_NONE);
/* Almost all global level Function objects are constructable
* but not all: Function.prototype is a non-constructable,
* callable Function.
*/
if (duk_bd_decode_flag(bd)) {
DUK_ASSERT(DUK_HOBJECT_HAS_CONSTRUCTABLE(h));
} else {
DUK_HOBJECT_CLEAR_CONSTRUCTABLE(h);
}
/* Cast converts magic to 16-bit signed value */
magic = (duk_int16_t) duk_bd_decode_flagged(bd, DUK__MAGIC_BITS, 0 /*def_value*/);
((duk_hnativefunction *) h)->magic = magic;
} else {
/* XXX: ARRAY_PART for Array prototype? */
duk_push_object_helper(ctx,
DUK_HOBJECT_FLAG_EXTENSIBLE,
-1); /* no prototype or class yet */
h = duk_require_hobject(ctx, -1);
DUK_ASSERT(h != NULL);
}
DUK_HOBJECT_SET_CLASS_NUMBER(h, class_num);
thr->builtins[i] = h;
DUK_HOBJECT_INCREF(thr, &h->hdr);
if (len >= 0) {
/*
//.........这里部分代码省略.........
示例15: duk_hthread_create_builtin_objects
void duk_hthread_create_builtin_objects(duk_hthread *thr) {
duk_context *ctx = (duk_context *) thr;
duk_bitdecoder_ctx bd_ctx;
duk_bitdecoder_ctx *bd = &bd_ctx; /* convenience */
duk_hobject *h;
int i, j;
DUK_DPRINT("INITBUILTINS BEGIN");
DUK_MEMZERO(&bd_ctx, sizeof(bd_ctx));
bd->data = (const duk_uint8_t *) duk_builtins_data;
bd->length = (duk_size_t) DUK_BUILTINS_DATA_LENGTH;
/*
* First create all built-in bare objects on the empty valstack.
* During init, their indices will correspond to built-in indices.
*
* Built-ins will be reachable from both valstack and thr->builtins.
*/
/* XXX: there is no need to resize valstack because builtin count
* is much less than the default space; assert for it.
*/
DUK_DDPRINT("create empty built-ins");
DUK_ASSERT_TOP(ctx, 0);
for (i = 0; i < DUK_NUM_BUILTINS; i++) {
int class_num;
int len = -1;
class_num = duk_bd_decode(bd, DUK__CLASS_BITS);
len = duk_bd_decode_flagged(bd, DUK__LENGTH_PROP_BITS, (duk_int32_t) -1 /*def_value*/);
if (class_num == DUK_HOBJECT_CLASS_FUNCTION) {
int natidx;
int stridx;
int c_nargs;
duk_c_function c_func;
duk_int16_t magic;
DUK_DDDPRINT("len=%d", len);
DUK_ASSERT(len >= 0);
natidx = duk_bd_decode(bd, DUK__NATIDX_BITS);
stridx = duk_bd_decode(bd, DUK__STRIDX_BITS);
c_func = duk_bi_native_functions[natidx];
c_nargs = duk_bd_decode_flagged(bd, DUK__NARGS_BITS, len /*def_value*/);
if (c_nargs == DUK__NARGS_VARARGS_MARKER) {
c_nargs = DUK_VARARGS;
}
/* FIXME: set magic directly here? (it could share the c_nargs arg) */
duk_push_c_function_nospecial(ctx, c_func, c_nargs);
h = duk_require_hobject(ctx, -1);
DUK_ASSERT(h != NULL);
/* Currently all built-in native functions are strict.
* duk_push_c_function() now sets strict flag, so
* assert for it.
*/
DUK_ASSERT(DUK_HOBJECT_HAS_STRICT(h));
/* FIXME: function properties */
duk_push_hstring_stridx(ctx, stridx);
duk_def_prop_stridx(ctx, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_NONE);
/* Almost all global level Function objects are constructable
* but not all: Function.prototype is a non-constructable,
* callable Function.
*/
if (duk_bd_decode_flag(bd)) {
DUK_ASSERT(DUK_HOBJECT_HAS_CONSTRUCTABLE(h));
} else {
DUK_HOBJECT_CLEAR_CONSTRUCTABLE(h);
}
/* Cast converts magic to 16-bit signed value */
magic = (duk_int16_t) duk_bd_decode_flagged(bd, DUK__MAGIC_BITS, 0 /*def_value*/);
((duk_hnativefunction *) h)->magic = magic;
} else {
/* FIXME: ARRAY_PART for Array prototype? */
duk_push_object_helper(ctx,
DUK_HOBJECT_FLAG_EXTENSIBLE,
-1); /* no prototype or class yet */
h = duk_require_hobject(ctx, -1);
DUK_ASSERT(h != NULL);
}
DUK_HOBJECT_SET_CLASS_NUMBER(h, class_num);
thr->builtins[i] = h;
DUK_HOBJECT_INCREF(thr, &h->hdr);
if (len >= 0) {
/*
//.........这里部分代码省略.........