/* intern built-in strings from precooked data (genstrings.py) */ static int duk__init_heap_strings(duk_heap *heap) { duk_bitdecoder_ctx bd_ctx; duk_bitdecoder_ctx *bd = &bd_ctx; /* convenience */ int i, j; DUK_MEMZERO(&bd_ctx, sizeof(bd_ctx)); bd->data = (const duk_uint8_t *) duk_strings_data; bd->length = (duk_size_t) DUK_STRDATA_DATA_LENGTH; for (i = 0; i < DUK_HEAP_NUM_STRINGS; i++) { duk_uint8_t tmp[DUK_STRDATA_MAX_STRLEN]; duk_hstring *h; int len; int mode; int t; len = duk_bd_decode(bd, 5); mode = 32; /* 0 = uppercase, 32 = lowercase (= 'a' - 'A') */ for (j = 0; j < len; j++) { t = duk_bd_decode(bd, 5); if (t < DUK__BITPACK_LETTER_LIMIT) { t = t + 'A' + mode; } else if (t == DUK__BITPACK_UNDERSCORE) { t = (int) '_'; } else if (t == DUK__BITPACK_FF) { /* Internal keys are prefixed with 0xFF in the stringtable * (which makes them invalid UTF-8 on purpose). */ t = (int) 0xff; } else if (t == DUK__BITPACK_SWITCH1) { t = duk_bd_decode(bd, 5); DUK_ASSERT(t >= 0 && t <= 25); t = t + 'A' + (mode ^ 32); } else if (t == DUK__BITPACK_SWITCH) { mode = mode ^ 32; t = duk_bd_decode(bd, 5); DUK_ASSERT(t >= 0 && t <= 25); t = t + 'A' + mode; } else if (t == DUK__BITPACK_SEVENBIT) { t = duk_bd_decode(bd, 7); } tmp[j] = (duk_uint8_t) t; } DUK_DDD(DUK_DDDPRINT("intern built-in string %d", i)); h = duk_heap_string_intern(heap, tmp, len); if (!h) { goto error; } /* special flags */ if (len > 0 && tmp[0] == 0xff) { DUK_HSTRING_SET_INTERNAL(h); } if (i == DUK_STRIDX_EVAL || i == DUK_STRIDX_LC_ARGUMENTS) { DUK_HSTRING_SET_EVAL_OR_ARGUMENTS(h); } if (i >= DUK_STRIDX_START_RESERVED && i < DUK_STRIDX_END_RESERVED) { DUK_HSTRING_SET_RESERVED_WORD(h); if (i >= DUK_STRIDX_START_STRICT_RESERVED) { DUK_HSTRING_SET_STRICT_RESERVED_WORD(h); } } DUK_DDD(DUK_DDDPRINT("interned: %!O", h)); /* The incref macro takes a thread pointer but doesn't use it * right now. */ DUK_HSTRING_INCREF(_never_referenced_, h); heap->strs[i] = h; } return 1; error: return 0; }
/* intern built-in strings from precooked data (genstrings.py) */ DUK_LOCAL duk_bool_t duk__init_heap_strings(duk_heap *heap) { duk_bitdecoder_ctx bd_ctx; duk_bitdecoder_ctx *bd = &bd_ctx; /* convenience */ duk_small_uint_t i, j; DUK_MEMZERO(&bd_ctx, sizeof(bd_ctx)); bd->data = (const duk_uint8_t *) duk_strings_data; bd->length = (duk_size_t) DUK_STRDATA_DATA_LENGTH; for (i = 0; i < DUK_HEAP_NUM_STRINGS; i++) { duk_uint8_t tmp[DUK_STRDATA_MAX_STRLEN]; duk_hstring *h; duk_small_uint_t len; duk_small_uint_t mode; duk_small_uint_t t; len = duk_bd_decode(bd, 5); mode = 32; /* 0 = uppercase, 32 = lowercase (= 'a' - 'A') */ for (j = 0; j < len; j++) { t = duk_bd_decode(bd, 5); if (t < DUK__BITPACK_LETTER_LIMIT) { t = t + DUK_ASC_UC_A + mode; } else if (t == DUK__BITPACK_UNDERSCORE) { t = DUK_ASC_UNDERSCORE; } else if (t == DUK__BITPACK_FF) { /* Internal keys are prefixed with 0xFF in the stringtable * (which makes them invalid UTF-8 on purpose). */ t = 0xff; } else if (t == DUK__BITPACK_SWITCH1) { t = duk_bd_decode(bd, 5); DUK_ASSERT_DISABLE(t >= 0); /* unsigned */ DUK_ASSERT(t <= 25); t = t + DUK_ASC_UC_A + (mode ^ 32); } else if (t == DUK__BITPACK_SWITCH) { mode = mode ^ 32; t = duk_bd_decode(bd, 5); DUK_ASSERT_DISABLE(t >= 0); DUK_ASSERT(t <= 25); t = t + DUK_ASC_UC_A + mode; } else if (t == DUK__BITPACK_SEVENBIT) { t = duk_bd_decode(bd, 7); } tmp[j] = (duk_uint8_t) t; } /* No need to length check string: it will never exceed even * the 16-bit length maximum. */ DUK_ASSERT(len <= 0xffffUL); DUK_DDD(DUK_DDDPRINT("intern built-in string %ld", (long) i)); h = duk_heap_string_intern(heap, tmp, len); if (!h) { goto error; } /* Special flags checks. Since these strings are always * reachable and a string cannot appear twice in the string * table, there's no need to check/set these flags elsewhere. * The 'internal' flag is set by string intern code. */ if (i == DUK_STRIDX_EVAL || i == DUK_STRIDX_LC_ARGUMENTS) { DUK_HSTRING_SET_EVAL_OR_ARGUMENTS(h); } if (i >= DUK_STRIDX_START_RESERVED && i < DUK_STRIDX_END_RESERVED) { DUK_HSTRING_SET_RESERVED_WORD(h); if (i >= DUK_STRIDX_START_STRICT_RESERVED) { DUK_HSTRING_SET_STRICT_RESERVED_WORD(h); } } DUK_DDD(DUK_DDDPRINT("interned: %!O", (duk_heaphdr *) h)); /* XXX: The incref macro takes a thread pointer but doesn't * use it right now. */ DUK_HSTRING_INCREF(_never_referenced_, h); #if defined(DUK_USE_HEAPPTR16) heap->strs16[i] = DUK_USE_HEAPPTR_ENC16((void *) h); #else heap->strs[i] = h; #endif } return 1; error: return 0; }