3131#define V8_MAP_PTR (ptr ) \
3232 ((ptr & ~V8_HeapObjectTagMask) | V8_HeapObjectTag)
3333
34+ #define V8_TYPE_SCRIPT (type ) \
35+ ((type) == V8_IT_SCRIPT)
36+
3437/*
3538 * Determine the encoding and representation of a V8 string.
3639 */
5356#define ASCII_SEQSTR (value ) \
5457 (V8_TYPE_STRING(value) && V8_STRENC_ASCII(value) && V8_STRREP_SEQ(value))
5558
56- #define ASCII_CONSSTR (value ) \
57- (V8_TYPE_STRING(value) && V8_STRENC_ASCII(value) && V8_STRREP_CONS(value))
59+ #define TWOBYTE_SEQSTR (value ) \
60+ (V8_TYPE_STRING(value) && !V8_STRENC_ASCII(value) && V8_STRREP_SEQ(value))
61+
62+ #define IS_CONSSTR (value ) \
63+ (V8_TYPE_STRING(value) && V8_STRREP_CONS(value))
5864
5965#define ASCII_EXTSTR (value ) \
6066 (V8_TYPE_STRING(value) && V8_STRENC_ASCII(value) && V8_STRREP_EXT(value))
123129 * "len": the string length
124130 *
125131 * "attrs": the type identifier for the string, which indicates the
126- * encoding and representation. We're only interested in ASCII
127- * encoded strings whose representation is one of:
132+ * encoding and representation. We're only interested in strings
133+ * whose representation is one of:
134+ *
135+ * SeqOneByteString stored directly as a char array inside the object
128136 *
129- * SeqString stored directly as a char array inside the object
137+ * SeqTwoByteString stored as a UTF-16 char array inside the object
130138 *
131- * ConsString pointer to two strings that should be concatenated
139+ * ConsString pointer to two strings that should be concatenated
132140 *
133- * ExternalString pointer to a char* outside the V8 heap
141+ * ExternalString pointer to a char* outside the V8 heap
134142 */
135143
136144/*
141149 this->map = V8_MAP_PTR(COPYIN_PTR(str + V8_OFF_HEAPOBJ_MAP)); \
142150 attrs = COPYIN_UINT8(this->map + V8_OFF_MAP_ATTRS);
143151
152+ #define APPEND_SEQSTR (str , len , attrs ) \
153+ APPEND_SEQONEBYTESTR(str, len, attrs) \
154+ APPEND_SEQTWOBYTESTR(str, len, attrs)
155+
144156/*
145- * Print out the given SeqString , or do nothing if the string is not an ASCII
146- * SeqString .
157+ * Print out the given SeqOneByteString , or do nothing if the string is not an ASCII
158+ * SeqOneByteString .
147159 */
148- #define APPEND_SEQSTR (str , len , attrs ) \
149- dtrace:helper:ustack: \
150- /!this->done && len > 0 && ASCII_SEQSTR(attrs)/ \
151- { \
160+ #define APPEND_SEQONEBYTESTR (str , len , attrs ) \
161+ dtrace:helper:ustack: \
162+ /!this->done && len > 0 && ASCII_SEQSTR(attrs)/ \
163+ { \
152164 copyinto(str + V8_OFF_STR_CHARS, len, this->buf + this->off); \
153165 this->off += len; \
154166 }
155167
168+ /*
169+ * LOOP_ITER: macro to paste "block" while "ivar" is less than "dynmax" and
170+ * "statmax". The subsequent LOOP_{4,8} macros facilitate pasting the same
171+ * thing 4 and 8 times, respectively. Like much of the rest of the code in this
172+ * file, this is regrettably necessary given the constraints under which we're
173+ * expected to run.
174+ */
175+ #define LOOP_ITER (ivar , dynmax , statmax , block ) \
176+ ((ivar) < (dynmax)) && ((ivar) < (statmax)) && (block); (ivar)++;
177+
178+ #define LOOP_4 (block ) \
179+ block \
180+ block \
181+ block \
182+ block \
183+
184+ #define LOOP_8 (block ) \
185+ LOOP_4(block) \
186+ LOOP_4(block)
187+
188+ /*
189+ * Print out the given SeqTwoByteString, or do nothing if the string is not an ASCII
190+ * SeqTwoByteString. NOTE: if you bump MAX_TWOBYTESTR_CHARS, you'll also need
191+ * to modify the LOOP_* macro calls below to match.
192+ */
193+ #define MAX_TWOBYTESTR_CHARS 128
194+ #define MAX_TWOBYTESTR_BYTES (2 * MAX_TWOBYTESTR_CHARS)
195+ #define TO_ASCII (c ) ((c) < 128 ? (c) : '?')
196+
197+ #define APPEND_SEQTWOBYTESTR (str , len , attrs ) \
198+ dtrace:helper:ustack: \
199+ /!this->done && len > 0 && TWOBYTE_SEQSTR(attrs)/ \
200+ { \
201+ this->i = 0; \
202+ this->stbuf = (uint16_t *)alloca(MAX_TWOBYTESTR_BYTES + 2); \
203+ copyinto(str + V8_OFF_TWOBYTESTR_CHARS, \
204+ MAX_TWOBYTESTR_BYTES, this->stbuf); \
205+ this->stbuf[MAX_TWOBYTESTR_BYTES - 1] = '\0'; \
206+ this->stbuf[MAX_TWOBYTESTR_BYTES] = '\0'; \
207+ \
208+ LOOP_8(LOOP_8(LOOP_4(LOOP_ITER(this->i, len, \
209+ MAX_TWOBYTESTR_CHARS, \
210+ APPEND_CHR(TO_ASCII(this->stbuf[this->i])))))) \
211+ \
212+ this->i = 0; \
213+ this->stbuf = 0; \
214+ }
215+
156216/*
157217 * Print out the given Node.js ExternalString, or do nothing if the string is
158218 * not an ASCII ExternalString.
159219 */
160220#define APPEND_NODESTR (str , len , attrs ) \
161- dtrace:helper:ustack: \
162- /!this->done && len > 0 && ASCII_EXTSTR(attrs)/ \
163- { \
164- this->resource = COPYIN_PTR(str + V8_OFF_EXTSTR_RSRC); \
221+ dtrace:helper:ustack: \
222+ /!this->done && len > 0 && ASCII_EXTSTR(attrs)/ \
223+ { \
224+ this->resource = COPYIN_PTR(str + V8_OFF_EXTSTR_RSRC); \
165225 this->dataptr = COPYIN_PTR(this->resource + NODE_OFF_EXTSTR_DATA); \
166226 copyinto(this->dataptr, len, this->buf + this->off); \
167227 this->off += len; \
226286 */
227287#define EXPAND_STR (str , len , attrs , s1s , s1l , s1a , s2s , s2l , s2a ) \
228288 dtrace:helper:ustack: \
229- /!this->done && len > 0 && ASCII_CONSSTR (attrs)/ \
289+ /!this->done && len > 0 && IS_CONSSTR (attrs)/ \
230290 { \
231291 len = 0; \
232292 \
@@ -316,6 +376,7 @@ dtrace:helper:ustack:
316376 this -> funcnamelen = 0 ;
317377 this -> funcnameattrs = 0 ;
318378 this -> script = (off_t ) 0 ;
379+ this -> scriptattrs = 0 ;
319380 this -> scriptnamestr = (off_t ) 0 ;
320381 this -> scriptnamelen = 0 ;
321382 this -> scriptnameattrs = 0 ;
@@ -477,24 +538,38 @@ dtrace:helper:ustack:
477538APPEND_V8STR (this -> funcnamestr , this -> funcnamelen , this -> funcnameattrs )
478539
479540/*
480- * Now look for the name of the script where the function was defined.
541+ * Now look for the name of the script where the function was defined. The
542+ * "script" itself may be undefined for special functions like "RegExp".
481543 */
482544dtrace :helper :ustack :
483545/!this -> done /
484546{
485547 this -> script = COPYIN_PTR (this -> shared + V8_OFF_SHARED_SCRIPT );
548+ this -> map = V8_MAP_PTR (COPYIN_PTR (this -> script + V8_OFF_HEAPOBJ_MAP ));
549+ this -> scriptattrs = COPYIN_UINT8 (this -> map + V8_OFF_MAP_ATTRS );
550+ }
551+
552+ dtrace :helper :ustack :
553+ /!this -> done && !V8_TYPE_SCRIPT (this -> scriptattrs )/
554+ {
555+ APPEND_CHR ('\0' );
556+ this -> done = 1 ;
557+ stringof (this -> buf );
558+ }
559+
560+
561+ dtrace :helper :ustack :
562+ /!this -> done /
563+ {
486564 this -> scriptnamestr = COPYIN_PTR (this -> script + V8_OFF_SCRIPT_NAME );
487565 LOAD_STRFIELDS (this -> scriptnamestr , this -> scriptnamelen ,
488566 this -> scriptnameattrs );
489-
490- APPEND_CHR4 (' ' ,'a' ,'t' ,' ' );
491567}
492568
493569dtrace :helper :ustack :
494- /!this -> done && this -> scriptnamelen = = 0 /
570+ /!this -> done && this -> scriptnamelen ! = 0 /
495571{
496- APPEND_CHR8 ('<' ,'u' ,'n' ,'k' ,'n' ,'o' ,'w' ,'n' );
497- APPEND_CHR ('>' );
572+ APPEND_CHR4 (' ' ,'a' ,'t' ,' ' );
498573}
499574
500575APPEND_V8STR (this -> scriptnamestr , this -> scriptnamelen , this -> scriptnameattrs )
@@ -511,6 +586,14 @@ dtrace:helper:ustack:
511586 this -> le_attrs = COPYIN_UINT8 (this -> map + V8_OFF_MAP_ATTRS );
512587}
513588
589+ dtrace :helper :ustack :
590+ /!this -> done && this -> le_attrs != V8_IT_FIXEDARRAY && this -> position == 0 /
591+ {
592+ APPEND_CHR ('\0' );
593+ this -> done = 1 ;
594+ stringof (this -> buf );
595+ }
596+
514597dtrace :helper :ustack :
515598/!this -> done && this -> le_attrs != V8_IT_FIXEDARRAY /
516599{
@@ -519,10 +602,9 @@ dtrace:helper:ustack:
519602 * undefined because V8 has not had to compute it yet. In this case we
520603 * just show the raw position and call it a day.
521604 */
522- APPEND_CHR8 (' ' ,'p' ,'o' ,'s' ,'i' ,'t' ,'i' ,'o' );
523- APPEND_CHR ('n' );
605+ APPEND_CHR4 (' ' ,'p' ,'o' ,'s' );
524606 APPEND_CHR (' ' );
525- APPEND_NUM (this -> position );
607+ APPEND_NUM (SMI_VALUE ( this -> position ) );
526608 APPEND_CHR ('\0' );
527609 this -> done = 1 ;
528610 stringof (this -> buf );
0 commit comments