{"id":674,"date":"2012-01-05T20:20:00","date_gmt":"2012-01-05T19:20:00","guid":{"rendered":"http:\/\/shadowcovenant.com\/blog\/2012\/01\/05\/lua-jit\/"},"modified":"2012-01-12T14:54:45","modified_gmt":"2012-01-12T13:54:45","slug":"lua-jit","status":"publish","type":"post","link":"http:\/\/shadowcovenant.com\/blog\/2012\/01\/05\/lua-jit\/","title":{"rendered":"LUA JIT"},"content":{"rendered":"<p align=\"justify\">Following the suggestion of one of my readers, I decided to take a deeper look into <a href=\"http:\/\/luajit.org\/\">LUAJIT<\/a>.<\/p>\n<p align=\"justify\">At first glance, LUAJIT is a Just-In-Time compiler for Lua, that uses exactly the same interface as the normal Lua library, but compiles the code instead of interpreting, resulting in very significant speed improvements.<\/p>\n<p align=\"justify\">Just that is enough reason to use it, and I intended to do it later in the project\u2026<\/p>\n<p align=\"justify\">But what caught my attention was the FFI library that enables me to bind functions and C structures in a much easier fashion\u2026<\/p>\n<p align=\"justify\">Under normal circumstances, if I wanted to have a function available to Lua (for example purposes, a sum function that takes two arguments and returns the sum of both), I\u2019d have to:<\/p>\n<ol>\n<li>\n<div align=\"justify\">Write the function itself <\/div>\n<li>\n<div align=\"justify\">Write a bind function (a C function) <\/div>\n<li>\n<div align=\"justify\">Bind that function to the environment <\/div>\n<\/li>\n<\/ol>\n<p align=\"justify\">&nbsp;<\/p>\n<p align=\"justify\">On the example:<\/p>\n<div align=\"justify\">\n<pre>int sum(int a,int b)<\/pre>\n<\/div>\n<div align=\"justify\">\n<pre>{<\/pre>\n<\/div>\n<div align=\"justify\">\n<pre>   return a+b;<\/pre>\n<\/div>\n<div align=\"justify\">\n<pre>}<\/pre>\n<\/div>\n<div align=\"justify\">\n<pre>&nbsp;<\/pre>\n<\/div>\n<div align=\"justify\">\n<pre>LuaGlue lua_sum(lua_State* L)<\/pre>\n<\/div>\n<div align=\"justify\">\n<pre>{<\/pre>\n<\/div>\n<div align=\"justify\">\n<pre>   int a=lua_get_number_argument(L,1);<\/pre>\n<\/div>\n<blockquote>\n<div align=\"justify\">\n<pre>   int b=lua_get_number_argument(L,2);<\/pre>\n<\/div>\n<\/blockquote>\n<div align=\"justify\">\n<pre> <\/pre>\n<\/div>\n<div align=\"justify\">\n<pre>   lua_push_number(L,a+b);<\/pre>\n<\/div>\n<div align=\"justify\">\n<pre>   return 1;<\/pre>\n<\/div>\n<div align=\"justify\">\n<pre>}<\/pre>\n<\/div>\n<div align=\"justify\">\n<pre>&nbsp;<\/pre>\n<\/div>\n<div align=\"justify\">\n<pre>env-&gt;add_function(\u201csum\u201d,lua_sum);<\/pre>\n<\/div>\n<div align=\"justify\">\n<pre>&nbsp;<\/pre>\n<\/div>\n<div align=\"justify\">\n<pre><\/pre>\n<\/div>\n<p align=\"justify\">This is of course a simplification, and misses parameter validation, etc\u2026<\/p>\n<p align=\"justify\">With Lua JIT, I can just:<\/p>\n<ol>\n<li>\n<div align=\"justify\">Write the function itself <\/div>\n<li>\n<div align=\"justify\">Bind the function directly in LUA<\/div>\n<\/li>\n<\/ol>\n<p align=\"justify\">&nbsp;<\/p>\n<p align=\"justify\">Step 1 is almost the same as before:<\/p>\n<div align=\"justify\">\n<pre>extern \u201cC\u201d int __declspec(dllexport) sum(int a,int b)<\/pre>\n<\/div>\n<div align=\"justify\">\n<pre>{   <\/pre>\n<\/div>\n<div align=\"justify\">\n<pre>   return a+b;<\/pre>\n<\/div>\n<div align=\"justify\">\n<pre>}<\/pre>\n<\/div>\n<div align=\"justify\">\n<pre> <\/pre>\n<\/div>\n<p align=\"justify\">The difference is that now I have to say that the function is to be implemented through C call, instead of stdcall (the extern \u201cC\u201d part) and that the function has to be exported (the __declspec(dllexport) part).<\/p>\n<p align=\"justify\">Then, for step 2 on LUA, I just have to do:<\/p>\n<div align=\"justify\">\n<pre>extern \u201cC\u201d int __declspec(dllexport) sum(int a,int b)<\/pre>\n<\/div>\n<div align=\"justify\">\n<pre>local ffi=require(\u201cffi\u201d)<\/pre>\n<\/div>\n<div align=\"justify\">\n<pre>ffi.cdef[[<\/pre>\n<\/div>\n<div align=\"justify\">\n<pre>   int sum(int a,int b);<\/pre>\n<\/div>\n<div align=\"justify\">\n<pre>]]<\/pre>\n<\/div>\n<div align=\"justify\">\n<pre>&nbsp;<\/pre>\n<\/div>\n<div align=\"justify\">\n<pre>local var=ffi.C.sum(10,20)<\/pre>\n<\/div>\n<div align=\"justify\">\n<pre>print(var)<\/pre>\n<\/div>\n<div align=\"justify\">\n<pre>&nbsp;<\/pre>\n<\/div>\n<p align=\"justify\">Much simpler and safer, I think!<\/p>\n<p align=\"justify\">The benefits aren\u2019t just here, you can declare C structs in both sides (C and Lua) and use them without incurring performance penalties, which allied to the metatype tables allow you to actually add something like a Vec3 class or something like that\u2026 Check out the part on \u201cDefining Metamethods for a C Type\u201d on the <a href=\"http:\/\/luajit.org\/ext_ffi_tutorial.html\">FFI Tutorial<\/a>. It really shows off what you can do with this\u2026<\/p>\n<p align=\"justify\">The only issue I see is that class support is tricky, although you can use classes like this:<\/p>\n<p align=\"justify\">C code (assuming a classA):<\/p>\n<pre>\nextern \"C\" classA __declspec(dllexport) *classA_new() \n{ \n   return new classA; \n}\n\nextern \"C\" void __declspec(dllexport) classA_set_a(classA* __this,int a) \n{ \n   __this->set_a(a); \n}    \n\nextern \"C\" int    __declspec(dllexport) classA_get_a(classA* __this) \n{ \n   return __this->get_a(); \n} \n<\/pre>\n<\/p>\n<p align=\"justify\">Lua code:<\/p>\n<pre>\nlocal ffi = require(\"ffi\")ffi.cdef[[\n   typedef struct { void *__this; } classA;\n\n   classA*    classA_new();   \n   void       classA_set_a(classA* t,int a);   \n   int        classA_get_a(classA* t);\n]]\n\nlocal classAlocal classA_mt = \n   {  __index = \n        {   \n           set_a = function(t,a) ffi.C.classA_set_a(t,a) end,   \n           get_a = function(t) return ffi.C.classA_get_a(t) end,  \n        },\n   }\nclassA = ffi.metatype(\"classA\", classA_mt)\n\nfunction test()   \n   local object=ffi.C.classA_new()\n   print(object)\n   local value=object:get_a()\n   std.log(log_debug,string.format(\"Value=%i\",value))\n   object:set_a(25)\n   std.log(log_debug,string.format(\"Value=%i\",object:get_a()))\nend\n<\/pre>\n<\/p>\n<p>Very convenient indeed!<\/p>\n<p align=\"justify\">Only problem is that I designed the SurgePlayer Lua structure without this in mind, and suddenly I have what seems like a better way of doing things available\u2026 <\/p>\n<p align=\"justify\">Now I need to rethink the whole system to take advantage of this, but still keep some of the benefits I had on the previous system. <\/p>\n<p align=\"justify\">I believe it will be well worth the trouble! <img decoding=\"async\" style=\"border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none\" class=\"wlEmoticon wlEmoticon-smile\" alt=\"Smile\" src=\"http:\/\/shadowcovenant.com\/blog\/wp-content\/uploads\/2012\/01\/wlEmoticon-smile1.png\"><\/p>\n<p align=\"justify\">By the way, there\u2019s a new post down at <a href=\"http:\/\/www.spellcasterstudios.com\">http:\/\/www.spellcasterstudios.com<\/a>, with video! Check it out!<\/p>\n<p align=\"justify\">Until next time!<\/p>\n<div id=\"tweetbutton674\" class=\"tw_button\" style=\"\"><a href=\"http:\/\/twitter.com\/share?url=http%3A%2F%2Fshadowcovenant.com%2Fblog%2F2012%2F01%2F05%2Flua-jit%2F&amp;text=LUA%20JIT&amp;related=&amp;lang=en&amp;count=horizontal&amp;counturl=http%3A%2F%2Fshadowcovenant.com%2Fblog%2F2012%2F01%2F05%2Flua-jit%2F\" class=\"twitter-share-button\"  style=\"width:55px;height:22px;background:transparent url('http:\/\/shadowcovenant.com\/blog\/wp-content\/plugins\/wp-tweet-button\/tweetn.png') no-repeat  0 0;text-align:left;text-indent:-9999px;display:block;\">Tweet<\/a><\/div>","protected":false},"excerpt":{"rendered":"<p>Following the suggestion of one of my readers, I decided to take a deeper look into LUAJIT. At first glance, LUAJIT is a Just-In-Time compiler for Lua, that uses exactly the same interface as the normal Lua library, but compiles the code instead of interpreting, resulting in very significant speed improvements. Just that is enough [&hellip;]<\/p>\n<div id=\"tweetbutton674\" class=\"tw_button\" style=\"\"><a href=\"http:\/\/twitter.com\/share?url=http%3A%2F%2Fshadowcovenant.com%2Fblog%2F2012%2F01%2F05%2Flua-jit%2F&amp;text=LUA%20JIT&amp;related=&amp;lang=en&amp;count=horizontal&amp;counturl=http%3A%2F%2Fshadowcovenant.com%2Fblog%2F2012%2F01%2F05%2Flua-jit%2F\" class=\"twitter-share-button\"  style=\"width:55px;height:22px;background:transparent url('http:\/\/shadowcovenant.com\/blog\/wp-content\/plugins\/wp-tweet-button\/tweetn.png') no-repeat  0 0;text-align:left;text-indent:-9999px;display:block;\">Tweet<\/a><\/div>","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[23,6,91],"tags":[53,94,93,56,92,95,96],"class_list":["post-674","post","type-post","status-publish","format-standard","hentry","category-development","category-games","category-scripting","tag-c","tag-classes","tag-ffi","tag-lua","tag-luajit","tag-methods","tag-structs"],"_links":{"self":[{"href":"http:\/\/shadowcovenant.com\/blog\/wp-json\/wp\/v2\/posts\/674","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/shadowcovenant.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/shadowcovenant.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/shadowcovenant.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/shadowcovenant.com\/blog\/wp-json\/wp\/v2\/comments?post=674"}],"version-history":[{"count":4,"href":"http:\/\/shadowcovenant.com\/blog\/wp-json\/wp\/v2\/posts\/674\/revisions"}],"predecessor-version":[{"id":679,"href":"http:\/\/shadowcovenant.com\/blog\/wp-json\/wp\/v2\/posts\/674\/revisions\/679"}],"wp:attachment":[{"href":"http:\/\/shadowcovenant.com\/blog\/wp-json\/wp\/v2\/media?parent=674"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/shadowcovenant.com\/blog\/wp-json\/wp\/v2\/categories?post=674"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/shadowcovenant.com\/blog\/wp-json\/wp\/v2\/tags?post=674"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}