RELEASE LuaJIT-2.0.0-beta2
This commit is contained in:
428
src/Makefile
428
src/Makefile
@@ -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"
|
||||
|
||||
##############################################################################
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
136
src/lj_api.c
136
src/lj_api.c
@@ -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)
|
||||
|
||||
11
src/lj_asm.c
11
src/lj_asm.c
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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. */
|
||||
}
|
||||
|
||||
46
src/lj_err.c
46
src/lj_err.c
@@ -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
|
||||
|
||||
|
||||
@@ -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!")
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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 ------------------------------ */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
|
||||
@@ -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. */
|
||||
|
||||
20
src/luajit.c
20
src/luajit.c
@@ -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)
|
||||
|
||||
10
src/luajit.h
10
src/luajit.h
@@ -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. */
|
||||
|
||||
Reference in New Issue
Block a user