알라딘MGG와이드바


게임 프로그래밍 패턴 Part 4 - 행동 패턴(Behavioral Patterns) 보충자료 개발 이야기

바이트코드(Bytecode)

1. 화성 탐사차인 큐리오시티 로버를 제어하는 소프트웨어는 RAD750 프로세서용 C 코드로 전체가 250만 줄 정도 밖에 안 된다고 한다.

5. 루비는 15년 동안이나 인터프리터 방식으로 되어 있었다가, 버전 1.9가 되어서야 이번 장에서 설명하는 바이트코드 방식으로 바뀌었다.

8. 이래서 많은 게임콘솔과 iOS에서는 로딩하거나 런타임에 생성한 기계어를 어플리케이션에서 실행하지 못하게 한다.(역주:앱 심사 과정에서 확인 못한 코드를 실행할 수 있기 때문이다.)

An Application may not download or install executable code. Interpreted code may only be used in an Application if all scripts, code and interpreters are packaged in the Application and not downloaded. The only exception to the foregoing is scripts and code downloaded and run by Apple's builtin WebKit framework, provided that such scripts and code do not change the primary purpose of the Application by providing features or functionality that are inconsistent with the intended and advertised purpose of the Application as submitted to the App Store.

Since the iPhone's kernel prevents an application from generating code dynamically Mono on the iPhone does not support any form of dynamic code generation. These include:
  • The System.Reflection.Emit is not available.
  • No support for System.Runtime.Remoting.
  • No support for creating types dynamically (no Type.GetType ("MyType`1")), although looking up existing types (Type.GetType ("System.String") for example, works just fine).
  • Reverse callbacks must be registered with the runtime at compile time.

Building LuaJIT for consoles requires both a supported host compiler (x86 or x64) and a cross-compiler (to PPC or ARM) from the official console SDK. Due to restrictions on consoles, the JIT compiler is disabled and only the fast interpreter is built. This is still faster than plain Lua, but much slower than the JIT compiler. The FFI is disabled, too, since it's not very useful in such an environment.

9. 프로그래밍 세계에서는 '가상 머신'과 '인터프리터'가 동의어로 사용된다. 이 책에서도 두 단어를 번갈아 쓸 것이다.
알파, 베타리더 중에서 '가상 머신'과 '인터프리터'는 명백히 다른 단어가 아니냐는 의견이 있었다. 저자로부터 받은 답변을 첨부한다.
I never think they are synonymous. Could you explain more?
-> No, among a lot of programming language people, they are synonymous. The JVM, CLR, Chrome's V8, Apple's JavaScriptCore, and Mozilla's SpiderMonkey are all considered "virtual machines" (that's what the "VM" in "JVM" is for) but they are just programming language interpreters. It's confusing because some languages don't call their implementations VMs. Python is always referred to as having an "interpreter". I could be wrong, but my hunch is that it's a cultural term based on the history of the people who implemented these languages. The JVM and most JavaScript VMs were written by people who often came from a Smalltalk background. It makes a lot more sense to think of Smalltalk as a "VM" because Smalltalk really is a whole system and environment to work in, not just a language. Those people left Smalltalk for other languages but brought the "VM" term with them.

11. 머시태시(Mustache), 루비의 리퀴드(Liquid), 자바스크립트의 핸들바(Handlebars), 파이썬의 진자(Jinja) 같은 템플릿 언어가 대부분 그래왔다.
The premise behind a template language is that the language is "embedded" within some other master document. Specifically, on your average document, the total size of the document is mostly document source than template language.

12. 예외적으로 <로보워(RoboWar)>라는 고전게임이 있었다. 이 게임에서 플레이어는 로봇을 조종하기 위해 기계어와 굉장히 비슷한 언어와 이 장에서 다루는 명령어 집합 같은 걸로 프로그램을 만들어야 한다.

14. 자바 가상머신이나 마이크로소프트 .NET 플랫폼의 핵심인 공통 언어 런타임(Common Language Runtime)에서는 한 바이트만으로도 충분하니, 우리도 한 바이트면 된다.
-> 2015년 기준으로 자바 바이트코드는 256개 중 198개가 사용 중이고 51개는 나중을 위해 예약되어 있다. .Net CIL(Common Intermediate Language) opcode 중에는 2바이트를 쓰는 게 몇 개 있다.
Of the 256 possible byte-long opcodes, 198 are currently in use (~77%), 51 are reserved for future use, and 3 instructions (~1%) are set aside as permanently unimplemented.


15. 이런 아키텍처를 스택 머신이라고 부른다. 포스(Forth), 포스트스크립트(PostScript), 팩터(Factor) 같은 프로그래밍 언어에서는 아예 사용자가 스택에 바로 접근할 수 있게 한다.
-> 이런 언어를 스택 기반 언어라고 한다. C++같은 언어에서는 컴파일러가 알아서 함수 인수를 스택에 쌓아 전달하는 반면, 스택 기반 언어에서는 코드에서 직접 스택에 값을 넣어야 함수에 인수를 전달할 수 있다.

포스(Forth)

포스트스크립트(Post Script)
스택 기계 기반 언어 중 널리 알려진 다른 언어는 포스트스크립트(PostScript)다. 포스트 스크립트는 문서를 출력 목적으로 기술하는 데 사용하는 언어다. 포스트크스립트는 제록스 PARC에서 1970년대 후반 존 워녹(JohnWaranock)을 비롯한 몇몇이 개발했으며, 존 워녹이 설계한 초기 언어를 바탕으로 했다. 그 그룹은 결국 PARC를 떠나 어도비 시스템즈를 설립했다. -> 출처가 기억이 안 나네.

'밑바닥까지 전부 거북이(turtles all the way down)' 같은 무한 회귀 문제
"지구가 태양의 주위를 돌고, 태양은 거대한 별들의 모임인 은하계의 주심의 주위를 돕니다..." - 버트런드 러셀.
"당신의 이야기는 말도 안 돼요. 세계는 거대한 거북의 등 뒤에 얹혀 있는 평평한 판이라고요." - 강연회 청중 가운데 한 할머니.
"그 거북은 무엇의 위에 있지요?"
"똑똑하군요, 젊은이. 아주 똑똑해... 그 아래로는 그렇게 끝없이 거북들이 있지요."
종료조건 없는 재귀함수와 비슷하다고 보면 된다.

다행히 나는 학부 시절 컴파일러 수업을 Programming Language Processors in Java: Compilers and Interpreters으로 배웠다. 자바라 쉽게 접근할 수 있었다.


NuRi's Tools - iframe 변환기


<아키에이지> 개발팀은 웹 기반 콘텐츠 개발툴 DDCMS으로 만들었다. 『위대한 게임의 탄생 3』(지앤선, 2013) 참고
<최강의 군단> 개발팀은 언리얼 엔진에 있는 그래프 편집 인터페이스를 활용해 스킬 개발 툴을 만들었다.

NuRi's Tools - iframe 변환기


25. 루아 개발팀은 루아 바이트코드 포멧을 따로 명시하지 않고, 버전업 할 때 바이트코드 포멧도 바꾸는 편이다. 지금 여기에서 설명한 것은 루아 5.1을 기준으로 한다. 루아 내부를 깊숙히 들여다보고 싶다면 'A No-Frills Introduction to Lua 5.1 VM Instructions' 문서를 읽어보자.

28. 바이트코드를 정적 자료형 언어를 통해서 컴파일했다면, 컴파일러가 안전한 바이트코드만 작성했을테니 안전하다고 생각할지도 모르겠다. 아주 틀린 얘기는 아니지만 악의적인 유저는 컴파일러를 통하지 않고 수동으로 악성 바이트코드를 집어넣을 수 있다는 걸 잊어서는 안 된다. 
자바 VM이 프로그램을 로딩할 때 바이트코드를 괜히 검증하는 게 아니다.

29. 저자는 렌(Wren) 언어를 개발하면서 재귀 하향 파서를 만들었다.

만들면서 배우는 인터프리터(한빛미디어, 2012) 5.3절 '재귀적 하향 구문 분석'에서도 자세히 설명하고 있다.

하위 클래스 샌드박스(Subclass Sandbox)

게임 엔진 아키텍처』(에이콘, 2013): 게임 프로그래밍 패턴 책을 번역하면서 많이 도움받은 책. 게임 개발자라면 꼭 읽어봐야 한다.

깨지기 쉬운 상위 클래스 문제('fragile base class')원서에서는 brittle base class problem이라고 되어 있었다.
달리나음님이 정리한 '깨지기 쉬운 기반 클래스 문제'

타입 객체(Type Object)

3. 위에서 시키는 대로 코드만 입력하는 프로그래머를 비하하는 말로 '코드 몽키'라고 부른다. 마찬가지로 '데이터 몽키'는 생각없이 데이터만 입력하는 사람을 의미한다.

2006년 조너선 콜턴은 Code Monkey라는 곡을 써서 많은 호응을 얻었다.

NuRi's Tools - iframe 변환기



7. 클래스 메서드 코드는 실행파일의 code segment에 들어간다.
A plain (non virtual) member function is just like a C function (except that it has this as an implicit, often first, parameter). For example your getA method is implemented like the following C function (outside of the object, e.g. in the code segment of the binary executable) :
int C$getA(A*thisptr) const { return thisptr->m_a; }
then imagine that the compiler is translating p->getA() into C$getA(p)

리버스코어 ReverseCore님도 잘 정리해 놓았다.


핑백

덧글

댓글 입력 영역


Yes24위대한게임의탄생3

위대한 게임의 탄생 3
예스24 | 애드온2