⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcoco.c

📁 lua的即时编译器。支持lua 5.1.2版本
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** Copyright (C) 2004-2007 Mike Pall. All rights reserved.**** Permission is hereby granted, free of charge, to any person obtaining** a copy of this software and associated documentation files (the** "Software"), to deal in the Software without restriction, including** without limitation the rights to use, copy, modify, merge, publish,** distribute, sublicense, and/or sell copies of the Software, and to** permit persons to whom the Software is furnished to do so, subject to** the following conditions:**** The above copyright notice and this permission notice shall be** included in all copies or substantial portions of the Software.**** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.**** [ MIT license: http://www.opensource.org/licenses/mit-license.php ]*//* Coco -- True C coroutines for Lua. http://luajit.org/coco.html */#ifndef COCO_DISABLE#define lcoco_c#define LUA_CORE#include "lua.h"#include "lobject.h"#include "lstate.h"#include "ldo.h"#include "lvm.h"#include "lgc.h"/*** Define this if you want to run Coco with valgrind. You will get random** errors about accessing memory from newly allocated C stacks if you don't.** You need at least valgrind 3.0 for this to work.**** This macro evaluates to a no-op if not run with valgrind. I.e. you can** use the same binary for regular runs, too (without a performance loss).*/#ifdef USE_VALGRIND#include <valgrind/valgrind.h>#define STACK_REG(coco, p, sz)	(coco)->vgid = VALGRIND_STACK_REGISTER(p, p+sz);#define STACK_DEREG(coco)	VALGRIND_STACK_DEREGISTER((coco)->vgid);#define STACK_VGID		unsigned int vgid;#else#define STACK_REG(coco, p, sz)#define STACK_DEREG(id)#define STACK_VGID#endif/* ------------------------------------------------------------------------ *//* Use Windows Fibers. */#if defined(COCO_USE_FIBERS)#define _WIN32_WINNT 0x0400#include <windows.h>#define COCO_MAIN_DECL		CALLBACKtypedef LPFIBER_START_ROUTINE coco_MainFunc;#define COCO_NEW(OL, NL, cstacksize, mainfunc) \  if ((L2COCO(NL)->fib = CreateFiber(cstacksize, mainfunc, NL)) == NULL) \    luaD_throw(OL, LUA_ERRMEM);#define COCO_FREE(L) \  DeleteFiber(L2COCO(L)->fib); \  L2COCO(L)->fib = NULL;/* See: http://blogs.msdn.com/oldnewthing/archive/2004/12/31/344799.aspx */#define COCO_JUMPIN(coco) \  { void *cur = GetCurrentFiber(); \    coco->back = (cur == NULL || cur == (void *)0x1e00) ? \      ConvertThreadToFiber(NULL) : cur; } \  SwitchToFiber(coco->fib);#define COCO_JUMPOUT(coco) \  SwitchToFiber(coco->back);/* CreateFiber() defaults to STACKSIZE from the Windows module .def file. */#define COCO_DEFAULT_CSTACKSIZE		0/* ------------------------------------------------------------------------ */#else /* !COCO_USE_FIBERS */#ifndef COCO_USE_UCONTEXT/* Try inline asm first. */#if __GNUC__ >= 3 && !defined(COCO_USE_SETJMP)#if defined(__i386) || defined(__i386__)#ifdef __PIC__typedef void *coco_ctx[4];  /* eip, esp, ebp, ebx */static inline void coco_switch(coco_ctx from, coco_ctx to){  __asm__ __volatile__ (    "call 1f\n" "1:\tpopl %%eax\n\t" "addl $(2f-1b),%%eax\n\t"    "movl %%eax, (%0)\n\t" "movl %%esp, 4(%0)\n\t"    "movl %%ebp, 8(%0)\n\t" "movl %%ebx, 12(%0)\n\t"    "movl 12(%1), %%ebx\n\t" "movl 8(%1), %%ebp\n\t"    "movl 4(%1), %%esp\n\t" "jmp *(%1)\n" "2:\n"    : "+S" (from), "+D" (to) : : "eax", "ecx", "edx", "memory", "cc");}#elsetypedef void *coco_ctx[3];  /* eip, esp, ebp */static inline void coco_switch(coco_ctx from, coco_ctx to){  __asm__ __volatile__ (    "movl $1f, (%0)\n\t" "movl %%esp, 4(%0)\n\t" "movl %%ebp, 8(%0)\n\t"    "movl 8(%1), %%ebp\n\t" "movl 4(%1), %%esp\n\t" "jmp *(%1)\n" "1:\n"    : "+S" (from), "+D" (to) : : "eax", "ebx", "ecx", "edx", "memory", "cc");}#endif#define COCO_CTX		coco_ctx#define COCO_SWITCH(from, to)	coco_switch(from, to);#define COCO_MAKECTX(coco, buf, func, stack, a0) \  buf[0] = (void *)(func); \  buf[1] = (void *)(stack); \  buf[2] = (void *)0; \  stack[0] = 0xdeadc0c0;  /* Dummy return address. */ \  coco->arg0 = (size_t)(a0);#define COCO_STATE_HEAD		size_t arg0;#elif __mips && _MIPS_SIM == _MIPS_SIM_ABI32 && !defined(__mips_eabi)/* No way to avoid the function prologue with inline assembler. So use this: */static const unsigned int coco_switch[] = {#ifdef __mips_soft_float#define COCO_STACKSAVE		-10  0x27bdffd8,  /* addiu sp, sp, -(10*4) */#else#define COCO_STACKSAVE		-22  0x27bdffa8,  /* addiu sp, sp, -(10*4+6*8) */  /* sdc1 {$f20-$f30}, offset(sp) */  0xf7be0050, 0xf7bc0048, 0xf7ba0040, 0xf7b80038, 0xf7b60030, 0xf7b40028,#endif  /* sw {gp,s0-s8}, offset(sp) */  0xafbe0024, 0xafb70020, 0xafb6001c, 0xafb50018, 0xafb40014, 0xafb30010,  0xafb2000c, 0xafb10008, 0xafb00004, 0xafbc0000,  /* sw sp, 4(a0); sw ra, 0(a0); lw ra, 0(a1); lw sp, 4(a1); move t9, ra */  0xac9d0004, 0xac9f0000, 0x8cbf0000, 0x8cbd0004, 0x03e0c821,  /* lw caller-saved-reg, offset(sp) */  0x8fbe0024, 0x8fb70020, 0x8fb6001c, 0x8fb50018, 0x8fb40014, 0x8fb30010,  0x8fb2000c, 0x8fb10008, 0x8fb00004, 0x8fbc0000,#ifdef __mips_soft_float  0x03e00008, 0x27bd0028  /* jr ra; addiu sp, sp, 10*4 */#else  /* ldc1 {$f20-$f30}, offset(sp) */  0xd7be0050, 0xd7bc0048, 0xd7ba0040, 0xd7b80038, 0xd7b60030, 0xd7b40028,  0x03e00008, 0x27bd0058  /* jr ra; addiu sp, sp, 10*4+6*8 */#endif};typedef void *coco_ctx[2];  /* ra, sp */#define COCO_CTX		coco_ctx#define COCO_SWITCH(from, to) \  ((void (*)(coco_ctx, coco_ctx))coco_switch)(from, to);#define COCO_MAKECTX(coco, buf, func, stack, a0) \  buf[0] = (void *)(func); \  buf[1] = (void *)&stack[COCO_STACKSAVE]; \  stack[4] = (size_t)(a0);  /* Assumes o32 ABI. */#define COCO_STACKADJUST	8#define COCO_MAIN_PARAM		int _a, int _b, int _c, int _d, lua_State *L#endif /* arch check */#endif /* !(__GNUC__ >= 3 && !defined(COCO_USE_SETJMP)) *//* Try _setjmp/_longjmp with a patched jump buffer. */#ifndef COCO_MAKECTX#include <setjmp.h>/* Check for supported CPU+OS combinations. */#if defined(__i386) || defined(__i386__)#define COCO_STATE_HEAD		size_t arg0;#define COCO_SETJMP_X86(coco, stack, a0) \  stack[COCO_STACKADJUST-1] = 0xdeadc0c0;  /* Dummy return address. */ \  coco->arg0 = (size_t)(a0);#if __GLIBC__ == 2 && defined(JB_SP)		/* x86-linux-glibc2 */#define COCO_PATCHCTX(coco, buf, func, stack, a0) \  buf->__jmpbuf[JB_PC] = (int)(func); \  buf->__jmpbuf[JB_SP] = (int)(stack); \  buf->__jmpbuf[JB_BP] = 0; \  COCO_SETJMP_X86(coco, stack, a0)#elif defined(__linux__) && defined(_I386_JMP_BUF_H)	/* x86-linux-libc5 */#define COCO_PATCHCTX(coco, buf, func, stack, a0) \  buf->__pc = (func); \  buf->__sp = (stack); \  buf->__bp = NULL; \  COCO_SETJMP_X86(coco, stack, a0)#elif defined(__FreeBSD__)			/* x86-FreeBSD */#define COCO_PATCHCTX(coco, buf, func, stack, a0) \  buf->_jb[0] = (long)(func); \  buf->_jb[2] = (long)(stack); \  buf->_jb[3] = 0; /* ebp */ \  COCO_SETJMP_X86(coco, stack, a0)#define COCO_STACKADJUST	2#elif defined(__NetBSD__) || defined(__OpenBSD__) /* x86-NetBSD, x86-OpenBSD */#define COCO_PATCHCTX(coco, buf, func, stack, a0) \  buf[0] = (long)(func); \  buf[2] = (long)(stack); \  buf[3] = 0; /* ebp */ \  COCO_SETJMP_X86(coco, stack, a0)#define COCO_STACKADJUST	2#elif defined(__solaris__) && _JBLEN == 10	/* x86-solaris */#define COCO_PATCHCTX(coco, buf, func, stack, a0) \  buf[5] = (int)(func); \  buf[4] = (int)(stack); \  buf[3] = 0; \  COCO_SETJMP_X86(coco, stack, a0)#elif defined(__MACH__) && defined(_BSD_I386_SETJMP_H_)	/* x86-macosx */#define COCO_PATCHCTX(coco, buf, func, stack, a0) \  buf[12] = (int)(func); \  buf[9] = (int)(stack); \  buf[8] = 0; /* ebp */ \  COCO_SETJMP_X86(coco, stack, a0)#endif#elif defined(__x86_64__) || defined(__x86_64)#define COCO_STATE_HEAD		size_t arg0;#define COCO_MAIN_PARAM \  int _a, int _b, int _c, int _d, int _e, int _f, lua_State *L#if __GLIBC__ == 2 && defined(JB_RSP)		/* x64-linux-glibc2 */#define COCO_PATCHCTX(coco, buf, func, stack, a0) \  buf->__jmpbuf[JB_PC] = (long)(func); \  buf->__jmpbuf[JB_RSP] = (long)(stack); \  buf->__jmpbuf[JB_RBP] = 0; \  stack[0] = 0xdeadc0c0;  /* Dummy return address. */ \  coco->arg0 = (size_t)(a0);#elif defined(__solaris__) && _JBLEN == 8		/* x64-solaris */#define COCO_PATCHCTX(coco, buf, func, stack, a0) \  buf[7] = (long)(func); \  buf[6] = (long)(stack); \  buf[5] = 0; \  stack[0] = 0xdeadc0c0;  /* Dummy return address. */ \  coco->arg0 = (size_t)(a0);#endif#elif defined(PPC) || defined(__ppc__) || defined(__PPC__) || \      defined(__powerpc__) || defined(__POWERPC__) || defined(_ARCH_PPC)#define COCO_STACKADJUST	16

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -