2010-08-20 4 views
1

Reflection.Emit을 사용하여 수학 표현 파서를 작성하고 있습니다 (예 : 2+2). 클래스는 중위 표현식 (예 : 2+2)을 가져 와서 후치 표현식 (예 : 2 2 +)으로 바꾸고 다른 클래스는 해당 후치 표현식을 IL로 컴파일하고 DynamicMethod을 만듭니다. 거기에서, 표현식은 비슷한 속도로 컴파일 타임에 생성 된 것처럼 평가 될 수 있습니다. Reflection.Emit을 사용하여 스택에서 MethodInfo 인스턴스를 사용하는 메서드 호출

이 컴파일러

는 암시 적 곱셈을 지원하므로 x(2 + 2) 같은 내가 사용자 정의 함수 (예를 들어, f(x))를 구현하려고하고, 지금

x * (2 + 2)으로 평가한다. 위와 같이 암시 적 곱셈과 사용자 정의 함수를 구분하려고 할 때 문제가 발생합니다. 예를 들어 사용자가 x(5)을 입력 한 경우 x5으로 곱하려고하는지 또는 인수를 사용하여 x 함수를 호출하는지 어떻게 알 수 있습니까?

이전의 경우 컴파일러는 if 문을 IL 스트림에 삽입합니다. 이 함수는 식별자가 x 인 함수가 정의되어 있는지 확인합니다. 있는 경우 out 변수와 로컬을 통해 MethodInfo 인스턴스를 스택에 삽입합니다.

내 실제 질문은 컴파일시 IlGenerator.Emit(OpCodes.Call, MethodInfo)을 호출하는 것과 동일한 속도의 스택에 MethodInfo 인스턴스를 사용하여 메서드를 실행할 수 있습니까?

감사합니다.

+0

디자인 권장 사항 : 곱셈을 명시 적으로 만들거나 구문을 호출하는 다른 함수가 있어야합니다. 모호한 구문을 사용하면 사용자 오류를 식별하기가 어렵거나 어렵습니다. 당신은 표준 산술 표기법이 짜증나거나 후위 문자로 변환하는 것을 귀찮게하지 않을 것이고, 이것은 이유 중 하나입니다. –

답변

1

MethodInfo 인스턴스를 스택에서 호출 할 수있는 유일한 방법은 Invoke 메서드를 호출하는 것입니다. 나는 당신이 이미이 가능성을 알고 있다고 확신하지만 그것이 너무 느릴 수도 있다고 두려워합니다. 나는 당신이 그것을 시도하고 스트레스를 받으면 성능을 향상시키는 것이 좋습니다. 귀하의 목적에 충분히 빠르다는 것을 알 수 있습니다.

그렇지 않은 경우 MethodInfo 인스턴스를 전달하지 않도록 디자인을 재구성하는 방법을 고려해야합니다. 예를 들어, 대신 관리되는 함수 포인터를 전달할 수 있습니다. 그것들은 ldftnldvirtftn 명령이 반환하는 것입니다. 그런 다음 calli 명령어를 사용하여 그 중 하나를 호출 할 수 있습니다. SignatureHelper class을 사용하여 calli이 피연산자로 예상하는 "호출 사이트 설명"을 만들어야합니다.

+0

고마워요! 여기서 정확한 해결책을 사용하지는 않았지만 다른 방식으로 처리하게되었습니다. – mgbowen

+0

@nasufara : 다른 솔루션에서 찾은 해결책을 설명하여 다른 사람들이 혜택을 누릴 수 있도록하십시오. – Timwi