2015-05-26 21 views
1

當duktape遇到錯誤時,是否有任何方法可以讓duktape正確解開C++堆棧(調用所有適當的析構函數等)?我知道Lua(例如)有能力通過從C++編譯器編譯Lua時使用longjmp切換到C++異常來做到這一點,但乍一看我在duktape中看不到任何類似的東西,而且我肯定清理了C++析構函數沒有被調用。如果這種能力還沒有存在於杜克塔佩,那麼是否有任何計劃? (如果longjmp目的地是以嚴格的LIFO方式設置和使用的,我猜它是可行的,如果不是,那麼也許不那麼可行......)當duktape拋出一個錯誤時,有什麼辦法可以得到正確的C++棧展開?

我一直在玩duktape到目前爲止,我留下了深刻的印象...我主要完成了一個基於C++模板的元編程庫,可以讓你自動創建duktape綁定到C++函數。這個堆棧展開的事情可能是一個完整的交易斷路器,但是......如果我不能相信我的C++析構函數被調用,那麼不要以爲我可以使用duktape。

編輯:實際上,在進一步的思考中,我可以在沒有堆棧展開的情況下使其工作,儘管當然一切都會顯着更復雜且容易出錯。它仍然是一個很棒的功能。

回答

1

從Duktape 1.2開始,還不支持用C++異常友好的try-catch機制替換setjmp/longjmp(用於Duktape中的錯誤處理)。雖然對未來版本的支持計劃。

+0

很高興聽到這是計劃未來的版本! – Scott

+0

處理錯誤的另一種方法可能是讓大多數API調用(例如duk_get_prop)實際上不會引發異常,而是在某處存儲異常對象,並讓C代碼檢查它並手動拋出它,讓它獨立(其中如果JavaScript實現可以在控制從C回調代碼返回時拋出它)或以某種其他方式處理它。 (例如,JavaScriptCore就是這樣處理這個問題的。)但是,不知道這是否是在duktape中做出的一個理智的改變。 – Scott

0

不幸的是,您沒有提供任何代碼示例,所以我的猜測是您沒有在duk_create_heap中設置致命錯誤處理程序,並且您當前正在使用不受保護的代碼執行變體,如duk_eval。您應該嘗試使用protected code execution函數變體,如duk_peval

+0

是的,我想出了我需要做的事情。這是相當尷尬的,但是......例如,沒有duk_get_prop或duk_put_prop的受保護版本,並且duk_safe_call使用起來很痛苦。最後,我編寫了自己的C++函數,它接受lambda作爲參數,在duktape堆棧中存儲一個指針,然後使用duk_safe_call調用一個輔助函數,然後從棧中取回lambda並調用它。 (除了一堆其他的堆棧轉換來保持棧處於合理的狀態。)整個事情可能有點緩慢。 – Scott

3

作爲一個快速更新:Duktape 1.4.0具有使用C++異常長期控制傳輸的支持(https://github.com/svaarala/duktape/tree/master/examples/cpp-exceptions):

  • 定義DUK_OPT_CPP_EXCEPTIONSDUK_USE_CPP_EXCEPTIONS如果你直接編輯0​​),並使用C++編譯編譯器。
  • 當Duktape/C函數放鬆時,自動析構函數將會工作。
  • 但是,您不能通過「Duktape」拋出C++異常。如果你這樣做,Duktape會將C++異常轉換爲Ecmascript異常。因此,雖然Duktape/C函數可以在內部使用C++異常,但這些異常在傳播到Duktape之前應該被捕獲。
相關問題