@@ -40,47 +40,6 @@ export class NodeVarRegistry {
4040 */
4141 bmsRefs = new Map < string , constants . BitmapsetReference > ( constants . getWellKnownBitmapsetReferences ( ) ) ;
4242
43- /*
44- * Update stored node types for internal usage from provided
45- * node tag file. i.e. `nodes.h' or `nodetags.h'.
46- */
47- updateNodeTypesFromFile ( file : vscode . TextDocument ) {
48- let added = 0 ;
49- for ( let lineNo = 0 ; lineNo < file . lineCount ; lineNo ++ ) {
50- /*
51- * NodeTag enum value has following representation:
52- *
53- * [spaces] T_*tag_name* [= *number*],
54- *
55- * We must obtain only *tag_name* part, because 'T_' prefix
56- * is constant and not important and *number* also not
57- * important because we must focus on words, not numbers - if
58- * there was garbage in structure, Node->type will be random numbers.
59- * That is how we find garbage.
60- */
61- const line = file . lineAt ( lineNo ) ;
62- if ( line . isEmptyOrWhitespace ) {
63- continue ;
64- }
65-
66- const text = line . text . trim ( ) ;
67- if ( ! text . startsWith ( 'T_' ) ) {
68- continue ;
69- }
70-
71- const tag = text . replace ( ',' , '' )
72- . replace ( 'T_' , '' )
73- . split ( ' ' , 1 ) [ 0 ] ;
74- if ( tag . trim ( ) === '' ) {
75- continue ;
76- }
77-
78- this . nodeTags . add ( tag ) ;
79- added ++ ;
80- }
81- return added ;
82- }
83-
8443 addAliases ( aliases : AliasInfo [ ] ) {
8544 aliases . forEach ( a => {
8645 this . aliases . set ( a . alias . trim ( ) , a . type . trim ( ) ) ;
@@ -4081,56 +4040,8 @@ class BitmapSetSpecialMember extends NodeVariable {
40814040 super ( 'Bitmapset' , args ) ;
40824041 }
40834042
4084- async isValidSet ( ) : Promise < boolean > {
4085- /*
4086- * First, validate NodeTag. BitmapSetSpecialMember could be
4087- * created using dumb type check, without actual NodeTag
4088- * checking. So we do it here
4089- */
4090- if ( this . context . hasBmsNodeTag ) {
4091- try {
4092- const tag = await this . evaluate ( `((Bitmapset *)${ this . getPointer ( ) } )->type` ) ;
4093- if ( tag . result !== 'T_Bitmapset' ) {
4094- if ( ! utils . isValidIdentifier ( tag . result ) ) {
4095- /* Do not track NodeTag anymore and perform check again */
4096- this . context . hasBmsNodeTag = false ;
4097- return await this . isValidSet ( ) ;
4098- } else {
4099- /* Tags do not match */
4100- return false ;
4101- }
4102- }
4103- } catch ( err ) {
4104- if ( ! ( err instanceof EvaluationError ) ) {
4105- throw err ;
4106- }
4107-
4108- if ( err . message . indexOf ( 'no member' ) === - 1 ) {
4109- throw err ;
4110- }
4111-
4112- /* CodeLLDB path */
4113- this . context . hasBmsNodeTag = false ;
4114- return await this . isValidSet ( ) ;
4115- }
4116- } else {
4117- /*
4118- * If we do not have NodeTag, then try to check that we can deref
4119- * pointer (means that pointer is valid).
4120- * 'nwords' member is only available option in this case.
4121- * If output is empty, then pointer is invalid.
4122- *
4123- * Also, pointer may give valid (at first glance) result,
4124- * but it contains garbage and value will be too large - we
4125- * check this too. 50 seems big enough to start worrying about.
4126- */
4127- const result = await this . evaluate ( `((Bitmapset *)${ this . getPointer ( ) } )->nwords` ) ;
4128- const nwords = Number ( result . result ) ;
4129- if ( ! ( Number . isInteger ( nwords ) && nwords < 50 ) ) {
4130- return false ;
4131- }
4132- }
4133-
4043+ async isValidSet ( members : Variable [ ] ) : Promise < boolean > {
4044+ /* This check is enough (if it exists) */
41344045 if ( this . context . hasBmsIsValidSet ) {
41354046 const expression = `bms_is_valid_set((Bitmapset *)${ this . getPointer ( ) } )` ;
41364047 try {
@@ -4151,6 +4062,34 @@ class BitmapSetSpecialMember extends NodeVariable {
41514062 return true ;
41524063 }
41534064 }
4065+
4066+ /* Fallback checking children members for validity/look normal */
4067+
4068+ if ( this . context . hasBmsNodeTag ) {
4069+ /* Check NodeTag is the most straight-forward approach */
4070+ const nodeTag = members . find ( m => m . name === 'type' ) ;
4071+ if ( nodeTag ) {
4072+ return nodeTag . value === 'T_Bitmapset' ;
4073+ }
4074+
4075+ this . context . hasBmsNodeTag = false ;
4076+ }
4077+
4078+ /* If we do not have NodeTag, then check that member values looks normally */
4079+ const nwords = members . find ( m => m . name === 'nwords' ) ;
4080+ if ( ! nwords ) {
4081+ return false ;
4082+ }
4083+
4084+ const n = Number ( nwords . value ) ;
4085+ /*
4086+ * For 64-bit system even 20 is large number: 10 * 64 = 640.
4087+ * Human will not be able to handle such amount of data.
4088+ */
4089+ const maxNWords = 10 ;
4090+ if ( Number . isNaN ( n ) || maxNWords <= n ) {
4091+ return false ;
4092+ }
41544093
41554094 return true ;
41564095 }
@@ -4188,7 +4127,7 @@ class BitmapSetSpecialMember extends NodeVariable {
41884127 return true ;
41894128 }
41904129
4191- async getSetElements ( ) : Promise < number [ ] | undefined > {
4130+ async getSetElements ( members : Variable [ ] ) : Promise < number [ ] | undefined > {
41924131 /*
41934132 * Must check we do not have breakpoints set in `bms_next_member`.
41944133 * Otherwise, we will get infinite recursion and backend will crash.
@@ -4200,9 +4139,12 @@ class BitmapSetSpecialMember extends NodeVariable {
42004139 /*
42014140 * We MUST check validity of set, because, otherwise,
42024141 * `Assert` will fail or SEGFAULT si thrown and whole
4203- * backend will crash
4142+ * backend will crash.
4143+ *
4144+ * Check performed using `bms_is_valid_set`, but if it
4145+ * is missing, then check members to look normally.
42044146 */
4205- if ( ! await this . isValidSet ( ) ) {
4147+ if ( ! await this . isValidSet ( members ) ) {
42064148 return ;
42074149 }
42084150
@@ -4343,12 +4285,12 @@ class BitmapSetSpecialMember extends NodeVariable {
43434285 const members = await Variable . getVariables ( this . variablesReference ,
43444286 this . frameId , this . context ,
43454287 this ) ;
4346- if ( ! members ) {
4288+ if ( ! members ?. length ) {
43474289 return members ;
43484290 }
43494291
43504292 /* Add special members to explore set elements */
4351- const setMembers = await this . getSetElements ( ) ;
4293+ const setMembers = await this . getSetElements ( members ) ;
43524294 if ( setMembers !== undefined ) {
43534295 const ref = await this . getBmsRef ( ) ;
43544296
@@ -4357,6 +4299,7 @@ class BitmapSetSpecialMember extends NodeVariable {
43574299 members . push ( new BitmapSetSpecialMember . BmsArrayVariable ( this , setMembers , ref ) ) ;
43584300 }
43594301
4302+ /* Do not show 'words' flexible array member */
43604303 return members . filter ( v => v . name !== 'words' ) ;
43614304 }
43624305
0 commit comments