Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/LuaInterface/Lua/src/LuaDLL.cpp
2 views
1
2
using namespace System;
3
using namespace System::Runtime::InteropServices;
4
using namespace System::Reflection;
5
using namespace System::Collections;
6
using namespace System::Text;
7
using namespace System::Security;
8
9
// #include <vcclr.h>
10
// #define _WINNT_
11
// #include <WinDef.h>
12
#include <vcclr.h>
13
// #include <atlstr.h>
14
#include <stdio.h>
15
#using <mscorlib.dll>
16
#include <string.h>
17
18
#define LUA_BUILD_AS_DLL
19
#define LUA_LIB
20
#define LUA_CORE
21
#define lua_c
22
#define luac_c
23
#define loslib_c
24
25
extern "C"
26
{
27
#include "lua.h"
28
#include "lualib.h"
29
#include "lauxlib.h"
30
31
32
33
int iuplua_open(lua_State * L);
34
int iupcontrolslua_open(lua_State * L);
35
int luaopen_winapi(lua_State * L);
36
37
//luasocket
38
int luaopen_socket_core(lua_State *L);
39
int luaopen_mime_core(lua_State *L);
40
41
static void luaperks(lua_State *L)
42
{
43
#ifdef LUAPERKS
44
iuplua_open(L);
45
iupcontrolslua_open(L);
46
luaopen_winapi(L);
47
48
//luasocket - yeah, have to open this in a weird way
49
lua_pushcfunction(L,luaopen_socket_core);
50
lua_setglobal(L,"tmp");
51
luaL_dostring(L, "package.preload[\"socket.core\"] = _G.tmp");
52
lua_pushcfunction(L,luaopen_mime_core);
53
lua_setglobal(L,"tmp");
54
luaL_dostring(L, "package.preload[\"mime.core\"] = _G.tmp");
55
#endif
56
}
57
58
}
59
60
// Not sure of the purpose of this, but I'm keeping it -kevinh
61
static int tag = 0;
62
63
namespace Lua511
64
{
65
66
67
#if 1
68
#undef LUA_TNONE
69
#undef LUA_TNIL
70
#undef LUA_TNUMBER
71
#undef LUA_TSTRING
72
#undef LUA_TBOOLEAN
73
#undef LUA_TTABLE
74
#undef LUA_TFUNCTION
75
#undef LUA_TUSERDATA
76
#undef LUA_TLIGHTUSERDATA
77
78
/*
79
* Lua types for the API, returned by lua_type function
80
*/
81
public enum class LuaTypes
82
{
83
LUA_TNONE=-1,
84
LUA_TNIL=0,
85
LUA_TNUMBER=3,
86
LUA_TSTRING=4,
87
LUA_TBOOLEAN=1,
88
LUA_TTABLE=5,
89
LUA_TFUNCTION=6,
90
LUA_TUSERDATA=7,
91
LUA_TLIGHTUSERDATA=2
92
};
93
94
#endif
95
96
#if 1
97
#undef LUA_GCSTOP
98
#undef LUA_GCRESTART
99
#undef LUA_GCCOLLECT
100
#undef LUA_GCCOUNT
101
#undef LUA_GCCOUNTB
102
#undef LUA_GCSTEP
103
#undef LUA_GCSETPAUSE
104
#undef LUA_GCSETSTEPMUL
105
106
/*
107
* Lua Garbage Collector options (param "what")
108
*/
109
public enum class LuaGCOptions
110
{
111
LUA_GCSTOP = 0,
112
LUA_GCRESTART = 1,
113
LUA_GCCOLLECT = 2,
114
LUA_GCCOUNT = 3,
115
LUA_GCCOUNTB = 4,
116
LUA_GCSTEP = 5,
117
LUA_GCSETPAUSE = 6,
118
LUA_GCSETSTEPMUL = 7,
119
};
120
#endif
121
122
#undef LUA_REGISTRYINDEX
123
#undef LUA_ENVIRONINDEX
124
#undef LUA_GLOBALSINDEX
125
126
/*
127
* Special stack indexes
128
*/
129
public enum class LuaIndexes
130
{
131
LUA_REGISTRYINDEX=-10000,
132
LUA_ENVIRONINDEX=-10001,
133
LUA_GLOBALSINDEX=-10002
134
};
135
136
137
#if 0
138
/*
139
* Structure used by the chunk reader
140
*/
141
// [ StructLayout( LayoutKind.Sequential )]
142
public ref struct ReaderInfo
143
{
144
public String^ chunkData;
145
public bool finished;
146
};
147
148
149
/*
150
* Delegate for chunk readers used with lua_load
151
*/
152
public delegate String^ LuaChunkReader(IntPtr luaState, ReaderInfo ^data, uint size);
153
#endif
154
155
/*
156
* Delegate for functions passed to Lua as function pointers
157
*/
158
[System::Runtime::InteropServices::UnmanagedFunctionPointer(CallingConvention::Cdecl)]
159
public delegate int LuaCSFunction(IntPtr luaState);
160
161
// delegate for lua debug hook callback (by Reinhard Ostermeier)
162
[System::Runtime::InteropServices::UnmanagedFunctionPointer(CallingConvention::Cdecl)]
163
public delegate void LuaHookFunction(IntPtr luaState, IntPtr luaDebug);
164
165
166
// To fix the strings:
167
// http://support.microsoft.com/kb/311259
168
169
public ref class LuaDLL
170
{
171
// steffenj: BEGIN additional Lua API functions new in Lua 5.1
172
public:
173
174
#define toState ((lua_State *) luaState.ToPointer())
175
176
static int lua_gc(IntPtr luaState, LuaGCOptions what, int data)
177
{
178
return ::lua_gc(toState, (int) what, data);
179
}
180
181
static String^ lua_typename(IntPtr luaState, LuaTypes type)
182
{
183
return gcnew String(::lua_typename(toState, (int) type));
184
}
185
186
#undef luaL_typename
187
188
static String^ luaL_typename(IntPtr luaState, int stackPos)
189
{
190
return lua_typename(luaState, lua_type(luaState, stackPos));
191
}
192
193
static void luaL_error(IntPtr luaState, String^ message)
194
{
195
char *cs = (char *) Marshal::StringToHGlobalAnsi(message).ToPointer();
196
197
::luaL_error(toState, cs);
198
Marshal::FreeHGlobal(IntPtr(cs));
199
}
200
201
static void luaL_where(IntPtr luaState, int level)
202
{
203
::luaL_where(toState, level);
204
}
205
206
207
// Not yet wrapped
208
// static String^ luaL_gsub(IntPtr luaState, String^ str, String^ pattern, String^ replacement);
209
210
#if 0
211
// the functions below are still untested
212
static void lua_getfenv(IntPtr luaState, int stackPos);
213
static int lua_isfunction(IntPtr luaState, int stackPos);
214
static int lua_islightuserdata(IntPtr luaState, int stackPos);
215
static int lua_istable(IntPtr luaState, int stackPos);
216
static int lua_isuserdata(IntPtr luaState, int stackPos);
217
static int lua_lessthan(IntPtr luaState, int stackPos1, int stackPos2);
218
static int lua_rawequal(IntPtr luaState, int stackPos1, int stackPos2);
219
static int lua_setfenv(IntPtr luaState, int stackPos);
220
static void lua_setfield(IntPtr luaState, int stackPos, String^ name);
221
static int luaL_callmeta(IntPtr luaState, int stackPos, String^ name);
222
// steffenj: END additional Lua API functions new in Lua 5.1
223
#endif
224
225
// steffenj: BEGIN Lua 5.1.1 API change (lua_open replaced by luaL_newstate)
226
static IntPtr luaL_newstate()
227
{
228
return IntPtr(::luaL_newstate());
229
}
230
231
static void lua_close(IntPtr luaState)
232
{
233
::lua_close(toState);
234
}
235
236
// steffenj: BEGIN Lua 5.1.1 API change (new function luaL_openlibs)
237
static void luaL_openlibs(IntPtr luaState)
238
{
239
::luaL_openlibs(toState);
240
::luaperks(toState);
241
}
242
243
// Not yet wrapped
244
// static int lua_objlen(IntPtr luaState, int stackPos);
245
246
// steffenj: END Lua 5.1.1 API change (lua_strlen is now lua_objlen)
247
// steffenj: BEGIN Lua 5.1.1 API change (lua_doString^ is now a macro luaL_dostring)
248
static int luaL_loadstring(IntPtr luaState, String^ chunk)
249
{
250
char *cs = (char *) Marshal::StringToHGlobalAnsi(chunk).ToPointer();
251
252
int result = ::luaL_loadstring(toState, cs);
253
Marshal::FreeHGlobal(IntPtr(cs));
254
255
return result;
256
}
257
258
#undef luaL_dostring
259
260
static int luaL_dostring(IntPtr luaState, String^ chunk)
261
{
262
int result = luaL_loadstring(luaState, chunk);
263
if (result != 0)
264
return result;
265
266
return lua_pcall(luaState, 0, -1, 0);
267
}
268
269
/// <summary>DEPRECATED - use luaL_dostring(IntPtr luaState, string chunk) instead!</summary>
270
static int lua_dostring(IntPtr luaState, String^ chunk)
271
{
272
return luaL_dostring(luaState, chunk);
273
}
274
275
// steffenj: END Lua 5.1.1 API change (lua_dostring is now a macro luaL_dostring)
276
// steffenj: BEGIN Lua 5.1.1 API change (lua_newtable is gone, lua_createtable is new)
277
static void lua_createtable(IntPtr luaState, int narr, int nrec)
278
{
279
::lua_createtable(toState, narr, nrec);
280
}
281
282
#undef lua_newtable
283
284
static void lua_newtable(IntPtr luaState)
285
{
286
lua_createtable(luaState, 0, 0);
287
}
288
289
#undef luaL_dofile
290
291
// steffenj: END Lua 5.1.1 API change (lua_newtable is gone, lua_createtable is new)
292
// steffenj: BEGIN Lua 5.1.1 API change (lua_dofile now in LuaLib as luaL_dofile macro)
293
static int luaL_dofile(IntPtr luaState, String^ fileName)
294
{
295
char *cs = (char *) Marshal::StringToHGlobalAnsi(fileName).ToPointer();
296
297
int result = ::luaL_loadfile(toState, cs);
298
299
//CP: Free filename string before return to ensure a file that isnt found still has the string freed (submitted by paul moore)
300
//link: http://luaforge.net/forum/forum.php?thread_id=2825&forum_id=145
301
Marshal::FreeHGlobal(IntPtr(cs));
302
303
if (result != 0)
304
return result;
305
306
return ::lua_pcall(toState, 0, -1, 0);
307
}
308
309
#undef lua_getglobal
310
311
// steffenj: END Lua 5.1.1 API change (lua_dofile now in LuaLib as luaL_dofile)
312
static void lua_getglobal(IntPtr luaState, String^ name)
313
{
314
lua_pushstring(luaState, name);
315
::lua_gettable(toState, (int) LuaIndexes::LUA_GLOBALSINDEX);
316
}
317
318
#undef lua_setglobal
319
320
static void lua_setglobal(IntPtr luaState, String^ name)
321
{
322
lua_pushstring(luaState,name);
323
lua_insert(luaState,-2);
324
lua_settable(luaState, (int) LuaIndexes::LUA_GLOBALSINDEX);
325
}
326
327
static void lua_settop(IntPtr luaState, int newTop)
328
{
329
::lua_settop(toState, newTop);
330
}
331
332
333
#undef lua_pop
334
335
static void lua_pop(IntPtr luaState, int amount)
336
{
337
lua_settop(luaState, -(amount) - 1);
338
}
339
340
static void lua_insert(IntPtr luaState, int newTop)
341
{
342
::lua_insert(toState, newTop);
343
}
344
345
static void lua_remove(IntPtr luaState, int index)
346
{
347
::lua_remove(toState, index);
348
}
349
350
static void lua_gettable(IntPtr luaState, int index)
351
{
352
::lua_gettable(toState, index);
353
}
354
355
356
static void lua_rawget(IntPtr luaState, int index)
357
{
358
::lua_rawget(toState, index);
359
}
360
361
362
static void lua_settable(IntPtr luaState, int index)
363
{
364
::lua_settable(toState, index);
365
}
366
367
368
static void lua_rawset(IntPtr luaState, int index)
369
{
370
::lua_rawset(toState, index);
371
}
372
373
static IntPtr lua_newthread(IntPtr luaState)
374
{
375
return IntPtr(::lua_newthread(toState));
376
}
377
378
static int lua_resume(IntPtr luaState, int narg)
379
{
380
return ::lua_resume(toState, narg);
381
}
382
383
static int lua_yield(IntPtr luaState, int nresults)
384
{
385
return ::lua_yield(toState, nresults);
386
}
387
388
389
static void lua_setmetatable(IntPtr luaState, int objIndex)
390
{
391
::lua_setmetatable(toState, objIndex);
392
}
393
394
395
static int lua_getmetatable(IntPtr luaState, int objIndex)
396
{
397
return ::lua_getmetatable(toState, objIndex);
398
}
399
400
401
static int lua_equal(IntPtr luaState, int index1, int index2)
402
{
403
return ::lua_equal(toState, index1, index2);
404
}
405
406
407
static void lua_pushvalue(IntPtr luaState, int index)
408
{
409
::lua_pushvalue(toState, index);
410
}
411
412
413
static void lua_replace(IntPtr luaState, int index)
414
{
415
::lua_replace(toState, index);
416
}
417
418
static int lua_gettop(IntPtr luaState)
419
{
420
return ::lua_gettop(toState);
421
}
422
423
424
static LuaTypes lua_type(IntPtr luaState, int index)
425
{
426
return (LuaTypes) ::lua_type(toState, index);
427
}
428
429
#undef lua_isnil
430
431
static bool lua_isnil(IntPtr luaState, int index)
432
{
433
return lua_type(luaState,index)==LuaTypes::LUA_TNIL;
434
}
435
436
static bool lua_isnumber(IntPtr luaState, int index)
437
{
438
return lua_type(luaState,index)==LuaTypes::LUA_TNUMBER;
439
}
440
441
#undef lua_isboolean
442
443
static bool lua_isboolean(IntPtr luaState, int index)
444
{
445
return lua_type(luaState,index)==LuaTypes::LUA_TBOOLEAN;
446
}
447
448
static int luaL_ref(IntPtr luaState, int registryIndex)
449
{
450
return ::luaL_ref(toState, registryIndex);
451
}
452
453
#undef lua_ref
454
455
static int lua_ref(IntPtr luaState, int lockRef)
456
{
457
if(lockRef!=0)
458
{
459
return luaL_ref(luaState, (int) LuaIndexes::LUA_REGISTRYINDEX);
460
}
461
else return 0;
462
}
463
464
static void lua_rawgeti(IntPtr luaState, int tableIndex, int index)
465
{
466
::lua_rawgeti(toState, tableIndex, index);
467
}
468
469
static void lua_rawseti(IntPtr luaState, int tableIndex, int index)
470
{
471
::lua_rawseti(toState, tableIndex, index);
472
}
473
474
475
static IntPtr lua_newuserdata(IntPtr luaState, int size)
476
{
477
return IntPtr(::lua_newuserdata(toState, size));
478
}
479
480
481
static IntPtr lua_touserdata(IntPtr luaState, int index)
482
{
483
return IntPtr(::lua_touserdata(toState, index));
484
}
485
486
#undef lua_getref
487
488
static void lua_getref(IntPtr luaState, int reference)
489
{
490
lua_rawgeti(luaState, (int) LuaIndexes::LUA_REGISTRYINDEX,reference);
491
}
492
493
// Unwrapped
494
// static void luaL_unref(IntPtr luaState, int registryIndex, int reference);
495
496
#undef lua_unref
497
498
static void lua_unref(IntPtr luaState, int reference)
499
{
500
::luaL_unref(toState, (int) LuaIndexes::LUA_REGISTRYINDEX,reference);
501
}
502
503
static bool lua_isstring(IntPtr luaState, int index)
504
{
505
return ::lua_isstring(toState, index) != 0;
506
}
507
508
509
static bool lua_iscfunction(IntPtr luaState, int index)
510
{
511
return ::lua_iscfunction(toState, index) != 0;
512
}
513
514
static void lua_pushnil(IntPtr luaState)
515
{
516
::lua_pushnil(toState);
517
}
518
519
520
521
static void lua_call(IntPtr luaState, int nArgs, int nResults)
522
{
523
::lua_call(toState, nArgs, nResults);
524
}
525
526
static int lua_pcall(IntPtr luaState, int nArgs, int nResults, int errfunc)
527
{
528
return ::lua_pcall(toState, nArgs, nResults, errfunc);
529
}
530
531
// static int lua_rawcall(IntPtr luaState, int nArgs, int nResults)
532
533
static IntPtr lua_tocfunction(IntPtr luaState, int index)
534
{
535
return IntPtr(::lua_tocfunction(toState, index));
536
}
537
538
static double lua_tonumber(IntPtr luaState, int index)
539
{
540
return ::lua_tonumber(toState, index);
541
}
542
543
544
static bool lua_toboolean(IntPtr luaState, int index)
545
{
546
return ::lua_toboolean(toState, index);
547
}
548
549
// unwrapped
550
// was out strLen
551
// static IntPtr lua_tolstring(IntPtr luaState, int index, [Out] int ^ strLen);
552
553
#undef lua_tostring
554
555
static String^ lua_tostring(IntPtr luaState, int index)
556
{
557
#if 1
558
// FIXME use the same format string as lua i.e. LUA_NUMBER_FMT
559
LuaTypes t = lua_type(luaState,index);
560
561
if(t == LuaTypes::LUA_TNUMBER)
562
return String::Format("{0}", lua_tonumber(luaState, index));
563
else if(t == LuaTypes::LUA_TSTRING)
564
{
565
size_t strlen;
566
567
const char *str = ::lua_tolstring(toState, index, &strlen);
568
return Marshal::PtrToStringAnsi(IntPtr((char *) str), strlen);
569
}
570
else if(t == LuaTypes::LUA_TNIL)
571
return nullptr; // treat lua nulls to as C# nulls
572
else
573
return gcnew String("0"); // Because luaV_tostring does this
574
#else
575
576
577
size_t strlen;
578
579
// Note! This method will _change_ the representation of the object on the stack to a string.
580
// We do not want this behavior so we do the conversion ourselves
581
const char *str = ::lua_tolstring(toState, index, &strlen);
582
if (str)
583
return Marshal::PtrToStringAnsi(IntPtr((char *) str), strlen);
584
else
585
return nullptr; // treat lua nulls to as C# nulls
586
#endif
587
}
588
589
static void lua_atpanic(IntPtr luaState, LuaCSFunction^ panicf)
590
{
591
IntPtr p = Marshal::GetFunctionPointerForDelegate(panicf);
592
::lua_atpanic(toState, (lua_CFunction) p.ToPointer());
593
}
594
595
#if 0
596
// no longer needed - all our functions are now stdcall calling convention
597
static int stdcall_closure(lua_State *L) {
598
lua_CFunction fn = (lua_CFunction)lua_touserdata(L, lua_upvalueindex(1));
599
return fn(L);
600
}
601
#endif
602
603
static void lua_pushstdcallcfunction(IntPtr luaState, LuaCSFunction^ function)
604
{
605
IntPtr p = Marshal::GetFunctionPointerForDelegate(function);
606
lua_pushcfunction(toState, (lua_CFunction) p.ToPointer());
607
}
608
609
610
#if 0
611
// not yet implemented
612
static void lua_atlock(IntPtr luaState, LuaCSFunction^ lockf)
613
{
614
IntPtr p = Marshal::GetFunctionPointerForDelegate(lockf);
615
::lua_atlock(toState, (lua_CFunction) p.ToPointer());
616
}
617
618
static void lua_atunlock(IntPtr luaState, LuaCSFunction^ unlockf);
619
#endif
620
621
static void lua_pushnumber(IntPtr luaState, double number)
622
{
623
::lua_pushnumber(toState, number);
624
}
625
626
static void lua_pushboolean(IntPtr luaState, bool value)
627
{
628
::lua_pushboolean(toState, value);
629
}
630
631
#if 0
632
// Not yet wrapped
633
static void lua_pushlstring(IntPtr luaState, String^ str, int size)
634
{
635
char *cs = (char *) Marshal::StringToHGlobalAnsi(str).ToPointer();
636
637
//
638
639
Marshal::FreeHGlobal(IntPtr(cs));
640
}
641
#endif
642
643
644
static void lua_pushstring(IntPtr luaState, String^ str)
645
{
646
char *cs = (char *) Marshal::StringToHGlobalAnsi(str).ToPointer();
647
648
::lua_pushstring(toState, cs);
649
650
Marshal::FreeHGlobal(IntPtr(cs));
651
}
652
653
654
static int luaL_newmetatable(IntPtr luaState, String^ meta)
655
{
656
char *cs = (char *) Marshal::StringToHGlobalAnsi(meta).ToPointer();
657
658
int result = ::luaL_newmetatable(toState, cs);
659
660
Marshal::FreeHGlobal(IntPtr(cs));
661
662
return result;
663
}
664
665
666
// steffenj: BEGIN Lua 5.1.1 API change (luaL_getmetatable is now a macro using lua_getfield)
667
static void lua_getfield(IntPtr luaState, int stackPos, String^ meta)
668
{
669
char *cs = (char *) Marshal::StringToHGlobalAnsi(meta).ToPointer();
670
671
::lua_getfield(toState, stackPos, cs);
672
673
Marshal::FreeHGlobal(IntPtr(cs));
674
}
675
676
#undef luaL_getmetatable
677
678
static void luaL_getmetatable(IntPtr luaState, String^ meta)
679
{
680
lua_getfield(luaState, (int) LuaIndexes::LUA_REGISTRYINDEX, meta);
681
}
682
683
static IntPtr luaL_checkudata(IntPtr luaState, int stackPos, String^ meta)
684
{
685
char *cs = (char *) Marshal::StringToHGlobalAnsi(meta).ToPointer();
686
687
void *result = ::luaL_checkudata(toState, stackPos, cs);
688
689
Marshal::FreeHGlobal(IntPtr(cs));
690
691
return IntPtr(result);
692
}
693
694
static bool luaL_getmetafield(IntPtr luaState, int stackPos, String^ field)
695
{
696
char *cs = (char *) Marshal::StringToHGlobalAnsi(field).ToPointer();
697
698
int result = ::luaL_getmetafield(toState, stackPos, cs);
699
700
Marshal::FreeHGlobal(IntPtr(cs));
701
702
return result != 0;
703
}
704
705
// wrapper not yet implemented
706
// static int lua_load(IntPtr luaState, LuaChunkReader chunkReader, ref ReaderInfo data, String^ chunkName);
707
708
static int luaL_loadbuffer(IntPtr luaState, String^ buff, String^ name)
709
{
710
//zero 23-may-2016 - get rid of this GARBAGE. lua can load UTF-8, why not use that?
711
//char *cs1 = (char *) Marshal::StringToHGlobalAnsi(buff).ToPointer();
712
//char *cs2 = (char *) Marshal::StringToHGlobalAnsi(name).ToPointer();
713
////CP: fix for MBCS, changed to use cs1's length (reported by qingrui.li)
714
//int result = ::luaL_loadbuffer(toState, cs1, strlen(cs1), cs2);
715
//Marshal::FreeHGlobal(IntPtr(cs1));
716
//Marshal::FreeHGlobal(IntPtr(cs2));
717
718
array<System::Byte> ^ _buff = System::Text::Encoding::UTF8->GetBytes(buff);
719
array<System::Byte> ^ _name = System::Text::Encoding::UTF8->GetBytes(name);
720
char* lbuff = "", *lname = nullptr;
721
pin_ptr<System::Byte> p_buff, p_name;
722
if(buff->Length != 0) { p_buff = &_buff[0]; lbuff = (char*)(System::Byte*)p_buff; }
723
if(name->Length != 0) { p_name= &_name[0]; lname = (char*)(System::Byte*)p_name; }
724
725
return ::luaL_loadbuffer(toState, lbuff, _buff->Length, lname);
726
}
727
728
static int luaL_loadfile(IntPtr luaState, String^ filename)
729
{
730
char *cs = (char *) Marshal::StringToHGlobalAnsi(filename).ToPointer();
731
int result = ::luaL_loadfile(toState, cs);
732
733
Marshal::FreeHGlobal(IntPtr(cs));
734
735
return result;
736
}
737
738
static void lua_error(IntPtr luaState)
739
{
740
::lua_error(toState);
741
}
742
743
744
static bool lua_checkstack(IntPtr luaState,int extra)
745
{
746
return ::lua_checkstack(toState, extra) != 0;
747
}
748
749
750
static int lua_next(IntPtr luaState,int index)
751
{
752
return ::lua_next(toState, index);
753
}
754
755
756
757
758
static void lua_pushlightuserdata(IntPtr luaState, IntPtr udata)
759
{
760
::lua_pushlightuserdata(toState, udata.ToPointer());
761
}
762
763
static int luanet_rawnetobj(IntPtr luaState,int obj)
764
{
765
int *udata= (int *) lua_touserdata(luaState, obj).ToPointer();
766
if(udata!=NULL) return *udata;
767
return -1;
768
}
769
770
771
// lua debug hook functions added by Reinhard Ostermeier
772
773
static int lua_sethook(IntPtr luaState, LuaHookFunction^ func, int mask, int count)
774
{
775
IntPtr p;
776
if (func == nullptr)
777
{
778
p = IntPtr::Zero;
779
}
780
else
781
{
782
p = Marshal::GetFunctionPointerForDelegate(func);
783
}
784
return ::lua_sethook(toState, (lua_Hook)p.ToPointer(), mask, count);
785
}
786
787
static int lua_gethookmask(IntPtr luaState)
788
{
789
return ::lua_gethookmask(toState);
790
}
791
792
static int lua_gethookcount(IntPtr luaState)
793
{
794
return ::lua_gethookcount(toState);
795
}
796
797
static int lua_getstack(IntPtr luaState, int level, IntPtr luaDebug)
798
{
799
return ::lua_getstack(toState, level, (lua_Debug*)luaDebug.ToPointer());
800
}
801
802
static int lua_getinfo(IntPtr luaState, String^ what, IntPtr luaDebug)
803
{
804
char *cs = (char *) Marshal::StringToHGlobalAnsi(what).ToPointer();
805
int ret = ::lua_getinfo(toState, cs, (lua_Debug*)luaDebug.ToPointer());
806
Marshal::FreeHGlobal(IntPtr(cs));
807
return ret;
808
}
809
810
static String^ lua_getlocal(IntPtr luaState, IntPtr luaDebug, int n)
811
{
812
const char* str = ::lua_getlocal(toState, (lua_Debug*)luaDebug.ToPointer(), n);
813
if (str == NULL)
814
{
815
return nullptr;
816
}
817
else
818
{
819
return gcnew String(str);
820
}
821
}
822
823
static String^ lua_setlocal(IntPtr luaState, IntPtr luaDebug, int n)
824
{
825
const char* str = ::lua_setlocal(toState, (lua_Debug*)luaDebug.ToPointer(), n);
826
if(str == NULL)
827
{
828
return nullptr;
829
}
830
else
831
{
832
return gcnew String(str);
833
}
834
}
835
836
static String^ lua_getupvalue(IntPtr luaState, int funcindex, int n)
837
{
838
const char* str = ::lua_getupvalue(toState, funcindex, n);
839
if(str == NULL)
840
{
841
return nullptr;
842
}
843
else
844
{
845
return gcnew String(str);
846
}
847
}
848
849
static String^ lua_setupvalue(IntPtr luaState, int funcindex, int n)
850
{
851
const char* str = ::lua_setupvalue(toState, funcindex, n);
852
if(str == NULL)
853
{
854
return nullptr;
855
}
856
else
857
{
858
return gcnew String(str);
859
}
860
}
861
862
// end of lua debug hook functions
863
864
private:
865
866
// Starting with 5.1 the auxlib version of checkudata throws an exception if the type isn't right
867
// Instead, we want to run our own version that checks the type and just returns null for failure
868
static void *checkudata_raw(lua_State *L, int ud, const char *tname)
869
{
870
void *p = ::lua_touserdata(L, ud);
871
872
if (p != NULL)
873
{ /* value is a userdata? */
874
if (::lua_getmetatable(L, ud))
875
{
876
int isEqual;
877
878
/* does it have a metatable? */
879
::lua_getfield(L, (int) LuaIndexes::LUA_REGISTRYINDEX, tname); /* get correct metatable */
880
881
isEqual = lua_rawequal(L, -1, -2);
882
883
// NASTY - we need our own version of the lua_pop macro
884
// lua_pop(L, 2); /* remove both metatables */
885
::lua_settop(L, -(2) - 1);
886
887
if (isEqual) /* does it have the correct mt? */
888
return p;
889
}
890
}
891
892
return NULL;
893
}
894
895
896
public:
897
898
static int luanet_checkudata(IntPtr luaState, int ud, String ^tname)
899
{
900
char *cs = (char *) Marshal::StringToHGlobalAnsi(tname).ToPointer();
901
902
int *udata=(int*) checkudata_raw(toState, ud, cs);
903
904
Marshal::FreeHGlobal(IntPtr(cs));
905
906
if(udata!=NULL) return *udata;
907
return -1;
908
}
909
910
911
static bool luaL_checkmetatable(IntPtr luaState,int index)
912
{
913
int retVal=0;
914
915
if(lua_getmetatable(luaState,index)!=0)
916
{
917
lua_pushlightuserdata(luaState, IntPtr(&tag));
918
lua_rawget(luaState, -2);
919
retVal = !lua_isnil(luaState, -1);
920
lua_settop(luaState, -3);
921
}
922
return retVal;
923
}
924
925
static IntPtr luanet_gettag()
926
{
927
return IntPtr(&tag);
928
}
929
930
static void luanet_newudata(IntPtr luaState,int val)
931
{
932
int* pointer=(int*) lua_newuserdata(luaState, sizeof(int)).ToPointer();
933
*pointer=val;
934
}
935
936
static int luanet_tonetobject(IntPtr luaState,int index)
937
{
938
int *udata;
939
940
if(lua_type(luaState,index)==LuaTypes::LUA_TUSERDATA)
941
{
942
if(luaL_checkmetatable(luaState, index))
943
{
944
udata=(int*) lua_touserdata(luaState,index).ToPointer();
945
if(udata!=NULL)
946
return *udata;
947
}
948
949
udata=(int*)checkudata_raw(toState,index, "luaNet_class");
950
if(udata!=NULL) return *udata;
951
udata=(int*)checkudata_raw(toState,index, "luaNet_searchbase");
952
if(udata!=NULL) return *udata;
953
udata=(int*)checkudata_raw(toState,index, "luaNet_function");
954
if(udata!=NULL) return *udata;
955
}
956
return -1;
957
}
958
959
960
#if 0
961
962
963
[DllImport(STUBDLL,CallingConvention=CallingConvention.Cdecl)]
964
965
#endif
966
};
967
}
968
969