interp: keep reverted package initializers in order
Previously, a package initializer that could not be reverted correctly would be called at runtime. But the initializer would be called in the wrong order: after later packages are initialized. This commit fixes this oversight and adds a test to verify the new behavior.
Этот коммит содержится в:
		
							родитель
							
								
									8cc7c6d572
								
							
						
					
					
						коммит
						607d824211
					
				
					 4 изменённых файлов: 40 добавлений и 1 удалений
				
			
		|  | @ -110,17 +110,19 @@ func Run(mod llvm.Module, debug bool) error { | ||||||
| 			fmt.Fprintln(os.Stderr, "call:", fn.Name()) | 			fmt.Fprintln(os.Stderr, "call:", fn.Name()) | ||||||
| 		} | 		} | ||||||
| 		_, mem, callErr := r.run(r.getFunction(fn), nil, nil, "    ") | 		_, mem, callErr := r.run(r.getFunction(fn), nil, nil, "    ") | ||||||
|  | 		call.EraseFromParentAsInstruction() | ||||||
| 		if callErr != nil { | 		if callErr != nil { | ||||||
| 			if isRecoverableError(callErr.Err) { | 			if isRecoverableError(callErr.Err) { | ||||||
| 				if r.debug { | 				if r.debug { | ||||||
| 					fmt.Fprintln(os.Stderr, "not interpreting", r.pkgName, "because of error:", callErr.Error()) | 					fmt.Fprintln(os.Stderr, "not interpreting", r.pkgName, "because of error:", callErr.Error()) | ||||||
| 				} | 				} | ||||||
| 				mem.revert() | 				mem.revert() | ||||||
|  | 				i8undef := llvm.Undef(r.i8ptrType) | ||||||
|  | 				r.builder.CreateCall(fn, []llvm.Value{i8undef, i8undef}, "") | ||||||
| 				continue | 				continue | ||||||
| 			} | 			} | ||||||
| 			return callErr | 			return callErr | ||||||
| 		} | 		} | ||||||
| 		call.EraseFromParentAsInstruction() |  | ||||||
| 		for index, obj := range mem.objects { | 		for index, obj := range mem.objects { | ||||||
| 			r.objects[index] = obj | 			r.objects[index] = obj | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -17,6 +17,7 @@ func TestInterp(t *testing.T) { | ||||||
| 		"slice-copy", | 		"slice-copy", | ||||||
| 		"consteval", | 		"consteval", | ||||||
| 		"interface", | 		"interface", | ||||||
|  | 		"revert", | ||||||
| 	} { | 	} { | ||||||
| 		name := name // make tc local to this closure | 		name := name // make tc local to this closure | ||||||
| 		t.Run(name, func(t *testing.T) { | 		t.Run(name, func(t *testing.T) { | ||||||
|  |  | ||||||
							
								
								
									
										21
									
								
								interp/testdata/revert.ll
									
										
									
									
										предоставленный
									
									
										Обычный файл
									
								
							
							
						
						
									
										21
									
								
								interp/testdata/revert.ll
									
										
									
									
										предоставленный
									
									
										Обычный файл
									
								
							|  | @ -0,0 +1,21 @@ | ||||||
|  | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||||||
|  | target triple = "x86_64--linux" | ||||||
|  | 
 | ||||||
|  | declare void @externalCall(i64) | ||||||
|  | 
 | ||||||
|  | define void @runtime.initAll() unnamed_addr { | ||||||
|  | entry: | ||||||
|  |   call void @foo.init(i8* undef, i8* undef) | ||||||
|  |   call void @main.init(i8* undef, i8* undef) | ||||||
|  |   ret void | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | define internal void @foo.init(i8* %context, i8* %parentHandle) unnamed_addr { | ||||||
|  |   unreachable ; this triggers a revert of @foo.init. | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | define internal void @main.init(i8* %context, i8* %parentHandle) unnamed_addr { | ||||||
|  | entry: | ||||||
|  |   call void @externalCall(i64 3) | ||||||
|  |   ret void | ||||||
|  | } | ||||||
							
								
								
									
										15
									
								
								interp/testdata/revert.out.ll
									
										
									
									
										предоставленный
									
									
										Обычный файл
									
								
							
							
						
						
									
										15
									
								
								interp/testdata/revert.out.ll
									
										
									
									
										предоставленный
									
									
										Обычный файл
									
								
							|  | @ -0,0 +1,15 @@ | ||||||
|  | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||||||
|  | target triple = "x86_64--linux" | ||||||
|  | 
 | ||||||
|  | declare void @externalCall(i64) local_unnamed_addr | ||||||
|  | 
 | ||||||
|  | define void @runtime.initAll() unnamed_addr { | ||||||
|  | entry: | ||||||
|  |   call fastcc void @foo.init(i8* undef, i8* undef) | ||||||
|  |   call void @externalCall(i64 3) | ||||||
|  |   ret void | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | define internal fastcc void @foo.init(i8* %context, i8* %parentHandle) unnamed_addr { | ||||||
|  |   unreachable | ||||||
|  | } | ||||||
		Загрузка…
	
	Создание таблицы
		
		Сослаться в новой задаче
	
	 Ayke van Laethem
						Ayke van Laethem