2014-03-27 2 views
5

에서 콜백 함수를 호출?비동기의 SpiderMonkey의 V27을 사용 SpiderMonkey를 JS 엔진

JS 코드 :

myFunction(function(){ 
    console.log("The function works"); 
}); 

C++ 코드 : 나는 SpiderMonkey를의 문서를 읽은

bool js_myFunction(JSContext* cx, uint32_t argc, jsval* vp) 
{ 
    if (argc == 1) 
    { 
     implement_async_function(cx, vp); 
     JS_SET_RVAL(cx, vp, JSVAL_NULL); 
     return true; 
    } 
    return false; 
} 

static JSContext* savedContext; 
static jsval* savedVal; 
void implement_async_function(JSContext* cx, jsval* vp) 
{ 
    // if the function is called immediately, everything is okay! 
    jsval retVal; 
    JS_CallFunctionValue(cx, nullptr, *vp, 0, nullptr, &retVal); 
    // "The function works" 

    // if some work has to be done before calling the callback... 
    savedContext = cx; 
    savedVal = vp; 
    start_async_process(); 
} 

void async_process_complete() 
{ 
    jsval retVal; 
    JS_CallFunctionValue(savedContext, nullptr, *savedVal, 0, nullptr, &retVal); 
    // "<no filename="filename">:0:true is not a function" 
    // or else it crashes... 
} 

void alternate_implement_async_function(JSContext* cx, jsval* vp) 
{ 
    // also tried this: 
    savedContext = cx; 
    savedVal = vp; 
    JS_AddValueRoot(savedContext, savedVal); 
    start_async_process(); 

    // and this: 
    savedContext = cx; 
    savedVal = new jsval(*vp); 
    JS_AddValueRoot(savedContext, savedVal); 
    start_async_process(); 

    // and using JS::RootedValue 

    // and using JS::Heap<JS::Value> 

    // and using the global context instead of the saved context 
} 

:

https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_Reference/JS::Value

https://developer.mozilla.org/en-US/docs/SpiderMonkey/GC_Rooting_Guide

,

https://developer.mozilla.org/en-US/docs/SpiderMonkey/JSAPI_Reference/JS_CallFunctionValue

https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_AddRoot

그리고 이것이

Spidermonkey and Garbage Collection을 게시 유래 확인 그리고 심지어 JS 콜백 함수 쓰레기 수집해서는 안됩니다 전역 함수 만들기 시도. (이것은 내가 원하는 것이 아닙니다.)

+1

* mozilla irc *에 가입 하시겠습니까? https://wiki.mozilla.org/IRC 나는 누군가가 즉시 당신을 도울 수있을 것이라고 생각합니다. – nonsensickle

답변

1

함수를 비동기 적으로 호출하려고 할 때 프로그램의 동작을 언급하지 않았지만 GC 이후에 함수를 호출하려고 할 때 seg fault라고 가정합니다 그것을 옮겼습니다. 객체을 저장하는 방법이 필요합니다 (코드에서와 같이 값이 아닙니다). JS::Rooted은 스택 루팅이 LIFO 순서에서 gc 일이 루트가되기를 기대하기 때문에이 상황에서는 허용되지 않습니다. 따라서 핸들을 JS::Heap<JSObject*> 핸들에 저장해야합니다. JS::Heap 핸들은 스택 대신 힙 (아마도 목록 또는 트리 구조에 있음)에 있어야합니다. JS::Heap 핸들이있는주의 사항은 기본 개체를 재배치하고 핸들을 업데이트 할 수 있도록 GC에서 추적해야한다는 것입니다. 추적은 this question에서 논의됩니다.

개체가 이제 제대로 저장되고 추적되었다고 가정하면 아무 문제없이 언제든지 호출 할 수 있습니다.