RELEASE LuaJIT-2.0.0-beta2

This commit is contained in:
Mike Pall
2009-12-08 19:49:20 +01:00
parent 55b1695971
commit 1d1fed48a0
46 changed files with 1289 additions and 441 deletions

View File

@@ -8,10 +8,17 @@
# Copyright (C) 2005-2009 Mike Pall. See Copyright Notice in luajit.h
##############################################################################
MAJVER= 2
MINVER= 0
RELVER= 0
ABIVER= 5.1
NODOTABIVER= 51
##############################################################################
# Compiler options: change them as needed. This mainly affects the speed of
# the JIT compiler itself, not the speed of the JIT compiled code.
# Turn any of the optional settings on by removing the '#' in front of them.
# You need to 'make clean' and 'make' again, if you change any options.
#
# Note: LuaJIT can only be compiled for x86, and not for x64 (yet)!
# In the meantime, the x86 binary runs fine under a x64 OS.
@@ -81,89 +88,142 @@ XCFLAGS=
#XCFLAGS+= -DLUA_USE_ASSERT
#
##############################################################################
##############################################################################
# Build mode: override the mode as needed. Default is mixed mode on POSIX.
# On Windows this is the same as dynamic mode.
#
# Mixed mode creates a static + dynamic library and a statically linked luajit.
BUILDMODE= mixed
#
# Static mode creates a static library and a statically linked luajit.
#BUILDMODE= static
#
# Dynamic mode creates a dynamic library and a dynamically linked luajit.
# Note: this executable will only run when the library is installed!
#BUILDMODE= dynamic
##############################################################################
# You probably don't need to change anything below this line.
##############################################################################
##############################################################################
# Flags and options for host and target.
##############################################################################
CCOPTIONS= $(CCDEBUG) $(CCOPT) $(CCWARN) $(CFLAGS) $(XCFLAGS)
LDOPTIONS= $(CCDEBUG) $(LDFLAGS)
HOST_CC= $(CC)
HOST_RM= rm -f
HOST_XCFLAGS=
HOST_XLDFLAGS=
HOST_XLIBS=
TARGET_CC= $(CC)
TARGET_STRIP= strip
TARGET_XCFLAGS= -D_FILE_OFFSET_BITS=64
TARGET_XLDFLAGS=
TARGET_XSHLDFLAGS= -shared
TARGET_XLIBS=
TARGET_ARCH= $(patsubst %,-DLUAJIT_TARGET=LUAJIT_ARCH_%,$(TARGET))
TARGET_DISABLE= -U_FORTIFY_SOURCE
ifneq (,$(findstring stack-protector,$(shell $(CC) -dumpspecs)))
TARGET_DISABLE+= -fno-stack-protector
endif
ifneq (,$(findstring Windows,$(OS)))
TARGET_SYS= Windows
else
TARGET_SYS:= $(shell uname -s)
ifneq (,$(findstring CYGWIN,$(TARGET_SYS)))
TARGET_SYS= Windows
endif
endif
ifeq (Linux,$(TARGET_SYS))
TARGET_XLIBS= -ldl
TARGET_XLDFLAGS= -Wl,-E
else
ifeq (Windows,$(TARGET_SYS))
HOST_RM= del
TARGET_STRIP= strip --strip-unneeded
else
ifeq (Darwin,$(TARGET_SYS))
TARGET_XSHLDFLAGS= -dynamiclib -single_module -undefined dynamic_lookup
TARGET_STRIP= strip -x
export MACOSX_DEPLOYMENT_TARGET=10.3
else
TARGET_XLDFLAGS= -Wl,-E
endif
endif
endif
# NOTE: The LuaJIT distribution comes with a pre-generated buildvm_*.h.
# You DO NOT NEED an installed copy of (plain) Lua 5.1 to run DynASM unless
# you want to MODIFY the corresponding *.dasc file. You can also use LuaJIT
# itself (bootstrapped from the pre-generated file) to run DynASM of course.
DASM_LUA= lua
Q= @
E= @echo
#Q=
#E= @:
##############################################################################
TARGET_CFLAGS= $(CCOPTIONS) $(TARGET_DISABLE) $(TARGET_XCFLAGS)
TARGET_LDFLAGS= $(LDOPTIONS) $(TARGET_XLDFLAGS)
TARGET_SHLDFLAGS= $(LDOPTIONS) $(TARGET_XSHLDFLAGS)
TARGET_LIBS= -lm $(TARGET_XLIBS)
ifneq (,$(CCDEBUG))
TARGET_STRIP= @:
endif
HOST_LUA= lua
HOST_XCFLAGS=
HOST_XLDFLAGS=
HOST_XLIBS=
HOST_CFLAGS= $(CCOPTIONS) $(HOST_XCFLAGS) $(TARGET_ARCH)
HOST_LDFLAGS= $(LDOPTIONS) $(HOST_XLDFLAGS)
HOST_LIBS= $(HOST_XLIBS)
# Cross-compilation example: make CROSS=i586-mingw32msvc- TARGET_SYS=Windows
CROSS=
STATIC_CC = $(CROSS)$(CC)
DYNAMIC_CC = $(CROSS)$(CC) -fPIC
TARGET_CC= $(STATIC_CC)
TARGET_STCC= $(STATIC_CC)
TARGET_DYNCC= $(DYNAMIC_CC)
TARGET_LD= $(CROSS)$(CC)
TARGET_AR= $(CROSS)ar rcus
TARGET_STRIP= $(CROSS)strip
TARGET_SONAME= libluajit-$(ABIVER).so.$(MAJVER)
TARGET_DYLIBNAME= libluajit-$(NODOTABIVER).$(MAJVER).$(MINVER).$(RELVER).dylib
TARGET_DLLNAME= lua$(NODOTABIVER).dll
TARGET_XSHLDFLAGS= -shared -fPIC -Wl,-soname,$(TARGET_SONAME)
TARGET_DYNXLDOPTS=
TARGET_ARCH= $(patsubst %,-DLUAJIT_TARGET=LUAJIT_ARCH_%,$(TARGET))
TARGET_DISABLE= -U_FORTIFY_SOURCE
ifneq (,$(findstring stack-protector,$(shell $(TARGET_CC) -dumpspecs)))
TARGET_DISABLE+= -fno-stack-protector
endif
TARGET_XCFLAGS= -D_FILE_OFFSET_BITS=64
TARGET_XLDFLAGS=
TARGET_XLDOPTS=
TARGET_XLIBS=
TARGET_CFLAGS= $(CCOPTIONS) $(TARGET_DISABLE) $(TARGET_XCFLAGS)
TARGET_LDFLAGS= $(LDOPTIONS) $(TARGET_XLDFLAGS) $(TARGET_XLDOPTS)
TARGET_SHLDFLAGS= $(LDOPTIONS) $(TARGET_XSHLDFLAGS)
TARGET_LIBS= -lm $(TARGET_XLIBS)
ifneq (,$(PREFIX))
ifneq (/usr/local,$(PREFIX))
TARGET_XCFLAGS+= -DLUA_XROOT=\"$(PREFIX)/\"
ifneq (/usr,$(PREFIX))
TARGET_DYNXLDOPTS= -Wl,-rpath,$(PREFIX)/lib
endif
endif
endif
##############################################################################
# System detection.
##############################################################################
ifneq (,$(findstring Windows,$(OS)))
HOST_SYS= Windows
else
HOST_SYS:= $(shell uname -s)
ifneq (,$(findstring CYGWIN,$(TARGET_SYS)))
HOST_SYS= Windows
endif
endif
ifeq (Windows,$(HOST_SYS))
HOST_RM= del
endif
TARGET_SYS= $(HOST_SYS)
ifeq (Windows,$(TARGET_SYS))
TARGET_STRIP+= --strip-unneeded
TARGET_XSHLDFLAGS= -shared
TARGET_DYNXLDOPTS=
else
ifeq (Darwin,$(TARGET_SYS))
export MACOSX_DEPLOYMENT_TARGET=10.4
TARGET_STRIP+= -x
TARGET_AR+= 2>/dev/null
TARGET_XSHLDFLAGS= -dynamiclib -single_module -undefined dynamic_lookup -fPIC
ifneq (,$(TARGET_DYNXLDOPTS))
TARGET_DYNXLDOPTS=
TARGET_XSHLDFLAGS+= -install_name $(PREFIX)/lib/$(TARGET_DYLIBNAME)
endif
else
TARGET_XLDFLAGS= -Wl,-E
ifeq (Linux,$(TARGET_SYS))
TARGET_XLIBS= -ldl
endif
endif
endif
ifneq (,$(CCDEBUG))
TARGET_STRIP= @:
endif
##############################################################################
# Files and pathnames.
##############################################################################
DASM_DIR= ../dynasm
DASM= $(DASM_LUA) $(DASM_DIR)/dynasm.lua
DASM= $(HOST_LUA) $(DASM_DIR)/dynasm.lua
DASM_FLAGS=
DASM_DISTFLAGS= -LN
BUILDVM_O= buildvm.o buildvm_asm.o buildvm_peobj.o buildvm_lib.o buildvm_fold.o
BUILDVM_T= buildvm
BUILDVM_X= ./$(BUILDVM_T)
HOST_O= $(BUILDVM_O)
HOST_T= $(BUILDVM_T)
@@ -188,121 +248,91 @@ LJCORE_O= lj_gc.o lj_err.o lj_ctype.o lj_bc.o lj_obj.o \
$(LJLIB_O) lib_init.o
LJVMCORE_O= $(LJVM_O) $(LJCORE_O)
# NYI: Need complete support for building as a shared library on POSIX.
# This is currently *only* suitable for MinGW and Cygwin, see below.
LUAJIT_O= luajit.o
LUAJIT_SO= luajit.so
LUAJIT_T= luajit
LJVMCORE_DYNO= $(LJVMCORE_O:.o=_dyn.o)
LIB_VMDEF= ../lib/vmdef.lua
LIB_VMDEFP= $(LIB_VMDEF)
TARGET_DEP= $(LIB_VMDEF)
TARGET_O= $(LJVMCORE_O) $(LUAJIT_O)
TARGET_T= $(LUAJIT_T)
LUAJIT_O= luajit.o
LUAJIT_A= libluajit.a
LUAJIT_SO= libluajit.so
LUAJIT_T= luajit
ALL_GEN= $(LJVM_S) lj_ffdef.h lj_libdef.h lj_recdef.h $(LIB_VMDEF) lj_folddef.h
ALL_T= $(LUAJIT_T) $(LUAJIT_A) $(LUAJIT_SO) $(BUILDVM_T)
ALL_GEN= $(LJVM_S) lj_ffdef.h lj_libdef.h lj_recdef.h $(LIB_VMDEFP) lj_folddef.h
ALL_DYNGEN= buildvm_x86.h
WIN_RM= *.obj *.lib *.exp *.dll *.exe *.manifest
ALL_RM= $(LUAJIT_T) $(LUAJIT_SO) $(HOST_T) $(ALL_GEN) *.o $(WIN_RM)
ifeq (Windows,$(TARGET_SYS))
LJVM_BOUT= $(LJVM_O)
LJVM_MODE= peobj
LIB_VMDEF= ..\lib\vmdef.lua
# Imported symbols are bound to a specific DLL name under Windows.
LUAJIT_SO= lua51.dll
LUAJIT_T= luajit.exe
BUILDVM_T= buildvm.exe
#
# You can comment out the following two lines to build a static executable.
# But then you won't be able to dynamically load any C modules, because
# they bind to lua51.dll.
#
TARGET_XCFLAGS+= -DLUA_BUILD_AS_DLL
TARGET_O= $(LUAJIT_SO) $(LUAJIT_O)
endif
WIN_RM= *.obj *.lib *.exp *.dll *.exe *.manifest *.pdb *.ilk
ALL_RM= $(ALL_T) $(ALL_GEN) *.o $(WIN_RM)
##############################################################################
# Build mode handling.
##############################################################################
default: $(TARGET_T)
# Mixed mode defaults.
TARGET_O= $(LUAJIT_A)
TARGET_T= $(LUAJIT_T) $(LUAJIT_SO)
TARGET_DEP= $(LIB_VMDEF) $(LUAJIT_SO)
all: $(TARGET_T)
ifeq (Windows,$(HOST_SYS))
BUILDVM_T= buildvm.exe
LIB_VMDEFP= $(subst /,\\,$(LIB_VMDEF))
endif
ifeq (Windows,$(TARGET_SYS))
DYNAMIC_CC= $(STATIC_CC)
LJVM_BOUT= $(LJVM_O)
LJVM_MODE= peobj
LUAJIT_SO= $(TARGET_DLLNAME)
LUAJIT_T= luajit.exe
ifneq ($(HOST_SYS),$(TARGET_SYS))
HOST_XCFLAGS+= -malign-double
endif
# Mixed mode is not supported on Windows. And static mode doesn't work well.
# C modules cannot be loaded, because they bind to lua51.dll.
ifneq (static,$(BUILDMODE))
BUILDMODE= dynamic
TARGET_XCFLAGS+= -DLUA_BUILD_AS_DLL
endif
endif
ifeq (static,$(BUILDMODE))
TARGET_DYNCC= @:
TARGET_T= $(LUAJIT_T)
TARGET_DEP= $(LIB_VMDEF)
else
ifeq (dynamic,$(BUILDMODE))
TARGET_CC= $(DYNAMIC_CC)
TARGET_DYNCC= @:
LJVMCORE_DYNO= $(LJVMCORE_O)
TARGET_O= $(LUAJIT_SO)
TARGET_XLDOPTS= $(TARGET_DYNXLDOPTS)
else
ifeq (Darwin,$(TARGET_SYS))
TARGET_DYNCC= @:
LJVMCORE_DYNO= $(LJVMCORE_O)
endif
endif
endif
Q= @
E= @echo
#Q=
#E= @:
##############################################################################
# Make targets.
##############################################################################
default all: $(TARGET_T)
amalg:
@grep "^[+|]" ljamalg.c
$(MAKE) all "LJCORE_O=ljamalg.o"
MAKE_TARGETS= amalg
##############################################################################
buildvm_x86.h: buildvm_x86.dasc
$(E) "DYNASM $@"
$(Q)$(DASM) $(DASM_FLAGS) -o $@ buildvm_x86.dasc
$(BUILDVM_T): $(BUILDVM_O)
$(E) "HOSTLINK $@"
$(Q)$(HOST_CC) $(HOST_LDFLAGS) -o $@ $(BUILDVM_O) $(HOST_LIBS)
$(LJVM_BOUT): $(BUILDVM_T)
$(E) "BUILDVM $@"
$(Q)./$(BUILDVM_T) -m $(LJVM_MODE) -o $@
lj_ffdef.h: $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)./$(BUILDVM_T) -m ffdef -o $@ $(LJLIB_C)
lj_libdef.h: $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)./$(BUILDVM_T) -m libdef -o $@ $(LJLIB_C)
lj_recdef.h: $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)./$(BUILDVM_T) -m recdef -o $@ $(LJLIB_C)
$(LIB_VMDEF): $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)./$(BUILDVM_T) -m vmdef -o $@ $(LJLIB_C)
lj_folddef.h: $(BUILDVM_T) lj_opt_fold.c
$(E) "BUILDVM $@"
$(Q)./$(BUILDVM_T) -m folddef -o $@ lj_opt_fold.c
$(LUAJIT_SO): $(LJVMCORE_O)
$(E) "LINK $@"
$(Q)$(TARGET_CC) $(TARGET_SHLDFLAGS) -o $@ $(LJVMCORE_O) $(TARGET_LIBS)
$(Q)$(TARGET_STRIP) $@
$(LUAJIT_T): $(TARGET_O) $(TARGET_DEP)
$(E) "LINK $@"
$(Q)$(TARGET_CC) $(TARGET_LDFLAGS) -o $@ $(TARGET_O) $(TARGET_LIBS)
$(Q)$(TARGET_STRIP) $@
$(E) "OK Successfully built LuaJIT"
##############################################################################
%.o: %.c
$(E) "CC $@"
$(Q)$(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ $<
%.o: %.s
$(E) "ASM $@"
$(Q)$(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ $<
$(HOST_O): %.o: %.c
$(E) "HOSTCC $@"
$(Q)$(HOST_CC) $(HOST_CFLAGS) -c -o $@ $<
include Makefile.dep
##############################################################################
clean:
$(HOST_RM) $(ALL_RM)
cleaner: clean
$(HOST_RM) $(ALL_DYNGEN)
cleaner:
$(HOST_RM) $(ALL_RM) $(ALL_DYNGEN)
distclean: clean
$(E) "DYNASM $@"
@@ -321,6 +351,86 @@ depend:
@test -s lj_folddef.h || $(HOST_RM) lj_folddef.h
@test -s buildvm_x86.h || $(HOST_RM) buildvm_x86.h
.PHONY: default all $(MAKE_TARGETS) clean cleaner distclean depend
.PHONY: default all amalg clean cleaner distclean depend
##############################################################################
# Rules for generated files.
##############################################################################
buildvm_x86.h: buildvm_x86.dasc
$(E) "DYNASM $@"
$(Q)$(DASM) $(DASM_FLAGS) -o $@ buildvm_x86.dasc
$(BUILDVM_T): $(BUILDVM_O)
$(E) "HOSTLINK $@"
$(Q)$(HOST_CC) $(HOST_LDFLAGS) -o $@ $(BUILDVM_O) $(HOST_LIBS)
$(LJVM_BOUT): $(BUILDVM_T)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m $(LJVM_MODE) -o $@
lj_ffdef.h: $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m ffdef -o $@ $(LJLIB_C)
lj_libdef.h: $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m libdef -o $@ $(LJLIB_C)
lj_recdef.h: $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m recdef -o $@ $(LJLIB_C)
$(LIB_VMDEF): $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m vmdef -o $(LIB_VMDEFP) $(LJLIB_C)
lj_folddef.h: $(BUILDVM_T) lj_opt_fold.c
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m folddef -o $@ lj_opt_fold.c
##############################################################################
# Object file rules.
##############################################################################
%.o: %.c
$(E) "CC $@"
$(Q)$(TARGET_DYNCC) $(TARGET_CFLAGS) -c -o $(@:.o=_dyn.o) $<
$(Q)$(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ $<
%.o: %.s
$(E) "ASM $@"
$(Q)$(TARGET_DYNCC) $(TARGET_CFLAGS) -c -o $(@:.o=_dyn.o) $<
$(Q)$(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ $<
$(LUAJIT_O):
$(E) "CC $@"
$(Q)$(TARGET_STCC) $(TARGET_CFLAGS) -c -o $@ $<
$(HOST_O): %.o: %.c
$(E) "HOSTCC $@"
$(Q)$(HOST_CC) $(HOST_CFLAGS) -c -o $@ $<
include Makefile.dep
##############################################################################
# Target file rules.
##############################################################################
$(LUAJIT_A): $(LJVMCORE_O)
$(E) "AR $@"
$(Q)$(TARGET_AR) $@ $(LJVMCORE_O)
# The dependency on _O, but linking with _DYNO is intentional.
$(LUAJIT_SO): $(LJVMCORE_O)
$(E) "DYNLINK $@"
$(Q)$(TARGET_LD) $(TARGET_SHLDFLAGS) -o $@ $(LJVMCORE_DYNO) $(TARGET_LIBS)
$(Q)$(TARGET_STRIP) $@
$(LUAJIT_T): $(TARGET_O) $(LUAJIT_O) $(TARGET_DEP)
$(E) "LINK $@"
$(Q)$(TARGET_LD) $(TARGET_LDFLAGS) -o $@ $(LUAJIT_O) $(TARGET_O) $(TARGET_LIBS)
$(Q)$(TARGET_STRIP) $@
$(E) "OK Successfully built LuaJIT"
##############################################################################

View File

@@ -34,8 +34,8 @@ lib_os.o: lib_os.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
lib_package.o: lib_package.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_err.h lj_errmsg.h lj_lib.h
lib_string.o: lib_string.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_state.h \
lj_ff.h lj_ffdef.h lj_ctype.h lj_lib.h lj_libdef.h
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h \
lj_state.h lj_ff.h lj_ffdef.h lj_ctype.h lj_lib.h lj_libdef.h
lib_table.o: lib_table.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_lib.h \
lj_libdef.h

View File

@@ -71,10 +71,7 @@ err:
exit(1);
}
emit_asm_bytes(ctx, cp, n);
if (!strncmp(sym, LABEL_PREFIX, sizeof(LABEL_PREFIX)-1))
fprintf(ctx->fp, "\t%s _%s\n", opname, sym);
else
fprintf(ctx->fp, "\t%s _" LABEL_PREFIX "wrapper_%s\n", opname, sym);
fprintf(ctx->fp, "\t%s _%s\n", opname, sym);
}
/* Emit an assembler label. */
@@ -135,7 +132,7 @@ void emit_asm(BuildCtx *ctx)
fprintf(ctx->fp, "\t.text\n");
emit_asm_align(ctx, 4);
emit_asm_label(ctx, LABEL_ASM_BEGIN, 0, 1);
emit_asm_label(ctx, LABEL_ASM_BEGIN, 0, 0);
if (ctx->mode == BUILD_elfasm)
fprintf(ctx->fp, ".Lbegin:\n");

View File

@@ -188,7 +188,12 @@ void emit_fold(BuildCtx *ctx)
} else if ((p[0] == 'F' || p[0] == 'X') && p[1] == '(' && q) {
p += 2;
*q = '\0';
fprintf(ctx->fp, funcidx ? ",\n %s" : " %s", p);
if (funcidx)
fprintf(ctx->fp, ",\n");
if (p[-2] == 'X')
fprintf(ctx->fp, " %s", p);
else
fprintf(ctx->fp, " fold_%s", p);
funcidx++;
} else {
buf[strlen(buf)-1] = '\0';

View File

@@ -264,7 +264,8 @@ void emit_peobj(BuildCtx *ctx)
emit_peobj_sym(ctx, name, 0,
PEOBJ_SECT_UNDEF, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN);
}
emit_peobj_sym_func(ctx, PEOBJ_SYM_PREFIX LABEL_ASM_BEGIN, 0);
emit_peobj_sym(ctx, PEOBJ_SYM_PREFIX LABEL_ASM_BEGIN, 0,
PEOBJ_SECT_TEXT, PEOBJ_TYPE_NULL, PEOBJ_SCL_EXTERN);
for (i = nzsym; i < ctx->nsym; i++) {
int pi = ctx->perm[i];
if (pi >= ctx->npc) {

View File

@@ -287,6 +287,35 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
| lea RA, [BASE+RA*8]
| jmp <9
|
|->gate_cwrap: // Call gate for wrapped C functions.
| // RA = new base, RB = CFUNC, RC = nargs+1, (BASE = old base), PC = return
| mov [RA-4], PC
| mov KBASE, CFUNC:RB->f
| mov L:RB, SAVE_L
| lea RC, [RA+NARGS:RC*8-8]
| mov L:RB->base, RA
| lea RA, [RC+8*LUA_MINSTACK]
| mov ARG2, KBASE
| mov ARG1, L:RB
| mov L:RB->top, RC
| cmp RA, L:RB->maxstack
| ja ->gate_c_growstack // Need to grow stack.
| set_vmstate C
| // (lua_State *L, lua_CFunction f)
| call aword [DISPATCH+DISPATCH_GL(wrapf)]
| set_vmstate INTERP
| // nresults returned in eax (RD).
| mov BASE, L:RB->base
| lea RA, [BASE+RD*8]
| neg RA
| add RA, L:RB->top // RA = (L->top-(L->base+nresults))*8
|->vm_returnc:
| add RD, 1 // RD = nresults+1
| mov NRESULTS, RD
| test PC, FRAME_TYPE
| jz ->BC_RET_Z // Handle regular return to Lua.
| jmp ->vm_return
|
|->gate_c: // Call gate for C functions.
| // RA = new base, RB = CFUNC, RC = nargs+1, (BASE = old base), PC = return
| mov [RA-4], PC
@@ -312,6 +341,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
| mov NRESULTS, RD
| test PC, FRAME_TYPE
| jz ->BC_RET_Z // Handle regular return to Lua.
| // Fallthrough.
|
|//-- Return handling (non-inline) ---------------------------------------
|
@@ -1455,7 +1485,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
| mov ARG5, RA
| fstp FPARG1
| mov RB, BASE
| call extern func
| call extern lj_wrapper_ .. func
| mov RA, ARG5
| mov BASE, RB
| jmp ->fff_resn
@@ -3584,6 +3614,85 @@ static void emit_asm_debug(BuildCtx *ctx)
"\t.byte 0x83\n\t.uleb128 0x5\n" /* offset ebx */
"\t.align 4\n"
".LEFDE0:\n\n", (int)ctx->codesz);
fprintf(ctx->fp, "\t.section .eh_frame,\"a\",@progbits\n");
fprintf(ctx->fp,
".Lframe1:\n"
"\t.long .LECIE1-.LSCIE1\n"
".LSCIE1:\n"
"\t.long 0\n"
"\t.byte 0x1\n"
"\t.string \"zPR\"\n"
"\t.uleb128 0x1\n"
"\t.sleb128 -4\n"
"\t.byte 0x8\n"
"\t.uleb128 6\n" /* augmentation length */
"\t.byte 0x1b\n" /* pcrel|sdata4 */
"\t.long lj_err_unwind_dwarf-.\n"
"\t.byte 0x1b\n" /* pcrel|sdata4 */
"\t.byte 0xc\n\t.uleb128 0x4\n\t.uleb128 0x4\n"
"\t.byte 0x88\n\t.uleb128 0x1\n"
"\t.align 4\n"
".LECIE1:\n\n");
fprintf(ctx->fp,
".LSFDE1:\n"
"\t.long .LEFDE1-.LASFDE1\n"
".LASFDE1:\n"
"\t.long .LASFDE1-.Lframe1\n"
"\t.long .Lbegin-.\n"
"\t.long %d\n"
"\t.uleb128 0\n" /* augmentation length */
"\t.byte 0xe\n\t.uleb128 0x30\n" /* def_cfa_offset */
"\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
"\t.byte 0x87\n\t.uleb128 0x3\n" /* offset edi */
"\t.byte 0x86\n\t.uleb128 0x4\n" /* offset esi */
"\t.byte 0x83\n\t.uleb128 0x5\n" /* offset ebx */
"\t.align 4\n"
".LEFDE1:\n\n", (int)ctx->codesz);
break;
case BUILD_machasm:
/* NYI: OSX ignores it. Something must be missing. */
fprintf(ctx->fp, "\t.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support\n");
fprintf(ctx->fp,
"EH_frame1:\n"
"\t.set L$set$0,LECIE1-LSCIE1\n"
"\t.long L$set$0\n"
"LSCIE1:\n"
"\t.long 0\n"
"\t.byte 0x1\n"
"\t.ascii \"zPR\"\n"
"\t.byte 0x1\n"
"\t.byte 128-4\n"
"\t.byte 0x8\n"
"\t.byte 6\n" /* augmentation length */
"\t.byte 0x9b\n" /* indirect|pcrel|sdata4 */
"\t.long L_lj_err_unwind_dwarf$non_lazy_ptr-.\n"
"\t.byte 0x1b\n" /* pcrel|sdata4 */
"\t.byte 0xc\n\t.byte 0x5\n\t.byte 0x4\n" /* esp=5 on 32 bit MACH-O. */
"\t.byte 0x88\n\t.byte 0x1\n"
"\t.align 2\n"
"LECIE1:\n\n");
fprintf(ctx->fp,
"_lj_vm_asm_begin.eh:\n"
"LSFDE1:\n"
"\t.set L$set$1,LEFDE1-LASFDE1\n"
"\t.long L$set$1\n"
"LASFDE1:\n"
"\t.long LASFDE1-EH_frame1\n"
"\t.long _lj_vm_asm_begin-.\n"
"\t.long %d\n"
"\t.byte 0\n" /* augmentation length */
"\t.byte 0xe\n\t.byte 0x30\n" /* def_cfa_offset */
"\t.byte 0x84\n\t.byte 0x2\n" /* offset ebp (4 for MACH-O)*/
"\t.byte 0x87\n\t.byte 0x3\n" /* offset edi */
"\t.byte 0x86\n\t.byte 0x4\n" /* offset esi */
"\t.byte 0x83\n\t.byte 0x5\n" /* offset ebx */
"\t.align 2\n"
"LEFDE1:\n\n", (int)ctx->codesz);
fprintf(ctx->fp,
"\t.non_lazy_symbol_pointer\n"
"L_lj_err_unwind_dwarf$non_lazy_ptr:\n"
".indirect_symbol _lj_err_unwind_dwarf\n"
".long 0\n");
break;
default: /* Difficult for other modes. */
break;

View File

@@ -20,97 +20,6 @@
#include "lj_err.h"
#include "lj_lib.h"
/* convert a stack index to positive */
#define abs_index(L, i) \
((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : lua_gettop(L) + (i) + 1)
/* -- Type checks --------------------------------------------------------- */
LUALIB_API void luaL_checkstack(lua_State *L, int size, const char *msg)
{
if (!lua_checkstack(L, size))
lj_err_callerv(L, LJ_ERR_STKOVM, msg);
}
LUALIB_API void luaL_checktype(lua_State *L, int narg, int tt)
{
if (lua_type(L, narg) != tt)
lj_err_argt(L, narg, tt);
}
LUALIB_API void luaL_checkany(lua_State *L, int narg)
{
lj_lib_checkany(L, narg);
}
LUALIB_API const char *luaL_checklstring(lua_State *L, int narg, size_t *len)
{
GCstr *s = lj_lib_checkstr(L, narg);
if (len != NULL) *len = s->len;
return strdata(s);
}
LUALIB_API const char *luaL_optlstring(lua_State *L, int narg,
const char *def, size_t *len)
{
GCstr *s = lj_lib_optstr(L, narg);
if (s) {
if (len != NULL) *len = s->len;
return strdata(s);
}
if (len != NULL) *len = def ? strlen(def) : 0;
return def;
}
LUALIB_API lua_Number luaL_checknumber(lua_State *L, int narg)
{
return lj_lib_checknum(L, narg);
}
LUALIB_API lua_Number luaL_optnumber(lua_State *L, int narg, lua_Number def)
{
lj_lib_opt(L, narg,
return lj_lib_checknum(L, narg);
,
return def;
)
}
LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int narg)
{
#if LJ_64
return (lua_Integer)lj_lib_checknum(L, narg);
#else
return lj_lib_checkint(L, narg);
#endif
}
LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int narg, lua_Integer def)
{
#if LJ_64
lj_lib_opt(L, narg,
return (lua_Integer)lj_lib_checknum(L, narg);
,
return def;
)
#else
return lj_lib_optint(L, narg, def);
#endif
}
LUALIB_API int luaL_checkoption(lua_State *L, int narg, const char *def,
const char *const lst[])
{
GCstr *s = lj_lib_optstr(L, narg);
const char *opt = s ? strdata(s) : def;
uint32_t i;
if (!opt) lj_err_argt(L, narg, LUA_TSTRING);
for (i = 0; lst[i]; i++)
if (strcmp(lst[i], opt) == 0)
return (int)i;
lj_err_argv(L, narg, LJ_ERR_INVOPTM, opt);
}
/* -- Module registration ------------------------------------------------- */
LUALIB_API const char *luaL_findtable(lua_State *L, int idx,
@@ -149,6 +58,7 @@ static int libsize(const luaL_Reg *l)
LUALIB_API void luaL_openlib(lua_State *L, const char *libname,
const luaL_Reg *l, int nup)
{
lj_lib_checkfpu(L);
if (libname) {
int size = libsize(l);
/* check whether lib already exists */
@@ -285,6 +195,10 @@ LUALIB_API void luaL_buffinit(lua_State *L, luaL_Buffer *B)
#define FREELIST_REF 0
/* Convert a stack index to an absolute index. */
#define abs_index(L, i) \
((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : lua_gettop(L) + (i) + 1)
LUALIB_API int luaL_ref(lua_State *L, int t)
{
int ref;

View File

@@ -523,8 +523,11 @@ static void io_fenv_new(lua_State *L, int narr, lua_CFunction cls)
LUALIB_API int luaopen_io(lua_State *L)
{
LJ_LIB_REG_(L, NULL, io_method);
lua_setfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
if (tvisnil(L->top-1)) {
LJ_LIB_REG_(L, NULL, io_method);
lua_setfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
}
io_fenv_new(L, 0, lj_cf_io_pipe_close); /* top-3 */
io_fenv_new(L, 2, lj_cf_io_file_close); /* top-2 */
LJ_LIB_REG(L, io);
@@ -532,7 +535,7 @@ LUALIB_API int luaopen_io(lua_State *L)
io_std_new(L, stdin, IO_INPUT, "stdin");
io_std_new(L, stdout, IO_OUTPUT, "stdout");
io_std_new(L, stderr, 0, "stderr");
lua_pop(L, 1);
L->top--;
return 1;
}

View File

@@ -73,8 +73,9 @@ LJLIB_CF(jit_flush)
#if LJ_HASJIT
if (L->base < L->top && (tvisnum(L->base) || tvisstr(L->base))) {
int traceno = lj_lib_checkint(L, 1);
luaJIT_setmode(L, traceno, LUAJIT_MODE_FLUSH|LUAJIT_MODE_TRACE);
return 0;
setboolV(L->top-1,
luaJIT_setmode(L, traceno, LUAJIT_MODE_FLUSH|LUAJIT_MODE_TRACE));
return 1;
}
#endif
return setjitmode(L, LUAJIT_MODE_FLUSH);

View File

@@ -69,11 +69,9 @@ LJLIB_ASM_(math_max) LJLIB_REC(math_minmax IR_MAX)
LJLIB_PUSH(3.14159265358979323846) LJLIB_SET(pi)
LJLIB_PUSH(1e310) LJLIB_SET(huge)
#ifdef __MACH__
LJ_FUNCA double lj_wrapper_sinh(double x) { return sinh(x); }
LJ_FUNCA double lj_wrapper_cosh(double x) { return cosh(x); }
LJ_FUNCA double lj_wrapper_tanh(double x) { return tanh(x); }
#endif
/* ------------------------------------------------------------------------ */
@@ -98,8 +96,8 @@ typedef union { uint64_t u64; double d; } U64double;
z = (((z<<q)^z) >> (k-s)) ^ ((z&((uint64_t)(int64_t)-1 << (64-k)))<<s); \
r ^= z; tw->gen[i] = z;
/* PRNG step function. Returns a double in the range 0.0 <= d < 1.0. */
static double tw223_step(TW223State *tw)
/* PRNG step function. Returns a double in the range 1.0 <= d < 2.0. */
static LJ_NOINLINE double tw223_step(TW223State *tw)
{
uint64_t z, r = 0;
U64double u;
@@ -108,16 +106,7 @@ static double tw223_step(TW223State *tw)
TW223_GEN(2, 55, 24, 7)
TW223_GEN(3, 47, 21, 8)
u.u64 = (r & (((uint64_t)1 << 52)-1)) | ((uint64_t)0x3ff << 52);
#if defined(__GNUC__) && LJ_TARGET_X86 && __pic__
/* Compensate for unbelievable GCC pessimization. */
{
volatile U64double u1;
u1.u64 = (uint64_t)0x3f8 << 52;
return u.d - u1.d;
}
#else
return u.d - 1.0;
#endif
return u.d;
}
/* PRNG initialization function. */
@@ -146,7 +135,7 @@ LJLIB_CF(math_random)
TW223State *tw = (TW223State *)(uddata(udataV(lj_lib_upvalue(L, 1))));
double d;
if (LJ_UNLIKELY(!tw->valid)) tw223_init(tw, 0.0);
d = tw223_step(tw);
d = tw223_step(tw) - 1.0;
if (n > 0) {
double r1 = lj_lib_checknum(L, 1);
if (n == 1) {

View File

@@ -354,6 +354,7 @@ static int lj_cf_package_require(lua_State *L)
lua_pushvalue(L, -1); /* extra copy to be returned */
lua_setfield(L, 2, name); /* _LOADED[name] = true */
}
lj_lib_checkfpu(L);
return 1;
}

View File

@@ -16,6 +16,7 @@
#include "lualib.h"
#include "lj_obj.h"
#include "lj_gc.h"
#include "lj_err.h"
#include "lj_str.h"
#include "lj_tab.h"
@@ -774,6 +775,7 @@ LJLIB_CF(string_format)
LUALIB_API int luaopen_string(lua_State *L)
{
GCtab *mt;
GCstr *mmstr;
LJ_LIB_REG(L, string);
#if defined(LUA_COMPAT_GFIND)
lua_getfield(L, -1, "gmatch");
@@ -782,8 +784,9 @@ LUALIB_API int luaopen_string(lua_State *L)
mt = lj_tab_new(L, 0, 1);
/* NOBARRIER: G(L)->mmname[] is a GC root. */
setgcref(G(L)->basemt[~LJ_TSTR], obj2gco(mt));
settabV(L, lj_tab_setstr(L, mt, strref(G(L)->mmname[MM_index])),
tabV(L->top-1));
mmstr = strref(G(L)->mmname[MM_index]);
if (isdead(G(L), obj2gco(mmstr))) flipwhite(obj2gco(mmstr));
settabV(L, lj_tab_setstr(L, mt, mmstr), tabV(L->top-1));
mt->nomm = cast_byte(~(1u<<MM_index));
return 1;
}

View File

@@ -74,21 +74,21 @@ LJLIB_CF(table_maxn)
TValue *array = tvref(t->array);
Node *node;
lua_Number m = 0;
uint32_t i;
for (i = 0; i < t->asize; i++)
ptrdiff_t i;
for (i = (ptrdiff_t)t->asize - 1; i >= 0; i--)
if (!tvisnil(&array[i])) {
m = (lua_Number)i;
m = (lua_Number)(int32_t)i;
break;
}
node = noderef(t->node);
for (i = 0; i <= t->hmask; i++)
for (i = (ptrdiff_t)t->hmask; i >= 0; i--)
if (tvisnum(&node[i].key) && numV(&node[i].key) > m)
m = numV(&node[i].key);
setnumV(L->top-1, m);
return 1;
}
LJLIB_CF(table_insert)
LJLIB_CF(table_insert) LJLIB_REC(.)
{
GCtab *t = lj_lib_checktab(L, 1);
int32_t n, i = (int32_t)lj_tab_len(t) + 1;
@@ -111,20 +111,20 @@ LJLIB_CF(table_insert)
}
{
TValue *dst = lj_tab_setint(L, t, i);
copyTV(L, dst, L->top-1);
copyTV(L, dst, L->top-1); /* Set new value. */
lj_gc_barriert(L, t, dst);
}
return 0;
}
LJLIB_CF(table_remove)
LJLIB_CF(table_remove) LJLIB_REC(.)
{
GCtab *t = lj_lib_checktab(L, 1);
int32_t e = (int32_t)lj_tab_len(t);
int32_t pos = lj_lib_optint(L, 2, e);
if (!(1 <= pos && pos <= e)) /* position is outside bounds? */
return 0; /* nothing to remove */
lua_rawgeti(L, 1, pos);
if (!(1 <= pos && pos <= e)) /* Nothing to remove? */
return 0;
lua_rawgeti(L, 1, pos); /* Get previous value. */
/* NOBARRIER: This just moves existing elements around. */
for (; pos < e; pos++) {
cTValue *src = lj_tab_getint(t, pos+1);
@@ -135,8 +135,8 @@ LJLIB_CF(table_remove)
setnilV(dst);
}
}
setnilV(lj_tab_setint(L, t, e));
return 1;
setnilV(lj_tab_setint(L, t, e)); /* Remove (last) value. */
return 1; /* Return previous value. */
}
LJLIB_CF(table_concat)

View File

@@ -91,6 +91,12 @@ LUA_API int lua_checkstack(lua_State *L, int size)
return 1;
}
LUALIB_API void luaL_checkstack(lua_State *L, int size, const char *msg)
{
if (!lua_checkstack(L, size))
lj_err_callerv(L, LJ_ERR_STKOVM, msg);
}
LUA_API void lua_xmove(lua_State *from, lua_State *to, int n)
{
TValue *f, *t;
@@ -193,6 +199,18 @@ LUA_API int lua_type(lua_State *L, int idx)
}
}
LUALIB_API void luaL_checktype(lua_State *L, int idx, int tt)
{
if (lua_type(L, idx) != tt)
lj_err_argt(L, idx, tt);
}
LUALIB_API void luaL_checkany(lua_State *L, int idx)
{
if (index2adr(L, idx) == niltv(L))
lj_err_arg(L, idx, LJ_ERR_NOVAL);
}
LUA_API const char *lua_typename(lua_State *L, int t)
{
UNUSED(L);
@@ -202,7 +220,7 @@ LUA_API const char *lua_typename(lua_State *L, int t)
LUA_API int lua_iscfunction(lua_State *L, int idx)
{
cTValue *o = index2adr(L, idx);
return !isluafunc(funcV(o));
return tvisfunc(o) && !isluafunc(funcV(o));
}
LUA_API int lua_isnumber(lua_State *L, int idx)
@@ -295,6 +313,30 @@ LUA_API lua_Number lua_tonumber(lua_State *L, int idx)
return 0;
}
LUALIB_API lua_Number luaL_checknumber(lua_State *L, int idx)
{
cTValue *o = index2adr(L, idx);
TValue tmp;
if (tvisnum(o))
return numV(o);
else if (!(tvisstr(o) && lj_str_numconv(strVdata(o), &tmp)))
lj_err_argt(L, idx, LUA_TNUMBER);
return numV(&tmp);
}
LUALIB_API lua_Number luaL_optnumber(lua_State *L, int idx, lua_Number def)
{
cTValue *o = index2adr(L, idx);
TValue tmp;
if (tvisnum(o))
return numV(o);
else if (tvisnil(o))
return def;
else if (!(tvisstr(o) && lj_str_numconv(strVdata(o), &tmp)))
lj_err_argt(L, idx, LUA_TNUMBER);
return numV(&tmp);
}
LUA_API lua_Integer lua_tointeger(lua_State *L, int idx)
{
cTValue *o = index2adr(L, idx);
@@ -313,6 +355,44 @@ LUA_API lua_Integer lua_tointeger(lua_State *L, int idx)
#endif
}
LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int idx)
{
cTValue *o = index2adr(L, idx);
TValue tmp;
lua_Number n;
if (LJ_LIKELY(tvisnum(o)))
n = numV(o);
else if (tvisstr(o) && lj_str_numconv(strVdata(o), &tmp))
n = numV(&tmp);
else
lj_err_argt(L, idx, LUA_TNUMBER);
#if LJ_64
return (lua_Integer)n;
#else
return lj_num2int(n);
#endif
}
LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int idx, lua_Integer def)
{
cTValue *o = index2adr(L, idx);
TValue tmp;
lua_Number n;
if (LJ_LIKELY(tvisnum(o)))
n = numV(o);
else if (tvisnil(o))
return def;
else if (tvisstr(o) && lj_str_numconv(strVdata(o), &tmp))
n = numV(&tmp);
else
lj_err_argt(L, idx, LUA_TNUMBER);
#if LJ_64
return (lua_Integer)n;
#else
return lj_num2int(n);
#endif
}
LUA_API int lua_toboolean(lua_State *L, int idx)
{
cTValue *o = index2adr(L, idx);
@@ -337,6 +417,57 @@ LUA_API const char *lua_tolstring(lua_State *L, int idx, size_t *len)
return strdata(s);
}
LUALIB_API const char *luaL_checklstring(lua_State *L, int idx, size_t *len)
{
TValue *o = index2adr(L, idx);
GCstr *s;
if (LJ_LIKELY(tvisstr(o))) {
s = strV(o);
} else if (tvisnum(o)) {
lj_gc_check(L);
o = index2adr(L, idx); /* GC may move the stack. */
s = lj_str_fromnum(L, &o->n);
} else {
lj_err_argt(L, idx, LUA_TSTRING);
}
if (len != NULL) *len = s->len;
return strdata(s);
}
LUALIB_API const char *luaL_optlstring(lua_State *L, int idx,
const char *def, size_t *len)
{
TValue *o = index2adr(L, idx);
GCstr *s;
if (LJ_LIKELY(tvisstr(o))) {
s = strV(o);
} else if (tvisnil(o)) {
if (len != NULL) *len = def ? strlen(def) : 0;
return def;
} else if (tvisnum(o)) {
lj_gc_check(L);
o = index2adr(L, idx); /* GC may move the stack. */
s = lj_str_fromnum(L, &o->n);
} else {
lj_err_argt(L, idx, LUA_TSTRING);
}
if (len != NULL) *len = s->len;
return strdata(s);
}
LUALIB_API int luaL_checkoption(lua_State *L, int idx, const char *def,
const char *const lst[])
{
ptrdiff_t i;
const char *s = lua_tolstring(L, idx, NULL);
if (s == NULL && (s = def) == NULL)
lj_err_argt(L, idx, LUA_TSTRING);
for (i = 0; lst[i]; i++)
if (strcmp(lst[i], s) == 0)
return (int)i;
lj_err_argv(L, idx, LJ_ERR_INVOPTM, s);
}
LUA_API size_t lua_objlen(lua_State *L, int idx)
{
TValue *o = index2adr(L, idx);
@@ -355,7 +486,8 @@ LUA_API size_t lua_objlen(lua_State *L, int idx)
LUA_API lua_CFunction lua_tocfunction(lua_State *L, int idx)
{
cTValue *o = index2adr(L, idx);
return funcV(o)->c.gate == lj_gate_c ? funcV(o)->c.f : NULL;
ASMFunction gate = funcV(o)->c.gate;
return (gate == lj_gate_c || gate == lj_gate_cwrap) ? funcV(o)->c.f : NULL;
}
LUA_API void *lua_touserdata(lua_State *L, int idx)

View File

@@ -738,11 +738,14 @@ static Reg ra_allocref(ASMState *as, IRRef ref, RegSet allow)
}
RA_DBGX((as, "hintmiss $f $r", ref, r));
}
/* Invariants should preferably get unused registers. */
if (ref < as->loopref && !irt_isphi(ir->t))
r = rset_pickbot(pick);
else
/* Invariants should preferably get unmodified registers. */
if (ref < as->loopref && !irt_isphi(ir->t)) {
if ((pick & ~as->modset))
pick &= ~as->modset;
r = rset_pickbot(pick); /* Reduce conflicts with inverse allocation. */
} else {
r = rset_picktop(pick);
}
} else {
r = ra_evict(as, allow);
}

View File

@@ -153,8 +153,7 @@ int luaJIT_setmode(lua_State *L, int idx, int mode)
case LUAJIT_MODE_TRACE:
if (!(mode & LUAJIT_MODE_FLUSH))
return 0; /* Failed. */
lj_trace_flush(G2J(g), idx);
break;
return lj_trace_flush(G2J(g), idx);
#else
case LUAJIT_MODE_ENGINE:
case LUAJIT_MODE_FUNC:
@@ -165,6 +164,20 @@ int luaJIT_setmode(lua_State *L, int idx, int mode)
return 0; /* Failed. */
break;
#endif
case LUAJIT_MODE_WRAPCFUNC:
if ((mode & LUAJIT_MODE_ON)) {
if (idx != 0) {
cTValue *tv = idx > 0 ? L->base + (idx-1) : L->top + idx;
if (tvislightud(tv) && lightudV(tv) != NULL)
g->wrapf = (lua_CFunction)lightudV(tv);
else
return 0; /* Failed. */
}
g->wrapmode = 1;
} else {
g->wrapmode = 0;
}
break;
default:
return 0; /* Failed. */
}

View File

@@ -676,6 +676,8 @@ LJ_NORET LJ_NOINLINE static void err_argmsg(lua_State *L, int narg,
{
const char *fname = "?";
const char *ftype = getfuncname(L, L->base - 1, &fname);
if (narg < 0 && narg > LUA_REGISTRYINDEX)
narg = (L->top - L->base) + narg + 1;
if (ftype && ftype[3] == 'h' && --narg == 0) /* Check for "method". */
msg = lj_str_pushf(L, err2msg(LJ_ERR_BADSELF), fname, msg);
else
@@ -761,3 +763,47 @@ LUALIB_API int luaL_error(lua_State *L, const char *fmt, ...)
return 0; /* unreachable */
}
/* -- C++ exception support ----------------------------------------------- */
#if defined(__ELF__) || defined(__MACH__)
typedef enum
{
_URC_NO_REASON,
_URC_FOREIGN_EXCEPTION_CAUGHT,
_URC_FATAL_PHASE2_ERROR,
_URC_FATAL_PHASE1_ERROR,
_URC_NORMAL_STOP,
_URC_END_OF_STACK,
_URC_HANDLER_FOUND,
_URC_INSTALL_CONTEXT,
_URC_CONTINUE_UNWIND
} _Unwind_Reason_Code;
#define _UA_SEARCH_PHASE 1
#define _UA_CLEANUP_PHASE 2
#define _UA_HANDLER_FRAME 4
#define _UA_FORCE_UNWIND 8
#define _UA_END_OF_STACK 16
extern void *_Unwind_GetCFA(void *ctx);
extern void _Unwind_DeleteException(void *uex);
/* DWARF2 personality handler referenced from .eh_frame. */
LJ_FUNCA int lj_err_unwind_dwarf(int version, int actions, uint64_t uexclass,
void *uex, void *ctx)
{
if (version != 1)
return _URC_FATAL_PHASE1_ERROR;
UNUSED(uexclass);
if ((actions & _UA_SEARCH_PHASE))
return _URC_HANDLER_FOUND;
if ((actions & _UA_HANDLER_FRAME)) {
void *cf = _Unwind_GetCFA(ctx);
lua_State *L = cframe_L(cf);
_Unwind_DeleteException(uex);
lj_err_msg(L, LJ_ERR_ERRCPP);
}
return _URC_CONTINUE_UNWIND;
}
#endif

View File

@@ -8,6 +8,7 @@
/* Basic error handling. */
ERRDEF(ERRMEM, "not enough memory")
ERRDEF(ERRERR, "error in error handling")
ERRDEF(ERRCPP, "C++ exception")
/* Allocations. */
ERRDEF(STROV, "string length overflow")
@@ -56,6 +57,9 @@ ERRDEF(NOENV, "no calling environment")
ERRDEF(CYIELD, "attempt to yield across C-call boundary")
ERRDEF(BADLU, "bad light userdata pointer")
ERRDEF(NOGCMM, "bad action while in __gc metamethod")
#ifdef LUA_USE_WIN
ERRDEF(BADFPU, "bad FPU precision (use D3DCREATE_FPU_PRESERVE with DirectX)")
#endif
/* Standard library function errors. */
ERRDEF(ASSERT, "assertion failed!")

View File

@@ -138,7 +138,7 @@ GCfunc *lj_func_newC(lua_State *L, MSize nelems, GCtab *env)
fn->c.nupvalues = cast_byte(nelems);
/* NOBARRIER: The GCfunc is new (marked white). */
setgcref(fn->c.env, obj2gco(env));
fn->c.gate = lj_gate_c;
fn->c.gate = G(L)->wrapmode ? lj_gate_cwrap : lj_gate_c;
return fn;
}

View File

@@ -230,8 +230,7 @@ static void gc_traverse_trace(global_State *g, Trace *T)
/* The current trace is a GC root while not anchored in the prototype (yet). */
#define gc_mark_curtrace(g) \
{ if (G2J(g)->state != LJ_TRACE_IDLE && G2J(g)->curtrace != 0) \
gc_traverse_trace(g, &G2J(g)->cur); }
{ if (G2J(g)->curtrace != 0) gc_traverse_trace(g, &G2J(g)->cur); }
#else
#define gc_mark_curtrace(g) UNUSED(g)
#endif

View File

@@ -252,6 +252,7 @@ TRef lj_ir_kgc(jit_State *J, GCobj *o, IRType t)
{
IRIns *ir, *cir = J->cur.ir;
IRRef ref;
lua_assert(!isdead(J2G(J), o));
for (ref = J->chain[IR_KGC]; ref; ref = cir[ref].prev)
if (ir_kgc(&cir[ref]) == o)
goto found;

View File

@@ -48,6 +48,15 @@ LJ_FUNC int lj_lib_checkopt(lua_State *L, int narg, int def, const char *lst);
#define lj_lib_upvalue(L, n) \
(&gcref((L->base-1)->fr.func)->fn.c.upvalue[(n)-1])
#ifdef LUA_USE_WIN
#define lj_lib_checkfpu(L) \
do { setnumV(L->top++, (lua_Number)1437217655); \
if (lua_tointeger(L, -1) != 1437217655) lj_err_caller(L, LJ_ERR_BADFPU); \
L->top--; } while (0)
#else
#define lj_lib_checkfpu(L) UNUSED(L)
#endif
/* Library function declarations. Scanned by buildvm. */
#define LJLIB_CF(name) static int lj_cf_##name(lua_State *L)
#define LJLIB_ASM(name) static int lj_ffh_##name(lua_State *L)

View File

@@ -531,7 +531,7 @@ typedef struct global_State {
uint8_t hookmask; /* Hook mask. */
uint8_t dispatchmode; /* Dispatch mode. */
uint8_t vmevmask; /* VM event mask. */
uint8_t unused1;
uint8_t wrapmode; /* Wrap mode. */
GCRef mainthref; /* Link to main thread. */
TValue registrytv; /* Anchor for registry. */
TValue tmptv; /* Temporary TValue. */
@@ -539,6 +539,7 @@ typedef struct global_State {
int32_t hookcount; /* Instruction hook countdown. */
int32_t hookcstart; /* Start count for instruction hook counter. */
lua_Hook hookf; /* Hook function. */
lua_CFunction wrapf; /* Wrapper for C function calls. */
lua_CFunction panic; /* Called as a last resort for errors. */
volatile int32_t vmstate; /* VM state or current JIT code trace number. */
GCRef jit_L; /* Current JIT code lua_State or NULL. */

View File

@@ -138,7 +138,7 @@ typedef IRRef (LJ_FASTCALL *FoldFunc)(jit_State *J);
/* Macros for the fold specs, so buildvm can recognize them. */
#define LJFOLD(x)
#define LJFOLDX(x)
#define LJFOLDF(name) static TRef LJ_FASTCALL name(jit_State *J)
#define LJFOLDF(name) static TRef LJ_FASTCALL fold_##name(jit_State *J)
/* Note: They must be at the start of a line or buildvm ignores them! */
/* Barrier to prevent using operands across PHIs. */
@@ -979,7 +979,7 @@ LJFOLDF(comm_equal)
/* For non-numbers only: x == x ==> drop; x ~= x ==> fail */
if (fins->op1 == fins->op2 && !irt_isnum(fins->t))
return CONDFOLD(fins->o == IR_EQ);
return comm_swap(J);
return fold_comm_swap(J);
}
LJFOLD(LT any any)
@@ -1013,7 +1013,7 @@ LJFOLDF(comm_dup)
{
if (fins->op1 == fins->op2) /* x o x ==> x */
return LEFTFOLD;
return comm_swap(J);
return fold_comm_swap(J);
}
LJFOLD(BXOR any any)
@@ -1021,7 +1021,7 @@ LJFOLDF(comm_bxor)
{
if (fins->op1 == fins->op2) /* i xor i ==> 0 */
return INTFOLD(0);
return comm_swap(J);
return fold_comm_swap(J);
}
/* -- Simplification of compound expressions ------------------------------ */

View File

@@ -286,7 +286,7 @@ static void loop_unroll(jit_State *J)
if (!irt_sametype(t, irr->t)) {
if (irt_isnum(t) && irt_isinteger(irr->t)) /* Fix int->num case. */
subst[ins] = tref_ref(emitir(IRTN(IR_TONUM), ref, 0));
else
else if (!(irt_isinteger(t) && irt_isinteger(irr->t)))
lj_trace_err(J, LJ_TRERR_TYPEINS);
}
}

View File

@@ -519,8 +519,8 @@ int lj_opt_fwd_wasnonnil(jit_State *J, IROpT loadop, IRRef xref)
} else if (irt_isnil(store->t)) { /* Must check any nil store. */
IRRef skref = IR(store->op1)->op2;
IRRef xkref = IR(xref)->op2;
/* Same key type MAY alias. */
if (irt_sametype(IR(skref)->t, IR(xkref)->t)) {
/* Same key type MAY alias. Need ALOAD check due to multiple int types. */
if (loadop == IR_ALOAD || irt_sametype(IR(skref)->t, IR(xkref)->t)) {
if (skref == xkref || !irref_isk(skref) || !irref_isk(xkref))
return 0; /* A nil store with same const key or var key MAY alias. */
/* Different const keys CANNOT alias. */

View File

@@ -168,8 +168,8 @@ static int rec_objcmp(jit_State *J, TRef a, TRef b, cTValue *av, cTValue *bv)
{
int diff = !lj_obj_equal(av, bv);
if (!tref_isk2(a, b)) { /* Shortcut, also handles primitives. */
IRType ta = tref_type(a);
IRType tb = tref_type(b);
IRType ta = tref_isinteger(a) ? IRT_INT : tref_type(a);
IRType tb = tref_isinteger(b) ? IRT_INT : tref_type(b);
if (ta != tb) {
/* Widen mixed number/int comparisons to number/number comparison. */
if (ta == IRT_INT && tb == IRT_NUM) {
@@ -447,7 +447,7 @@ static int rec_mm_lookup(jit_State *J, RecordIndex *ix, MMS mm)
mix.tab = lj_ir_ktab(J, mt);
goto nocheck;
}
ix->mt = mix.tab;
ix->mt = mt ? mix.tab : TREF_NIL;
emitir(IRTG(mt ? IR_NE : IR_EQ, IRT_TAB), mix.tab, lj_ir_knull(J, IRT_TAB));
nocheck:
if (mt) {
@@ -457,6 +457,8 @@ nocheck:
copyTV(J->L, &ix->mobjv, mo);
ix->mtv = mt;
settabV(J->L, &mix.tabv, mt);
if (isdead(J2G(J), obj2gco(mmstr)))
flipwhite(obj2gco(mmstr)); /* Need same logic as lj_str_new(). */
setstrV(J->L, &mix.keyv, mmstr);
mix.key = lj_ir_kstr(J, mmstr);
mix.val = 0;
@@ -880,7 +882,7 @@ static void recff_nyi(jit_State *J, TRef *res, RecordFFData *rd)
lj_trace_err_info(J, LJ_TRERR_NYIFF);
}
LJ_NORET static void recff_err_ffu(jit_State *J, RecordFFData *rd)
LJ_NORET static void recff_err_nyi(jit_State *J, RecordFFData *rd)
{
setfuncV(J->L, &J->errinfo, rd->fn);
lj_trace_err_info(J, LJ_TRERR_NYIFFU);
@@ -986,7 +988,7 @@ static void recff_tonumber(jit_State *J, TRef *res, RecordFFData *rd)
if (arg[1]) {
TRef base = lj_ir_toint(J, arg[1]);
if (!tref_isk(base) || IR(tref_ref(base))->i != 10)
recff_err_ffu(J, rd);
recff_err_nyi(J, rd);
}
if (tref_isstr(tr))
tr = emitir(IRTG(IR_STRTO, IRT_NUM), tr, 0);
@@ -1016,7 +1018,7 @@ static void recff_tostring(jit_State *J, TRef *res, RecordFFData *rd)
} else if (tref_isnumber(tr)) {
res[0] = emitir(IRT(IR_TOSTR, IRT_STR), tr, 0);
} else {
recff_err_ffu(J, rd);
recff_err_nyi(J, rd);
}
}
}
@@ -1338,6 +1340,58 @@ static void recff_table_getn(jit_State *J, TRef *res, RecordFFData *rd)
UNUSED(rd);
}
static void recff_table_remove(jit_State *J, TRef *res, RecordFFData *rd)
{
if (tref_istab(arg[0])) {
if (!arg[1] || tref_isnil(arg[1])) { /* Simple pop: t[#t] = nil */
TRef trlen = emitir(IRTI(IR_TLEN), arg[0], 0);
GCtab *t = tabV(&rd->argv[0]);
MSize len = lj_tab_len(t);
emitir(IRTGI(len ? IR_NE : IR_EQ), trlen, lj_ir_kint(J, 0));
if (len) {
RecordIndex ix;
ix.tab = arg[0];
ix.key = trlen;
settabV(J->L, &ix.tabv, t);
setintV(&ix.keyv, len);
ix.idxchain = 0;
if (rd->cres != 0) { /* Specialize load only if result needed. */
ix.val = 0;
res[0] = rec_idx(J, &ix); /* Load previous value. */
/* Assumes ix.key/ix.tab is not modified for raw rec_idx(). */
}
ix.val = TREF_NIL;
rec_idx(J, &ix); /* Remove value. */
} else {
rd->nres = 0;
}
} else { /* Complex case: remove in the middle. */
recff_err_nyi(J, rd);
}
} /* else: Interpreter will throw. */
}
static void recff_table_insert(jit_State *J, TRef *res, RecordFFData *rd)
{
rd->nres = 0;
if (tref_istab(arg[0]) && arg[1]) {
if (!arg[2]) { /* Simple push: t[#t+1] = v */
TRef trlen = emitir(IRTI(IR_TLEN), arg[0], 0);
GCtab *t = tabV(&rd->argv[0]);
RecordIndex ix;
ix.tab = arg[0];
ix.val = arg[1];
ix.key = emitir(IRTI(IR_ADD), trlen, lj_ir_kint(J, 1));
settabV(J->L, &ix.tabv, t);
setintV(&ix.keyv, lj_tab_len(t) + 1);
ix.idxchain = 0;
rec_idx(J, &ix); /* Set new value. */
} else { /* Complex case: insert in the middle. */
recff_err_nyi(J, rd);
}
} /* else: Interpreter will throw. */
}
/* -- Record calls and returns -------------------------------------------- */
#undef arg
@@ -1618,8 +1672,8 @@ void lj_record_ins(jit_State *J)
case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
/* Emit nothing for two numeric or string consts. */
if (!(tref_isk2(ra,rc) && tref_isnumber_str(ra) && tref_isnumber_str(rc))) {
IRType ta = tref_type(ra);
IRType tc = tref_type(rc);
IRType ta = tref_isinteger(ra) ? IRT_INT : tref_type(ra);
IRType tc = tref_isinteger(rc) ? IRT_INT : tref_type(rc);
int irop;
if (ta != tc) {
/* Widen mixed number/int comparisons to number/number comparison. */

View File

@@ -191,8 +191,8 @@ GCtab *lj_tab_dup(lua_State *L, const GCtab *kt)
Node *kn = &knode[i];
Node *n = &node[i];
Node *next = nextnode(kn);
copyTV(L, &n->val, &kn->val);
copyTV(L, &n->key, &kn->key);
/* Don't use copyTV here, since it asserts on a copy of a DEADKEY. */
n->val = kn->val; n->key = kn->key;
setmref(n->next, next == NULL? next : (Node *)((char *)next + d));
}
}

View File

@@ -191,47 +191,58 @@ static void trace_unpatch(jit_State *J, Trace *T)
}
}
/* Flush a root trace and any attached side traces. */
void lj_trace_flush(jit_State *J, TraceNo traceno)
/* Free a root trace and any attached side traces. */
static void trace_freeroot(jit_State *J, Trace *T, TraceNo traceno)
{
Trace *T = NULL;
GCproto *pt;
if (traceno > 0 && traceno <= J->sizetrace)
T = J->trace[traceno];
if (T == NULL)
return;
pt = &gcref(T->startpt)->pt;
if (T->root == 0 && pt != NULL) {
TraceNo side;
/* First unpatch any modified bytecode. */
trace_unpatch(J, T);
/* Unlink root trace from chain anchored in prototype. */
if (pt->trace == traceno) { /* Trace is first in chain. Easy. */
pt->trace = T->nextroot;
} else { /* Otherwise search in chain of root traces. */
Trace *T2 = J->trace[pt->trace];
while (T2->nextroot != traceno) {
lua_assert(T2->nextroot != 0);
T2 = J->trace[T2->nextroot];
}
T2->nextroot = T->nextroot; /* Unlink from chain. */
GCproto *pt = &gcref(T->startpt)->pt;
TraceNo side;
lua_assert(T->root == 0 && pt != NULL);
/* First unpatch any modified bytecode. */
trace_unpatch(J, T);
/* Unlink root trace from chain anchored in prototype. */
if (pt->trace == traceno) { /* Trace is first in chain. Easy. */
pt->trace = T->nextroot;
} else { /* Otherwise search in chain of root traces. */
Trace *T2 = J->trace[pt->trace];
while (T2->nextroot != traceno) {
lua_assert(T2->nextroot != 0);
T2 = J->trace[T2->nextroot];
}
/* Free all side traces. */
for (side = T->nextside; side != 0; ) {
TraceNo next = J->trace[side]->nextside;
trace_free(J, side);
side = next;
T2->nextroot = T->nextroot; /* Unlink from chain. */
}
/* Free all side traces. */
for (side = T->nextside; side != 0; ) {
TraceNo next = J->trace[side]->nextside;
trace_free(J, side);
side = next;
}
/* Now free the trace itself. */
trace_free(J, traceno);
}
/* Flush a root trace + side traces, if there are no links to it. */
int lj_trace_flush(jit_State *J, TraceNo traceno)
{
if (traceno > 0 && traceno < J->sizetrace) {
Trace *T = J->trace[traceno];
if (T && T->root == 0) {
ptrdiff_t i;
for (i = (ptrdiff_t)J->sizetrace-1; i > 0; i--)
if (i != (ptrdiff_t)traceno && J->trace[i] &&
J->trace[i]->root != traceno && J->trace[i]->link == traceno)
return 0; /* Failed: existing link to trace. */
trace_freeroot(J, T, traceno);
return 1; /* Ok. */
}
/* Now free the trace itself. */
trace_free(J, traceno);
} /* Flush for non-root traces is currently ignored. */
}
return 0; /* Failed. */
}
/* Flush all traces associated with a prototype. */
void lj_trace_flushproto(global_State *g, GCproto *pt)
{
while (pt->trace != 0)
lj_trace_flush(G2J(g), pt->trace);
trace_freeroot(G2J(g), G2J(g)->trace[pt->trace], pt->trace);
}
/* Flush all traces. */
@@ -241,8 +252,11 @@ int lj_trace_flushall(lua_State *L)
ptrdiff_t i;
if ((J2G(J)->hookmask & HOOK_GC))
return 1;
for (i = (ptrdiff_t)J->sizetrace-1; i > 0; i--)
lj_trace_flush(J, (TraceNo)i);
for (i = (ptrdiff_t)J->sizetrace-1; i > 0; i--) {
Trace *T = J->trace[i];
if (T && T->root == 0)
trace_freeroot(J, T, (TraceNo)i);
}
#ifdef LUA_USE_ASSERT
for (i = 0; i < (ptrdiff_t)J->sizetrace; i++)
lua_assert(J->trace[i] == NULL);

View File

@@ -26,7 +26,7 @@ LJ_FUNC_NORET void lj_trace_err_info(jit_State *J, TraceError e);
LJ_FUNC void lj_trace_freeproto(global_State *g, GCproto *pt);
LJ_FUNC void lj_trace_reenableproto(GCproto *pt);
LJ_FUNC void lj_trace_flushproto(global_State *g, GCproto *pt);
LJ_FUNC void lj_trace_flush(jit_State *J, TraceNo traceno);
LJ_FUNC int lj_trace_flush(jit_State *J, TraceNo traceno);
LJ_FUNC int lj_trace_flushall(lua_State *L);
LJ_FUNC void lj_trace_freestate(global_State *g);

View File

@@ -46,6 +46,7 @@ LJ_ASMF void lj_vm_powi(void);
LJ_ASMF void lj_gate_lf(void);
LJ_ASMF void lj_gate_lv(void);
LJ_ASMF void lj_gate_c(void);
LJ_ASMF void lj_gate_cwrap(void);
/* Continuations for metamethods. */
LJ_ASMF void lj_cont_cat(void); /* Continue with concatenation. */
@@ -55,12 +56,11 @@ LJ_ASMF void lj_cont_condt(void); /* Branch if result is true. */
LJ_ASMF void lj_cont_condf(void); /* Branch if result is false. */
/* Start of the ASM code. */
LJ_ASMF void lj_vm_asm_begin(void);
LJ_ASMF char lj_vm_asm_begin[];
/* Opcode handler offsets, relative to lj_vm_asm_begin. */
LJ_ASMF const uint16_t lj_vm_op_ofs[];
#define makeasmfunc(ofs) \
((ASMFunction)((char *)lj_vm_asm_begin + (ofs)))
#define makeasmfunc(ofs) ((ASMFunction)(lj_vm_asm_begin + (ofs)))
#endif

View File

@@ -1,9 +1,9 @@
// lua.hpp
// Lua header files for C++
// <<extern "C">> not supplied automatically because Lua also compiles as C++
// C++ wrapper for LuaJIT header files.
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#include "lualib.h"
#include "luajit.h"
}

View File

@@ -34,13 +34,22 @@
".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
#else
#define LUA_ROOT "/usr/local/"
#define LUA_JDIR LUA_ROOT "share/luajit-2.0.0-beta1/"
#define LUA_LDIR LUA_ROOT "share/lua/5.1/"
#define LUA_CDIR LUA_ROOT "lib/lua/5.1/"
#ifdef LUA_XROOT
#define LUA_JDIR LUA_XROOT "share/luajit-2.0.0-beta2/"
#define LUA_XPATH \
";" LUA_XROOT "share/lua/5.1/?.lua;" LUA_XROOT "share/lua/5.1/?/init.lua"
#define LUA_XCPATH LUA_XROOT "lib/lua/5.1/?.lua;"
#else
#define LUA_JDIR LUA_ROOT "share/luajit-2.0.0-beta2/"
#define LUA_XPATH
#define LUA_XCPATH
#endif
#define LUA_PATH_DEFAULT \
"./?.lua;" LUA_JDIR"?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;"
"./?.lua;" LUA_JDIR"?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua" LUA_XPATH
#define LUA_CPATH_DEFAULT \
"./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so"
"./?.so;" LUA_CDIR"?.so;" LUA_XCPATH LUA_CDIR"loadall.so"
#endif
/* Environment variable names for path overrides and initialization code. */

View File

@@ -55,16 +55,16 @@ static void laction(int i)
static void print_usage(void)
{
fprintf(stderr,
"usage: %s [options] [script [args]].\n"
"usage: %s [options]... [script [args]...].\n"
"Available options are:\n"
" -e stat execute string " LUA_QL("stat") "\n"
" -l name require library " LUA_QL("name") "\n"
" -j cmd perform LuaJIT control command\n"
" -O[lvl] set LuaJIT optimization level\n"
" -i enter interactive mode after executing " LUA_QL("script") "\n"
" -v show version information\n"
" -- stop handling options\n"
" - execute stdin and stop handling options\n"
" -e chunk Execute string " LUA_QL("chunk") ".\n"
" -l name Require library " LUA_QL("name") ".\n"
" -j cmd Perform LuaJIT control command.\n"
" -O[opt] Control LuaJIT optimizations.\n"
" -i Enter interactive mode after executing " LUA_QL("script") ".\n"
" -v Show version information.\n"
" -- Stop handling options.\n"
" - Execute stdin and stop handling options.\n"
,
progname);
fflush(stderr);
@@ -143,7 +143,7 @@ static void print_jit_status(lua_State *L)
fputs(lua_toboolean(L, n) ? "JIT: ON" : "JIT: OFF", stderr);
for (n++; (s = lua_tostring(L, n)); n++)
fprintf(stderr, " %s", s);
fputs("\n", stdout);
fputs("\n", stderr);
}
static int getargs(lua_State *L, char **argv, int n)

View File

@@ -30,9 +30,9 @@
#include "lua.h"
#define LUAJIT_VERSION "LuaJIT 2.0.0-beta1"
#define LUAJIT_VERSION "LuaJIT 2.0.0-beta2"
#define LUAJIT_VERSION_NUM 20000 /* Version 2.0.0 = 02.00.00. */
#define LUAJIT_VERSION_SYM luaJIT_version_2_0_0_beta1
#define LUAJIT_VERSION_SYM luaJIT_version_2_0_0_beta2
#define LUAJIT_COPYRIGHT "Copyright (C) 2005-2009 Mike Pall"
#define LUAJIT_URL "http://luajit.org/"
@@ -49,12 +49,14 @@ enum {
LUAJIT_MODE_TRACE, /* Flush a compiled trace. */
LUAJIT_MODE_WRAPCFUNC = 0x10, /* Set wrapper mode for C function calls. */
LUAJIT_MODE_MAX
};
/* Flags or'ed in to the mode. */
#define LUAJIT_MODE_OFF 0x0000 /* Disable JIT compilation. */
#define LUAJIT_MODE_ON 0x0100 /* (Re-)enable JIT compilation. */
#define LUAJIT_MODE_OFF 0x0000 /* Turn feature off. */
#define LUAJIT_MODE_ON 0x0100 /* Turn feature on. */
#define LUAJIT_MODE_FLUSH 0x0200 /* Flush JIT-compiled code. */
/* LuaJIT public C API. */