2010-07-05 7 views
1

여유 시간에 reflection.emit을 사용하여 컴파일러를 작성하고 있는데 이해가 안된다는 문제가 있습니다.reflectio.emit을 사용하여 변수를 저장하는 System.AccessViolationException

약간의 컨텍스트가 있는데, 몇 가지 유형이있는 런타임이 있고 그 중 하나는 두 개의 float 값 (X 및 Y)이있는 더 간단한 벡터 구조체 인 Float2입니다. 나는 값 (a hlsl)을 swizzle 수 있도록 몇 가지 속성을 만들었습니다. 예를 들어, 새로운 Float2 (1.0f, 2.0f)를 가지고 있다면, (새로운 Float2 (1.0f, 2.0f)와 같은) YX float2 (2.0f, 1.0f)를 얻습니다. 내가 사용하는 언어에서이 형식을 사용하여 현재이 경우 (생략 언어의 사소한 세부 사항) 테스트 해요 :

float2 a = float2(1.0, 2.0).yx; 
return a; 

나는 새 통화에 float2 (1.0, 2.0) 변환거야와의 속성 YX 접근 내 Float2 형식 .yx.

문제는 "System.AccessViolationException : 보호 된 메모리를 읽거나 쓰려고 시도했습니다. 종종 다른 메모리가 손상되었음을 나타냅니다."입니다. 나는 왜 이런 식으로하면 이해하지 못합니다.

float2 a = float2(1.0, 2.0); 
return a; 

모든 것이 잘 풀립니다.

내가 생성은 다음과 같다 해요 IL 코드 (나는 문제가 발생 생각 : 그것은 비록 일어나는 이유 "L_0014 stloc.0는"나도 몰라)의

.method public virtual final instance valuetype 
[Bifrost.Psl]Bifrost.Psl.Compiler.Runtime.Float2 Main() cil managed 
{ 
    .maxstack 3 
    .locals init (
     [0] valuetype [Bifrost.Psl]Bifrost.Psl.Compiler.Runtime.Float2 num) 
    L_0000: ldc.r4 1 
    L_0005: ldc.r4 2 
    L_000a: newobj instance void [Bifrost.Psl]Bifrost.Psl.Compiler.Runtime.Float2::.ctor(float32, float32) 
    L_000f: call instance valuetype [Bifrost.Psl]Bifrost.Psl.Compiler.Runtime.Float2 [Bifrost.Psl]Bifrost.Psl.Compiler.Runtime.Float2::get_XY() 
    L_0014: stloc.0 
    L_0015: ldloc.0 
    L_0016: ret 
} 

결과 peverify :

[IL] : 오류 : 오프셋 0x0000000F] [발견 값 'Bifrost.Psl.Compiler.Runtime.Float2가'] 예기치 [값 'Bifrost.Psl.Compiler.Runtime.Float2'의 어드레스 예상] 스택에 입력하십시오.

+0

일리노이에 어떤 문제도 보이지 않습니다. 문제가 생성자 또는 XY 속성 getter 중 하나라고 추측해야합니다. 코드 스 니펫이 잘못되어 * new * 키워드가 누락되었습니다. –

+0

죄송하지만, 제 언어에는 새로운 것이 없습니다. float2 (1.0, 2.0)는 값을 생성합니다. 일리노이 내가 그 명령에 대한 newobj을 생성하고 있어요 –

답변

4

귀하의 Float2이 어떤 모양인지는 모르겠지만 IL은 정상적으로 보입니다.

이 디버깅하는 가장 좋은 방법은 어셈블리를 디스크에 저장 한 다음 을 실행하여을 확인하는 것입니다. AccessViolationException을 생성하는 모든 코드는 으로 오류가 발생합니다.

편집 :newobj doc on MSDN은 값 유형에 대한 포인터 인 객체 참조를 스택에 푸시하는 것에 대해 이야기합니다. 당신이 다음 peverify에서이 오류가 발생하는 경우 난 당신이 임시 변수에 저장된 값 형식의 주소를 얻기 위해

  1. newobj
  2. stloc에 임시 변수
  3. ldloca 필요가 있다고 생각 지금은 그것에 대해 생각
  4. call

, 이것은 무엇을 C#을 컴파일러는 4.ToString();과 같은 값 유형에 대한 직접 호출을 수행합니다.

+0

흠 좋은 팁, 내가 받고있어 [일리노이] : 오류 : [오프셋 0x0000000F] [발견 된 값 'Bifrost.Psl.Compiler.Runtime.Float2'] [예상 값 'Bifrost.Psl.Compiler.Runtime.Float2'의 주소] 스택에 예기치 않은 유형이 있습니다. 이것은 생성자가 반환하는 것과 관련이 있어야합니다 ... –

+0

내 편집보기 ... :) –

+0

나는 그 tnks를 많이 시도 할 것입니다. 나는 대답으로 업데이트 할 것이다. –