compiler: fix stuck parsing of 'enum{}' + handle such bugs
							parent
							
								
									ae3d84df6b
								
							
						
					
					
						commit
						f4834bd85d
					
				|  | @ -8,7 +8,7 @@ import ( | ||||||
| 	strings | 	strings | ||||||
| 	filepath | 	filepath | ||||||
| 	//compiler.x64
 | 	//compiler.x64
 | ||||||
| 	// time
 | 	time | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| struct Parser { | struct Parser { | ||||||
|  | @ -25,6 +25,7 @@ mut: | ||||||
| 	scanner                &Scanner | 	scanner                &Scanner | ||||||
| 	tokens                 []Token | 	tokens                 []Token | ||||||
| 	token_idx              int | 	token_idx              int | ||||||
|  | 	prev_stuck_token_idx   int | ||||||
| 	tok                    TokenKind | 	tok                    TokenKind | ||||||
| 	prev_tok               TokenKind | 	prev_tok               TokenKind | ||||||
| 	prev_tok2              TokenKind // TODO remove these once the tokens are cached
 | 	prev_tok2              TokenKind // TODO remove these once the tokens are cached
 | ||||||
|  | @ -462,8 +463,17 @@ fn (p mut Parser) parse(pass Pass) { | ||||||
| 		} | 		} | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  | 	 | ||||||
|  | 	parsing_start_ticks := time.ticks() | ||||||
|  | 	compile_cycles_stuck_mask := u64( 0x1FFFFFFF ) // 2^29-1 cycles
 | ||||||
|  | 	mut parsing_cycle := u64(1) | ||||||
|  | 	p.prev_stuck_token_idx = p.token_idx | ||||||
| 	// Go through every top level token or throw a compilation error if a non-top level token is met
 | 	// Go through every top level token or throw a compilation error if a non-top level token is met
 | ||||||
| 	for { | 	for { | ||||||
|  | 		parsing_cycle++ | ||||||
|  | 		if compile_cycles_stuck_mask == (parsing_cycle & compile_cycles_stuck_mask) { | ||||||
|  | 			p.check_if_parser_is_stuck(parsing_cycle, parsing_start_ticks) | ||||||
|  | 		} | ||||||
| 		match p.tok { | 		match p.tok { | ||||||
| 			.key_import { | 			.key_import { | ||||||
| 				p.imports() | 				p.imports() | ||||||
|  | @ -480,6 +490,8 @@ fn (p mut Parser) parse(pass Pass) { | ||||||
| 					// (for example, by DOOM). such fields are
 | 					// (for example, by DOOM). such fields are
 | ||||||
| 					// basically int consts
 | 					// basically int consts
 | ||||||
| 					p.enum_decl(true) | 					p.enum_decl(true) | ||||||
|  | 				} else { | ||||||
|  | 					p.error('Nameless enums are not allowed.') | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			.key_pub { | 			.key_pub { | ||||||
|  | @ -3162,3 +3174,22 @@ fn todo_remove() { | ||||||
| 	//x64.new_gen('f')
 | 	//x64.new_gen('f')
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | fn (p mut Parser) check_if_parser_is_stuck(parsing_cycle u64, parsing_start_ticks i64){ | ||||||
|  | 	if p.prev_stuck_token_idx == p.token_idx { | ||||||
|  | 		// many many cycles have passed with no progress :-( ...
 | ||||||
|  | 		eprintln('Parsing is [probably] stuck. Cycle: ${parsing_cycle:12ld} .') | ||||||
|  | 		eprintln('  parsing file: ${p.file_path} | pass: ${p.pass} | mod: ${p.mod} | fn: ${p.cur_fn.name}') | ||||||
|  | 		p.print_current_tokens('  source') | ||||||
|  | 		if time.ticks() > parsing_start_ticks + 10*1000{ | ||||||
|  | 			p.warn('V compiling is too slow.') | ||||||
|  | 		} | ||||||
|  | 		if time.ticks() > parsing_start_ticks + 30*1000{ | ||||||
|  | 			p.error(' | ||||||
|  | V took more than 30 seconds to compile this file. | ||||||
|  | Please create a GitHub issue: https://github.com/vlang/v/issues/new/choose .
 | ||||||
|  | ') | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	p.prev_stuck_token_idx = p.token_idx | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -106,13 +106,16 @@ int typ; | ||||||
| } $enum_name; | } $enum_name; | ||||||
| ' | ' | ||||||
| 	} | 	} | ||||||
| 	// Skip empty enums
 | 	// Skip nameless enums
 | ||||||
| 	else if !no_name && !p.first_pass() { | 	else if !no_name && !p.first_pass() { | ||||||
| 		p.cgen.typedefs << 'typedef int $enum_name;' | 		p.cgen.typedefs << 'typedef int $enum_name;' | ||||||
| 	}	 | 	}	 | ||||||
| 	p.check(.rcbr) | 	p.check(.rcbr) | ||||||
| 	p.fgen_nl() | 	p.fgen_nl() | ||||||
| 	p.fgen_nl() | 	p.fgen_nl() | ||||||
|  | 	if !no_name && fields.len == 0 { | ||||||
|  | 		p.error('Empty enums are not allowed.') | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn (p mut Parser) check_enum_member_access() { | fn (p mut Parser) check_enum_member_access() { | ||||||
|  |  | ||||||
|  | @ -9,7 +9,7 @@ module gl | ||||||
| #flag @VROOT/thirdparty/glad/glad.o | #flag @VROOT/thirdparty/glad/glad.o | ||||||
| 
 | 
 | ||||||
| // joe-c: fix & remove
 | // joe-c: fix & remove
 | ||||||
| pub enum TmpGlImportHack{} | pub enum TmpGlImportHack{ non_empty } | ||||||
| 
 | 
 | ||||||
| pub fn init_glad() { | pub fn init_glad() { | ||||||
| 	ok := C.gladLoadGL() | 	ok := C.gladLoadGL() | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue