本文整理汇总了C++中DUK_HSTRING_GET_BYTELEN函数的典型用法代码示例。如果您正苦于以下问题:C++ DUK_HSTRING_GET_BYTELEN函数的具体用法?C++ DUK_HSTRING_GET_BYTELEN怎么用?C++ DUK_HSTRING_GET_BYTELEN使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了DUK_HSTRING_GET_BYTELEN函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: DUK_REALLOC
/* Overflow, relevant mainly when listlen is 16 bits. */
return 1; /* fail */
}
new_lst = (duk_hstring **) DUK_REALLOC(heap, e->u.strlist, sizeof(duk_hstring *) * (e->listlen + 1));
if (new_lst == NULL) {
return 1; /* fail */
}
new_lst[e->listlen++] = h;
e->u.strlist = new_lst;
}
return 0;
}
#endif /* DUK_USE_HEAPPTR16 */
#if defined(DUK_USE_HEAPPTR16)
DUK_LOCAL duk_hstring *duk__find_matching_string_chain(duk_heap *heap, const duk_uint8_t *str, duk_uint32_t blen, duk_uint32_t strhash) {
duk_small_uint_t slotidx;
duk_strtab_entry *e;
duk_uint16_t *lst;
duk_size_t i, n;
duk_uint16_t null16 = heap->heapptr_null16;
DUK_ASSERT(heap != NULL);
slotidx = strhash % DUK_STRTAB_CHAIN_SIZE;
DUK_ASSERT(slotidx < DUK_STRTAB_CHAIN_SIZE);
e = heap->strtable + slotidx;
if (e->listlen == 0) {
if (e->u.str16 != null16) {
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((const void *) str, (const void *) DUK_HSTRING_GET_DATA(h), (size_t) blen) == 0) {
return h;
}
}
} else {
DUK_ASSERT(e->u.strlist16 != null16);
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(heap->heap_udata, lst[i]);
DUK_ASSERT(h != NULL);
if (DUK_HSTRING_GET_BYTELEN(h) == blen &&
DUK_MEMCMP((const void *) str, (const void *) DUK_HSTRING_GET_DATA(h), (size_t) blen) == 0) {
return h;
}
}
}
}
return NULL;
}
#else /* DUK_USE_HEAPPTR16 */
DUK_LOCAL duk_hstring *duk__find_matching_string_chain(duk_heap *heap, const duk_uint8_t *str, duk_uint32_t blen, duk_uint32_t strhash) {
duk_small_uint_t slotidx;
duk_strtab_entry *e;
duk_hstring **lst;
duk_size_t i, n;
DUK_ASSERT(heap != NULL);
slotidx = strhash % DUK_STRTAB_CHAIN_SIZE;
DUK_ASSERT(slotidx < DUK_STRTAB_CHAIN_SIZE);
e = heap->strtable + slotidx;
if (e->listlen == 0) {
if (e->u.str != NULL &&
DUK_HSTRING_GET_BYTELEN(e->u.str) == blen &&
DUK_MEMCMP((const void *) str, (const void *) DUK_HSTRING_GET_DATA(e->u.str), (size_t) blen) == 0) {
return e->u.str;
}
} else {
DUK_ASSERT(e->u.strlist != NULL);
lst = e->u.strlist;
for (i = 0, n = e->listlen; i < n; i++) {
if (lst[i] != NULL &&
DUK_HSTRING_GET_BYTELEN(lst[i]) == blen &&
DUK_MEMCMP((const void *) str, (const void *) DUK_HSTRING_GET_DATA(lst[i]), (size_t) blen) == 0) {
return lst[i];
}
}
}
return NULL;
}
示例2: duk_hstring_char_code_at_raw
DUK_INTERNAL duk_ucodepoint_t duk_hstring_char_code_at_raw(duk_hthread *thr, duk_hstring *h, duk_uint_t pos) {
duk_uint32_t boff;
const duk_uint8_t *p, *p_start, *p_end;
duk_ucodepoint_t cp;
/* Caller must check character offset to be inside the string. */
DUK_ASSERT(thr != NULL);
DUK_ASSERT(h != NULL);
DUK_ASSERT_DISABLE(pos >= 0); /* unsigned */
DUK_ASSERT(pos < (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h));
boff = duk_heap_strcache_offset_char2byte(thr, h, (duk_uint32_t) pos);
DUK_DDD(DUK_DDDPRINT("charCodeAt: pos=%ld -> boff=%ld, str=%!O",
(long) pos, (long) boff, (duk_heaphdr *) h));
DUK_ASSERT_DISABLE(boff >= 0);
DUK_ASSERT(boff < DUK_HSTRING_GET_BYTELEN(h));
p_start = DUK_HSTRING_GET_DATA(h);
p_end = p_start + DUK_HSTRING_GET_BYTELEN(h);
p = p_start + boff;
DUK_DDD(DUK_DDDPRINT("p_start=%p, p_end=%p, p=%p",
(void *) p_start, (void *) p_end, (void *) p));
/* This may throw an error though not for valid E5 strings. */
cp = duk_unicode_decode_xutf8_checked(thr, &p, p_start, p_end);
return cp;
}
示例3: duk_bi_string_prototype_locale_compare
DUK_INTERNAL duk_ret_t duk_bi_string_prototype_locale_compare(duk_context *ctx) {
duk_hstring *h1;
duk_hstring *h2;
duk_size_t h1_len, h2_len, prefix_len;
duk_small_int_t ret = 0;
duk_small_int_t rc;
/* The current implementation of localeCompare() is simply a codepoint
* by codepoint comparison, implemented with a simple string compare
* because UTF-8 should preserve codepoint ordering (assuming valid
* shortest UTF-8 encoding).
*
* The specification requires that the return value must be related
* to the sort order: e.g. negative means that 'this' comes before
* 'that' in sort order. We assume an ascending sort order.
*/
/* XXX: could share code with duk_js_ops.c, duk_js_compare_helper */
h1 = duk_push_this_coercible_to_string(ctx);
DUK_ASSERT(h1 != NULL);
h2 = duk_to_hstring(ctx, 0);
DUK_ASSERT(h2 != NULL);
h1_len = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h1);
h2_len = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h2);
prefix_len = (h1_len <= h2_len ? h1_len : h2_len);
/* Zero size compare not an issue with DUK_MEMCMP. */
rc = (duk_small_int_t) DUK_MEMCMP((const char *) DUK_HSTRING_GET_DATA(h1),
(const char *) DUK_HSTRING_GET_DATA(h2),
prefix_len);
if (rc < 0) {
ret = -1;
goto done;
} else if (rc > 0) {
ret = 1;
goto done;
}
/* prefix matches, lengths matter now */
if (h1_len > h2_len) {
ret = 1;
goto done;
} else if (h1_len == h2_len) {
DUK_ASSERT(ret == 0);
goto done;
}
ret = -1;
goto done;
done:
duk_push_int(ctx, (duk_int_t) ret);
return 1;
}
示例4: duk_js_string_compare
DUK_INTERNAL duk_small_int_t duk_js_string_compare(duk_hstring *h1, duk_hstring *h2) {
/*
* String comparison (E5 Section 11.8.5, step 4), which
* needs to compare codepoint by codepoint.
*
* However, UTF-8 allows us to use strcmp directly: the shared
* prefix will be encoded identically (UTF-8 has unique encoding)
* and the first differing character can be compared with a simple
* unsigned byte comparison (which strcmp does).
*
* This will not work properly for non-xutf-8 strings, but this
* is not an issue for compliance.
*/
duk_size_t h1_len, h2_len, prefix_len;
duk_small_int_t rc;
DUK_ASSERT(h1 != NULL);
DUK_ASSERT(h2 != NULL);
h1_len = DUK_HSTRING_GET_BYTELEN(h1);
h2_len = DUK_HSTRING_GET_BYTELEN(h2);
prefix_len = (h1_len <= h2_len ? h1_len : h2_len);
/* XXX: this special case can now be removed with DUK_MEMCMP */
/* memcmp() should return zero (equal) for zero length, but avoid
* it because there are some platform specific bugs. Don't use
* strncmp() because it stops comparing at a NUL.
*/
if (prefix_len == 0) {
rc = 0;
} else {
rc = DUK_MEMCMP((const char *) DUK_HSTRING_GET_DATA(h1),
(const char *) DUK_HSTRING_GET_DATA(h2),
prefix_len);
}
if (rc < 0) {
return -1;
} else if (rc > 0) {
return 1;
}
/* prefix matches, lengths matter now */
if (h1_len < h2_len) {
/* e.g. "x" < "xx" */
return -1;
} else if (h1_len > h2_len) {
return 1;
}
return 0;
}
示例5: DUK_ASSERT
static duk_hstring *duk__find_matching_string(duk_heap *heap, duk_hstring **entries, duk_uint32_t size, duk_uint8_t *str, duk_uint32_t blen, duk_uint32_t strhash) {
duk_uint32_t i;
duk_uint32_t step;
DUK_ASSERT(size > 0);
i = DUK__HASH_INITIAL(strhash, size);
step = DUK__HASH_PROBE_STEP(strhash);
for (;;) {
duk_hstring *e;
e = entries[i];
if (!e) {
return NULL;
}
if (e != DUK__DELETED_MARKER(heap) && DUK_HSTRING_GET_BYTELEN(e) == blen) {
if (DUK_MEMCMP(str, DUK_HSTRING_GET_DATA(e), blen) == 0) {
DUK_DDD(DUK_DDDPRINT("find matching hit: %d (step %d, size %d)", i, step, size));
return e;
}
}
DUK_DDD(DUK_DDDPRINT("find matching miss: %d (step %d, size %d)", i, step, size));
i = (i + step) % size;
/* looping should never happen */
DUK_ASSERT(i != DUK__HASH_INITIAL(strhash, size));
}
DUK_UNREACHABLE();
}
示例6: duk__print_hstring
DUK_LOCAL void duk__print_hstring(duk__dprint_state *st, duk_hstring *h, duk_bool_t quotes) {
duk_fixedbuffer *fb = st->fb;
const duk_uint8_t *p;
const duk_uint8_t *p_end;
/* terminal type: no depth check */
if (duk_fb_is_full(fb)) {
return;
}
duk__print_shared_heaphdr_string(st, &h->hdr);
if (!h) {
duk_fb_put_cstring(fb, "NULL");
return;
}
p = DUK_HSTRING_GET_DATA(h);
p_end = p + DUK_HSTRING_GET_BYTELEN(h);
if (p_end > p && p[0] == DUK_ASC_UNDERSCORE) {
/* if property key begins with underscore, encode it with
* forced quotes (e.g. "_Foo") to distinguish it from encoded
* internal properties (e.g. \xffBar -> _Bar).
*/
quotes = 1;
}
if (quotes) {
duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_DOUBLEQUOTE);
}
while (p < p_end) {
duk_uint8_t ch = *p++;
/* two special escapes: '\' and '"', other printables as is */
if (ch == '\\') {
duk_fb_sprintf(fb, "\\\\");
} else if (ch == '"') {
duk_fb_sprintf(fb, "\\\"");
} else if (ch >= 0x20 && ch <= 0x7e) {
duk_fb_put_byte(fb, ch);
} else if (ch == 0xff && !quotes) {
/* encode \xffBar as _Bar if no quotes are applied, this is for
* readable internal keys.
*/
duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_UNDERSCORE);
} else {
duk_fb_sprintf(fb, "\\x%02lx", (unsigned long) ch);
}
}
if (quotes) {
duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_DOUBLEQUOTE);
}
#if defined(DUK_USE_REFERENCE_COUNTING)
/* XXX: limit to quoted strings only, to save keys from being cluttered? */
duk_fb_sprintf(fb, "/%lu", (unsigned long) DUK_HEAPHDR_GET_REFCOUNT(&h->hdr));
#endif
}
示例7: DUK_ALLOC
static duk_hstring *duk__alloc_init_hstring(duk_heap *heap,
duk_uint8_t *str,
duk_uint32_t blen,
duk_uint32_t strhash) {
duk_hstring *res = NULL;
duk_uint8_t *data;
duk_size_t alloc_size;
duk_uarridx_t dummy;
/* NUL terminate for convenient C access */
alloc_size = (duk_size_t) (sizeof(duk_hstring) + blen + 1);
res = (duk_hstring *) DUK_ALLOC(heap, alloc_size);
if (!res) {
goto error;
}
DUK_MEMZERO(res, sizeof(duk_hstring));
#ifdef DUK_USE_EXPLICIT_NULL_INIT
DUK_HEAPHDR_STRING_INIT_NULLS(&res->hdr);
#endif
DUK_HEAPHDR_SET_TYPE_AND_FLAGS(&res->hdr, DUK_HTYPE_STRING, 0);
if (duk_js_to_arrayindex_raw_string(str, blen, &dummy)) {
DUK_HSTRING_SET_ARRIDX(res);
}
/* All strings beginning with 0xff are treated as "internal",
* even strings interned by the user. This allows user code to
* create internal properties too, and makes behavior consistent
* in case user code happens to use a string also used by Duktape
* (such as string has already been interned and has the 'internal'
* flag set).
*/
if (blen > 0 && str[0] == (duk_uint8_t) 0xff) {
DUK_HSTRING_SET_INTERNAL(res);
}
res->hash = strhash;
res->blen = blen;
res->clen = (duk_uint32_t) duk_unicode_unvalidated_utf8_length(str, (duk_size_t) blen); /* clen <= blen */
data = (duk_uint8_t *) (res + 1);
DUK_MEMCPY(data, str, blen);
data[blen] = (duk_uint8_t) 0;
DUK_DDD(DUK_DDDPRINT("interned string, hash=0x%08lx, blen=%ld, clen=%ld, has_arridx=%ld",
(unsigned long) DUK_HSTRING_GET_HASH(res),
(long) DUK_HSTRING_GET_BYTELEN(res),
(long) DUK_HSTRING_GET_CHARLEN(res),
(long) DUK_HSTRING_HAS_ARRIDX(res) ? 1 : 0));
return res;
error:
DUK_FREE(heap, res);
return NULL;
}
示例8: duk_hbuffer_append_hstring
size_t duk_hbuffer_append_hstring(duk_hthread *thr, duk_hbuffer_dynamic *buf, duk_hstring *str) {
size_t len;
DUK_ASSERT(thr != NULL);
DUK_ASSERT(buf != NULL);
DUK_ASSERT(str != NULL);
DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(buf));
len = DUK_HSTRING_GET_BYTELEN(str);
duk_hbuffer_insert_bytes(thr, buf, DUK_HBUFFER_GET_SIZE(buf), (duk_uint8_t *) DUK_HSTRING_GET_DATA(str), len);
return len;
}
示例9: duk_js_toboolean
DUK_INTERNAL duk_bool_t duk_js_toboolean(duk_tval *tv) {
switch (DUK_TVAL_GET_TAG(tv)) {
case DUK_TAG_UNDEFINED:
case DUK_TAG_NULL:
return 0;
case DUK_TAG_BOOLEAN:
return DUK_TVAL_GET_BOOLEAN(tv);
case DUK_TAG_STRING: {
duk_hstring *h = DUK_TVAL_GET_STRING(tv);
DUK_ASSERT(h != NULL);
return (DUK_HSTRING_GET_BYTELEN(h) > 0 ? 1 : 0);
}
case DUK_TAG_OBJECT: {
return 1;
}
case DUK_TAG_BUFFER: {
/* mimic semantics for strings */
duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);
DUK_ASSERT(h != NULL);
return (DUK_HBUFFER_GET_SIZE(h) > 0 ? 1 : 0);
}
case DUK_TAG_POINTER: {
void *p = DUK_TVAL_GET_POINTER(tv);
return (p != NULL ? 1 : 0);
}
case DUK_TAG_LIGHTFUNC: {
return 1;
}
#if defined(DUK_USE_FASTINT)
case DUK_TAG_FASTINT:
if (DUK_TVAL_GET_FASTINT(tv) != 0) {
return 1;
} else {
return 0;
}
#endif
default: {
/* number */
duk_double_t d;
int c;
DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));
DUK_ASSERT(DUK_TVAL_IS_DOUBLE(tv));
d = DUK_TVAL_GET_DOUBLE(tv);
c = DUK_FPCLASSIFY((double) d);
if (c == DUK_FP_ZERO || c == DUK_FP_NAN) {
return 0;
} else {
return 1;
}
}
}
DUK_UNREACHABLE();
}
示例10: DUK_ASSERT
DUK_LOCAL duk_hstring *duk__find_matching_string_chain(duk_heap *heap, const duk_uint8_t *str, duk_uint32_t blen, duk_uint32_t strhash) {
duk_small_uint_t slotidx;
duk_strtab_entry *e;
duk_uint16_t *lst;
duk_size_t i, n;
duk_uint16_t null16 = heap->heapptr_null16;
DUK_ASSERT(heap != NULL);
slotidx = strhash % DUK_STRTAB_CHAIN_SIZE;
DUK_ASSERT(slotidx < DUK_STRTAB_CHAIN_SIZE);
e = heap->strtable + slotidx;
if (e->listlen == 0) {
if (e->u.str16 != null16) {
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((const void *) str, (const void *) DUK_HSTRING_GET_DATA(h), (size_t) blen) == 0) {
return h;
}
}
} else {
DUK_ASSERT(e->u.strlist16 != null16);
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(heap->heap_udata, lst[i]);
DUK_ASSERT(h != NULL);
if (DUK_HSTRING_GET_BYTELEN(h) == blen &&
DUK_MEMCMP((const void *) str, (const void *) DUK_HSTRING_GET_DATA(h), (size_t) blen) == 0) {
return h;
}
}
}
}
return NULL;
}
示例11: duk_js_string_compare
DUK_INTERNAL duk_small_int_t duk_js_string_compare(duk_hstring *h1, duk_hstring *h2) {
/*
* String comparison (E5 Section 11.8.5, step 4), which
* needs to compare codepoint by codepoint.
*
* However, UTF-8 allows us to use strcmp directly: the shared
* prefix will be encoded identically (UTF-8 has unique encoding)
* and the first differing character can be compared with a simple
* unsigned byte comparison (which strcmp does).
*
* This will not work properly for non-xutf-8 strings, but this
* is not an issue for compliance.
*/
DUK_ASSERT(h1 != NULL);
DUK_ASSERT(h2 != NULL);
return duk_js_data_compare((const duk_uint8_t *) DUK_HSTRING_GET_DATA(h1),
(const duk_uint8_t *) DUK_HSTRING_GET_DATA(h2),
(duk_size_t) DUK_HSTRING_GET_BYTELEN(h1),
(duk_size_t) DUK_HSTRING_GET_BYTELEN(h2));
}
示例12: duk_regexp_create_instance
DUK_INTERNAL void duk_regexp_create_instance(duk_hthread *thr) {
duk_context *ctx = (duk_context *) thr;
duk_hobject *h;
duk_hstring *h_bc;
duk_small_int_t re_flags;
/* [ ... escape_source bytecode ] */
h_bc = duk_get_hstring(ctx, -1);
DUK_ASSERT(h_bc != NULL);
DUK_ASSERT(DUK_HSTRING_GET_BYTELEN(h_bc) >= 1); /* always at least the header */
DUK_ASSERT(DUK_HSTRING_GET_CHARLEN(h_bc) >= 1);
DUK_ASSERT((duk_small_int_t) DUK_HSTRING_GET_DATA(h_bc)[0] < 0x80); /* flags always encodes to 1 byte */
re_flags = (duk_small_int_t) DUK_HSTRING_GET_DATA(h_bc)[0];
/* [ ... escaped_source bytecode ] */
duk_push_object(ctx);
h = duk_get_hobject(ctx, -1);
DUK_ASSERT(h != NULL);
duk_insert(ctx, -3);
/* [ ... regexp_object escaped_source bytecode ] */
DUK_HOBJECT_SET_CLASS_NUMBER(h, DUK_HOBJECT_CLASS_REGEXP);
DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, thr->builtins[DUK_BIDX_REGEXP_PROTOTYPE]);
duk_xdef_prop_stridx(ctx, -3, DUK_STRIDX_INT_BYTECODE, DUK_PROPDESC_FLAGS_NONE);
/* [ ... regexp_object escaped_source ] */
duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_SOURCE, DUK_PROPDESC_FLAGS_NONE);
/* [ ... regexp_object ] */
duk_push_boolean(ctx, (re_flags & DUK_RE_FLAG_GLOBAL));
duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_GLOBAL, DUK_PROPDESC_FLAGS_NONE);
duk_push_boolean(ctx, (re_flags & DUK_RE_FLAG_IGNORE_CASE));
duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_IGNORE_CASE, DUK_PROPDESC_FLAGS_NONE);
duk_push_boolean(ctx, (re_flags & DUK_RE_FLAG_MULTILINE));
duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_MULTILINE, DUK_PROPDESC_FLAGS_NONE);
duk_push_int(ctx, 0);
duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_LAST_INDEX, DUK_PROPDESC_FLAGS_W);
/* [ ... regexp_object ] */
}
示例13: duk_js_to_arrayindex_string_helper
/* Called by duk_hstring.h macros */
DUK_INTERNAL duk_uarridx_t duk_js_to_arrayindex_string_helper(duk_hstring *h) {
duk_uarridx_t res;
duk_small_int_t rc;
if (!DUK_HSTRING_HAS_ARRIDX(h)) {
return DUK_HSTRING_NO_ARRAY_INDEX;
}
rc = duk_js_to_arrayindex_raw_string(DUK_HSTRING_GET_DATA(h),
DUK_HSTRING_GET_BYTELEN(h),
&res);
DUK_UNREF(rc);
DUK_ASSERT(rc != 0);
return res;
}
示例14: DUK_ASSERT
DUK_LOCAL duk_uint8_t *duk__dump_hstring_raw(duk_uint8_t *p, duk_hstring *h) {
duk_size_t len;
duk_uint32_t tmp32;
DUK_ASSERT(h != NULL);
len = DUK_HSTRING_GET_BYTELEN(h);
DUK_ASSERT(len <= 0xffffffffUL); /* string limits */
tmp32 = (duk_uint32_t) len;
DUK_RAW_WRITE_U32_BE(p, tmp32);
DUK_MEMCPY((void *) p,
(const void *) DUK_HSTRING_GET_DATA(h),
len);
p += len;
return p;
}
示例15: sizeof
static duk_hstring *duk__alloc_init_hstring(duk_heap *heap,
duk_uint8_t *str,
duk_uint32_t blen,
duk_uint32_t strhash) {
duk_hstring *res = NULL;
duk_uint8_t *data;
duk_uint32_t alloc_size;
duk_uint32_t dummy;
/* NUL terminate for convenient C access */
alloc_size = sizeof(duk_hstring) + blen + 1;
res = (duk_hstring *) DUK_ALLOC(heap, alloc_size);
if (!res) {
goto error;
}
DUK_MEMZERO(res, sizeof(duk_hstring));
#ifdef DUK_USE_EXPLICIT_NULL_INIT
DUK_HEAPHDR_STRING_INIT_NULLS(&res->hdr);
#endif
DUK_HEAPHDR_SET_TYPE_AND_FLAGS(&res->hdr, DUK_HTYPE_STRING, 0);
if (duk_js_to_arrayindex_raw_string(str, blen, &dummy)) {
DUK_HSTRING_SET_ARRIDX(res);
}
res->hash = strhash;
res->blen = blen;
res->clen = (duk_uint32_t) duk_unicode_unvalidated_utf8_length(str, (duk_size_t) blen); /* clen <= blen */
data = (duk_uint8_t *) (res + 1);
DUK_MEMCPY(data, str, blen);
data[blen] = (duk_uint8_t) 0;
DUK_DDD(DUK_DDDPRINT("interned string, hash=0x%08x, blen=%d, clen=%d, arridx=%d",
DUK_HSTRING_GET_HASH(res),
DUK_HSTRING_GET_BYTELEN(res),
DUK_HSTRING_GET_CHARLEN(res),
DUK_HSTRING_HAS_ARRIDX(res) ? 1 : 0));
return res;
error:
DUK_FREE(heap, res);
return NULL;
}