이거 정말 리포에 설명도 대충되어 있고 자바 사용자들 특유의 번잡하고 의미 불명의 코드들로 설명해두어서 진 좀 빠졌습니다.

 

권한 측은 모두 허용으로 되어있기 때문에 서드파티 스크립트 등의 호출을 허용하는 경우 등, 보안상 신경을 써야 한다면 수정해서 사용해야 합니다:

gist.github.com/SeaniaTwix/ca0fdc751da93c84fd121b5b8e300b27

 

graalvm_load_js.kt

GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

이제 가장 중요한 엔트리 파일인데, graalvm의 Context를 사용할 때는 기존 jvm의 Invocable처럼 invokeFunction 메서드가 없다는 것입니다. 일단 함수를 실행하려면 가장 마지막에 함수를 지정해야 합니다. 이때 이 익명 함수는 순수 값으로 가장 마지막에 존재해야 합니다. 즉 export 식이어서도 안 되고 const나 let으로 지정할 경우 이 또한 식(expression)이지만 값(value)이 아니므로 Value 값에서 invoke 할 수 없습니다. 단, 초기화를 하지 않는, 기존 값에 재할당 하는 식(expression)은 es 문법상 그 자체가 식의 결과 값을 반환하므로 가능합니다.

 

혹은 es6의 arrow 함수를 사용해도 됩니다. 개인적으로 arrow 함수를 사용하길 선호하는 편이지만 이 경우 문맥상 덩그러니 있는 것 같아서  아래에서는 사용하지 않았습니다.

또, 아래 코드에서는 굳이 가장 마지막에 추가적인 함수를 넣지 않고 최상위 코드 레이어에서 호출하는 라인만 함수 정의 위로 올려줘도 됩니다만, 함수 호출이 마지막에 와서는 안 된다는 것을 알리기 위해 고의적으로 작성하였습니다.

 

gist.github.com/SeaniaTwix/d703b484ced9328b43c85265fbd1d7b5

 

main.js

GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

그 이외에는 다를 게 없습니다. 모듈 파일은 일반적인 esm와 동일합니다:

gist.github.com/SeaniaTwix/083f8a30ff2bb8e11c9828167017a7c1

 

world.js

GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

위 코드들을 실행하면 다음과 같이 출력됩니다.

inside: hello world
outside: hello world

추가로 Value의 invokeMember 메서드로 첫 번째 인자에 이름을 문자열 값으로 넣어 호출하는 방법도 있습니다만 js 쪽 코드가 더 골때려집니다. 결국 위에서 설명한 방식보다 더 번잡합니다.

class ScriptApp {

    static run(...args) {
        print(...args)
    };

}

ScriptApp // 여기에 주목

 

함수 값 처럼 클래스 객체를 그대로 마지막에 써주어야 합니다. 그냥 class 정의로 끝나면 graalvm은 eval의 반환 값을 undefined로 반환하거나 가장 마지막에 정의된 함수 객체를 반환합니다.

 

여러모로 방식이 골때리네요.

 

가장 무난한 방법은 그냥 호출할 함수를 익명으로 가장 아래에 정의하거나 (정말 최고의 방법), 애당초 Context를 초기화 할 때 빌더에서 environment에 값을 미리 넣어주고 함수 정의 없이 최상위 문맥에서 코드를 실행하는 방식입니다만, 이는 스크립트 소스에서 env로 할당되는 값이 무엇이 있는지 어디서 오는지 알기 힘들 뿐더러 구문을 잘못 읽을 여지를 주기에 개인적으로 선호하는 방식은 아닙니다.

또한 타입스크립트를 사용 중인데 어지간해서는 declare var를 피하려고 하고 있기 때문에 저는 이 방식은 사용하지 않고 있습니다.

 

하여튼 이런 방식 말고 뭔가 더 있을 것 같은데 아직 모르겠습니다. 문맥상 마지막에 온 것만으로 반환 값이 되는 건 OCaml 같은 ML 계열 언어에서 많이 쓰이므로 어색하진 않고 좋아하는 계열의 언어입니다만, 코드의 최종 문맥상 마지막 값을 호스트로 반환해서 사용하는 건 ecmascript와 java 계열 언어 디자인상 어울리지 않는 것 같습니다. 뭐, graaljs 설계자는 무언가 이유가 있어서 이렇게 만들었겠죠.

 

그리고 자바 코드를 일일이 뒤져보는 건 진짜 고통인지라 요 1~2 시간 본 걸로도 지치네요.

 

이만 끝.

'공부 > JavaScript' 카테고리의 다른 글

[MapleStory] 플레이어 스크립트  (0) 2014.09.09


...

cm.sendOkS("그렇군...", 2);

...