initial commit

This commit is contained in:
2021-04-12 20:25:02 +02:00
commit 3d7202a915
806 changed files with 194211 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
This file is only here to guarantee that unpackers don't skip creating the /lib directory.

View File

@@ -0,0 +1,43 @@
# This makefile assumes the ndk-build tool is executed from the sdk/angelscript/projects/android directory
# Change the next line to full path if there are any errors to link or find files
SDK_BASE_PATH := $(call my-dir)/../../../..
ANGELSCRIPT_INCLUDE := $(SDK_BASE_PATH)/angelscript/include/
# -----------------------------------------------------
# Build the AngelScript library
# -----------------------------------------------------
include $(CLEAR_VARS)
LOCAL_MODULE := libangelscript
# Android API: Checks if can use pthreads. Version 2.3 fully supports threads and atomic instructions
# ifeq ($(TARGET_PLATFORM),android-3)
# LOCAL_CFLAGS := -DAS_NO_THREADS
# else
# ifeq ($(TARGET_PLATFORM),android-4)
# LOCAL_CFLAGS := -DAS_NO_THREADS
# else
# ifeq ($(TARGET_PLATFORM),android-5)
# LOCAL_CFLAGS := -DAS_NO_THREADS
# else
# ifeq ($(TARGET_PLATFORM),android-6)
# LOCAL_CFLAGS := -DAS_NO_THREADS
# else
# ifeq ($(TARGET_PLATFORM),android-7)
# LOCAL_CFLAGS := -DAS_NO_THREADS
# else
# ifeq ($(TARGET_PLATFORM),android-8)
# LOCAL_CFLAGS := -DAS_NO_THREADS
# endif
# endif
# endif
# endif
# endif
# endif
LOCAL_CPP_FEATURES += rtti exceptions
LOCAL_SRC_FILES := $(wildcard $(SDK_BASE_PATH)/angelscript/source/*.S)
LOCAL_SRC_FILES += $(wildcard $(SDK_BASE_PATH)/angelscript/source/*.cpp)
LOCAL_PATH := .
LOCAL_ARM_MODE := arm
include $(BUILD_STATIC_LIBRARY)

View File

@@ -0,0 +1,3 @@
APP_ABI := mips armeabi armeabi-v7a x86
APP_PLATFORM := android-19
APP_STL := gnustl_static

View File

@@ -0,0 +1,2 @@
include("${CMAKE_CURRENT_LIST_DIR}/AngelscriptTargets.cmake")

View File

@@ -0,0 +1,37 @@
# This is a basic version file for the Config-mode of find_package().
# It is used by write_basic_package_version_file() as input file for configure_file()
# to create a version-file which can be installed along a config.cmake file.
#
# The created file sets PACKAGE_VERSION_EXACT if the current version string and
# the requested version string are exactly the same and it sets
# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version.
# The variable CVF_VERSION must be set before calling configure_file().
set(PACKAGE_VERSION "2.34.0")
if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
set(PACKAGE_VERSION_COMPATIBLE TRUE)
if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
set(PACKAGE_VERSION_EXACT TRUE)
endif()
endif()
# if the installed project requested no architecture check, don't perform the check
if("FALSE")
return()
endif()
# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "8" STREQUAL "")
return()
endif()
# check that the installed version has the same 32/64bit-ness as the one which is currently searching:
if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "8")
math(EXPR installedBits "8 * 8")
set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
set(PACKAGE_VERSION_UNSUITABLE TRUE)
endif()

View File

@@ -0,0 +1,63 @@
# Generated by CMake
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.5)
message(FATAL_ERROR "CMake >= 2.6.0 required")
endif()
cmake_policy(PUSH)
cmake_policy(VERSION 2.6)
#----------------------------------------------------------------
# Generated CMake target import file.
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Protect against multiple inclusion, which would fail when already imported targets are added once more.
set(_targetsDefined)
set(_targetsNotDefined)
set(_expectedTargets)
foreach(_expectedTarget Angelscript::angelscript)
list(APPEND _expectedTargets ${_expectedTarget})
if(NOT TARGET ${_expectedTarget})
list(APPEND _targetsNotDefined ${_expectedTarget})
endif()
if(TARGET ${_expectedTarget})
list(APPEND _targetsDefined ${_expectedTarget})
endif()
endforeach()
if("${_targetsDefined}" STREQUAL "${_expectedTargets}")
unset(_targetsDefined)
unset(_targetsNotDefined)
unset(_expectedTargets)
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
return()
endif()
if(NOT "${_targetsDefined}" STREQUAL "")
message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_targetsDefined}\nTargets not yet defined: ${_targetsNotDefined}\n")
endif()
unset(_targetsDefined)
unset(_targetsNotDefined)
unset(_expectedTargets)
# Create imported target Angelscript::angelscript
add_library(Angelscript::angelscript STATIC IMPORTED)
set_target_properties(Angelscript::angelscript PROPERTIES
INTERFACE_LINK_LIBRARIES "Threads::Threads"
)
# Import target "Angelscript::angelscript" for configuration "Debug"
set_property(TARGET Angelscript::angelscript APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(Angelscript::angelscript PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX"
IMPORTED_LOCATION_DEBUG "/home/nathan/Projects/Angelscript/angelscript/projects/cmake/libangelscript.a"
)
# This file does not depend on other imported targets which have
# been exported from the same project but in a separate export set.
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)

View File

@@ -0,0 +1,239 @@
cmake_minimum_required(VERSION 3.16)
include(CheckIPOSupported)
project(angelscript)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
option(BUILD_SHARED_LIBS "Build shared library" OFF)
option(LINK_STD_STATICALLY "Build shared library" OFF)
option(AS_NO_EXCEPTIONS "Disable exception handling in script context" OFF)
if(MSVC)
option(MSVC_COMPILE_FLAGS "Compiler flags to use with MSVC" "/MP")
endif()
if(APPLE)
option(BUILD_FRAMEWORK "Build Framework bundle for OSX" OFF)
endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
add_link_options(-fuse-ld=lld)
endif ()
file(READ ../../include/angelscript.h ANGELSCRIPT_H)
string(REGEX MATCH "#define ANGELSCRIPT_VERSION_STRING \"([0-9]*).([0-9]*).([0-9]*)" ANGELSCRIPT_VERSION_REGEX ${ANGELSCRIPT_H})
set(ANGELSCRIPT_VERSION_MAJOR ${CMAKE_MATCH_1})
set(ANGELSCRIPT_VERSION_MINOR ${CMAKE_MATCH_2})
set(ANGELSCRIPT_VERSION_PATCH ${CMAKE_MATCH_3})
set(PROJECT_VERSION ${ANGELSCRIPT_VERSION_MAJOR}.${ANGELSCRIPT_VERSION_MINOR}.${ANGELSCRIPT_VERSION_PATCH})
message(STATUS "Configuring angelscript ${PROJECT_VERSION}")
set(ANGELSCRIPT_HEADERS
../../include/angelscript.h
../../source/as_array.h
../../source/as_builder.h
../../source/as_bytecode.h
../../source/as_callfunc.h
../../source/as_compiler.h
../../source/as_config.h
../../source/as_configgroup.h
../../source/as_context.h
../../source/as_criticalsection.h
../../source/as_datatype.h
../../source/as_debug.h
../../source/as_generic.h
../../source/as_map.h
../../source/as_memory.h
../../source/as_module.h
../../source/as_objecttype.h
../../source/as_outputbuffer.h
../../source/as_parser.h
../../source/as_property.h
../../source/as_restore.h
../../source/as_scriptcode.h
../../source/as_scriptengine.h
../../source/as_scriptfunction.h
../../source/as_scriptnode.h
../../source/as_scriptobject.h
../../source/as_string.h
../../source/as_string_util.h
../../source/as_texts.h
../../source/as_thread.h
../../source/as_tokendef.h
../../source/as_tokenizer.h
../../source/as_typeinfo.h
../../source/as_variablescope.h
)
set(ANGELSCRIPT_SOURCE
../../source/as_atomic.cpp
../../source/as_builder.cpp
../../source/as_bytecode.cpp
../../source/as_callfunc.cpp
../../source/as_callfunc_mips.cpp
../../source/as_callfunc_x86.cpp
../../source/as_callfunc_x64_gcc.cpp
../../source/as_callfunc_x64_msvc.cpp
../../source/as_callfunc_x64_mingw.cpp
../../source/as_compiler.cpp
../../source/as_configgroup.cpp
../../source/as_context.cpp
../../source/as_datatype.cpp
../../source/as_gc.cpp
../../source/as_generic.cpp
../../source/as_globalproperty.cpp
../../source/as_memory.cpp
../../source/as_module.cpp
../../source/as_objecttype.cpp
../../source/as_outputbuffer.cpp
../../source/as_parser.cpp
../../source/as_restore.cpp
../../source/as_scriptcode.cpp
../../source/as_scriptengine.cpp
../../source/as_scriptfunction.cpp
../../source/as_scriptnode.cpp
../../source/as_scriptobject.cpp
../../source/as_string.cpp
../../source/as_string_util.cpp
../../source/as_thread.cpp
../../source/as_tokenizer.cpp
../../source/as_typeinfo.cpp
../../source/as_variablescope.cpp
)
if(MSVC AND CMAKE_CL_64)
enable_language(ASM_MASM)
if(CMAKE_ASM_MASM_COMPILER_WORKS)
set(ANGELSCRIPT_SOURCE ${ANGELSCRIPT_SOURCE} ../../source/as_callfunc_x64_msvc_asm.asm)
else()
message(FATAL ERROR "MSVC x86_64 target requires a working assembler")
endif()
endif()
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^arm")
enable_language(ASM)
if(CMAKE_ASM_COMPILER_WORKS)
set(ANGELSCRIPT_SOURCE ${ANGELSCRIPT_SOURCE} ../../source/as_callfunc_arm.cpp ../../source/as_callfunc_arm_gcc.S)
set_property(SOURCE ../../source/as_callfunc_arm_gcc.S APPEND PROPERTY COMPILE_FLAGS " -Wa,-mimplicit-it=always")
else()
message(FATAL ERROR "ARM target requires a working assembler")
endif()
endif()
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^aarch64")
enable_language(ASM)
if(CMAKE_ASM_COMPILER_WORKS)
set(ANGELSCRIPT_SOURCE ${ANGELSCRIPT_SOURCE} ../../source/as_callfunc_arm64.cpp ../../source/as_callfunc_arm64_gcc.S)
#set_property(SOURCE ../../source/as_callfunc_arm64_gcc.S APPEND PROPERTY COMPILE_FLAGS " -Wa")
else()
message(FATAL ERROR "ARM target requires a working assembler")
endif()
endif()
if(MSVC)
set(CMAKE_DEBUG_POSTFIX "d")
endif()
if(NOT BUILD_FRAMEWORK)
set(ANGELSCRIPT_LIBRARY_NAME angelscript)
else()
set(ANGELSCRIPT_LIBRARY_NAME Angelscript) # OS X frameworks should have capitalized name
set(BUILD_SHARED_LIBS TRUE)
endif()
set(ANGELSCRIPT_LIBRARY_NAME ${ANGELSCRIPT_LIBRARY_NAME} CACHE STRING "" FORCE)
add_library(${ANGELSCRIPT_LIBRARY_NAME} ${ANGELSCRIPT_SOURCE} ${ANGELSCRIPT_HEADERS})
target_include_directories(${ANGELSCRIPT_LIBRARY_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../include)
if(MSVC)
target_compile_definitions(${ANGELSCRIPT_LIBRARY_NAME} PRIVATE -D_CRT_SECURE_NO_WARNINGS)
endif()
target_compile_definitions(${ANGELSCRIPT_LIBRARY_NAME} PRIVATE -DANGELSCRIPT_EXPORT -D_LIB)
if(AS_NO_EXCEPTIONS)
target_compile_definitions(${ANGELSCRIPT_LIBRARY_NAME} PRIVATE AS_NO_EXCEPTIONS)
endif()
# Don't override the default library output path to avoid conflicts when building for multiple target platforms
#set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/../../lib)
if (LINK_STD_STATICALLY)
message(STATUS "Linking std libraries statically")
set (CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
target_link_libraries(${ANGELSCRIPT_LIBRARY_NAME} -lpthread -static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ )
else()
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(${ANGELSCRIPT_LIBRARY_NAME} -lpthread)
endif()
set_target_properties(${ANGELSCRIPT_LIBRARY_NAME} PROPERTIES VERSION ${PROJECT_VERSION})
if(BUILD_FRAMEWORK)
set_target_properties(${ANGELSCRIPT_LIBRARY_NAME} PROPERTIES
FRAMEWORK TRUE
FRAMEWORK_VERSION ${PROJECT_VERSION}
MACOSX_FRAMEWORK_IDENTIFIER com.angelcode.Angelscript
MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${PROJECT_VERSION}
MACOSX_FRAMEWORK_BUNDLE_VERSION ${PROJECT_VERSION}
XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
PUBLIC_HEADER ../../include/angelscript.h
)
endif()
if(MSVC AND MSVC_COMPILE_FLAGS)
target_compile_options(${ANGELSCRIPT_LIBRARY_NAME} PRIVATE "${MSVC_COMPILE_FLAGS}")
endif()
# Don't override the default runtime output path to avoid conflicts when building for multiple target platforms
#set(RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../../bin)
#See https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#creating-packages for a detailed explanation about this part
install(TARGETS ${ANGELSCRIPT_LIBRARY_NAME} EXPORT AngelscriptTargets
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
INCLUDES DESTINATION include
)
install(FILES
${CMAKE_CURRENT_SOURCE_DIR}/../../include/angelscript.h
DESTINATION include
COMPONENT Devel
)
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/Angelscript/AngelscriptConfigVersion.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion
)
export(EXPORT AngelscriptTargets
FILE "${CMAKE_CURRENT_BINARY_DIR}/Angelscript/AngelscriptTargets.cmake"
NAMESPACE Angelscript::
)
configure_file(cmake/AngelscriptConfig.cmake
"${CMAKE_CURRENT_BINARY_DIR}/Angelscript/AngelscriptConfig.cmake"
COPYONLY
)
set(ConfigPackageLocation lib/cmake/Angelscript)
install(EXPORT AngelscriptTargets
FILE AngelscriptTargets.cmake
NAMESPACE Angelscript::
DESTINATION ${ConfigPackageLocation}
)
install(
FILES
cmake/AngelscriptConfig.cmake
"${CMAKE_CURRENT_BINARY_DIR}/Angelscript/AngelscriptConfigVersion.cmake"
DESTINATION ${ConfigPackageLocation}
COMPONENT Devel
)

View File

@@ -0,0 +1,2 @@
include("${CMAKE_CURRENT_LIST_DIR}/AngelscriptTargets.cmake")

View File

@@ -0,0 +1,15 @@
{
"graph_lock": {
"nodes": {
"0": {
"ref": "AngelScript/2.35",
"options": "link_std_statically=True\nshared=True",
"path": "conanfile.py",
"context": "host"
}
},
"revisions_enabled": false
},
"version": "0.4",
"profile_host": "[settings]\narch=x86_64\narch_build=x86_64\nbuild_type=Release\ncompiler=clang\ncompiler.libcxx=libstdc++11\ncompiler.version=11\nos=Linux\nos_build=Linux\n[options]\nlink_std_statically=True\nshared=True\n[build_requires]\n[env]\n"
}

View File

@@ -0,0 +1,675 @@
include(CMakeParseArguments)
macro(conan_find_apple_frameworks FRAMEWORKS_FOUND FRAMEWORKS SUFFIX BUILD_TYPE)
if(APPLE)
if(CMAKE_BUILD_TYPE)
set(_BTYPE ${CMAKE_BUILD_TYPE})
elseif(NOT BUILD_TYPE STREQUAL "")
set(_BTYPE ${BUILD_TYPE})
endif()
if(_BTYPE)
if(${_BTYPE} MATCHES "Debug|_DEBUG")
set(CONAN_FRAMEWORKS${SUFFIX} ${CONAN_FRAMEWORKS${SUFFIX}_DEBUG} ${CONAN_FRAMEWORKS${SUFFIX}})
set(CONAN_FRAMEWORK_DIRS${SUFFIX} ${CONAN_FRAMEWORK_DIRS${SUFFIX}_DEBUG} ${CONAN_FRAMEWORK_DIRS${SUFFIX}})
elseif(${_BTYPE} MATCHES "Release|_RELEASE")
set(CONAN_FRAMEWORKS${SUFFIX} ${CONAN_FRAMEWORKS${SUFFIX}_RELEASE} ${CONAN_FRAMEWORKS${SUFFIX}})
set(CONAN_FRAMEWORK_DIRS${SUFFIX} ${CONAN_FRAMEWORK_DIRS${SUFFIX}_RELEASE} ${CONAN_FRAMEWORK_DIRS${SUFFIX}})
elseif(${_BTYPE} MATCHES "RelWithDebInfo|_RELWITHDEBINFO")
set(CONAN_FRAMEWORKS${SUFFIX} ${CONAN_FRAMEWORKS${SUFFIX}_RELWITHDEBINFO} ${CONAN_FRAMEWORKS${SUFFIX}})
set(CONAN_FRAMEWORK_DIRS${SUFFIX} ${CONAN_FRAMEWORK_DIRS${SUFFIX}_RELWITHDEBINFO} ${CONAN_FRAMEWORK_DIRS${SUFFIX}})
elseif(${_BTYPE} MATCHES "MinSizeRel|_MINSIZEREL")
set(CONAN_FRAMEWORKS${SUFFIX} ${CONAN_FRAMEWORKS${SUFFIX}_MINSIZEREL} ${CONAN_FRAMEWORKS${SUFFIX}})
set(CONAN_FRAMEWORK_DIRS${SUFFIX} ${CONAN_FRAMEWORK_DIRS${SUFFIX}_MINSIZEREL} ${CONAN_FRAMEWORK_DIRS${SUFFIX}})
endif()
endif()
foreach(_FRAMEWORK ${FRAMEWORKS})
# https://cmake.org/pipermail/cmake-developers/2017-August/030199.html
find_library(CONAN_FRAMEWORK_${_FRAMEWORK}_FOUND NAME ${_FRAMEWORK} PATHS ${CONAN_FRAMEWORK_DIRS${SUFFIX}} CMAKE_FIND_ROOT_PATH_BOTH)
if(CONAN_FRAMEWORK_${_FRAMEWORK}_FOUND)
list(APPEND ${FRAMEWORKS_FOUND} ${CONAN_FRAMEWORK_${_FRAMEWORK}_FOUND})
else()
message(FATAL_ERROR "Framework library ${_FRAMEWORK} not found in paths: ${CONAN_FRAMEWORK_DIRS${SUFFIX}}")
endif()
endforeach()
endif()
endmacro()
### Definition of global aggregated variables ###
set(CONAN_PACKAGE_NAME AngelScript)
set(CONAN_PACKAGE_VERSION 2.35)
set(CONAN_SETTINGS_ARCH "x86_64")
set(CONAN_SETTINGS_BUILD_TYPE "Release")
set(CONAN_SETTINGS_COMPILER "clang")
set(CONAN_SETTINGS_COMPILER_LIBCXX "libstdc++11")
set(CONAN_SETTINGS_COMPILER_VERSION "11")
set(CONAN_SETTINGS_OS "Linux")
set(CONAN_DEPENDENCIES )
# Storing original command line args (CMake helper) flags
set(CONAN_CMD_CXX_FLAGS ${CONAN_CXX_FLAGS})
set(CONAN_CMD_SHARED_LINKER_FLAGS ${CONAN_SHARED_LINKER_FLAGS})
set(CONAN_CMD_C_FLAGS ${CONAN_C_FLAGS})
# Defining accumulated conan variables for all deps
set(CONAN_INCLUDE_DIRS ${CONAN_INCLUDE_DIRS})
set(CONAN_LIB_DIRS ${CONAN_LIB_DIRS})
set(CONAN_BIN_DIRS ${CONAN_BIN_DIRS})
set(CONAN_RES_DIRS ${CONAN_RES_DIRS})
set(CONAN_FRAMEWORK_DIRS ${CONAN_FRAMEWORK_DIRS})
set(CONAN_LIBS ${CONAN_LIBS})
set(CONAN_PKG_LIBS ${CONAN_PKG_LIBS})
set(CONAN_SYSTEM_LIBS ${CONAN_SYSTEM_LIBS})
set(CONAN_FRAMEWORKS ${CONAN_FRAMEWORKS})
set(CONAN_FRAMEWORKS_FOUND "") # Will be filled later
set(CONAN_DEFINES ${CONAN_DEFINES})
set(CONAN_BUILD_MODULES_PATHS ${CONAN_BUILD_MODULES_PATHS})
set(CONAN_CMAKE_MODULE_PATH ${CONAN_CMAKE_MODULE_PATH})
set(CONAN_CXX_FLAGS " ${CONAN_CXX_FLAGS}")
set(CONAN_SHARED_LINKER_FLAGS " ${CONAN_SHARED_LINKER_FLAGS}")
set(CONAN_EXE_LINKER_FLAGS " ${CONAN_EXE_LINKER_FLAGS}")
set(CONAN_C_FLAGS " ${CONAN_C_FLAGS}")
# Apple Frameworks
conan_find_apple_frameworks(CONAN_FRAMEWORKS_FOUND "${CONAN_FRAMEWORKS}" "" "")
# Append to aggregated values variable: Use CONAN_LIBS instead of CONAN_PKG_LIBS to include user appended vars
set(CONAN_LIBS ${CONAN_LIBS} ${CONAN_SYSTEM_LIBS} ${CONAN_FRAMEWORKS_FOUND})
### Definition of macros and functions ###
macro(conan_define_targets)
if(${CMAKE_VERSION} VERSION_LESS "3.1.2")
message(FATAL_ERROR "TARGETS not supported by your CMake version!")
endif() # CMAKE > 3.x
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CONAN_CMD_CXX_FLAGS}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CONAN_CMD_C_FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${CONAN_CMD_SHARED_LINKER_FLAGS}")
set(CONAN_TARGETS )
endmacro()
macro(conan_basic_setup)
set(options TARGETS NO_OUTPUT_DIRS SKIP_RPATH KEEP_RPATHS SKIP_STD SKIP_FPIC)
cmake_parse_arguments(ARGUMENTS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
if(CONAN_EXPORTED)
conan_message(STATUS "Conan: called by CMake conan helper")
endif()
if(CONAN_IN_LOCAL_CACHE)
conan_message(STATUS "Conan: called inside local cache")
endif()
if(NOT ARGUMENTS_NO_OUTPUT_DIRS)
conan_message(STATUS "Conan: Adjusting output directories")
conan_output_dirs_setup()
endif()
if(NOT ARGUMENTS_TARGETS)
conan_message(STATUS "Conan: Using cmake global configuration")
conan_global_flags()
else()
conan_message(STATUS "Conan: Using cmake targets configuration")
conan_define_targets()
endif()
if(ARGUMENTS_SKIP_RPATH)
# Change by "DEPRECATION" or "SEND_ERROR" when we are ready
conan_message(WARNING "Conan: SKIP_RPATH is deprecated, it has been renamed to KEEP_RPATHS")
endif()
if(NOT ARGUMENTS_SKIP_RPATH AND NOT ARGUMENTS_KEEP_RPATHS)
# Parameter has renamed, but we keep the compatibility with old SKIP_RPATH
conan_set_rpath()
endif()
if(NOT ARGUMENTS_SKIP_STD)
conan_set_std()
endif()
if(NOT ARGUMENTS_SKIP_FPIC)
conan_set_fpic()
endif()
conan_check_compiler()
conan_set_libcxx()
conan_set_vs_runtime()
conan_set_find_paths()
conan_include_build_modules()
conan_set_find_library_paths()
endmacro()
macro(conan_set_find_paths)
# CMAKE_MODULE_PATH does not have Debug/Release config, but there are variables
# CONAN_CMAKE_MODULE_PATH_DEBUG to be used by the consumer
# CMake can find findXXX.cmake files in the root of packages
set(CMAKE_MODULE_PATH ${CONAN_CMAKE_MODULE_PATH} ${CMAKE_MODULE_PATH})
# Make find_package() to work
set(CMAKE_PREFIX_PATH ${CONAN_CMAKE_MODULE_PATH} ${CMAKE_PREFIX_PATH})
# Set the find root path (cross build)
set(CMAKE_FIND_ROOT_PATH ${CONAN_CMAKE_FIND_ROOT_PATH} ${CMAKE_FIND_ROOT_PATH})
if(CONAN_CMAKE_FIND_ROOT_PATH_MODE_PROGRAM)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ${CONAN_CMAKE_FIND_ROOT_PATH_MODE_PROGRAM})
endif()
if(CONAN_CMAKE_FIND_ROOT_PATH_MODE_LIBRARY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ${CONAN_CMAKE_FIND_ROOT_PATH_MODE_LIBRARY})
endif()
if(CONAN_CMAKE_FIND_ROOT_PATH_MODE_INCLUDE)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ${CONAN_CMAKE_FIND_ROOT_PATH_MODE_INCLUDE})
endif()
endmacro()
macro(conan_set_find_library_paths)
# CMAKE_INCLUDE_PATH, CMAKE_LIBRARY_PATH does not have Debug/Release config, but there are variables
# CONAN_INCLUDE_DIRS_DEBUG/RELEASE CONAN_LIB_DIRS_DEBUG/RELEASE to be used by the consumer
# For find_library
set(CMAKE_INCLUDE_PATH ${CONAN_INCLUDE_DIRS} ${CMAKE_INCLUDE_PATH})
set(CMAKE_LIBRARY_PATH ${CONAN_LIB_DIRS} ${CMAKE_LIBRARY_PATH})
endmacro()
macro(conan_set_vs_runtime)
if(CONAN_LINK_RUNTIME)
conan_get_policy(CMP0091 policy_0091)
if(policy_0091 STREQUAL "NEW")
if(CONAN_LINK_RUNTIME MATCHES "MTd")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDebug")
elseif(CONAN_LINK_RUNTIME MATCHES "MDd")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDebugDLL")
elseif(CONAN_LINK_RUNTIME MATCHES "MT")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded")
elseif(CONAN_LINK_RUNTIME MATCHES "MD")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL")
endif()
else()
foreach(flag CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELEASE
CMAKE_C_FLAGS_RELWITHDEBINFO CMAKE_CXX_FLAGS_RELWITHDEBINFO
CMAKE_C_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_MINSIZEREL)
if(DEFINED ${flag})
string(REPLACE "/MD" ${CONAN_LINK_RUNTIME} ${flag} "${${flag}}")
endif()
endforeach()
foreach(flag CMAKE_C_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG)
if(DEFINED ${flag})
string(REPLACE "/MDd" ${CONAN_LINK_RUNTIME} ${flag} "${${flag}}")
endif()
endforeach()
endif()
endif()
endmacro()
macro(conan_flags_setup)
# Macro maintained for backwards compatibility
conan_set_find_library_paths()
conan_global_flags()
conan_set_rpath()
conan_set_vs_runtime()
conan_set_libcxx()
endmacro()
function(conan_message MESSAGE_OUTPUT)
if(NOT CONAN_CMAKE_SILENT_OUTPUT)
message(${ARGV${0}})
endif()
endfunction()
function(conan_get_policy policy_id policy)
if(POLICY "${policy_id}")
cmake_policy(GET "${policy_id}" _policy)
set(${policy} "${_policy}" PARENT_SCOPE)
else()
set(${policy} "" PARENT_SCOPE)
endif()
endfunction()
function(conan_find_libraries_abs_path libraries package_libdir libraries_abs_path)
foreach(_LIBRARY_NAME ${libraries})
find_library(CONAN_FOUND_LIBRARY NAME ${_LIBRARY_NAME} PATHS ${package_libdir}
NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
if(CONAN_FOUND_LIBRARY)
conan_message(STATUS "Library ${_LIBRARY_NAME} found ${CONAN_FOUND_LIBRARY}")
set(CONAN_FULLPATH_LIBS ${CONAN_FULLPATH_LIBS} ${CONAN_FOUND_LIBRARY})
else()
conan_message(STATUS "Library ${_LIBRARY_NAME} not found in package, might be system one")
set(CONAN_FULLPATH_LIBS ${CONAN_FULLPATH_LIBS} ${_LIBRARY_NAME})
endif()
unset(CONAN_FOUND_LIBRARY CACHE)
endforeach()
set(${libraries_abs_path} ${CONAN_FULLPATH_LIBS} PARENT_SCOPE)
endfunction()
function(conan_package_library_targets libraries package_libdir libraries_abs_path deps build_type package_name)
unset(_CONAN_ACTUAL_TARGETS CACHE)
unset(_CONAN_FOUND_SYSTEM_LIBS CACHE)
foreach(_LIBRARY_NAME ${libraries})
find_library(CONAN_FOUND_LIBRARY NAME ${_LIBRARY_NAME} PATHS ${package_libdir}
NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
if(CONAN_FOUND_LIBRARY)
conan_message(STATUS "Library ${_LIBRARY_NAME} found ${CONAN_FOUND_LIBRARY}")
set(_LIB_NAME CONAN_LIB::${package_name}_${_LIBRARY_NAME}${build_type})
add_library(${_LIB_NAME} UNKNOWN IMPORTED)
set_target_properties(${_LIB_NAME} PROPERTIES IMPORTED_LOCATION ${CONAN_FOUND_LIBRARY})
set(CONAN_FULLPATH_LIBS ${CONAN_FULLPATH_LIBS} ${_LIB_NAME})
set(_CONAN_ACTUAL_TARGETS ${_CONAN_ACTUAL_TARGETS} ${_LIB_NAME})
else()
conan_message(STATUS "Library ${_LIBRARY_NAME} not found in package, might be system one")
set(CONAN_FULLPATH_LIBS ${CONAN_FULLPATH_LIBS} ${_LIBRARY_NAME})
set(_CONAN_FOUND_SYSTEM_LIBS "${_CONAN_FOUND_SYSTEM_LIBS};${_LIBRARY_NAME}")
endif()
unset(CONAN_FOUND_LIBRARY CACHE)
endforeach()
# Add all dependencies to all targets
string(REPLACE " " ";" deps_list "${deps}")
foreach(_CONAN_ACTUAL_TARGET ${_CONAN_ACTUAL_TARGETS})
set_property(TARGET ${_CONAN_ACTUAL_TARGET} PROPERTY INTERFACE_LINK_LIBRARIES "${_CONAN_FOUND_SYSTEM_LIBS};${deps_list}")
endforeach()
set(${libraries_abs_path} ${CONAN_FULLPATH_LIBS} PARENT_SCOPE)
endfunction()
macro(conan_set_libcxx)
if(DEFINED CONAN_LIBCXX)
conan_message(STATUS "Conan: C++ stdlib: ${CONAN_LIBCXX}")
if(CONAN_COMPILER STREQUAL "clang" OR CONAN_COMPILER STREQUAL "apple-clang")
if(CONAN_LIBCXX STREQUAL "libstdc++" OR CONAN_LIBCXX STREQUAL "libstdc++11" )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libstdc++")
elseif(CONAN_LIBCXX STREQUAL "libc++")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
endif()
endif()
if(CONAN_COMPILER STREQUAL "sun-cc")
if(CONAN_LIBCXX STREQUAL "libCstd")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -library=Cstd")
elseif(CONAN_LIBCXX STREQUAL "libstdcxx")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -library=stdcxx4")
elseif(CONAN_LIBCXX STREQUAL "libstlport")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -library=stlport4")
elseif(CONAN_LIBCXX STREQUAL "libstdc++")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -library=stdcpp")
endif()
endif()
if(CONAN_LIBCXX STREQUAL "libstdc++11")
add_definitions(-D_GLIBCXX_USE_CXX11_ABI=1)
elseif(CONAN_LIBCXX STREQUAL "libstdc++")
add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)
endif()
endif()
endmacro()
macro(conan_set_std)
conan_message(STATUS "Conan: Adjusting language standard")
# Do not warn "Manually-specified variables were not used by the project"
set(ignorevar "${CONAN_STD_CXX_FLAG}${CONAN_CMAKE_CXX_STANDARD}${CONAN_CMAKE_CXX_EXTENSIONS}")
if (CMAKE_VERSION VERSION_LESS "3.1" OR
(CMAKE_VERSION VERSION_LESS "3.12" AND ("${CONAN_CMAKE_CXX_STANDARD}" STREQUAL "20" OR "${CONAN_CMAKE_CXX_STANDARD}" STREQUAL "gnu20")))
if(CONAN_STD_CXX_FLAG)
conan_message(STATUS "Conan setting CXX_FLAGS flags: ${CONAN_STD_CXX_FLAG}")
set(CMAKE_CXX_FLAGS "${CONAN_STD_CXX_FLAG} ${CMAKE_CXX_FLAGS}")
endif()
else()
if(CONAN_CMAKE_CXX_STANDARD)
conan_message(STATUS "Conan setting CPP STANDARD: ${CONAN_CMAKE_CXX_STANDARD} WITH EXTENSIONS ${CONAN_CMAKE_CXX_EXTENSIONS}")
set(CMAKE_CXX_STANDARD ${CONAN_CMAKE_CXX_STANDARD})
set(CMAKE_CXX_EXTENSIONS ${CONAN_CMAKE_CXX_EXTENSIONS})
endif()
endif()
endmacro()
macro(conan_set_rpath)
conan_message(STATUS "Conan: Adjusting default RPATHs Conan policies")
if(APPLE)
# https://cmake.org/Wiki/CMake_RPATH_handling
# CONAN GUIDE: All generated libraries should have the id and dependencies to other
# dylibs without path, just the name, EX:
# libMyLib1.dylib:
# libMyLib1.dylib (compatibility version 0.0.0, current version 0.0.0)
# libMyLib0.dylib (compatibility version 0.0.0, current version 0.0.0)
# /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
# /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
# AVOID RPATH FOR *.dylib, ALL LIBS BETWEEN THEM AND THE EXE
# SHOULD BE ON THE LINKER RESOLVER PATH (./ IS ONE OF THEM)
set(CMAKE_SKIP_RPATH 1 CACHE BOOL "rpaths" FORCE)
# Policy CMP0068
# We want the old behavior, in CMake >= 3.9 CMAKE_SKIP_RPATH won't affect the install_name in OSX
set(CMAKE_INSTALL_NAME_DIR "")
endif()
endmacro()
macro(conan_set_fpic)
if(DEFINED CONAN_CMAKE_POSITION_INDEPENDENT_CODE)
conan_message(STATUS "Conan: Adjusting fPIC flag (${CONAN_CMAKE_POSITION_INDEPENDENT_CODE})")
set(CMAKE_POSITION_INDEPENDENT_CODE ${CONAN_CMAKE_POSITION_INDEPENDENT_CODE})
endif()
endmacro()
macro(conan_output_dirs_setup)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
endmacro()
macro(conan_split_version VERSION_STRING MAJOR MINOR)
#make a list from the version string
string(REPLACE "." ";" VERSION_LIST "${VERSION_STRING}")
#write output values
list(LENGTH VERSION_LIST _version_len)
list(GET VERSION_LIST 0 ${MAJOR})
if(${_version_len} GREATER 1)
list(GET VERSION_LIST 1 ${MINOR})
endif()
endmacro()
macro(conan_error_compiler_version)
message(FATAL_ERROR "Detected a mismatch for the compiler version between your conan profile settings and CMake: \n"
"Compiler version specified in your conan profile: ${CONAN_COMPILER_VERSION}\n"
"Compiler version detected in CMake: ${VERSION_MAJOR}.${VERSION_MINOR}\n"
"Please check your conan profile settings (conan profile show [default|your_profile_name])\n"
"P.S. You may set CONAN_DISABLE_CHECK_COMPILER CMake variable in order to disable this check."
)
endmacro()
set(_CONAN_CURRENT_DIR ${CMAKE_CURRENT_LIST_DIR})
function(conan_get_compiler CONAN_INFO_COMPILER CONAN_INFO_COMPILER_VERSION)
conan_message(STATUS "Current conanbuildinfo.cmake directory: " ${_CONAN_CURRENT_DIR})
if(NOT EXISTS ${_CONAN_CURRENT_DIR}/conaninfo.txt)
conan_message(STATUS "WARN: conaninfo.txt not found")
return()
endif()
file (READ "${_CONAN_CURRENT_DIR}/conaninfo.txt" CONANINFO)
# MATCHALL will match all, including the last one, which is the full_settings one
string(REGEX MATCH "full_settings.*" _FULL_SETTINGS_MATCHED ${CONANINFO})
string(REGEX MATCH "compiler=([-A-Za-z0-9_ ]+)" _MATCHED ${_FULL_SETTINGS_MATCHED})
if(DEFINED CMAKE_MATCH_1)
string(STRIP "${CMAKE_MATCH_1}" _CONAN_INFO_COMPILER)
set(${CONAN_INFO_COMPILER} ${_CONAN_INFO_COMPILER} PARENT_SCOPE)
endif()
string(REGEX MATCH "compiler.version=([-A-Za-z0-9_.]+)" _MATCHED ${_FULL_SETTINGS_MATCHED})
if(DEFINED CMAKE_MATCH_1)
string(STRIP "${CMAKE_MATCH_1}" _CONAN_INFO_COMPILER_VERSION)
set(${CONAN_INFO_COMPILER_VERSION} ${_CONAN_INFO_COMPILER_VERSION} PARENT_SCOPE)
endif()
endfunction()
function(check_compiler_version)
conan_split_version(${CMAKE_CXX_COMPILER_VERSION} VERSION_MAJOR VERSION_MINOR)
if(DEFINED CONAN_SETTINGS_COMPILER_TOOLSET)
conan_message(STATUS "Conan: Skipping compiler check: Declared 'compiler.toolset'")
return()
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
# MSVC_VERSION is defined since 2.8.2 at least
# https://cmake.org/cmake/help/v2.8.2/cmake.html#variable:MSVC_VERSION
# https://cmake.org/cmake/help/v3.14/variable/MSVC_VERSION.html
if(
# 1920-1929 = VS 16.0 (v142 toolset)
(CONAN_COMPILER_VERSION STREQUAL "16" AND NOT((MSVC_VERSION GREATER 1919) AND (MSVC_VERSION LESS 1930))) OR
# 1910-1919 = VS 15.0 (v141 toolset)
(CONAN_COMPILER_VERSION STREQUAL "15" AND NOT((MSVC_VERSION GREATER 1909) AND (MSVC_VERSION LESS 1920))) OR
# 1900 = VS 14.0 (v140 toolset)
(CONAN_COMPILER_VERSION STREQUAL "14" AND NOT(MSVC_VERSION EQUAL 1900)) OR
# 1800 = VS 12.0 (v120 toolset)
(CONAN_COMPILER_VERSION STREQUAL "12" AND NOT VERSION_MAJOR STREQUAL "18") OR
# 1700 = VS 11.0 (v110 toolset)
(CONAN_COMPILER_VERSION STREQUAL "11" AND NOT VERSION_MAJOR STREQUAL "17") OR
# 1600 = VS 10.0 (v100 toolset)
(CONAN_COMPILER_VERSION STREQUAL "10" AND NOT VERSION_MAJOR STREQUAL "16") OR
# 1500 = VS 9.0 (v90 toolset)
(CONAN_COMPILER_VERSION STREQUAL "9" AND NOT VERSION_MAJOR STREQUAL "15") OR
# 1400 = VS 8.0 (v80 toolset)
(CONAN_COMPILER_VERSION STREQUAL "8" AND NOT VERSION_MAJOR STREQUAL "14") OR
# 1310 = VS 7.1, 1300 = VS 7.0
(CONAN_COMPILER_VERSION STREQUAL "7" AND NOT VERSION_MAJOR STREQUAL "13") OR
# 1200 = VS 6.0
(CONAN_COMPILER_VERSION STREQUAL "6" AND NOT VERSION_MAJOR STREQUAL "12") )
conan_error_compiler_version()
endif()
elseif(CONAN_COMPILER STREQUAL "gcc")
conan_split_version(${CONAN_COMPILER_VERSION} CONAN_COMPILER_MAJOR CONAN_COMPILER_MINOR)
set(_CHECK_VERSION ${VERSION_MAJOR}.${VERSION_MINOR})
set(_CONAN_VERSION ${CONAN_COMPILER_MAJOR}.${CONAN_COMPILER_MINOR})
if(NOT ${CONAN_COMPILER_VERSION} VERSION_LESS 5.0)
conan_message(STATUS "Conan: Compiler GCC>=5, checking major version ${CONAN_COMPILER_VERSION}")
conan_split_version(${CONAN_COMPILER_VERSION} CONAN_COMPILER_MAJOR CONAN_COMPILER_MINOR)
if("${CONAN_COMPILER_MINOR}" STREQUAL "")
set(_CHECK_VERSION ${VERSION_MAJOR})
set(_CONAN_VERSION ${CONAN_COMPILER_MAJOR})
endif()
endif()
conan_message(STATUS "Conan: Checking correct version: ${_CHECK_VERSION}")
if(NOT ${_CHECK_VERSION} VERSION_EQUAL ${_CONAN_VERSION})
conan_error_compiler_version()
endif()
elseif(CONAN_COMPILER STREQUAL "clang")
conan_split_version(${CONAN_COMPILER_VERSION} CONAN_COMPILER_MAJOR CONAN_COMPILER_MINOR)
set(_CHECK_VERSION ${VERSION_MAJOR}.${VERSION_MINOR})
set(_CONAN_VERSION ${CONAN_COMPILER_MAJOR}.${CONAN_COMPILER_MINOR})
if(NOT ${CONAN_COMPILER_VERSION} VERSION_LESS 8.0)
conan_message(STATUS "Conan: Compiler Clang>=8, checking major version ${CONAN_COMPILER_VERSION}")
if("${CONAN_COMPILER_MINOR}" STREQUAL "")
set(_CHECK_VERSION ${VERSION_MAJOR})
set(_CONAN_VERSION ${CONAN_COMPILER_MAJOR})
endif()
endif()
conan_message(STATUS "Conan: Checking correct version: ${_CHECK_VERSION}")
if(NOT ${_CHECK_VERSION} VERSION_EQUAL ${_CONAN_VERSION})
conan_error_compiler_version()
endif()
elseif(CONAN_COMPILER STREQUAL "apple-clang" OR CONAN_COMPILER STREQUAL "sun-cc" OR CONAN_COMPILER STREQUAL "mcst-lcc")
conan_split_version(${CONAN_COMPILER_VERSION} CONAN_COMPILER_MAJOR CONAN_COMPILER_MINOR)
if(NOT ${VERSION_MAJOR}.${VERSION_MINOR} VERSION_EQUAL ${CONAN_COMPILER_MAJOR}.${CONAN_COMPILER_MINOR})
conan_error_compiler_version()
endif()
elseif(CONAN_COMPILER STREQUAL "intel")
conan_split_version(${CONAN_COMPILER_VERSION} CONAN_COMPILER_MAJOR CONAN_COMPILER_MINOR)
if(NOT ${CONAN_COMPILER_VERSION} VERSION_LESS 19.1)
if(NOT ${VERSION_MAJOR}.${VERSION_MINOR} VERSION_EQUAL ${CONAN_COMPILER_MAJOR}.${CONAN_COMPILER_MINOR})
conan_error_compiler_version()
endif()
else()
if(NOT ${VERSION_MAJOR} VERSION_EQUAL ${CONAN_COMPILER_MAJOR})
conan_error_compiler_version()
endif()
endif()
else()
conan_message(STATUS "WARN: Unknown compiler '${CONAN_COMPILER}', skipping the version check...")
endif()
endfunction()
function(conan_check_compiler)
if(CONAN_DISABLE_CHECK_COMPILER)
conan_message(STATUS "WARN: Disabled conan compiler checks")
return()
endif()
if(NOT DEFINED CMAKE_CXX_COMPILER_ID)
if(DEFINED CMAKE_C_COMPILER_ID)
conan_message(STATUS "This project seems to be plain C, using '${CMAKE_C_COMPILER_ID}' compiler")
set(CMAKE_CXX_COMPILER_ID ${CMAKE_C_COMPILER_ID})
set(CMAKE_CXX_COMPILER_VERSION ${CMAKE_C_COMPILER_VERSION})
else()
message(FATAL_ERROR "This project seems to be plain C, but no compiler defined")
endif()
endif()
if(NOT CMAKE_CXX_COMPILER_ID AND NOT CMAKE_C_COMPILER_ID)
# This use case happens when compiler is not identified by CMake, but the compilers are there and work
conan_message(STATUS "*** WARN: CMake was not able to identify a C or C++ compiler ***")
conan_message(STATUS "*** WARN: Disabling compiler checks. Please make sure your settings match your environment ***")
return()
endif()
if(NOT DEFINED CONAN_COMPILER)
conan_get_compiler(CONAN_COMPILER CONAN_COMPILER_VERSION)
if(NOT DEFINED CONAN_COMPILER)
conan_message(STATUS "WARN: CONAN_COMPILER variable not set, please make sure yourself that "
"your compiler and version matches your declared settings")
return()
endif()
endif()
if(NOT CMAKE_HOST_SYSTEM_NAME STREQUAL ${CMAKE_SYSTEM_NAME})
set(CROSS_BUILDING 1)
endif()
# If using VS, verify toolset
if (CONAN_COMPILER STREQUAL "Visual Studio")
if (CONAN_SETTINGS_COMPILER_TOOLSET MATCHES "LLVM" OR
CONAN_SETTINGS_COMPILER_TOOLSET MATCHES "llvm" OR
CONAN_SETTINGS_COMPILER_TOOLSET MATCHES "clang" OR
CONAN_SETTINGS_COMPILER_TOOLSET MATCHES "Clang")
set(EXPECTED_CMAKE_CXX_COMPILER_ID "Clang")
elseif (CONAN_SETTINGS_COMPILER_TOOLSET MATCHES "Intel")
set(EXPECTED_CMAKE_CXX_COMPILER_ID "Intel")
else()
set(EXPECTED_CMAKE_CXX_COMPILER_ID "MSVC")
endif()
if (NOT CMAKE_CXX_COMPILER_ID MATCHES ${EXPECTED_CMAKE_CXX_COMPILER_ID})
message(FATAL_ERROR "Incorrect '${CONAN_COMPILER}'. Toolset specifies compiler as '${EXPECTED_CMAKE_CXX_COMPILER_ID}' "
"but CMake detected '${CMAKE_CXX_COMPILER_ID}'")
endif()
# Avoid checks when cross compiling, apple-clang crashes because its APPLE but not apple-clang
# Actually CMake is detecting "clang" when you are using apple-clang, only if CMP0025 is set to NEW will detect apple-clang
elseif((CONAN_COMPILER STREQUAL "gcc" AND NOT CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR
(CONAN_COMPILER STREQUAL "apple-clang" AND NOT CROSS_BUILDING AND (NOT APPLE OR NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")) OR
(CONAN_COMPILER STREQUAL "clang" AND NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") OR
(CONAN_COMPILER STREQUAL "sun-cc" AND NOT CMAKE_CXX_COMPILER_ID MATCHES "SunPro") )
message(FATAL_ERROR "Incorrect '${CONAN_COMPILER}', is not the one detected by CMake: '${CMAKE_CXX_COMPILER_ID}'")
endif()
if(NOT DEFINED CONAN_COMPILER_VERSION)
conan_message(STATUS "WARN: CONAN_COMPILER_VERSION variable not set, please make sure yourself "
"that your compiler version matches your declared settings")
return()
endif()
check_compiler_version()
endfunction()
macro(conan_set_flags build_type)
set(CMAKE_CXX_FLAGS${build_type} "${CMAKE_CXX_FLAGS${build_type}} ${CONAN_CXX_FLAGS${build_type}}")
set(CMAKE_C_FLAGS${build_type} "${CMAKE_C_FLAGS${build_type}} ${CONAN_C_FLAGS${build_type}}")
set(CMAKE_SHARED_LINKER_FLAGS${build_type} "${CMAKE_SHARED_LINKER_FLAGS${build_type}} ${CONAN_SHARED_LINKER_FLAGS${build_type}}")
set(CMAKE_EXE_LINKER_FLAGS${build_type} "${CMAKE_EXE_LINKER_FLAGS${build_type}} ${CONAN_EXE_LINKER_FLAGS${build_type}}")
endmacro()
macro(conan_global_flags)
if(CONAN_SYSTEM_INCLUDES)
include_directories(SYSTEM ${CONAN_INCLUDE_DIRS}
"$<$<CONFIG:Release>:${CONAN_INCLUDE_DIRS_RELEASE}>"
"$<$<CONFIG:RelWithDebInfo>:${CONAN_INCLUDE_DIRS_RELWITHDEBINFO}>"
"$<$<CONFIG:MinSizeRel>:${CONAN_INCLUDE_DIRS_MINSIZEREL}>"
"$<$<CONFIG:Debug>:${CONAN_INCLUDE_DIRS_DEBUG}>")
else()
include_directories(${CONAN_INCLUDE_DIRS}
"$<$<CONFIG:Release>:${CONAN_INCLUDE_DIRS_RELEASE}>"
"$<$<CONFIG:RelWithDebInfo>:${CONAN_INCLUDE_DIRS_RELWITHDEBINFO}>"
"$<$<CONFIG:MinSizeRel>:${CONAN_INCLUDE_DIRS_MINSIZEREL}>"
"$<$<CONFIG:Debug>:${CONAN_INCLUDE_DIRS_DEBUG}>")
endif()
link_directories(${CONAN_LIB_DIRS})
conan_find_libraries_abs_path("${CONAN_LIBS_DEBUG}" "${CONAN_LIB_DIRS_DEBUG}"
CONAN_LIBS_DEBUG)
conan_find_libraries_abs_path("${CONAN_LIBS_RELEASE}" "${CONAN_LIB_DIRS_RELEASE}"
CONAN_LIBS_RELEASE)
conan_find_libraries_abs_path("${CONAN_LIBS_RELWITHDEBINFO}" "${CONAN_LIB_DIRS_RELWITHDEBINFO}"
CONAN_LIBS_RELWITHDEBINFO)
conan_find_libraries_abs_path("${CONAN_LIBS_MINSIZEREL}" "${CONAN_LIB_DIRS_MINSIZEREL}"
CONAN_LIBS_MINSIZEREL)
add_compile_options(${CONAN_DEFINES}
"$<$<CONFIG:Debug>:${CONAN_DEFINES_DEBUG}>"
"$<$<CONFIG:Release>:${CONAN_DEFINES_RELEASE}>"
"$<$<CONFIG:RelWithDebInfo>:${CONAN_DEFINES_RELWITHDEBINFO}>"
"$<$<CONFIG:MinSizeRel>:${CONAN_DEFINES_MINSIZEREL}>")
conan_set_flags("")
conan_set_flags("_RELEASE")
conan_set_flags("_DEBUG")
endmacro()
macro(conan_target_link_libraries target)
if(CONAN_TARGETS)
target_link_libraries(${target} ${CONAN_TARGETS})
else()
target_link_libraries(${target} ${CONAN_LIBS})
foreach(_LIB ${CONAN_LIBS_RELEASE})
target_link_libraries(${target} optimized ${_LIB})
endforeach()
foreach(_LIB ${CONAN_LIBS_DEBUG})
target_link_libraries(${target} debug ${_LIB})
endforeach()
endif()
endmacro()
macro(conan_include_build_modules)
if(CMAKE_BUILD_TYPE)
if(${CMAKE_BUILD_TYPE} MATCHES "Debug")
set(CONAN_BUILD_MODULES_PATHS ${CONAN_BUILD_MODULES_PATHS_DEBUG} ${CONAN_BUILD_MODULES_PATHS})
elseif(${CMAKE_BUILD_TYPE} MATCHES "Release")
set(CONAN_BUILD_MODULES_PATHS ${CONAN_BUILD_MODULES_PATHS_RELEASE} ${CONAN_BUILD_MODULES_PATHS})
elseif(${CMAKE_BUILD_TYPE} MATCHES "RelWithDebInfo")
set(CONAN_BUILD_MODULES_PATHS ${CONAN_BUILD_MODULES_PATHS_RELWITHDEBINFO} ${CONAN_BUILD_MODULES_PATHS})
elseif(${CMAKE_BUILD_TYPE} MATCHES "MinSizeRel")
set(CONAN_BUILD_MODULES_PATHS ${CONAN_BUILD_MODULES_PATHS_MINSIZEREL} ${CONAN_BUILD_MODULES_PATHS})
endif()
endif()
foreach(_BUILD_MODULE_PATH ${CONAN_BUILD_MODULES_PATHS})
include(${_BUILD_MODULE_PATH})
endforeach()
endmacro()
### Definition of user declared vars (user_info) ###

View File

@@ -0,0 +1,49 @@
[includedirs]
[libdirs]
[bindirs]
[resdirs]
[builddirs]
[libs]
[system_libs]
[defines]
[cppflags]
[cxxflags]
[cflags]
[sharedlinkflags]
[exelinkflags]
[sysroot]
[frameworks]
[frameworkdirs]

View File

@@ -0,0 +1,42 @@
from conans import ConanFile, CMake, tools
import os
class AngelScriptConan(ConanFile):
name = "AngelScript"
version = "2.35"
license = "<Put the package license here>"
url = "<Package recipe repository url here, for issues about the package>"
description = "<Description of Hello here>"
settings = "os", "compiler", "build_type", "arch"
options = {"shared": [True, False], "link_std_statically": [True, False]}
default_options = {"shared": False, "link_std_statically": True}
generators = "cmake"
exports_sources = "../../*"
def build(self):
cmake = CMake(self)
if (self.options.shared):
self.output.info("Building shared lib.")
cmake.definitions["BUILD_SHARED_LIBS"] = 1
else:
self.output.info("Building static lib.")
if (self.options.link_std_statically):
cmake.definitions["LINK_STD_STATICALLY"] = 1
cmake.configure(build_dir="./build", source_dir="../projects/cmake")
cmake.build()
def package(self):
os.chdir(os.path.dirname(__file__))
print(os.getcwd())
self.copy("include/angelscript.h", dst="include", keep_path=False)
self.copy("*.dll", dst="bin", keep_path=False)
self.copy("*.so", dst="lib", keep_path=False)
self.copy("*.so.*", dst="lib", keep_path=False)
self.copy("*.dylib", dst="lib", keep_path=False)
self.copy("*.a", dst="lib", keep_path=False)
def package_info(self):
self.cpp_info.libs = ["angelscript"]

View File

@@ -0,0 +1,35 @@
[settings]
arch=x86_64
build_type=Release
compiler=clang
compiler.libcxx=libstdc++11
compiler.version=11
os=Linux
[requires]
[options]
link_std_statically=True
shared=True
[full_settings]
arch=x86_64
build_type=Release
compiler=clang
compiler.libcxx=libstdc++11
compiler.version=11
os=Linux
[full_requires]
[full_options]
link_std_statically=True
shared=True
[recipe_hash]
[env]

View File

@@ -0,0 +1,18 @@
{
"options": [
[
"link_std_statically",
"True"
],
[
"shared",
"True"
]
],
"root": {
"name": "AngelScript",
"version": "2.35",
"user": null,
"channel": null
}
}

View File

@@ -0,0 +1,159 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="Static library" />
<Option pch_mode="0" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option output="../../lib/libangelscriptd.a" prefix_auto="0" extension_auto="0" />
<Option working_dir="" />
<Option object_output="objs/debug" />
<Option type="2" />
<Option compiler="gcc" />
<Option createDefFile="1" />
<Option projectResourceIncludeDirsRelation="2" />
<Compiler>
<Add option="-g" />
<Add option="-m32" />
<Add option="-DANGELSCRIPT_EXPORT" />
<Add option="-D_DEBUG" />
</Compiler>
</Target>
<Target title="Debug 64">
<Option output="../../lib/libangelscript64d.a" prefix_auto="0" extension_auto="0" />
<Option working_dir="" />
<Option object_output="objs/debug_64" />
<Option type="2" />
<Option compiler="gcc" />
<Option createDefFile="1" />
<Option projectResourceIncludeDirsRelation="2" />
<Compiler>
<Add option="-g" />
<Add option="-m64" />
<Add option="-DANGELSCRIPT_EXPORT" />
<Add option="-D_DEBUG" />
</Compiler>
</Target>
<Target title="Release">
<Option output="../../lib/libangelscript.a" prefix_auto="0" extension_auto="0" />
<Option working_dir="" />
<Option object_output="objs/release" />
<Option type="2" />
<Option compiler="gcc" />
<Option createDefFile="1" />
<Option projectResourceIncludeDirsRelation="2" />
<Compiler>
<Add option="-O3" />
<Add option="-m32" />
<Add option="-DANGELSCRIPT_EXPORT" />
<Add option="-DNDEBUG" />
</Compiler>
</Target>
<Target title="Release 64">
<Option output="../../lib/libangelscript64.a" prefix_auto="0" extension_auto="0" />
<Option working_dir="" />
<Option object_output="objs/release_64" />
<Option type="2" />
<Option compiler="gcc" />
<Option createDefFile="1" />
<Option projectResourceIncludeDirsRelation="2" />
<Compiler>
<Add option="-O3" />
<Add option="-m64" />
<Add option="-DANGELSCRIPT_EXPORT" />
<Add option="-DNDEBUG" />
</Compiler>
</Target>
</Build>
<VirtualTargets>
<Add alias="All" targets="Debug;Debug 64;Release;Release 64;" />
</VirtualTargets>
<Compiler>
<Add option="-std=c++11" />
<Add option="-Wall" />
<Add option="-fexceptions" />
<Add option="-fno-strict-aliasing" />
</Compiler>
<Unit filename="../../include/angelscript.h" />
<Unit filename="../../source/as_array.h" />
<Unit filename="../../source/as_atomic.cpp" />
<Unit filename="../../source/as_atomic.h" />
<Unit filename="../../source/as_builder.cpp" />
<Unit filename="../../source/as_builder.h" />
<Unit filename="../../source/as_bytecode.cpp" />
<Unit filename="../../source/as_bytecode.h" />
<Unit filename="../../source/as_callfunc.cpp" />
<Unit filename="../../source/as_callfunc.h" />
<Unit filename="../../source/as_callfunc_arm.cpp" />
<Unit filename="../../source/as_callfunc_mips.cpp" />
<Unit filename="../../source/as_callfunc_ppc.cpp" />
<Unit filename="../../source/as_callfunc_ppc_64.cpp" />
<Unit filename="../../source/as_callfunc_sh4.cpp" />
<Unit filename="../../source/as_callfunc_x64_gcc.cpp" />
<Unit filename="../../source/as_callfunc_x64_mingw.cpp" />
<Unit filename="../../source/as_callfunc_x64_msvc.cpp" />
<Unit filename="../../source/as_callfunc_x86.cpp" />
<Unit filename="../../source/as_callfunc_xenon.cpp" />
<Unit filename="../../source/as_compiler.cpp" />
<Unit filename="../../source/as_compiler.h" />
<Unit filename="../../source/as_config.h" />
<Unit filename="../../source/as_configgroup.cpp" />
<Unit filename="../../source/as_configgroup.h" />
<Unit filename="../../source/as_context.cpp" />
<Unit filename="../../source/as_context.h" />
<Unit filename="../../source/as_criticalsection.h" />
<Unit filename="../../source/as_datatype.cpp" />
<Unit filename="../../source/as_datatype.h" />
<Unit filename="../../source/as_debug.h" />
<Unit filename="../../source/as_gc.cpp" />
<Unit filename="../../source/as_gc.h" />
<Unit filename="../../source/as_generic.cpp" />
<Unit filename="../../source/as_generic.h" />
<Unit filename="../../source/as_globalproperty.cpp" />
<Unit filename="../../source/as_map.h" />
<Unit filename="../../source/as_memory.cpp" />
<Unit filename="../../source/as_memory.h" />
<Unit filename="../../source/as_module.cpp" />
<Unit filename="../../source/as_module.h" />
<Unit filename="../../source/as_objecttype.cpp" />
<Unit filename="../../source/as_objecttype.h" />
<Unit filename="../../source/as_outputbuffer.cpp" />
<Unit filename="../../source/as_outputbuffer.h" />
<Unit filename="../../source/as_parser.cpp" />
<Unit filename="../../source/as_parser.h" />
<Unit filename="../../source/as_property.h" />
<Unit filename="../../source/as_restore.cpp" />
<Unit filename="../../source/as_restore.h" />
<Unit filename="../../source/as_scriptcode.cpp" />
<Unit filename="../../source/as_scriptcode.h" />
<Unit filename="../../source/as_scriptengine.cpp" />
<Unit filename="../../source/as_scriptengine.h" />
<Unit filename="../../source/as_scriptfunction.cpp" />
<Unit filename="../../source/as_scriptfunction.h" />
<Unit filename="../../source/as_scriptnode.cpp" />
<Unit filename="../../source/as_scriptnode.h" />
<Unit filename="../../source/as_scriptobject.cpp" />
<Unit filename="../../source/as_scriptobject.h" />
<Unit filename="../../source/as_string.cpp" />
<Unit filename="../../source/as_string.h" />
<Unit filename="../../source/as_string_util.cpp" />
<Unit filename="../../source/as_string_util.h" />
<Unit filename="../../source/as_texts.h" />
<Unit filename="../../source/as_thread.cpp" />
<Unit filename="../../source/as_thread.h" />
<Unit filename="../../source/as_tokendef.h" />
<Unit filename="../../source/as_tokenizer.cpp" />
<Unit filename="../../source/as_tokenizer.h" />
<Unit filename="../../source/as_typeinfo.cpp" />
<Unit filename="../../source/as_typeinfo.h" />
<Unit filename="../../source/as_variablescope.cpp" />
<Unit filename="../../source/as_variablescope.h" />
<Extensions>
<code_completion />
<envvars />
<debugger />
</Extensions>
</Project>
</CodeBlocks_project_file>

View File

@@ -0,0 +1,131 @@
# Angelscript makefile for linux (based on MingW makefile)
# Type 'make' then 'make install' to complete the installation of the library
# For 'make install' to work, set LOCAL according to your system configuration
LOCAL = /usr/local
# If you want to build a shared library, then run make with SHARED=1 and VERSION=version
LIB = libangelscript.a
DEVLIB = libangelscript.dylib
BUNDLE = libangelscript.so
INC = angelscript.h
SRCDIR = ../../source
INCDIR = ../../include
OBJDIR = obj
LIBDIR = ../../lib
CXX = c++
AFLAGS= -arch i386 -arch x86_64
CXXFLAGS = -g -Wall -fPIC $(AFLAGS)
CXXBFLAGS = $(CXXFLAGS) -fno-common
DELETER = rm -f
COPIER = cp -a
SRCNAMES = \
as_atomic.cpp \
as_builder.cpp \
as_bytecode.cpp \
as_callfunc.cpp \
as_callfunc_arm.cpp \
as_callfunc_mips.cpp \
as_callfunc_ppc.cpp \
as_callfunc_ppc_64.cpp \
as_callfunc_sh4.cpp \
as_callfunc_x86.cpp \
as_callfunc_x64_gcc.cpp \
as_compiler.cpp \
as_context.cpp \
as_configgroup.cpp \
as_datatype.cpp \
as_generic.cpp \
as_gc.cpp \
as_globalproperty.cpp \
as_memory.cpp \
as_module.cpp \
as_objecttype.cpp \
as_outputbuffer.cpp \
as_parser.cpp \
as_restore.cpp \
as_scriptcode.cpp \
as_scriptengine.cpp \
as_scriptfunction.cpp \
as_scriptnode.cpp \
as_scriptobject.cpp \
as_string.cpp \
as_string_util.cpp \
as_thread.cpp \
as_tokenizer.cpp \
as_typeinfo.cpp \
as_variablescope.cpp \
OBJ = $(addprefix $(OBJDIR)/, $(notdir $(SRCNAMES:.cpp=.o)))
BOBJ = $(addprefix $(OBJDIR)/, $(notdir $(SRCNAMES:.cpp=.lo)))
TARG = $(LIBDIR)/$(LIB) $(LIBDIR)/$(DEVLIB) $(LIBDIR)/$(BUNDLE)
all: $(TARG)
$(LIBDIR)/$(LIB): $(OBJDIR) $(LIBDIR) $(OBJ)
rm -f $(LIBDIR)/$(LIB)
ar r $(LIBDIR)/$(LIB) $(OBJ)
ranlib $(LIBDIR)/$(LIB)
file $(LIBDIR)/$(LIB)
$(LIBDIR)/$(DEVLIB): $(OBJDIR) $(LIBDIR) $(OBJ)
rm -f $(LIBDIR)/$(DEVLIB)
$(CXX) $(AFLAGS) -dynamiclib -o $(DEVLIB) $(OBJ)
mv $(DEVLIB) $(LIBDIR)/$(DEVLIB)
file $(LIBDIR)/$(DEVLIB)
$(LIBDIR)/$(BUNDLE): $(OBJDIR) $(LIBDIR) $(BOBJ)
rm -f $(LIBDIR)/$(BUNDLE)
$(CXX) $(AFLAGS) -bundle -flat_namespace -undefined suppress -o $(LIBDIR)/$(BUNDLE) $(BOBJ)
file $(LIBDIR)/$(BUNDLE)
@echo -------------------------------------------------------------------
@echo Done. As root, type 'make install' to install the library.
$(OBJDIR):
mkdir $(OBJDIR)
$(LIBDIR):
mkdir $(LIBDIR)
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
$(CXX) $(CXXFLAGS) -o $@ -c $<
$(OBJDIR)/%.o: $(SRCDIR)/%.S
$(CXX) $(CXXFLAGS) -o $@ -c $<
$(OBJDIR)/%.o: $(SRCDIR)/%.s
$(CXX) $(CXXFLAGS) -o $@ -c $<
$(OBJDIR)/%.lo: $(SRCDIR)/%.cpp
$(CXX) $(CXXBFLAGS) -o $@ -c $<
$(OBJDIR)/%.lo: $(SRCDIR)/%.S
$(CXX) $(CXXBFLAGS) -o $@ -c $<
$(OBJDIR)/%.lo: $(SRCDIR)/%.s
$(CXX) $(CXXBFLAGS) -o $@ -c $<
clean:
$(DELETER) $(OBJ) $(BOBJ) $(TARG)
install: $(TARG)
@echo Installing to: $(LOCAL)/lib and $(LOCAL)/include...
@echo -------------------------------------------------------------------
ifdef SHARED
$(COPIER) $(LIBDIR)/$(DEVLIB) $(LOCAL)/lib
endif
$(COPIER) $(TARG) $(LOCAL)/lib
$(COPIER) $(INCDIR)/$(INC) $(LOCAL)/include
@echo -------------------------------------------------------------------
@echo Angelscript library installed. Enjoy!
uninstall:
$(DELETER) $(LOCAL)/include/$(INC) $(LOCAL)/lib/$(LIB) $(LOCAL)/lib/$(DEVLIB)
@echo -------------------------------------------------------------------
@echo Angelscript library uninstalled.
.PHONY: all clean install uninstall

View File

@@ -0,0 +1,73 @@
** (UN)FREQUENTLY ASKED QUESTIONS **
1. Why do you have to specify PREFIX= even when building
when overriding the default ?
2. When overriding the default prefix, how do you compile
and link my program ?
--
1. Why do you have to specify PREFIX= even when building,
when overriding the default ?
Because it allows easier linking. The way the Linux
link loader works, if the library name has a slash in it,
then it resolves it that way. If it doesn't it goes through
a series of steps which tries to find it. However, without
updating a certain file it won't find it under '/usr/local'
(and similar with '/tmp'). Therefore, as long as you have
the same PREFIX= (or don't specify it at all), all you need
to do to link to the shared version is link to it (and any
other dependencies; -lpthread comes to mind here). For
example the link options might be :
-langelscript_s -lpthread
--
2. When overriding the default prefix, how do you compile
and link my program ?
An example scenario is the following :
You installed into /opt which means the following
files should exist :
/opt/include/angelscript.h
/opt/lib/libangelscript.so (which is a symbolic link to
the current version installed)
/opt/lib/libangelscript.a (the static library).
If you #include angelscript.h you might normally
have :
#include <angelscript.h>
However, when that file is not in the standard directories
the compiler searches, you have to either use :
#include "/opt/include/angelscript.h"
(method one)
or alternatively keep the include (using the angle brackets)
but pass the include path (or paths actually but in this case
path) to the compiler so it knows to search an additional
location. If you're using g++ then the following option
will work (it also works for gcc but I am assuming you
are using C++) :
-I/opt/include
You must however still link. You therefore must pass another
option to the compiler (which will pass it to the linker)
and the option os -L which is used like so (to follow the
scenario) :
-L/opt/lib
The rest is the same.
CONTACT INFO:
If you have any questions or concerns, by all
means have Andreas contact me (at this time I
don't have an email I feel okay sharing - if it
seems this is of use to others I will likely
create an email on my server for this very
purpose). For now Andreas can forward the
message to me.

View File

@@ -0,0 +1,247 @@
# AngelScript makefile for Linux.
# Type 'make' then 'make install' to complete
# the installation of the library. You no
# longer have to specify SHARED=1 VERSION=x.y.z
# (the Makefile automatically determines it
# and builds it and the static library).
# See README for how to use the shared library
# instead of the static. The README also
# contains other information and in particular
# specifies on how to override the install
# location should you desire this (you don't
# have to - nor should you - edit this
# file).
#
# One note: I don't have a way to test
# the phone builds. I am an old-timer
# and I _still_ miss customer-owned
# coin-operated telephones. In fact
# I still _miss_ the rotary telephone!
## library names and versions
LIBNAME=libangelscript
AS_VER:=$(shell awk -F\" '/\#define ANGELSCRIPT_VERSION_STRING/{print $$2}' ../../include/angelscript.h | cut -d" " -f1)
SHLIB=$(LIBNAME).so.$(AS_VER)
ARLIB=$(LIBNAME).a
## install directories
ifeq ($(PREFIX),)
PREFIX=/usr/local
endif
INCLUDEDIR_DEST=$(PREFIX)/include
LIBDIR_DEST=$(PREFIX)/lib
DOCDIR_BASEDIR=$(PREFIX)/share/doc/angelscript-$(AS_VER)
DOXYGEN_DEST=$(DOCDIR_BASEDIR)/html
SAMPLES_DEST=$(DOCDIR_BASEDIR)/samples
## install commands
INSTALL = install
INSTALL_DIR = $(INSTALL) -d
INSTALL_SHLIB = $(INSTALL) -m 755
INSTALL_ARLIB = $(INSTALL) -m 644
INSTALL_HEADER = $(INSTALL) -m 644
CP_SYMLINK = cp --no-dereference --preserve=links
CP_R = cp -R
HEADER = angelscript.h
SRCDIR = ../../source
INCDIR = ../../include
## platform specific settings
ifeq ($(TARGETPLATFORM), iphone)
IPHONEBIN = /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin
OBJDIR = obj-iphone
LIBDIR = ../../lib-iphone
CXX ?= $(IPHONEBIN)/clang++
CXXFLAGS += -Wall -fPIC -fno-strict-aliasing -arch armv7 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk -miphoneos-version-min=3.0
else ifeq ($(TARGETPLATFORM), iphonesimulator)
IPHONEBIN = /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin
OBJDIR = obj-iphone
LIBDIR = ../../lib-iphone
CXX ?= $(IPHONEBIN)/clang++
CXXFLAGS += -Wall -fPIC -fno-strict-aliasing -arch i386 -isysroot /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk -miphoneos-version-min=3.0
else ifeq ($(TARGETPLATFORM), android)
ANDROIDNDKROOT = /cygdrive/c/android/android-ndk-1.6_r1
ANDROIDBIN = $(ANDROIDNDKROOT)/build/prebuilt/windows/arm-eabi-4.2.1/bin
SYSROOT = $(ANDROIDNDKROOT)/build/platforms/android-4/arch-arm
OBJDIR = obj-android
LIBDIR = ../../lib-android
CXX ?= $(ANDROIDBIN)/arm-eabi-gcc
CXXFLAGS += -I$(SYSROOT)/usr/include \
-Wall \
-DANDROID \
-fno-exceptions \
-march=armv6 -mthumb-interwork \
-mfloat-abi=softfp -fno-rtti
else
OBJDIR = obj
LIBDIR = ../../lib
CXX ?= g++
# On i686 architecture you may need to add -march=i686 if you get
# an undefined symbol for __sync_sub_and_fetch_4 in as_atomic.cpp.
CXXFLAGS += -Wall -fPIC -fno-strict-aliasing
endif
## Detect if targetting ARM CPU and if so tell assembler to accept implicit IT constructs in thumb mode
GCC_ARCH := $(shell $(CXX) -dumpmachine)
$(info GCC ARCH: $(GCC_ARCH))
ifneq (,$(findstring arm-,$(GCC_ARCH)))
CXXFLAGS += -Wa,-mimplicit-it=thumb
else ifneq (,$(findstring armv7-, $(GCC_ARCH)))
CXXFLAGS += -Wa,-mimplicit-it=thumb
endif
## toolchain
AR ?= ar
RANLIB ?= ranlib
SRCNAMES = \
as_atomic.cpp \
as_builder.cpp \
as_bytecode.cpp \
as_callfunc.cpp \
as_callfunc_arm.cpp \
as_callfunc_mips.cpp \
as_callfunc_ppc.cpp \
as_callfunc_ppc_64.cpp \
as_callfunc_sh4.cpp \
as_callfunc_x86.cpp \
as_callfunc_x64_gcc.cpp \
as_callfunc_x64_mingw.cpp \
as_compiler.cpp \
as_context.cpp \
as_configgroup.cpp \
as_datatype.cpp \
as_generic.cpp \
as_gc.cpp \
as_globalproperty.cpp \
as_memory.cpp \
as_module.cpp \
as_objecttype.cpp \
as_outputbuffer.cpp \
as_parser.cpp \
as_restore.cpp \
as_scriptcode.cpp \
as_scriptengine.cpp \
as_scriptfunction.cpp \
as_scriptnode.cpp \
as_scriptobject.cpp \
as_string.cpp \
as_string_util.cpp \
as_thread.cpp \
as_tokenizer.cpp \
as_typeinfo.cpp \
as_variablescope.cpp \
OBJ = $(addprefix $(OBJDIR)/, $(notdir $(SRCNAMES:.cpp=.o)))
ifeq ($(TARGETPLATFORM), iphone)
OBJ += $(OBJDIR)/as_callfunc_arm_xcode.o
else
OBJ += $(OBJDIR)/as_callfunc_arm_gcc.o
endif
default: all
all: shared static
shared: $(LIBDIR)/$(SHLIB) $(LIBDIR)/$(LIBNAME).so
static: $(LIBDIR) $(OBJDIR) $(LIBDIR)/$(ARLIB)
$(OBJDIR):
mkdir -p "$(OBJDIR)"
$(LIBDIR):
mkdir -p "$(LIBDIR)"
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
$(CXX) $(CXXFLAGS) -o $@ -c $<
$(OBJDIR)/%.o: $(SRCDIR)/%.S
$(CXX) $(CXXFLAGS) -o $@ -c $<
$(OBJDIR)/%.o: $(SRCDIR)/%.s
$(CXX) $(CXXFLAGS) -o $@ -c $<
$(LIBDIR)/$(SHLIB): $(OBJ)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared -Wl,-soname,$(SHLIB) -o "$(LIBDIR)"/$(SHLIB) $(OBJ)
$(LIBDIR)/$(LIBNAME).so: $(LIBDIR)/$(SHLIB)
@( cd "$(LIBDIR)" && ln -s $(SHLIB) $(LIBNAME).so )
$(LIBDIR)/$(ARLIB): $(OBJ)
$(AR) r "$(LIBDIR)"/$(ARLIB) $(OBJ)
$(RANLIB) "$(LIBDIR)"/$(ARLIB)
## install rules
install_header: $(INCDIR)/$(HEADER)
$(INSTALL_DIR) "$(DESTDIR)/$(INCLUDEDIR_DEST)"
$(INSTALL_HEADER) "$(INCDIR)"/$(HEADER) "$(DESTDIR)/$(INCLUDEDIR_DEST)/"$(HEADER)
install_shared:
$(INSTALL_DIR) "$(DESTDIR)/$(LIBDIR_DEST)"
$(INSTALL_SHLIB) "$(LIBDIR)"/$(SHLIB) "$(DESTDIR)/$(LIBDIR_DEST)/"$(SHLIB)
$(CP_SYMLINK) "$(LIBDIR)"/$(LIBNAME).so "$(DESTDIR)/$(LIBDIR_DEST)/"$(LIBNAME).so
install_static: $(LIBDIR)/$(ARLIB) $(LIBDIR)/$(SHLIB)
$(INSTALL_DIR) "$(DESTDIR)/$(LIBDIR_DEST)"
$(INSTALL_ARLIB) "$(LIBDIR)"/$(ARLIB) "$(DESTDIR)/$(LIBDIR_DEST)/"$(ARLIB)
install_docs: ./../../../docs
$(INSTALL_DIR) "$(DESTDIR)/$(DOCDIR_BASEDIR)"
$(CP_R) ./../../../docs "$(DESTDIR)/$(DOXYGEN_DEST)"
install_samples: ./../../../samples
$(INSTALL_DIR) "$(DESTDIR)/$(DOCDIR_BASEDIR)"
$(CP_R) ./../../../samples "$(DESTDIR)/$(SAMPLES_DEST)"
install_all: install_docs install_samples install
install: install_header install_shared install_static
uninstall:
rm -f "$(DESTDIR)/$(INCLUDEDIR_DEST)/$(HEADER)" "$(DESTDIR)/$(LIBDIR_DEST)"/$(LIBNAME)*
help:
@echo -------------------------------------------------------------------
@echo 'BUILDING:'
@echo ' make all: build shared and static libs'
@echo ' make shared: build shared lib only'
@echo ' make static: build static lib only'
@echo
@echo 'INSTALLING:'
@echo ' make install: install headers, shared and static libs'
@echo ' make install_header: install only the headers'
@echo ' make install_shared: install only the shared libs'
@echo ' make install_static: install only the static libs'
@echo ' make install_docs: install only the documentation'
@echo ' make install_samples: install only the samples'
@echo ' make install_all: install everything, including docs and samples'
@echo
@echo 'PARAMETERS (pass to make, as in PARAM=value):'
@echo ' PREFIX: installation prefix (default /usr/local)'
@echo ' INCLUDEDIR_DEST: where to install headers (default PREFIX/include)'
@echo ' LIBDIR_DEST: where to install libraries (default PREFIX/lib)'
@echo ' DOCDIR_BASEDIR: where the basedir of the documentation lies'
@echo ' (default PREFIX/share/doc/angelscript-AS_VER)'
@echo ' DOXYGEN_DEST: where to install doxygen documentation'
@echo ' (default DOCDIR_BASEDIR/html)'
@echo ' SAMPLES_DEST: where to install samples'
@echo ' (default DOCDIR_BASEDIR/samples)'
@echo ' DESTDIR: destination, prepended to PREFIX, usually used by'
@echo ' package managers (default empty)'
@echo -------------------------------------------------------------------
clean:
rm -f $(OBJ) "$(LIBDIR)"/$(ARLIB) "$(LIBDIR)"/$(SHLIB) "$(LIBDIR)"/$(LIBNAME).so
.PHONY: all clean install install_all install_docs install_header install_samples install_shared install_static shared static uninstall

View File

@@ -0,0 +1,63 @@
If you want to override /usr/local as the default prefix
(which means /usr/local/include would have the header file and
/usr/local/lib would have the library files), then run
make, make install and make uninstall (to build, to
install and uninstall respectively - you need it for
all three as I explain below) :
make PREFIX=/tmp
make PREFIX=/tmp install
make PREFIX=/tmp uninstall
The last two will of course have to be done
as root if you need permissions to write to
the directory (for /tmp you wouldn't unless
the files already existed by someone else and
you didn't have permission).
In any case, the above would install header file
under '/tmp/include' and the library file(s) under
'/tmp/lib'.
If you want to know the technical details as to why
you have to (when overriding the install location)
specify PREFIX= even when building, see the FAQ
file (summary: it makes it easier for you when linking
in the shared library).
A word of caution to those overriding prefix :
--
You are more than welcome to disregard this but I feel
it is something I should bring up. If you do override
the prefix I strongly recommend you do not specify
'/usr'. Why one might ask. The typical way is
that user-compiled programs/libraries/etc. go under
'/usr/local' (other times '/opt'). This has multiple
benefits: you keep '/usr' clean and if you have a
package manager then it makes it easy to say:
"The only files under /usr/include and /usr/lib are
those that belong to a package."
In other words it is easier to maintain integrity
and verify everything. Most important of it all
(aside the security implications) is this:
You have less chance of name clashes. If there ever
is a package that installs to /usr and it includes
the files (maybe a package for AngelScript) then you
will have issues.
--
Lastly: I don't have a way to test the phone builds
so I cannot verify the build process (it really
depends on the environment and architecture, like
most things); I'm an old-timer that hates the
"smart" trend (besides: it is a horrible misuse
of the world 'smart').
CONTACT:
If you have any questions or concerns, by all
means have Andreas contact me (at this time I
don't have an email I feel okay sharing - if it
seems this is of use to others I will likely
create an email on my server for this very
purpose). For now Andreas can forward the
message to me.

View File

@@ -0,0 +1,2 @@
This file is here just in case your unarchiver does not extract empty directories.
Feel free to remove it.

View File

@@ -0,0 +1,111 @@
#!/usr/bin/env mkb
options
{
enable-exceptions=1
lib
module_path="../../source"
}
subproject angelscript_lib
defines
{
}
if {{ defined I3D_ARCH_ARM }}
{
files
{
(../../source)
as_callfunc_arm_gcc.S
}
option buildenv=scons
}
else
{
files
{
(../../source)
#as_callfunc_x64_msvc_asm.asm
as_callfunc_arm_msvc.asm
}
}
files
{
(../../source)
as_array.h
as_atomic.cpp
as_atomic.h
as_builder.cpp
as_builder.h
as_bytecode.cpp
as_bytecode.h
as_callfunc.cpp
as_callfunc.h
as_callfunc_arm.cpp
as_callfunc_mips.cpp
as_callfunc_ppc.cpp
as_callfunc_ppc_64.cpp
as_callfunc_sh4.cpp
as_callfunc_x64_gcc.cpp
as_callfunc_x64_mingw.cpp
as_callfunc_x64_msvc.cpp
as_callfunc_x86.cpp
as_callfunc_xenon.cpp
as_compiler.cpp
as_compiler.h
as_config.h
as_configgroup.cpp
as_configgroup.h
as_context.cpp
as_context.h
as_criticalsection.h
as_datatype.cpp
as_datatype.h
as_debug.h
as_gc.cpp
as_gc.h
as_generic.cpp
as_generic.h
as_globalproperty.cpp
as_map.h
as_memory.cpp
as_memory.h
as_module.cpp
as_module.h
as_objecttype.cpp
as_objecttype.h
as_outputbuffer.cpp
as_outputbuffer.h
as_parser.cpp
as_parser.h
as_property.h
as_restore.cpp
as_restore.h
as_scriptcode.cpp
as_scriptcode.h
as_scriptengine.cpp
as_scriptengine.h
as_scriptfunction.cpp
as_scriptfunction.h
as_scriptnode.cpp
as_scriptnode.h
as_scriptobject.cpp
as_scriptobject.h
as_string.cpp
as_string.h
as_string_util.cpp
as_string_util.h
as_texts.h
as_thread.cpp
as_thread.h
as_tokendef.h
as_tokenizer.cpp
as_tokenizer.h
as_typeinfo.cpp
as_typeinfo.h
as_variablescope.cpp
as_variablescope.h
}

View File

@@ -0,0 +1,24 @@
#!/usr/bin/env mkb
display_name "AngelScript_Lib"
includepath
{
../../include
../../sdk/add_on
}
defines
{
}
library
{
".,angelscript_lib"
}
files
{
(../../include)
angelscript.h
}

View File

@@ -0,0 +1,28 @@
import argparse
import os
import re
HEADER = os.path.join(os.path.dirname(os.path.abspath(__file__)),
"..", "..", "include", "angelscript.h")
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--num", action="store_true", help="Print numeric version")
args = parser.parse_args()
if args.num:
regex = re.compile(r'^#define ANGELSCRIPT_VERSION\s+(\d+)')
else:
regex = re.compile(r'^#define ANGELSCRIPT_VERSION_STRING\s+"(\d+\.\d+\.\d+.*)"')
with open(HEADER, "r") as fobj:
for l in fobj:
match = re.match(regex, l)
if match is not None:
print(match.group(1))
return
assert False, "Can't find version"
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,68 @@
project('angelscript', 'cpp',
version : run_command(find_program('python3'), 'detect_ver.py').stdout().strip(),
meson_version : '>=0.28.0',
license : 'zlib')
threads = dependency('threads')
angel_srcs = [
'../../source/as_atomic.cpp',
'../../source/as_builder.cpp',
'../../source/as_bytecode.cpp',
'../../source/as_callfunc.cpp',
'../../source/as_callfunc_mips.cpp',
'../../source/as_callfunc_ppc.cpp',
'../../source/as_callfunc_ppc_64.cpp',
'../../source/as_callfunc_sh4.cpp',
'../../source/as_callfunc_x86.cpp',
'../../source/as_callfunc_x64_gcc.cpp',
'../../source/as_callfunc_x64_mingw.cpp',
'../../source/as_compiler.cpp',
'../../source/as_context.cpp',
'../../source/as_configgroup.cpp',
'../../source/as_datatype.cpp',
'../../source/as_generic.cpp',
'../../source/as_gc.cpp',
'../../source/as_globalproperty.cpp',
'../../source/as_memory.cpp',
'../../source/as_module.cpp',
'../../source/as_objecttype.cpp',
'../../source/as_outputbuffer.cpp',
'../../source/as_parser.cpp',
'../../source/as_restore.cpp',
'../../source/as_scriptcode.cpp',
'../../source/as_scriptengine.cpp',
'../../source/as_scriptfunction.cpp',
'../../source/as_scriptnode.cpp',
'../../source/as_scriptobject.cpp',
'../../source/as_string.cpp',
'../../source/as_string_util.cpp',
'../../source/as_thread.cpp',
'../../source/as_tokenizer.cpp',
'../../source/as_typeinfo.cpp',
'../../source/as_variablescope.cpp',
]
if host_machine.cpu_family() == 'arm'
add_languages('c')
angel_srcs += [
'../../source/as_callfunc_arm.cpp',
'../../source/as_callfunc_arm_gcc.S',
]
endif
angelscript_version_num = run_command(find_program('python3'), 'detect_ver.py', '--num').stdout().strip()
angelscript_lib = library(
'angelscript',
sources : angel_srcs,
dependencies : threads,
version : angelscript_version_num,
install : true,
)
angelscript_inc = include_directories('../../include')
angelscript_dep = declare_dependency(
link_with : angelscript_lib,
include_directories : angelscript_inc,
version : meson.project_version(),
)
install_headers('../../include/angelscript.h')

View File

@@ -0,0 +1,83 @@
# Angelscript MingW makefile
# Type 'make' then 'make install' to complete the installation of the library
CXX ?= g++
AR ?= ar
# Debug flags: -ggdb -DAS_DEBUG
# Release flags: -O2
# to exclude the script compiler: -DAS_NO_COMPILER
# to use only generic calling convention: -DAS_MAX_PORTABILITY
CXXFLAGS ?= -O2
SRCDIR = ../../source
OBJDIR = obj
SRCNAMES = \
as_atomic.cpp \
as_builder.cpp \
as_bytecode.cpp \
as_callfunc.cpp \
as_callfunc_mips.cpp \
as_callfunc_ppc_64.cpp \
as_callfunc_ppc.cpp \
as_callfunc_sh4.cpp \
as_callfunc_x86.cpp \
as_callfunc_x64_mingw.cpp \
as_compiler.cpp \
as_configgroup.cpp \
as_context.cpp \
as_datatype.cpp \
as_generic.cpp \
as_gc.cpp \
as_globalproperty.cpp \
as_memory.cpp \
as_module.cpp \
as_objecttype.cpp \
as_outputbuffer.cpp \
as_parser.cpp \
as_restore.cpp \
as_scriptcode.cpp \
as_scriptengine.cpp \
as_scriptfunction.cpp \
as_scriptnode.cpp \
as_scriptobject.cpp \
as_string.cpp \
as_string_util.cpp \
as_thread.cpp \
as_tokenizer.cpp \
as_typeinfo.cpp \
as_variablescope.cpp \
OBJ = $(addprefix $(OBJDIR)/, $(notdir $(SRCNAMES:.cpp=.o)))
BIN = ../../lib/libangelscript.a
OBJ_D = $(subst /,\,$(OBJ))
BIN_D = $(subst /,\,$(BIN))
DELETER = del /f
COPIER = copy /y
INCLUDEFILES_D = ..\..\include\angelscript.h
UNINSTALLFILES_D = $(MINGDIR)\lib\libangelscript.a $(MINGDIR)\include\angelscript.h
all: $(BIN)
$(BIN): $(OBJ)
$(AR) rcs $(BIN) $(OBJ)
@echo -------------------------------------------------------------------
@echo Done. Now type 'make install' to install the library on your MinGW.
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
$(CXX) $(CXXFLAGS) -o $@ -c $<
clean:
$(DELETER) $(OBJ_D) $(BIN_D)
install: $(BIN)
$(COPIER) $(BIN_D) $(MINGDIR)\lib
$(COPIER) $(INCLUDEFILES_D) $(MINGDIR)\include
@echo -------------------------------------------------------------------
@echo Angelscript library installed. Enjoy!
uninstall:
$(DELETER) $(UNINSTALLFILES_D)
@echo -------------------------------------------------------------------
@echo Angelscript library uninstalled.
.PHONY: all clean install uninstall

View File

@@ -0,0 +1,2 @@
This file is here just in case your unarchiver does not extract empty directories.
Feel free to remove it.

View File

@@ -0,0 +1,9 @@
If you haven't done that already set up an environment variable named MINGDIR
pointing the the directory where your MinGW is, e.g. "C:\MINGW"
To compile the library, just type in the command line:
make
make install
Sent in by Jakub "krajzega" Wasilewski

View File

@@ -0,0 +1,26 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 2012 for Windows Desktop
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "angelscript", "angelscript.vcxproj", "{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Debug|Win32.ActiveCfg = Debug|Win32
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Debug|Win32.Build.0 = Debug|Win32
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Debug|x64.ActiveCfg = Debug|x64
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Debug|x64.Build.0 = Debug|x64
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Release|Win32.ActiveCfg = Release|Win32
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Release|Win32.Build.0 = Release|Win32
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Release|x64.ActiveCfg = Release|x64
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,438 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="clang_debug|ARM">
<Configuration>clang_debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="clang_debug|Win32">
<Configuration>clang_debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="clang_debug|x64">
<Configuration>clang_debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}</ProjectGuid>
<RootNamespace>angelscript</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
<PlatformToolset>v140_clang_3_7</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
<PlatformToolset>v140_clang_3_7</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
<PlatformToolset>v140_Clang_3_7</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\lib\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'">..\..\lib\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\lib\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">..\..\lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'">$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../lib\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">../../lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)64d</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">$(ProjectName)64d</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectName)d</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'">$(ProjectName)d</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">$(ProjectName)d_arm</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">$(ProjectName)d_arm</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectName)64</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<TargetName>$(ProjectName)_arm</TargetName>
<OutDir>..\..\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<OutDir>..\..\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">
<OutDir>..\..\lib\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<SmallerTypeCheck>false</SmallerTypeCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<FloatingPointModel>Fast</FloatingPointModel>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)$(ProjectName)d.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>AS_MAX_PORTABILITY;ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Enabled</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<SmallerTypeCheck>false</SmallerTypeCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>EnableAllWarnings</WarningLevel>
<DebugInformationFormat>FullDebug</DebugInformationFormat>
<FloatingPointModel>Fast</FloatingPointModel>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)$(ProjectName)d.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<Optimization>Disabled</Optimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<SmallerTypeCheck>false</SmallerTypeCheck>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<FloatingPointModel>Fast</FloatingPointModel>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">
<ClCompile>
<Optimization>Disabled</Optimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<SmallerTypeCheck>false</SmallerTypeCheck>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<FloatingPointModel>Fast</FloatingPointModel>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<SmallerTypeCheck>false</SmallerTypeCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)$(ProjectName)64d.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Enabled</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<SmallerTypeCheck>false</SmallerTypeCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>EnableAllWarnings</WarningLevel>
<DebugInformationFormat>FullDebug</DebugInformationFormat>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)$(ProjectName)64d.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level3</WarningLevel>
<Optimization>Full</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<ClCompile>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<BufferSecurityCheck>false</BufferSecurityCheck>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level3</WarningLevel>
<Optimization>Full</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<EnableEnhancedInstructionSet>
</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level4</WarningLevel>
<Optimization>Full</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<EnableEnhancedInstructionSet>
</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
<FloatingPointExceptions>
</FloatingPointExceptions>
</ClCompile>
<Lib>
<OutputFile>..\..\lib\angelscript64.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\source\as_atomic.cpp" />
<ClCompile Include="..\..\source\as_builder.cpp" />
<ClCompile Include="..\..\source\as_bytecode.cpp" />
<ClCompile Include="..\..\source\as_callfunc.cpp" />
<ClCompile Include="..\..\source\as_callfunc_arm.cpp" />
<ClCompile Include="..\..\source\as_callfunc_mips.cpp" />
<ClCompile Include="..\..\source\as_callfunc_ppc.cpp" />
<ClCompile Include="..\..\source\as_callfunc_ppc_64.cpp" />
<ClCompile Include="..\..\source\as_callfunc_sh4.cpp" />
<ClCompile Include="..\..\source\as_callfunc_x64_gcc.cpp" />
<ClCompile Include="..\..\source\as_callfunc_x64_mingw.cpp" />
<ClCompile Include="..\..\source\as_callfunc_x64_msvc.cpp" />
<ClCompile Include="..\..\source\as_callfunc_x86.cpp" />
<ClCompile Include="..\..\source\as_callfunc_xenon.cpp" />
<ClCompile Include="..\..\source\as_compiler.cpp" />
<ClCompile Include="..\..\source\as_configgroup.cpp" />
<ClCompile Include="..\..\source\as_context.cpp" />
<ClCompile Include="..\..\source\as_datatype.cpp" />
<ClCompile Include="..\..\source\as_gc.cpp" />
<ClCompile Include="..\..\source\as_generic.cpp" />
<ClCompile Include="..\..\source\as_globalproperty.cpp" />
<ClCompile Include="..\..\source\as_memory.cpp" />
<ClCompile Include="..\..\source\as_module.cpp" />
<ClCompile Include="..\..\source\as_objecttype.cpp" />
<ClCompile Include="..\..\source\as_outputbuffer.cpp" />
<ClCompile Include="..\..\source\as_parser.cpp" />
<ClCompile Include="..\..\source\as_restore.cpp" />
<ClCompile Include="..\..\source\as_scriptcode.cpp" />
<ClCompile Include="..\..\source\as_scriptengine.cpp" />
<ClCompile Include="..\..\source\as_scriptfunction.cpp" />
<ClCompile Include="..\..\source\as_scriptnode.cpp" />
<ClCompile Include="..\..\source\as_scriptobject.cpp" />
<ClCompile Include="..\..\source\as_string.cpp" />
<ClCompile Include="..\..\source\as_string_util.cpp" />
<ClCompile Include="..\..\source\as_thread.cpp" />
<ClCompile Include="..\..\source\as_tokenizer.cpp" />
<ClCompile Include="..\..\source\as_typeinfo.cpp" />
<ClCompile Include="..\..\source\as_variablescope.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\angelscript.h" />
<ClInclude Include="..\..\source\as_array.h" />
<ClInclude Include="..\..\source\as_atomic.h" />
<ClInclude Include="..\..\source\as_builder.h" />
<ClInclude Include="..\..\source\as_bytecode.h" />
<ClInclude Include="..\..\source\as_callfunc.h" />
<ClInclude Include="..\..\source\as_compiler.h" />
<ClInclude Include="..\..\source\as_config.h" />
<ClInclude Include="..\..\source\as_configgroup.h" />
<ClInclude Include="..\..\source\as_context.h" />
<ClInclude Include="..\..\source\as_criticalsection.h" />
<ClInclude Include="..\..\source\as_datatype.h" />
<ClInclude Include="..\..\source\as_debug.h" />
<ClInclude Include="..\..\source\as_gc.h" />
<ClInclude Include="..\..\source\as_generic.h" />
<ClInclude Include="..\..\source\as_map.h" />
<ClInclude Include="..\..\source\as_memory.h" />
<ClInclude Include="..\..\source\as_module.h" />
<ClInclude Include="..\..\source\as_objecttype.h" />
<ClInclude Include="..\..\source\as_outputbuffer.h" />
<ClInclude Include="..\..\source\as_parser.h" />
<ClInclude Include="..\..\source\as_property.h" />
<ClInclude Include="..\..\source\as_restore.h" />
<ClInclude Include="..\..\source\as_scriptcode.h" />
<ClInclude Include="..\..\source\as_scriptengine.h" />
<ClInclude Include="..\..\source\as_scriptfunction.h" />
<ClInclude Include="..\..\source\as_scriptnode.h" />
<ClInclude Include="..\..\source\as_scriptobject.h" />
<ClInclude Include="..\..\source\as_string.h" />
<ClInclude Include="..\..\source\as_string_util.h" />
<ClInclude Include="..\..\source\as_symboltable.h" />
<ClInclude Include="..\..\source\as_texts.h" />
<ClInclude Include="..\..\source\as_thread.h" />
<ClInclude Include="..\..\source\as_tokendef.h" />
<ClInclude Include="..\..\source\as_tokenizer.h" />
<ClInclude Include="..\..\source\as_typeinfo.h" />
<ClInclude Include="..\..\source\as_variablescope.h" />
<ClInclude Include="..\..\source\as_namespace.h" />
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\..\source\as_callfunc_x64_msvc_asm.asm">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ml64.exe /c /nologo /Fo"$(Configuration)\as_callfunc_x64_msvc_asm.obj" /W3 /Zi /Ta "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\as_callfunc_x64_msvc_asm.obj;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ml64.exe /c /nologo /Fo"$(Configuration)\as_callfunc_x64_msvc_asm.obj" /W3 /Zi /Ta "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">ml64.exe /c /nologo /Fo"$(Configuration)\as_callfunc_x64_msvc_asm.obj" /W3 /Zi /Ta "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\as_callfunc_x64_msvc_asm.obj;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">$(Configuration)\as_callfunc_x64_msvc_asm.obj;%(Outputs)</Outputs>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<None Include="..\..\source\as_callfunc_arm_gcc.S" />
<CustomBuild Include="..\..\source\as_callfunc_arm_msvc.asm">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">armasm.exe -g -32 -o "$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj" "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">armasm.exe -g -32 -o "$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj" "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">armasm.exe -32 -o "$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj" "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj;%(Outputs)</Outputs>
</CustomBuild>
<None Include="..\..\source\as_callfunc_arm_vita.S" />
<None Include="..\..\source\as_callfunc_arm_xcode.S" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,268 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\source\as_atomic.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_builder.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_bytecode.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_mips.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_sh4.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_x86.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_compiler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_configgroup.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_context.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_datatype.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_gc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_generic.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_globalproperty.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_memory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_module.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_objecttype.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_outputbuffer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_parser.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_restore.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_scriptcode.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_scriptengine.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_scriptfunction.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_scriptnode.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_scriptobject.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_string.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_string_util.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_thread.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_tokenizer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_typeinfo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_variablescope.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_x64_msvc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_arm.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_ppc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_ppc_64.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_x64_gcc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_x64_mingw.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_xenon.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\angelscript.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_array.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_builder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_bytecode.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_callfunc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_compiler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_config.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_configgroup.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_context.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_datatype.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_debug.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_generic.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_map.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_module.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_objecttype.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_outputbuffer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_parser.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_property.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_restore.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_scriptcode.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_scriptengine.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_scriptfunction.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_scriptnode.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_scriptobject.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_string.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_string_util.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_texts.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_thread.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_tokendef.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_tokenizer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_typeinfo.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_variablescope.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_gc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_criticalsection.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_symboltable.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_atomic.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_memory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_namespace.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\..\source\as_callfunc_x64_msvc_asm.asm">
<Filter>Source Files</Filter>
</CustomBuild>
<CustomBuild Include="..\..\source\as_callfunc_arm_msvc.asm">
<Filter>Source Files</Filter>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<None Include="..\..\source\as_callfunc_arm_gcc.S">
<Filter>Source Files</Filter>
</None>
<None Include="..\..\source\as_callfunc_arm_xcode.S">
<Filter>Source Files</Filter>
</None>
<None Include="..\..\source\as_callfunc_arm_vita.S">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,26 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 2012 for Windows Desktop
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "angelscript", "angelscript.vcxproj", "{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Debug|Win32.ActiveCfg = Debug|Win32
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Debug|Win32.Build.0 = Debug|Win32
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Debug|x64.ActiveCfg = Debug|x64
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Debug|x64.Build.0 = Debug|x64
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Release|Win32.ActiveCfg = Release|Win32
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Release|Win32.Build.0 = Release|Win32
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Release|x64.ActiveCfg = Release|x64
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,439 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="clang_debug|ARM">
<Configuration>clang_debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="clang_debug|Win32">
<Configuration>clang_debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="clang_debug|x64">
<Configuration>clang_debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}</ProjectGuid>
<RootNamespace>angelscript</RootNamespace>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
<PlatformToolset>v140_clang_3_7</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
<PlatformToolset>v140_clang_3_7</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
<PlatformToolset>v140_Clang_3_7</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\lib\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'">..\..\lib\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\lib\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">..\..\lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'">$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../lib\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">../../lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)64d</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">$(ProjectName)64d</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectName)d</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'">$(ProjectName)d</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">$(ProjectName)d_arm</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">$(ProjectName)d_arm</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectName)64</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<TargetName>$(ProjectName)_arm</TargetName>
<OutDir>..\..\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<OutDir>..\..\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">
<OutDir>..\..\lib\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<SmallerTypeCheck>false</SmallerTypeCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<FloatingPointModel>Fast</FloatingPointModel>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)$(ProjectName)d.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>AS_MAX_PORTABILITY;ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Enabled</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<SmallerTypeCheck>false</SmallerTypeCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>EnableAllWarnings</WarningLevel>
<DebugInformationFormat>FullDebug</DebugInformationFormat>
<FloatingPointModel>Fast</FloatingPointModel>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)$(ProjectName)d.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<Optimization>Disabled</Optimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<SmallerTypeCheck>false</SmallerTypeCheck>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<FloatingPointModel>Fast</FloatingPointModel>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">
<ClCompile>
<Optimization>Disabled</Optimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<SmallerTypeCheck>false</SmallerTypeCheck>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<FloatingPointModel>Fast</FloatingPointModel>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<SmallerTypeCheck>false</SmallerTypeCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)$(ProjectName)64d.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Enabled</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<SmallerTypeCheck>false</SmallerTypeCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>EnableAllWarnings</WarningLevel>
<DebugInformationFormat>FullDebug</DebugInformationFormat>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)$(ProjectName)64d.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level3</WarningLevel>
<Optimization>Full</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<ClCompile>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<BufferSecurityCheck>false</BufferSecurityCheck>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level3</WarningLevel>
<Optimization>Full</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<EnableEnhancedInstructionSet>
</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level4</WarningLevel>
<Optimization>Full</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<EnableEnhancedInstructionSet>
</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
<FloatingPointExceptions>
</FloatingPointExceptions>
</ClCompile>
<Lib>
<OutputFile>..\..\lib\angelscript64.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\source\as_atomic.cpp" />
<ClCompile Include="..\..\source\as_builder.cpp" />
<ClCompile Include="..\..\source\as_bytecode.cpp" />
<ClCompile Include="..\..\source\as_callfunc.cpp" />
<ClCompile Include="..\..\source\as_callfunc_arm.cpp" />
<ClCompile Include="..\..\source\as_callfunc_mips.cpp" />
<ClCompile Include="..\..\source\as_callfunc_ppc.cpp" />
<ClCompile Include="..\..\source\as_callfunc_ppc_64.cpp" />
<ClCompile Include="..\..\source\as_callfunc_sh4.cpp" />
<ClCompile Include="..\..\source\as_callfunc_x64_gcc.cpp" />
<ClCompile Include="..\..\source\as_callfunc_x64_mingw.cpp" />
<ClCompile Include="..\..\source\as_callfunc_x64_msvc.cpp" />
<ClCompile Include="..\..\source\as_callfunc_x86.cpp" />
<ClCompile Include="..\..\source\as_callfunc_xenon.cpp" />
<ClCompile Include="..\..\source\as_compiler.cpp" />
<ClCompile Include="..\..\source\as_configgroup.cpp" />
<ClCompile Include="..\..\source\as_context.cpp" />
<ClCompile Include="..\..\source\as_datatype.cpp" />
<ClCompile Include="..\..\source\as_gc.cpp" />
<ClCompile Include="..\..\source\as_generic.cpp" />
<ClCompile Include="..\..\source\as_globalproperty.cpp" />
<ClCompile Include="..\..\source\as_memory.cpp" />
<ClCompile Include="..\..\source\as_module.cpp" />
<ClCompile Include="..\..\source\as_objecttype.cpp" />
<ClCompile Include="..\..\source\as_outputbuffer.cpp" />
<ClCompile Include="..\..\source\as_parser.cpp" />
<ClCompile Include="..\..\source\as_restore.cpp" />
<ClCompile Include="..\..\source\as_scriptcode.cpp" />
<ClCompile Include="..\..\source\as_scriptengine.cpp" />
<ClCompile Include="..\..\source\as_scriptfunction.cpp" />
<ClCompile Include="..\..\source\as_scriptnode.cpp" />
<ClCompile Include="..\..\source\as_scriptobject.cpp" />
<ClCompile Include="..\..\source\as_string.cpp" />
<ClCompile Include="..\..\source\as_string_util.cpp" />
<ClCompile Include="..\..\source\as_thread.cpp" />
<ClCompile Include="..\..\source\as_tokenizer.cpp" />
<ClCompile Include="..\..\source\as_typeinfo.cpp" />
<ClCompile Include="..\..\source\as_variablescope.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\angelscript.h" />
<ClInclude Include="..\..\source\as_array.h" />
<ClInclude Include="..\..\source\as_atomic.h" />
<ClInclude Include="..\..\source\as_builder.h" />
<ClInclude Include="..\..\source\as_bytecode.h" />
<ClInclude Include="..\..\source\as_callfunc.h" />
<ClInclude Include="..\..\source\as_compiler.h" />
<ClInclude Include="..\..\source\as_config.h" />
<ClInclude Include="..\..\source\as_configgroup.h" />
<ClInclude Include="..\..\source\as_context.h" />
<ClInclude Include="..\..\source\as_criticalsection.h" />
<ClInclude Include="..\..\source\as_datatype.h" />
<ClInclude Include="..\..\source\as_debug.h" />
<ClInclude Include="..\..\source\as_gc.h" />
<ClInclude Include="..\..\source\as_generic.h" />
<ClInclude Include="..\..\source\as_map.h" />
<ClInclude Include="..\..\source\as_memory.h" />
<ClInclude Include="..\..\source\as_module.h" />
<ClInclude Include="..\..\source\as_objecttype.h" />
<ClInclude Include="..\..\source\as_outputbuffer.h" />
<ClInclude Include="..\..\source\as_parser.h" />
<ClInclude Include="..\..\source\as_property.h" />
<ClInclude Include="..\..\source\as_restore.h" />
<ClInclude Include="..\..\source\as_scriptcode.h" />
<ClInclude Include="..\..\source\as_scriptengine.h" />
<ClInclude Include="..\..\source\as_scriptfunction.h" />
<ClInclude Include="..\..\source\as_scriptnode.h" />
<ClInclude Include="..\..\source\as_scriptobject.h" />
<ClInclude Include="..\..\source\as_string.h" />
<ClInclude Include="..\..\source\as_string_util.h" />
<ClInclude Include="..\..\source\as_symboltable.h" />
<ClInclude Include="..\..\source\as_texts.h" />
<ClInclude Include="..\..\source\as_thread.h" />
<ClInclude Include="..\..\source\as_tokendef.h" />
<ClInclude Include="..\..\source\as_tokenizer.h" />
<ClInclude Include="..\..\source\as_typeinfo.h" />
<ClInclude Include="..\..\source\as_variablescope.h" />
<ClInclude Include="..\..\source\as_namespace.h" />
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\..\source\as_callfunc_x64_msvc_asm.asm">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ml64.exe /c /nologo /Fo"$(Configuration)\as_callfunc_x64_msvc_asm.obj" /W3 /Zi /Ta "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\as_callfunc_x64_msvc_asm.obj;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ml64.exe /c /nologo /Fo"$(Configuration)\as_callfunc_x64_msvc_asm.obj" /W3 /Zi /Ta "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">ml64.exe /c /nologo /Fo"$(Configuration)\as_callfunc_x64_msvc_asm.obj" /W3 /Zi /Ta "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\as_callfunc_x64_msvc_asm.obj;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">$(Configuration)\as_callfunc_x64_msvc_asm.obj;%(Outputs)</Outputs>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<None Include="..\..\source\as_callfunc_arm_gcc.S" />
<CustomBuild Include="..\..\source\as_callfunc_arm_msvc.asm">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">armasm.exe -g -32 -o "$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj" "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">armasm.exe -g -32 -o "$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj" "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">armasm.exe -32 -o "$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj" "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj;%(Outputs)</Outputs>
</CustomBuild>
<None Include="..\..\source\as_callfunc_arm_vita.S" />
<None Include="..\..\source\as_callfunc_arm_xcode.S" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,268 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\source\as_atomic.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_builder.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_bytecode.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_mips.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_sh4.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_x86.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_compiler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_configgroup.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_context.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_datatype.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_gc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_generic.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_globalproperty.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_memory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_module.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_objecttype.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_outputbuffer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_parser.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_restore.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_scriptcode.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_scriptengine.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_scriptfunction.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_scriptnode.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_scriptobject.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_string.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_string_util.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_thread.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_tokenizer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_typeinfo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_variablescope.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_x64_msvc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_arm.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_ppc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_ppc_64.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_x64_gcc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_x64_mingw.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_xenon.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\angelscript.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_array.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_builder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_bytecode.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_callfunc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_compiler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_config.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_configgroup.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_context.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_datatype.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_debug.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_generic.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_map.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_module.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_objecttype.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_outputbuffer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_parser.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_property.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_restore.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_scriptcode.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_scriptengine.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_scriptfunction.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_scriptnode.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_scriptobject.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_string.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_string_util.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_texts.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_thread.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_tokendef.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_tokenizer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_typeinfo.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_variablescope.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_gc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_criticalsection.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_symboltable.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_atomic.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_memory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_namespace.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\..\source\as_callfunc_x64_msvc_asm.asm">
<Filter>Source Files</Filter>
</CustomBuild>
<CustomBuild Include="..\..\source\as_callfunc_arm_msvc.asm">
<Filter>Source Files</Filter>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<None Include="..\..\source\as_callfunc_arm_gcc.S">
<Filter>Source Files</Filter>
</None>
<None Include="..\..\source\as_callfunc_arm_xcode.S">
<Filter>Source Files</Filter>
</None>
<None Include="..\..\source\as_callfunc_arm_vita.S">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

View File

@@ -0,0 +1,26 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 2012 for Windows Desktop
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "angelscript", "angelscript.vcxproj", "{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Debug|Win32.ActiveCfg = Debug|Win32
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Debug|Win32.Build.0 = Debug|Win32
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Debug|x64.ActiveCfg = Debug|x64
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Debug|x64.Build.0 = Debug|x64
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Release|Win32.ActiveCfg = Release|Win32
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Release|Win32.Build.0 = Release|Win32
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Release|x64.ActiveCfg = Release|x64
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,554 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="clang_debug|ARM">
<Configuration>clang_debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="clang_debug|ARM64">
<Configuration>clang_debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="clang_debug|Win32">
<Configuration>clang_debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="clang_debug|x64">
<Configuration>clang_debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}</ProjectGuid>
<RootNamespace>angelscript</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
<PlatformToolset>v140_clang_3_7</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
<PlatformToolset>v140_clang_3_7</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
<PlatformToolset>v140_clang_3_7</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
<PlatformToolset>v140_Clang_3_7</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\lib\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'">..\..\lib\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\lib\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">..\..\lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'">$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../lib\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">../../lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)64d</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">$(ProjectName)64d</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectName)d</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'">$(ProjectName)d</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">$(ProjectName)d_arm</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(ProjectName)d_arm64</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">$(ProjectName)d_arm</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM64'">$(ProjectName)d_arm64</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectName)64</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<TargetName>$(ProjectName)_arm</TargetName>
<OutDir>..\..\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<TargetName>$(ProjectName)_arm64</TargetName>
<OutDir>..\..\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<OutDir>..\..\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">
<OutDir>..\..\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM64'">
<OutDir>..\..\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<OutDir>..\..\lib\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<SmallerTypeCheck>false</SmallerTypeCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<FloatingPointModel>Fast</FloatingPointModel>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)$(ProjectName)d.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>AS_MAX_PORTABILITY;ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Enabled</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<SmallerTypeCheck>false</SmallerTypeCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>EnableAllWarnings</WarningLevel>
<DebugInformationFormat>FullDebug</DebugInformationFormat>
<FloatingPointModel>Fast</FloatingPointModel>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)$(ProjectName)d.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<Optimization>Disabled</Optimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<SmallerTypeCheck>false</SmallerTypeCheck>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<FloatingPointModel>Fast</FloatingPointModel>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<SmallerTypeCheck>false</SmallerTypeCheck>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<FloatingPointModel>Fast</FloatingPointModel>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">
<ClCompile>
<Optimization>Disabled</Optimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<SmallerTypeCheck>false</SmallerTypeCheck>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<FloatingPointModel>Fast</FloatingPointModel>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<SmallerTypeCheck>false</SmallerTypeCheck>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<FloatingPointModel>Fast</FloatingPointModel>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<SmallerTypeCheck>false</SmallerTypeCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)$(ProjectName)64d.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Enabled</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<SmallerTypeCheck>false</SmallerTypeCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>EnableAllWarnings</WarningLevel>
<DebugInformationFormat>FullDebug</DebugInformationFormat>
<FloatingPointModel>Fast</FloatingPointModel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)$(ProjectName)64d.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level3</WarningLevel>
<Optimization>Full</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<ClCompile>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<BufferSecurityCheck>false</BufferSecurityCheck>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level3</WarningLevel>
<Optimization>Full</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<EnableEnhancedInstructionSet>
</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<ClCompile>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<BufferSecurityCheck>false</BufferSecurityCheck>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level3</WarningLevel>
<Optimization>Full</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<EnableEnhancedInstructionSet>
</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level4</WarningLevel>
<Optimization>Full</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<EnableEnhancedInstructionSet>
</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
<FloatingPointExceptions>
</FloatingPointExceptions>
</ClCompile>
<Lib>
<OutputFile>..\..\lib\angelscript64.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\source\as_atomic.cpp" />
<ClCompile Include="..\..\source\as_builder.cpp" />
<ClCompile Include="..\..\source\as_bytecode.cpp" />
<ClCompile Include="..\..\source\as_callfunc.cpp" />
<ClCompile Include="..\..\source\as_callfunc_arm.cpp" />
<ClCompile Include="..\..\source\as_callfunc_arm64.cpp" />
<ClCompile Include="..\..\source\as_callfunc_mips.cpp" />
<ClCompile Include="..\..\source\as_callfunc_ppc.cpp" />
<ClCompile Include="..\..\source\as_callfunc_ppc_64.cpp" />
<ClCompile Include="..\..\source\as_callfunc_sh4.cpp" />
<ClCompile Include="..\..\source\as_callfunc_x64_gcc.cpp" />
<ClCompile Include="..\..\source\as_callfunc_x64_mingw.cpp" />
<ClCompile Include="..\..\source\as_callfunc_x64_msvc.cpp" />
<ClCompile Include="..\..\source\as_callfunc_x86.cpp" />
<ClCompile Include="..\..\source\as_callfunc_xenon.cpp" />
<ClCompile Include="..\..\source\as_compiler.cpp" />
<ClCompile Include="..\..\source\as_configgroup.cpp" />
<ClCompile Include="..\..\source\as_context.cpp" />
<ClCompile Include="..\..\source\as_datatype.cpp" />
<ClCompile Include="..\..\source\as_gc.cpp" />
<ClCompile Include="..\..\source\as_generic.cpp" />
<ClCompile Include="..\..\source\as_globalproperty.cpp" />
<ClCompile Include="..\..\source\as_memory.cpp" />
<ClCompile Include="..\..\source\as_module.cpp" />
<ClCompile Include="..\..\source\as_objecttype.cpp" />
<ClCompile Include="..\..\source\as_outputbuffer.cpp" />
<ClCompile Include="..\..\source\as_parser.cpp" />
<ClCompile Include="..\..\source\as_restore.cpp" />
<ClCompile Include="..\..\source\as_scriptcode.cpp" />
<ClCompile Include="..\..\source\as_scriptengine.cpp" />
<ClCompile Include="..\..\source\as_scriptfunction.cpp" />
<ClCompile Include="..\..\source\as_scriptnode.cpp" />
<ClCompile Include="..\..\source\as_scriptobject.cpp" />
<ClCompile Include="..\..\source\as_string.cpp" />
<ClCompile Include="..\..\source\as_string_util.cpp" />
<ClCompile Include="..\..\source\as_thread.cpp" />
<ClCompile Include="..\..\source\as_tokenizer.cpp" />
<ClCompile Include="..\..\source\as_typeinfo.cpp" />
<ClCompile Include="..\..\source\as_variablescope.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\angelscript.h" />
<ClInclude Include="..\..\source\as_array.h" />
<ClInclude Include="..\..\source\as_atomic.h" />
<ClInclude Include="..\..\source\as_builder.h" />
<ClInclude Include="..\..\source\as_bytecode.h" />
<ClInclude Include="..\..\source\as_callfunc.h" />
<ClInclude Include="..\..\source\as_compiler.h" />
<ClInclude Include="..\..\source\as_config.h" />
<ClInclude Include="..\..\source\as_configgroup.h" />
<ClInclude Include="..\..\source\as_context.h" />
<ClInclude Include="..\..\source\as_criticalsection.h" />
<ClInclude Include="..\..\source\as_datatype.h" />
<ClInclude Include="..\..\source\as_debug.h" />
<ClInclude Include="..\..\source\as_gc.h" />
<ClInclude Include="..\..\source\as_generic.h" />
<ClInclude Include="..\..\source\as_map.h" />
<ClInclude Include="..\..\source\as_memory.h" />
<ClInclude Include="..\..\source\as_module.h" />
<ClInclude Include="..\..\source\as_objecttype.h" />
<ClInclude Include="..\..\source\as_outputbuffer.h" />
<ClInclude Include="..\..\source\as_parser.h" />
<ClInclude Include="..\..\source\as_property.h" />
<ClInclude Include="..\..\source\as_restore.h" />
<ClInclude Include="..\..\source\as_scriptcode.h" />
<ClInclude Include="..\..\source\as_scriptengine.h" />
<ClInclude Include="..\..\source\as_scriptfunction.h" />
<ClInclude Include="..\..\source\as_scriptnode.h" />
<ClInclude Include="..\..\source\as_scriptobject.h" />
<ClInclude Include="..\..\source\as_string.h" />
<ClInclude Include="..\..\source\as_string_util.h" />
<ClInclude Include="..\..\source\as_symboltable.h" />
<ClInclude Include="..\..\source\as_texts.h" />
<ClInclude Include="..\..\source\as_thread.h" />
<ClInclude Include="..\..\source\as_tokendef.h" />
<ClInclude Include="..\..\source\as_tokenizer.h" />
<ClInclude Include="..\..\source\as_typeinfo.h" />
<ClInclude Include="..\..\source\as_variablescope.h" />
<ClInclude Include="..\..\source\as_namespace.h" />
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\..\source\as_callfunc_x64_msvc_asm.asm">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ml64.exe /c /nologo /Fo"$(Configuration)\as_callfunc_x64_msvc_asm.obj" /W3 /Zi /Ta "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\as_callfunc_x64_msvc_asm.obj;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ml64.exe /c /nologo /Fo"$(Configuration)\as_callfunc_x64_msvc_asm.obj" /W3 /Zi /Ta "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">ml64.exe /c /nologo /Fo"$(Configuration)\as_callfunc_x64_msvc_asm.obj" /W3 /Zi /Ta "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\as_callfunc_x64_msvc_asm.obj;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">$(Configuration)\as_callfunc_x64_msvc_asm.obj;%(Outputs)</Outputs>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\..\source\as_callfunc_arm64_msvc.asm">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM64'">armasm64.exe -g -o "$(Platform)\$(Configuration)\as_callfunc_arm64_msvc.obj" "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">armasm64.exe -g -o "$(Platform)\$(Configuration)\as_callfunc_arm64_msvc.obj" "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">armasm64.exe -o "$(Platform)\$(Configuration)\as_callfunc_arm64_msvc.obj" "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(Platform)\$(Configuration)\as_callfunc_arm64_msvc.obj;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM64'">$(Platform)\$(Configuration)\as_callfunc_arm64_msvc.obj;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(Platform)\$(Configuration)\as_callfunc_arm64_msvc.obj;%(Outputs)</Outputs>
</CustomBuild>
<None Include="..\..\source\as_callfunc_arm64_gcc.S" />
<None Include="..\..\source\as_callfunc_arm_gcc.S" />
<CustomBuild Include="..\..\source\as_callfunc_arm_msvc.asm">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">armasm.exe -g -32 -o "$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj" "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">armasm.exe -g -32 -o "$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj" "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">armasm.exe -32 -o "$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj" "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj;%(Outputs)</Outputs>
</CustomBuild>
<None Include="..\..\source\as_callfunc_arm_vita.S" />
<None Include="..\..\source\as_callfunc_arm_xcode.S" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,277 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\source\as_atomic.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_builder.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_bytecode.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_mips.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_sh4.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_x86.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_compiler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_configgroup.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_context.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_datatype.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_gc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_generic.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_globalproperty.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_memory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_module.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_objecttype.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_outputbuffer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_parser.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_restore.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_scriptcode.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_scriptengine.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_scriptfunction.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_scriptnode.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_scriptobject.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_string.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_string_util.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_thread.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_tokenizer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_typeinfo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_variablescope.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_x64_msvc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_arm.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_ppc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_ppc_64.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_x64_gcc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_x64_mingw.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_xenon.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\as_callfunc_arm64.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\angelscript.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_array.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_builder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_bytecode.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_callfunc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_compiler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_config.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_configgroup.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_context.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_datatype.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_debug.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_generic.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_map.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_module.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_objecttype.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_outputbuffer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_parser.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_property.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_restore.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_scriptcode.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_scriptengine.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_scriptfunction.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_scriptnode.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_scriptobject.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_string.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_string_util.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_texts.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_thread.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_tokendef.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_tokenizer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_typeinfo.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_variablescope.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_gc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_criticalsection.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_symboltable.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_atomic.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_memory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\as_namespace.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\..\source\as_callfunc_x64_msvc_asm.asm">
<Filter>Source Files</Filter>
</CustomBuild>
<CustomBuild Include="..\..\source\as_callfunc_arm_msvc.asm">
<Filter>Source Files</Filter>
</CustomBuild>
<CustomBuild Include="..\..\source\as_callfunc_arm64_msvc.asm">
<Filter>Source Files</Filter>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<None Include="..\..\source\as_callfunc_arm_gcc.S">
<Filter>Source Files</Filter>
</None>
<None Include="..\..\source\as_callfunc_arm_xcode.S">
<Filter>Source Files</Filter>
</None>
<None Include="..\..\source\as_callfunc_arm_vita.S">
<Filter>Source Files</Filter>
</None>
<None Include="..\..\source\as_callfunc_arm64_gcc.S">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,136 @@
TEMPLATE = lib
DEPENDPATH += ../../source ../../include
INCLUDEPATH += ../../include
QMAKE_CXXFLAGS += -Wno-strict-aliasing
CONFIG -= debug debug_and_release release app_bundle qt dll
CONFIG += staticlib release
DEFINES += _CRT_SECURE_NO_WARNINGS
DESTDIR = ../../lib
win32: LIBS += -lwinmm
HEADERS += ../../include/angelscript.h \
../../source/as_array.h \
../../source/as_atomic.h \
../../source/as_builder.h \
../../source/as_bytecode.h \
../../source/as_callfunc.h \
../../source/as_compiler.h \
../../source/as_config.h \
../../source/as_configgroup.h \
../../source/as_context.h \
../../source/as_criticalsection.h \
../../source/as_datatype.h \
../../source/as_debug.h \
../../source/as_gc.h \
../../source/as_generic.h \
../../source/as_map.h \
../../source/as_memory.h \
../../source/as_module.h \
../../source/as_objecttype.h \
../../source/as_outputbuffer.h \
../../source/as_parser.h \
../../source/as_property.h \
../../source/as_restore.h \
../../source/as_scriptcode.h \
../../source/as_scriptengine.h \
../../source/as_scriptfunction.h \
../../source/as_scriptnode.h \
../../source/as_scriptobject.h \
../../source/as_string.h \
../../source/as_string_util.h \
../../source/as_symboltable.h \
../../source/as_texts.h \
../../source/as_thread.h \
../../source/as_tokendef.h \
../../source/as_tokenizer.h \
../../source/as_typeinfo.h \
../../source/as_variablescope.h
SOURCES += ../../source/as_atomic.cpp \
../../source/as_builder.cpp \
../../source/as_bytecode.cpp \
../../source/as_callfunc.cpp \
../../source/as_callfunc_mips.cpp \
../../source/as_callfunc_ppc.cpp \
../../source/as_callfunc_ppc_64.cpp \
../../source/as_callfunc_sh4.cpp \
../../source/as_callfunc_x64_gcc.cpp \
../../source/as_callfunc_x64_mingw.cpp \
../../source/as_callfunc_x64_msvc.cpp \
../../source/as_callfunc_x86.cpp \
../../source/as_callfunc_xenon.cpp \
../../source/as_compiler.cpp \
../../source/as_configgroup.cpp \
../../source/as_context.cpp \
../../source/as_datatype.cpp \
../../source/as_gc.cpp \
../../source/as_generic.cpp \
../../source/as_globalproperty.cpp \
../../source/as_memory.cpp \
../../source/as_module.cpp \
../../source/as_objecttype.cpp \
../../source/as_outputbuffer.cpp \
../../source/as_parser.cpp \
../../source/as_restore.cpp \
../../source/as_scriptcode.cpp \
../../source/as_scriptengine.cpp \
../../source/as_scriptfunction.cpp \
../../source/as_scriptnode.cpp \
../../source/as_scriptobject.cpp \
../../source/as_string.cpp \
../../source/as_string_util.cpp \
../../source/as_thread.cpp \
../../source/as_tokenizer.cpp \
../../source/as_typeinfo.cpp \
../../source/as_variablescope.cpp
HEADERS += ../../../add_on/scriptany/scriptany.h \
../../../add_on/scriptarray/scriptarray.h \
../../../add_on/scriptdictionary/scriptdictionary.h \
../../../add_on/scriptmath/scriptmath.h \
../../../add_on/scripthandle/scripthandle.h \
../../../add_on/scriptstdstring/scriptstdstring.h \
../../../add_on/scriptbuilder/scriptbuilder.h
SOURCES += ../../../add_on/scriptany/scriptany.cpp \
../../../add_on/scriptarray/scriptarray.cpp \
../../../add_on/scriptdictionary/scriptdictionary.cpp \
../../../add_on/scriptmath/scriptmath.cpp \
../../../add_on/scripthandle/scripthandle.cpp \
../../../add_on/scriptstdstring/scriptstdstring.cpp \
../../../add_on/scriptstdstring/scriptstdstring_utils.cpp \
../../../add_on/scriptbuilder/scriptbuilder.cpp
OBJECTS_DIR = tmp
MOC_DIR = tmp
UI_DIR = tmp
RCC_DIR = tmp
!win32-g++:win32:contains(QMAKE_HOST.arch, x86_64):{
asm_compiler.commands = ml64 /c
asm_compiler.commands += /Fo ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
asm_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
asm_compiler.input = ASM_SOURCES
asm_compiler.variable_out = OBJECTS
asm_compiler.name = compiling[asm] ${QMAKE_FILE_IN}
silent:asm_compiler.commands = @echo compiling[asm] ${QMAKE_FILE_IN} && $$asm_compiler.commands
QMAKE_EXTRA_COMPILERS += asm_compiler
ASM_SOURCES += \
$$PWD/angelscript/source/as_callfunc_x64_msvc_asm.asm
if(win32-msvc2008|win32-msvc2010):equals(TEMPLATE_PREFIX, "vc") {
SOURCES += \
$$PWD/angelscript/source/as_callfunc_x64_msvc_asm.asm
}
}
# QMAKE_CXXFLAGS_RELEASE += /MP

View File

@@ -0,0 +1,768 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
6E91005C1823FC7000D59009 /* angelscript.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E91005B1823FC7000D59009 /* angelscript.h */; };
6E91005D1823FC7000D59009 /* angelscript.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E91005B1823FC7000D59009 /* angelscript.h */; };
6E91FF911823DA0D00D59009 /* as_array.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BCF51523FF2300EFAB3F /* as_array.h */; };
6E91FF921823DA0D00D59009 /* as_atomic.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BCF71523FF2300EFAB3F /* as_atomic.h */; };
6E91FF931823DA0D00D59009 /* as_builder.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BCF91523FF2300EFAB3F /* as_builder.h */; };
6E91FF941823DA0D00D59009 /* as_bytecode.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BCFB1523FF2300EFAB3F /* as_bytecode.h */; };
6E91FF951823DA0D00D59009 /* as_callfunc.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BCFD1523FF2300EFAB3F /* as_callfunc.h */; };
6E91FF961823DA0D00D59009 /* as_compiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD0D1523FF2300EFAB3F /* as_compiler.h */; };
6E91FF971823DA0D00D59009 /* as_config.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD0E1523FF2300EFAB3F /* as_config.h */; };
6E91FF981823DA0D00D59009 /* as_configgroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD111523FF2300EFAB3F /* as_configgroup.h */; };
6E91FF991823DA0D00D59009 /* as_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD131523FF2300EFAB3F /* as_context.h */; };
6E91FF9A1823DA0D00D59009 /* as_criticalsection.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD141523FF2300EFAB3F /* as_criticalsection.h */; };
6E91FF9B1823DA0D00D59009 /* as_datatype.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD161523FF2300EFAB3F /* as_datatype.h */; };
6E91FF9C1823DA0D00D59009 /* as_debug.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD171523FF2300EFAB3F /* as_debug.h */; };
6E91FF9D1823DA0D00D59009 /* as_gc.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD191523FF2300EFAB3F /* as_gc.h */; };
6E91FF9E1823DA0D00D59009 /* as_generic.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD1B1523FF2300EFAB3F /* as_generic.h */; };
6E91FF9F1823DA0D00D59009 /* as_map.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD1D1523FF2300EFAB3F /* as_map.h */; };
6E91FFA01823DA0D00D59009 /* as_memory.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD1F1523FF2300EFAB3F /* as_memory.h */; };
6E91FFA11823DA0D00D59009 /* as_module.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD211523FF2300EFAB3F /* as_module.h */; };
6E91FFA21823DA0D00D59009 /* as_objecttype.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD231523FF2300EFAB3F /* as_objecttype.h */; };
6E91FFA31823DA0D00D59009 /* as_outputbuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD251523FF2300EFAB3F /* as_outputbuffer.h */; };
6E91FFA41823DA0D00D59009 /* as_parser.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD271523FF2300EFAB3F /* as_parser.h */; };
6E91FFA51823DA0D00D59009 /* as_property.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD281523FF2300EFAB3F /* as_property.h */; };
6E91FFA61823DA0D00D59009 /* as_restore.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD2A1523FF2300EFAB3F /* as_restore.h */; };
6E91FFA71823DA0D00D59009 /* as_scriptcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD2C1523FF2300EFAB3F /* as_scriptcode.h */; };
6E91FFA81823DA0D00D59009 /* as_scriptengine.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD2E1523FF2300EFAB3F /* as_scriptengine.h */; };
6E91FFA91823DA0D00D59009 /* as_scriptfunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD301523FF2300EFAB3F /* as_scriptfunction.h */; };
6E91FFAA1823DA0D00D59009 /* as_scriptnode.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD321523FF2300EFAB3F /* as_scriptnode.h */; };
6E91FFAB1823DA0D00D59009 /* as_scriptobject.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD341523FF2300EFAB3F /* as_scriptobject.h */; };
6E91FFAC1823DA0D00D59009 /* as_string.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD361523FF2300EFAB3F /* as_string.h */; };
6E91FFAD1823DA0D00D59009 /* as_string_util.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD381523FF2300EFAB3F /* as_string_util.h */; };
6E91FFAE1823DA0D00D59009 /* as_texts.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD391523FF2300EFAB3F /* as_texts.h */; };
6E91FFAF1823DA0D00D59009 /* as_thread.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD3B1523FF2300EFAB3F /* as_thread.h */; };
6E91FFB01823DA0D00D59009 /* as_tokendef.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD3C1523FF2300EFAB3F /* as_tokendef.h */; };
6E91FFB11823DA0D00D59009 /* as_tokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD3E1523FF2300EFAB3F /* as_tokenizer.h */; };
6E91FFB21823DA0D00D59009 /* as_typeinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD401523FF2300EFAB3F /* as_typeinfo.h */; };
6E91FFB31823DA0D00D59009 /* as_variablescope.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD421523FF2300EFAB3F /* as_variablescope.h */; };
6E91FFB51823DA0D00D59009 /* as_atomic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BCF61523FF2300EFAB3F /* as_atomic.cpp */; };
6E91FFB61823DA0D00D59009 /* as_builder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BCF81523FF2300EFAB3F /* as_builder.cpp */; };
6E91FFB71823DA0D00D59009 /* as_bytecode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BCFA1523FF2300EFAB3F /* as_bytecode.cpp */; };
6E91FFB81823DA0D00D59009 /* as_callfunc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BCFC1523FF2300EFAB3F /* as_callfunc.cpp */; };
6E91FFB91823DA0D00D59009 /* as_callfunc_arm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BCFE1523FF2300EFAB3F /* as_callfunc_arm.cpp */; };
6E91FFBA1823DA0D00D59009 /* as_callfunc_arm_gcc.S in Sources */ = {isa = PBXBuildFile; fileRef = 7547BCFF1523FF2300EFAB3F /* as_callfunc_arm_gcc.S */; };
6E91FFBC1823DA0D00D59009 /* as_callfunc_arm_xcode.S in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD011523FF2300EFAB3F /* as_callfunc_arm_xcode.S */; };
6E91FFBD1823DA0D00D59009 /* as_callfunc_mips.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD021523FF2300EFAB3F /* as_callfunc_mips.cpp */; };
6E91FFBE1823DA0D00D59009 /* as_callfunc_ppc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD031523FF2300EFAB3F /* as_callfunc_ppc.cpp */; };
6E91FFBF1823DA0D00D59009 /* as_callfunc_ppc_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD041523FF2300EFAB3F /* as_callfunc_ppc_64.cpp */; };
6E91FFC01823DA0D00D59009 /* as_callfunc_sh4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD051523FF2300EFAB3F /* as_callfunc_sh4.cpp */; };
6E91FFC11823DA0D00D59009 /* as_callfunc_x64_gcc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD061523FF2300EFAB3F /* as_callfunc_x64_gcc.cpp */; };
6E91FFC51823DA0D00D59009 /* as_callfunc_x86.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD0A1523FF2300EFAB3F /* as_callfunc_x86.cpp */; };
6E91FFC71823DA0D00D59009 /* as_compiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD0C1523FF2300EFAB3F /* as_compiler.cpp */; };
6E91FFC81823DA0D00D59009 /* as_configgroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD101523FF2300EFAB3F /* as_configgroup.cpp */; };
6E91FFC91823DA0D00D59009 /* as_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD121523FF2300EFAB3F /* as_context.cpp */; };
6E91FFCA1823DA0D00D59009 /* as_datatype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD151523FF2300EFAB3F /* as_datatype.cpp */; };
6E91FFCB1823DA0D00D59009 /* as_gc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD181523FF2300EFAB3F /* as_gc.cpp */; };
6E91FFCC1823DA0D00D59009 /* as_generic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD1A1523FF2300EFAB3F /* as_generic.cpp */; };
6E91FFCD1823DA0D00D59009 /* as_globalproperty.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD1C1523FF2300EFAB3F /* as_globalproperty.cpp */; };
6E91FFCE1823DA0D00D59009 /* as_memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD1E1523FF2300EFAB3F /* as_memory.cpp */; };
6E91FFCF1823DA0D00D59009 /* as_module.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD201523FF2300EFAB3F /* as_module.cpp */; };
6E91FFD01823DA0D00D59009 /* as_objecttype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD221523FF2300EFAB3F /* as_objecttype.cpp */; };
6E91FFD11823DA0D00D59009 /* as_outputbuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD241523FF2300EFAB3F /* as_outputbuffer.cpp */; };
6E91FFD21823DA0D00D59009 /* as_parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD261523FF2300EFAB3F /* as_parser.cpp */; };
6E91FFD31823DA0D00D59009 /* as_restore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD291523FF2300EFAB3F /* as_restore.cpp */; };
6E91FFD41823DA0D00D59009 /* as_scriptcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD2B1523FF2300EFAB3F /* as_scriptcode.cpp */; };
6E91FFD51823DA0D00D59009 /* as_scriptengine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD2D1523FF2300EFAB3F /* as_scriptengine.cpp */; };
6E91FFD61823DA0D00D59009 /* as_scriptfunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD2F1523FF2300EFAB3F /* as_scriptfunction.cpp */; };
6E91FFD71823DA0D00D59009 /* as_scriptnode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD311523FF2300EFAB3F /* as_scriptnode.cpp */; };
6E91FFD81823DA0D00D59009 /* as_scriptobject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD331523FF2300EFAB3F /* as_scriptobject.cpp */; };
6E91FFD91823DA0D00D59009 /* as_string.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD351523FF2300EFAB3F /* as_string.cpp */; };
6E91FFDA1823DA0D00D59009 /* as_string_util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD371523FF2300EFAB3F /* as_string_util.cpp */; };
6E91FFDB1823DA0D00D59009 /* as_thread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD3A1523FF2300EFAB3F /* as_thread.cpp */; };
6E91FFDC1823DA0D00D59009 /* as_tokenizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD3D1523FF2300EFAB3F /* as_tokenizer.cpp */; };
6E91FFDD1823DA0D00D59009 /* as_typeinfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD3F1523FF2300EFAB3F /* as_typeinfo.cpp */; };
6E91FFDE1823DA0D00D59009 /* as_variablescope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD411523FF2300EFAB3F /* as_variablescope.cpp */; };
7547BD451523FF2300EFAB3F /* as_array.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BCF51523FF2300EFAB3F /* as_array.h */; };
7547BD461523FF2300EFAB3F /* as_atomic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BCF61523FF2300EFAB3F /* as_atomic.cpp */; };
7547BD471523FF2300EFAB3F /* as_atomic.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BCF71523FF2300EFAB3F /* as_atomic.h */; };
7547BD481523FF2300EFAB3F /* as_builder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BCF81523FF2300EFAB3F /* as_builder.cpp */; };
7547BD491523FF2300EFAB3F /* as_builder.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BCF91523FF2300EFAB3F /* as_builder.h */; };
7547BD4A1523FF2300EFAB3F /* as_bytecode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BCFA1523FF2300EFAB3F /* as_bytecode.cpp */; };
7547BD4B1523FF2300EFAB3F /* as_bytecode.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BCFB1523FF2300EFAB3F /* as_bytecode.h */; };
7547BD4C1523FF2300EFAB3F /* as_callfunc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BCFC1523FF2300EFAB3F /* as_callfunc.cpp */; };
7547BD4D1523FF2300EFAB3F /* as_callfunc.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BCFD1523FF2300EFAB3F /* as_callfunc.h */; };
7547BD4E1523FF2300EFAB3F /* as_callfunc_arm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BCFE1523FF2300EFAB3F /* as_callfunc_arm.cpp */; };
7547BD4F1523FF2300EFAB3F /* as_callfunc_arm_gcc.S in Sources */ = {isa = PBXBuildFile; fileRef = 7547BCFF1523FF2300EFAB3F /* as_callfunc_arm_gcc.S */; };
7547BD521523FF2300EFAB3F /* as_callfunc_mips.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD021523FF2300EFAB3F /* as_callfunc_mips.cpp */; };
7547BD531523FF2300EFAB3F /* as_callfunc_ppc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD031523FF2300EFAB3F /* as_callfunc_ppc.cpp */; };
7547BD541523FF2300EFAB3F /* as_callfunc_ppc_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD041523FF2300EFAB3F /* as_callfunc_ppc_64.cpp */; };
7547BD551523FF2300EFAB3F /* as_callfunc_sh4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD051523FF2300EFAB3F /* as_callfunc_sh4.cpp */; };
7547BD561523FF2300EFAB3F /* as_callfunc_x64_gcc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD061523FF2300EFAB3F /* as_callfunc_x64_gcc.cpp */; };
7547BD5A1523FF2300EFAB3F /* as_callfunc_x86.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD0A1523FF2300EFAB3F /* as_callfunc_x86.cpp */; };
7547BD5C1523FF2300EFAB3F /* as_compiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD0C1523FF2300EFAB3F /* as_compiler.cpp */; };
7547BD5D1523FF2300EFAB3F /* as_compiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD0D1523FF2300EFAB3F /* as_compiler.h */; };
7547BD5E1523FF2300EFAB3F /* as_config.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD0E1523FF2300EFAB3F /* as_config.h */; };
7547BD5F1523FF2300EFAB3F /* as_configgroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD101523FF2300EFAB3F /* as_configgroup.cpp */; };
7547BD601523FF2300EFAB3F /* as_configgroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD111523FF2300EFAB3F /* as_configgroup.h */; };
7547BD611523FF2300EFAB3F /* as_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD121523FF2300EFAB3F /* as_context.cpp */; };
7547BD621523FF2300EFAB3F /* as_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD131523FF2300EFAB3F /* as_context.h */; };
7547BD631523FF2300EFAB3F /* as_criticalsection.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD141523FF2300EFAB3F /* as_criticalsection.h */; };
7547BD641523FF2300EFAB3F /* as_datatype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD151523FF2300EFAB3F /* as_datatype.cpp */; };
7547BD651523FF2300EFAB3F /* as_datatype.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD161523FF2300EFAB3F /* as_datatype.h */; };
7547BD661523FF2300EFAB3F /* as_debug.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD171523FF2300EFAB3F /* as_debug.h */; };
7547BD671523FF2300EFAB3F /* as_gc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD181523FF2300EFAB3F /* as_gc.cpp */; };
7547BD681523FF2300EFAB3F /* as_gc.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD191523FF2300EFAB3F /* as_gc.h */; };
7547BD691523FF2300EFAB3F /* as_generic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD1A1523FF2300EFAB3F /* as_generic.cpp */; };
7547BD6A1523FF2300EFAB3F /* as_generic.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD1B1523FF2300EFAB3F /* as_generic.h */; };
7547BD6B1523FF2300EFAB3F /* as_globalproperty.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD1C1523FF2300EFAB3F /* as_globalproperty.cpp */; };
7547BD6C1523FF2300EFAB3F /* as_map.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD1D1523FF2300EFAB3F /* as_map.h */; };
7547BD6D1523FF2300EFAB3F /* as_memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD1E1523FF2300EFAB3F /* as_memory.cpp */; };
7547BD6E1523FF2300EFAB3F /* as_memory.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD1F1523FF2300EFAB3F /* as_memory.h */; };
7547BD6F1523FF2300EFAB3F /* as_module.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD201523FF2300EFAB3F /* as_module.cpp */; };
7547BD701523FF2300EFAB3F /* as_module.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD211523FF2300EFAB3F /* as_module.h */; };
7547BD711523FF2300EFAB3F /* as_objecttype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD221523FF2300EFAB3F /* as_objecttype.cpp */; };
7547BD721523FF2300EFAB3F /* as_objecttype.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD231523FF2300EFAB3F /* as_objecttype.h */; };
7547BD731523FF2300EFAB3F /* as_outputbuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD241523FF2300EFAB3F /* as_outputbuffer.cpp */; };
7547BD741523FF2300EFAB3F /* as_outputbuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD251523FF2300EFAB3F /* as_outputbuffer.h */; };
7547BD751523FF2300EFAB3F /* as_parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD261523FF2300EFAB3F /* as_parser.cpp */; };
7547BD761523FF2300EFAB3F /* as_parser.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD271523FF2300EFAB3F /* as_parser.h */; };
7547BD771523FF2300EFAB3F /* as_property.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD281523FF2300EFAB3F /* as_property.h */; };
7547BD781523FF2300EFAB3F /* as_restore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD291523FF2300EFAB3F /* as_restore.cpp */; };
7547BD791523FF2300EFAB3F /* as_restore.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD2A1523FF2300EFAB3F /* as_restore.h */; };
7547BD7A1523FF2300EFAB3F /* as_scriptcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD2B1523FF2300EFAB3F /* as_scriptcode.cpp */; };
7547BD7B1523FF2300EFAB3F /* as_scriptcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD2C1523FF2300EFAB3F /* as_scriptcode.h */; };
7547BD7C1523FF2300EFAB3F /* as_scriptengine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD2D1523FF2300EFAB3F /* as_scriptengine.cpp */; };
7547BD7D1523FF2300EFAB3F /* as_scriptengine.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD2E1523FF2300EFAB3F /* as_scriptengine.h */; };
7547BD7E1523FF2300EFAB3F /* as_scriptfunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD2F1523FF2300EFAB3F /* as_scriptfunction.cpp */; };
7547BD7F1523FF2300EFAB3F /* as_scriptfunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD301523FF2300EFAB3F /* as_scriptfunction.h */; };
7547BD801523FF2300EFAB3F /* as_scriptnode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD311523FF2300EFAB3F /* as_scriptnode.cpp */; };
7547BD811523FF2300EFAB3F /* as_scriptnode.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD321523FF2300EFAB3F /* as_scriptnode.h */; };
7547BD821523FF2300EFAB3F /* as_scriptobject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD331523FF2300EFAB3F /* as_scriptobject.cpp */; };
7547BD831523FF2300EFAB3F /* as_scriptobject.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD341523FF2300EFAB3F /* as_scriptobject.h */; };
7547BD841523FF2300EFAB3F /* as_string.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD351523FF2300EFAB3F /* as_string.cpp */; };
7547BD851523FF2300EFAB3F /* as_string.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD361523FF2300EFAB3F /* as_string.h */; };
7547BD861523FF2300EFAB3F /* as_string_util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD371523FF2300EFAB3F /* as_string_util.cpp */; };
7547BD871523FF2300EFAB3F /* as_string_util.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD381523FF2300EFAB3F /* as_string_util.h */; };
7547BD881523FF2300EFAB3F /* as_texts.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD391523FF2300EFAB3F /* as_texts.h */; };
7547BD891523FF2300EFAB3F /* as_thread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD3A1523FF2300EFAB3F /* as_thread.cpp */; };
7547BD8A1523FF2300EFAB3F /* as_thread.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD3B1523FF2300EFAB3F /* as_thread.h */; };
7547BD8B1523FF2300EFAB3F /* as_tokendef.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD3C1523FF2300EFAB3F /* as_tokendef.h */; };
7547BD8C1523FF2300EFAB3F /* as_tokenizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD3D1523FF2300EFAB3F /* as_tokenizer.cpp */; };
7547BD8D1523FF2300EFAB3F /* as_tokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD3E1523FF2300EFAB3F /* as_tokenizer.h */; };
7547BD8E1523FF2300EFAB3F /* as_typeinfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD3F1523FF2300EFAB3F /* as_typeinfo.cpp */; };
7547BD8F1523FF2300EFAB3F /* as_typeinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD401523FF2300EFAB3F /* as_typeinfo.h */; };
7547BD901523FF2300EFAB3F /* as_variablescope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD411523FF2300EFAB3F /* as_variablescope.cpp */; };
7547BD911523FF2300EFAB3F /* as_variablescope.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD421523FF2300EFAB3F /* as_variablescope.h */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
6E91005B1823FC7000D59009 /* angelscript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = angelscript.h; sourceTree = "<group>"; };
6E91FFE31823DA0D00D59009 /* libangelscript.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libangelscript.a; sourceTree = BUILT_PRODUCTS_DIR; };
7547BCF51523FF2300EFAB3F /* as_array.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_array.h; sourceTree = "<group>"; };
7547BCF61523FF2300EFAB3F /* as_atomic.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_atomic.cpp; sourceTree = "<group>"; };
7547BCF71523FF2300EFAB3F /* as_atomic.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_atomic.h; sourceTree = "<group>"; };
7547BCF81523FF2300EFAB3F /* as_builder.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_builder.cpp; sourceTree = "<group>"; };
7547BCF91523FF2300EFAB3F /* as_builder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_builder.h; sourceTree = "<group>"; };
7547BCFA1523FF2300EFAB3F /* as_bytecode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_bytecode.cpp; sourceTree = "<group>"; };
7547BCFB1523FF2300EFAB3F /* as_bytecode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_bytecode.h; sourceTree = "<group>"; };
7547BCFC1523FF2300EFAB3F /* as_callfunc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_callfunc.cpp; sourceTree = "<group>"; };
7547BCFD1523FF2300EFAB3F /* as_callfunc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_callfunc.h; sourceTree = "<group>"; };
7547BCFE1523FF2300EFAB3F /* as_callfunc_arm.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_callfunc_arm.cpp; sourceTree = "<group>"; };
7547BCFF1523FF2300EFAB3F /* as_callfunc_arm_gcc.S */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.asm; path = as_callfunc_arm_gcc.S; sourceTree = "<group>"; };
7547BD001523FF2300EFAB3F /* as_callfunc_arm_msvc.asm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.asm.asm; path = as_callfunc_arm_msvc.asm; sourceTree = "<group>"; };
7547BD011523FF2300EFAB3F /* as_callfunc_arm_xcode.S */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.asm; path = as_callfunc_arm_xcode.S; sourceTree = "<group>"; };
7547BD021523FF2300EFAB3F /* as_callfunc_mips.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_callfunc_mips.cpp; sourceTree = "<group>"; };
7547BD031523FF2300EFAB3F /* as_callfunc_ppc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_callfunc_ppc.cpp; sourceTree = "<group>"; };
7547BD041523FF2300EFAB3F /* as_callfunc_ppc_64.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_callfunc_ppc_64.cpp; sourceTree = "<group>"; };
7547BD051523FF2300EFAB3F /* as_callfunc_sh4.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_callfunc_sh4.cpp; sourceTree = "<group>"; };
7547BD061523FF2300EFAB3F /* as_callfunc_x64_gcc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_callfunc_x64_gcc.cpp; sourceTree = "<group>"; };
7547BD071523FF2300EFAB3F /* as_callfunc_x64_mingw.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_callfunc_x64_mingw.cpp; sourceTree = "<group>"; };
7547BD081523FF2300EFAB3F /* as_callfunc_x64_msvc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_callfunc_x64_msvc.cpp; sourceTree = "<group>"; };
7547BD091523FF2300EFAB3F /* as_callfunc_x64_msvc_asm.asm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.asm.asm; path = as_callfunc_x64_msvc_asm.asm; sourceTree = "<group>"; };
7547BD0A1523FF2300EFAB3F /* as_callfunc_x86.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_callfunc_x86.cpp; sourceTree = "<group>"; };
7547BD0B1523FF2300EFAB3F /* as_callfunc_xenon.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_callfunc_xenon.cpp; sourceTree = "<group>"; };
7547BD0C1523FF2300EFAB3F /* as_compiler.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_compiler.cpp; sourceTree = "<group>"; };
7547BD0D1523FF2300EFAB3F /* as_compiler.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_compiler.h; sourceTree = "<group>"; };
7547BD0E1523FF2300EFAB3F /* as_config.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_config.h; sourceTree = "<group>"; };
7547BD101523FF2300EFAB3F /* as_configgroup.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_configgroup.cpp; sourceTree = "<group>"; };
7547BD111523FF2300EFAB3F /* as_configgroup.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_configgroup.h; sourceTree = "<group>"; };
7547BD121523FF2300EFAB3F /* as_context.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_context.cpp; sourceTree = "<group>"; };
7547BD131523FF2300EFAB3F /* as_context.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_context.h; sourceTree = "<group>"; };
7547BD141523FF2300EFAB3F /* as_criticalsection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_criticalsection.h; sourceTree = "<group>"; };
7547BD151523FF2300EFAB3F /* as_datatype.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_datatype.cpp; sourceTree = "<group>"; };
7547BD161523FF2300EFAB3F /* as_datatype.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_datatype.h; sourceTree = "<group>"; };
7547BD171523FF2300EFAB3F /* as_debug.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_debug.h; sourceTree = "<group>"; };
7547BD181523FF2300EFAB3F /* as_gc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_gc.cpp; sourceTree = "<group>"; };
7547BD191523FF2300EFAB3F /* as_gc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_gc.h; sourceTree = "<group>"; };
7547BD1A1523FF2300EFAB3F /* as_generic.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_generic.cpp; sourceTree = "<group>"; };
7547BD1B1523FF2300EFAB3F /* as_generic.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_generic.h; sourceTree = "<group>"; };
7547BD1C1523FF2300EFAB3F /* as_globalproperty.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_globalproperty.cpp; sourceTree = "<group>"; };
7547BD1D1523FF2300EFAB3F /* as_map.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_map.h; sourceTree = "<group>"; };
7547BD1E1523FF2300EFAB3F /* as_memory.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_memory.cpp; sourceTree = "<group>"; };
7547BD1F1523FF2300EFAB3F /* as_memory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_memory.h; sourceTree = "<group>"; };
7547BD201523FF2300EFAB3F /* as_module.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_module.cpp; sourceTree = "<group>"; };
7547BD211523FF2300EFAB3F /* as_module.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_module.h; sourceTree = "<group>"; };
7547BD221523FF2300EFAB3F /* as_objecttype.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_objecttype.cpp; sourceTree = "<group>"; };
7547BD231523FF2300EFAB3F /* as_objecttype.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_objecttype.h; sourceTree = "<group>"; };
7547BD241523FF2300EFAB3F /* as_outputbuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_outputbuffer.cpp; sourceTree = "<group>"; };
7547BD251523FF2300EFAB3F /* as_outputbuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_outputbuffer.h; sourceTree = "<group>"; };
7547BD261523FF2300EFAB3F /* as_parser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_parser.cpp; sourceTree = "<group>"; };
7547BD271523FF2300EFAB3F /* as_parser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_parser.h; sourceTree = "<group>"; };
7547BD281523FF2300EFAB3F /* as_property.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_property.h; sourceTree = "<group>"; };
7547BD291523FF2300EFAB3F /* as_restore.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_restore.cpp; sourceTree = "<group>"; };
7547BD2A1523FF2300EFAB3F /* as_restore.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_restore.h; sourceTree = "<group>"; };
7547BD2B1523FF2300EFAB3F /* as_scriptcode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_scriptcode.cpp; sourceTree = "<group>"; };
7547BD2C1523FF2300EFAB3F /* as_scriptcode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_scriptcode.h; sourceTree = "<group>"; };
7547BD2D1523FF2300EFAB3F /* as_scriptengine.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_scriptengine.cpp; sourceTree = "<group>"; };
7547BD2E1523FF2300EFAB3F /* as_scriptengine.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_scriptengine.h; sourceTree = "<group>"; };
7547BD2F1523FF2300EFAB3F /* as_scriptfunction.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_scriptfunction.cpp; sourceTree = "<group>"; };
7547BD301523FF2300EFAB3F /* as_scriptfunction.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_scriptfunction.h; sourceTree = "<group>"; };
7547BD311523FF2300EFAB3F /* as_scriptnode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_scriptnode.cpp; sourceTree = "<group>"; };
7547BD321523FF2300EFAB3F /* as_scriptnode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_scriptnode.h; sourceTree = "<group>"; };
7547BD331523FF2300EFAB3F /* as_scriptobject.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_scriptobject.cpp; sourceTree = "<group>"; };
7547BD341523FF2300EFAB3F /* as_scriptobject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_scriptobject.h; sourceTree = "<group>"; };
7547BD351523FF2300EFAB3F /* as_string.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_string.cpp; sourceTree = "<group>"; };
7547BD361523FF2300EFAB3F /* as_string.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_string.h; sourceTree = "<group>"; };
7547BD371523FF2300EFAB3F /* as_string_util.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_string_util.cpp; sourceTree = "<group>"; };
7547BD381523FF2300EFAB3F /* as_string_util.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_string_util.h; sourceTree = "<group>"; };
7547BD391523FF2300EFAB3F /* as_texts.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_texts.h; sourceTree = "<group>"; };
7547BD3A1523FF2300EFAB3F /* as_thread.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_thread.cpp; sourceTree = "<group>"; };
7547BD3B1523FF2300EFAB3F /* as_thread.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_thread.h; sourceTree = "<group>"; };
7547BD3C1523FF2300EFAB3F /* as_tokendef.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_tokendef.h; sourceTree = "<group>"; };
7547BD3D1523FF2300EFAB3F /* as_tokenizer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_tokenizer.cpp; sourceTree = "<group>"; };
7547BD3E1523FF2300EFAB3F /* as_tokenizer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_tokenizer.h; sourceTree = "<group>"; };
7547BD3F1523FF2300EFAB3F /* as_typeinfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_typeinfo.cpp; sourceTree = "<group>"; };
7547BD401523FF2300EFAB3F /* as_typeinfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_typeinfo.h; sourceTree = "<group>"; };
7547BD411523FF2300EFAB3F /* as_variablescope.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_variablescope.cpp; sourceTree = "<group>"; };
7547BD421523FF2300EFAB3F /* as_variablescope.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_variablescope.h; sourceTree = "<group>"; };
D2AAC07E0554694100DB518D /* libangelscript.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libangelscript.a; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
6E91FFDF1823DA0D00D59009 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
D2AAC07C0554694100DB518D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
034768DFFF38A50411DB9C8B /* Products */ = {
isa = PBXGroup;
children = (
D2AAC07E0554694100DB518D /* libangelscript.a */,
6E91FFE31823DA0D00D59009 /* libangelscript.a */,
);
name = Products;
sourceTree = "<group>";
};
0867D691FE84028FC02AAC07 /* angelscript */ = {
isa = PBXGroup;
children = (
6E91005A1823FC7000D59009 /* include */,
7547BCF41523FF2300EFAB3F /* source */,
08FB77AEFE84172EC02AAC07 /* Classes */,
0867D69AFE84028FC02AAC07 /* Frameworks */,
034768DFFF38A50411DB9C8B /* Products */,
);
name = angelscript;
sourceTree = "<group>";
};
0867D69AFE84028FC02AAC07 /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
08FB77AEFE84172EC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
);
name = Classes;
sourceTree = "<group>";
};
6E91005A1823FC7000D59009 /* include */ = {
isa = PBXGroup;
children = (
6E91005B1823FC7000D59009 /* angelscript.h */,
);
name = include;
path = ../../include;
sourceTree = "<group>";
};
7547BCF41523FF2300EFAB3F /* source */ = {
isa = PBXGroup;
children = (
7547BCF51523FF2300EFAB3F /* as_array.h */,
7547BCF61523FF2300EFAB3F /* as_atomic.cpp */,
7547BCF71523FF2300EFAB3F /* as_atomic.h */,
7547BCF81523FF2300EFAB3F /* as_builder.cpp */,
7547BCF91523FF2300EFAB3F /* as_builder.h */,
7547BCFA1523FF2300EFAB3F /* as_bytecode.cpp */,
7547BCFB1523FF2300EFAB3F /* as_bytecode.h */,
7547BCFC1523FF2300EFAB3F /* as_callfunc.cpp */,
7547BCFD1523FF2300EFAB3F /* as_callfunc.h */,
7547BCFE1523FF2300EFAB3F /* as_callfunc_arm.cpp */,
7547BCFF1523FF2300EFAB3F /* as_callfunc_arm_gcc.S */,
7547BD001523FF2300EFAB3F /* as_callfunc_arm_msvc.asm */,
7547BD011523FF2300EFAB3F /* as_callfunc_arm_xcode.S */,
7547BD021523FF2300EFAB3F /* as_callfunc_mips.cpp */,
7547BD031523FF2300EFAB3F /* as_callfunc_ppc.cpp */,
7547BD041523FF2300EFAB3F /* as_callfunc_ppc_64.cpp */,
7547BD051523FF2300EFAB3F /* as_callfunc_sh4.cpp */,
7547BD061523FF2300EFAB3F /* as_callfunc_x64_gcc.cpp */,
7547BD071523FF2300EFAB3F /* as_callfunc_x64_mingw.cpp */,
7547BD081523FF2300EFAB3F /* as_callfunc_x64_msvc.cpp */,
7547BD091523FF2300EFAB3F /* as_callfunc_x64_msvc_asm.asm */,
7547BD0A1523FF2300EFAB3F /* as_callfunc_x86.cpp */,
7547BD0B1523FF2300EFAB3F /* as_callfunc_xenon.cpp */,
7547BD0C1523FF2300EFAB3F /* as_compiler.cpp */,
7547BD0D1523FF2300EFAB3F /* as_compiler.h */,
7547BD0E1523FF2300EFAB3F /* as_config.h */,
7547BD101523FF2300EFAB3F /* as_configgroup.cpp */,
7547BD111523FF2300EFAB3F /* as_configgroup.h */,
7547BD121523FF2300EFAB3F /* as_context.cpp */,
7547BD131523FF2300EFAB3F /* as_context.h */,
7547BD141523FF2300EFAB3F /* as_criticalsection.h */,
7547BD151523FF2300EFAB3F /* as_datatype.cpp */,
7547BD161523FF2300EFAB3F /* as_datatype.h */,
7547BD171523FF2300EFAB3F /* as_debug.h */,
7547BD181523FF2300EFAB3F /* as_gc.cpp */,
7547BD191523FF2300EFAB3F /* as_gc.h */,
7547BD1A1523FF2300EFAB3F /* as_generic.cpp */,
7547BD1B1523FF2300EFAB3F /* as_generic.h */,
7547BD1C1523FF2300EFAB3F /* as_globalproperty.cpp */,
7547BD1D1523FF2300EFAB3F /* as_map.h */,
7547BD1E1523FF2300EFAB3F /* as_memory.cpp */,
7547BD1F1523FF2300EFAB3F /* as_memory.h */,
7547BD201523FF2300EFAB3F /* as_module.cpp */,
7547BD211523FF2300EFAB3F /* as_module.h */,
7547BD221523FF2300EFAB3F /* as_objecttype.cpp */,
7547BD231523FF2300EFAB3F /* as_objecttype.h */,
7547BD241523FF2300EFAB3F /* as_outputbuffer.cpp */,
7547BD251523FF2300EFAB3F /* as_outputbuffer.h */,
7547BD261523FF2300EFAB3F /* as_parser.cpp */,
7547BD271523FF2300EFAB3F /* as_parser.h */,
7547BD281523FF2300EFAB3F /* as_property.h */,
7547BD291523FF2300EFAB3F /* as_restore.cpp */,
7547BD2A1523FF2300EFAB3F /* as_restore.h */,
7547BD2B1523FF2300EFAB3F /* as_scriptcode.cpp */,
7547BD2C1523FF2300EFAB3F /* as_scriptcode.h */,
7547BD2D1523FF2300EFAB3F /* as_scriptengine.cpp */,
7547BD2E1523FF2300EFAB3F /* as_scriptengine.h */,
7547BD2F1523FF2300EFAB3F /* as_scriptfunction.cpp */,
7547BD301523FF2300EFAB3F /* as_scriptfunction.h */,
7547BD311523FF2300EFAB3F /* as_scriptnode.cpp */,
7547BD321523FF2300EFAB3F /* as_scriptnode.h */,
7547BD331523FF2300EFAB3F /* as_scriptobject.cpp */,
7547BD341523FF2300EFAB3F /* as_scriptobject.h */,
7547BD351523FF2300EFAB3F /* as_string.cpp */,
7547BD361523FF2300EFAB3F /* as_string.h */,
7547BD371523FF2300EFAB3F /* as_string_util.cpp */,
7547BD381523FF2300EFAB3F /* as_string_util.h */,
7547BD391523FF2300EFAB3F /* as_texts.h */,
7547BD3A1523FF2300EFAB3F /* as_thread.cpp */,
7547BD3B1523FF2300EFAB3F /* as_thread.h */,
7547BD3C1523FF2300EFAB3F /* as_tokendef.h */,
7547BD3D1523FF2300EFAB3F /* as_tokenizer.cpp */,
7547BD3E1523FF2300EFAB3F /* as_tokenizer.h */,
7547BD3F1523FF2300EFAB3F /* as_typeinfo.cpp */,
7547BD401523FF2300EFAB3F /* as_typeinfo.h */,
7547BD411523FF2300EFAB3F /* as_variablescope.cpp */,
7547BD421523FF2300EFAB3F /* as_variablescope.h */,
);
name = source;
path = ../../source;
sourceTree = SOURCE_ROOT;
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
6E91FF901823DA0D00D59009 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
6E91FF911823DA0D00D59009 /* as_array.h in Headers */,
6E91FF921823DA0D00D59009 /* as_atomic.h in Headers */,
6E91FF931823DA0D00D59009 /* as_builder.h in Headers */,
6E91FF941823DA0D00D59009 /* as_bytecode.h in Headers */,
6E91FF951823DA0D00D59009 /* as_callfunc.h in Headers */,
6E91FF961823DA0D00D59009 /* as_compiler.h in Headers */,
6E91FF971823DA0D00D59009 /* as_config.h in Headers */,
6E91FF981823DA0D00D59009 /* as_configgroup.h in Headers */,
6E91FF991823DA0D00D59009 /* as_context.h in Headers */,
6E91FF9A1823DA0D00D59009 /* as_criticalsection.h in Headers */,
6E91FF9B1823DA0D00D59009 /* as_datatype.h in Headers */,
6E91FF9C1823DA0D00D59009 /* as_debug.h in Headers */,
6E91FF9D1823DA0D00D59009 /* as_gc.h in Headers */,
6E91FF9E1823DA0D00D59009 /* as_generic.h in Headers */,
6E91FF9F1823DA0D00D59009 /* as_map.h in Headers */,
6E91FFA01823DA0D00D59009 /* as_memory.h in Headers */,
6E91FFA11823DA0D00D59009 /* as_module.h in Headers */,
6E91FFA21823DA0D00D59009 /* as_objecttype.h in Headers */,
6E91FFA31823DA0D00D59009 /* as_outputbuffer.h in Headers */,
6E91FFA41823DA0D00D59009 /* as_parser.h in Headers */,
6E91FFA51823DA0D00D59009 /* as_property.h in Headers */,
6E91FFA61823DA0D00D59009 /* as_restore.h in Headers */,
6E91FFA71823DA0D00D59009 /* as_scriptcode.h in Headers */,
6E91FFA81823DA0D00D59009 /* as_scriptengine.h in Headers */,
6E91FFA91823DA0D00D59009 /* as_scriptfunction.h in Headers */,
6E91005D1823FC7000D59009 /* angelscript.h in Headers */,
6E91FFAA1823DA0D00D59009 /* as_scriptnode.h in Headers */,
6E91FFAB1823DA0D00D59009 /* as_scriptobject.h in Headers */,
6E91FFAC1823DA0D00D59009 /* as_string.h in Headers */,
6E91FFAD1823DA0D00D59009 /* as_string_util.h in Headers */,
6E91FFAE1823DA0D00D59009 /* as_texts.h in Headers */,
6E91FFAF1823DA0D00D59009 /* as_thread.h in Headers */,
6E91FFB01823DA0D00D59009 /* as_tokendef.h in Headers */,
6E91FFB11823DA0D00D59009 /* as_tokenizer.h in Headers */,
6E91FFB21823DA0D00D59009 /* as_typeinfo.h in Headers */,
6E91FFB31823DA0D00D59009 /* as_variablescope.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D2AAC07A0554694100DB518D /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
7547BD451523FF2300EFAB3F /* as_array.h in Headers */,
7547BD471523FF2300EFAB3F /* as_atomic.h in Headers */,
7547BD491523FF2300EFAB3F /* as_builder.h in Headers */,
7547BD4B1523FF2300EFAB3F /* as_bytecode.h in Headers */,
7547BD4D1523FF2300EFAB3F /* as_callfunc.h in Headers */,
7547BD5D1523FF2300EFAB3F /* as_compiler.h in Headers */,
7547BD5E1523FF2300EFAB3F /* as_config.h in Headers */,
7547BD601523FF2300EFAB3F /* as_configgroup.h in Headers */,
7547BD621523FF2300EFAB3F /* as_context.h in Headers */,
7547BD631523FF2300EFAB3F /* as_criticalsection.h in Headers */,
7547BD651523FF2300EFAB3F /* as_datatype.h in Headers */,
7547BD661523FF2300EFAB3F /* as_debug.h in Headers */,
7547BD681523FF2300EFAB3F /* as_gc.h in Headers */,
7547BD6A1523FF2300EFAB3F /* as_generic.h in Headers */,
7547BD6C1523FF2300EFAB3F /* as_map.h in Headers */,
7547BD6E1523FF2300EFAB3F /* as_memory.h in Headers */,
7547BD701523FF2300EFAB3F /* as_module.h in Headers */,
7547BD721523FF2300EFAB3F /* as_objecttype.h in Headers */,
7547BD741523FF2300EFAB3F /* as_outputbuffer.h in Headers */,
7547BD761523FF2300EFAB3F /* as_parser.h in Headers */,
7547BD771523FF2300EFAB3F /* as_property.h in Headers */,
7547BD791523FF2300EFAB3F /* as_restore.h in Headers */,
7547BD7B1523FF2300EFAB3F /* as_scriptcode.h in Headers */,
7547BD7D1523FF2300EFAB3F /* as_scriptengine.h in Headers */,
7547BD7F1523FF2300EFAB3F /* as_scriptfunction.h in Headers */,
6E91005C1823FC7000D59009 /* angelscript.h in Headers */,
7547BD811523FF2300EFAB3F /* as_scriptnode.h in Headers */,
7547BD831523FF2300EFAB3F /* as_scriptobject.h in Headers */,
7547BD851523FF2300EFAB3F /* as_string.h in Headers */,
7547BD871523FF2300EFAB3F /* as_string_util.h in Headers */,
7547BD881523FF2300EFAB3F /* as_texts.h in Headers */,
7547BD8A1523FF2300EFAB3F /* as_thread.h in Headers */,
7547BD8B1523FF2300EFAB3F /* as_tokendef.h in Headers */,
7547BD8D1523FF2300EFAB3F /* as_tokenizer.h in Headers */,
7547BD8F1523FF2300EFAB3F /* as_typeinfo.h in Headers */,
7547BD911523FF2300EFAB3F /* as_variablescope.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
6E91FF8F1823DA0D00D59009 /* angelscript iOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = 6E91FFE01823DA0D00D59009 /* Build configuration list for PBXNativeTarget "angelscript iOS" */;
buildPhases = (
6E91FF901823DA0D00D59009 /* Headers */,
6E91FFB41823DA0D00D59009 /* Sources */,
6E91FFDF1823DA0D00D59009 /* Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = "angelscript iOS";
productName = angelscript;
productReference = 6E91FFE31823DA0D00D59009 /* libangelscript.a */;
productType = "com.apple.product-type.library.static";
};
D2AAC07D0554694100DB518D /* angelscript OSX */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "angelscript OSX" */;
buildPhases = (
D2AAC07A0554694100DB518D /* Headers */,
D2AAC07B0554694100DB518D /* Sources */,
D2AAC07C0554694100DB518D /* Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = "angelscript OSX";
productName = angelscript;
productReference = D2AAC07E0554694100DB518D /* libangelscript.a */;
productType = "com.apple.product-type.library.static";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
0867D690FE84028FC02AAC07 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0510;
};
buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "angelscript" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
English,
Japanese,
French,
German,
);
mainGroup = 0867D691FE84028FC02AAC07 /* angelscript */;
productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
D2AAC07D0554694100DB518D /* angelscript OSX */,
6E91FF8F1823DA0D00D59009 /* angelscript iOS */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
6E91FFB41823DA0D00D59009 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6E91FFB51823DA0D00D59009 /* as_atomic.cpp in Sources */,
6E91FFB61823DA0D00D59009 /* as_builder.cpp in Sources */,
6E91FFB71823DA0D00D59009 /* as_bytecode.cpp in Sources */,
6E91FFB81823DA0D00D59009 /* as_callfunc.cpp in Sources */,
6E91FFB91823DA0D00D59009 /* as_callfunc_arm.cpp in Sources */,
6E91FFBA1823DA0D00D59009 /* as_callfunc_arm_gcc.S in Sources */,
6E91FFBC1823DA0D00D59009 /* as_callfunc_arm_xcode.S in Sources */,
6E91FFBD1823DA0D00D59009 /* as_callfunc_mips.cpp in Sources */,
6E91FFBE1823DA0D00D59009 /* as_callfunc_ppc.cpp in Sources */,
6E91FFBF1823DA0D00D59009 /* as_callfunc_ppc_64.cpp in Sources */,
6E91FFC01823DA0D00D59009 /* as_callfunc_sh4.cpp in Sources */,
6E91FFC11823DA0D00D59009 /* as_callfunc_x64_gcc.cpp in Sources */,
6E91FFC51823DA0D00D59009 /* as_callfunc_x86.cpp in Sources */,
6E91FFC71823DA0D00D59009 /* as_compiler.cpp in Sources */,
6E91FFC81823DA0D00D59009 /* as_configgroup.cpp in Sources */,
6E91FFC91823DA0D00D59009 /* as_context.cpp in Sources */,
6E91FFCA1823DA0D00D59009 /* as_datatype.cpp in Sources */,
6E91FFCB1823DA0D00D59009 /* as_gc.cpp in Sources */,
6E91FFCC1823DA0D00D59009 /* as_generic.cpp in Sources */,
6E91FFCD1823DA0D00D59009 /* as_globalproperty.cpp in Sources */,
6E91FFCE1823DA0D00D59009 /* as_memory.cpp in Sources */,
6E91FFCF1823DA0D00D59009 /* as_module.cpp in Sources */,
6E91FFD01823DA0D00D59009 /* as_objecttype.cpp in Sources */,
6E91FFD11823DA0D00D59009 /* as_outputbuffer.cpp in Sources */,
6E91FFD21823DA0D00D59009 /* as_parser.cpp in Sources */,
6E91FFD31823DA0D00D59009 /* as_restore.cpp in Sources */,
6E91FFD41823DA0D00D59009 /* as_scriptcode.cpp in Sources */,
6E91FFD51823DA0D00D59009 /* as_scriptengine.cpp in Sources */,
6E91FFD61823DA0D00D59009 /* as_scriptfunction.cpp in Sources */,
6E91FFD71823DA0D00D59009 /* as_scriptnode.cpp in Sources */,
6E91FFD81823DA0D00D59009 /* as_scriptobject.cpp in Sources */,
6E91FFD91823DA0D00D59009 /* as_string.cpp in Sources */,
6E91FFDA1823DA0D00D59009 /* as_string_util.cpp in Sources */,
6E91FFDB1823DA0D00D59009 /* as_thread.cpp in Sources */,
6E91FFDC1823DA0D00D59009 /* as_tokenizer.cpp in Sources */,
6E91FFDD1823DA0D00D59009 /* as_typeinfo.cpp in Sources */,
6E91FFDE1823DA0D00D59009 /* as_variablescope.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D2AAC07B0554694100DB518D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7547BD461523FF2300EFAB3F /* as_atomic.cpp in Sources */,
7547BD481523FF2300EFAB3F /* as_builder.cpp in Sources */,
7547BD4A1523FF2300EFAB3F /* as_bytecode.cpp in Sources */,
7547BD4C1523FF2300EFAB3F /* as_callfunc.cpp in Sources */,
7547BD4E1523FF2300EFAB3F /* as_callfunc_arm.cpp in Sources */,
7547BD4F1523FF2300EFAB3F /* as_callfunc_arm_gcc.S in Sources */,
7547BD521523FF2300EFAB3F /* as_callfunc_mips.cpp in Sources */,
7547BD531523FF2300EFAB3F /* as_callfunc_ppc.cpp in Sources */,
7547BD541523FF2300EFAB3F /* as_callfunc_ppc_64.cpp in Sources */,
7547BD551523FF2300EFAB3F /* as_callfunc_sh4.cpp in Sources */,
7547BD561523FF2300EFAB3F /* as_callfunc_x64_gcc.cpp in Sources */,
7547BD5A1523FF2300EFAB3F /* as_callfunc_x86.cpp in Sources */,
7547BD5C1523FF2300EFAB3F /* as_compiler.cpp in Sources */,
7547BD5F1523FF2300EFAB3F /* as_configgroup.cpp in Sources */,
7547BD611523FF2300EFAB3F /* as_context.cpp in Sources */,
7547BD641523FF2300EFAB3F /* as_datatype.cpp in Sources */,
7547BD671523FF2300EFAB3F /* as_gc.cpp in Sources */,
7547BD691523FF2300EFAB3F /* as_generic.cpp in Sources */,
7547BD6B1523FF2300EFAB3F /* as_globalproperty.cpp in Sources */,
7547BD6D1523FF2300EFAB3F /* as_memory.cpp in Sources */,
7547BD6F1523FF2300EFAB3F /* as_module.cpp in Sources */,
7547BD711523FF2300EFAB3F /* as_objecttype.cpp in Sources */,
7547BD731523FF2300EFAB3F /* as_outputbuffer.cpp in Sources */,
7547BD751523FF2300EFAB3F /* as_parser.cpp in Sources */,
7547BD781523FF2300EFAB3F /* as_restore.cpp in Sources */,
7547BD7A1523FF2300EFAB3F /* as_scriptcode.cpp in Sources */,
7547BD7C1523FF2300EFAB3F /* as_scriptengine.cpp in Sources */,
7547BD7E1523FF2300EFAB3F /* as_scriptfunction.cpp in Sources */,
7547BD801523FF2300EFAB3F /* as_scriptnode.cpp in Sources */,
7547BD821523FF2300EFAB3F /* as_scriptobject.cpp in Sources */,
7547BD841523FF2300EFAB3F /* as_string.cpp in Sources */,
7547BD861523FF2300EFAB3F /* as_string_util.cpp in Sources */,
7547BD891523FF2300EFAB3F /* as_thread.cpp in Sources */,
7547BD8C1523FF2300EFAB3F /* as_tokenizer.cpp in Sources */,
7547BD8E1523FF2300EFAB3F /* as_typeinfo.cpp in Sources */,
7547BD901523FF2300EFAB3F /* as_variablescope.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
1DEB921F08733DC00010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
CLANG_CXX_LANGUAGE_STANDARD = "compiler-default";
CLANG_CXX_LIBRARY = "compiler-default";
COPY_PHASE_STRIP = NO;
DSTROOT = /tmp/angelscript.dst;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_MODEL_TUNING = G5;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = angelscript_Prefix.pch;
INSTALL_PATH = /usr/local/lib/OSX/x86_64/Debug;
PRODUCT_NAME = angelscript;
SDKROOT = macosx;
};
name = Debug;
};
1DEB922008733DC00010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
CLANG_CXX_LANGUAGE_STANDARD = "compiler-default";
CLANG_CXX_LIBRARY = "compiler-default";
DSTROOT = /tmp/angelscript.dst;
GCC_MODEL_TUNING = G5;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = angelscript_Prefix.pch;
INSTALL_PATH = /usr/local/lib/OSX/x86_64/Release;
PRODUCT_NAME = angelscript;
SDKROOT = macosx;
};
name = Release;
};
1DEB922308733DC00010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CLANG_CXX_LANGUAGE_STANDARD = "gnu++98";
CLANG_CXX_LIBRARY = "libstdc++";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
ONLY_ACTIVE_ARCH = YES;
OTHER_LDFLAGS = "-ObjC";
PREBINDING = NO;
};
name = Debug;
};
1DEB922408733DC00010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CLANG_CXX_LANGUAGE_STANDARD = "gnu++98";
CLANG_CXX_LIBRARY = "libstdc++";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
OTHER_LDFLAGS = "-ObjC";
PREBINDING = NO;
};
name = Release;
};
6E91FFE11823DA0D00D59009 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
COPY_PHASE_STRIP = NO;
DSTROOT = /tmp/angelscript.dst;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_MODEL_TUNING = G5;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = angelscript_Prefix.pch;
INSTALL_PATH = /usr/local/lib/iOS/arm64/Debug;
"INSTALL_PATH[sdk=iphonesimulator*]" = /usr/local/lib/iOS/x86_64/Debug;
PRODUCT_NAME = angelscript;
SDKROOT = iphoneos;
};
name = Debug;
};
6E91FFE21823DA0D00D59009 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
DSTROOT = /tmp/angelscript.dst;
GCC_MODEL_TUNING = G5;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = angelscript_Prefix.pch;
INSTALL_PATH = /usr/local/lib/iOS/arm64/Release;
"INSTALL_PATH[sdk=iphonesimulator*]" = /usr/local/lib/iOS/x86_64/Release;
PRODUCT_NAME = angelscript;
SDKROOT = iphoneos;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "angelscript OSX" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB921F08733DC00010E9CD /* Debug */,
1DEB922008733DC00010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "angelscript" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB922308733DC00010E9CD /* Debug */,
1DEB922408733DC00010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
6E91FFE01823DA0D00D59009 /* Build configuration list for PBXNativeTarget "angelscript iOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
6E91FFE11823DA0D00D59009 /* Debug */,
6E91FFE21823DA0D00D59009 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 0867D690FE84028FC02AAC07 /* Project object */;
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:angelscript.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildLocationStyle</key>
<string>CustomLocation</string>
<key>CustomBuildIntermediatesPath</key>
<string>tmp</string>
<key>CustomBuildLocationType</key>
<string>RelativeToWorkspace</string>
<key>CustomBuildProductsPath</key>
<string>../../lib/</string>
<key>DerivedDataLocationStyle</key>
<string>Default</string>
<key>HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges</key>
<true/>
<key>IssueFilterStyle</key>
<string>ShowActiveSchemeOnly</string>
<key>LiveSourceIssuesEnabled</key>
<true/>
<key>SnapshotAutomaticallyBeforeSignificantChanges</key>
<true/>
<key>SnapshotLocationStyle</key>
<string>Default</string>
</dict>
</plist>

View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0510"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D2AAC07D0554694100DB518D"
BuildableName = "libangelscript.a"
BlueprintName = "angelscript OSX"
ReferencedContainer = "container:angelscript.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0510"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6E91FF8F1823DA0D00D59009"
BuildableName = "libangelscript.a"
BlueprintName = "angelscript iOS"
ReferencedContainer = "container:angelscript.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>angelscript OSX.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
<key>angelscript iOS.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>6E91FF8F1823DA0D00D59009</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>D2AAC07D0554694100DB518D</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>

View File

@@ -0,0 +1,7 @@
//
// Prefix header for all source files of the 'CocoaTouchStaticLibrary' target in the 'CocoaTouchStaticLibrary' project.
//
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#endif

View File

@@ -0,0 +1,528 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
#ifndef AS_ARRAY_H
#define AS_ARRAY_H
#if !defined(AS_NO_MEMORY_H)
#include <memory.h>
#endif
#include <string.h> // some compilers declare memcpy() here
#ifdef _MSC_VER
#pragma warning(disable:4345) // warning about a change in how the code is handled in this version
#endif
BEGIN_AS_NAMESPACE
template <class T> class asCArray
{
public:
asCArray();
asCArray(const asCArray<T> &);
asCArray(asUINT reserve);
~asCArray();
void Allocate(asUINT numElements, bool keepData);
void AllocateNoConstruct(asUINT numElements, bool keepData);
asUINT GetCapacity() const;
void PushLast(const T &element);
T PopLast();
bool SetLength(asUINT numElements);
bool SetLengthNoConstruct(asUINT numElements);
asUINT GetLength() const;
void Copy(const T*, asUINT count);
asCArray<T> &operator =(const asCArray<T> &);
void SwapWith(asCArray<T> &other);
const T &operator [](asUINT index) const;
T &operator [](asUINT index);
T *AddressOf();
const T *AddressOf() const;
bool Concatenate(const asCArray<T> &);
void Concatenate(T*, unsigned int count);
bool Exists(const T &element) const;
int IndexOf(const T &element) const;
void RemoveIndex(asUINT index); // Removes the entry without reordering the array
void RemoveValue(const T &element); // Removes the value without reordering the array
void RemoveIndexUnordered(asUINT index); // Removes the entry without keeping the order
bool operator==(const asCArray<T> &) const;
bool operator!=(const asCArray<T> &) const;
protected:
T *array;
asUINT length; // 32bits is enough for all uses of this array
asUINT maxLength;
char buf[2*4*AS_PTR_SIZE]; // Avoid dynamically allocated memory for tiny arrays
};
// Implementation
template <class T>
T *asCArray<T>::AddressOf()
{
return array;
}
template <class T>
const T *asCArray<T>::AddressOf() const
{
return array;
}
template <class T>
asCArray<T>::asCArray(void)
{
array = 0;
length = 0;
maxLength = 0;
}
template <class T>
asCArray<T>::asCArray(const asCArray<T> &copy)
{
array = 0;
length = 0;
maxLength = 0;
*this = copy;
}
template <class T>
asCArray<T>::asCArray(asUINT reserve)
{
array = 0;
length = 0;
maxLength = 0;
Allocate(reserve, false);
}
template <class T>
asCArray<T>::~asCArray(void)
{
// Allocating a zero length array will free all memory
Allocate(0,0);
}
template <class T>
asUINT asCArray<T>::GetLength() const
{
return length;
}
template <class T>
const T &asCArray<T>::operator [](asUINT index) const
{
asASSERT(index < length);
return array[index];
}
template <class T>
T &asCArray<T>::operator [](asUINT index)
{
asASSERT(index < length);
return array[index];
}
template <class T>
void asCArray<T>::PushLast(const T &element)
{
if( length == maxLength )
{
if( maxLength == 0 )
Allocate(1, false);
else
Allocate(2*maxLength, true);
if( length == maxLength )
{
// Out of memory. Return without doing anything
return;
}
}
array[length++] = element;
}
template <class T>
T asCArray<T>::PopLast()
{
asASSERT(length > 0);
return array[--length];
}
template <class T>
void asCArray<T>::Allocate(asUINT numElements, bool keepData)
{
// We have 4 situations
// 1. The previous array is 8 bytes or smaller and the new array is also 8 bytes or smaller
// 2. The previous array is 8 bytes or smaller and the new array is larger than 8 bytes
// 3. The previous array is larger than 8 bytes and the new array is 8 bytes or smaller
// 4. The previous array is larger than 8 bytes and the new array is also larger than 8 bytes
T *tmp = 0;
if( numElements )
{
if( sizeof(T)*numElements <= sizeof(buf) )
// Use the internal buffer
tmp = reinterpret_cast<T*>(buf);
else
{
// Allocate the array and construct each of the elements
tmp = asNEWARRAY(T,numElements);
if( tmp == 0 )
{
// Out of memory. Return without doing anything
return;
}
}
if( array == tmp )
{
// Construct only the newly allocated elements
for( asUINT n = length; n < numElements; n++ )
new (&tmp[n]) T();
}
else
{
// Construct all elements
for( asUINT n = 0; n < numElements; n++ )
new (&tmp[n]) T();
}
}
if( array )
{
asUINT oldLength = length;
if( array == tmp )
{
if( keepData )
{
if( length > numElements )
length = numElements;
}
else
length = 0;
// Call the destructor for elements that are no longer used
for( asUINT n = length; n < oldLength; n++ )
array[n].~T();
}
else
{
if( keepData )
{
if( length > numElements )
length = numElements;
for( asUINT n = 0; n < length; n++ )
tmp[n] = array[n];
}
else
length = 0;
// Call the destructor for all elements
for( asUINT n = 0; n < oldLength; n++ )
array[n].~T();
if( array != reinterpret_cast<T*>(buf) )
asDELETEARRAY(array);
}
}
array = tmp;
maxLength = numElements;
}
template <class T>
void asCArray<T>::AllocateNoConstruct(asUINT numElements, bool keepData)
{
// We have 4 situations
// 1. The previous array is 8 bytes or smaller and the new array is also 8 bytes or smaller
// 2. The previous array is 8 bytes or smaller and the new array is larger than 8 bytes
// 3. The previous array is larger than 8 bytes and the new array is 8 bytes or smaller
// 4. The previous array is larger than 8 bytes and the new array is also larger than 8 bytes
T *tmp = 0;
if( numElements )
{
if( sizeof(T)*numElements <= sizeof(buf) )
// Use the internal buffer
tmp = reinterpret_cast<T*>(buf);
else
{
// Allocate the array and construct each of the elements
tmp = asNEWARRAY(T,numElements);
if( tmp == 0 )
{
// Out of memory. Return without doing anything
return;
}
}
}
if( array )
{
if( array == tmp )
{
if( keepData )
{
if( length > numElements )
length = numElements;
}
else
length = 0;
}
else
{
if( keepData )
{
if( length > numElements )
length = numElements;
memcpy(tmp, array, sizeof(T)*length);
}
else
length = 0;
if( array != reinterpret_cast<T*>(buf) )
asDELETEARRAY(array);
}
}
array = tmp;
maxLength = numElements;
}
template <class T>
asUINT asCArray<T>::GetCapacity() const
{
return maxLength;
}
template <class T>
bool asCArray<T>::SetLength(asUINT numElements)
{
if( numElements > maxLength )
{
Allocate(numElements, true);
if( numElements > maxLength )
{
// Out of memory. Return without doing anything
return false;
}
}
length = numElements;
return true;
}
template <class T>
bool asCArray<T>::SetLengthNoConstruct(asUINT numElements)
{
if( numElements > maxLength )
{
AllocateNoConstruct(numElements, true);
if( numElements > maxLength )
{
// Out of memory. Return without doing anything
return false;
}
}
length = numElements;
return true;
}
template <class T>
void asCArray<T>::Copy(const T *data, asUINT count)
{
if( maxLength < count )
{
Allocate(count, false);
if( maxLength < count )
{
// Out of memory. Return without doing anything
return;
}
}
for( asUINT n = 0; n < count; n++ )
array[n] = data[n];
length = count;
}
template <class T>
asCArray<T> &asCArray<T>::operator =(const asCArray<T> &copy)
{
Copy(copy.array, copy.length);
return *this;
}
template <class T>
void asCArray<T>::SwapWith(asCArray<T> &other)
{
T *tmpArray = array;
asUINT tmpLength = length;
asUINT tmpMaxLength = maxLength;
char tmpBuf[sizeof(buf)];
memcpy(tmpBuf, buf, sizeof(buf));
array = other.array;
length = other.length;
maxLength = other.maxLength;
memcpy(buf, other.buf, sizeof(buf));
other.array = tmpArray;
other.length = tmpLength;
other.maxLength = tmpMaxLength;
memcpy(other.buf, tmpBuf, sizeof(buf));
// If the data is in the internal buffer, then the array pointer must refer to it
if( array == reinterpret_cast<T*>(other.buf) )
array = reinterpret_cast<T*>(buf);
if( other.array == reinterpret_cast<T*>(buf) )
other.array = reinterpret_cast<T*>(other.buf);
}
template <class T>
bool asCArray<T>::operator ==(const asCArray<T> &other) const
{
if( length != other.length ) return false;
for( asUINT n = 0; n < length; n++ )
if( array[n] != other.array[n] )
return false;
return true;
}
template <class T>
bool asCArray<T>::operator !=(const asCArray<T> &other) const
{
return !(*this == other);
}
// Returns false if the concatenation wasn't successful due to out of memory
template <class T>
bool asCArray<T>::Concatenate(const asCArray<T> &other)
{
if( maxLength < length + other.length )
{
Allocate(length + other.length, true);
if( maxLength < length + other.length )
{
// Out of memory
return false;
}
}
for( asUINT n = 0; n < other.length; n++ )
array[length+n] = other.array[n];
length += other.length;
// Success
return true;
}
template <class T>
void asCArray<T>::Concatenate(T* other, unsigned int count)
{
for( unsigned int c = 0; c < count; c++ )
PushLast(other[c]);
}
template <class T>
bool asCArray<T>::Exists(const T &e) const
{
return IndexOf(e) == -1 ? false : true;
}
template <class T>
int asCArray<T>::IndexOf(const T &e) const
{
for( asUINT n = 0; n < length; n++ )
if( array[n] == e ) return static_cast<int>(n);
return -1;
}
template <class T>
void asCArray<T>::RemoveIndex(asUINT index)
{
if( index < length )
{
for( asUINT n = index; n < length-1; n++ )
array[n] = array[n+1];
PopLast();
}
}
template <class T>
void asCArray<T>::RemoveValue(const T &e)
{
for( asUINT n = 0; n < length; n++ )
{
if( array[n] == e )
{
RemoveIndex(n);
break;
}
}
}
template <class T>
void asCArray<T>::RemoveIndexUnordered(asUINT index)
{
if( index == length - 1 )
PopLast();
else if( index < length )
array[index] = PopLast();
}
END_AS_NAMESPACE
#endif

View File

@@ -0,0 +1,179 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2014 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_atomic.cpp
//
// The implementation of the atomic class for thread safe reference counting
//
#include "as_atomic.h"
BEGIN_AS_NAMESPACE
asCAtomic::asCAtomic()
{
value = 0;
}
asDWORD asCAtomic::get() const
{
// A very high ref count is highly unlikely. It most likely a problem with
// memory that has been overwritten or is being accessed after it was deleted.
asASSERT(value < 1000000);
return value;
}
void asCAtomic::set(asDWORD val)
{
// A very high ref count is highly unlikely. It most likely a problem with
// memory that has been overwritten or is being accessed after it was deleted.
asASSERT(value < 1000000);
value = val;
}
asDWORD asCAtomic::atomicInc()
{
// A very high ref count is highly unlikely. It most likely a problem with
// memory that has been overwritten or is being accessed after it was deleted.
asASSERT(value < 1000000);
return asAtomicInc((int&)value);
}
asDWORD asCAtomic::atomicDec()
{
// A very high ref count is highly unlikely. It most likely a problem with
// memory that has been overwritten or is being accessed after it was deleted.
asASSERT(value < 1000000);
return asAtomicDec((int&)value);
}
//
// The following code implements the atomicInc and atomicDec on different platforms
//
#if defined(AS_NO_THREADS) || defined(AS_NO_ATOMIC)
int asAtomicInc(int &value)
{
return ++value;
}
int asAtomicDec(int &value)
{
return --value;
}
#elif defined(AS_XENON) /// XBox360
END_AS_NAMESPACE
#include <xtl.h>
BEGIN_AS_NAMESPACE
int asAtomicInc(int &value)
{
return InterlockedIncrement((LONG*)&value);
}
int asAtomicDec(int &value)
{
return InterlockedDecrement((LONG*)&value);
}
#elif defined(AS_WIN)
END_AS_NAMESPACE
#define WIN32_MEAN_AND_LEAN
#include <windows.h>
BEGIN_AS_NAMESPACE
int asAtomicInc(int &value)
{
return InterlockedIncrement((LONG*)&value);
}
int asAtomicDec(int &value)
{
asASSERT(value > 0);
return InterlockedDecrement((LONG*)&value);
}
#elif defined(AS_LINUX) || defined(AS_BSD) || defined(AS_ILLUMOS) || defined(AS_ANDROID)
//
// atomic_inc_and_test() and atomic_dec_and_test() from asm/atomic.h is not meant
// to be used outside the Linux kernel. Instead we should use the GNUC provided
// __sync_add_and_fetch() and __sync_sub_and_fetch() functions.
//
// Reference: http://golubenco.org/blog/atomic-operations/
//
// These are only available in GCC 4.1 and above, so for older versions we
// use the critical sections, though it is a lot slower.
//
int asAtomicInc(int &value)
{
return __sync_add_and_fetch(&value, 1);
}
int asAtomicDec(int &value)
{
return __sync_sub_and_fetch(&value, 1);
}
#elif defined(AS_MAC) || defined(AS_IPHONE)
END_AS_NAMESPACE
#include <libkern/OSAtomic.h>
BEGIN_AS_NAMESPACE
int asAtomicInc(int &value)
{
return OSAtomicIncrement32((int32_t*)&value);
}
int asAtomicDec(int &value)
{
return OSAtomicDecrement32((int32_t*)&value);
}
#else
// If we get here, then the configuration in as_config.h
// is wrong for the compiler/platform combination.
int ERROR_PleaseFixTheConfig[-1];
#endif
END_AS_NAMESPACE

View File

@@ -0,0 +1,69 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2013 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_atomic.h
//
// The asCAtomic class provides methods for performing threadsafe
// operations on a single dword, e.g. reference counting and
// bitfields.
//
#ifndef AS_ATOMIC_H
#define AS_ATOMIC_H
#include "as_config.h"
BEGIN_AS_NAMESPACE
class asCAtomic
{
public:
asCAtomic();
asDWORD get() const;
void set(asDWORD val);
// Increase and return new value
asDWORD atomicInc();
// Decrease and return new value
asDWORD atomicDec();
protected:
asDWORD value;
};
END_AS_NAMESPACE
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,262 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2019 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_builder.h
//
// This is the class that manages the compilation of the scripts
//
#ifndef AS_BUILDER_H
#define AS_BUILDER_H
#include "as_config.h"
#include "as_symboltable.h"
#include "as_scriptengine.h"
#include "as_module.h"
#include "as_array.h"
#include "as_scriptcode.h"
#include "as_scriptnode.h"
#include "as_datatype.h"
#include "as_property.h"
BEGIN_AS_NAMESPACE
#ifdef AS_NO_COMPILER
// Forward declare the structure, as it is part of some function signatures used even without the compiler
struct sGlobalVariableDescription;
#endif
#ifndef AS_NO_COMPILER
struct sFunctionDescription
{
asCScriptCode *script;
asCScriptNode *node;
asCString name;
asCObjectType *objType;
asCArray<asCString> paramNames;
int funcId;
bool isExistingShared;
};
struct sGlobalVariableDescription
{
asCScriptCode *script;
asCScriptNode *declaredAtNode;
asCScriptNode *initializationNode;
asCString name;
asCGlobalProperty *property;
asCDataType datatype;
asSNameSpace *ns;
int index;
bool isCompiled;
bool isPureConstant;
bool isEnumValue;
asQWORD constantValue;
};
struct sPropertyInitializer
{
sPropertyInitializer() : declNode(0), initNode(0), file(0) {}
sPropertyInitializer(const asCString &nm, asCScriptNode *decl, asCScriptNode *init, asCScriptCode *f) : name(nm), declNode(decl), initNode(init), file(f) {}
sPropertyInitializer &operator=(const sPropertyInitializer &o) {name = o.name; declNode = o.declNode; initNode = o.initNode; file = o.file; return *this;}
asCString name;
asCScriptNode *declNode;
asCScriptNode *initNode;
asCScriptCode *file;
};
struct sClassDeclaration
{
sClassDeclaration() {script = 0; node = 0; validState = 0; typeInfo = 0; isExistingShared = false; isFinal = false;}
asCScriptCode *script;
asCScriptNode *node;
asCString name;
int validState;
asCTypeInfo *typeInfo;
bool isExistingShared;
bool isFinal;
asCArray<sPropertyInitializer> propInits;
};
struct sFuncDef
{
asCScriptCode *script;
asCScriptNode *node;
asCString name;
int idx;
};
struct sMixinClass
{
asCScriptCode *script;
asCScriptNode *node;
asCString name;
asSNameSpace *ns;
};
#endif // AS_NO_COMPILER
class asCBuilder
{
public:
asCBuilder(asCScriptEngine *engine, asCModule *module);
~asCBuilder();
// These methods are used by the application interface
int VerifyProperty(asCDataType *dt, const char *decl, asCString &outName, asCDataType &outType, asSNameSpace *ns);
int ParseDataType(const char *datatype, asCDataType *result, asSNameSpace *implicitNamespace, bool isReturnType = false);
int ParseTemplateDecl(const char *decl, asCString *name, asCArray<asCString> &subtypeNames);
int ParseFunctionDeclaration(asCObjectType *type, const char *decl, asCScriptFunction *func, bool isSystemFunction, asCArray<bool> *paramAutoHandles = 0, bool *returnAutoHandle = 0, asSNameSpace *ns = 0, asCScriptNode **outListPattern = 0, asCObjectType **outParentClass = 0);
int ParseVariableDeclaration(const char *decl, asSNameSpace *implicitNamespace, asCString &outName, asSNameSpace *&outNamespace, asCDataType &outDt);
int CheckNameConflict(const char *name, asCScriptNode *node, asCScriptCode *code, asSNameSpace *ns, bool isProperty, bool isVirtualProperty);
int CheckNameConflictMember(asCTypeInfo *type, const char *name, asCScriptNode *node, asCScriptCode *code, bool isProperty, bool isVirtualProperty);
int ValidateVirtualProperty(asCScriptFunction *func);
#ifndef AS_NO_COMPILER
int AddCode(const char *name, const char *code, int codeLength, int lineOffset, int sectionIdx, bool makeCopy);
asCScriptCode *FindOrAddCode(const char *name, const char *code, size_t length);
int Build();
int CompileFunction(const char *sectionName, const char *code, int lineOffset, asDWORD compileFlags, asCScriptFunction **outFunc);
int CompileGlobalVar(const char *sectionName, const char *code, int lineOffset);
#endif
protected:
friend class asCModule;
friend class asCParser;
friend class asCScriptFunction;
friend class asCScriptEngine;
void Reset();
void WriteInfo(const asCString &scriptname, const asCString &msg, int r, int c, bool preMessage);
void WriteInfo(const asCString &msg, asCScriptCode *file, asCScriptNode *node);
void WriteError(const asCString &scriptname, const asCString &msg, int r, int c);
void WriteError(const asCString &msg, asCScriptCode *file, asCScriptNode *node);
void WriteWarning(const asCString &scriptname, const asCString &msg, int r, int c);
void WriteWarning(const asCString &msg, asCScriptCode *file, asCScriptNode *node);
bool DoesGlobalPropertyExist(const char *prop, asSNameSpace *ns, asCGlobalProperty **outProp = 0, sGlobalVariableDescription **outDesc = 0, bool *isAppProp = 0);
asCGlobalProperty *GetGlobalProperty(const char *prop, asSNameSpace *ns, bool *isCompiled, bool *isPureConstant, asQWORD *constantValue, bool *isAppProp);
int ValidateDefaultArgs(asCScriptCode *script, asCScriptNode *node, asCScriptFunction *func);
asCString GetCleanExpressionString(asCScriptNode *n, asCScriptCode *file);
asSNameSpace *GetNameSpaceFromNode(asCScriptNode *node, asCScriptCode *script, asSNameSpace *implicitNs, asCScriptNode **next, asCObjectType **objType = 0);
asSNameSpace *GetNameSpaceByString(const asCString &nsName, asSNameSpace *implicitNs, asCScriptNode *errNode, asCScriptCode *script, asCTypeInfo **scopeType = 0, bool isRequired = true);
asCString GetScopeFromNode(asCScriptNode *n, asCScriptCode *script, asCScriptNode **next = 0);
asCTypeInfo *GetType(const char *type, asSNameSpace *ns, asCObjectType *parentType);
asCObjectType *GetObjectType(const char *type, asSNameSpace *ns);
asCFuncdefType *GetFuncDef(const char *type, asSNameSpace *ns, asCObjectType *parentType);
asCTypeInfo *GetTypeFromTypesKnownByObject(const char *type, asCObjectType *currentType);
asCDataType CreateDataTypeFromNode(asCScriptNode *node, asCScriptCode *file, asSNameSpace *implicitNamespace, bool acceptHandleForScope = false, asCObjectType *currentType = 0, bool reportError = true, bool *isValid = 0);
asCObjectType *GetTemplateInstanceFromNode(asCScriptNode *node, asCScriptCode *file, asCObjectType *templateType, asSNameSpace *implicitNamespace, asCObjectType *currentType, asCScriptNode **next = 0);
asCDataType ModifyDataTypeFromNode(const asCDataType &type, asCScriptNode *node, asCScriptCode *file, asETypeModifiers *inOutFlag, bool *autoHandle);
int numErrors;
int numWarnings;
bool silent;
asCScriptEngine *engine;
asCModule *module;
#ifndef AS_NO_COMPILER
protected:
friend class asCCompiler;
int CheckForConflictsDueToDefaultArgs(asCScriptCode *script, asCScriptNode *node, asCScriptFunction *func, asCObjectType *objType);
int GetNamespaceAndNameFromNode(asCScriptNode *n, asCScriptCode *script, asSNameSpace *implicitNs, asSNameSpace *&outNs, asCString &outName);
int RegisterMixinClass(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
sMixinClass *GetMixinClass(const char *name, asSNameSpace *ns);
void IncludePropertiesFromMixins(sClassDeclaration *decl);
void IncludeMethodsFromMixins(sClassDeclaration *decl);
void AddInterfaceToClass(sClassDeclaration *decl, asCScriptNode *errNode, asCObjectType *intf);
void AddInterfaceFromMixinToClass(sClassDeclaration *decl, asCScriptNode *errNode, sMixinClass *mixin);
int RegisterScriptFunctionFromNode(asCScriptNode *node, asCScriptCode *file, asCObjectType *object = 0, bool isInterface = false, bool isGlobalFunction = false, asSNameSpace *ns = 0, bool isExistingShared = false, bool isMixin = false);
int RegisterScriptFunction(asCScriptNode *node, asCScriptCode *file, asCObjectType *objType, bool isInterface, bool isGlobalFunction, asSNameSpace *ns, bool isExistingShared, bool isMixin, asCString &name, asCDataType &returnType, asCArray<asCString> &parameterNames, asCArray<asCDataType> &parameterTypes, asCArray<asETypeModifiers> &inOutFlags, asCArray<asCString *> &defaultArgs, asSFunctionTraits funcTraits);
int RegisterVirtualProperty(asCScriptNode *node, asCScriptCode *file, asCObjectType *object = 0, bool isInterface = false, bool isGlobalFunction = false, asSNameSpace *ns = 0, bool isExistingShared = false);
int RegisterImportedFunction(int funcID, asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
int RegisterGlobalVar(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
int RegisterClass(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
int RegisterInterface(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
int RegisterEnum(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
int RegisterTypedef(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
int RegisterFuncDef(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns, asCObjectType *parent);
asCScriptFunction *RegisterLambda(asCScriptNode *node, asCScriptCode *file, asCScriptFunction *funcDef, const asCString &name, asSNameSpace *ns);
void CompleteFuncDef(sFuncDef *funcDef);
void CompileInterfaces();
void CompileClasses(asUINT originalNumTempl);
void DetermineTypeRelations();
void GetParsedFunctionDetails(asCScriptNode *node, asCScriptCode *file, asCObjectType *objType, asCString &name, asCDataType &returnType, asCArray<asCString> &parameterNames, asCArray<asCDataType> &parameterTypes, asCArray<asETypeModifiers> &inOutFlags, asCArray<asCString *> &defaultArgs, asSFunctionTraits &traits, asSNameSpace *implicitNamespace);
bool DoesMethodExist(asCObjectType *objType, int methodId, asUINT *methodIndex = 0);
void AddDefaultConstructor(asCObjectType *objType, asCScriptCode *file);
asCObjectProperty *AddPropertyToClass(sClassDeclaration *c, const asCString &name, const asCDataType &type, bool isPrivate, bool isProtected, bool isInherited, asCScriptCode *file = 0, asCScriptNode *node = 0);
int CreateVirtualFunction(asCScriptFunction *func, int idx);
void ParseScripts();
void RegisterTypesFromScript(asCScriptNode *node, asCScriptCode *script, asSNameSpace *ns);
void RegisterNonTypesFromScript(asCScriptNode *node, asCScriptCode *script, asSNameSpace *ns);
void CompileFunctions();
void CompileGlobalVariables();
int GetEnumValueFromType(asCEnumType *type, const char *name, asCDataType &outDt, asDWORD &outValue);
int GetEnumValue(const char *name, asCDataType &outDt, asDWORD &outValue, asSNameSpace *ns);
bool DoesTypeExist(const asCString &type);
asCObjectProperty *GetObjectProperty(asCDataType &obj, const char *prop);
asCScriptFunction *GetFunctionDescription(int funcId);
void GetFunctionDescriptions(const char *name, asCArray<int> &funcs, asSNameSpace *ns);
void GetObjectMethodDescriptions(const char *name, asCObjectType *objectType, asCArray<int> &methods, bool objIsConst, const asCString &scope = "", asCScriptNode *errNode = 0, asCScriptCode *script = 0);
void EvaluateTemplateInstances(asUINT startIdx, bool keepSilent);
void CleanupEnumValues();
asCArray<asCScriptCode *> scripts;
asCArray<sFunctionDescription *> functions;
asCSymbolTable<sGlobalVariableDescription> globVariables;
asCArray<sClassDeclaration *> classDeclarations;
asCArray<sClassDeclaration *> interfaceDeclarations;
asCArray<sClassDeclaration *> namedTypeDeclarations;
asCArray<sFuncDef *> funcDefs;
asCArray<sMixinClass *> mixinClasses;
// For use with the DoesTypeExists() method
bool hasCachedKnownTypes;
asCMap<asCString, bool> knownTypes;
#endif
};
END_AS_NAMESPACE
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,205 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2018 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_bytecode.h
//
// A class for constructing the final byte code
//
#ifndef AS_BYTECODE_H
#define AS_BYTECODE_H
#include "as_config.h"
#ifndef AS_NO_COMPILER
#include "as_array.h"
BEGIN_AS_NAMESPACE
#define BYTECODE_SIZE 4
#define MAX_DATA_SIZE 8
#define MAX_INSTR_SIZE (BYTECODE_SIZE+MAX_DATA_SIZE)
class asCScriptEngine;
class asCScriptFunction;
class asCByteInstruction;
class asCByteCode
{
public:
asCByteCode(asCScriptEngine *engine);
~asCByteCode();
void ClearAll();
int GetSize();
void Finalize(const asCArray<int> &tempVariableOffsets);
void Optimize();
void OptimizeLocally(const asCArray<int> &tempVariableOffsets);
void ExtractLineNumbers();
void ExtractObjectVariableInfo(asCScriptFunction *outFunc);
void ExtractTryCatchInfo(asCScriptFunction *outFunc);
int ResolveJumpAddresses();
int FindLabel(int label, asCByteInstruction *from, asCByteInstruction **dest, int *positionDelta);
void AddPath(asCArray<asCByteInstruction *> &paths, asCByteInstruction *instr, int stackSize);
void Output(asDWORD *array);
void AddCode(asCByteCode *bc);
void PostProcess();
#ifdef AS_DEBUG
void DebugOutput(const char *name, asCScriptFunction *func);
#endif
int GetLastInstr();
int RemoveLastInstr();
asDWORD GetLastInstrValueDW();
void InsertIfNotExists(asCArray<int> &vars, int var);
void GetVarsUsed(asCArray<int> &vars);
bool IsVarUsed(int offset);
void ExchangeVar(int oldOffset, int newOffset);
bool IsSimpleExpression();
void Label(short label);
void Line(int line, int column, int scriptIdx);
void ObjInfo(int offset, int info);
void Block(bool start);
void TryBlock(short catchLabel);
void VarDecl(int varDeclIdx);
void Call(asEBCInstr bc, int funcID, int pop);
void CallPtr(asEBCInstr bc, int funcPtrVar, int pop);
void Alloc(asEBCInstr bc, void *objID, int funcID, int pop);
void Ret(int pop);
void JmpP(int var, asDWORD max);
int InsertFirstInstrDWORD(asEBCInstr bc, asDWORD param);
int InsertFirstInstrQWORD(asEBCInstr bc, asQWORD param);
int Instr(asEBCInstr bc);
int InstrQWORD(asEBCInstr bc, asQWORD param);
int InstrDOUBLE(asEBCInstr bc, double param);
int InstrPTR(asEBCInstr bc, void *param);
int InstrDWORD(asEBCInstr bc, asDWORD param);
int InstrWORD(asEBCInstr bc, asWORD param);
int InstrSHORT(asEBCInstr bc, short param);
int InstrFLOAT(asEBCInstr bc, float param);
int InstrINT(asEBCInstr bc, int param);
int InstrW_W_W(asEBCInstr bc, int a, int b, int c);
int InstrSHORT_B(asEBCInstr bc, short a, asBYTE b);
int InstrSHORT_W(asEBCInstr bc, short a, asWORD b);
int InstrSHORT_DW(asEBCInstr bc, short a, asDWORD b);
int InstrSHORT_QW(asEBCInstr bc, short a, asQWORD b);
int InstrW_DW(asEBCInstr bc, asWORD a, asDWORD b);
int InstrW_QW(asEBCInstr bc, asWORD a, asQWORD b);
int InstrW_PTR(asEBCInstr bc, short a, void *param);
int InstrW_FLOAT(asEBCInstr bc, asWORD a, float b);
int InstrW_W(asEBCInstr bc, int w, int b);
int InstrSHORT_DW_DW(asEBCInstr bc, short a, asDWORD b, asDWORD c);
asCScriptEngine *GetEngine() const { return engine; };
asCArray<int> lineNumbers;
asCArray<int> sectionIdxs;
int largestStackUsed;
protected:
// Assignments are not allowed
void operator=(const asCByteCode &) {}
// Helpers for Optimize
bool CanBeSwapped(asCByteInstruction *curr);
asCByteInstruction *ChangeFirstDeleteNext(asCByteInstruction *curr, asEBCInstr bc);
asCByteInstruction *DeleteFirstChangeNext(asCByteInstruction *curr, asEBCInstr bc);
asCByteInstruction *DeleteInstruction(asCByteInstruction *instr);
void RemoveInstruction(asCByteInstruction *instr);
asCByteInstruction *GoBack(asCByteInstruction *curr);
asCByteInstruction *GoForward(asCByteInstruction *curr);
void InsertBefore(asCByteInstruction *before, asCByteInstruction *instr);
bool RemoveUnusedValue(asCByteInstruction *curr, asCByteInstruction **next);
bool IsTemporary(int offset);
bool IsTempRegUsed(asCByteInstruction *curr);
bool IsTempVarRead(asCByteInstruction *curr, int offset);
bool PostponeInitOfTemp(asCByteInstruction *curr, asCByteInstruction **next);
bool IsTempVarReadByInstr(asCByteInstruction *curr, int var);
bool IsTempVarOverwrittenByInstr(asCByteInstruction *curr, int var);
bool IsInstrJmpOrLabel(asCByteInstruction *curr);
int AddInstruction();
int AddInstructionFirst();
asCByteInstruction *first;
asCByteInstruction *last;
const asCArray<int> *temporaryVariables;
asCScriptEngine *engine;
};
class asCByteInstruction
{
public:
asCByteInstruction();
void AddAfter(asCByteInstruction *nextCode);
void AddBefore(asCByteInstruction *nextCode);
void Remove();
int GetSize();
int GetStackIncrease();
asCByteInstruction *next;
asCByteInstruction *prev;
asEBCInstr op;
asQWORD arg;
short wArg[3];
int size;
int stackInc;
// Testing
bool marked;
int stackSize;
};
END_AS_NAMESPACE
#endif // AS_NO_COMPILER
#endif

View File

@@ -0,0 +1,921 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2020 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_callfunc.cpp
//
// These functions handle the actual calling of system functions
//
#include "as_config.h"
#include "as_callfunc.h"
#include "as_scriptengine.h"
#include "as_texts.h"
#include "as_context.h"
BEGIN_AS_NAMESPACE
// ref: Member Function Pointers and the Fastest Possible C++ Delegates
// describes the structure of class method pointers for most compilers
// http://www.codeproject.com/Articles/7150/Member-Function-Pointers-and-the-Fastest-Possible
// ref: The code comments for ItaniumCXXABI::EmitLoadOfMemberFunctionPointer in the LLVM compiler
// describes the structure for class method pointers on Itanium and arm64 ABI
// http://clang.llvm.org/doxygen/CodeGen_2ItaniumCXXABI_8cpp_source.html#l00937
int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv, void *auxiliary, asSSystemFunctionInterface *internal)
{
memset(internal, 0, sizeof(asSSystemFunctionInterface));
internal->func = ptr.ptr.f.func;
internal->auxiliary = 0;
// Was a compatible calling convention specified?
if( internal->func )
{
if( ptr.flag == 1 && callConv != asCALL_GENERIC )
return asWRONG_CALLING_CONV;
else if( ptr.flag == 2 && (callConv == asCALL_GENERIC || callConv == asCALL_THISCALL || callConv == asCALL_THISCALL_ASGLOBAL || callConv == asCALL_THISCALL_OBJFIRST || callConv == asCALL_THISCALL_OBJLAST) )
return asWRONG_CALLING_CONV;
else if( ptr.flag == 3 && !(callConv == asCALL_THISCALL || callConv == asCALL_THISCALL_ASGLOBAL || callConv == asCALL_THISCALL_OBJFIRST || callConv == asCALL_THISCALL_OBJLAST) )
return asWRONG_CALLING_CONV;
}
asDWORD base = callConv;
if( !isMethod )
{
if( base == asCALL_CDECL )
internal->callConv = ICC_CDECL;
else if( base == asCALL_STDCALL )
internal->callConv = ICC_STDCALL;
else if( base == asCALL_THISCALL_ASGLOBAL )
{
if(auxiliary == 0)
return asINVALID_ARG;
internal->auxiliary = auxiliary;
internal->callConv = ICC_THISCALL;
// This is really a thiscall, so it is necessary to check for virtual method pointers
base = asCALL_THISCALL;
isMethod = true;
}
else if (base == asCALL_GENERIC)
{
internal->callConv = ICC_GENERIC_FUNC;
// The auxiliary object is optional for generic calling convention
internal->auxiliary = auxiliary;
}
else
return asNOT_SUPPORTED;
}
if( isMethod )
{
#ifndef AS_NO_CLASS_METHODS
if( base == asCALL_THISCALL || base == asCALL_THISCALL_OBJFIRST || base == asCALL_THISCALL_OBJLAST )
{
internalCallConv thisCallConv;
if( base == asCALL_THISCALL )
{
if(callConv != asCALL_THISCALL_ASGLOBAL && auxiliary)
return asINVALID_ARG;
thisCallConv = ICC_THISCALL;
}
else
{
#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
return asNOT_SUPPORTED;
#else
if(auxiliary == 0)
return asINVALID_ARG;
internal->auxiliary = auxiliary;
if( base == asCALL_THISCALL_OBJFIRST )
thisCallConv = ICC_THISCALL_OBJFIRST;
else //if( base == asCALL_THISCALL_OBJLAST )
thisCallConv = ICC_THISCALL_OBJLAST;
#endif
}
internal->callConv = thisCallConv;
#ifdef GNU_STYLE_VIRTUAL_METHOD
if( (size_t(ptr.ptr.f.func) & 1) )
internal->callConv = (internalCallConv)(thisCallConv + 2);
#endif
internal->baseOffset = ( int )MULTI_BASE_OFFSET(ptr);
#if (defined(AS_ARM64) || defined(AS_ARM) || defined(AS_MIPS)) && (defined(__GNUC__) || defined(AS_PSVITA))
// As the least significant bit in func is used to switch to THUMB mode
// on ARM processors, the LSB in the __delta variable is used instead of
// the one in __pfn on ARM processors.
// MIPS also appear to use the base offset to indicate virtual method.
if( (size_t(internal->baseOffset) & 1) )
internal->callConv = (internalCallConv)(thisCallConv + 2);
#endif
#ifdef HAVE_VIRTUAL_BASE_OFFSET
// We don't support virtual inheritance
if( VIRTUAL_BASE_OFFSET(ptr) != 0 )
return asNOT_SUPPORTED;
#endif
}
else
#endif
if( base == asCALL_CDECL_OBJLAST )
internal->callConv = ICC_CDECL_OBJLAST;
else if( base == asCALL_CDECL_OBJFIRST )
internal->callConv = ICC_CDECL_OBJFIRST;
else if (base == asCALL_GENERIC)
{
internal->callConv = ICC_GENERIC_METHOD;
internal->auxiliary = auxiliary;
}
else
return asNOT_SUPPORTED;
}
return 0;
}
// This function should prepare system functions so that it will be faster to call them
int PrepareSystemFunctionGeneric(asCScriptFunction *func, asSSystemFunctionInterface *internal, asCScriptEngine *engine)
{
asASSERT(internal->callConv == ICC_GENERIC_METHOD || internal->callConv == ICC_GENERIC_FUNC);
// Calculate the size needed for the parameters
internal->paramSize = func->GetSpaceNeededForArguments();
// Prepare the clean up instructions for the function arguments
internal->cleanArgs.SetLength(0);
int offset = 0;
for( asUINT n = 0; n < func->parameterTypes.GetLength(); n++ )
{
asCDataType &dt = func->parameterTypes[n];
if( (dt.IsObject() || dt.IsFuncdef()) && !dt.IsReference() )
{
if (dt.IsFuncdef())
{
// If the generic call mode is set to old behaviour then always release handles
// else only release the handle if the function is declared with auto handles
if (engine->ep.genericCallMode == 0 || (internal->paramAutoHandles.GetLength() > n && internal->paramAutoHandles[n]))
{
asSSystemFunctionInterface::SClean clean;
clean.op = 0; // call release
clean.ot = &engine->functionBehaviours;
clean.off = short(offset);
internal->cleanArgs.PushLast(clean);
}
}
else if( dt.GetTypeInfo()->flags & asOBJ_REF )
{
// If the generic call mode is set to old behaviour then always release handles
// else only release the handle if the function is declared with auto handles
if (!dt.IsObjectHandle() ||
engine->ep.genericCallMode == 0 ||
(internal->paramAutoHandles.GetLength() > n && internal->paramAutoHandles[n]) )
{
asSTypeBehaviour *beh = &CastToObjectType(dt.GetTypeInfo())->beh;
asASSERT((dt.GetTypeInfo()->flags & asOBJ_NOCOUNT) || beh->release);
if (beh->release)
{
asSSystemFunctionInterface::SClean clean;
clean.op = 0; // call release
clean.ot = CastToObjectType(dt.GetTypeInfo());
clean.off = short(offset);
internal->cleanArgs.PushLast(clean);
}
}
}
else
{
asSSystemFunctionInterface::SClean clean;
clean.op = 1; // call free
clean.ot = CastToObjectType(dt.GetTypeInfo());
clean.off = short(offset);
// Call the destructor then free the memory
asSTypeBehaviour *beh = &CastToObjectType(dt.GetTypeInfo())->beh;
if( beh->destruct )
clean.op = 2; // call destruct, then free
internal->cleanArgs.PushLast(clean);
}
}
if( dt.IsObject() && !dt.IsObjectHandle() && !dt.IsReference() )
offset += AS_PTR_SIZE;
else
offset += dt.GetSizeOnStackDWords();
}
return 0;
}
// This function should prepare system functions so that it will be faster to call them
int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *internal, asCScriptEngine *engine)
{
#ifdef AS_MAX_PORTABILITY
UNUSED_VAR(func);
UNUSED_VAR(internal);
UNUSED_VAR(engine);
// This should never happen, as when AS_MAX_PORTABILITY is on, all functions
// are asCALL_GENERIC, which are prepared by PrepareSystemFunctionGeneric
asASSERT(false);
#else
// References are always returned as primitive data
if( func->returnType.IsReference() || func->returnType.IsObjectHandle() )
{
internal->hostReturnInMemory = false;
internal->hostReturnSize = sizeof(void*)/4;
internal->hostReturnFloat = false;
}
// Registered types have special flags that determine how they are returned
else if( func->returnType.IsObject() )
{
asDWORD objType = func->returnType.GetTypeInfo()->flags;
// Only value types can be returned by value
asASSERT( objType & asOBJ_VALUE );
if( !(objType & (asOBJ_APP_CLASS | asOBJ_APP_PRIMITIVE | asOBJ_APP_FLOAT | asOBJ_APP_ARRAY)) )
{
// If the return is by value then we need to know the true type
engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, func->GetDeclarationStr().AddressOf());
asCString str;
str.Format(TXT_CANNOT_RET_TYPE_s_BY_VAL, func->returnType.GetTypeInfo()->name.AddressOf());
engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
engine->ConfigError(asINVALID_CONFIGURATION, 0, 0, 0);
}
else if( objType & asOBJ_APP_ARRAY )
{
// Array types are always returned in memory
internal->hostReturnInMemory = true;
internal->hostReturnSize = sizeof(void*)/4;
internal->hostReturnFloat = false;
}
else if( objType & asOBJ_APP_CLASS )
{
internal->hostReturnFloat = false;
if( objType & COMPLEX_RETURN_MASK )
{
internal->hostReturnInMemory = true;
internal->hostReturnSize = sizeof(void*)/4;
}
else
{
#ifdef HAS_128_BIT_PRIMITIVES
if( func->returnType.GetSizeInMemoryDWords() > 4 )
#else
if( func->returnType.GetSizeInMemoryDWords() > 2 )
#endif
{
internal->hostReturnInMemory = true;
internal->hostReturnSize = sizeof(void*)/4;
}
else
{
internal->hostReturnInMemory = false;
internal->hostReturnSize = func->returnType.GetSizeInMemoryDWords();
#ifdef SPLIT_OBJS_BY_MEMBER_TYPES
if( func->returnType.GetTypeInfo()->flags & asOBJ_APP_CLASS_ALLFLOATS )
internal->hostReturnFloat = true;
#endif
}
#ifdef THISCALL_RETURN_SIMPLE_IN_MEMORY
if((internal->callConv == ICC_THISCALL ||
#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
internal->callConv == ICC_VIRTUAL_THISCALL) &&
#else
internal->callConv == ICC_VIRTUAL_THISCALL ||
internal->callConv == ICC_THISCALL_OBJFIRST ||
internal->callConv == ICC_THISCALL_OBJLAST) &&
#endif
func->returnType.GetSizeInMemoryDWords() >= THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE)
{
internal->hostReturnInMemory = true;
internal->hostReturnSize = sizeof(void*)/4;
}
#endif
#ifdef CDECL_RETURN_SIMPLE_IN_MEMORY
if((internal->callConv == ICC_CDECL ||
internal->callConv == ICC_CDECL_OBJLAST ||
internal->callConv == ICC_CDECL_OBJFIRST) &&
func->returnType.GetSizeInMemoryDWords() >= CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE)
{
internal->hostReturnInMemory = true;
internal->hostReturnSize = sizeof(void*)/4;
}
#endif
#ifdef STDCALL_RETURN_SIMPLE_IN_MEMORY
if( internal->callConv == ICC_STDCALL &&
func->returnType.GetSizeInMemoryDWords() >= STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE)
{
internal->hostReturnInMemory = true;
internal->hostReturnSize = sizeof(void*)/4;
}
#endif
}
#ifdef SPLIT_OBJS_BY_MEMBER_TYPES
// It's not safe to return objects by value because different registers
// will be used depending on the memory layout of the object.
// Ref: http://www.x86-64.org/documentation/abi.pdf
// Ref: http://www.agner.org/optimize/calling_conventions.pdf
// If the application informs that the class should be treated as all integers, then we allow it
if( !internal->hostReturnInMemory &&
!(func->returnType.GetTypeInfo()->flags & (asOBJ_APP_CLASS_ALLINTS | asOBJ_APP_CLASS_ALLFLOATS)) )
{
engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, func->GetDeclarationStr().AddressOf());
asCString str;
str.Format(TXT_DONT_SUPPORT_RET_TYPE_s_BY_VAL, func->returnType.Format(func->nameSpace).AddressOf());
engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
engine->ConfigError(asINVALID_CONFIGURATION, 0, 0, 0);
}
#endif
}
else if( objType & asOBJ_APP_PRIMITIVE )
{
internal->hostReturnInMemory = false;
internal->hostReturnSize = func->returnType.GetSizeInMemoryDWords();
internal->hostReturnFloat = false;
}
else if( objType & asOBJ_APP_FLOAT )
{
internal->hostReturnInMemory = false;
internal->hostReturnSize = func->returnType.GetSizeInMemoryDWords();
internal->hostReturnFloat = true;
}
}
// Primitive types can easily be determined
#ifdef HAS_128_BIT_PRIMITIVES
else if( func->returnType.GetSizeInMemoryDWords() > 4 )
{
// Shouldn't be possible to get here
asASSERT(false);
}
else if( func->returnType.GetSizeInMemoryDWords() == 4 )
{
internal->hostReturnInMemory = false;
internal->hostReturnSize = 4;
internal->hostReturnFloat = false;
}
#else
else if( func->returnType.GetSizeInMemoryDWords() > 2 )
{
// Shouldn't be possible to get here
asASSERT(false);
}
#endif
else if( func->returnType.GetSizeInMemoryDWords() == 2 )
{
internal->hostReturnInMemory = false;
internal->hostReturnSize = 2;
internal->hostReturnFloat = func->returnType.IsEqualExceptConst(asCDataType::CreatePrimitive(ttDouble, true));
}
else if( func->returnType.GetSizeInMemoryDWords() == 1 )
{
internal->hostReturnInMemory = false;
internal->hostReturnSize = 1;
internal->hostReturnFloat = func->returnType.IsEqualExceptConst(asCDataType::CreatePrimitive(ttFloat, true));
}
else
{
internal->hostReturnInMemory = false;
internal->hostReturnSize = 0;
internal->hostReturnFloat = false;
}
// Calculate the size needed for the parameters
internal->paramSize = func->GetSpaceNeededForArguments();
// Verify if the function takes any objects by value
asUINT n;
internal->takesObjByVal = false;
for( n = 0; n < func->parameterTypes.GetLength(); n++ )
{
if( func->parameterTypes[n].IsObject() && !func->parameterTypes[n].IsObjectHandle() && !func->parameterTypes[n].IsReference() )
{
internal->takesObjByVal = true;
// Can't pass objects by value unless the application type is informed
if( !(func->parameterTypes[n].GetTypeInfo()->flags & (asOBJ_APP_CLASS | asOBJ_APP_PRIMITIVE | asOBJ_APP_FLOAT | asOBJ_APP_ARRAY)) )
{
engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, func->GetDeclarationStr().AddressOf());
asCString str;
str.Format(TXT_CANNOT_PASS_TYPE_s_BY_VAL, func->parameterTypes[n].GetTypeInfo()->name.AddressOf());
engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
engine->ConfigError(asINVALID_CONFIGURATION, 0, 0, 0);
}
#ifdef SPLIT_OBJS_BY_MEMBER_TYPES
// It's not safe to pass objects by value because different registers
// will be used depending on the memory layout of the object
// Ref: http://www.x86-64.org/documentation/abi.pdf
// Ref: http://www.agner.org/optimize/calling_conventions.pdf
if(
#ifdef COMPLEX_OBJS_PASSED_BY_REF
!(func->parameterTypes[n].GetTypeInfo()->flags & COMPLEX_MASK) &&
#endif
#ifdef LARGE_OBJS_PASS_BY_REF
func->parameterTypes[n].GetSizeInMemoryDWords() < AS_LARGE_OBJ_MIN_SIZE &&
#endif
!(func->parameterTypes[n].GetTypeInfo()->flags & (asOBJ_APP_PRIMITIVE | asOBJ_APP_FLOAT | asOBJ_APP_CLASS_ALLINTS | asOBJ_APP_CLASS_ALLFLOATS)) )
{
engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, func->GetDeclarationStr().AddressOf());
asCString str;
str.Format(TXT_DONT_SUPPORT_TYPE_s_BY_VAL, func->parameterTypes[n].GetTypeInfo()->name.AddressOf());
engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
engine->ConfigError(asINVALID_CONFIGURATION, 0, 0, 0);
}
#endif
break;
}
}
// Prepare the clean up instructions for the function arguments
internal->cleanArgs.SetLength(0);
int offset = 0;
for( n = 0; n < func->parameterTypes.GetLength(); n++ )
{
asCDataType &dt = func->parameterTypes[n];
#if defined(COMPLEX_OBJS_PASSED_BY_REF) || defined(AS_LARGE_OBJS_PASSED_BY_REF)
bool needFree = false;
#ifdef COMPLEX_OBJS_PASSED_BY_REF
if( dt.GetTypeInfo() && dt.GetTypeInfo()->flags & COMPLEX_MASK ) needFree = true;
#endif
#ifdef AS_LARGE_OBJS_PASSED_BY_REF
if( dt.GetSizeInMemoryDWords() >= AS_LARGE_OBJ_MIN_SIZE ) needFree = true;
#endif
if( needFree &&
dt.IsObject() &&
!dt.IsObjectHandle() &&
!dt.IsReference() )
{
asSSystemFunctionInterface::SClean clean;
clean.op = 1; // call free
clean.ot = CastToObjectType(dt.GetTypeInfo());
clean.off = short(offset);
#ifndef AS_CALLEE_DESTROY_OBJ_BY_VAL
// If the called function doesn't destroy objects passed by value we must do so here
asSTypeBehaviour *beh = &CastToObjectType(dt.GetTypeInfo())->beh;
if( beh->destruct )
clean.op = 2; // call destruct, then free
#endif
internal->cleanArgs.PushLast(clean);
}
#endif
if( n < internal->paramAutoHandles.GetLength() && internal->paramAutoHandles[n] )
{
asSSystemFunctionInterface::SClean clean;
clean.op = 0; // call release
if (dt.IsFuncdef())
clean.ot = &engine->functionBehaviours;
else
clean.ot = CastToObjectType(dt.GetTypeInfo());
clean.off = short(offset);
internal->cleanArgs.PushLast(clean);
}
if( dt.IsObject() && !dt.IsObjectHandle() && !dt.IsReference() )
offset += AS_PTR_SIZE;
else
offset += dt.GetSizeOnStackDWords();
}
#endif // !defined(AS_MAX_PORTABILITY)
return 0;
}
#ifdef AS_MAX_PORTABILITY
int CallSystemFunction(int id, asCContext *context)
{
asCScriptEngine *engine = context->m_engine;
asCScriptFunction *func = engine->scriptFunctions[id];
asSSystemFunctionInterface *sysFunc = func->sysFuncIntf;
int callConv = sysFunc->callConv;
if( callConv == ICC_GENERIC_FUNC || callConv == ICC_GENERIC_METHOD )
return context->CallGeneric(func);
context->SetInternalException(TXT_INVALID_CALLING_CONVENTION);
return 0;
}
#else
//
// CallSystemFunctionNative
//
// This function is implemented for each platform where the native calling conventions is supported.
// See the various as_callfunc_xxx.cpp files for their implementation. It is responsible for preparing
// the arguments for the function call, calling the function, and then retrieving the return value.
//
// Parameters:
//
// context - This is the context that can be used to retrieve specific information from the engine
// descr - This is the script function object that holds the information on how to call the function
// obj - This is the object pointer, if the call is for a class method, otherwise it is null
// args - This is the function arguments, which are packed as in AngelScript
// retPointer - This points to a the memory buffer where the return object is to be placed, if the function returns the value in memory rather than in registers
// retQW2 - This output parameter should be used if the function returns a value larger than 64bits in registers
// secondObj - This is the object pointer that the proxy method should invoke its method on when the call convention is THISCALL_OBJFIRST/LAST
//
// Return value:
//
// The function should return the value that is returned in registers.
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &retQW2, void *secondObj);
int CallSystemFunction(int id, asCContext *context)
{
asCScriptEngine *engine = context->m_engine;
asCScriptFunction *descr = engine->scriptFunctions[id];
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
int callConv = sysFunc->callConv;
if( callConv == ICC_GENERIC_FUNC || callConv == ICC_GENERIC_METHOD )
return context->CallGeneric(descr);
asQWORD retQW = 0;
asQWORD retQW2 = 0;
asDWORD *args = context->m_regs.stackPointer;
void *retPointer = 0;
int popSize = sysFunc->paramSize;
// TODO: clean-up: CallSystemFunctionNative should have two arguments for object pointers
// objForThiscall is the object pointer that should be used for the thiscall
// objForArg is the object pointer that should be passed as argument when using OBJFIRST or OBJLAST
// Used to save two object pointers with THISCALL_OBJLAST or THISCALL_OBJFIRST
void *obj = 0;
void *secondObj = 0;
#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
if( callConv >= ICC_THISCALL )
{
if(sysFunc->auxiliary)
{
// This class method is being called as if it is a global function
obj = sysFunc->auxiliary;
}
else
{
// The object pointer should be popped from the context stack
popSize += AS_PTR_SIZE;
// Check for null pointer
obj = (void*)*(asPWORD*)(args);
if( obj == 0 )
{
context->SetInternalException(TXT_NULL_POINTER_ACCESS);
return 0;
}
// Skip the object pointer
args += AS_PTR_SIZE;
}
// Add the base offset for multiple inheritance
#if (defined(__GNUC__) && (defined(AS_ARM64) || defined(AS_ARM) || defined(AS_MIPS))) || defined(AS_PSVITA)
// On GNUC + ARM the lsb of the offset is used to indicate a virtual function
// and the whole offset is thus shifted one bit left to keep the original
// offset resolution
// MIPS also work like ARM in this regard
obj = (void*)(asPWORD(obj) + (sysFunc->baseOffset>>1));
#else
obj = (void*)(asPWORD(obj) + sysFunc->baseOffset);
#endif
}
#else // !defined(AS_NO_THISCALL_FUNCTOR_METHOD)
if( callConv >= ICC_THISCALL )
{
bool continueCheck = true; // True if need check objectPointer or context stack for object
int continueCheckIndex = 0; // Index into objectsPtrs to save the object if continueCheck
if( callConv >= ICC_THISCALL_OBJLAST )
{
asASSERT( sysFunc->auxiliary != 0 );
// This class method is being called as object method (sysFunc->auxiliary must be set).
obj = sysFunc->auxiliary;
continueCheckIndex = 1;
}
else if(sysFunc->auxiliary)
{
// This class method is being called as if it is a global function
obj = sysFunc->auxiliary;
continueCheck = false;
}
if( obj )
{
// Add the base offset for multiple inheritance
#if (defined(__GNUC__) && (defined(AS_ARM64) || defined(AS_ARM) || defined(AS_MIPS))) || defined(AS_PSVITA)
// On GNUC + ARM the lsb of the offset is used to indicate a virtual function
// and the whole offset is thus shifted one bit left to keep the original
// offset resolution
// MIPS also work like ARM in this regard
obj = (void*)(asPWORD(obj) + (sysFunc->baseOffset>>1));
#else
obj = (void*)(asPWORD(obj) + sysFunc->baseOffset);
#endif
}
if( continueCheck )
{
void *tempPtr = 0;
// The object pointer should be popped from the context stack
popSize += AS_PTR_SIZE;
// Check for null pointer
tempPtr = (void*)*(asPWORD*)(args);
if( tempPtr == 0 )
{
context->SetInternalException(TXT_NULL_POINTER_ACCESS);
return 0;
}
// Add the base offset for multiple inheritance
#if (defined(__GNUC__) && (defined(AS_ARM64) || defined(AS_ARM) || defined(AS_MIPS))) || defined(AS_PSVITA)
// On GNUC + ARM the lsb of the offset is used to indicate a virtual function
// and the whole offset is thus shifted one bit left to keep the original
// offset resolution
// MIPS also work like ARM in this regard
tempPtr = (void*)(asPWORD(tempPtr) + (sysFunc->baseOffset>>1));
#else
tempPtr = (void*)(asPWORD(tempPtr) + sysFunc->baseOffset);
#endif
// Skip the object pointer
args += AS_PTR_SIZE;
if( continueCheckIndex )
secondObj = tempPtr;
else
{
asASSERT( obj == 0 );
obj = tempPtr;
}
}
}
#endif // AS_NO_THISCALL_FUNCTOR_METHOD
if( descr->DoesReturnOnStack() )
{
// Get the address of the location for the return value from the stack
retPointer = (void*)*(asPWORD*)(args);
popSize += AS_PTR_SIZE;
args += AS_PTR_SIZE;
// When returning the value on the location allocated by the called
// we shouldn't set the object type in the register
context->m_regs.objectType = 0;
}
else
{
// Set the object type of the reference held in the register
context->m_regs.objectType = descr->returnType.GetTypeInfo();
}
// For composition we need to add the offset and/or dereference the pointer
if(obj)
{
obj = (void*) ((char*) obj + sysFunc->compositeOffset);
if(sysFunc->isCompositeIndirect) obj = *((void**)obj);
}
context->m_callingSystemFunction = descr;
bool cppException = false;
#ifdef AS_NO_EXCEPTIONS
retQW = CallSystemFunctionNative(context, descr, obj, args, sysFunc->hostReturnInMemory ? retPointer : 0, retQW2, secondObj);
#else
// This try/catch block is to catch potential exception that may
// be thrown by the registered function. The implementation of the
// CallSystemFunctionNative() must make sure not to have any manual
// clean-up after the call to the real function, or that won't be
// executed in case of an exception.
try
{
retQW = CallSystemFunctionNative(context, descr, obj, args, sysFunc->hostReturnInMemory ? retPointer : 0, retQW2, secondObj);
}
catch(...)
{
cppException = true;
// Convert the exception to a script exception so the VM can
// properly report the error to the application and then clean up
context->HandleAppException();
}
#endif
context->m_callingSystemFunction = 0;
// Store the returned value in our stack
if( (descr->returnType.IsObject() || descr->returnType.IsFuncdef()) && !descr->returnType.IsReference() )
{
if( descr->returnType.IsObjectHandle() )
{
#if defined(AS_BIG_ENDIAN) && AS_PTR_SIZE == 1
// Since we're treating the system function as if it is returning a QWORD we are
// actually receiving the value in the high DWORD of retQW.
retQW >>= 32;
#endif
context->m_regs.objectRegister = (void*)(asPWORD)retQW;
if( sysFunc->returnAutoHandle && context->m_regs.objectRegister )
{
asASSERT( !(descr->returnType.GetTypeInfo()->flags & asOBJ_NOCOUNT) );
engine->CallObjectMethod(context->m_regs.objectRegister, CastToObjectType(descr->returnType.GetTypeInfo())->beh.addref);
}
}
else
{
asASSERT( retPointer );
if( !sysFunc->hostReturnInMemory )
{
// Copy the returned value to the pointer sent by the script engine
if( sysFunc->hostReturnSize == 1 )
{
#if defined(AS_BIG_ENDIAN) && AS_PTR_SIZE == 1
// Since we're treating the system function as if it is returning a QWORD we are
// actually receiving the value in the high DWORD of retQW.
retQW >>= 32;
#endif
*(asDWORD*)retPointer = (asDWORD)retQW;
}
else if( sysFunc->hostReturnSize == 2 )
*(asQWORD*)retPointer = retQW;
else if( sysFunc->hostReturnSize == 3 )
{
*(asQWORD*)retPointer = retQW;
*(((asDWORD*)retPointer) + 2) = (asDWORD)retQW2;
}
else // if( sysFunc->hostReturnSize == 4 )
{
*(asQWORD*)retPointer = retQW;
*(((asQWORD*)retPointer) + 1) = retQW2;
}
}
if( context->m_status == asEXECUTION_EXCEPTION && !cppException )
{
// If the function raised a script exception it really shouldn't have
// initialized the object. However, as it is a soft exception there is
// no way for the application to not return a value, so instead we simply
// destroy it here, to pretend it was never created.
if(CastToObjectType(descr->returnType.GetTypeInfo())->beh.destruct )
engine->CallObjectMethod(retPointer, CastToObjectType(descr->returnType.GetTypeInfo())->beh.destruct);
}
}
}
else
{
// Store value in value register
if( sysFunc->hostReturnSize == 1 )
{
#if defined(AS_BIG_ENDIAN)
// Since we're treating the system function as if it is returning a QWORD we are
// actually receiving the value in the high DWORD of retQW.
retQW >>= 32;
// Due to endian issues we need to handle return values that are
// less than a DWORD (32 bits) in size specially
int numBytes = descr->returnType.GetSizeInMemoryBytes();
if( descr->returnType.IsReference() ) numBytes = 4;
switch( numBytes )
{
case 1:
{
// 8 bits
asBYTE *val = (asBYTE*)&context->m_regs.valueRegister;
val[0] = (asBYTE)retQW;
val[1] = 0;
val[2] = 0;
val[3] = 0;
val[4] = 0;
val[5] = 0;
val[6] = 0;
val[7] = 0;
}
break;
case 2:
{
// 16 bits
asWORD *val = (asWORD*)&context->m_regs.valueRegister;
val[0] = (asWORD)retQW;
val[1] = 0;
val[2] = 0;
val[3] = 0;
}
break;
default:
{
// 32 bits
asDWORD *val = (asDWORD*)&context->m_regs.valueRegister;
val[0] = (asDWORD)retQW;
val[1] = 0;
}
break;
}
#else
*(asDWORD*)&context->m_regs.valueRegister = (asDWORD)retQW;
#endif
}
else
context->m_regs.valueRegister = retQW;
}
// Clean up arguments
const asUINT cleanCount = sysFunc->cleanArgs.GetLength();
if( cleanCount )
{
args = context->m_regs.stackPointer;
// Skip the hidden argument for the return pointer
// TODO: runtime optimize: This check and increment should have been done in PrepareSystemFunction
if( descr->DoesReturnOnStack() )
args += AS_PTR_SIZE;
// Skip the object pointer on the stack
// TODO: runtime optimize: This check and increment should have been done in PrepareSystemFunction
if( callConv >= ICC_THISCALL && sysFunc->auxiliary == 0 )
args += AS_PTR_SIZE;
asSSystemFunctionInterface::SClean *clean = sysFunc->cleanArgs.AddressOf();
for( asUINT n = 0; n < cleanCount; n++, clean++ )
{
void **addr = (void**)&args[clean->off];
if( clean->op == 0 )
{
if( *addr != 0 )
{
engine->CallObjectMethod(*addr, clean->ot->beh.release);
*addr = 0;
}
}
else
{
asASSERT( clean->op == 1 || clean->op == 2 );
asASSERT( *addr );
if( clean->op == 2 )
engine->CallObjectMethod(*addr, clean->ot->beh.destruct);
engine->CallFree(*addr);
}
}
}
return popSize;
}
#endif // AS_MAX_PORTABILITY
END_AS_NAMESPACE

View File

@@ -0,0 +1,152 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2020 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_callfunc.h
//
// These functions handle the actual calling of system functions
//
#ifndef AS_CALLFUNC_H
#define AS_CALLFUNC_H
#include "as_array.h"
BEGIN_AS_NAMESPACE
class asCContext;
class asCScriptEngine;
class asCScriptFunction;
class asCObjectType;
struct asSSystemFunctionInterface;
int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv, void *auxiliary, asSSystemFunctionInterface *internal);
int PrepareSystemFunctionGeneric(asCScriptFunction *func, asSSystemFunctionInterface *internal, asCScriptEngine *engine);
int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *internal, asCScriptEngine *engine);
int CallSystemFunction(int id, asCContext *context);
inline asPWORD FuncPtrToUInt(asFUNCTION_t func)
{
// A little trickery as the C++ standard doesn't allow direct
// conversion between function pointer and data pointer
union { asFUNCTION_t func; asPWORD idx; } u;
u.func = func;
return u.idx;
}
enum internalCallConv
{
ICC_GENERIC_FUNC,
ICC_GENERIC_FUNC_RETURNINMEM, // never used
ICC_CDECL,
ICC_CDECL_RETURNINMEM,
ICC_STDCALL,
ICC_STDCALL_RETURNINMEM,
ICC_THISCALL,
ICC_THISCALL_RETURNINMEM,
ICC_VIRTUAL_THISCALL,
ICC_VIRTUAL_THISCALL_RETURNINMEM,
ICC_CDECL_OBJLAST,
ICC_CDECL_OBJLAST_RETURNINMEM,
ICC_CDECL_OBJFIRST,
ICC_CDECL_OBJFIRST_RETURNINMEM,
ICC_GENERIC_METHOD,
ICC_GENERIC_METHOD_RETURNINMEM, // never used
ICC_THISCALL_OBJLAST,
ICC_THISCALL_OBJLAST_RETURNINMEM,
ICC_VIRTUAL_THISCALL_OBJLAST,
ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM,
ICC_THISCALL_OBJFIRST,
ICC_THISCALL_OBJFIRST_RETURNINMEM,
ICC_VIRTUAL_THISCALL_OBJFIRST,
ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM
};
struct asSSystemFunctionInterface
{
asFUNCTION_t func;
int baseOffset;
internalCallConv callConv;
bool hostReturnInMemory;
bool hostReturnFloat;
int hostReturnSize;
int paramSize;
bool takesObjByVal;
asCArray<bool> paramAutoHandles; // TODO: Should be able to remove this array. Perhaps the flags can be stored together with the inOutFlags in asCScriptFunction?
bool returnAutoHandle;
int compositeOffset;
bool isCompositeIndirect;
void *auxiliary; // can be used for functors, e.g. by asCALL_THISCALL_ASGLOBAL or asCALL_THISCALL_OBJFIRST
struct SClean
{
asCObjectType *ot; // argument type for clean up
short op; // clean up operation: 0 = release, 1 = free, 2 = destruct then free
short off; // argument offset on the stack
};
asCArray<SClean> cleanArgs;
asSSystemFunctionInterface() : func(0), baseOffset(0), callConv(ICC_GENERIC_FUNC), hostReturnInMemory(false), hostReturnFloat(false), hostReturnSize(0), paramSize(0), takesObjByVal(false), returnAutoHandle(false), compositeOffset(0), isCompositeIndirect(false), auxiliary(0) {}
asSSystemFunctionInterface(const asSSystemFunctionInterface &in)
{
*this = in;
}
asSSystemFunctionInterface &operator=(const asSSystemFunctionInterface &in)
{
func = in.func;
baseOffset = in.baseOffset;
callConv = in.callConv;
hostReturnInMemory = in.hostReturnInMemory;
hostReturnFloat = in.hostReturnFloat;
hostReturnSize = in.hostReturnSize;
paramSize = in.paramSize;
takesObjByVal = in.takesObjByVal;
paramAutoHandles = in.paramAutoHandles;
returnAutoHandle = in.returnAutoHandle;
compositeOffset = in.compositeOffset;
isCompositeIndirect = in.isCompositeIndirect;
auxiliary = in.auxiliary;
cleanArgs = in.cleanArgs;
return *this;
}
};
END_AS_NAMESPACE
#endif

View File

@@ -0,0 +1,665 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_callfunc_arm.cpp
//
// These functions handle the actual calling of system functions on the arm platform
//
// Written by Fredrik Ehnbom in June 2009, based on as_callfunc_x86.cpp
//
// The code was complemented to support Linux with ARM by Carlos Luna in December, 2012.
//
// Added support for functor methods by Jordi Oliveras Rovira in April, 2014.
// This code has to conform to both AAPCS and the modified ABI for iOS
//
// Reference:
//
// AAPCS: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf
// iOS: http://developer.apple.com/library/ios/documentation/Xcode/Conceptual/iPhoneOSABIReference/iPhoneOSABIReference.pdf
#include "as_config.h"
#ifndef AS_MAX_PORTABILITY
#ifdef AS_ARM
#include "as_callfunc.h"
#include "as_scriptengine.h"
#include "as_texts.h"
#include "as_tokendef.h"
#include "as_context.h"
#if defined(AS_SOFTFP)
// This code supports the soft-float ABI, i.e. g++ -mfloat-abi=softfp
//
// The code for iOS, Android, Marmalade and Windows Phone goes here
BEGIN_AS_NAMESPACE
extern "C" asQWORD armFunc (const asDWORD *, int, asFUNCTION_t);
extern "C" asQWORD armFuncR0 (const asDWORD *, int, asFUNCTION_t, asDWORD r0);
extern "C" asQWORD armFuncR0R1 (const asDWORD *, int, asFUNCTION_t, asDWORD r0, asDWORD r1);
extern "C" asQWORD armFuncObjLast (const asDWORD *, int, asFUNCTION_t, asDWORD obj);
extern "C" asQWORD armFuncR0ObjLast (const asDWORD *, int, asFUNCTION_t, asDWORD r0, asDWORD obj);
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void *secondObject)
{
asCScriptEngine *engine = context->m_engine;
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
int callConv = sysFunc->callConv;
asQWORD retQW = 0;
asFUNCTION_t func = sysFunc->func;
int paramSize = sysFunc->paramSize;
asFUNCTION_t *vftable;
if( sysFunc->hostReturnInMemory )
{
// The return is made in memory
callConv++;
}
bool isThisCallMethod = callConv >= ICC_THISCALL_OBJLAST;
asDWORD paramBuffer[64+2];
// Android & Linux needs to align 64bit types on even registers, but this isn't done on iOS or Windows Phone
// TODO: optimize runtime: There should be a check for this in PrepareSystemFunction() so this
// doesn't have to be done for functions that don't have any 64bit types
#if !defined(AS_ANDROID) && !defined(AS_LINUX)
// In cases of thiscall methods, the callstack is configured as a standard thiscall
// adding the secondObject as first or last element in callstack
if( sysFunc->takesObjByVal || isThisCallMethod )
#endif
{
#if defined(AS_ANDROID) || defined(AS_LINUX)
// mask is used as a toggler to skip uneven registers.
int mask = 1;
if( isThisCallMethod )
{
mask = 0;
}
else
{
// Check for object pointer as first argument
switch( callConv )
{
case ICC_THISCALL:
case ICC_CDECL_OBJFIRST:
case ICC_VIRTUAL_THISCALL:
case ICC_THISCALL_RETURNINMEM:
case ICC_CDECL_OBJFIRST_RETURNINMEM:
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
mask = 0;
break;
default:
break;
}
}
// Check for hidden address in case of return by value
if( sysFunc->hostReturnInMemory )
mask = !mask;
#endif
paramSize = 0;
int spos = 0;
int dpos = 2;
if( isThisCallMethod && (callConv >= ICC_THISCALL_OBJFIRST &&
callConv <= ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM) )
{
// Add the object pointer as the first parameter
paramBuffer[dpos++] = (asDWORD)secondObject;
paramSize++;
}
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
{
// TODO: runtime optimize: Declare a reference to descr->parameterTypes[n] so the array doesn't have to be access all the time
if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
{
#ifdef COMPLEX_OBJS_PASSED_BY_REF
if( descr->parameterTypes[n].GetTypeInfo()->flags & COMPLEX_MASK )
{
paramBuffer[dpos++] = args[spos++];
paramSize++;
}
else
#endif
{
#if defined(AS_ANDROID) || defined(AS_LINUX)
if( (descr->parameterTypes[n].GetTypeInfo()->flags & asOBJ_APP_CLASS_ALIGN8) &&
((dpos & 1) == mask) )
{
// 64 bit value align
dpos++;
paramSize++;
}
#endif
// Copy the object's memory to the buffer
memcpy(&paramBuffer[dpos], *(void**)(args+spos), descr->parameterTypes[n].GetSizeInMemoryBytes());
// Delete the original memory
engine->CallFree(*(char**)(args+spos));
spos++;
dpos += descr->parameterTypes[n].GetSizeInMemoryDWords();
paramSize += descr->parameterTypes[n].GetSizeInMemoryDWords();
}
}
else
{
#if defined(AS_ANDROID) || defined(AS_LINUX)
// Should an alignment be performed?
if( !descr->parameterTypes[n].IsObjectHandle() &&
!descr->parameterTypes[n].IsReference() &&
descr->parameterTypes[n].GetSizeOnStackDWords() == 2 &&
((dpos & 1) == mask) )
{
// 64 bit value align
dpos++;
paramSize++;
}
#endif
// Copy the value directly
paramBuffer[dpos++] = args[spos++];
if( descr->parameterTypes[n].GetSizeOnStackDWords() > 1 )
paramBuffer[dpos++] = args[spos++];
paramSize += descr->parameterTypes[n].GetSizeOnStackDWords();
}
}
if( isThisCallMethod && (callConv >= ICC_THISCALL_OBJLAST &&
callConv <= ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM) )
{
// Add the object pointer as the last parameter
paramBuffer[dpos++] = (asDWORD)secondObject;
paramSize++;
}
// Keep a free location at the beginning
args = &paramBuffer[2];
}
switch( callConv )
{
case ICC_CDECL_RETURNINMEM: // fall through
case ICC_STDCALL_RETURNINMEM:
retQW = armFuncR0(args, paramSize<<2, func, (asDWORD)retPointer);
break;
case ICC_CDECL: // fall through
case ICC_STDCALL:
retQW = armFunc(args, paramSize<<2, func);
break;
case ICC_THISCALL: // fall through
case ICC_CDECL_OBJFIRST:
case ICC_THISCALL_OBJFIRST:
case ICC_THISCALL_OBJLAST:
retQW = armFuncR0(args, paramSize<<2, func, (asDWORD)obj);
break;
case ICC_THISCALL_RETURNINMEM:
case ICC_THISCALL_OBJFIRST_RETURNINMEM:
case ICC_THISCALL_OBJLAST_RETURNINMEM:
#ifdef __GNUC__
// On GNUC the address where the return value will be placed should be put in R0
retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
#else
// On Windows the R0 should always hold the object pointer, and the address for the return value comes after
retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)obj, (asDWORD)retPointer);
#endif
break;
case ICC_CDECL_OBJFIRST_RETURNINMEM:
retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
break;
case ICC_VIRTUAL_THISCALL:
case ICC_VIRTUAL_THISCALL_OBJFIRST:
case ICC_VIRTUAL_THISCALL_OBJLAST:
// Get virtual function table from the object pointer
vftable = *(asFUNCTION_t**)obj;
retQW = armFuncR0(args, paramSize<<2, vftable[FuncPtrToUInt(func)>>2], (asDWORD)obj);
break;
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
case ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM:
case ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM:
// Get virtual function table from the object pointer
vftable = *(asFUNCTION_t**)obj;
#ifdef __GNUC__
// On GNUC the address where the return value will be placed should be put in R0
retQW = armFuncR0R1(args, (paramSize+1)<<2, vftable[FuncPtrToUInt(func)>>2], (asDWORD)retPointer, (asDWORD)obj);
#else
// On Windows the R0 should always hold the object pointer, and the address for the return value comes after
retQW = armFuncR0R1(args, (paramSize+1)<<2, vftable[FuncPtrToUInt(func)>>2], (asDWORD)obj, (asDWORD)retPointer);
#endif
break;
case ICC_CDECL_OBJLAST:
retQW = armFuncObjLast(args, paramSize<<2, func, (asDWORD)obj);
break;
case ICC_CDECL_OBJLAST_RETURNINMEM:
retQW = armFuncR0ObjLast(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
break;
default:
context->SetInternalException(TXT_INVALID_CALLING_CONVENTION);
}
return retQW;
}
END_AS_NAMESPACE
#elif !defined(AS_SOFTFP)
// This code supports the hard-float ABI, i.e. g++ -mfloat-abi=hard
// The main difference is that the floating point values are passed in the fpu registers
#define VFP_OFFSET 70
#define STACK_OFFSET 6
#define PARAM_BUFFER_SIZE 104
BEGIN_AS_NAMESPACE
extern "C" asQWORD armFunc (const asDWORD *, int, asFUNCTION_t);
extern "C" asQWORD armFuncR0 (const asDWORD *, int, asFUNCTION_t, asDWORD r0);
extern "C" asQWORD armFuncR0R1 (const asDWORD *, int, asFUNCTION_t, asDWORD r0, asDWORD r1);
extern "C" asQWORD armFuncObjLast (const asDWORD *, int, asFUNCTION_t, asDWORD obj);
extern "C" asQWORD armFuncR0ObjLast (const asDWORD *, int, asFUNCTION_t, asDWORD r0, asDWORD obj);
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void *secondObject)
{
asCScriptEngine *engine = context->m_engine;
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
int callConv = sysFunc->callConv;
asQWORD retQW = 0;
asFUNCTION_t func = sysFunc->func;
int paramSize = sysFunc->paramSize;
asFUNCTION_t *vftable;
//---------------------------------------------------------------------------- RPi
int freeFloatSlot = VFP_OFFSET;
int freeDoubleSlot = VFP_OFFSET;
int stackPos = STACK_OFFSET;
int stackSize = 0;
//----------------------------------------------------------------------------
//---------------------------------------------------------------------------- RPi
// We<57>ll divide paramBuffer into several segments:
//
// 0-1 Unused
// 2-5 (+8 / +0 asm) values that should be placed in R0 - R3
// 6-67 (+24 / +16 asm) values that should be placed on the stack
// 68 (+272 / +264 asm) number of values stored in r registers (R0 - R3)
// 69 (+276 / +268 asm) number of args stored on the stack
// 70-85 (+280 / +272 asm) values that should be placed in VFP registers (16)
// 86-87 (+344 / +336 asm) sp original value - sp final value - for debugging
// 88-103 (+352 / +344 asm) Check area for free-used VFP registers
//
// Total number of elements: 104
//
// When passing the paramBuffer to the asm routines via the args pointer we are
// offsetting the start of the array to being at element # 2. That<61>s why in asm
// all addresses must have an offset of -2 words (-8 bytes).
//---------------------------------------------------------------------------- RPi
asDWORD paramBuffer[PARAM_BUFFER_SIZE];
memset(paramBuffer, 0, sizeof(asDWORD) * PARAM_BUFFER_SIZE);
if( sysFunc->hostReturnInMemory )
{
// TODO: runtime optimize: This check should be done in PrepareSystemFunction
if ( !( descr->returnType.GetTypeInfo()->flags & COMPLEX_RETURN_MASK ) &&
( descr->returnType.GetTypeInfo()->flags & asOBJ_APP_CLASS_ALLFLOATS ) &&
descr->returnType.GetSizeInMemoryBytes() <= 8 )
callConv--;
// The return is made in memory
callConv++;
}
bool isThisCallMethod = callConv >= ICC_THISCALL_OBJLAST;
// Linux needs to align 64bit types on even registers, but this isn't done on iOS or Windows Phone
// TODO: optimize runtime: There should be a check for this in PrepareSystemFunction() so this
// doesn't have to be done for functions that don't have any 64bit types
{
// mask is used as a toggler to skip uneven registers.
int mask = 1;
if( isThisCallMethod )
{
mask = 0;
}
else
{
// Check for object pointer as first argument
switch( callConv )
{
case ICC_THISCALL:
case ICC_CDECL_OBJFIRST:
case ICC_VIRTUAL_THISCALL:
case ICC_THISCALL_RETURNINMEM:
case ICC_CDECL_OBJFIRST_RETURNINMEM:
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
mask = 0;
break;
default:
break;
}
}
// Check for hidden address in case of return by value
if( sysFunc->hostReturnInMemory )
mask = !mask;
paramSize = 0;
int spos = 0;
int dpos = 2;
if( isThisCallMethod && (callConv >= ICC_THISCALL_OBJFIRST &&
callConv <= ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM) )
{
// Add the object pointer as the first parameter
paramBuffer[dpos++] = (asDWORD)secondObject;
paramSize++;
}
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
{
// TODO: runtime optimize: Declare a reference to descr->parameterTypes[n] so the array doesn't have to be access all the time
if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() &&
!(descr->parameterTypes[n].GetTypeInfo()->flags & asOBJ_APP_ARRAY) )
{
#ifdef COMPLEX_OBJS_PASSED_BY_REF
if( descr->parameterTypes[n].GetTypeInfo()->flags & COMPLEX_MASK )
{
paramBuffer[dpos++] = args[spos++];
paramSize++;
}
else
#endif
{
if( (descr->parameterTypes[n].GetTypeInfo()->flags & asOBJ_APP_CLASS_ALIGN8) )
{
if ( (dpos & 1) == mask )
{
// 64 bit value align
dpos++;
paramSize++;
}
if ( (stackPos & 1) == mask )
{
// 64 bit value align
stackPos++;
stackSize++;
}
}
// Copy the object's memory to the buffer
if (descr->parameterTypes[n].GetTypeInfo()->flags & asOBJ_APP_CLASS_ALLFLOATS)
{
int target = (freeFloatSlot > freeDoubleSlot) ? freeFloatSlot : freeDoubleSlot;
if ( descr->parameterTypes[n].GetSizeInMemoryDWords() <= ( (VFP_OFFSET + 16) - target) )
{
memcpy(&paramBuffer[target], *(void**)(args+spos), descr->parameterTypes[n].GetSizeInMemoryBytes());
memset(&paramBuffer[target + 18], (asDWORD)1, descr->parameterTypes[n].GetSizeInMemoryDWords());
target += descr->parameterTypes[n].GetSizeInMemoryDWords();
freeFloatSlot = freeDoubleSlot = target;
}
else
{
memcpy(&paramBuffer[stackPos], *(void**)(args+spos), descr->parameterTypes[n].GetSizeInMemoryBytes());
stackPos += descr->parameterTypes[n].GetSizeInMemoryDWords();
stackSize += descr->parameterTypes[n].GetSizeOnStackDWords();
}
}
else
{
memcpy(&paramBuffer[dpos], *(void**)(args+spos), descr->parameterTypes[n].GetSizeInMemoryBytes());
dpos += descr->parameterTypes[n].GetSizeInMemoryDWords();
paramSize += descr->parameterTypes[n].GetSizeInMemoryDWords();
}
// Delete the original memory
engine->CallFree(*(char**)(args+spos));
spos++;
}
continue;
}
else if( descr->parameterTypes[n].IsFloatType() && !descr->parameterTypes[n].IsReference() )
{
// Are there any "s" registers available?
if ( freeFloatSlot < (VFP_OFFSET + 16) )
{
if (freeFloatSlot == freeDoubleSlot)
freeDoubleSlot += 2;
paramBuffer[freeFloatSlot + 18] = (asDWORD)1;
paramBuffer[freeFloatSlot++] = args[spos++];
while(freeFloatSlot < (VFP_OFFSET + 16) && paramBuffer[freeFloatSlot + 18] != 0)
freeFloatSlot++;
}
// If not, then store the float arg in the stack area
else
{
paramBuffer[stackPos++] = args[spos++];
stackSize++;
}
continue;
}
else if( descr->parameterTypes[n].IsDoubleType() && !descr->parameterTypes[n].IsReference() )
{
// Are there any "d" registers available?
if ( freeDoubleSlot < (VFP_OFFSET + 15) )
{
if (freeFloatSlot == freeDoubleSlot)
freeFloatSlot += 2;
// Copy two dwords for the double
paramBuffer[freeDoubleSlot + 18] = (asDWORD)1;
paramBuffer[freeDoubleSlot + 19] = (asDWORD)1;
paramBuffer[freeDoubleSlot++] = args[spos++];
paramBuffer[freeDoubleSlot++] = args[spos++];
while(freeDoubleSlot < (VFP_OFFSET + 15) && paramBuffer[freeDoubleSlot + 18] != 0)
freeDoubleSlot += 2;
}
// If not, then store the double arg in the stack area
else
{
if ( (stackPos & 1) == mask )
{
// 64 bit value align
stackPos++;
stackSize++;
}
paramBuffer[stackPos++] = args[spos++];
paramBuffer[stackPos++] = args[spos++];
stackSize += 2;
}
continue;
}
else
{
// Copy the value directly to "r" registers or the stack, checking for alignment
if (paramSize < 4)
{
// Should an alignment be performed?
if( (dpos & 1) == mask && descr->parameterTypes[n].GetSizeOnStackDWords() == 2 &&
!descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() &&
!descr->parameterTypes[n].IsAnyType() )
{
// 64 bit value align
dpos++;
paramSize++;
}
paramBuffer[dpos++] = args[spos++];
paramSize += descr->parameterTypes[n].GetSizeOnStackDWords();
}
else
{
// Should an alignment be performed?
if( (stackPos & 1) == mask && descr->parameterTypes[n].GetSizeOnStackDWords() == 2 &&
!descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() &&
!descr->parameterTypes[n].IsAnyType() )
{
// 64 bit value align
stackPos++;
stackSize++;
}
paramBuffer[stackPos++] = args[spos++];
stackSize += descr->parameterTypes[n].GetSizeOnStackDWords();
}
if( descr->parameterTypes[n].GetSizeOnStackDWords() > 1 )
{
if (paramSize < 5)
paramBuffer[dpos++] = args[spos++];
else
paramBuffer[stackPos++] = args[spos++];
}
}// else...
}// Loop
if( isThisCallMethod && (callConv >= ICC_THISCALL_OBJLAST &&
callConv <= ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM) )
{
if (paramSize < 4)
{
paramBuffer[dpos++] = (asDWORD)secondObject;
paramSize++;
}
else
{
paramBuffer[stackPos++] = (asDWORD)secondObject;
stackSize++;
}
}
// Keep a free location at the beginning
args = &paramBuffer[2];
}
paramBuffer[69] = static_cast<asDWORD>(stackSize<<2);
switch( callConv )
{
case ICC_CDECL_RETURNINMEM: // fall through
case ICC_STDCALL_RETURNINMEM:
retQW = armFuncR0(args, paramSize<<2, func, (asDWORD)retPointer);
break;
case ICC_CDECL: // fall through
case ICC_STDCALL:
retQW = armFunc(args, paramSize<<2, func);
break;
case ICC_THISCALL: // fall through
case ICC_CDECL_OBJFIRST:
case ICC_THISCALL_OBJFIRST:
case ICC_THISCALL_OBJLAST:
retQW = armFuncR0(args, paramSize<<2, func, (asDWORD)obj);
break;
case ICC_THISCALL_RETURNINMEM:
case ICC_THISCALL_OBJFIRST_RETURNINMEM:
case ICC_THISCALL_OBJLAST_RETURNINMEM:
// On GNUC the address where the return value will be placed should be put in R0
retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
break;
case ICC_CDECL_OBJFIRST_RETURNINMEM:
retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
break;
case ICC_VIRTUAL_THISCALL:
case ICC_VIRTUAL_THISCALL_OBJFIRST:
case ICC_VIRTUAL_THISCALL_OBJLAST:
// Get virtual function table from the object pointer
vftable = *(asFUNCTION_t**)obj;
retQW = armFuncR0(args, paramSize<<2, vftable[FuncPtrToUInt(func)>>2], (asDWORD)obj);
break;
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
case ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM:
case ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM:
// Get virtual function table from the object pointer
vftable = *(asFUNCTION_t**)obj;
// On GNUC the address where the return value will be placed should be put in R0
retQW = armFuncR0R1(args, (paramSize+1)<<2, vftable[FuncPtrToUInt(func)>>2], (asDWORD)retPointer, (asDWORD)obj);
break;
case ICC_CDECL_OBJLAST:
retQW = armFuncObjLast(args, paramSize<<2, func, (asDWORD)obj);
break;
case ICC_CDECL_OBJLAST_RETURNINMEM:
retQW = armFuncR0ObjLast(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
break;
default:
context->SetInternalException(TXT_INVALID_CALLING_CONVENTION);
}
// On Linux with arm the float and double values are returns in the
// floating point registers, s0 and s1. Objects that contain only
// float types and are not considered complex are also returned in the
// floating point registers.
if( sysFunc->hostReturnFloat )
{
retQW = paramBuffer[VFP_OFFSET];
if ( sysFunc->hostReturnSize > 1 )
retQW = *( (asQWORD*)&paramBuffer[VFP_OFFSET] );
}
else if ( descr->returnType.IsObject() )
{
// TODO: runtime optimize: This should be identified with a flag determined in PrepareSystemFunction
if ( !descr->returnType.IsObjectHandle() &&
!descr->returnType.IsReference() &&
!(descr->returnType.GetTypeInfo()->flags & COMPLEX_RETURN_MASK) &&
(descr->returnType.GetTypeInfo()->flags & asOBJ_APP_CLASS_ALLFLOATS) )
memcpy( retPointer, &paramBuffer[VFP_OFFSET], descr->returnType.GetSizeInMemoryBytes() );
}
return retQW;
}
END_AS_NAMESPACE
#endif // AS_LINUX
#endif // AS_ARM
#endif // AS_MAX_PORTABILITY

View File

@@ -0,0 +1,329 @@
/*
AngelCode Scripting Library
Copyright (c) 2020-2020 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_callfunc_arm64.cpp
//
// These functions handle the actual calling of system functions on the arm64 platform
//
// Written by Max Waine in July 2020, based on as_callfunc_arm.cpp
//
#include "as_config.h"
#ifndef AS_MAX_PORTABILITY
#ifdef AS_ARM64
#include "as_callfunc.h"
#include "as_scriptengine.h"
#include "as_texts.h"
#include "as_tokendef.h"
#include "as_context.h"
// ARM64 targets use has no software floating-point ABI, it's all hardware (or totally disabled)
#define HFA_RET_REGISTERS 4 // s0-s3/d0-d3
#define GP_ARG_REGISTERS 8 // x0-x7
#define FLOAT_ARG_REGISTERS 8 // v0-v7
BEGIN_AS_NAMESPACE
// x0-7: Argument registers (pass params or return results. OK as volatile local variables)
// x8: Indirect result register (e.g. address of large returned struct)
// x9-15: Volatile local variable registers
// x16-17: Intra-procedure-call temporary registers
// x18: Platform register (reserved for use of platform ABIs)
// x19-29: Non-volatile variable registers (must be saved and restored if modified)
// x29: Frame pointer register
// x30: Link register (where to return to)
extern "C" void GetHFAReturnDouble(asQWORD *out1, asQWORD *out2, asQWORD returnSize);
extern "C" void GetHFAReturnFloat(asQWORD *out1, asQWORD *out2, asQWORD returnSize);
extern "C" asQWORD CallARM64RetInMemory(
const asQWORD *gpRegArgs, asQWORD numGPRegArgs,
const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
const asQWORD *stackArgs, asQWORD numStackArgs,
void *retPointer, asFUNCTION_t func
);
extern "C" double CallARM64Double(
const asQWORD *gpRegArgs, asQWORD numGPRegArgs,
const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
const asQWORD *stackArgs, asQWORD numStackArgs,
asFUNCTION_t func
);
extern "C" float CallARM64Float(
const asQWORD *gpRegArgs, asQWORD numGPRegArgs,
const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
const asQWORD *stackArgs, asQWORD numStackArgs,
asFUNCTION_t func
);
extern "C" asQWORD CallARM64(
const asQWORD *gpRegArgs, asQWORD numGPRegArgs,
const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
const asQWORD *stackArgs, asQWORD numStackArgs,
asFUNCTION_t func
);
extern "C" asQWORD CallARM64Ret128(
const asQWORD *gpRegArgs, asQWORD numGPRegArgs,
const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
const asQWORD *stackArgs, asQWORD numStackArgs,
asQWORD *higherQWORD, asFUNCTION_t func
);
//
// If it's possible to fit in registers,
// there may not be enough float register space even if true is returned
//
static inline bool IsRegisterHFA(const asCDataType &type)
{
const asCTypeInfo *const typeInfo = type.GetTypeInfo();
if( typeInfo == nullptr ||
(typeInfo->flags & asOBJ_APP_CLASS_ALLFLOATS) == 0 ||
type.IsObjectHandle() && type.IsReference() )
return false;
const bool doubles = (typeInfo->flags & asOBJ_APP_CLASS_ALIGN8) != 0;
const int maxAllowedSize = doubles ? sizeof(double) * HFA_RET_REGISTERS : sizeof(float) * HFA_RET_REGISTERS;
return type.GetSizeInMemoryBytes() <= maxAllowedSize;
}
//
// If it's possible to fit it in registers,
// if true is returned there is enough space to fit
//
static inline bool IsRegisterHFAParameter(const asCDataType &type, const asQWORD numFloatRegArgs)
{
if( !IsRegisterHFA(type) )
return false;
const bool doubles = (type.GetTypeInfo()->flags & asOBJ_APP_CLASS_ALIGN8) != 0;
const int registersUsed = type.GetSizeInMemoryDWords() / (doubles ? sizeof(double) : sizeof(float));
return numFloatRegArgs + registersUsed <= FLOAT_ARG_REGISTERS;
}
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &retQW2, void *secondObject)
{
asCScriptEngine *engine = context->m_engine;
const asSSystemFunctionInterface *const sysFunc = descr->sysFuncIntf;
const asCDataType &retType = descr->returnType;
const asCTypeInfo *const retTypeInfo = retType.GetTypeInfo();
asFUNCTION_t func = sysFunc->func;
int callConv = sysFunc->callConv;
asQWORD retQW = 0;
asQWORD gpRegArgs[GP_ARG_REGISTERS];
asQWORD floatRegArgs[FLOAT_ARG_REGISTERS];
asQWORD stackArgs[64]; // It's how many x64 users can have
asQWORD numGPRegArgs = 0;
asQWORD numFloatRegArgs = 0;
asQWORD numStackArgs = 0;
asFUNCTION_t *vftable;
// Optimization to avoid check 12 values (all ICC_ that contains THISCALL)
if( (callConv >= ICC_THISCALL && callConv <= ICC_VIRTUAL_THISCALL_RETURNINMEM) ||
(callConv >= ICC_THISCALL_OBJLAST && callConv <= ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM) )
{
// Add the object pointer as the first parameter
gpRegArgs[numGPRegArgs++] = (asQWORD)obj;
}
if( callConv == ICC_CDECL_OBJFIRST || callConv == ICC_CDECL_OBJFIRST_RETURNINMEM )
{
// Add the object pointer as the first parameter
gpRegArgs[numGPRegArgs++] = (asQWORD)obj;
}
else if( callConv == ICC_THISCALL_OBJFIRST || callConv == ICC_THISCALL_OBJFIRST_RETURNINMEM ||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST || callConv == ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM )
{
// Add the object pointer as the first parameter
gpRegArgs[numGPRegArgs++] = (asQWORD)secondObject;
}
if( callConv == ICC_VIRTUAL_THISCALL || callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM || callConv == ICC_VIRTUAL_THISCALL_OBJFIRST ||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM || callConv == ICC_VIRTUAL_THISCALL_OBJLAST || callConv == ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM )
{
// Get virtual function table from the object pointer
vftable = *(asFUNCTION_t**)obj;
func = vftable[FuncPtrToUInt(func)/sizeof(void*)];
}
asUINT argsPos = 0;
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
{
const asCDataType &parmType = descr->parameterTypes[n];
const asCTypeInfo *const parmTypeInfo = parmType.GetTypeInfo();
if( parmType.IsObject() && !parmType.IsObjectHandle() && !parmType.IsReference() )
{
const asUINT parmDWords = parmType.GetSizeInMemoryDWords();
const asUINT parmQWords = (parmDWords >> 1) + (parmDWords & 1);
const bool passedAsPointer = parmQWords <= 2;
const bool fitsInRegisters = passedAsPointer ? (numGPRegArgs < GP_ARG_REGISTERS) : (numGPRegArgs + parmQWords <= GP_ARG_REGISTERS);
asQWORD *const argsArray = fitsInRegisters ? gpRegArgs : stackArgs;
asQWORD &numArgs = fitsInRegisters ? numGPRegArgs : numStackArgs;
if( (parmTypeInfo->flags & COMPLEX_MASK) )
{
argsArray[numArgs++] = *(asQWORD*)&args[argsPos];
argsPos += AS_PTR_SIZE;
}
else if( IsRegisterHFAParameter(parmType, numFloatRegArgs) )
{
if( (parmTypeInfo->flags & asOBJ_APP_CLASS_ALIGN8) != 0 )
{
const asQWORD *const contents = *(asQWORD**)&args[argsPos];
for( asUINT i = 0; i < parmQWords; i++ )
floatRegArgs[numFloatRegArgs++] = *(asQWORD*)&contents[i];
}
else
{
const asDWORD *const contents = *(asDWORD**)&args[argsPos];
for( asUINT i = 0; i < parmDWords; i++ )
floatRegArgs[numFloatRegArgs++] = *(asQWORD*)&contents[i];
}
engine->CallFree(*(char**)(args+argsPos));
argsPos += AS_PTR_SIZE;
}
else
{
// Copy the object's memory to the buffer
memcpy(&argsArray[numArgs], *(void**)(args+argsPos), parmType.GetSizeInMemoryBytes());
// Delete the original memory
engine->CallFree(*(char**)(args+argsPos));
argsPos += AS_PTR_SIZE;
numArgs += parmQWords;
}
}
else if( parmType.IsFloatType() && !parmType.IsReference() )
{
if( numFloatRegArgs >= FLOAT_ARG_REGISTERS )
stackArgs[numStackArgs++] = args[argsPos];
else
floatRegArgs[numFloatRegArgs++] = args[argsPos];
argsPos++;
}
else if( parmType.IsDoubleType() && !parmType.IsReference() )
{
if( numFloatRegArgs >= FLOAT_ARG_REGISTERS )
stackArgs[numStackArgs++] = *(asQWORD*)&args[argsPos];
else
floatRegArgs[numFloatRegArgs++] = *(asQWORD*)&args[argsPos];
argsPos += 2;
}
else
{
// Copy the value directly
const asUINT parmDWords = parmType.GetSizeOnStackDWords();
const asUINT parmQWords = (parmDWords >> 1) + (parmDWords & 1);
const bool fitsInRegisters = numGPRegArgs + parmQWords <= GP_ARG_REGISTERS;
asQWORD *const argsArray = fitsInRegisters ? gpRegArgs : stackArgs;
asQWORD &numArgs = fitsInRegisters ? numGPRegArgs : numStackArgs;
memcpy(&argsArray[numArgs], (void*)(args+argsPos), parmDWords * 4);
argsPos += parmDWords;
numArgs += parmQWords;
}
}
if( callConv == ICC_CDECL_OBJLAST || callConv == ICC_CDECL_OBJLAST_RETURNINMEM )
{
// Add the object pointer as the last parameter
if( numGPRegArgs < GP_ARG_REGISTERS )
gpRegArgs[numGPRegArgs++] = (asQWORD)obj;
else
stackArgs[numStackArgs++] = (asQWORD)obj;
}
else if( callConv == ICC_THISCALL_OBJLAST || callConv == ICC_THISCALL_OBJLAST_RETURNINMEM ||
callConv == ICC_VIRTUAL_THISCALL_OBJLAST || callConv == ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM )
{
// Add the object pointer as the last parameter
if( numGPRegArgs < GP_ARG_REGISTERS )
gpRegArgs[numGPRegArgs++] = (asQWORD)secondObject;
else
stackArgs[numStackArgs++] = (asQWORD)secondObject;
}
if( IsRegisterHFA(retType) && !(retTypeInfo->flags & COMPLEX_MASK) )
{
// This is to deal with HFAs (Homogeneous Floating-point Aggregates):
// ARM64 will place all-float composite types (of equal precision)
// with <= 4 members in the float return registers
const int structSize = retType.GetSizeInMemoryBytes();
CallARM64(gpRegArgs, numGPRegArgs, floatRegArgs, numFloatRegArgs, stackArgs, numStackArgs, func);
if( (retTypeInfo->flags & asOBJ_APP_CLASS_ALIGN8) != 0 )
{
if( structSize <= sizeof(double) * 2 )
GetHFAReturnDouble(&retQW, &retQW2, structSize);
else
GetHFAReturnDouble((asQWORD*)retPointer, ((asQWORD*)retPointer) + 1, structSize);
}
else
GetHFAReturnFloat(&retQW, &retQW2, structSize);
}
else if( sysFunc->hostReturnFloat )
{
if( sysFunc->hostReturnSize == 1 )
*(float*)&retQW = CallARM64Float(gpRegArgs, numGPRegArgs, floatRegArgs, numFloatRegArgs, stackArgs, numStackArgs, func);
else
*(double*)&retQW = CallARM64Double(gpRegArgs, numGPRegArgs, floatRegArgs, numFloatRegArgs, stackArgs, numStackArgs, func);
}
else if( sysFunc->hostReturnInMemory )
retQW = CallARM64RetInMemory(gpRegArgs, numGPRegArgs, floatRegArgs, numFloatRegArgs, stackArgs, numStackArgs, retPointer, func);
else
{
if( retType.GetSizeInMemoryBytes() > sizeof(asQWORD) )
retQW = CallARM64Ret128(gpRegArgs, numGPRegArgs, floatRegArgs, numFloatRegArgs, stackArgs, numStackArgs, &retQW2, func);
else
retQW = CallARM64(gpRegArgs, numGPRegArgs, floatRegArgs, numFloatRegArgs, stackArgs, numStackArgs, func);
}
return retQW;
}
END_AS_NAMESPACE
#endif // AS_ARM64
#endif // AS_MAX_PORTABILITY

View File

@@ -0,0 +1,219 @@
//
// AngelCode Scripting Library
// Copyright (c) 2020-2020 Andreas Jonsson
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any
// damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any
// purpose, including commercial applications, and to alter it and
// redistribute it freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented// you
// must not claim that you wrote the original software. If you use
// this software in a product, an acknowledgment in the product
// documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and
// must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
// The original version of this library can be located at:
// http://www.angelcode.com/angelscript/
//
// Andreas Jonsson
// andreas@angelcode.com
//
// Assembly routines for the ARM64/AArch64 call convention used for Linux
// Written by Max Waine in July 2020, based on as_callfunc_arm_msvc.asm,
// with assistance & guidance provided by Sir Kane
// Compile with GCC/GAS
.arch armv8-a
.text
.global GetHFAReturnDouble
.global GetHFAReturnFloat
.global CallARM64Ret128
.global CallARM64RetInMemory
.global CallARM64Double
.global CallARM64Float
.global CallARM64
.type GetHFAReturnDouble, %function
.type GetHFAReturnFloat, %function
.type CallARM64Ret128, %function
.type CallARM64RetInMemory, %function
.type CallARM64Double, %function
.type CallARM64Float, %function
.type CallARM64, %function
.align 2
GetHFAReturnDouble:
adr x9, populateDoubles
sub x9, x9, x1, lsr 1 // x9 -= returnSize >> 1; (/2 because double is 2x instruction size)
br x9
str d3, [x0, #0x18]
str d2, [x0, #0x10]
str d1, [x1]
str d0, [x0]
populateDoubles:
ret
.align 2
GetHFAReturnFloat:
adr x9, populateFloats
sub x9, x9, x2 // x9 -= returnSize; (already 4 bytes per return)
br x9
str s3, [x1, #0x4]
str s2, [x1]
str s1, [x0, #0x4]
str s0, [x0]
populateFloats:
ret
//[returnType] CallARM64[type](
// const asQWORD *gpRegArgs, asQWORD numGPRegArgs,
// const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
// const asQWORD *stackArgs, asQWORD numStackArgs,
// asFUNCTION_t func
//)
.align 2
CallARM64Double:
CallARM64Float:
CallARM64:
.cfi_startproc
stp fp, lr, [sp,#-0x20]!
str x20, [sp,#0x10]
.cfi_def_cfa_offset 0x20
.cfi_offset 20, 0x10
.cfi_offset fp, -0x20
.cfi_offset lr, -0x18
mov fp, sp
mov x20, #0
cbz x5, stackArgsLoopEnd
// Align count to 2, then multiply by 8, resulting in a size aligned to 16
add x20, x5, #1
lsl x20, x20, #3
and x20, x20, #-0x10
// Multiply count by 8
lsl x10, x5, #3
sub sp, sp, x20
stackArgsLoopStart:
ldp x9,x11, [x4],#16
stp x9,x11, [sp],#16
subs x10, x10, #16
bgt stackArgsLoopStart
stackArgsLoopEnd:
// Calculate amount to jump forward, avoiding pointless instructions
adr x9, populateFloatRegisterArgsEnd
sub x9, x9, x3, lsl 2 // x9 -= numFloatRegArgs * 4
br x9
ldr d7, [x2, #0x38]
ldr d6, [x2, #0x30]
ldr d5, [x2, #0x28]
ldr d4, [x2, #0x20]
ldr d3, [x2, #0x18]
ldr d2, [x2, #0x10]
ldr d1, [x2, #0x08]
ldr d0, [x2]
populateFloatRegisterArgsEnd:
mov x15, x6
// Calculate amount to jump forward, avoiding pointless instructions
adr x9, populateGPRegisterArgsEnd
sub x9, x9, x1, lsl 2 // x9 -= numGPRegArgs * 4
br x9
ldr x7, [x0, #0x38]
ldr x6, [x0, #0x30]
ldr x5, [x0, #0x28]
ldr x4, [x0, #0x20]
ldr x3, [x0, #0x18]
ldr x2, [x0, #0x10]
ldr x1, [x0, #0x08]
ldr x0, [x0]
populateGPRegisterArgsEnd:
// Actually call function
sub sp, sp, x20
blr x15
add sp, sp, x20
ldr x20, [sp,#0x10]
ldp fp, lr, [sp],#0x20
.cfi_restore lr
.cfi_restore fp
.cfi_restore 20
.cfi_def_cfa_offset 0
ret
.cfi_endproc
.align 2
CallARM64Ret128:
.cfi_startproc
stp fp, lr, [sp,#-0x20]!
str x20, [sp,#0x10]
.cfi_def_cfa_offset 0x20
.cfi_offset 20, 0x10
.cfi_offset fp, -0x20
.cfi_offset lr, -0x18
mov fp, sp
mov x20, x6
mov x6, x7
mov x7, #0
bl CallARM64
str x1, [x20]
ldr x20, [sp,#0x10]
ldp fp, lr, [sp],#0x20
.cfi_restore lr
.cfi_restore fp
.cfi_restore 20
.cfi_def_cfa_offset 0
ret
.cfi_endproc
.align 2
CallARM64RetInMemory:
.cfi_startproc
stp fp, lr, [sp,#-0x10]!
mov fp, sp
.cfi_def_cfa_offset 0x10
.cfi_offset fp, -0x10
.cfi_offset lr, -0x08
mov x8, x6
mov x6, x7
mov x7, #0
bl CallARM64
mov x0, x8
ldp fp, lr, [sp],#0x10
.cfi_restore lr
.cfi_restore fp
.cfi_def_cfa_offset 0
ret
.cfi_endproc

View File

@@ -0,0 +1,205 @@
;
; AngelCode Scripting Library
; Copyright (c) 2020-2020 Andreas Jonsson
;
; This software is provided 'as-is', without any express or implied
; warranty. In no event will the authors be held liable for any
; damages arising from the use of this software.
;
; Permission is granted to anyone to use this software for any
; purpose, including commercial applications, and to alter it and
; redistribute it freely, subject to the following restrictions:
;
; 1. The origin of this software must not be misrepresented; you
; must not claim that you wrote the original software. If you use
; this software in a product, an acknowledgment in the product
; documentation would be appreciated but is not required.
;
; 2. Altered source versions must be plainly marked as such, and
; must not be misrepresented as being the original software.
;
; 3. This notice may not be removed or altered from any source
; distribution.
;
; The original version of this library can be located at:
; http://www.angelcode.com/angelscript/
;
; Andreas Jonsson
; andreas@angelcode.com
;
; Assembly routines for the ARM64/AArch64 call convention used for Windows 10 on ARM
; Written by Max Waine in July 2020, based on as_callfunc_arm_msvc.asm
; MSVC currently doesn't support inline assembly for the ARM64 platform,
; and if they're treating it like x64 /won't/ ever support inline assembly,
; so this separate file is needed.
; Compile with Microsoft ARM64 assembler (armasm64)
; http://msdn.microsoft.com/en-us/library/hh873190.aspx
AREA |.rdata|, DATA, READONLY
EXPORT GetHFAReturnDouble
EXPORT GetHFAReturnFloat
EXPORT CallARM64Ret128
EXPORT CallARM64RetInMemory
EXPORT CallARM64Double
EXPORT CallARM64Float
EXPORT CallARM64
AREA |.text|, CODE, ALIGN=2
ALIGN 4
GetHFAReturnDouble PROC
adr x9, |populateDoubles|
sub x9, x9, x1, lsr 1 ; x9 -= returnSize >> 1; (/2 because double is 2x instruction size)
br x9
str d3, [x0, #0x18]
str d2, [x0, #0x10]
str d1, [x1]
str d0, [x0]
|populateDoubles|
ret
ENDP ; GetHFAReturnDouble
ALIGN 4
GetHFAReturnFloat PROC
adr x9, |populateFloats|
sub x9, x9, x2 // x9 -= returnSize; (already 4 bytes per return)
br x9
str s3, [x1, #0x4]
str s2, [x1]
str s1, [x0, #0x4]
str s0, [x0]
|populateFloats|
ret
ENDP ; GetHFAReturnFloat
;[returnType] CallARM64[type](
; const asQWORD *gpRegArgs, asQWORD numGPRegArgs,
; const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
; const asQWORD *stackArgs, asQWORD numStackArgs,
; asFUNCTION_t func
;)
ALIGN 4
CallARM64Double PROC
stp fp, lr, [sp,#-0x10]!
bl CallARM64
ldp fp, lr, [sp,#-0x10]!
ret
ENDP ; CallARM64Double
ALIGN 4
CallARM64Float PROC
stp fp, lr, [sp,#-0x10]!
bl CallARM64
ldp fp, lr, [sp,#-0x10]!
ret
ENDP ; CallARM64Float
ALIGN 4
CallARM64 PROC
stp fp, lr, [sp,#-0x20]!
str x20, [sp,#0x10]
mov x20, #0;
cbz x5, |stackArgsLoopEnd|
; Align count to 2, then multiply by 8, resulting in a size aligned to 16
add x20, x5, #1
lsl x20, x20, #3
and x20, x20, #-0x10
; Multiply count by 8
lsl x10, x5, #3
sub sp, sp, x20
|stackArgsLoopStart|
ldp x9,x11, [x4],#16
stp x9,x11, [sp],#16
subs x10, x10, #16
bgt |stackArgsLoopStart|
|stackArgsLoopEnd|
; Calculate amount to jump forward, avoiding pointless instructions
adr x9, |populateFloatRegisterArgsEnd|
sub x9, x9, x3, lsl 2 ; x9 -= numFloatRegArgs * 4
br x9
ldr d7, [x2, #0x38]
ldr d6, [x2, #0x30]
ldr d5, [x2, #0x28]
ldr d4, [x2, #0x20]
ldr d3, [x2, #0x18]
ldr d2, [x2, #0x10]
ldr d1, [x2, #0x08]
ldr d0, [x2]
|populateFloatRegisterArgsEnd|
mov x15, x6
; Calculate amount to jump forward, avoiding pointless instructions
adr x9, |populateGPRegisterArgsEnd|
sub x9, x9, x1, lsl 2 ; x9 -= numGPRegArgs * 4
br x9
ldr x7, [x0, #0x38]
ldr x6, [x0, #0x30]
ldr x5, [x0, #0x28]
ldr x4, [x0, #0x20]
ldr x3, [x0, #0x18]
ldr x2, [x0, #0x10]
ldr x1, [x0, #0x08]
ldr x0, [x0]
|populateGPRegisterArgsEnd|
; Actually call function
sub sp, sp, x20
blr x15
add sp, sp, x20
ldr x20, [sp,#0x10]
ldp fp, lr, [sp],#0x20
ret
ENDP ; CallARM64
ALIGN 4
CallARM64Ret128 PROC
stp fp, lr, [sp,#-0x20]!
str x20, [sp,#0x10]
mov fp, sp
mov x20, x6
mov x6, x7
mov x7, #0
bl CallARM64
str x1, [x20]
ldr x20, [sp,#0x10]
ldp fp, lr, [sp],#0x20
ret ; CallARM64Ret128
ALIGN 4
CallARM64RetInMemory PROC
stp fp, lr, [sp,#-0x10]!
mov fp, sp
mov x8, x6
mov x6, x7
mov x7, #0
bl CallARM64
mov x0, x8
ldp fp, lr, [sp],#0x10
ret ; CallARM64RetInMemory
END

View File

@@ -0,0 +1,730 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2020 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
/*
Assembly routines for the ARM call convention
Written by Fredrik Ehnbom in June 2009
Adapted to GNUC by darktemplar216 in September 2009
Modified by Lasse Oorni for 8-byte stack alignment in May 2012
The assembler routines for Linux were written by Carlos Luna in December 2012
*/
#if !defined(AS_MAX_PORTABILITY)
#if defined(__arm__) || defined(__ARM__) || defined(I3D_ARCH_ARM)
#if !defined(__linux__) || defined(__ANDROID__) || defined(ANDROID) || defined(__SOFTFP__) || defined(__ARM_PCS)
/* iOS, Android, Marmalade, and Linux with soft-float ABI goes here */
.global armFunc
.global armFuncR0
.global armFuncR0R1
.global armFuncObjLast
.global armFuncR0ObjLast
/* --------------------------------------------------------------------------------------------*/
armFunc:
stmdb sp!, {r4-r8, lr}
mov r6, r0 /* arg table */
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
mov r4, r2 /* function address */
mov r8, #0
beq nomoreargs
/* Load the first 4 arguments into r0-r3 */
cmp r7, #4
ldrge r0, [r6],#4
cmp r7, #2*4
ldrge r1, [r6],#4
cmp r7, #3*4
ldrge r2, [r6],#4
cmp r7, #4*4
ldrge r3, [r6],#4
ble nomoreargs
/* Load the rest of the arguments onto the stack */
sub r7, r7, #4*4 /* skip the 4 registers already loaded into r0-r3 */
add r8, r7, #4 /* ensure 8-byte stack alignment */
bic r8, r8, #4
sub sp, sp, r8
mov r12, sp /* copy size != frame size, so store frame start sp */
stackargsloop:
ldr r5, [r6], #4
str r5, [sp], #4
subs r7, r7, #4
bne stackargsloop
mov sp, r12
nomoreargs:
#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
mov lr, pc /* older ARM didn't support blx */
mov pc, r4
#else
blx r4
#endif
add sp, sp, r8
ldmia sp!, {r4-r8, pc}
/* --------------------------------------------------------------------------------------------*/
armFuncObjLast:
stmdb sp!, {r4-r8, lr}
mov r6, r0 /* arg table */
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
mov r4, r2 /* function address */
mov r8, #0
mov r0, r3 /* objlast. might get overwritten */
mov r5, r3 /* objlast to temp reg */
beq nomoreargsarmFuncObjLast
/* Load the first 4 arguments into r0-r3 */
cmp r7, #4
ldrge r0, [r6],#4
cmp r7, #2*4
ldrge r1, [r6],#4
movlt r1, r5
cmp r7, #3*4
ldrge r2, [r6],#4
movlt r2, r5
cmp r7, #4*4
ldrge r3, [r6],#4
movlt r3, r5
blt nomoreargsarmFuncObjLast
/* Load the rest of the arguments onto the stack */
sub r7, r7, #4*4 /* skip the 4 registers already loaded into r0-r3 */
add r8, r7, #8 /* account for the objlast pointer, ensure 8-byte stack alignment */
bic r8, r8, #4
str r5, [sp,#-4] /* store the objlast on stack, twice in case we adjusted alignment */
str r5, [sp,#-8]
sub sp, sp, r8 /* adjust frame */
cmp r7, #0 /* we may also have come here with no extra params */
beq nomoreargsarmFuncObjLast
mov r12, sp /* copy size != frame size, so store frame start sp */
stackargslooparmFuncObjLast:
ldr r5, [r6], #4
str r5, [sp], #4
subs r7, r7, #4
bne stackargslooparmFuncObjLast
mov sp, r12
nomoreargsarmFuncObjLast:
#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
mov lr, pc /* older ARM didn't support blx */
mov pc, r4
#else
blx r4
#endif
add sp, sp, r8
ldmia sp!, {r4-r8, pc}
/* --------------------------------------------------------------------------------------------*/
armFuncR0ObjLast:
stmdb sp!, {r4-r8, lr}
ldr r5, [sp,#6*4] /* objlast to temp reg */
mov r6, r0 /* arg table */
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
mov r4, r2 /* function address */
mov r8, #0
mov r0, r3 /* r0 explicitly set */
mov r1, r5 /* objlast. might get overwritten */
beq nomoreargsarmFuncR0ObjLast
/* Load the first 3 arguments into r1-r3 */
cmp r7, #1*4
ldrge r1, [r6],#4
cmp r7, #2*4
ldrge r2, [r6],#4
movlt r2, r5
cmp r7, #3*4
ldrge r3, [r6],#4
movlt r3, r5
blt nomoreargsarmFuncR0ObjLast
/* Load the rest of the arguments onto the stack */
sub r7, r7, #3*4 /* skip the 3 registers already loaded into r1-r3 */
add r8, r7, #8 /* account for the objlast pointer, ensure 8-byte stack alignment */
bic r8, r8, #4
str r5, [sp,#-4] /* store the objlast on stack, twice in case we adjusted alignment */
str r5, [sp,#-8]
sub sp, sp, r8 /* adjust frame */
cmp r7, #0 /* we may also have come here with no extra params */
beq nomoreargsarmFuncR0ObjLast
mov r12, sp /* copy size != frame size, so store frame start sp */
stackargslooparmFuncR0ObjLast:
ldr r5, [r6], #4
str r5, [sp], #4
subs r7, r7, #4
bne stackargslooparmFuncR0ObjLast
mov sp, r12
nomoreargsarmFuncR0ObjLast:
#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
mov lr, pc /* older ARM didn't support blx */
mov pc, r4
#else
blx r4
#endif
add sp, sp, r8
ldmia sp!, {r4-r8, pc}
/* --------------------------------------------------------------------------------------------*/
armFuncR0:
stmdb sp!, {r4-r8, lr}
mov r6, r0 /* arg table */
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
mov r4, r2 /* function address */
mov r8, #0
mov r0, r3 /* r0 explicitly set */
beq nomoreargsarmFuncR0
/* Load the first 3 arguments into r1-r3 */
cmp r7, #1*4
ldrge r1, [r6],#4
cmp r7, #2*4
ldrge r2, [r6],#4
cmp r7, #3*4
ldrge r3, [r6],#4
ble nomoreargsarmFuncR0
/* Load the rest of the arguments onto the stack */
sub r7, r7, #3*4 /* skip the 3 registers already loaded into r1-r3 */
add r8, r7, #4 /* ensure 8-byte stack alignment */
bic r8, r8, #4
sub sp, sp, r8
mov r12, sp /* copy size != frame size, so store frame start sp */
stackargslooparmFuncR0:
ldr r5, [r6], #4
str r5, [sp], #4
subs r7, r7, #4
bne stackargslooparmFuncR0
mov sp, r12
nomoreargsarmFuncR0:
#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
mov lr, pc /* older ARM didn't support blx */
mov pc, r4
#else
blx r4
#endif
add sp, sp, r8
ldmia sp!, {r4-r8, pc}
/* --------------------------------------------------------------------------------------------*/
armFuncR0R1:
stmdb sp!, {r4-r8, lr}
mov r6, r0 /* arg table */
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
mov r4, r2 /* function address */
mov r8, #0
mov r0, r3 /* r0 explicitly set */
ldr r1, [sp, #6*4] /* r1 explicitly set too */
beq nomoreargsarmFuncR0R1
/* Load the first 2 arguments into r2-r3 */
cmp r7, #1*4
ldrge r2, [r6],#4
cmp r7, #2*4
ldrge r3, [r6],#4
ble nomoreargsarmFuncR0R1
/* Load the rest of the arguments onto the stack */
sub r7, r7, #2*4 /* skip the 2 registers already loaded into r2-r3 */
add r8, r7, #4 /* ensure 8-byte stack alignment */
bic r8, r8, #4
sub sp, sp, r8
mov r12, sp /* copy size != frame size, so store frame start sp */
stackargslooparmFuncR0R1:
ldr r5, [r6], #4
str r5, [sp], #4
subs r7, r7, #4
bne stackargslooparmFuncR0R1
mov sp, r12
nomoreargsarmFuncR0R1:
#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
mov lr, pc /* older ARM didn't support blx */
mov pc, r4
#else
blx r4
#endif
add sp, sp, r8
ldmia sp!, {r4-r8, pc}
/* --------------------------------------------------------------------------------------------*/
#elif defined(__linux__) && !defined(__SOFTFP__) && !defined(__ARM_PCS)
/* The Linux with hard-float ABI code goes here */
/* These codes are suitable for armeabi + vfp / armeabihf */
/* when using armeabi + vfp, please set C_FLAGS -mfloat-abi=softfp -mfpu=vfp */
/* using armeabihf, please set C_FLAGS -mfloat-abi=hard -mfpu=vfpv3-d16 */
/* if you prefer to run in ARM mode, please add -marm to C_FLAGS */
/* while using thumb mode, please add -mthumb -Wa,-mimplicit-it=thumb */
/* SP is a multiple of 8 when control first enters a program.*/
/* This places an obligation on authors of low level OS, RTOS, and runtime library code to align SP at all points */
/* at which control first enters a body of (AAPCS-conforming) code. (please read "ARM IHI 0046B" document)*/
.section .text
.align 2 /* Align the function code to a 4-byte (2^n) word boundary. */
#if defined(__thumb__) || defined(__thumb2__)
.thumb
.syntax unified
#else
.arm /* Use ARM instructions instead of Thumb.*/
#endif
.globl armFunc /* Make the function globally accessible.*/
armFunc:
push {r4-r8, r10, r11, lr} /* sp must be 8-byte alignment for ABI compliance, so the pushed registers must be even */
mov r6, r0 /* arg table */
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
mov r4, r2 /* function address */
/* Load float and double args into d0-d7 and s0-s15 */
add r10, r6, #272 /* r10 (r6 + 272) points to the first value for the VFP registers */
mov r8, #0
vldmia.64 r10, {d0-d7} /* Load contents starting at r10 into registers d0-d7 */
/* If there are no arguments to set into r0-r3 */
/* go check if there are arguments for the stack */
beq stackargs
/* Load the first 4 arguments into r0-r3 */
cmp r7, #4
ldrge r0, [r6]
cmp r7, #8
ldrge r1, [r6, #4]
cmp r7, #12
ldrge r2, [r6, #8]
cmp r7, #16
ldrge r3, [r6, #12]
stackargs:
ldr r5, [r6, #268] /* Load stack size into r5 */
movs r7, r5 /* Load stack size into r7, checking for 0 args */
/* If there are no args for the stack, branch */
beq nomoreargs
/* Load the rest of the arguments onto the stack */
/* Ensure 8-byte stack alignment */
mov r8, sp
sub sp, sp, r7
add r6, r6, #16 /* Set r6 to point to the first arg to be placed on the stack */
sub r12, sp, #8
bic r12, r12, #7 /* thumb mode couldn't support "bic sp, sp, #7" instruction */
sub r8, r8, r12
mov sp, r12 /* copy size != frame size, so store frame start sp, r12(ip) is not callee saved register */
stackargsloop:
ldr r5, [r6], #4
subs r7, r7, #4
str r5, [sp], #4
bne stackargsloop
mov sp, r12
nomoreargs:
#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
mov lr, pc /* older ARM didn't support blx */
mov pc, r4
#else
blx r4
#endif
add sp, sp, r8
vstmia.64 r10, {d0-d7} /* Copy contents of registers d0-d7 to the address stored in r10 */
pop {r4-r8, r10, r11, pc}
/* --------------------------------------------------------------------------------------------*/
.align 2 /* Align the function code to a 4-byte (2^n) word boundary. */
#if defined(__thumb__) || defined(__thumb2__)
.thumb
.syntax unified
#else
.arm /* Use ARM instructions instead of Thumb.*/
#endif
.globl armFuncObjLast /* Make the function globally accessible.*/
armFuncObjLast:
push {r4-r8, r10, r11, lr} /* We<EFBFBD>re storing r11 just to keep the stack aligned to an 8 byte boundary */
mov r6, r0 /* arg table */
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
mov r4, r2 /* function address */
mov r0, r3 /* objlast. might get overwritten */
mov r5, #0 /* This will hold an offset of #4 only if objlast couldn<EFBFBD>t be placed into an "r" register */
/* Load float and double args into d0-d7 and s0-s15 (r10 holds pointer to first float value) */
add r10, r6, #272 /* r10 (r6 + 272) points to the first value for the VFP registers */
mov r8, #0
vldmia.64 r10, {d0-d7} /* Load contents starting at r10 into registers d0-d7 */
/* If there are no arguments to set into r0-r3 */
/* go check if there are arguments for the stack */
beq stackargsFuncObjLast
mov r5, r3 /* store objlast in r5 temporarily */
/* Load the first 4 arguments into r0-r3 */
cmp r7, #4
ldrge r0, [r6]
cmp r7, #8
ldrge r1, [r6,#4]
movlt r1, r5
cmp r7, #12
ldrge r2, [r6,#8]
movlt r2, r5
cmp r7, #16
ldrge r3, [r6,#12]
movlt r3, r5
movlt r5, #0 /* If objlast got placed into a register, r5 = 0 */
blt stackargsFuncObjLast /* If objlast got placed into a register, go to stackargsFuncObjLast */
str r5, [r6, #12] /* Put objlast in r6 + 12 */
mov r5, #4 /* Set r5 with an offset of #4, so objlast can be loaded into the stack */
stackargsFuncObjLast:
ldr r7, [r6, #268] /* Load stack size into r7 */
add r7, r7, r5 /* Add the offset placed in r5 (could be #0 or #4) */
cmp r7, #0 /* Check for 0 args */
/* If there are no args for the stack, branch */
beq nomoreargsarmFuncObjLast
/* Load the rest of the arguments onto the stack */
/* Ensure 8-byte stack alignment */
mov r8, sp
sub sp, sp, r7
add r6, r6, #16 /* Set r6 to point to the first arg to be placed on the stack */
sub r12, sp, #8
sub r6, r6, r5 /* r6 = r6 - r5 (r5 can be #0 or #4) */
bic r12, r12, #7 /* thumb mode couldn't support "bic sp, sp, #7" instruction */
sub r8, r8, r12
mov sp, r12 /* copy size != frame size, so store frame start sp, r12(ip) is not callee saved register */
stackargslooparmFuncObjLast:
ldr r5, [r6], #4
subs r7, r7, #4
str r5, [sp], #4
bne stackargslooparmFuncObjLast
mov sp, r12
nomoreargsarmFuncObjLast:
#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
mov lr, pc /* older ARM didn't support blx */
mov pc, r4
#else
blx r4
#endif
add sp, sp, r8
vstmia.64 r10, {d0-d7} /* Copy contents of registers d0-d10 to the address stored in r10 */
pop {r4-r8, r10,r11, pc}
/* ------------------------------------------------------------------------------------------- */
.align 2 /* Align the function code to a 4-byte (2^n) word boundary. */
#if defined(__thumb__) || defined(__thumb2__)
.thumb
.syntax unified
#else
.arm /* Use ARM instructions instead of Thumb.*/
#endif
.globl armFuncR0ObjLast /* Make the function globally accessible.*/
armFuncR0ObjLast:
push {r4-r8, r10, r11, lr}
ldr r5, [sp,#32] /* objlast to temp reg */
mov r6, r0 /* arg table */
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
mov r4, r2 /* function address */
mov r0, r3 /* r0 explicitly set */
mov r1, r5 /* objlast. might get overwritten */
mov r5, #0 /* This will hold an offset of #4 or #8 if objlast or one arg couldn<EFBFBD>t be placed into an "r" register */
/* Load float and double args into d0-d7 and s0-s15 (r10 holds pointer to first float value) */
add r10, r6, #272 /* r10 (r6 + 272) points to the first value for the VFP registers */
mov r8, #0
vldmia.64 r10, {d0-d7} /* Load contents starting at r10 into registers d0-d7 */
/* If there are no arguments to set into r0-r3 */
/* go check if there are arguments for the stack */
beq stackargsFuncR0ObjLast
mov r5, r1 /* store objlast in r5 temporarily */
/* Load the first 3 arguments into r1-r3 */
cmp r7, #4
ldrge r1, [r6]
cmp r7, #8
ldrge r2, [r6,#4]
movlt r2, r5
cmp r7, #12
ldrge r3, [r6,#8]
movlt r3, r5
movlt r5, #0 /* If objlast got placed into a register, r5 = 0 */
blt stackargsFuncR0ObjLast /* If objlast got placed into a register, go to stackargsFuncR0ObjLast */
cmp r7, #16 /* Else if we have one last arg set the offset accordingly and store the arg in the array */
ldrge r7, [r6, #12]
strge r7, [r6, #8]
str r5, [r6, #12] /* Put objlast in r6 + 12 */
mov r5, #0
movge r5, #4 /* Set r5 with an offset of #4 if there<EFBFBD>s one last arg that couldn<EFBFBD>t be placed in r registers */
add r5, r5, #4 /* Set r5 with an offset of + #4, so objlast can be loaded into the stack */
stackargsFuncR0ObjLast:
ldr r7, [r6, #268] /* Load stack size into r7 */
add r7, r7, r5 /* Add the offset placed in r5 (could be #0 or #4) */
cmp r7, #0 /* Check for 0 args */
/* If there are no args for the stack, branch */
beq nomoreargsarmFuncR0ObjLast
/* Load the rest of the arguments onto the stack */
/* Ensure 8-byte stack alignment */
mov r8, sp
sub sp, sp, r7
add r6, r6, #16 /* Set r6 to point to the first arg to be placed on the stack */
sub r12, sp, #8
sub r6, r6, r5 /* r6 = r6 - r5 (r5 can be #0 or #4) */
bic r12, r12, #7 /* thumb mode couldn't support "bic sp, sp, #7" instruction */
sub r8, r8, r12
mov sp, r12 /* copy size != frame size, so store frame start sp, r12(ip) is not callee saved register */
stackargslooparmFuncR0ObjLast:
ldr r5, [r6], #4
subs r7, r7, #4
str r5, [sp], #4
bne stackargslooparmFuncR0ObjLast
mov sp, r12
nomoreargsarmFuncR0ObjLast:
#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
mov lr, pc /* older ARM didn't support blx */
mov pc, r4
#else
blx r4
#endif
add sp, sp, r8
vstmia.64 r10, {d0-d7} /* Copy contents of registers d0-d10 to the address stored in r10 */
pop {r4-r8, r10, r11, pc}
/* ------------------------------------------------------------------------------------------- */
.align 2 /* Align the function code to a 4-byte (2^n) word boundary. */
#if defined(__thumb__) || defined(__thumb2__)
.thumb
.syntax unified
#else
.arm /* Use ARM instructions instead of Thumb.*/
#endif
.globl armFuncR0 /* Make the function globally accessible.*/
armFuncR0:
push {r4-r8, r10, r11, lr}
mov r6, r0 /* arg table */
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
mov r4, r2 /* function address */
mov r11, #0 /* This will hold an offset of #4 only if the last arg that should have been placed into an "r" reg needs to go to the stack */
mov r0, r3 /* r0 explicitly set */
/* Load float and double args into d0-d7 and s0-s15 (r10 holds pointer to first float value) */
add r10, r6, #272 /* r10 (r6 + 272) points to the first value for the VFP registers */
mov r8, #0
vldmia.64 r10, {d0-d7} /* Load contents starting at r10 into registers d0-d7 */
/* If there are no arguments to set into r0-r3 */
/* go check if there are arguments for the stack */
beq stackargsarmFuncR0
/* Load the first 3 arguments into r1-r3 */
cmp r7, #4
ldrge r1, [r6]
cmp r7, #8
ldrge r2, [r6, #4]
cmp r7, #12
ldrge r3, [r6, #8]
cmp r7, #16
movge r11, #4 /* If there is still one arg to be placed, set the offset in r11 to #4 */
stackargsarmFuncR0:
ldr r5, [r6, #268] /* Load stack size into r5 */
add r5, r11 /* Add the offset placed in r11 (could be #0 or #4) */
movs r7, r5 /* Load stack size into r7, checking for 0 args */
/* If there are no args for the stack, branch */
beq nomoreargsarmFuncR0
/* Load the rest of the arguments onto the stack */
/* Ensure 8-byte stack alignment */
mov r8, sp
sub sp, sp, r7
add r6, r6, #16 /* Set r6 to point to the first arg to be placed on the stack */
sub r12, sp, #8
sub r6, r6, r11 /* r6 = r6 - r11 (r11 can be #0 or #4) */
bic r12, r12, #7 /* thumb mode couldn't support "bic sp, sp, #7" instruction */
sub r8, r8, r12
mov sp, r12 /* copy size != frame size, so store frame start sp, r12(ip) is not callee saved register */
stackargslooparmFuncR0:
ldr r5, [r6], #4
subs r7, r7, #4
str r5, [sp], #4
bne stackargslooparmFuncR0
mov sp, r12
nomoreargsarmFuncR0:
#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
mov lr, pc /* older ARM didn't support blx */
mov pc, r4
#else
blx r4
#endif
add sp, sp, r8
vstmia.64 r10, {d0-d7} /* Copy contents of registers d0-d10 to the address stored in r10 */
pop {r4-r8, r10, r11, pc}
/* ------------------------------------------------------------------------------------------- */
.align 2 /* Align the function code to a 4-byte (2^n) word boundary. */
#if defined(__thumb__) || defined(__thumb2__)
.thumb
.syntax unified
#else
.arm /* Use ARM instructions instead of Thumb.*/
#endif
.globl armFuncR0R1 /* Make the function globally accessible.*/
armFuncR0R1:
push {r4-r8, r10, r11, lr}
mov r6, r0 /* arg table */
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
mov r4, r2 /* function address */
mov r11, #0 /* This will hold an offset of #4 or #8 only if the last arg (or last 2 args) that should have been placed into "r" regs need to go to the stack */
mov r0, r3 /* r0 explicitly set */
ldr r1, [sp, #32] /* r1 explicitly set too */
/* Load float and double args into d0-d7 and s0-s15 (r10 holds pointer to first float value) */
add r10, r6, #272 /* r10 (r6 + 272) points to the first value for the VFP registers */
mov r8, #0
vldmia.64 r10, {d0-d7} /* Load contents starting at r10 into registers d0-d7 */
/* If there are no arguments to set into r2-r3 */
/* go check if there are arguments for the stack */
beq stackargsarmFuncR0R1
/* Load the first 2 arguments into r2-r3 */
cmp r7, #4
ldrge r2, [r6]
cmp r7, #8
ldrge r3, [r6, #4]
cmp r7, #12
movge r11, #4 /* If there is a third arg to be placed, set the offset in r11 to #4 */
cmp r7, #16
movge r11, #8 /* If there is a fourth arg to be placed, set the offset in r11 to #8 */
ldrlt r7, [r6, #8] /* Else copy the third arg to the correct place in the array */
strlt r7, [r6, #12]
stackargsarmFuncR0R1:
ldr r5, [r6, #268] /* Load stack size into r5 */
add r5, r11 /* Add the offset placed in r11 (could be #0 or #4 or #8) */
movs r7, r5 /* Load stack size into r7, checking for 0 args */
/* If there are no args for the stack, branch */
beq nomoreargsarmFuncR0R1
/* Load the rest of the arguments onto the stack */
/* Ensure 8-byte stack alignment */
mov r8, sp
sub sp, sp, r7
add r6, r6, #16 /* Set r6 to point to the first arg to be placed on the stack */
sub r12, sp, #8
sub r6, r6, r11 /* r6 = r6 - r11 (r11 can be #0 or #4 or #8) */
bic r12, r12, #7 /* thumb mode couldn't support "bic sp, sp, #7" instruction */
sub r8, r8, r12
mov sp, r12 /* copy size != frame size, so store frame start sp, r12(ip) is not callee saved register */
stackargslooparmFuncR0R1:
ldr r5, [r6], #4
subs r7, r7, #4
str r5, [sp], #4
bne stackargslooparmFuncR0R1
mov sp, r12
nomoreargsarmFuncR0R1:
#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
mov lr, pc /* older ARM didn't support blx */
mov pc, r4
#else
blx r4
#endif
add sp, sp, r8
vstmia.64 r10, {d0-d7} /* Copy contents of registers d0-d10 to the address stored in r10 */
pop {r4-r8, r10, r11, pc}
#endif /* hard float abi */
#endif /* arm */
#if defined(__linux__) && defined(__ELF__)
/* ref: http://hardened.gentoo.org/gnu-stack.xml
ref: https://wiki.gentoo.org/wiki/Hardened/GNU_stack_quickstart */
.section .note.GNU-stack,"",%progbits
#endif
#endif /* !AS_MAX_PORTABILITY */

View File

@@ -0,0 +1,249 @@
;
; AngelCode Scripting Library
; Copyright (c) 2003-2014 Andreas Jonsson
;
; This software is provided 'as-is', without any express or implied
; warranty. In no event will the authors be held liable for any
; damages arising from the use of this software.
;
; Permission is granted to anyone to use this software for any
; purpose, including commercial applications, and to alter it and
; redistribute it freely, subject to the following restrictions:
;
; 1. The origin of this software must not be misrepresented; you
; must not claim that you wrote the original software. If you use
; this software in a product, an acknowledgment in the product
; documentation would be appreciated but is not required.
;
; 2. Altered source versions must be plainly marked as such, and
; must not be misrepresented as being the original software.
;
; 3. This notice may not be removed or altered from any source
; distribution.
;
; The original version of this library can be located at:
; http://www.angelcode.com/angelscript/
;
; Andreas Jonsson
; andreas@angelcode.com
;
; Assembly routines for the ARM call convention used for Windows CE
; Written by Fredrik Ehnbom in June 2009
; MSVC currently doesn't support inline assembly for the ARM platform
; so this separate file is needed.
; Compile with Microsoft ARM assembler (armasm)
; http://msdn.microsoft.com/en-us/library/hh873190.aspx
AREA |.rdata|, DATA, READONLY
EXPORT armFunc
EXPORT armFuncR0
EXPORT armFuncR0R1
EXPORT armFuncObjLast
EXPORT armFuncR0ObjLast
AREA |.text|, CODE, ARM, ALIGN=3
ALIGN 8
armFunc PROC
stmdb sp!, {r4-r8, lr}
mov r6, r0 ; arg table
movs r7, r1 ; arg size (also set the condition code flags so that we detect if there are no arguments)
mov r4, r2 ; function address
mov r8, #0
beq |nomoreargs|
; Load the first 4 arguments into r0-r3
cmp r7, #4
ldrge r0, [r6],#4
cmp r7, #2*4
ldrge r1, [r6],#4
cmp r7, #3*4
ldrge r2, [r6],#4
cmp r7, #4*4
ldrge r3, [r6],#4
ble |nomoreargs|
; Load the rest of the arguments onto the stack
sub r7, r7, #4*4 ; skip the 4 registers already loaded into r0-r3
sub sp, sp, r7
mov r8, r7
|stackargsloop|
ldr r5, [r6], #4
str r5, [sp], #4
subs r7, r7, #4
bne |stackargsloop|
|nomoreargs|
sub sp, sp, r8
blx r4
add sp, sp, r8
ldmia sp!, {r4-r8, pc}
ENDP
ALIGN 8
armFuncObjLast PROC
stmdb sp!, {r4-r8, lr}
mov r6, r0 ; arg table
movs r7, r1 ; arg size (also set the condition code flags so that we detect if there are no arguments)
mov r4, r2 ; function address
mov r8, #0
mov r0, r3 ; objlast. might get overwritten
str r3, [sp, #-4]! ; objlast again.
beq |nomoreargs@armFuncObjLast|
; Load the first 4 arguments into r0-r3
cmp r7, #4
ldrge r0, [r6],#4
cmp r7, #2*4
ldrge r1, [r6],#4
ldrlt r1, [sp]
cmp r7, #3*4
ldrge r2, [r6],#4
ldrlt r2, [sp]
cmp r7, #4*4
ldrge r3, [r6],#4
ldrlt r3, [sp]
ble |nomoreargs@armFuncObjLast|
; Load the rest of the arguments onto the stack
sub r7, r7, #4*4 ; skip the 4 registers already loaded into r0-r3
sub sp, sp, r7
mov r8, r7
|stackargsloop@armFuncObjLast|
ldr r5, [r6], #4
str r5, [sp], #4
subs r7, r7, #4
bne |stackargsloop@armFuncObjLast|
|nomoreargs@armFuncObjLast|
sub sp, sp, r8
blx r4
add sp, sp, r8
add sp, sp, #4
ldmia sp!, {r4-r8, pc}
ENDP
ALIGN 8
armFuncR0ObjLast PROC
stmdb sp!, {r4-r8, lr}
ldr r7, [sp,#6*4]
str r7, [sp,#-4]!
mov r6, r0 ; arg table
movs r7, r1 ; arg size (also set the condition code flags so that we detect if there are no arguments)
mov r4, r2 ; function address
mov r8, #0
mov r0, r3 ; r0 explicitly set
ldr r1, [sp] ; objlast. might get overwritten
beq |nomoreargs@armFuncR0ObjLast|
; Load the first 3 arguments into r1-r3
cmp r7, #1*4
ldrge r1, [r6],#4
cmp r7, #2*4
ldrge r2, [r6],#4
ldrlt r2, [sp]
cmp r7, #3*4
ldrge r3, [r6],#4
ldrlt r3, [sp]
ble |nomoreargs@armFuncR0ObjLast|
; Load the rest of the arguments onto the stack
sub r7, r7, #3*4 ; skip the 3 registers already loaded into r1-r3
sub sp, sp, r7
mov r8, r7
|stackargsloop@armFuncR0ObjLast|
ldr r5, [r6], #4
str r5, [sp], #4
subs r7, r7, #4
bne |stackargsloop@armFuncR0ObjLast|
|nomoreargs@armFuncR0ObjLast|
sub sp, sp, r8
blx r4
add sp, sp, r8
add sp, sp, #4
ldmia sp!, {r4-r8, pc}
ENDP
ALIGN 8
armFuncR0 PROC
stmdb sp!, {r4-r8, lr}
mov r6, r0 ; arg table
movs r7, r1 ; arg size (also set the condition code flags so that we detect if there are no arguments)
mov r4, r2 ; function address
mov r8, #0
mov r0, r3 ; r0 explicitly set
beq |nomoreargs@armFuncR0|
; Load the first 3 arguments into r1-r3
cmp r7, #1*4
ldrge r1, [r6],#4
cmp r7, #2*4
ldrge r2, [r6],#4
cmp r7, #3*4
ldrge r3, [r6],#4
ble |nomoreargs@armFuncR0|
; Load the rest of the arguments onto the stack
sub r7, r7, #3*4 ; skip the 3 registers already loaded into r1-r3
sub sp, sp, r7
mov r8, r7
|stackargsloop@armFuncR0|
ldr r5, [r6], #4
str r5, [sp], #4
subs r7, r7, #4
bne |stackargsloop@armFuncR0|
|nomoreargs@armFuncR0|
sub sp, sp, r8
blx r4
add sp, sp, r8
ldmia sp!, {r4-r8, pc}
ENDP
ALIGN 8
armFuncR0R1 PROC
stmdb sp!, {r4-r8, lr}
mov r6, r0 ; arg table
movs r7, r1 ; arg size (also set the condition code flags so that we detect if there are no arguments)
mov r4, r2 ; function address
mov r8, #0
mov r0, r3 ; r0 explicitly set
ldr r1, [sp, #6*4] ; r1 explicitly set too
beq |nomoreargs@armFuncR0R1|
; Load the first 2 arguments into r2-r3
cmp r7, #1*4
ldrge r2, [r6],#4
cmp r7, #2*4
ldrge r3, [r6],#4
ble |nomoreargs@armFuncR0R1|
; Load the rest of the arguments onto the stack
sub r7, r7, #2*4 ; skip the 2 registers already loaded into r2-r3
sub sp, sp, r7
mov r8, r7
|stackargsloop@armFuncR0R1|
ldr r5, [r6], #4
str r5, [sp], #4
subs r7, r7, #4
bne |stackargsloop@armFuncR0R1|
|nomoreargs@armFuncR0R1|
sub sp, sp, r8
blx r4
add sp, sp, r8
ldmia sp!, {r4-r8, pc}
ENDP
END

View File

@@ -0,0 +1,485 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
/*
Assembly routines for the Playstation Vita SNC call convention.
This code was adapted from as_callfunc_arm_gcc (ARM, Linux hard float) by Brandon Bare on October 2014.
*/
#if !defined(AS_MAX_PORTABILITY)
#ifdef __psp2__
.syntax unified
.cpu cortex-a9
.fpu neon
.section .text.armCallFunc
.balign 2
.thumb
.thumb_func
.align 2
.global armFunc
.global armFuncR0
.global armFuncR0R1
.global armFuncObjLast
.global armFuncR0ObjLast
.type armFunc, %function
.type armFuncR0, %function
.type armFuncR0R1, %function
.type armFuncObjLast, %function
.type armFuncR0ObjLast, %function
/* --------------------------------------------------------------------------------------------*/
armFunc:
.fnstart
push {r4-r8, r10, r11, lr} /* sp must be 8-byte alignment for ABI compliance, so the pushed registers must be even */
mov r6, r0 /* arg table */
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
mov r4, r2 /* function address */
/* Load float and double args into d0-d7 and s0-s15 */
add r10, r6, #272 /* r10 (r6 + 272) points to the first value for the VFP registers */
mov r8, #0
vldmia.64 r10, {d0-d7} /* Load contents starting at r10 into registers d0-d7 */
/* If there are no arguments to set into r0-r3 */
/* go check if there are arguments for the stack */
beq stackargs
/* Load the first 4 arguments into r0-r3 */
cmp r7, #4
it ge
ldrge r0, [r6]
cmp r7, #8
it ge
ldrge r1, [r6, #4]
cmp r7, #12
it ge
ldrge r2, [r6, #8]
cmp r7, #16
it ge
ldrge r3, [r6, #12]
stackargs:
ldr r5, [r6, #268] /* Load stack size into r5 */
movs r7, r5 /* Load stack size into r7, checking for 0 args */
/* If there are no args for the stack, branch */
beq nomoreargs
/* Load the rest of the arguments onto the stack */
/* Ensure 8-byte stack alignment */
mov r8, sp
sub sp, sp, r7
add r6, r6, #16 /* Set r6 to point to the first arg to be placed on the stack */
sub r12, sp, #8
bic r12, r12, #7 /* thumb mode couldn't support "bic sp, sp, #7" instruction */
sub r8, r8, r12
mov sp, r12 /* copy size != frame size, so store frame start sp, r12(ip) is not callee saved register */
stackargsloop:
ldr r5, [r6], #4
subs r7, r7, #4
str r5, [sp], #4
bne stackargsloop
mov sp, r12
nomoreargs:
blx r4
add sp, sp, r8
vstmia.64 r10, {d0-d7} /* Copy contents of registers d0-d7 to the address stored in r10 */
pop {r4-r8, r10, r11, pc}
.fnend
/* --------------------------------------------------------------------------------------------*/
armFuncObjLast:
.fnstart
push {r4-r8, r10, r11, lr} /* We<EFBFBD>re storing r11 just to keep the stack aligned to an 8 byte boundary */
mov r6, r0 /* arg table */
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
mov r4, r2 /* function address */
mov r0, r3 /* objlast. might get overwritten */
mov r5, #0 /* This will hold an offset of #4 only if objlast couldn<EFBFBD>t be placed into an "r" register */
/* Load float and double args into d0-d7 and s0-s15 (r10 holds pointer to first float value) */
add r10, r6, #272 /* r10 (r6 + 272) points to the first value for the VFP registers */
mov r8, #0
vldmia.64 r10, {d0-d7} /* Load contents starting at r10 into registers d0-d7 */
/* If there are no arguments to set into r0-r3 */
/* go check if there are arguments for the stack */
beq stackargsFuncObjLast
mov r5, r3 /* store objlast in r5 temporarily */
/* Load the first 4 arguments into r0-r3 */
cmp r7, #4
it ge
ldrge r0, [r6]
cmp r7, #8
it ge
ldrge r1, [r6,#4]
it lt
movlt r1, r5
cmp r7, #12
it ge
ldrge r2, [r6,#8]
it lt
movlt r2, r5
cmp r7, #16
it ge
ldrge r3, [r6,#12]
ittt lt
movlt r3, r5
movlt r5, #0 /* If objlast got placed into a register, r5 = 0 */
blt stackargsFuncObjLast /* If objlast got placed into a register, go to stackargsFuncObjLast */
str r5, [r6, #12] /* Put objlast in r6 + 12 */
mov r5, #4 /* Set r5 with an offset of #4, so objlast can be loaded into the stack */
stackargsFuncObjLast:
ldr r7, [r6, #268] /* Load stack size into r7 */
add r7, r7, r5 /* Add the offset placed in r5 (could be #0 or #4) */
cmp r7, #0 /* Check for 0 args */
/* If there are no args for the stack, branch */
beq nomoreargsarmFuncObjLast
/* Load the rest of the arguments onto the stack */
/* Ensure 8-byte stack alignment */
mov r8, sp
sub sp, sp, r7
add r6, r6, #16 /* Set r6 to point to the first arg to be placed on the stack */
sub r12, sp, #8
sub r6, r6, r5 /* r6 = r6 - r5 (r5 can be #0 or #4) */
bic r12, r12, #7 /* thumb mode couldn't support "bic sp, sp, #7" instruction */
sub r8, r8, r12
mov sp, r12 /* copy size != frame size, so store frame start sp, r12(ip) is not callee saved register */
stackargslooparmFuncObjLast:
ldr r5, [r6], #4
subs r7, r7, #4
str r5, [sp], #4
bne stackargslooparmFuncObjLast
mov sp, r12
nomoreargsarmFuncObjLast:
blx r4
add sp, sp, r8
vstmia.64 r10, {d0-d7} /* Copy contents of registers d0-d10 to the address stored in r10 */
pop {r4-r8, r10,r11, pc}
.fnend
/* --------------------------------------------------------------------------------------------*/
armFuncR0ObjLast:
.fnstart
push {r4-r8, r10, r11, lr}
ldr r5, [sp,#32] /* objlast to temp reg */
mov r6, r0 /* arg table */
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
mov r4, r2 /* function address */
mov r0, r3 /* r0 explicitly set */
mov r1, r5 /* objlast. might get overwritten */
mov r5, #0 /* This will hold an offset of #4 or #8 if objlast or one arg couldn<EFBFBD>t be placed into an "r" register */
/* Load float and double args into d0-d7 and s0-s15 (r10 holds pointer to first float value) */
add r10, r6, #272 /* r10 (r6 + 272) points to the first value for the VFP registers */
mov r8, #0
vldmia.64 r10, {d0-d7} /* Load contents starting at r10 into registers d0-d7 */
/* If there are no arguments to set into r0-r3 */
/* go check if there are arguments for the stack */
beq stackargsFuncR0ObjLast
mov r5, r1 /* store objlast in r5 temporarily */
/* Load the first 3 arguments into r1-r3 */
cmp r7, #4
it ge
ldrge r1, [r6]
cmp r7, #8
it ge
ldrge r2, [r6,#4]
it lt
movlt r2, r5
cmp r7, #12
it ge
ldrge r3, [r6,#8]
ittt lt
movlt r3, r5
movlt r5, #0 /* If objlast got placed into a register, r5 = 0 */
blt stackargsFuncR0ObjLast /* If objlast got placed into a register, go to stackargsFuncR0ObjLast */
cmp r7, #16 /* Else if we have one last arg set the offset accordingly and store the arg in the array */
itt ge
ldrge r7, [r6, #12]
strge r7, [r6, #8]
str r5, [r6, #12] /* Put objlast in r6 + 12 */
mov r5, #0
it ge
movge r5, #4 /* Set r5 with an offset of #4 if there<EFBFBD>s one last arg that couldn<EFBFBD>t be placed in r registers */
add r5, r5, #4 /* Set r5 with an offset of + #4, so objlast can be loaded into the stack */
stackargsFuncR0ObjLast:
ldr r7, [r6, #268] /* Load stack size into r7 */
add r7, r7, r5 /* Add the offset placed in r5 (could be #0 or #4) */
cmp r7, #0 /* Check for 0 args */
/* If there are no args for the stack, branch */
beq nomoreargsarmFuncR0ObjLast
/* Load the rest of the arguments onto the stack */
/* Ensure 8-byte stack alignment */
mov r8, sp
sub sp, sp, r7
add r6, r6, #16 /* Set r6 to point to the first arg to be placed on the stack */
sub r12, sp, #8
sub r6, r6, r5 /* r6 = r6 - r5 (r5 can be #0 or #4) */
bic r12, r12, #7 /* thumb mode couldn't support "bic sp, sp, #7" instruction */
sub r8, r8, r12
mov sp, r12 /* copy size != frame size, so store frame start sp, r12(ip) is not callee saved register */
stackargslooparmFuncR0ObjLast:
ldr r5, [r6], #4
subs r7, r7, #4
str r5, [sp], #4
bne stackargslooparmFuncR0ObjLast
mov sp, r12
nomoreargsarmFuncR0ObjLast:
blx r4
add sp, sp, r8
vstmia.64 r10, {d0-d7} /* Copy contents of registers d0-d10 to the address stored in r10 */
pop {r4-r8, r10, r11, pc}
.fnend
/* --------------------------------------------------------------------------------------------*/
armFuncR0:
.fnstart
push {r4-r8, r10, r11, lr}
mov r6, r0 /* arg table */
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
mov r4, r2 /* function address */
mov r11, #0 /* This will hold an offset of #4 only if the last arg that should have been placed into an "r" reg needs to go to the stack */
mov r0, r3 /* r0 explicitly set */
/* Load float and double args into d0-d7 and s0-s15 (r10 holds pointer to first float value) */
add r10, r6, #272 /* r10 (r6 + 272) points to the first value for the VFP registers */
mov r8, #0
vldmia.64 r10, {d0-d7} /* Load contents starting at r10 into registers d0-d7 */
/* If there are no arguments to set into r0-r3 */
/* go check if there are arguments for the stack */
beq stackargsarmFuncR0
/* Load the first 3 arguments into r1-r3 */
cmp r7, #4
it ge
ldrge r1, [r6]
cmp r7, #8
it ge
ldrge r2, [r6, #4]
cmp r7, #12
it ge
ldrge r3, [r6, #8]
cmp r7, #16
it ge
movge r11, #4 /* If there is still one arg to be placed, set the offset in r11 to #4 */
stackargsarmFuncR0:
ldr r5, [r6, #268] /* Load stack size into r5 */
add r5, r11 /* Add the offset placed in r11 (could be #0 or #4) */
movs r7, r5 /* Load stack size into r7, checking for 0 args */
/* If there are no args for the stack, branch */
beq nomoreargsarmFuncR0
/* Load the rest of the arguments onto the stack */
/* Ensure 8-byte stack alignment */
mov r8, sp
sub sp, sp, r7
add r6, r6, #16 /* Set r6 to point to the first arg to be placed on the stack */
sub r12, sp, #8
sub r6, r6, r11 /* r6 = r6 - r11 (r11 can be #0 or #4) */
bic r12, r12, #7 /* thumb mode couldn't support "bic sp, sp, #7" instruction */
sub r8, r8, r12
mov sp, r12 /* copy size != frame size, so store frame start sp, r12(ip) is not callee saved register */
stackargslooparmFuncR0:
ldr r5, [r6], #4
subs r7, r7, #4
str r5, [sp], #4
bne stackargslooparmFuncR0
mov sp, r12
nomoreargsarmFuncR0:
blx r4
add sp, sp, r8
vstmia.64 r10, {d0-d7} /* Copy contents of registers d0-d10 to the address stored in r10 */
pop {r4-r8, r10, r11, pc}
.fnend
/* --------------------------------------------------------------------------------------------*/
armFuncR0R1:
.fnstart
push {r4-r8, r10, r11, lr}
mov r6, r0 /* arg table */
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
mov r4, r2 /* function address */
mov r11, #0 /* This will hold an offset of #4 or #8 only if the last arg (or last 2 args) that should have been placed into "r" regs need to go to the stack */
mov r0, r3 /* r0 explicitly set */
ldr r1, [sp, #32] /* r1 explicitly set too */
/* Load float and double args into d0-d7 and s0-s15 (r10 holds pointer to first float value) */
add r10, r6, #272 /* r10 (r6 + 272) points to the first value for the VFP registers */
mov r8, #0
vldmia.64 r10, {d0-d7} /* Load contents starting at r10 into registers d0-d7 */
/* If there are no arguments to set into r2-r3 */
/* go check if there are arguments for the stack */
beq stackargsarmFuncR0R1
/* Load the first 2 arguments into r2-r3 */
cmp r7, #4
it ge
ldrge r2, [r6]
cmp r7, #8
it ge
ldrge r3, [r6, #4]
cmp r7, #12
it ge
movge r11, #4 /* If there is a third arg to be placed, set the offset in r11 to #4 */
cmp r7, #16
it ge
movge r11, #8 /* If there is a fourth arg to be placed, set the offset in r11 to #8 */
itt lt
ldrlt r7, [r6, #8] /* Else copy the third arg to the correct place in the array */
strlt r7, [r6, #12]
stackargsarmFuncR0R1:
ldr r5, [r6, #268] /* Load stack size into r5 */
add r5, r11 /* Add the offset placed in r11 (could be #0 or #4 or #8) */
movs r7, r5 /* Load stack size into r7, checking for 0 args */
/* If there are no args for the stack, branch */
beq nomoreargsarmFuncR0R1
/* Load the rest of the arguments onto the stack */
/* Ensure 8-byte stack alignment */
mov r8, sp
sub sp, sp, r7
add r6, r6, #16 /* Set r6 to point to the first arg to be placed on the stack */
sub r12, sp, #8
sub r6, r6, r11 /* r6 = r6 - r11 (r11 can be #0 or #4 or #8) */
bic r12, r12, #7 /* thumb mode couldn't support "bic sp, sp, #7" instruction */
sub r8, r8, r12
mov sp, r12 /* copy size != frame size, so store frame start sp, r12(ip) is not callee saved register */
stackargslooparmFuncR0R1:
ldr r5, [r6], #4
subs r7, r7, #4
str r5, [sp], #4
bne stackargslooparmFuncR0R1
mov sp, r12
nomoreargsarmFuncR0R1:
blx r4
add sp, sp, r8
vstmia.64 r10, {d0-d7} /* Copy contents of registers d0-d10 to the address stored in r10 */
pop {r4-r8, r10, r11, pc}
.fnend
#endif
#endif /* !AS_MAX_PORTABILITY */

View File

@@ -0,0 +1,242 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
// Assembly routines for the ARM call convention
// Written by Fredrik Ehnbom in June 2009
// Adapted to GNUC by darktemplar216 in September 2009
// Small fixed to work under XCode GCC by Gilad Novik in October 2009
#if !defined(AS_MAX_PORTABILITY)
#if defined(__arm__) || defined(__ARM__)
.align 2
.globl _armFunc
.globl _armFuncR0
.globl _armFuncR0R1
.globl _armFuncObjLast
.globl _armFuncR0ObjLast
_armFunc:
stmdb sp!, {r4-r8, lr}
mov r6, r0 // arg table
movs r7, r1 // arg size (also set the condition code flags so that we detect if there are no arguments)
mov r4, r2 // function address
mov r8, #0
beq nomoreargs
// Load the first 4 arguments into r0-r3
cmp r7, #4
ldrge r0, [r6],#4
cmp r7, #2*4
ldrge r1, [r6],#4
cmp r7, #3*4
ldrge r2, [r6],#4
cmp r7, #4*4
ldrge r3, [r6],#4
ble nomoreargs
// Load the rest of the arguments onto the stack
sub r7, r7, #4*4 // skip the 4 registers already loaded into r0-r3
sub sp, sp, r7
mov r8, r7
stackargsloop:
ldr r5, [r6], #4
str r5, [sp], #4
subs r7, r7, #4
bne stackargsloop
nomoreargs:
sub sp, sp, r8
blx r4
add sp, sp, r8
ldmia sp!, {r4-r8, pc}
_armFuncObjLast:
stmdb sp!, {r4-r8, lr}
mov r6, r0 // arg table
movs r7, r1 // arg size (also set the condition code flags so that we detect if there are no arguments)
mov r4, r2 // function address
mov r8, #0
mov r0, r3 // objlast. might get overwritten
str r3, [sp, #-4]! // objlast again.
beq nomoreargsarmFuncObjLast
// Load the first 4 arguments into r0-r3
cmp r7, #4
ldrge r0, [r6],#4
cmp r7, #2*4
ldrge r1, [r6],#4
ldrlt r1, [sp]
cmp r7, #3*4
ldrge r2, [r6],#4
ldrlt r2, [sp]
cmp r7, #4*4
ldrge r3, [r6],#4
ldrlt r3, [sp]
ble nomoreargsarmFuncObjLast
// Load the rest of the arguments onto the stack
sub r7, r7, #4*4 // skip the 4 registers already loaded into r0-r3
sub sp, sp, r7
mov r8, r7
stackargslooparmFuncObjLast:
ldr r5, [r6], #4
str r5, [sp], #4
subs r7, r7, #4
bne stackargslooparmFuncObjLast
nomoreargsarmFuncObjLast:
sub sp, sp, r8
blx r4
add sp, sp, r8
add sp, sp, #4
ldmia sp!, {r4-r8, pc}
_armFuncR0ObjLast:
stmdb sp!, {r4-r8, lr}
ldr r7, [sp,#6*4]
str r7, [sp,#-4]!
mov r6, r0 // arg table
movs r7, r1 // arg size (also set the condition code flags so that we detect if there are no arguments)
mov r4, r2 // function address
mov r8, #0
mov r0, r3 // r0 explicitly set
ldr r1, [sp] // objlast. might get overwritten
beq nomoreargsarmFuncR0ObjLast
// Load the first 3 arguments into r1-r3
cmp r7, #1*4
ldrge r1, [r6],#4
cmp r7, #2*4
ldrge r2, [r6],#4
ldrlt r2, [sp]
cmp r7, #3*4
ldrge r3, [r6],#4
ldrlt r3, [sp]
ble nomoreargsarmFuncR0ObjLast
// Load the rest of the arguments onto the stack
sub r7, r7, #3*4 // skip the 3 registers already loaded into r1-r3
sub sp, sp, r7
mov r8, r7
stackargslooparmFuncR0ObjLast:
ldr r5, [r6], #4
str r5, [sp], #4
subs r7, r7, #4
bne stackargslooparmFuncR0ObjLast
nomoreargsarmFuncR0ObjLast:
sub sp, sp, r8
blx r4
add sp, sp, r8
add sp, sp, #4
ldmia sp!, {r4-r8, pc}
_armFuncR0:
stmdb sp!, {r4-r8, lr}
mov r6, r0 // arg table
movs r7, r1 // arg size (also set the condition code flags so that we detect if there are no arguments)
mov r4, r2 // function address
mov r8, #0
mov r0, r3 // r0 explicitly set
beq nomoreargsarmFuncR0
// Load the first 3 arguments into r1-r3
cmp r7, #1*4
ldrge r1, [r6],#4
cmp r7, #2*4
ldrge r2, [r6],#4
cmp r7, #3*4
ldrge r3, [r6],#4
ble nomoreargsarmFuncR0
// Load the rest of the arguments onto the stack
sub r7, r7, #3*4 // skip the 3 registers already loaded into r1-r3
sub sp, sp, r7
mov r8, r7
stackargslooparmFuncR0:
ldr r5, [r6], #4
str r5, [sp], #4
subs r7, r7, #4
bne stackargslooparmFuncR0
nomoreargsarmFuncR0:
sub sp, sp, r8
blx r4
add sp, sp, r8
ldmia sp!, {r4-r8, pc}
_armFuncR0R1:
stmdb sp!, {r4-r8, lr}
mov r6, r0 // arg table
movs r7, r1 // arg size (also set the condition code flags so that we detect if there are no arguments)
mov r4, r2 // function address
mov r8, #0
mov r0, r3 // r0 explicitly set
ldr r1, [sp, #6*4] // r1 explicitly set too
beq nomoreargsarmFuncR0R1
// Load the first 2 arguments into r2-r3
cmp r7, #1*4
ldrge r2, [r6],#4
cmp r7, #2*4
ldrge r3, [r6],#4
ble nomoreargsarmFuncR0R1
// Load the rest of the arguments onto the stack
sub r7, r7, #2*4 // skip the 2 registers already loaded into r2-r3
sub sp, sp, r7
mov r8, r7
stackargslooparmFuncR0R1:
ldr r5, [r6], #4
str r5, [sp], #4
subs r7, r7, #4
bne stackargslooparmFuncR0R1
nomoreargsarmFuncR0R1:
sub sp, sp, r8
blx r4
add sp, sp, r8
ldmia sp!, {r4-r8, pc}
#endif
#endif /* !AS_MAX_PORTABILITY */

View File

@@ -0,0 +1,735 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_callfunc_mips.cpp
//
// These functions handle the actual calling of system functions
//
// This version is MIPS specific and was originally written
// by Manu Evans in April, 2006 for Playstation Portable (PSP)
//
// Support for Linux with MIPS was added by Andreas Jonsson in April, 2015
//
#include "as_config.h"
#ifndef AS_MAX_PORTABILITY
#ifdef AS_MIPS
#include "as_callfunc.h"
#include "as_scriptengine.h"
#include "as_texts.h"
#include "as_tokendef.h"
#include "as_context.h"
#include <stdio.h>
#include <stdlib.h>
#if !defined(AS_ANDROID)
#include <regdef.h>
#endif
BEGIN_AS_NAMESPACE
#if defined(__linux__) && defined(_ABIO32)
// The MIPS ABI used by Linux is implemented here
// (Tested on CI20 MIPS Creator with Debian Linux)
//
// ref: SYSTEM V
// APPLICATION BINARY INTERFACE
// MIPS RISC Processor
// http://math-atlas.sourceforge.net/devel/assembly/mipsabi32.pdf
//
// ref: MIPS Instruction Reference
// http://www.mrc.uidaho.edu/mrc/people/jff/digital/MIPSir.html
union SFloatRegs
{
union { double d0; struct { float f0; asDWORD dummy0; };};
union { double d1; struct { float f1; asDWORD dummy1; };};
} ;
extern "C" asQWORD mipsFunc(asUINT argSize, asDWORD *argBuffer, void *func, SFloatRegs &floatRegs);
asDWORD GetReturnedFloat();
asQWORD GetReturnedDouble();
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void *secondObject)
{
asCScriptEngine *engine = context->m_engine;
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
int callConv = sysFunc->callConv;
asQWORD retQW = 0;
void *func = (void*)sysFunc->func;
void **vftable;
asDWORD argBuffer[128]; // Ought to be big enough
asASSERT( sysFunc->paramSize < 128 );
asDWORD argOffset = 0;
SFloatRegs floatRegs;
asDWORD floatOffset = 0;
// If the application function returns the value in memory then
// the first argument must be the pointer to that memory
if( sysFunc->hostReturnInMemory )
{
asASSERT( retPointer );
argBuffer[argOffset++] = (asPWORD)retPointer;
}
if( callConv == ICC_CDECL_OBJFIRST || callConv == ICC_CDECL_OBJFIRST_RETURNINMEM ||
callConv == ICC_THISCALL || callConv == ICC_THISCALL_RETURNINMEM ||
callConv == ICC_VIRTUAL_THISCALL || callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM ||
callConv == ICC_THISCALL_OBJFIRST || callConv == ICC_VIRTUAL_THISCALL_OBJFIRST ||
callConv == ICC_THISCALL_OBJFIRST_RETURNINMEM || callConv == ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM ||
callConv == ICC_THISCALL_OBJLAST || callConv == ICC_VIRTUAL_THISCALL_OBJLAST ||
callConv == ICC_THISCALL_OBJLAST_RETURNINMEM || callConv == ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM )
{
// Add the object pointer as the first argument
argBuffer[argOffset++] = (asPWORD)obj;
}
if( callConv == ICC_THISCALL_OBJFIRST || callConv == ICC_VIRTUAL_THISCALL_OBJFIRST ||
callConv == ICC_THISCALL_OBJFIRST_RETURNINMEM || callConv == ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM )
{
// Add the second object pointer
argBuffer[argOffset++] = (asPWORD)secondObject;
}
int spos = 0;
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
{
asCDataType &paramType = descr->parameterTypes[n];
if( paramType.IsObject() && !paramType.IsObjectHandle() && !paramType.IsReference() )
{
if( paramType.GetTypeInfo()->flags & COMPLEX_MASK )
{
// The object is passed by reference
argBuffer[argOffset++] = args[spos++];
}
else
{
// Ensure 8byte alignment for classes that need it
if( (paramType.GetTypeInfo()->flags & asOBJ_APP_CLASS_ALIGN8) && (argOffset & 1) )
argOffset++;
// Copy the object's memory to the buffer
memcpy(&argBuffer[argOffset], *(void**)(args+spos), paramType.GetSizeInMemoryBytes());
// Delete the original memory
engine->CallFree(*(char**)(args+spos));
spos++;
argOffset += paramType.GetSizeInMemoryDWords();
}
}
else if( paramType.GetTokenType() == ttQuestion )
{
// Copy both pointer and type id
argBuffer[argOffset++] = args[spos++];
argBuffer[argOffset++] = args[spos++];
}
else
{
// The first 2 floats or doubles are loaded into the float registers.
// Actually this is only done if they are the first arguments to the function,
// but it doesn't cause any harm to load them into the registers even if they
// won't be used so we don't need to check if they really are the first args.
if( floatOffset == 0 )
{
if( paramType.GetTokenType() == ttFloat )
floatRegs.f0 = *reinterpret_cast<float*>(&args[spos]);
else if( paramType.GetTokenType() == ttDouble )
floatRegs.d0 = *reinterpret_cast<double*>(&args[spos]);
floatOffset++;
}
else if( floatOffset == 1 )
{
if( paramType.GetTokenType() == ttFloat )
floatRegs.f1 = *reinterpret_cast<float*>(&args[spos]);
else if( paramType.GetTokenType() == ttDouble )
floatRegs.d1 = *reinterpret_cast<double*>(&args[spos]);
floatOffset++;
}
// Copy the value directly
if( paramType.GetSizeOnStackDWords() > 1 )
{
// Make sure the argument is 8byte aligned
if( argOffset & 1 )
argOffset++;
*reinterpret_cast<asQWORD*>(&argBuffer[argOffset]) = *reinterpret_cast<asQWORD*>(&args[spos]);
argOffset += 2;
spos += 2;
}
else
argBuffer[argOffset++] = args[spos++];
}
}
if( callConv == ICC_CDECL_OBJLAST || callConv == ICC_CDECL_OBJLAST_RETURNINMEM )
{
// Add the object pointer as the last argument
argBuffer[argOffset++] = (asPWORD)obj;
}
if( callConv == ICC_THISCALL_OBJLAST || callConv == ICC_VIRTUAL_THISCALL_OBJLAST ||
callConv == ICC_THISCALL_OBJLAST_RETURNINMEM || callConv == ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM )
{
// Add the second object pointer
argBuffer[argOffset++] = (asPWORD)secondObject;
}
switch( callConv )
{
case ICC_CDECL:
case ICC_CDECL_RETURNINMEM:
case ICC_STDCALL:
case ICC_STDCALL_RETURNINMEM:
case ICC_CDECL_OBJLAST:
case ICC_CDECL_OBJLAST_RETURNINMEM:
case ICC_CDECL_OBJFIRST:
case ICC_CDECL_OBJFIRST_RETURNINMEM:
case ICC_THISCALL:
case ICC_THISCALL_RETURNINMEM:
case ICC_THISCALL_OBJFIRST:
case ICC_THISCALL_OBJFIRST_RETURNINMEM:
case ICC_THISCALL_OBJLAST:
case ICC_THISCALL_OBJLAST_RETURNINMEM:
retQW = mipsFunc(argOffset*4, argBuffer, func, floatRegs);
break;
case ICC_VIRTUAL_THISCALL:
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
case ICC_VIRTUAL_THISCALL_OBJFIRST:
case ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM:
case ICC_VIRTUAL_THISCALL_OBJLAST:
case ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM:
// Get virtual function table from the object pointer
vftable = *(void***)obj;
retQW = mipsFunc(argOffset*4, argBuffer, vftable[asPWORD(func)>>2], floatRegs);
break;
default:
context->SetInternalException(TXT_INVALID_CALLING_CONVENTION);
}
// If the return is a float value we need to get the value from the FP register
if( sysFunc->hostReturnFloat )
{
if( sysFunc->hostReturnSize == 1 )
*(asDWORD*)&retQW = GetReturnedFloat();
else
retQW = GetReturnedDouble();
}
return retQW;
}
asDWORD GetReturnedFloat()
{
asDWORD f;
asm("swc1 $f0, %0\n" : "=m"(f));
return f;
}
asQWORD GetReturnedDouble()
{
asQWORD d = 0;
asm("sdc1 $f0, %0\n" : "=m"(d));
return d;
}
// asQWORD mipsFunc(asUINT argSize, asDWORD *argBuffer, void *func, SFloatRegs &floatRegs);
// $2,$3 $4 $5 $6 $7
asm(
" .text\n"
//" .align 2\n"
" .cfi_startproc\n"
" .global mipsFunc\n"
" .ent mipsFunc\n"
"mipsFunc:\n"
//" .frame $fp,64,$31 # vars= 0, regs= 0/0, args= 0, gp= 0\n"
//" .mask 0x00000000,0\n"
//" .fmask 0x00000000,0\n"
" .set noreorder\n"
" .set nomacro\n"
// align the stack frame to 8 bytes
" addiu $12, $4, 7\n" // t4 ($12) = argSize ($4) + 7
" li $13, -8\n" // t5 ($13) = 0xfffffffffffffff8
" and $12, $12, $13\n" // t4 ($12) &= t5 ($13). t4 holds the size of the argument block
// It is required that the caller reserves space for at least 16 bytes even if there are less than 4 arguments
// and add 8 bytes for the return pointer and s0 ($16) backup
" addiu $13, $12, 24\n" // t5 = t4 + 24. t5 ($13) holds the total size of the stack frame (including return pointer)
// save the s0 register (so we can use it to remember where our return pointer is lives)
" sw $16, -4($sp)\n" // store the s0 register (so we can use it to remember how big our stack frame is)
" .cfi_offset 16, -4\n"
// store the return pointer
" sw $31, -8($sp)\n"
" .cfi_offset 31, -8\n"
// keep original stack pointer
" move $16, $sp\n"
" .cfi_def_cfa_register 16\n"
// push the stack
" subu $sp, $sp, $13\n"
// store the argument in temporary registers
" addiu $25, $6, 0\n" // t9 ($25) holds the function pointer (must be t9 for position independent code)
" addiu $3, $4, 0\n" // v1 ($3) holds the size of the argument buffer
" move $15, $5\n" // t7 ($15) holds the pointer to the argBuffer
" move $14, $7\n" // t6 ($14) holds the values for the float registers
// load integer registers
" lw $4, 0($15)\n" // a0 ($4)
" lw $5, 4($15)\n" // a1 ($5)
" lw $6, 8($15)\n" // a2 ($6)
" lw $7, 12($15)\n" // a3 ($7)
// load float registers
" ldc1 $f12, 8($14)\n"
" ldc1 $f14, 0($14)\n"
// skip stack parameters if there are 4 or less as they are moved into the registers
" addi $14, $3, -16\n" // The first 4 args were already loaded into registers
" blez $14, andCall\n"
" nop\n"
// push stack parameters
"pushArgs:\n"
" addi $3, -4\n"
// load from $15 + stack bytes ($3)
" addu $14, $15, $3\n"
" lw $14, 0($14)\n"
// store to $sp + stack bytes ($3)
" addu $13, $sp, $3\n"
" sw $14, 0($13)\n"
// if there are more, loop...
" bne $3, $0, pushArgs\n"
" nop\n"
// and call the function
"andCall:\n"
" jalr $25\n"
" nop\n"
// restore original stack pointer
" move $sp, $16\n"
// restore the return pointer
" lw $31, -8($sp)\n"
// restore the original value of $16
" lw $16, -4($sp)\n"
// and return from the function
" jr $31\n"
" nop\n"
" .set macro\n"
" .set reorder\n"
" .end mipsFunc\n"
" .cfi_endproc\n"
" .size mipsFunc, .-mipsFunc\n"
);
#else // !(defined(__linux__) && defined(_ABIO32))
// The MIPS ABI used by PSP and PS2 is implemented here
#define AS_MIPS_MAX_ARGS 32
#define AS_NUM_REG_FLOATS 8
#define AS_NUM_REG_INTS 8
// The array used to send values to the correct places.
// first 0-8 regular values to load into the a0-a3, t0-t3 registers
// then 0-8 float values to load into the f12-f19 registers
// then (AS_MIPS_MAX_ARGS - 16) values to load onto the stack
// the +1 is for when CallThis (object methods) is used
// extra +1 when returning in memory
extern "C" {
// TODO: This array shouldn't be global. It should be a local array in CallSystemFunctionNative
asDWORD mipsArgs[AS_MIPS_MAX_ARGS + 1 + 1];
}
// Loads all data into the correct places and calls the function.
// intArgSize is the size in bytes for how much data to put in int registers
// floatArgSize is the size in bytes for how much data to put in float registers
// stackArgSize is the size in bytes for how much data to put on the callstack
extern "C" asQWORD mipsFunc(int intArgSize, int floatArgSize, int stackArgSize, asDWORD func);
// puts the arguments in the correct place in the mipsArgs-array. See comments above.
// This could be done better.
inline void splitArgs(const asDWORD *args, int argNum, int &numRegIntArgs, int &numRegFloatArgs, int &numRestArgs, int hostFlags)
{
int i;
int argBit = 1;
for (i = 0; i < argNum; i++)
{
if (hostFlags & argBit)
{
if (numRegFloatArgs < AS_NUM_REG_FLOATS)
{
// put in float register
mipsArgs[AS_NUM_REG_INTS + numRegFloatArgs] = args[i];
numRegFloatArgs++;
}
else
{
// put in stack
mipsArgs[AS_NUM_REG_INTS + AS_NUM_REG_FLOATS + numRestArgs] = args[i];
numRestArgs++;
}
}
else
{
if (numRegIntArgs < AS_NUM_REG_INTS)
{
// put in int register
mipsArgs[numRegIntArgs] = args[i];
numRegIntArgs++;
}
else
{
// put in stack
mipsArgs[AS_NUM_REG_INTS + AS_NUM_REG_FLOATS + numRestArgs] = args[i];
numRestArgs++;
}
}
argBit <<= 1;
}
}
asQWORD CallCDeclFunction(const asDWORD *args, int argSize, asDWORD func, int flags)
{
int argNum = argSize >> 2;
int intArgs = 0;
int floatArgs = 0;
int restArgs = 0;
// put the arguments in the correct places in the mipsArgs array
if(argNum > 0)
splitArgs(args, argNum, intArgs, floatArgs, restArgs, flags);
return mipsFunc(intArgs << 2, floatArgs << 2, restArgs << 2, func);
}
// This function is identical to CallCDeclFunction, with the only difference that
// the value in the first parameter is the object
asQWORD CallThisCallFunction(const void *obj, const asDWORD *args, int argSize, asDWORD func, int flags)
{
int argNum = argSize >> 2;
int intArgs = 1;
int floatArgs = 0;
int restArgs = 0;
mipsArgs[0] = (asDWORD) obj;
// put the arguments in the correct places in the mipsArgs array
if (argNum > 0)
splitArgs(args, argNum, intArgs, floatArgs, restArgs, flags);
return mipsFunc(intArgs << 2, floatArgs << 2, restArgs << 2, func);
}
// This function is identical to CallCDeclFunction, with the only difference that
// the value in the last parameter is the object
asQWORD CallThisCallFunction_objLast(const void *obj, const asDWORD *args, int argSize, asDWORD func, int flags)
{
int argNum = argSize >> 2;
int intArgs = 0;
int floatArgs = 0;
int restArgs = 0;
// put the arguments in the correct places in the mipsArgs array
if(argNum > 0)
splitArgs(args, argNum, intArgs, floatArgs, restArgs, flags);
if(intArgs < AS_NUM_REG_INTS)
{
mipsArgs[intArgs] = (asDWORD) obj;
intArgs++;
}
else
{
mipsArgs[AS_NUM_REG_INTS + AS_NUM_REG_FLOATS + restArgs] = (asDWORD) obj;
restArgs++;
}
return mipsFunc(intArgs << 2, floatArgs << 2, restArgs << 2, func);
}
asDWORD GetReturnedFloat()
{
asDWORD f;
asm("swc1 $f0, %0\n" : "=m"(f));
return f;
}
asQWORD GetReturnedDouble()
{
asQWORD d = 0;
asm("sdc1 $f0, %0\n" : "=m"(d));
return d;
}
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void */*secondObject*/)
{
asCScriptEngine *engine = context->m_engine;
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
int callConv = sysFunc->callConv;
// TODO: Mips does not yet support THISCALL_OBJFIRST/LAST
asQWORD retQW = 0;
void *func = (void*)sysFunc->func;
int paramSize = sysFunc->paramSize;
asDWORD *vftable;
if( descr->returnType.IsObject() && !descr->returnType.IsReference() && !descr->returnType.IsObjectHandle() )
{
mipsArgs[AS_MIPS_MAX_ARGS+1] = (asDWORD) retPointer;
}
asASSERT(descr->parameterTypes.GetLength() <= AS_MIPS_MAX_ARGS);
// mark all float arguments
int argBit = 1;
int hostFlags = 0;
int intArgs = 0;
for( size_t a = 0; a < descr->parameterTypes.GetLength(); a++ )
{
if (descr->parameterTypes[a].IsFloatType())
hostFlags |= argBit;
else
intArgs++;
argBit <<= 1;
}
asDWORD paramBuffer[64];
if( sysFunc->takesObjByVal )
{
paramSize = 0;
int spos = 0;
int dpos = 1;
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
{
if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
{
#ifdef COMPLEX_OBJS_PASSED_BY_REF
if( descr->parameterTypes[n].GetTypeInfo()->flags & COMPLEX_MASK )
{
paramBuffer[dpos++] = args[spos++];
paramSize++;
}
else
#endif
{
// Copy the object's memory to the buffer
memcpy(&paramBuffer[dpos], *(void**)(args+spos), descr->parameterTypes[n].GetSizeInMemoryBytes());
// Delete the original memory
engine->CallFree(*(char**)(args+spos));
spos++;
dpos += descr->parameterTypes[n].GetSizeInMemoryDWords();
paramSize += descr->parameterTypes[n].GetSizeInMemoryDWords();
}
}
else
{
// Copy the value directly
paramBuffer[dpos++] = args[spos++];
if( descr->parameterTypes[n].GetSizeOnStackDWords() > 1 )
paramBuffer[dpos++] = args[spos++];
paramSize += descr->parameterTypes[n].GetSizeOnStackDWords();
}
}
// Keep a free location at the beginning
args = &paramBuffer[1];
}
switch( callConv )
{
case ICC_CDECL:
case ICC_CDECL_RETURNINMEM:
case ICC_STDCALL:
case ICC_STDCALL_RETURNINMEM:
retQW = CallCDeclFunction(args, paramSize<<2, (asDWORD)func, hostFlags);
break;
case ICC_THISCALL:
case ICC_THISCALL_RETURNINMEM:
retQW = CallThisCallFunction(obj, args, paramSize<<2, (asDWORD)func, hostFlags);
break;
case ICC_VIRTUAL_THISCALL:
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
// Get virtual function table from the object pointer
vftable = *(asDWORD**)obj;
retQW = CallThisCallFunction(obj, args, paramSize<<2, vftable[asDWORD(func)>>2], hostFlags);
break;
case ICC_CDECL_OBJLAST:
case ICC_CDECL_OBJLAST_RETURNINMEM:
retQW = CallThisCallFunction_objLast(obj, args, paramSize<<2, (asDWORD)func, hostFlags);
break;
case ICC_CDECL_OBJFIRST:
case ICC_CDECL_OBJFIRST_RETURNINMEM:
retQW = CallThisCallFunction(obj, args, paramSize<<2, (asDWORD)func, hostFlags);
break;
default:
context->SetInternalException(TXT_INVALID_CALLING_CONVENTION);
}
// If the return is a float value we need to get the value from the FP register
if( sysFunc->hostReturnFloat )
{
if( sysFunc->hostReturnSize == 1 )
*(asDWORD*)&retQW = GetReturnedFloat();
else
retQW = GetReturnedDouble();
}
return retQW;
}
asm(
" .text\n"
//" .align 2\n"
" .global mipsFunc\n"
" .ent mipsFunc\n"
"mipsFunc:\n"
//" .frame $fp,64,$31 # vars= 0, regs= 0/0, args= 0, gp= 0\n"
//" .mask 0x00000000,0\n"
//" .fmask 0x00000000,0\n"
" .set noreorder\n"
" .set nomacro\n"
// align the stack frame to 8 bytes
" addiu $12, $6, 7\n"
" li $13, -8\n" // 0xfffffffffffffff8
" and $12, $12, $13\n" // t4 holds the size of the argument block
// and add 8 bytes for the return pointer and s0 backup
" addiu $13, $12, 8\n" // t5 holds the total size of the stack frame (including return pointer)
// save the s0 register (so we can use it to remember where our return pointer is lives)
" sw $16, -4($sp)\n" // store the s0 register (so we can use it to remember how big our stack frame is)
// push the stack
" subu $sp, $sp, $13\n"
// find the return address, place in s0
" addu $16, $sp, $12\n"
// store the return pointer
" sw $31, 0($16)\n"
// backup our function params
" addiu $2, $7, 0\n"
" addiu $3, $6, 0\n"
// get global mipsArgs[] array pointer
//" lui $15, %hi(mipsArgs)\n"
//" addiu $15, $15, %lo(mipsArgs)\n"
// we'll use the macro instead because SN Systems doesnt like %hi/%lo
".set macro\n"
" la $15, mipsArgs\n"
".set nomacro\n"
// load register params
" lw $4, 0($15)\n"
" lw $5, 4($15)\n"
" lw $6, 8($15)\n"
" lw $7, 12($15)\n"
" lw $8, 16($15)\n"
" lw $9, 20($15)\n"
" lw $10, 24($15)\n"
" lw $11, 28($15)\n"
// load float params
" lwc1 $f12, 32($15)\n"
" lwc1 $f13, 36($15)\n"
" lwc1 $f14, 40($15)\n"
" lwc1 $f15, 44($15)\n"
" lwc1 $f16, 48($15)\n"
" lwc1 $f17, 52($15)\n"
" lwc1 $f18, 56($15)\n"
" lwc1 $f19, 60($15)\n"
// skip stack paramaters if there are none
" beq $3, $0, andCall\n"
// push stack paramaters
" addiu $15, $15, 64\n"
"pushArgs:\n"
" addiu $3, -4\n"
// load from $15 + stack bytes ($3)
" addu $14, $15, $3\n"
" lw $14, 0($14)\n"
// store to $sp + stack bytes ($3)
" addu $13, $sp, $3\n"
" sw $14, 0($13)\n"
// if there are more, loop...
" bne $3, $0, pushArgs\n"
" nop\n"
// and call the function
"andCall:\n"
" jal $2\n"
" nop\n"
// restore the return pointer
" lw $31, 0($16)\n"
// pop the stack pointer (remembering the return pointer was 8 bytes below the top)
" addiu $sp, $16, 8\n"
// and return from the function
" jr $31\n"
// restore the s0 register (in the branch delay slot)
" lw $16, -4($sp)\n"
" .set macro\n"
" .set reorder\n"
" .end mipsFunc\n"
" .size mipsFunc, .-mipsFunc\n"
);
#endif // PSP and PS2 MIPS ABI
END_AS_NAMESPACE
#endif // AS_MIPS
#endif // AS_MAX_PORTABILITY

View File

@@ -0,0 +1,674 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_callfunc_ppc.cpp
//
// These functions handle the actual calling of system functions
//
// This version is PPC specific
//
#include <stdio.h>
#include "as_config.h"
#ifndef AS_MAX_PORTABILITY
#ifdef AS_PPC
#include "as_callfunc.h"
#include "as_scriptengine.h"
#include "as_texts.h"
#include "as_tokendef.h"
#include "as_context.h"
#include <stdlib.h>
BEGIN_AS_NAMESPACE
// This part was originally written by Pecan Heber, June 2006, for
// use on MacOS X with 32bit PPC processor. He based the code on the
// code in as_callfunc_sh4.cpp
#define AS_PPC_MAX_ARGS 32
// The array used to send values to the correct places.
// Contains a byte of argTypes to indicate the register tYpe to load
// or zero if end of arguments
// The +1 is for when CallThis (object methods) is used
// Extra +1 when returning in memory
// Extra +1 in ppcArgsType to ensure zero end-of-args marker
// TODO: multithread: We need to remove these global variables for thread-safety
enum argTypes { ppcENDARG, ppcINTARG, ppcFLOATARG, ppcDOUBLEARG };
static asDWORD ppcArgs[2*AS_PPC_MAX_ARGS + 1 + 1];
// Using extern "C" because we use this symbol name in the assembly code
extern "C"
{
static asBYTE ppcArgsType[2*AS_PPC_MAX_ARGS + 1 + 1 + 1];
}
// NOTE: these values are for PowerPC 32 bit.
#define PPC_LINKAGE_SIZE (24) // how big the PPC linkage area is in a stack frame
#define PPC_NUM_REGSTORE (9) // how many registers of the PPC we need to store/restore for ppcFunc()
#define PPC_REGSTORE_SIZE (4*PPC_NUM_REGSTORE) // how many bytes are required for register store/restore
#define EXTRA_STACK_SIZE (PPC_LINKAGE_SIZE + PPC_REGSTORE_SIZE) // memory required, not including parameters, for the stack frame
#define PPC_STACK_SIZE(numParams) (-( ( ((((numParams)<8)?8:(numParams))<<2) + EXTRA_STACK_SIZE + 15 ) & ~15 )) // calculates the total stack size needed for ppcFunc64, must pad to 16bytes
// Loads all data into the correct places and calls the function.
// ppcArgsType is an array containing a byte type (enum argTypes) for each argument.
// stackArgSize is the size in bytes for how much data to put on the stack frame
extern "C" asQWORD ppcFunc(const asDWORD* argsPtr, int StackArgSize, asDWORD func);
asm(" .text\n"
" .align 2\n" // align the code to 1 << 2 = 4 bytes
" .globl _ppcFunc\n"
"_ppcFunc:\n"
// We're receiving the following parameters
// r3 : argsPtr
// r4 : StackArgSize
// r5 : func
// The following registers are used through out the function
// r31 : the address of the label address, as reference for all other labels
// r30 : temporary variable
// r29 : arg list pointer
// r28 : number of FPR registers used by the parameters
// r27 : the function pointer that will be called
// r26 : the location of the parameters for the call
// r25 : arg type list pointer
// r24 : temporary variable
// r23 : number of GPR registers used by the parameters
// r1 : this is stack pointer
// r0 : temporary variable
// f0 : temporary variable
// We need to store some of the registers for restoral before returning to caller
// lr - always stored in 8(r1) - this is the return address
// cr - not required to be stored, but if it is, its place is in 4(r1) - this is the condition register
// r1 - always stored in 0(r1) - this is the stack pointer
// r11
// r13 to r31
// f14 to f31
// Store register values and setup our stack frame
" mflr r0 \n" // move the return address into r0
" stw r0, 8(r1) \n" // Store the return address on the stack
" stmw r23, -36(r1) \n" // Store registers r23 to r31 on the stack
" stwux r1, r1, r4 \n" // Increase the stack with the needed space and store the original value in the destination
// Obtain an address that we'll use as our position of reference when obtaining addresses of other labels
" bl address \n"
"address: \n"
" mflr r31 \n"
// initial registers for the function
" mr r29, r3 \n" // (r29) args list
" mr r27, r5 \n" // load the function pointer to call. func actually holds the pointer to our function
" addi r26, r1, 24 \n" // setup the pointer to the parameter area to the function we're going to call
" sub r0, r0, r0 \n" // zero out r0
" mr r23, r0 \n" // zero out r23, which holds the number of used GPR registers
" mr r28, r0 \n" // zero our r22, which holds the number of used float registers
// load the global ppcArgsType which holds the types of arguments for each argument
" addis r25, r31, ha16(_ppcArgsType - address) \n" // load the upper 16 bits of the address to r25
" la r25, lo16(_ppcArgsType - address)(r25) \n" // load the lower 16 bits of the address to r25
" subi r25, r25, 1 \n" // since we increment r25 on its use, we'll pre-decrement it
// loop through the arguments
"ppcNextArg: \n"
" addi r25, r25, 1 \n" // increment r25, our arg type pointer
// switch based on the current argument type (0:end, 1:int, 2:float 3:double)
" lbz r24, 0(r25) \n" // load the current argument type (it's a byte)
" mulli r24, r24, 4 \n" // our jump table has 4 bytes per case (1 instruction)
" addis r30, r31, ha16(ppcTypeSwitch - address) \n" // load the address of the jump table for the switch
" la r30, lo16(ppcTypeSwitch - address)(r30) \n"
" add r0, r30, r24 \n" // offset by our argument type
" mtctr r0 \n" // load the jump address into CTR
" bctr \n" // jump into the jump table/switch
" nop \n"
// the jump table/switch based on the current argument type
"ppcTypeSwitch: \n"
" b ppcArgsEnd \n"
" b ppcArgIsInteger \n"
" b ppcArgIsFloat \n"
" b ppcArgIsDouble \n"
// when we get here we have finished processing all the arguments
// everything is ready to go to call the function
"ppcArgsEnd: \n"
" mtctr r27 \n" // the function pointer is stored in r27, load that into CTR
" bctrl \n" // call the function. We have to do it this way so that the LR gets the proper
" nop \n" // return value (the next instruction below). So we have to branch from CTR instead of LR.
// Restore registers and caller's stack frame, then return to caller
" lwz r1, 0(r1) \n" // restore the caller's stack pointer
" lwz r0, 8(r1) \n" // load in the caller's LR
" mtlr r0 \n" // restore the caller's LR
" lmw r23, -36(r1) \n" // restore registers r23 to r31 from the stack
" blr \n" // return back to the caller
" nop \n"
// Integer argument (GPR register)
"ppcArgIsInteger: \n"
" addis r30, r31, ha16(ppcLoadIntReg - address) \n" // load the address to the jump table for integer registers
" la r30, lo16(ppcLoadIntReg - address)(r30) \n"
" mulli r0, r23, 8 \n" // each item in the jump table is 2 instructions (8 bytes)
" add r0, r0, r30 \n" // calculate ppcLoadIntReg[numUsedGPRRegs]
" lwz r30, 0(r29) \n" // load the next argument from the argument list into r30
" cmpwi r23, 8 \n" // we can only load GPR3 through GPR10 (8 registers)
" bgt ppcLoadIntRegUpd \n" // if we're beyond 8 GPR registers, we're in the stack, go there
" mtctr r0 \n" // load the address of our ppcLoadIntReg jump table (we're below 8 GPR registers)
" bctr \n" // load the argument into a GPR register
" nop \n"
// jump table for GPR registers, for the first 8 GPR arguments
"ppcLoadIntReg: \n"
" mr r3, r30 \n" // arg0 (to r3)
" b ppcLoadIntRegUpd \n"
" mr r4, r30 \n" // arg1 (to r4)
" b ppcLoadIntRegUpd \n"
" mr r5, r30 \n" // arg2 (to r5)
" b ppcLoadIntRegUpd \n"
" mr r6, r30 \n" // arg3 (to r6)
" b ppcLoadIntRegUpd \n"
" mr r7, r30 \n" // arg4 (to r7)
" b ppcLoadIntRegUpd \n"
" mr r8, r30 \n" // arg5 (to r8)
" b ppcLoadIntRegUpd \n"
" mr r9, r30 \n" // arg6 (to r9)
" b ppcLoadIntRegUpd \n"
" mr r10, r30 \n" // arg7 (to r10)
" b ppcLoadIntRegUpd \n"
// all GPR arguments still go on the stack
"ppcLoadIntRegUpd: \n"
" stw r30, 0(r26) \n" // store the argument into the next slot on the stack's argument list
" addi r23, r23, 1 \n" // count a used GPR register
" addi r29, r29, 4 \n" // move to the next argument on the list
" addi r26, r26, 4 \n" // adjust our argument stack pointer for the next
" b ppcNextArg \n" // next argument
// single Float argument
"ppcArgIsFloat:\n"
" addis r30, r31, ha16(ppcLoadFloatReg - address) \n" // get the base address of the float register jump table
" la r30, lo16(ppcLoadFloatReg - address)(r30) \n"
" mulli r0, r28, 8 \n" // each jump table entry is 8 bytes
" add r0, r0, r30 \n" // calculate the offset to ppcLoadFloatReg[numUsedFloatReg]
" lfs f0, 0(r29) \n" // load the next argument as a float into f0
" cmpwi r28, 13 \n" // can't load more than 13 float/double registers
" bgt ppcLoadFloatRegUpd \n" // if we're beyond 13 registers, just fall to inserting into the stack
" mtctr r0 \n" // jump into the float jump table
" bctr \n"
" nop \n"
// jump table for float registers, for the first 13 float arguments
"ppcLoadFloatReg: \n"
" fmr f1, f0 \n" // arg0 (f1)
" b ppcLoadFloatRegUpd \n"
" fmr f2, f0 \n" // arg1 (f2)
" b ppcLoadFloatRegUpd \n"
" fmr f3, f0 \n" // arg2 (f3)
" b ppcLoadFloatRegUpd \n"
" fmr f4, f0 \n" // arg3 (f4)
" b ppcLoadFloatRegUpd \n"
" fmr f5, f0 \n" // arg4 (f5)
" b ppcLoadFloatRegUpd \n"
" fmr f6, f0 \n" // arg5 (f6)
" b ppcLoadFloatRegUpd \n"
" fmr f7, f0 \n" // arg6 (f7)
" b ppcLoadFloatRegUpd \n"
" fmr f8, f0 \n" // arg7 (f8)
" b ppcLoadFloatRegUpd \n"
" fmr f9, f0 \n" // arg8 (f9)
" b ppcLoadFloatRegUpd \n"
" fmr f10, f0 \n" // arg9 (f10)
" b ppcLoadFloatRegUpd \n"
" fmr f11, f0 \n" // arg10 (f11)
" b ppcLoadFloatRegUpd \n"
" fmr f12, f0 \n" // arg11 (f12)
" b ppcLoadFloatRegUpd \n"
" fmr f13, f0 \n" // arg12 (f13)
" b ppcLoadFloatRegUpd \n"
" nop \n"
// all float arguments still go on the stack
"ppcLoadFloatRegUpd: \n"
" stfs f0, 0(r26) \n" // store, as a single float, f0 (current argument) on to the stack argument list
" addi r23, r23, 1 \n" // a float register eats up a GPR register
" addi r28, r28, 1 \n" // ...and, of course, a float register
" addi r29, r29, 4 \n" // move to the next argument in the list
" addi r26, r26, 4 \n" // move to the next stack slot
" b ppcNextArg \n" // on to the next argument
" nop \n"
// double Float argument
"ppcArgIsDouble: \n"
" addis r30, r31, ha16(ppcLoadDoubleReg - address) \n" // load the base address of the jump table for double registers
" la r30, lo16(ppcLoadDoubleReg - address)(r30) \n"
" mulli r0, r28, 8 \n" // each slot of the jump table is 8 bytes
" add r0, r0, r30 \n" // calculate ppcLoadDoubleReg[numUsedFloatReg]
" lfd f0, 0(r29) \n" // load the next argument, as a double float, into f0
" cmpwi r28, 13 \n" // the first 13 floats must go into float registers also
" bgt ppcLoadDoubleRegUpd \n" // if we're beyond 13, then just put on to the stack
" mtctr r0 \n" // we're under 13, first load our register
" bctr \n" // jump into the jump table
" nop \n"
// jump table for float registers, for the first 13 float arguments
"ppcLoadDoubleReg: \n"
" fmr f1, f0 \n" // arg0 (f1)
" b ppcLoadDoubleRegUpd \n"
" fmr f2, f0 \n" // arg1 (f2)
" b ppcLoadDoubleRegUpd \n"
" fmr f3, f0 \n" // arg2 (f3)
" b ppcLoadDoubleRegUpd \n"
" fmr f4, f0 \n" // arg3 (f4)
" b ppcLoadDoubleRegUpd \n"
" fmr f5, f0 \n" // arg4 (f5)
" b ppcLoadDoubleRegUpd \n"
" fmr f6, f0 \n" // arg5 (f6)
" b ppcLoadDoubleRegUpd \n"
" fmr f7, f0 \n" // arg6 (f7)
" b ppcLoadDoubleRegUpd \n"
" fmr f8, f0 \n" // arg7 (f8)
" b ppcLoadDoubleRegUpd \n"
" fmr f9, f0 \n" // arg8 (f9)
" b ppcLoadDoubleRegUpd \n"
" fmr f10, f0 \n" // arg9 (f10)
" b ppcLoadDoubleRegUpd \n"
" fmr f11, f0 \n" // arg10 (f11)
" b ppcLoadDoubleRegUpd \n"
" fmr f12, f0 \n" // arg11 (f12)
" b ppcLoadDoubleRegUpd \n"
" fmr f13, f0 \n" // arg12 (f13)
" b ppcLoadDoubleRegUpd \n"
" nop \n"
// all float arguments still go on the stack
"ppcLoadDoubleRegUpd: \n"
" stfd f0, 0(r26) \n" // store f0, as a double, into the argument list on the stack
" addi r23, r23, 2 \n" // a double float eats up two GPRs
" addi r28, r28, 1 \n" // ...and, of course, a float
" addi r29, r29, 8 \n" // increment to our next argument we need to process (8 bytes for the 64bit float)
" addi r26, r26, 8 \n" // increment to the next slot on the argument list on the stack (8 bytes)
" b ppcNextArg \n" // on to the next argument
" nop \n"
);
asDWORD GetReturnedFloat()
{
asDWORD f;
asm(" stfs f1, %0\n" : "=m"(f));
return f;
}
asQWORD GetReturnedDouble()
{
asQWORD f;
asm(" stfd f1, %0\n" : "=m"(f));
return f;
}
// puts the arguments in the correct place in the stack array. See comments above.
void stackArgs(const asDWORD *args, const asBYTE *argsType, int& numIntArgs, int& numFloatArgs, int& numDoubleArgs)
{
int i;
int argWordPos = numIntArgs + numFloatArgs + (numDoubleArgs*2);
int typeOffset = numIntArgs + numFloatArgs + numDoubleArgs;
int typeIndex;
for( i = 0, typeIndex = 0; ; i++, typeIndex++ )
{
// store the type
ppcArgsType[typeOffset++] = argsType[typeIndex];
if( argsType[typeIndex] == ppcENDARG )
break;
switch( argsType[typeIndex] )
{
case ppcFLOATARG:
// stow float
ppcArgs[argWordPos] = args[i]; // it's just a bit copy
numFloatArgs++;
argWordPos++; //add one word
break;
case ppcDOUBLEARG:
// stow double
memcpy( &ppcArgs[argWordPos], &args[i], sizeof(double) ); // we have to do this because of alignment
numDoubleArgs++;
argWordPos+=2; //add two words
i++;//doubles take up 2 argument slots
break;
case ppcINTARG:
// stow register
ppcArgs[argWordPos] = args[i];
numIntArgs++;
argWordPos++;
break;
}
}
// close off the argument list (if we have max args we won't close it off until here)
ppcArgsType[typeOffset] = ppcENDARG;
}
static asQWORD CallCDeclFunction(const asDWORD* pArgs, const asBYTE *pArgsType, int argSize, asDWORD func, void *retInMemory)
{
int baseArgCount = 0;
if( retInMemory )
{
// the first argument is the 'return in memory' pointer
ppcArgs[0] = (asDWORD)retInMemory;
ppcArgsType[0] = ppcINTARG;
ppcArgsType[1] = ppcENDARG;
baseArgCount = 1;
}
// put the arguments in the correct places in the ppcArgs array
int numTotalArgs = baseArgCount;
if( argSize > 0 )
{
int intArgs = baseArgCount, floatArgs = 0, doubleArgs = 0;
stackArgs( pArgs, pArgsType, intArgs, floatArgs, doubleArgs );
numTotalArgs = intArgs + floatArgs + 2*doubleArgs; // doubles occupy two slots
}
else
{
// no arguments, cap the type list
ppcArgsType[baseArgCount] = ppcENDARG;
}
// call the function with the arguments
return ppcFunc( ppcArgs, PPC_STACK_SIZE(numTotalArgs), func );
}
// This function is identical to CallCDeclFunction, with the only difference that
// the value in the first parameter is the object (unless we are returning in memory)
static asQWORD CallThisCallFunction(const void *obj, const asDWORD* pArgs, const asBYTE *pArgsType, int argSize, asDWORD func, void *retInMemory )
{
int baseArgCount = 0;
if( retInMemory )
{
// the first argument is the 'return in memory' pointer
ppcArgs[0] = (asDWORD)retInMemory;
ppcArgsType[0] = ppcINTARG;
ppcArgsType[1] = ppcENDARG;
baseArgCount = 1;
}
// the first argument is the 'this' of the object
ppcArgs[baseArgCount] = (asDWORD)obj;
ppcArgsType[baseArgCount++] = ppcINTARG;
ppcArgsType[baseArgCount] = ppcENDARG;
// put the arguments in the correct places in the ppcArgs array
int numTotalArgs = baseArgCount;
if( argSize > 0 )
{
int intArgs = baseArgCount, floatArgs = 0, doubleArgs = 0;
stackArgs( pArgs, pArgsType, intArgs, floatArgs, doubleArgs );
numTotalArgs = intArgs + floatArgs + 2*doubleArgs; // doubles occupy two slots
}
// call the function with the arguments
return ppcFunc( ppcArgs, PPC_STACK_SIZE(numTotalArgs), func);
}
// This function is identical to CallCDeclFunction, with the only difference that
// the value in the last parameter is the object
// NOTE: on PPC the order for the args is reversed
static asQWORD CallThisCallFunction_objLast(const void *obj, const asDWORD* pArgs, const asBYTE *pArgsType, int argSize, asDWORD func, void *retInMemory)
{
UNUSED_VAR(argSize);
int baseArgCount = 0;
if( retInMemory )
{
// the first argument is the 'return in memory' pointer
ppcArgs[0] = (asDWORD)retInMemory;
ppcArgsType[0] = ppcINTARG;
ppcArgsType[1] = ppcENDARG;
baseArgCount = 1;
}
// stack any of the arguments
int intArgs = baseArgCount, floatArgs = 0, doubleArgs = 0;
stackArgs( pArgs, pArgsType, intArgs, floatArgs, doubleArgs );
int numTotalArgs = intArgs + floatArgs + doubleArgs;
// can we fit the object in at the end?
if( numTotalArgs < AS_PPC_MAX_ARGS )
{
// put the object pointer at the end
int argPos = intArgs + floatArgs + (doubleArgs * 2);
ppcArgs[argPos] = (asDWORD)obj;
ppcArgsType[numTotalArgs++] = ppcINTARG;
ppcArgsType[numTotalArgs] = ppcENDARG;
}
// call the function with the arguments
return ppcFunc( ppcArgs, PPC_STACK_SIZE(numTotalArgs), func );
}
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void */*secondObject*/)
{
// TODO: PPC does not yet support THISCALL_OBJFIRST/LAST
// use a working array of types, we'll configure the final one in stackArgs
asBYTE argsType[2*AS_PPC_MAX_ARGS + 1 + 1 + 1];
memset( argsType, 0, sizeof(argsType));
asCScriptEngine *engine = context->m_engine;
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
asQWORD retQW = 0;
void *func = (void*)sysFunc->func;
int paramSize = sysFunc->paramSize;
asDWORD *vftable = NULL;
int a, s;
// convert the parameters that are < 4 bytes from little endian to big endian
int argDwordOffset = 0;
for( a = 0; a < (int)descr->parameterTypes.GetLength(); a++ )
{
int numBytes = descr->parameterTypes[a].GetSizeInMemoryBytes();
if( numBytes >= 4 || descr->parameterTypes[a].IsReference() || descr->parameterTypes[a].IsObjectHandle() )
{
argDwordOffset += descr->parameterTypes[a].GetSizeOnStackDWords();
continue;
}
// flip
asASSERT( numBytes == 1 || numBytes == 2 );
switch( numBytes )
{
case 1:
{
volatile asBYTE *bPtr = (asBYTE*)ARG_DW(args[argDwordOffset]);
asBYTE t = bPtr[0];
bPtr[0] = bPtr[3];
bPtr[3] = t;
t = bPtr[1];
bPtr[1] = bPtr[2];
bPtr[2] = t;
}
break;
case 2:
{
volatile asWORD *wPtr = (asWORD*)ARG_DW(args[argDwordOffset]);
asWORD t = wPtr[0];
wPtr[0] = wPtr[1];
wPtr[1] = t;
}
break;
}
argDwordOffset++;
}
// mark all float/double/int arguments
if( !sysFunc->takesObjByVal )
{
for( s = 0, a = 0; s < (int)descr->parameterTypes.GetLength(); s++, a++ )
{
if( descr->parameterTypes[s].IsFloatType() && !descr->parameterTypes[s].IsReference() )
{
argsType[a] = ppcFLOATARG;
}
else if( descr->parameterTypes[s].IsDoubleType() && !descr->parameterTypes[s].IsReference() )
{
argsType[a] = ppcDOUBLEARG;
}
else
{
argsType[a] = ppcINTARG;
if( descr->parameterTypes[s].GetSizeOnStackDWords() == 2 )
{
// Add an extra integer argument for the extra size
a++;
argsType[a] = ppcINTARG;
}
}
}
}
asDWORD paramBuffer[64];
if( sysFunc->takesObjByVal )
{
paramSize = 0;
int spos = 0;
int dpos = 1;
int a = 0;
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
{
if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
{
#ifdef COMPLEX_OBJS_PASSED_BY_REF
if( descr->parameterTypes[n].GetTypeInfo()->flags & COMPLEX_MASK )
{
argsType[a++] = ppcINTARG;
paramBuffer[dpos++] = args[spos++];
paramSize++;
}
else
#endif
{
// TODO: Probably have to handle asOBJ_APP_FLOAT as a primitive
// Copy the object's memory to the buffer
memcpy( &paramBuffer[dpos], *(void**)(args+spos), descr->parameterTypes[n].GetSizeInMemoryBytes() );
// Delete the original memory
engine->CallFree(*(char**)(args+spos) );
spos++;
asUINT dwords = descr->parameterTypes[n].GetSizeInMemoryDWords();
dpos += dwords;
paramSize += dwords;
for( asUINT i = 0; i < dwords; i++ )
argsType[a++] = ppcINTARG;
}
}
else
{
// Copy the value directly
paramBuffer[dpos++] = args[spos++];
if( descr->parameterTypes[n].IsFloatType() && !descr->parameterTypes[n].IsReference() )
argsType[a++] = ppcFLOATARG;
else if( descr->parameterTypes[n].IsDoubleType() && !descr->parameterTypes[n].IsReference() )
argsType[a++] = ppcDOUBLEARG;
else
argsType[a++] = ppcINTARG;
if( descr->parameterTypes[n].GetSizeOnStackDWords() > 1 )
{
paramBuffer[dpos++] = args[spos++];
if( !descr->parameterTypes[n].IsDoubleType() ) // Double already knows it is 2 dwords
argsType[a++] = ppcINTARG;
}
paramSize += descr->parameterTypes[n].GetSizeOnStackDWords();
}
}
// Keep a free location at the beginning
args = &paramBuffer[1];
}
int callConv = sysFunc->callConv;
switch( callConv )
{
case ICC_CDECL:
case ICC_CDECL_RETURNINMEM:
case ICC_STDCALL:
case ICC_STDCALL_RETURNINMEM:
retQW = CallCDeclFunction( args, argsType, paramSize, (asDWORD)func, retPointer );
break;
case ICC_THISCALL:
case ICC_THISCALL_RETURNINMEM:
retQW = CallThisCallFunction(obj, args, argsType, paramSize, (asDWORD)func, retPointer );
break;
case ICC_VIRTUAL_THISCALL:
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
// Get virtual function table from the object pointer
vftable = *(asDWORD**)obj;
retQW = CallThisCallFunction( obj, args, argsType, paramSize, vftable[asDWORD(func)>>2], retPointer );
break;
case ICC_CDECL_OBJLAST:
case ICC_CDECL_OBJLAST_RETURNINMEM:
retQW = CallThisCallFunction_objLast( obj, args, argsType, paramSize, (asDWORD)func, retPointer );
break;
case ICC_CDECL_OBJFIRST:
case ICC_CDECL_OBJFIRST_RETURNINMEM:
retQW = CallThisCallFunction( obj, args, argsType, paramSize, (asDWORD)func, retPointer );
break;
default:
context->SetInternalException(TXT_INVALID_CALLING_CONVENTION);
}
// If the return is a float value we need to get the value from the FP register
if( sysFunc->hostReturnFloat )
{
if( sysFunc->hostReturnSize == 1 )
*(asDWORD*)&retQW = GetReturnedFloat();
else
retQW = GetReturnedDouble();
}
return retQW;
}
END_AS_NAMESPACE
#endif // AS_PPC
#endif // AS_MAX_PORTABILITY

View File

@@ -0,0 +1,773 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2016 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_callfunc_ppc_64.cpp
//
// These functions handle the actual calling of system functions
//
// This version is 64 bit PPC specific
//
#include "as_config.h"
#ifndef AS_MAX_PORTABILITY
#ifdef AS_PPC_64
#if AS_PTR_SIZE == 2
// TODO: Add support for PPC 64bit platforms with 64bit pointers, for example Linux PPC64 (big endian) and PPC64 (little endian)
#error This code has not been prepared for PPC with 64bit pointers. Most likely the ABI is different
#else
#include "as_callfunc.h"
#include "as_scriptengine.h"
#include "as_texts.h"
#include "as_tokendef.h"
#include "as_context.h"
#include <stdio.h>
#include <stdlib.h>
#ifdef __SNC__
#include "ppu_asm_intrinsics.h"
#endif
BEGIN_AS_NAMESPACE
// This part was written and tested by Jeff Slutter
// from Reactor Zero, Abril, 2007, for PlayStation 3, which
// is a PowerPC 64bit based architecture. Even though it is
// 64bit it seems the pointer size is still 32bit.
// It still remains to be seen how well this code works
// on other PPC platforms, such as XBox 360, GameCube.
#define AS_PPC_MAX_ARGS 32
// The array used to send values to the correct places.
// Contains a byte of argTypes to indicate the register type to load
// or zero if end of arguments
// The +1 is for when CallThis (object methods) is used
// Extra +1 when returning in memory
// Extra +1 in ppcArgsType to ensure zero end-of-args marker
// TODO: multithread: The global variables must be removed to make the code thread safe
extern "C"
{
enum argTypes { ppcENDARG = 0, ppcINTARG = 1, ppcFLOATARG = 2, ppcDOUBLEARG = 3, ppcLONGARG = 4 };
static asBYTE ppcArgsType[AS_PPC_MAX_ARGS + 1 + 1 + 1];
static asDWORD ppcArgs[2*AS_PPC_MAX_ARGS + 1 + 1];
}
// NOTE: these values are for PowerPC 64 bit. I'm sure things are different for PowerPC 32bit, but I don't have one.
// I'm pretty sure that PPC 32bit sets up a stack frame slightly different (only 24 bytes for linkage area for instance)
#define PPC_LINKAGE_SIZE (0x30) // how big the PPC linkage area is in a stack frame
#define PPC_NUM_REGSTORE (10) // how many registers of the PPC we need to store/restore for ppcFunc64()
#define PPC_REGSTORE_SIZE (8*PPC_NUM_REGSTORE) // how many bytes are required for register store/restore
#define EXTRA_STACK_SIZE (PPC_LINKAGE_SIZE + PPC_REGSTORE_SIZE) // memory required, not including parameters, for the stack frame
#define PPC_STACK_SIZE(numParams) ( -(( ( (((numParams)<8)?8:(numParams))<<3) + EXTRA_STACK_SIZE + 15 ) & ~15) ) // calculates the total stack size needed for ppcFunc64, must pad to 16bytes
// This is PowerPC 64 bit specific
// Loads all data into the correct places and calls the function.
// ppcArgsType is an array containing a byte type (enum argTypes) for each argument.
// StackArgSizeInBytes is the size in bytes of the stack frame (takes into account linkage area, etc. must be multiple of 16)
extern "C" asQWORD ppcFunc64(const asDWORD* argsPtr, int StackArgSizeInBytes, asDWORD func);
asm(""
".text\n"
".align 4\n"
".p2align 4,,15\n"
".globl .ppcFunc64\n"
".ppcFunc64:\n"
// function prolog
"std %r22, -0x08(%r1)\n" // we need a register other than r0, to store the old stack pointer
"mr %r22, %r1\n" // store the old stack pointer, for now (to make storing registers easier)
"stdux %r1, %r1, %r4\n" // atomically store and update the stack pointer for the new stack frame (in case of a signal/interrupt)
"mflr %r0\n" // get the caller's LR register
"std %r0, 0x10(%r22)\n" // store the caller's LR register
"std %r23, -0x10(%r22)\n" //
"std %r24, -0x18(%r22)\n" //
"std %r25, -0x20(%r22)\n" //
"std %r26, -0x28(%r22)\n" //
"std %r27, -0x30(%r22)\n" //
"std %r28, -0x38(%r22)\n" //
"std %r29, -0x40(%r22)\n" //
"std %r30, -0x48(%r22)\n" //
"std %r31, -0x50(%r22)\n" //
"std %r3, 0x30(%r22)\n" // save our parameters
"std %r4, 0x38(%r22)\n" //
"std %r5, 0x40(%r22)\n" //
"mr %r31, %r1\n" // functions tend to store the stack pointer here too
// initial registers for the function
"mr %r29, %r3\n" // (r29) args list
"lwz %r27, 0(%r5)\n" // load the function pointer to call. func actually holds the pointer to our function
"addi %r26, %r1, 0x30\n" // setup the pointer to the parameter area to the function we're going to call
"sub %r0,%r0,%r0\n" // zero out r0
"mr %r23,%r0\n" // zero out r23, which holds the number of used GPR registers
"mr %r22,%r0\n" // zero our r22, which holds the number of used float registers
// load the global ppcArgsType which holds the types of arguments for each argument
"lis %r25, ppcArgsType@ha\n" // load the upper 16 bits of the address to r25
"addi %r25, %r25, ppcArgsType@l\n" // load the lower 16 bits of the address to r25
"subi %r25, %r25, 1\n" // since we increment r25 on its use, we'll pre-decrement it
// loop through the arguments
"ppcNextArg:\n"
"addi %r25, %r25, 1\n" // increment r25, our arg type pointer
// switch based on the current argument type (0:end, 1:int, 2:float 3:double)
"lbz %r24, 0(%r25)\n" // load the current argument type (it's a byte)
"mulli %r24, %r24, 4\n" // our jump table has 4 bytes per case (1 instruction)
"lis %r30, ppcTypeSwitch@ha\n" // load the address of the jump table for the switch
"addi %r30, %r30, ppcTypeSwitch@l\n"
"add %r0, %r30, %r24\n" // offset by our argument type
"mtctr %r0\n" // load the jump address into CTR
"bctr\n" // jump into the jump table/switch
"nop\n"
// the jump table/switch based on the current argument type
"ppcTypeSwitch:\n"
"b ppcArgsEnd\n"
"b ppcArgIsInteger\n"
"b ppcArgIsFloat\n"
"b ppcArgIsDouble\n"
"b ppcArgIsLong\n"
// when we get here we have finished processing all the arguments
// everything is ready to go to call the function
"ppcArgsEnd:\n"
"mtctr %r27\n" // the function pointer is stored in r27, load that into CTR
"bctrl\n" // call the function. We have to do it this way so that the LR gets the proper
"nop\n" // return value (the next instruction below). So we have to branch from CTR instead of LR.
// when we get here, the function has returned, this is the function epilog
"ld %r11,0x00(%r1)\n" // load in the caller's stack pointer
"ld %r0,0x10(%r11)\n" // load in the caller's LR
"mtlr %r0\n" // restore the caller's LR
"ld %r22, -0x08(%r11)\n" // load registers
"ld %r23, -0x10(%r11)\n" //
"ld %r24, -0x18(%r11)\n" //
"ld %r25, -0x20(%r11)\n" //
"ld %r26, -0x28(%r11)\n" //
"ld %r27, -0x30(%r11)\n" //
"ld %r28, -0x38(%r11)\n" //
"ld %r29, -0x40(%r11)\n" //
"ld %r30, -0x48(%r11)\n" //
"ld %r31, -0x50(%r11)\n" //
"mr %r1, %r11\n" // restore the caller's SP
"blr\n" // return back to the caller
"nop\n"
// Integer argument (GPR register)
"ppcArgIsInteger:\n"
"lis %r30,ppcLoadIntReg@ha\n" // load the address to the jump table for integer registers
"addi %r30, %r30, ppcLoadIntReg@l\n"
"mulli %r0, %r23, 8\n" // each item in the jump table is 2 instructions (8 bytes)
"add %r0, %r0, %r30\n" // calculate ppcLoadIntReg[numUsedGPRRegs]
"lwz %r30,0(%r29)\n" // load the next argument from the argument list into r30
"cmpwi %r23, 8\n" // we can only load GPR3 through GPR10 (8 registers)
"bgt ppcLoadIntRegUpd\n" // if we're beyond 8 GPR registers, we're in the stack, go there
"mtctr %r0\n" // load the address of our ppcLoadIntReg jump table (we're below 8 GPR registers)
"bctr\n" // load the argument into a GPR register
"nop\n"
// jump table for GPR registers, for the first 8 GPR arguments
"ppcLoadIntReg:\n"
"mr %r3,%r30\n" // arg0 (to r3)
"b ppcLoadIntRegUpd\n"
"mr %r4,%r30\n" // arg1 (to r4)
"b ppcLoadIntRegUpd\n"
"mr %r5,%r30\n" // arg2 (to r5)
"b ppcLoadIntRegUpd\n"
"mr %r6,%r30\n" // arg3 (to r6)
"b ppcLoadIntRegUpd\n"
"mr %r7,%r30\n" // arg4 (to r7)
"b ppcLoadIntRegUpd\n"
"mr %r8,%r30\n" // arg5 (to r8)
"b ppcLoadIntRegUpd\n"
"mr %r9,%r30\n" // arg6 (to r9)
"b ppcLoadIntRegUpd\n"
"mr %r10,%r30\n" // arg7 (to r10)
"b ppcLoadIntRegUpd\n"
// all GPR arguments still go on the stack
"ppcLoadIntRegUpd:\n"
"std %r30,0(%r26)\n" // store the argument into the next slot on the stack's argument list
"addi %r23, %r23, 1\n" // count a used GPR register
"addi %r29, %r29, 4\n" // move to the next argument on the list
"addi %r26, %r26, 8\n" // adjust our argument stack pointer for the next
"b ppcNextArg\n" // next argument
// single Float argument
"ppcArgIsFloat:\n"
"lis %r30,ppcLoadFloatReg@ha\n" // get the base address of the float register jump table
"addi %r30, %r30, ppcLoadFloatReg@l\n"
"mulli %r0, %r22 ,8\n" // each jump table entry is 8 bytes
"add %r0, %r0, %r30\n" // calculate the offset to ppcLoadFloatReg[numUsedFloatReg]
"lfs 0, 0(%r29)\n" // load the next argument as a float into f0
"cmpwi %r22, 13\n" // can't load more than 13 float/double registers
"bgt ppcLoadFloatRegUpd\n" // if we're beyond 13 registers, just fall to inserting into the stack
"mtctr %r0\n" // jump into the float jump table
"bctr\n"
"nop\n"
// jump table for float registers, for the first 13 float arguments
"ppcLoadFloatReg:\n"
"fmr 1,0\n" // arg0 (f1)
"b ppcLoadFloatRegUpd\n"
"fmr 2,0\n" // arg1 (f2)
"b ppcLoadFloatRegUpd\n"
"fmr 3,0\n" // arg2 (f3)
"b ppcLoadFloatRegUpd\n"
"fmr 4,0\n" // arg3 (f4)
"b ppcLoadFloatRegUpd\n"
"fmr 5,0\n" // arg4 (f5)
"b ppcLoadFloatRegUpd\n"
"fmr 6,0\n" // arg5 (f6)
"b ppcLoadFloatRegUpd\n"
"fmr 7,0\n" // arg6 (f7)
"b ppcLoadFloatRegUpd\n"
"fmr 8,0\n" // arg7 (f8)
"b ppcLoadFloatRegUpd\n"
"fmr 9,0\n" // arg8 (f9)
"b ppcLoadFloatRegUpd\n"
"fmr 10,0\n" // arg9 (f10)
"b ppcLoadFloatRegUpd\n"
"fmr 11,0\n" // arg10 (f11)
"b ppcLoadFloatRegUpd\n"
"fmr 12,0\n" // arg11 (f12)
"b ppcLoadFloatRegUpd\n"
"fmr 13,0\n" // arg12 (f13)
"b ppcLoadFloatRegUpd\n"
"nop\n"
// all float arguments still go on the stack
"ppcLoadFloatRegUpd:\n"
"stfs 0, 0x04(%r26)\n" // store, as a single float, f0 (current argument) on to the stack argument list
"addi %r23, %r23, 1\n" // a float register eats up a GPR register
"addi %r22, %r22, 1\n" // ...and, of course, a float register
"addi %r29, %r29, 4\n" // move to the next argument in the list
"addi %r26, %r26, 8\n" // move to the next stack slot
"b ppcNextArg\n" // on to the next argument
"nop\n"
// double Float argument
"ppcArgIsDouble:\n"
"lis %r30, ppcLoadDoubleReg@ha\n" // load the base address of the jump table for double registers
"addi %r30, %r30, ppcLoadDoubleReg@l\n"
"mulli %r0, %r22, 8\n" // each slot of the jump table is 8 bytes
"add %r0, %r0, %r30\n" // calculate ppcLoadDoubleReg[numUsedFloatReg]
"lfd 0, 0(%r29)\n" // load the next argument, as a double float, into f0
"cmpwi %r22,13\n" // the first 13 floats must go into float registers also
"bgt ppcLoadDoubleRegUpd\n" // if we're beyond 13, then just put on to the stack
"mtctr %r0\n" // we're under 13, first load our register
"bctr\n" // jump into the jump table
"nop\n"
// jump table for float registers, for the first 13 float arguments
"ppcLoadDoubleReg:\n"
"fmr 1,0\n" // arg0 (f1)
"b ppcLoadDoubleRegUpd\n"
"fmr 2,0\n" // arg1 (f2)
"b ppcLoadDoubleRegUpd\n"
"fmr 3,0\n" // arg2 (f3)
"b ppcLoadDoubleRegUpd\n"
"fmr 4,0\n" // arg3 (f4)
"b ppcLoadDoubleRegUpd\n"
"fmr 5,0\n" // arg4 (f5)
"b ppcLoadDoubleRegUpd\n"
"fmr 6,0\n" // arg5 (f6)
"b ppcLoadDoubleRegUpd\n"
"fmr 7,0\n" // arg6 (f7)
"b ppcLoadDoubleRegUpd\n"
"fmr 8,0\n" // arg7 (f8)
"b ppcLoadDoubleRegUpd\n"
"fmr 9,0\n" // arg8 (f9)
"b ppcLoadDoubleRegUpd\n"
"fmr 10,0\n" // arg9 (f10)
"b ppcLoadDoubleRegUpd\n"
"fmr 11,0\n" // arg10 (f11)
"b ppcLoadDoubleRegUpd\n"
"fmr 12,0\n" // arg11 (f12)
"b ppcLoadDoubleRegUpd\n"
"fmr 13,0\n" // arg12 (f13)
"b ppcLoadDoubleRegUpd\n"
"nop\n"
// all float arguments still go on the stack
"ppcLoadDoubleRegUpd:\n"
"stfd 0,0(%r26)\n" // store f0, as a double, into the argument list on the stack
"addi %r23, %r23, 1\n" // a double float eats up one GPR
"addi %r22, %r22, 1\n" // ...and, of course, a float
"addi %r29, %r29, 8\n" // increment to our next argument we need to process (8 bytes for the 64bit float)
"addi %r26, %r26, 8\n" // increment to the next slot on the argument list on the stack (8 bytes)
"b ppcNextArg\n" // on to the next argument
"nop\n"
// Long (64 bit int) argument
"ppcArgIsLong:\n"
"lis %r30,ppcLoadLongReg@ha\n" // load the address to the jump table for integer64
"addi %r30, %r30, ppcLoadLongReg@l\n"
"mulli %r0, %r23, 8\n" // each item in the jump table is 2 instructions (8 bytes)
"add %r0, %r0, %r30\n" // calculate ppcLoadLongReg[numUsedGPRRegs]
"ld %r30,0(%r29)\n" // load the next argument from the argument list into r30
"cmpwi %r23, 8\n" // we can only load GPR3 through GPR10 (8 registers)
"bgt ppcLoadLongRegUpd\n" // if we're beyond 8 GPR registers, we're in the stack, go there
"mtctr %r0\n" // load the address of our ppcLoadLongReg jump table (we're below 8 GPR registers)
"bctr\n" // load the argument into a GPR register
"nop\n"
// jump table for GPR registers, for the first 8 GPR arguments
"ppcLoadLongReg:\n"
"mr %r3,%r30\n" // arg0 (to r3)
"b ppcLoadLongRegUpd\n"
"mr %r4,%r30\n" // arg1 (to r4)
"b ppcLoadLongRegUpd\n"
"mr %r5,%r30\n" // arg2 (to r5)
"b ppcLoadLongRegUpd\n"
"mr %r6,%r30\n" // arg3 (to r6)
"b ppcLoadLongRegUpd\n"
"mr %r7,%r30\n" // arg4 (to r7)
"b ppcLoadLongRegUpd\n"
"mr %r8,%r30\n" // arg5 (to r8)
"b ppcLoadLongRegUpd\n"
"mr %r9,%r30\n" // arg6 (to r9)
"b ppcLoadLongRegUpd\n"
"mr %r10,%r30\n" // arg7 (to r10)
"b ppcLoadLongRegUpd\n"
// all GPR arguments still go on the stack
"ppcLoadLongRegUpd:\n"
"std %r30,0(%r26)\n" // store the argument into the next slot on the stack's argument list
"addi %r23, %r23, 1\n" // count a used GPR register
"addi %r29, %r29, 8\n" // move to the next argument on the list
"addi %r26, %r26, 8\n" // adjust our argument stack pointer for the next
"b ppcNextArg\n" // next argument
);
static asDWORD GetReturnedFloat(void)
{
asDWORD f;
#ifdef __SNC__
__stfs( __freg(1), 0, (void*)&f);
#else
asm(" stfs 1, %0\n" : "=m"(f));
#endif
return f;
}
static asQWORD GetReturnedDouble(void)
{
asQWORD f;
#ifdef __SNC__
__stfd( __freg(1), 0, (void*)&f);
#else
asm(" stfd 1, %0\n" : "=m"(f));
#endif
return f;
}
// puts the arguments in the correct place in the stack array. See comments above.
static void stackArgs( const asDWORD *args, const asBYTE *argsType, int &numIntArgs, int &numFloatArgs, int &numDoubleArgs, int &numLongArgs )
{
// initialize our offset based on any already placed arguments
int i;
int argWordPos = numIntArgs + numFloatArgs + (numDoubleArgs*2) + (numLongArgs*2);
int typeOffset = numIntArgs + numFloatArgs + numDoubleArgs + numLongArgs;
int typeIndex;
for( i = 0, typeIndex = 0; ; i++, typeIndex++ )
{
// store the type
ppcArgsType[typeOffset++] = argsType[typeIndex];
if( argsType[typeIndex] == ppcENDARG )
break;
switch( argsType[typeIndex] )
{
case ppcFLOATARG:
{
// stow float
ppcArgs[argWordPos] = args[i]; // it's just a bit copy
numFloatArgs++;
argWordPos++; //add one word
}
break;
case ppcDOUBLEARG:
{
// stow double
memcpy( &ppcArgs[argWordPos], &args[i], sizeof(double) ); // we have to do this because of alignment
numDoubleArgs++;
argWordPos+=2; //add two words
i++;//doubles take up 2 argument slots
}
break;
case ppcINTARG:
{
// stow register
ppcArgs[argWordPos] = args[i];
numIntArgs++;
argWordPos++;
}
break;
case ppcLONGARG:
{
// stow long
memcpy( &ppcArgs[argWordPos], &args[i], 8 ); // for alignment purposes, we use memcpy
numLongArgs++;
argWordPos += 2; // add two words
i++; // longs take up 2 argument slots
}
break;
}
}
// close off the argument list (if we have max args we won't close it off until here)
ppcArgsType[typeOffset] = ppcENDARG;
}
static asQWORD CallCDeclFunction(const asDWORD* pArgs, const asBYTE *pArgsType, int argSize, asDWORD func, void *retInMemory)
{
int baseArgCount = 0;
if( retInMemory )
{
// the first argument is the 'return in memory' pointer
ppcArgs[0] = (asDWORD)retInMemory;
ppcArgsType[0] = ppcINTARG;
ppcArgsType[1] = ppcENDARG;
baseArgCount = 1;
}
// put the arguments in the correct places in the ppcArgs array
int numTotalArgs = baseArgCount;
if( argSize > 0 )
{
int intArgs = baseArgCount, floatArgs = 0, doubleArgs = 0, longArgs = 0;
stackArgs( pArgs, pArgsType, intArgs, floatArgs, doubleArgs, longArgs );
numTotalArgs = intArgs + floatArgs + doubleArgs + longArgs;
}
else
{
// no arguments, cap the type list
ppcArgsType[baseArgCount] = ppcENDARG;
}
// call the function with the arguments
return ppcFunc64( ppcArgs, PPC_STACK_SIZE(numTotalArgs), func );
}
// This function is identical to CallCDeclFunction, with the only difference that
// the value in the first parameter is the object (unless we are returning in memory)
static asQWORD CallThisCallFunction(const void *obj, const asDWORD* pArgs, const asBYTE *pArgsType, int argSize, asDWORD func, void *retInMemory )
{
int baseArgCount = 0;
if( retInMemory )
{
// the first argument is the 'return in memory' pointer
ppcArgs[0] = (asDWORD)retInMemory;
ppcArgsType[0] = ppcINTARG;
ppcArgsType[1] = ppcENDARG;
baseArgCount = 1;
}
// the first argument is the 'this' of the object
ppcArgs[baseArgCount] = (asDWORD)obj;
ppcArgsType[baseArgCount++] = ppcINTARG;
ppcArgsType[baseArgCount] = ppcENDARG;
// put the arguments in the correct places in the ppcArgs array
int numTotalArgs = baseArgCount;
if( argSize > 0 )
{
int intArgs = baseArgCount, floatArgs = 0, doubleArgs = 0, longArgs = 0;
stackArgs( pArgs, pArgsType, intArgs, floatArgs, doubleArgs, longArgs );
numTotalArgs = intArgs + floatArgs + doubleArgs + longArgs;
}
// call the function with the arguments
return ppcFunc64( ppcArgs, PPC_STACK_SIZE(numTotalArgs), func);
}
// This function is identical to CallCDeclFunction, with the only difference that
// the value in the last parameter is the object
// NOTE: on PPC the order for the args is reversed
static asQWORD CallThisCallFunction_objLast(const void *obj, const asDWORD* pArgs, const asBYTE *pArgsType, int argSize, asDWORD func, void *retInMemory)
{
UNUSED_VAR(argSize);
int baseArgCount = 0;
if( retInMemory )
{
// the first argument is the 'return in memory' pointer
ppcArgs[0] = (asDWORD)retInMemory;
ppcArgsType[0] = ppcINTARG;
ppcArgsType[1] = ppcENDARG;
baseArgCount = 1;
}
// stack any of the arguments
int intArgs = baseArgCount, floatArgs = 0, doubleArgs = 0, longArgs = 0;
stackArgs( pArgs, pArgsType, intArgs, floatArgs, doubleArgs, longArgs );
int numTotalArgs = intArgs + floatArgs + doubleArgs;
// can we fit the object in at the end?
if( numTotalArgs < AS_PPC_MAX_ARGS )
{
// put the object pointer at the end
int argPos = intArgs + floatArgs + (doubleArgs * 2) + (longArgs *2);
ppcArgs[argPos] = (asDWORD)obj;
ppcArgsType[numTotalArgs++] = ppcINTARG;
ppcArgsType[numTotalArgs] = ppcENDARG;
}
// call the function with the arguments
return ppcFunc64( ppcArgs, PPC_STACK_SIZE(numTotalArgs), func );
}
// returns true if the given parameter is a 'variable argument'
inline bool IsVariableArgument( asCDataType type )
{
return (type.GetTokenType() == ttQuestion) ? true : false;
}
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void */*secondObject*/)
{
// TODO: PPC 64 does not yet support THISCALL_OBJFIRST/LAST
// use a working array of types, we'll configure the final one in stackArgs
asBYTE argsType[AS_PPC_MAX_ARGS + 1 + 1 + 1];
memset( argsType, 0, sizeof(argsType));
asCScriptEngine *engine = context->m_engine;
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
int callConv = sysFunc->callConv;
asQWORD retQW = 0;
void *func = (void*)sysFunc->func;
int paramSize = sysFunc->paramSize;
asDWORD *vftable = NULL;
int a;
// convert the parameters that are < 4 bytes from little endian to big endian
int argDwordOffset = 0;
int totalArgumentCount = 0;
for( a = 0; a < (int)descr->parameterTypes.GetLength(); ++a )
{
// get the size for the parameter
int numBytes = descr->parameterTypes[a].GetSizeInMemoryBytes();
++totalArgumentCount;
// is this a variable argument?
// for variable arguments, the typeID will always follow...but we know it is 4 bytes
// so we can skip that parameter automatically.
bool isVarArg = IsVariableArgument( descr->parameterTypes[a] );
if( isVarArg )
{
++totalArgumentCount;
}
if( numBytes >= 4 || descr->parameterTypes[a].IsReference() || descr->parameterTypes[a].IsObjectHandle() )
{
// DWORD or larger parameter --- no flipping needed
argDwordOffset += descr->parameterTypes[a].GetSizeOnStackDWords();
}
else
{
// flip
asASSERT( numBytes == 1 || numBytes == 2 );
switch( numBytes )
{
case 1:
{
volatile asBYTE *bPtr = (asBYTE*)ARG_DW(args[argDwordOffset]);
asBYTE t = bPtr[0];
bPtr[0] = bPtr[3];
bPtr[3] = t;
t = bPtr[1];
bPtr[1] = bPtr[2];
bPtr[2] = t;
}
break;
case 2:
{
volatile asWORD *wPtr = (asWORD*)ARG_DW(args[argDwordOffset]);
asWORD t = wPtr[0];
wPtr[0] = wPtr[1];
wPtr[1] = t;
}
break;
}
++argDwordOffset;
}
if( isVarArg )
{
// skip the implicit typeID
++argDwordOffset;
}
}
asASSERT( totalArgumentCount <= AS_PPC_MAX_ARGS );
// mark all float/double/int arguments
int argIndex = 0;
for( a = 0; a < (int)descr->parameterTypes.GetLength(); ++a, ++argIndex )
{
// get the base type
argsType[argIndex] = ppcINTARG;
if( descr->parameterTypes[a].IsFloatType() && !descr->parameterTypes[a].IsReference() )
{
argsType[argIndex] = ppcFLOATARG;
}
if( descr->parameterTypes[a].IsDoubleType() && !descr->parameterTypes[a].IsReference() )
{
argsType[argIndex] = ppcDOUBLEARG;
}
if( descr->parameterTypes[a].GetSizeOnStackDWords() == 2 && !descr->parameterTypes[a].IsDoubleType() && !descr->parameterTypes[a].IsReference() )
{
argsType[argIndex] = ppcLONGARG;
}
// if it is a variable argument, account for the typeID
if( IsVariableArgument(descr->parameterTypes[a]) )
{
// implicitly add another parameter (AFTER the parameter above), for the TypeID
argsType[++argIndex] = ppcINTARG;
}
}
asASSERT( argIndex == totalArgumentCount );
asDWORD paramBuffer[64];
if( sysFunc->takesObjByVal )
{
paramSize = 0;
int spos = 0;
int dpos = 1;
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
{
if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() &&
!(descr->parameterTypes[n].GetTypeInfo()->flags & asOBJ_APP_ARRAY) )
{
#ifdef COMPLEX_OBJS_PASSED_BY_REF
if( descr->parameterTypes[n].GetTypeInfo()->flags & COMPLEX_MASK )
{
paramBuffer[dpos++] = args[spos++];
++paramSize;
}
else
#endif
{
// NOTE: we may have to do endian flipping here
// Copy the object's memory to the buffer
memcpy( &paramBuffer[dpos], *(void**)(args+spos), descr->parameterTypes[n].GetSizeInMemoryBytes() );
// Delete the original memory
engine->CallFree( *(char**)(args+spos) );
spos++;
dpos += descr->parameterTypes[n].GetSizeInMemoryDWords();
paramSize += descr->parameterTypes[n].GetSizeInMemoryDWords();
}
}
else
{
// Copy the value directly
paramBuffer[dpos++] = args[spos++];
if( descr->parameterTypes[n].GetSizeOnStackDWords() > 1 )
{
paramBuffer[dpos++] = args[spos++];
}
paramSize += descr->parameterTypes[n].GetSizeOnStackDWords();
}
// if this was a variable argument parameter, then account for the implicit typeID
if( IsVariableArgument( descr->parameterTypes[n] ) )
{
// the TypeID is just a DWORD
paramBuffer[dpos++] = args[spos++];
++paramSize;
}
}
// Keep a free location at the beginning
args = &paramBuffer[1];
}
// one last verification to make sure things are how we expect
switch( callConv )
{
case ICC_CDECL:
case ICC_CDECL_RETURNINMEM:
case ICC_STDCALL:
case ICC_STDCALL_RETURNINMEM:
retQW = CallCDeclFunction( args, argsType, paramSize, (asDWORD)func, retPointer );
break;
case ICC_THISCALL:
case ICC_THISCALL_RETURNINMEM:
retQW = CallThisCallFunction(obj, args, argsType, paramSize, (asDWORD)func, retPointer );
break;
case ICC_VIRTUAL_THISCALL:
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
// Get virtual function table from the object pointer
vftable = *(asDWORD**)obj;
retQW = CallThisCallFunction( obj, args, argsType, paramSize, vftable[asDWORD(func)>>2], retPointer );
break;
case ICC_CDECL_OBJLAST:
case ICC_CDECL_OBJLAST_RETURNINMEM:
retQW = CallThisCallFunction_objLast( obj, args, argsType, paramSize, (asDWORD)func, retPointer );
break;
case ICC_CDECL_OBJFIRST:
case ICC_CDECL_OBJFIRST_RETURNINMEM:
retQW = CallThisCallFunction( obj, args, argsType, paramSize, (asDWORD)func, retPointer );
break;
default:
context->SetInternalException(TXT_INVALID_CALLING_CONVENTION);
}
if( sysFunc->hostReturnFloat )
{
// If the return is a float value we need to get the value from the FP register
if( sysFunc->hostReturnSize == 1 )
*(asDWORD*)&retQW = GetReturnedFloat();
else
retQW = GetReturnedDouble();
}
else if( sysFunc->hostReturnSize == 1 )
{
// Move the bits to the higher value to compensate for the adjustment that the caller does
retQW <<= 32;
}
return retQW;
}
END_AS_NAMESPACE
#endif // AS_PTR_SIZE == 2
#endif // AS_PPC_64
#endif // AS_MAX_PORTABILITY

View File

@@ -0,0 +1,393 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_callfunc_sh4.cpp
//
// These functions handle the actual calling of system functions
//
// This version is SH4 specific and was originally written
// by Fredrik Ehnbom in May, 2004
// Later updated for angelscript 2.0.0 by Fredrik Ehnbom in Jan, 2005
// References:
// * http://www.renesas.com/avs/resource/japan/eng/pdf/mpumcu/e602156_sh4.pdf
// * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcechp40/html/_callsh4_SH_4_Calling_Standard.asp
#include "as_config.h"
#ifndef AS_MAX_PORTABILITY
#ifdef AS_SH4
#include "as_callfunc.h"
#include "as_scriptengine.h"
#include "as_texts.h"
#include "as_tokendef.h"
#include "as_context.h"
#include <stdio.h>
#include <stdlib.h>
BEGIN_AS_NAMESPACE
#define AS_SH4_MAX_ARGS 32
// The array used to send values to the correct places.
// first 0-4 regular values to load into the r4-r7 registers
// then 0-8 float values to load into the fr4-fr11 registers
// then (AS_SH4_MAX_ARGS - 12) values to load onto the stack
// the +1 is for when CallThis (object methods) is used
// extra +1 when returning in memory
extern "C" {
static asDWORD sh4Args[AS_SH4_MAX_ARGS + 1 + 1];
}
// Loads all data into the correct places and calls the function.
// intArgSize is the size in bytes for how much data to put in int registers
// floatArgSize is the size in bytes for how much data to put in float registers
// stackArgSize is the size in bytes for how much data to put on the callstack
extern "C" asQWORD sh4Func(int intArgSize, int floatArgSize, int stackArgSize, asDWORD func);
asm(""
" .align 4\n"
" .global _sh4Func\n"
"_sh4Func:\n"
" mov.l r14,@-r15\n"
" mov.l r13,@-r15\n"
" mov.l r12,@-r15\n"
" sts.l pr,@-r15\n" // must be saved since we call a subroutine
" mov r7, r14\n" // func
" mov r6, r13\n" // stackArgSize
" mov.l r5,@-r15\n" // floatArgSize
" mov.l sh4Args,r0\n"
" pref @r0\n"
" mov r4, r1\n" // intArgsize
" mov #33*4,r2\n"
" extu.b r2,r2\n" // make unsigned (33*4 = 132 => 128)
" mov.l @(r0,r2), r2\n" // r2 has adress for when returning in memory
"_sh4f_intarguments:\n" // copy all the int arguments to the respective registers
" mov #4*2*2,r3\n" // calculate how many bytes to skip
" sub r1,r3\n"
" braf r3\n"
" add #-4,r1\n" // we are indexing the array backwards, so subtract one (delayed slot)
" mov.l @(r0,r1),r7\n" // 4 arguments
" add #-4,r1\n"
" mov.l @(r0,r1),r6\n" // 3 arguments
" add #-4,r1\n"
" mov.l @(r0,r1),r5\n" // 2 arguments
" add #-4,r1\n"
" mov.l @(r0,r1),r4\n" // 1 argument
" nop\n"
"_sh4f_floatarguments:\n" // copy all the float arguments to the respective registers
" add #4*4, r0\n"
" mov.l @r15+,r1\n" // floatArgSize
" mov #8*2*2,r3\n" // calculate how many bytes to skip
" sub r1,r3\n"
" braf r3\n"
" add #-4,r1\n" // we are indexing the array backwards, so subtract one (delayed slot)
" fmov.s @(r0,r1),fr11\n" // 8 arguments
" add #-4,r1\n"
" fmov.s @(r0,r1),fr10\n" // 7 arguments
" add #-4,r1\n"
" fmov.s @(r0,r1),fr9\n" // 6 arguments
" add #-4,r1\n"
" fmov.s @(r0,r1),fr8\n" // 5 arguments
" add #-4,r1\n"
" fmov.s @(r0,r1),fr7\n" // 4 arguments
" add #-4,r1\n"
" fmov.s @(r0,r1),fr6\n" // 3 arguments
" add #-4,r1\n"
" fmov.s @(r0,r1),fr5\n" // 2 arguments
" add #-4,r1\n"
" fmov.s @(r0,r1),fr4\n" // 1 argument
" nop\n"
"_sh4f_stackarguments:\n" // copy all the stack argument onto the stack
" add #8*4, r0\n"
" mov r0, r1\n"
" mov #0, r0\n" // init position counter (also used as a 0-check on the line after)
" cmp/eq r0, r13\n"
" bt _sh4f_functioncall\n" // no arguments to push onto the stack
" mov r13, r3\n" // stackArgSize
" sub r3,r15\n" // "allocate" space on the stack
" shlr2 r3\n" // make into a counter
"_sh4f_stackloop:\n"
" mov.l @r1+, r12\n"
" mov.l r12, @(r0, r15)\n"
" add #4, r0\n"
" dt r3\n"
" bf _sh4f_stackloop\n"
"_sh4f_functioncall:\n"
" jsr @r14\n" // no arguments
" nop\n"
" add r13, r15\n" // restore stack position
" lds.l @r15+,pr\n"
" mov.l @r15+, r12\n"
" mov.l @r15+, r13\n"
" rts\n"
" mov.l @r15+, r14\n" // delayed slot
"\n"
" .align 4\n"
"sh4Args:\n"
" .long _sh4Args\n"
);
// puts the arguments in the correct place in the sh4Args-array. See comments above.
// This could be done better.
inline void splitArgs(const asDWORD *args, int argNum, int &numRegIntArgs, int &numRegFloatArgs, int &numRestArgs, int hostFlags) {
int i;
int argBit = 1;
for (i = 0; i < argNum; i++) {
if (hostFlags & argBit) {
if (numRegFloatArgs < 12 - 4) {
// put in float register
sh4Args[4 + numRegFloatArgs] = args[i];
numRegFloatArgs++;
} else {
// put in stack
sh4Args[4 + 8 + numRestArgs] = args[i];
numRestArgs++;
}
} else {
if (numRegIntArgs < 8 - 4) {
// put in int register
sh4Args[numRegIntArgs] = args[i];
numRegIntArgs++;
} else {
// put in stack
sh4Args[4 + 8 + numRestArgs] = args[i];
numRestArgs++;
}
}
argBit <<= 1;
}
}
asQWORD CallCDeclFunction(const asDWORD *args, int argSize, asDWORD func, int flags)
{
int argNum = argSize >> 2;
int intArgs = 0;
int floatArgs = 0;
int restArgs = 0;
// put the arguments in the correct places in the sh4Args array
if (argNum > 0)
splitArgs(args, argNum, intArgs, floatArgs, restArgs, flags);
return sh4Func(intArgs << 2, floatArgs << 2, restArgs << 2, func);
}
// This function is identical to CallCDeclFunction, with the only difference that
// the value in the first parameter is the object
asQWORD CallThisCallFunction(const void *obj, const asDWORD *args, int argSize, asDWORD func, int flags)
{
int argNum = argSize >> 2;
int intArgs = 1;
int floatArgs = 0;
int restArgs = 0;
sh4Args[0] = (asDWORD) obj;
// put the arguments in the correct places in the sh4Args array
if (argNum >= 1)
splitArgs(args, argNum, intArgs, floatArgs, restArgs, flags);
return sh4Func(intArgs << 2, floatArgs << 2, restArgs << 2, func);
}
// This function is identical to CallCDeclFunction, with the only difference that
// the value in the last parameter is the object
asQWORD CallThisCallFunction_objLast(const void *obj, const asDWORD *args, int argSize, asDWORD func, int flags)
{
int argNum = argSize >> 2;
int intArgs = 0;
int floatArgs = 0;
int restArgs = 0;
// put the arguments in the correct places in the sh4Args array
if (argNum >= 1)
splitArgs(args, argNum, intArgs, floatArgs, restArgs, flags);
if (intArgs < 4) {
sh4Args[intArgs] = (asDWORD) obj;
intArgs++;
} else {
sh4Args[4 + 8 + restArgs] = (asDWORD) obj;
restArgs++;
}
return sh4Func(intArgs << 2, floatArgs << 2, restArgs << 2, func);
}
asDWORD GetReturnedFloat()
{
asDWORD f;
asm("fmov.s fr0, %0\n" : "=m"(f));
return f;
}
// sizeof(double) == 4 with sh-elf-gcc (3.4.0) -m4
// so this isn't really used...
asQWORD GetReturnedDouble()
{
asQWORD d;
asm("fmov dr0, %0\n" : "=m"(d));
return d;
}
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void */*secondObject*/)
{
// TODO: SH4 does not yet support THISCALL_OBJFIRST/LAST
asCScriptEngine *engine = context->m_engine;
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
int callConv = sysFunc->callConv;
asQWORD retQW = 0;
void *func = (void*)sysFunc->func;
int paramSize = sysFunc->paramSize;
asDWORD *vftable;
if( descr->returnType.IsObject() && !descr->returnType.IsReference() && !descr->returnType.IsObjectHandle() )
{
sh4Args[AS_SH4_MAX_ARGS+1] = (asDWORD) retPointer;
}
asASSERT(descr->parameterTypes.GetLength() <= 32);
// mark all float arguments
int argBit = 1;
int hostFlags = 0;
int intArgs = 0;
for( asUINT a = 0; a < descr->parameterTypes.GetLength(); a++ ) {
if (descr->parameterTypes[a].IsFloatType()) {
hostFlags |= argBit;
} else intArgs++;
argBit <<= 1;
}
asDWORD paramBuffer[64];
if( sysFunc->takesObjByVal )
{
paramSize = 0;
int spos = 0;
int dpos = 1;
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
{
if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
{
#ifdef COMPLEX_OBJS_PASSED_BY_REF
if( descr->parameterTypes[n].GetTypeInfo()->flags & COMPLEX_MASK )
{
paramBuffer[dpos++] = args[spos++];
paramSize++;
}
else
#endif
{
// Copy the object's memory to the buffer
memcpy(&paramBuffer[dpos], *(void**)(args+spos), descr->parameterTypes[n].GetSizeInMemoryBytes());
// Delete the original memory
engine->CallFree(*(char**)(args+spos));
spos++;
dpos += descr->parameterTypes[n].GetSizeInMemoryDWords();
paramSize += descr->parameterTypes[n].GetSizeInMemoryDWords();
}
}
else
{
// Copy the value directly
paramBuffer[dpos++] = args[spos++];
if( descr->parameterTypes[n].GetSizeOnStackDWords() > 1 )
paramBuffer[dpos++] = args[spos++];
paramSize += descr->parameterTypes[n].GetSizeOnStackDWords();
}
}
// Keep a free location at the beginning
args = &paramBuffer[1];
}
switch( callConv )
{
case ICC_CDECL:
case ICC_CDECL_RETURNINMEM:
case ICC_STDCALL:
case ICC_STDCALL_RETURNINMEM:
retQW = CallCDeclFunction(args, paramSize<<2, (asDWORD)func, hostFlags);
break;
case ICC_THISCALL:
case ICC_THISCALL_RETURNINMEM:
retQW = CallThisCallFunction(obj, args, paramSize<<2, (asDWORD)func, hostFlags);
break;
case ICC_VIRTUAL_THISCALL:
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
// Get virtual function table from the object pointer
vftable = *(asDWORD**)obj;
retQW = CallThisCallFunction(obj, args, paramSize<<2, vftable[asDWORD(func)>>2], hostFlags);
break;
case ICC_CDECL_OBJLAST:
case ICC_CDECL_OBJLAST_RETURNINMEM:
retQW = CallThisCallFunction_objLast(obj, args, paramSize<<2, (asDWORD)func, hostFlags);
break;
case ICC_CDECL_OBJFIRST:
case ICC_CDECL_OBJFIRST_RETURNINMEM:
retQW = CallThisCallFunction(obj, args, paramSize<<2, (asDWORD)func, hostFlags);
break;
default:
context->SetInternalException(TXT_INVALID_CALLING_CONVENTION);
}
// If the return is a float value we need to get the value from the FP register
if( sysFunc->hostReturnFloat )
{
if( sysFunc->hostReturnSize == 1 )
*(asDWORD*)&retQW = GetReturnedFloat();
else
retQW = GetReturnedDouble();
}
return retQW;
}
END_AS_NAMESPACE
#endif // AS_SH4
#endif // AS_MAX_PORTABILITY

View File

@@ -0,0 +1,477 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2017 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
/*
* Implements the AMD64 calling convention for gcc-based 64bit Unices
*
* Author: Ionut "gargltk" Leonte <ileonte@bitdefender.com>
*
* Initial author: niteice
*
* Added support for functor methods by Jordi Oliveras Rovira in April, 2014.
*/
// Useful references for the System V AMD64 ABI:
// http://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64/
// http://math-atlas.sourceforge.net/devel/assembly/abi_sysV_amd64.pdf
#include "as_config.h"
#ifndef AS_MAX_PORTABILITY
#ifdef AS_X64_GCC
#include "as_scriptengine.h"
#include "as_texts.h"
#include "as_context.h"
BEGIN_AS_NAMESPACE
enum argTypes { x64INTARG = 0, x64FLOATARG = 1 };
typedef asQWORD ( *funcptr_t )( void );
#define X64_MAX_ARGS 32
#define MAX_CALL_INT_REGISTERS 6
#define MAX_CALL_SSE_REGISTERS 8
#define X64_CALLSTACK_SIZE ( X64_MAX_ARGS + MAX_CALL_SSE_REGISTERS + 3 )
// Note to self: Always remember to inform the used registers on the clobber line,
// so that the gcc optimizer doesn't try to use them for other things
static asQWORD __attribute__((noinline)) X64_CallFunction(const asQWORD *args, int cnt, funcptr_t func, asQWORD &retQW2, bool returnFloat)
{
// Need to flag the variable as volatile so the compiler doesn't optimize out the variable
volatile asQWORD retQW1 = 0;
// Reference: http://www.x86-64.org/documentation/abi.pdf
__asm__ __volatile__ (
" movq %0, %%rcx \n" // rcx = cnt
" movq %1, %%r10 \n" // r10 = args
" movq %2, %%r11 \n" // r11 = func
// Backup stack pointer in R15 that is guaranteed to maintain its value over function calls
" movq %%rsp, %%r15 \n"
#ifdef __OPTIMIZE__
// Make sure the stack unwind logic knows we've backed up the stack pointer in register r15
// This should only be done if any optimization is done. If no optimization (-O0) is used,
// then the compiler already backups the rsp before entering the inline assembler code
" .cfi_def_cfa_register r15 \n"
#endif
// Skip the first 128 bytes on the stack frame, called "red zone",
// that might be used by the compiler to store temporary values
" sub $128, %%rsp \n"
// Make sure the stack pointer will be aligned to 16 bytes when the function is called
" movq %%rcx, %%rdx \n"
" salq $3, %%rdx \n"
" movq %%rsp, %%rax \n"
" sub %%rdx, %%rax \n"
" and $15, %%rax \n"
" sub %%rax, %%rsp \n"
// Push the stack parameters, i.e. the arguments that won't be loaded into registers
" movq %%rcx, %%rsi \n"
" testl %%esi, %%esi \n"
" jle endstack \n"
" subl $1, %%esi \n"
" xorl %%edx, %%edx \n"
" leaq 8(, %%rsi, 8), %%rcx \n"
"loopstack: \n"
" movq 112(%%r10, %%rdx), %%rax \n"
" pushq %%rax \n"
" addq $8, %%rdx \n"
" cmpq %%rcx, %%rdx \n"
" jne loopstack \n"
"endstack: \n"
// Populate integer and floating point parameters
" movq %%r10, %%rax \n"
" mov (%%rax), %%rdi \n"
" mov 8(%%rax), %%rsi \n"
" mov 16(%%rax), %%rdx \n"
" mov 24(%%rax), %%rcx \n"
" mov 32(%%rax), %%r8 \n"
" mov 40(%%rax), %%r9 \n"
" add $48, %%rax \n"
" movsd (%%rax), %%xmm0 \n"
" movsd 8(%%rax), %%xmm1 \n"
" movsd 16(%%rax), %%xmm2 \n"
" movsd 24(%%rax), %%xmm3 \n"
" movsd 32(%%rax), %%xmm4 \n"
" movsd 40(%%rax), %%xmm5 \n"
" movsd 48(%%rax), %%xmm6 \n"
" movsd 56(%%rax), %%xmm7 \n"
// Call the function
" call *%%r11 \n"
// Restore stack pointer
" mov %%r15, %%rsp \n"
#ifdef __OPTIMIZE__
// Inform the stack unwind logic that the stack pointer has been restored
// This should only be done if any optimization is done. If no optimization (-O0) is used,
// then the compiler already backups the rsp before entering the inline assembler code
" .cfi_def_cfa_register rsp \n"
#endif
// Put return value in retQW1 and retQW2, using either RAX:RDX or XMM0:XMM1 depending on type of return value
" movl %5, %%ecx \n"
" testb %%cl, %%cl \n"
" je intret \n"
" lea %3, %%rax \n"
" movq %%xmm0, (%%rax) \n"
" lea %4, %%rdx \n"
" movq %%xmm1, (%%rdx) \n"
" jmp endcall \n"
"intret: \n"
" movq %%rax, %3 \n"
" movq %%rdx, %4 \n"
"endcall: \n"
: : "g" ((asQWORD)cnt), "g" (args), "g" (func), "m" (retQW1), "m" (retQW2), "m" (returnFloat)
: "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7",
"%rdi", "%rsi", "%rax", "%rdx", "%rcx", "%r8", "%r9", "%r10", "%r11", "%r15");
return retQW1;
}
// returns true if the given parameter is a 'variable argument'
static inline bool IsVariableArgument( asCDataType type )
{
return ( type.GetTokenType() == ttQuestion ) ? true : false;
}
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &retQW2, void *secondObject)
{
asCScriptEngine *engine = context->m_engine;
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
int callConv = sysFunc->callConv;
asQWORD retQW = 0;
asDWORD *stack_pointer = args;
funcptr_t *vftable = NULL;
int totalArgumentCount = 0;
int n = 0;
int param_post = 0;
int argIndex = 0;
funcptr_t func = (funcptr_t)sysFunc->func;
if( sysFunc->hostReturnInMemory )
{
// The return is made in memory
callConv++;
}
#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
// Determine the real function pointer in case of virtual method
if ( obj && ( callConv == ICC_VIRTUAL_THISCALL || callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM ) )
#else
if ( obj && ( callConv == ICC_VIRTUAL_THISCALL ||
callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM ||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST ||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM ||
callConv == ICC_VIRTUAL_THISCALL_OBJLAST ||
callConv == ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM) )
#endif
{
vftable = *((funcptr_t**)obj);
func = vftable[FuncPtrToUInt(asFUNCTION_t(func)) >> 3];
}
// Determine the type of the arguments, and prepare the input array for the X64_CallFunction
asQWORD paramBuffer[X64_CALLSTACK_SIZE] = { 0 };
asBYTE argsType[X64_CALLSTACK_SIZE] = { 0 };
switch ( callConv )
{
case ICC_CDECL_RETURNINMEM:
case ICC_STDCALL_RETURNINMEM:
{
paramBuffer[0] = (asPWORD)retPointer;
argsType[0] = x64INTARG;
argIndex = 1;
break;
}
#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
case ICC_THISCALL_OBJLAST:
case ICC_VIRTUAL_THISCALL_OBJLAST:
param_post = 2;
#endif
case ICC_THISCALL:
case ICC_VIRTUAL_THISCALL:
case ICC_CDECL_OBJFIRST:
{
paramBuffer[0] = (asPWORD)obj;
argsType[0] = x64INTARG;
argIndex = 1;
break;
}
#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
case ICC_THISCALL_OBJLAST_RETURNINMEM:
case ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM:
param_post = 2;
#endif
case ICC_THISCALL_RETURNINMEM:
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
case ICC_CDECL_OBJFIRST_RETURNINMEM:
{
paramBuffer[0] = (asPWORD)retPointer;
paramBuffer[1] = (asPWORD)obj;
argsType[0] = x64INTARG;
argsType[1] = x64INTARG;
argIndex = 2;
break;
}
#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
case ICC_THISCALL_OBJFIRST:
case ICC_VIRTUAL_THISCALL_OBJFIRST:
{
paramBuffer[0] = (asPWORD)obj;
paramBuffer[1] = (asPWORD)secondObject;
argsType[0] = x64INTARG;
argsType[1] = x64INTARG;
argIndex = 2;
break;
}
case ICC_THISCALL_OBJFIRST_RETURNINMEM:
case ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM:
{
paramBuffer[0] = (asPWORD)retPointer;
paramBuffer[1] = (asPWORD)obj;
paramBuffer[2] = (asPWORD)secondObject;
argsType[0] = x64INTARG;
argsType[1] = x64INTARG;
argsType[2] = x64INTARG;
argIndex = 3;
break;
}
#endif
case ICC_CDECL_OBJLAST:
param_post = 1;
break;
case ICC_CDECL_OBJLAST_RETURNINMEM:
{
paramBuffer[0] = (asPWORD)retPointer;
argsType[0] = x64INTARG;
argIndex = 1;
param_post = 1;
break;
}
}
int argumentCount = ( int )descr->parameterTypes.GetLength();
for( int a = 0; a < argumentCount; ++a )
{
const asCDataType &parmType = descr->parameterTypes[a];
if( parmType.IsFloatType() && !parmType.IsReference() )
{
argsType[argIndex] = x64FLOATARG;
memcpy(paramBuffer + argIndex, stack_pointer, sizeof(float));
argIndex++;
stack_pointer++;
}
else if( parmType.IsDoubleType() && !parmType.IsReference() )
{
argsType[argIndex] = x64FLOATARG;
memcpy(paramBuffer + argIndex, stack_pointer, sizeof(double));
argIndex++;
stack_pointer += 2;
}
else if( IsVariableArgument( parmType ) )
{
// The variable args are really two, one pointer and one type id
argsType[argIndex] = x64INTARG;
argsType[argIndex+1] = x64INTARG;
memcpy(paramBuffer + argIndex, stack_pointer, sizeof(void*));
memcpy(paramBuffer + argIndex + 1, stack_pointer + 2, sizeof(asDWORD));
argIndex += 2;
stack_pointer += 3;
}
else if( parmType.IsPrimitive() ||
parmType.IsReference() ||
parmType.IsObjectHandle() )
{
argsType[argIndex] = x64INTARG;
if( parmType.GetSizeOnStackDWords() == 1 )
{
memcpy(paramBuffer + argIndex, stack_pointer, sizeof(asDWORD));
stack_pointer++;
}
else
{
memcpy(paramBuffer + argIndex, stack_pointer, sizeof(asQWORD));
stack_pointer += 2;
}
argIndex++;
}
else
{
// An object is being passed by value
if( (parmType.GetTypeInfo()->flags & COMPLEX_MASK) ||
parmType.GetSizeInMemoryDWords() > 4 )
{
// Copy the address of the object
argsType[argIndex] = x64INTARG;
memcpy(paramBuffer + argIndex, stack_pointer, sizeof(asQWORD));
argIndex++;
}
else if( (parmType.GetTypeInfo()->flags & asOBJ_APP_CLASS_ALLINTS) ||
(parmType.GetTypeInfo()->flags & asOBJ_APP_PRIMITIVE) )
{
// Copy the value of the object
if( parmType.GetSizeInMemoryDWords() > 2 )
{
argsType[argIndex] = x64INTARG;
argsType[argIndex+1] = x64INTARG;
memcpy(paramBuffer + argIndex, *(asDWORD**)stack_pointer, parmType.GetSizeInMemoryBytes());
argIndex += 2;
}
else
{
argsType[argIndex] = x64INTARG;
memcpy(paramBuffer + argIndex, *(asDWORD**)stack_pointer, parmType.GetSizeInMemoryBytes());
argIndex++;
}
// Delete the original memory
engine->CallFree(*(void**)stack_pointer);
}
else if( (parmType.GetTypeInfo()->flags & asOBJ_APP_CLASS_ALLFLOATS) ||
(parmType.GetTypeInfo()->flags & asOBJ_APP_FLOAT) )
{
// Copy the value of the object
if( parmType.GetSizeInMemoryDWords() > 2 )
{
argsType[argIndex] = x64FLOATARG;
argsType[argIndex+1] = x64FLOATARG;
memcpy(paramBuffer + argIndex, *(asDWORD**)stack_pointer, parmType.GetSizeInMemoryBytes());
argIndex += 2;
}
else
{
argsType[argIndex] = x64FLOATARG;
memcpy(paramBuffer + argIndex, *(asDWORD**)stack_pointer, parmType.GetSizeInMemoryBytes());
argIndex++;
}
// Delete the original memory
engine->CallFree(*(void**)stack_pointer);
}
stack_pointer += 2;
}
}
// For the CDECL_OBJ_LAST calling convention we need to add the object pointer as the last argument
if( param_post )
{
#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
paramBuffer[argIndex] = (asPWORD)obj;
#else
paramBuffer[argIndex] = (asPWORD)(param_post > 1 ? secondObject : obj);
#endif
argsType[argIndex] = x64INTARG;
argIndex++;
}
totalArgumentCount = argIndex;
/*
* Q: WTF is going on here !?
*
* A: The idea is to pre-arange the parameters so that X64_CallFunction() can do
* it's little magic which must work regardless of how the compiler decides to
* allocate registers. Basically:
* - the first MAX_CALL_INT_REGISTERS entries in tempBuff will
* contain the values/types of the x64INTARG parameters - that is the ones who
* go into the registers. If the function has less then MAX_CALL_INT_REGISTERS
* integer parameters then the last entries will be set to 0
* - the next MAX_CALL_SSE_REGISTERS entries will contain the float/double arguments
* that go into the floating point registers. If the function has less than
* MAX_CALL_SSE_REGISTERS floating point parameters then the last entries will
* be set to 0
* - index MAX_CALL_INT_REGISTERS + MAX_CALL_SSE_REGISTERS marks the start of the
* parameters which will get passed on the stack. These are added to the array
* in reverse order so that X64_CallFunction() can simply push them to the stack
* without the need to perform further tests
*/
asQWORD tempBuff[X64_CALLSTACK_SIZE] = { 0 };
asBYTE argsSet[X64_CALLSTACK_SIZE] = { 0 };
int used_int_regs = 0;
int used_sse_regs = 0;
int used_stack_args = 0;
int idx = 0;
for ( n = 0; ( n < totalArgumentCount ) && ( used_int_regs < MAX_CALL_INT_REGISTERS ); n++ )
{
if ( argsType[n] == x64INTARG )
{
argsSet[n] = 1;
tempBuff[idx++] = paramBuffer[n];
used_int_regs++;
}
}
idx = MAX_CALL_INT_REGISTERS;
for ( n = 0; ( n < totalArgumentCount ) && ( used_sse_regs < MAX_CALL_SSE_REGISTERS ); n++ )
{
if ( argsType[n] == x64FLOATARG )
{
argsSet[n] = 1;
tempBuff[idx++] = paramBuffer[n];
used_sse_regs++;
}
}
idx = MAX_CALL_INT_REGISTERS + MAX_CALL_SSE_REGISTERS;
for ( n = totalArgumentCount - 1; n >= 0; n-- )
{
if ( !argsSet[n] )
{
tempBuff[idx++] = paramBuffer[n];
used_stack_args++;
}
}
retQW = X64_CallFunction( tempBuff, used_stack_args, func, retQW2, sysFunc->hostReturnFloat );
return retQW;
}
END_AS_NAMESPACE
#endif // AS_X64_GCC
#endif // AS_MAX_PORTABILITY

View File

@@ -0,0 +1,348 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// This code was adapted from as_callfunc_x64_msvc by _Vicious_ on August 20th, 2011.
//
// Added support for functor methods by Jordi Oliveras Rovira in April, 2014.
//
#include <stdio.h>
#include "as_config.h"
#ifndef AS_MAX_PORTABILITY
#ifdef AS_X64_MINGW
#include "as_callfunc.h"
#include "as_scriptengine.h"
#include "as_texts.h"
#include "as_context.h"
BEGIN_AS_NAMESPACE
static asQWORD __attribute__((noinline)) CallX64(const asQWORD *args, const asQWORD *floatArgs, const int paramSize, asQWORD func)
{
volatile asQWORD ret = 0;
__asm__ __volatile__ (
"# Move the parameters into registers before the rsp is modified\n"
"mov %1, %%r10\n" // r10 = args
"mov %2, %%r11\n" // r11 = floatArgs
"xor %%r12, %%r12\n"
"mov %3, %%r12d\n"
"mov %4, %%r14\n" // r14 = func
"# Store the stack pointer in r15 since it is guaranteed not to change over a function call\n"
"mov %%rsp, %%r15\n"
"# Allocate space on the stack for the arguments\n"
"# Make room for at least 4 arguments even if there are less. When\n"
"# the compiler does optimizations for speed it may use these for \n"
"# temporary storage.\n"
"mov %%r12, %%rdi\n"
"add $32,%%edi\n"
"# Make sure the stack pointer is 16byte aligned so the\n"
"# whole program optimizations will work properly\n"
"# TODO: runtime optimize: Can this be optimized with fewer instructions?\n"
"mov %%rsp,%%rsi\n"
"sub %%rdi,%%rsi\n"
"and $0x8,%%rsi\n"
"add %%rsi,%%rdi\n"
"sub %%rdi,%%rsp\n"
"# Jump straight to calling the function if no parameters\n"
"cmp $0,%%r12 # Compare paramSize with 0\n"
"je callfunc # Jump to call funtion if (paramSize == 0)\n"
"# Copy arguments from script stack to application stack\n"
"# Order is (first to last):\n"
"# rcx, rdx, r8, r9 & everything else goes on stack\n"
"movq (%%r10),%%rcx\n"
"movq 8(%%r10),%%rdx\n"
"movq 16(%%r10),%%r8\n"
"movq 24(%%r10),%%r9\n"
"# Negate the 4 params from the size to be copied\n"
"sub $32,%%r12d\n"
"js copyfloat # Jump if negative result\n"
"jz copyfloat # Jump if zero result\n"
"# Now copy all remaining params onto stack allowing space for first four\n"
"# params to be flushed back to the stack if required by the callee.\n"
"add $32,%%r10 # Position input pointer 4 args ahead\n"
"mov %%rsp,%%r13 # Put the stack pointer into r13\n"
"add $32,%%r13 # Leave space for first 4 args on stack\n"
"copyoverflow:\n"
"movq (%%r10),%%rdi # Read param from source stack into rdi\n"
"movq %%rdi,(%%r13) # Copy param to real stack\n"
"add $8,%%r13 # Move virtual stack pointer\n"
"add $8,%%r10 # Move source stack pointer\n"
"sub $8,%%r12d # Decrement remaining count\n"
"jnz copyoverflow # Continue if more params\n"
"copyfloat:\n"
"# Any floating point params?\n"
"cmp $0,%%r11\n"
"je callfunc\n"
"movlpd (%%r11),%%xmm0\n"
"movlpd 8(%%r11),%%xmm1\n"
"movlpd 16(%%r11),%%xmm2\n"
"movlpd 24(%%r11),%%xmm3\n"
"callfunc:\n"
"call *%%r14\n"
"# restore stack pointer\n"
"mov %%r15, %%rsp\n"
"lea %0, %%rbx\n" // Load the address of the ret variable into rbx
"movq %%rax,(%%rbx)\n" // Copy the returned value into the ret variable
: // no output
: "m" (ret), "r" (args), "r" (floatArgs), "r" (paramSize), "r" (func)
: "rdi", "rsi", "rsp", "rbx", "r10", "r11", "%r12", "r13", "r14", "r15"
);
return ret;
}
static asDWORD GetReturnedFloat()
{
volatile asDWORD ret = 0;
__asm__ __volatile__ (
"lea %0, %%rax\n"
"movss %%xmm0, (%%rax)"
: /* no output */
: "m" (ret)
: "%rax"
);
return ret;
}
static asQWORD GetReturnedDouble()
{
volatile asQWORD ret = 0;
__asm__ __volatile__ (
"lea %0, %%rax\n"
"movlpd %%xmm0, (%%rax)"
: /* no optput */
: "m" (ret)
: "%rax"
);
return ret;
}
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void *secondObject)
{
asCScriptEngine *engine = context->m_engine;
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
asQWORD retQW = 0;
void *func = (void*)sysFunc->func;
asUINT paramSize = 0; // QWords
void **vftable;
asQWORD allArgBuffer[64];
asQWORD floatArgBuffer[4];
int callConv = sysFunc->callConv;
if( sysFunc->hostReturnInMemory )
{
// The return is made in memory
callConv++;
// Set the return pointer as the first argument
allArgBuffer[paramSize++] = (asQWORD)retPointer;
}
#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
if( callConv == ICC_THISCALL ||
callConv == ICC_THISCALL_RETURNINMEM ||
callConv == ICC_VIRTUAL_THISCALL ||
callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM )
#else
// Optimization to avoid check 12 values (all ICC_ that contains THISCALL)
if( (callConv >= ICC_THISCALL && callConv <= ICC_VIRTUAL_THISCALL_RETURNINMEM) ||
(callConv >= ICC_THISCALL_OBJLAST && callConv <= ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM) )
#endif
{
// Add the object pointer as the first parameter
allArgBuffer[paramSize++] = (asQWORD)obj;
}
if( callConv == ICC_CDECL_OBJFIRST ||
callConv == ICC_CDECL_OBJFIRST_RETURNINMEM )
{
// Add the object pointer as the first parameter
allArgBuffer[paramSize++] = (asQWORD)obj;
}
#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
else if( callConv == ICC_THISCALL_OBJFIRST ||
callConv == ICC_THISCALL_OBJFIRST_RETURNINMEM ||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST ||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM )
{
// Add the object pointer as the first parameter
allArgBuffer[paramSize++] = (asQWORD)secondObject;
}
#endif
#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
if( callConv == ICC_VIRTUAL_THISCALL ||
callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM )
#else
if( callConv == ICC_VIRTUAL_THISCALL ||
callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM ||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST ||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM ||
callConv == ICC_VIRTUAL_THISCALL_OBJLAST ||
callConv == ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM )
#endif
{
// Get the true function pointer from the virtual function table
vftable = *(void***)obj;
func = vftable[asPWORD(func)>>3];
}
// Move the arguments to the buffer
asUINT dpos = paramSize;
asUINT spos = 0;
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
{
if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
{
if( descr->parameterTypes[n].GetSizeInMemoryDWords() >= AS_LARGE_OBJ_MIN_SIZE ||
(descr->parameterTypes[n].GetTypeInfo()->flags & COMPLEX_MASK) )
{
allArgBuffer[dpos++] = *(asQWORD*)&args[spos];
spos += AS_PTR_SIZE;
paramSize++;
}
else
{
// Copy the object's memory to the buffer
memcpy(&allArgBuffer[dpos], *(void**)(args+spos), descr->parameterTypes[n].GetSizeInMemoryBytes());
// Delete the original memory
engine->CallFree(*(char**)(args+spos));
spos += AS_PTR_SIZE;
asUINT dwords = descr->parameterTypes[n].GetSizeInMemoryDWords();
asUINT qwords = (dwords >> 1) + (dwords & 1);
dpos += qwords;
paramSize += qwords;
}
}
else if( descr->parameterTypes[n].GetTokenType() == ttQuestion )
{
// Copy the reference and the type id
allArgBuffer[dpos++] = *(asQWORD*)&args[spos];
spos += 2;
allArgBuffer[dpos++] = args[spos++];
paramSize += 2;
}
else
{
// Copy the value directly
asUINT dwords = descr->parameterTypes[n].GetSizeOnStackDWords();
if( dwords > 1 )
{
allArgBuffer[dpos] = *(asQWORD*)&args[spos];
// Double arguments are moved to a separate buffer in order to be placed in the XMM registers,
// though this is only done for first 4 arguments, the rest are placed on the stack
if( paramSize < 4 && descr->parameterTypes[n].IsDoubleType() )
floatArgBuffer[dpos] = *(asQWORD*)&args[spos];
dpos++;
spos += 2;
}
else
{
allArgBuffer[dpos] = args[spos];
// Float arguments are moved to a separate buffer in order to be placed in the XMM registers,
// though this is only done for first 4 arguments, the rest are placed on the stack
if( paramSize < 4 && descr->parameterTypes[n].IsFloatType() )
floatArgBuffer[dpos] = args[spos];
dpos++;
spos++;
}
paramSize++;
}
}
if( callConv == ICC_CDECL_OBJLAST ||
callConv == ICC_CDECL_OBJLAST_RETURNINMEM )
{
// Add the object pointer as the last parameter
allArgBuffer[paramSize++] = (asQWORD)obj;
}
#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
else if( callConv == ICC_THISCALL_OBJLAST ||
callConv == ICC_THISCALL_OBJLAST_RETURNINMEM ||
callConv == ICC_VIRTUAL_THISCALL_OBJLAST ||
callConv == ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM )
{
// Add the object pointer as the last parameter
allArgBuffer[paramSize++] = (asQWORD)secondObject;
}
#endif
retQW = CallX64(allArgBuffer, floatArgBuffer, paramSize*8, (asPWORD)func);
// If the return is a float value we need to get the value from the FP register
if( sysFunc->hostReturnFloat )
{
if( sysFunc->hostReturnSize == 1 )
*(asDWORD*)&retQW = GetReturnedFloat();
else
retQW = GetReturnedDouble();
}
return retQW;
}
END_AS_NAMESPACE
#endif // AS_X64_MSVC
#endif // AS_MAX_PORTABILITY

View File

@@ -0,0 +1,217 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// Added support for thiscall methods by Jordi Oliveras Rovira in April, 2014.
//
#include <stdio.h>
#include "as_config.h"
#ifndef AS_MAX_PORTABILITY
#ifdef AS_X64_MSVC
#include "as_callfunc.h"
#include "as_scriptengine.h"
#include "as_texts.h"
#include "as_context.h"
BEGIN_AS_NAMESPACE
// These functions are implemented in as_callfunc_x64_msvc.asm
extern "C" asQWORD CallX64(const asQWORD *args, const asQWORD *floatArgs, int paramSize, asQWORD func);
extern "C" asDWORD GetReturnedFloat();
extern "C" asQWORD GetReturnedDouble();
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void *secondObject)
{
asCScriptEngine *engine = context->m_engine;
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
asQWORD retQW = 0;
void *func = (void*)sysFunc->func;
asUINT paramSize = 0; // QWords
void **vftable;
asQWORD allArgBuffer[64];
asQWORD floatArgBuffer[4];
int callConv = sysFunc->callConv;
// Optimization to avoid check 12 values (all ICC_ that contains THISCALL)
if( (callConv >= ICC_THISCALL && callConv <= ICC_VIRTUAL_THISCALL_RETURNINMEM) ||
(callConv >= ICC_THISCALL_OBJLAST && callConv <= ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM) )
{
// Add the object pointer as the first parameter
allArgBuffer[paramSize++] = (asQWORD)obj;
}
if( sysFunc->hostReturnInMemory )
{
// The return is made in memory
callConv++;
// Set the return pointer as the first argument
allArgBuffer[paramSize++] = (asQWORD)retPointer;
}
if( callConv == ICC_CDECL_OBJFIRST ||
callConv == ICC_CDECL_OBJFIRST_RETURNINMEM )
{
// Add the object pointer as the first parameter
allArgBuffer[paramSize++] = (asQWORD)obj;
}
else if( callConv == ICC_THISCALL_OBJFIRST ||
callConv == ICC_THISCALL_OBJFIRST_RETURNINMEM ||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST ||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM )
{
// Add the object pointer as the first parameter
allArgBuffer[paramSize++] = (asQWORD)secondObject;
}
if( callConv == ICC_VIRTUAL_THISCALL ||
callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM ||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST ||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM ||
callConv == ICC_VIRTUAL_THISCALL_OBJLAST ||
callConv == ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM )
{
// Get the true function pointer from the virtual function table
vftable = *(void***)obj;
func = vftable[asPWORD(func)>>2];
}
// Move the arguments to the buffer
asUINT dpos = paramSize;
asUINT spos = 0;
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
{
asCDataType &dt = descr->parameterTypes[n];
if( dt.IsObject() && !dt.IsObjectHandle() && !dt.IsReference() )
{
if( dt.GetSizeInMemoryDWords() >= AS_LARGE_OBJ_MIN_SIZE ||
(dt.GetTypeInfo()->flags & COMPLEX_MASK) )
{
allArgBuffer[dpos++] = *(asQWORD*)&args[spos];
spos += AS_PTR_SIZE;
paramSize++;
}
else
{
// Copy the object's memory to the buffer
memcpy(&allArgBuffer[dpos], *(void**)(args+spos), dt.GetSizeInMemoryBytes());
// Delete the original memory
engine->CallFree(*(char**)(args+spos));
spos += AS_PTR_SIZE;
asUINT dwords = dt.GetSizeInMemoryDWords();
asUINT qwords = (dwords >> 1) + (dwords & 1);
dpos += qwords;
paramSize += qwords;
}
}
else if( dt.GetTokenType() == ttQuestion )
{
// Copy the reference and the type id
allArgBuffer[dpos++] = *(asQWORD*)&args[spos];
spos += 2;
allArgBuffer[dpos++] = args[spos++];
paramSize += 2;
}
else
{
// Copy the value directly
asUINT dwords = dt.GetSizeOnStackDWords();
if( dwords > 1 )
{
allArgBuffer[dpos] = *(asQWORD*)&args[spos];
// Double arguments are moved to a separate buffer in order to be placed in the XMM registers,
// though this is only done for first 4 arguments, the rest are placed on the stack
if( paramSize < 4 && dt.IsDoubleType() )
floatArgBuffer[dpos] = *(asQWORD*)&args[spos];
dpos++;
spos += 2;
}
else
{
allArgBuffer[dpos] = args[spos];
// Float arguments are moved to a separate buffer in order to be placed in the XMM registers,
// though this is only done for first 4 arguments, the rest are placed on the stack
if( paramSize < 4 && dt.IsFloatType() )
floatArgBuffer[dpos] = args[spos];
dpos++;
spos++;
}
paramSize++;
}
}
if( callConv == ICC_CDECL_OBJLAST ||
callConv == ICC_CDECL_OBJLAST_RETURNINMEM )
{
// Add the object pointer as the last parameter
allArgBuffer[paramSize++] = (asQWORD)obj;
}
else if( callConv == ICC_THISCALL_OBJLAST ||
callConv == ICC_THISCALL_OBJLAST_RETURNINMEM ||
callConv == ICC_VIRTUAL_THISCALL_OBJLAST ||
callConv == ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM )
{
// Add the object pointer as the last parameter
allArgBuffer[paramSize++] = (asQWORD)secondObject;
}
retQW = CallX64(allArgBuffer, floatArgBuffer, paramSize*8, (asPWORD)func);
// If the return is a float value we need to get the value from the FP register
if( sysFunc->hostReturnFloat )
{
if( sysFunc->hostReturnSize == 1 )
*(asDWORD*)&retQW = GetReturnedFloat();
else
retQW = GetReturnedDouble();
}
return retQW;
}
END_AS_NAMESPACE
#endif // AS_X64_MSVC
#endif // AS_MAX_PORTABILITY

View File

@@ -0,0 +1,208 @@
;
; AngelCode Scripting Library
; Copyright (c) 2003-2011 Andreas Jonsson
;
; This software is provided 'as-is', without any express or implied
; warranty. In no event will the authors be held liable for any
; damages arising from the use of this software.
;
; Permission is granted to anyone to use this software for any
; purpose, including commercial applications, and to alter it and
; redistribute it freely, subject to the following restrictions:
;
; 1. The origin of this software must not be misrepresented; you
; must not claim that you wrote the original software. If you use
; this software in a product, an acknowledgment in the product
; documentation would be appreciated but is not required.
;
; 2. Altered source versions must be plainly marked as such, and
; must not be misrepresented as being the original software.
;
; 3. This notice may not be removed or altered from any source
; distribution.
;
; The original version of this library can be located at:
; http://www.angelcode.com/angelscript/
;
; Andreas Jonsson
; andreas@angelcode.com
;
.code
PUBLIC CallX64
; asQWORD CallX64(const asQWORD *args, const asQWORD *floatArgs, int paramSize, asQWORD func)
CallX64 PROC FRAME
; PROLOG
; We must save preserved registers that are used
; TODO: No need to save unused registers
push rbp
.pushreg rbp
push rsi
.pushreg rsi
push r11
.pushreg r11
push rdi
.pushreg rdi
push r12
.pushreg r12
push r13
.pushreg r13
push r14
.pushreg r14
push r15
.pushreg r15
push rbx
.pushreg rbx
sub rsp, 050h
.allocstack 050h
mov rbp, rsp
.setframe rbp, 0
.endprolog
; Move function param to non-scratch register
mov r14, r9 ; r14 = function
; Allocate space on the stack for the arguments
; Make room for at least 4 arguments even if there are less. When
; the compiler does optimizations for speed it may use these for
; temporary storage.
mov rdi, r8
add rdi, 32
; Make sure the stack pointer is 16byte aligned so the
; whole program optimizations will work properly
; TODO: optimize: Can this be optimized with fewer instructions?
mov rsi, rsp
sub rsi, rdi
and rsi, 8h
add rdi, rsi
sub rsp, rdi
; Jump straight to calling the function if no parameters
cmp r8d, 0 ; Compare paramSize with 0
je callfunc ; Jump to call funtion if (paramSize == 0)
; Move params to non-scratch registers
mov rsi, rcx ; rsi = pArgs
mov r11, rdx ; r11 = pFloatArgs (can be NULL)
mov r12d, r8d ; r12 = paramSize
; Copy arguments from script stack to application stack
; Order is (first to last):
; rcx, rdx, r8, r9 & everything else goes on stack
mov rcx, qword ptr [rsi]
mov rdx, qword ptr [rsi + 8]
mov r8, qword ptr [rsi + 16]
mov r9, qword ptr [rsi + 24]
; Negate the 4 params from the size to be copied
sub r12d, 32
js copyfloat ; Jump if negative result
jz copyfloat ; Jump if zero result
; Now copy all remaining params onto stack allowing space for first four
; params to be flushed back to the stack if required by the callee.
add rsi, 32 ; Position input pointer 4 args ahead
mov r13, rsp ; Put the stack pointer into r13
add r13, 32 ; Leave space for first 4 args on stack
copyoverflow:
mov r15, qword ptr [rsi] ; Read param from source stack into r15
mov qword ptr [r13], r15 ; Copy param to real stack
add r13, 8 ; Move virtual stack pointer
add rsi, 8 ; Move source stack pointer
sub r12d, 8 ; Decrement remaining count
jnz copyoverflow ; Continue if more params
copyfloat:
; Any floating point params?
cmp r11, 0
je callfunc
movlpd xmm0, qword ptr [r11]
movlpd xmm1, qword ptr [r11 + 8]
movlpd xmm2, qword ptr [r11 + 16]
movlpd xmm3, qword ptr [r11 + 24]
callfunc:
; Call function
call r14
; Restore the stack
mov rsp, rbp
; EPILOG: Restore stack & preserved registers
add rsp, 050h
pop rbx
pop r15
pop r14
pop r13
pop r12
pop rdi
pop r11
pop rsi
pop rbp
; return value in RAX
ret
CallX64 ENDP
PUBLIC GetReturnedFloat
; asDWORD GetReturnedFloat()
GetReturnedFloat PROC FRAME
; PROLOG: Store registers and allocate stack space
sub rsp, 8 ; We'll need 4 bytes for temporary storage (8 bytes with alignment)
.allocstack 8
.endprolog
; Move the float value from the XMM0 register to RAX register
movss dword ptr [rsp], xmm0
mov eax, dword ptr [rsp]
; EPILOG: Clean up
add rsp, 8
ret
GetReturnedFloat ENDP
PUBLIC GetReturnedDouble
; asDWORD GetReturnedDouble()
GetReturnedDouble PROC FRAME
; PROLOG: Store registers and allocate stack space
sub rsp, 8 ; We'll need 8 bytes for temporary storage
.allocstack 8
.endprolog
; Move the double value from the XMM0 register to the RAX register
movlpd qword ptr [rsp], xmm0
mov rax, qword ptr [rsp]
; EPILOG: Clean up
add rsp, 8
ret
GetReturnedDouble ENDP
END

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,737 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_callfunc_xenon.cpp
//
// These functions handle the actual calling of system functions
//
// This version is Xenon specific
// Modified from as_callfunc_ppc.cpp by Laszlo Perneky February 2007
//
// Modified by Cyril Tissier March 2010:
// various fixes in 'float' args passing / function return
// properly handling 'double' type
// various fixes in asm ppcFunc
// fix for variable arguments
//
// Modified by Anthony Clark May 2015
// Fixed the issue where int64 and uint64 could not be passed nativly
// few minor fixes within asm ppcFunc to handle int64 and uint64
// XBox 360 calling convention
// ===========================
// I've yet to find an official document with the ABI for XBox 360,
// but I'll describe what I've gathered from the code and tests
// performed by the AngelScript community.
//
// Arguments are passed in the following registers:
// r3 - r10 : integer/pointer arguments (each register is 64bit)
// fr1 - fr13 : float/double arguments (each register is 64bit)
//
// Arguments that don't fit in the registers will be pushed on the stack.
//
// When a float or double is passed as argument, its value will be placed
// in the next available float register, but it will also reserve general
// purpose register.
//
// Example: void foo(float a, int b). a will be passed in fr1 and b in r4.
//
// For each argument passed to a function an 8byte slot is reserved on the
// stack, so that the function can offload the value there if needed. The
// first slot is at r1+20, the next at r1+28, etc.
//
// If the function is a class method, the this pointer is passed as hidden
// first argument. If the function returns an object in memory, the address
// for that memory is passed as hidden first argument.
//
// Return value are placed in the following registers:
// r3 : integer/pointer values
// fr1 : float/double values
//
// Rules for registers
// r1 : stack pointer
// r14-r31 : nonvolatile, i.e. their values must be preserved
// fr14-fr31 : nonvolatile, i.e. their values must be preserved
// r0, r2, r13 : dedicated. I'm not sure what it means, but it is probably best not to use them
//
// The stack pointer must always be aligned at 8 bytes.
//
// References:
// https://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/852569B20050FF77852569970071B0D6/$file/eabi_app.pdf
//
// TODO: The code doesn't handle objects passed by value (unless they are max 4 bytes in size)
#include "as_config.h"
#ifndef AS_MAX_PORTABILITY
#if defined(AS_XENON)
#include "as_callfunc.h"
#include "as_scriptengine.h"
#include "as_texts.h"
#include "as_tokendef.h"
#include "as_context.h"
#include <stdio.h>
#include <stdlib.h>
#include <xtl.h>
BEGIN_AS_NAMESPACE
#define AS_PPC_MAX_ARGS 32
#define AS_PPC_THISCALL_REG 1
#define AS_PPC_RETURNINMEM_REG 1
#define AS_PPC_ENDOFARGS 1
// The array used to send values to the correct places.
// Contains a byte of argTypes to indicate the register type to load, or zero if end of arguments
enum argTypes
{
ppcENDARG = 0,
ppcINTARG = 1,
ppcFLOATARG = 2,
ppcDOUBLEARG = 3
};
// Loads all data into the correct places and calls the function.
// pArgs is the array of the argument values
// pArgTypes is an array containing a byte indicating the type (enum argTypes) for each argument.
// dwFunc is the address of the function that will be called
asQWORD __declspec( naked ) ppcFunc(const asQWORD* pArgs, asDWORD dwFunc, const asBYTE* pArgTypes)
{
__asm
{
_ppcFunc:
// Prologue
// Read and stack the link register (return address)
mflr r12
stw r12,-8(r1)
// Backup all non-volatile registers we use in this function
std r31,-10h(r1) // stack pointer for pushing arguments
std r27,-18h(r1) // dwFunc
std r26,-20h(r1) // pArgs
std r25,-28h(r1) // pArgTypes
std r24,-30h(r1) // current arg type
std r23,-38h(r1) // counter for used GPRs
std r22,-40h(r1) // counter for used float registers
// Setup the stack frame to make room for the backup of registers
// and the arguments that will be passed to the application function.
// 512 bytes is enough for about 50 arguments plus backup of 8
// TODO: Should perhaps make this dynamic based on number of arguments
stwu r1,-200h(r1)
//////////////////////////////////////////////////////////////////////////
// Initialize local variables
//////////////////////////////////////////////////////////////////////////
// r31 is our pointer into the stack where the arguments will be place
// The MSVC optimizer seems to rely on nobody copying the r1 register directly
// so we can't just do a simple 'addi r31, r1, 14h' as the optimizer may
// end up moving this instruction to before the update of r1 above.
// Instead we'll read the previous stack pointer from the stack, and then
// subtract to get the correct offset.
lwz r31, 0(r1)
subi r31, r31, 1ECh // prev r1 - 512 + 20 = curr r1 + 20
mr r26, r3 // pArgs
mr r27, r4 // dwFunc
mr r25, r5 // pArgTypes
// Counting of used/assigned GPR's
sub r23, r23, r23
// Counting of used/assigned Float Registers
sub r22, r22, r22
// Begin loading and stacking registers
subi r25, r25, 1
//////////////////////////////////////////////////////////////////////////
// Fetch the next argument
//////////////////////////////////////////////////////////////////////////
ppcNextArg:
// Increment rArgTypePtr
addi r25, r25, 1
// Get data type
lbz r24, 0(r25)
// r24 holds the data type
cmplwi cr6, r24, 0
beq cr6, ppcArgsEnd
cmplwi cr6, r24, 1
beq cr6, ppcArgIsInteger
cmplwi cr6, r24, 2
beq cr6, ppcArgIsFloat
cmplwi cr6, r24, 3
beq cr6, ppcArgIsDouble
//////////////////////////////////////////////////////////////////////////
// Load and stack integer arguments
//////////////////////////////////////////////////////////////////////////
ppcArgIsInteger:
// Get the arg from the stack
ld r12, 0(r26)
// r23 holds the integer arg count so far
cmplwi cr6, r23, 0
beq cr6, ppcLoadIntReg0
cmplwi cr6, r23, 1
beq cr6, ppcLoadIntReg1
cmplwi cr6, r23, 2
beq cr6, ppcLoadIntReg2
cmplwi cr6, r23, 3
beq cr6, ppcLoadIntReg3
cmplwi cr6, r23, 4
beq cr6, ppcLoadIntReg4
cmplwi cr6, r23, 5
beq cr6, ppcLoadIntReg5
cmplwi cr6, r23, 6
beq cr6, ppcLoadIntReg6
cmplwi cr6, r23, 7
beq cr6, ppcLoadIntReg7
// no more than 8 parameters
b ppcLoadIntRegUpd
ppcLoadIntReg0:
mr r3, r12
b ppcLoadIntRegUpd
ppcLoadIntReg1:
mr r4, r12
b ppcLoadIntRegUpd
ppcLoadIntReg2:
mr r5, r12
b ppcLoadIntRegUpd
ppcLoadIntReg3:
mr r6, r12
b ppcLoadIntRegUpd
ppcLoadIntReg4:
mr r7, r12
b ppcLoadIntRegUpd
ppcLoadIntReg5:
mr r8, r12
b ppcLoadIntRegUpd
ppcLoadIntReg6:
mr r9, r12
b ppcLoadIntRegUpd
ppcLoadIntReg7:
mr r10, r12
b ppcLoadIntRegUpd
ppcLoadIntRegUpd:
std r12, 0(r31) // push on the stack
addi r31, r31, 8 // inc stack by 1 reg
addi r23, r23, 1 // Increment used int register count
addi r26, r26, 8 // Increment pArgs
b ppcNextArg // Call next arg
//////////////////////////////////////////////////////////////////////////
// Load and stack float arguments
//////////////////////////////////////////////////////////////////////////
ppcArgIsFloat:
// Get the arg from the stack
lfs fr0, 0(r26)
// r22 holds the float arg count so far
cmplwi cr6, r22, 0
beq cr6, ppcLoadFloatReg0
cmplwi cr6, r22, 1
beq cr6, ppcLoadFloatReg1
cmplwi cr6, r22, 2
beq cr6, ppcLoadFloatReg2
cmplwi cr6, r22, 3
beq cr6, ppcLoadFloatReg3
cmplwi cr6, r22, 4
beq cr6, ppcLoadFloatReg4
cmplwi cr6, r22, 5
beq cr6, ppcLoadFloatReg5
cmplwi cr6, r22, 6
beq cr6, ppcLoadFloatReg6
cmplwi cr6, r22, 7
beq cr6, ppcLoadFloatReg7
cmplwi cr6, r22, 8
beq cr6, ppcLoadFloatReg8
cmplwi cr6, r22, 9
beq cr6, ppcLoadFloatReg9
cmplwi cr6, r22, 10
beq cr6, ppcLoadFloatReg10
cmplwi cr6, r22, 11
beq cr6, ppcLoadFloatReg11
cmplwi cr6, r22, 12
beq cr6, ppcLoadFloatReg12
// no more than 12 parameters
b ppcLoadFloatRegUpd
ppcLoadFloatReg0:
fmr fr1, fr0
b ppcLoadFloatRegUpd
ppcLoadFloatReg1:
fmr fr2, fr0
b ppcLoadFloatRegUpd
ppcLoadFloatReg2:
fmr fr3, fr0
b ppcLoadFloatRegUpd
ppcLoadFloatReg3:
fmr fr4, fr0
b ppcLoadFloatRegUpd
ppcLoadFloatReg4:
fmr fr5, fr0
b ppcLoadFloatRegUpd
ppcLoadFloatReg5:
fmr fr6, fr0
b ppcLoadFloatRegUpd
ppcLoadFloatReg6:
fmr fr7, fr0
b ppcLoadFloatRegUpd
ppcLoadFloatReg7:
fmr fr8, fr0
b ppcLoadFloatRegUpd
ppcLoadFloatReg8:
fmr fr9, fr0
b ppcLoadFloatRegUpd
ppcLoadFloatReg9:
fmr fr10, fr0
b ppcLoadFloatRegUpd
ppcLoadFloatReg10:
fmr fr11, fr0
b ppcLoadFloatRegUpd
ppcLoadFloatReg11:
fmr fr12, fr0
b ppcLoadFloatRegUpd
ppcLoadFloatReg12:
fmr fr13, fr0
b ppcLoadFloatRegUpd
ppcLoadFloatRegUpd:
stfs fr0, 0(r31) // push on the stack
addi r31, r31, 8 // inc stack by 1 reg
addi r22, r22, 1 // Increment used float register count
addi r23, r23, 1 // Increment used int register count - a float reg eats up a GPR
addi r26, r26, 4 // Increment pArgs
b ppcNextArg // Call next arg
//////////////////////////////////////////////////////////////////////////
// Load and stack double float arguments
//////////////////////////////////////////////////////////////////////////
ppcArgIsDouble:
// Get the arg from the stack
lfd fr0, 0(r26)
// r22 holds the float arg count so far
cmplwi cr6, r22, 0
beq cr6, ppcLoadDoubleReg0
cmplwi cr6, r22, 1
beq cr6, ppcLoadDoubleReg1
cmplwi cr6, r22, 2
beq cr6, ppcLoadDoubleReg2
cmplwi cr6, r22, 3
beq cr6, ppcLoadDoubleReg3
cmplwi cr6, r22, 4
beq cr6, ppcLoadDoubleReg4
cmplwi cr6, r22, 5
beq cr6, ppcLoadDoubleReg5
cmplwi cr6, r22, 6
beq cr6, ppcLoadDoubleReg6
cmplwi cr6, r22, 7
beq cr6, ppcLoadDoubleReg7
cmplwi cr6, r22, 8
beq cr6, ppcLoadDoubleReg8
cmplwi cr6, r22, 9
beq cr6, ppcLoadDoubleReg9
cmplwi cr6, r22, 10
beq cr6, ppcLoadDoubleReg10
cmplwi cr6, r22, 11
beq cr6, ppcLoadDoubleReg11
cmplwi cr6, r22, 12
beq cr6, ppcLoadDoubleReg12
// no more than 12 parameters
b ppcLoadDoubleRegUpd
ppcLoadDoubleReg0:
fmr fr1, fr0
b ppcLoadDoubleRegUpd
ppcLoadDoubleReg1:
fmr fr2, fr0
b ppcLoadDoubleRegUpd
ppcLoadDoubleReg2:
fmr fr3, fr0
b ppcLoadDoubleRegUpd
ppcLoadDoubleReg3:
fmr fr4, fr0
b ppcLoadDoubleRegUpd
ppcLoadDoubleReg4:
fmr fr5, fr0
b ppcLoadDoubleRegUpd
ppcLoadDoubleReg5:
fmr fr6, fr0
b ppcLoadDoubleRegUpd
ppcLoadDoubleReg6:
fmr fr7, fr0
b ppcLoadDoubleRegUpd
ppcLoadDoubleReg7:
fmr fr8, fr0
b ppcLoadDoubleRegUpd
ppcLoadDoubleReg8:
fmr fr9, fr0
b ppcLoadDoubleRegUpd
ppcLoadDoubleReg9:
fmr fr10, fr0
b ppcLoadDoubleRegUpd
ppcLoadDoubleReg10:
fmr fr11, fr0
b ppcLoadDoubleRegUpd
ppcLoadDoubleReg11:
fmr fr12, fr0
b ppcLoadDoubleRegUpd
ppcLoadDoubleReg12:
fmr fr13, fr0
b ppcLoadDoubleRegUpd
ppcLoadDoubleRegUpd:
stfd fr0, 0(r31) // push on the stack
addi r31, r31, 8 // inc stack by 1 reg
addi r22, r22, 1 // Increment used float register count
addi r23, r23, 1 // Increment used int register count
addi r26, r26, 8 // Increment pArgs
b ppcNextArg
//////////////////////////////////////////////////////////////////////////
// Finished
//////////////////////////////////////////////////////////////////////////
ppcArgsEnd:
// Call the function
mtctr r27
bctrl
// Epilogue
// Restore callers stack
addi r1, r1, 200h
// restore all registers we used in this fct
ld r22,-40h(r1)
ld r23,-38h(r1)
ld r24,-30h(r1)
ld r25,-28h(r1)
ld r26,-20h(r1)
ld r27,-18h(r1)
ld r31,-10h(r1)
// Fetch return link to caller
lwz r12,-8(r1)
mtlr r12
blr
}
}
asDWORD GetReturnedFloat()
{
// This variable must be declared volatile so that the
// compiler optimizations do not remove its initialization
// with the fr1 register due to believing the fr1 register
// isn't initialized.
volatile asDWORD f;
__asm
{
stfs fr1, f
}
return f;
}
asQWORD GetReturnedDouble()
{
// This variable must be declared volatile so that the
// compiler optimizations do not remove its initialization
// with the fr1 register due to believing the fr1 register
// isn't initialized.
volatile asQWORD f;
__asm
{
stfd fr1, f
}
return f;
}
// returns true if the given parameter is a 'variable argument'
inline bool IsVariableArgument( asCDataType type )
{
return (type.GetTokenType() == ttQuestion) ? true : false;
}
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void */*secondObject*/)
{
// TODO: Xenon does not yet support THISCALL_OBJFIRST/LAST
asCScriptEngine *engine = context->m_engine;
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
int callConv = sysFunc->callConv;
asQWORD retQW = 0;
void *func = (void*)sysFunc->func;
asDWORD *vftable;
// Pack the arguments into an array that ppcFunc() can use to load each CPU register properly
asBYTE ppcArgsType[AS_PPC_MAX_ARGS + AS_PPC_RETURNINMEM_REG + AS_PPC_THISCALL_REG + AS_PPC_ENDOFARGS];
asQWORD ppcArgs[AS_PPC_MAX_ARGS + AS_PPC_RETURNINMEM_REG + AS_PPC_THISCALL_REG];
int argsCnt = 0;
// If the function returns an object in memory, we allocate the memory and put the ptr to the front (will go to r3)
if( sysFunc->hostReturnInMemory )
{
ppcArgs[argsCnt] = (asDWORD)retPointer;
ppcArgsType[argsCnt] = ppcINTARG;
argsCnt++;
}
// If we have an object and it's not objectlast, then we put it as the first arg
if ( obj &&
callConv != ICC_CDECL_OBJLAST &&
callConv != ICC_CDECL_OBJLAST_RETURNINMEM )
{
ppcArgs[argsCnt] = (asDWORD)obj;
ppcArgsType[argsCnt] = ppcINTARG;
argsCnt++;
}
// If the function takes any objects by value, they must be copied
// to the stack, shifting the other arguments as necessary. paramBuffer
// will then replace the args pointer that was received from the VM.
// TODO: Is this really how XBox 360 passes objects by value?
asDWORD paramBuffer[AS_PPC_MAX_ARGS];
if( sysFunc->takesObjByVal )
{
int paramSize = 0;
int spos = 0;
int dpos = 1;
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
{
// Parameter object by value
if( descr->parameterTypes[n].IsObject() &&
!descr->parameterTypes[n].IsObjectHandle() &&
!descr->parameterTypes[n].IsReference() )
{
#ifdef COMPLEX_OBJS_PASSED_BY_REF
if( descr->parameterTypes[n].GetTypeInfo()->flags & COMPLEX_MASK )
{
paramBuffer[dpos++] = args[spos++];
paramSize++;
}
else
#endif
{
// Copy the object's memory to the buffer
memcpy( &paramBuffer[dpos], *(void**)(args + spos), descr->parameterTypes[n].GetSizeInMemoryBytes() );
// Delete the original memory
engine->CallFree(*(char**)(args + spos));
spos++;
dpos += descr->parameterTypes[n].GetSizeInMemoryDWords();
paramSize += descr->parameterTypes[n].GetSizeInMemoryDWords();
}
}
else
{
// Copy the value directly
paramBuffer[dpos++] = args[spos++];
if( descr->parameterTypes[n].GetSizeOnStackDWords() > 1 )
paramBuffer[dpos++] = args[spos++];
paramSize += descr->parameterTypes[n].GetSizeOnStackDWords();
}
// If this was a variable argument parameter, then account for the implicit typeId
if( IsVariableArgument( descr->parameterTypes[n] ) )
{
// the TypeId is just a DWORD
paramBuffer[dpos++] = args[spos++];
++paramSize;
}
}
// Keep a free location at the beginning
args = &paramBuffer[1];
asASSERT( paramSize <= AS_PPC_MAX_ARGS );
}
const asUINT paramCount = (asUINT)descr->parameterTypes.GetLength();
asBYTE * pCurArgType = (asBYTE*)&ppcArgsType[argsCnt];
asBYTE * pCurFixedArgValue = (asBYTE*)&ppcArgs[argsCnt];
asBYTE * pCurStackArgValue = (asBYTE*)args;
for( asUINT n = 0; n < paramCount; n++ )
{
argsCnt++;
if (descr->parameterTypes[n].IsFloatType() && !descr->parameterTypes[n].IsReference())
{
*pCurArgType++ = ppcFLOATARG;
*((float*) pCurFixedArgValue) = *((float*) pCurStackArgValue);
pCurFixedArgValue += 4;
pCurStackArgValue += 4;
}
else if (descr->parameterTypes[n].IsDoubleType() && !descr->parameterTypes[n].IsReference())
{
*pCurArgType++ = ppcDOUBLEARG;
*((double*) pCurFixedArgValue) = *((double*) pCurStackArgValue);
pCurFixedArgValue += 8;
pCurStackArgValue += 8;
}
else
{
// TODO: The code also ignore the fact that large objects
// passed by value has been copied to the stack
// in the above loop.
*pCurArgType++ = ppcINTARG;
*((asQWORD*) pCurFixedArgValue) = *((asUINT*) pCurStackArgValue);
if( !descr->parameterTypes[n].IsReference() )
{
// If the arg is not 4 bytes which we coppied, lets do it again the right way
asUINT numBytes = descr->parameterTypes[n].GetSizeInMemoryBytes();
if( numBytes == 1 )
{
*((asQWORD*) pCurFixedArgValue) = *((asBYTE*) pCurStackArgValue);
}
else if( numBytes == 2 )
{
*((asQWORD*) pCurFixedArgValue) = *((asWORD*) pCurStackArgValue);
}
else if( numBytes == 8 )
{
*((asQWORD*) pCurFixedArgValue) = *((asQWORD*) pCurStackArgValue);
pCurStackArgValue += 4; // Increase our cur stack arg value by 4 bytes to = 8 total later
}
}
pCurFixedArgValue += 8;
pCurStackArgValue += 4;
// if it is a variable argument, account for the typeId
// implicitly add another parameter (AFTER the parameter above) for the typeId
if( IsVariableArgument(descr->parameterTypes[n]) )
{
argsCnt++;
*pCurArgType++ = ppcINTARG;
*((int*) pCurFixedArgValue) = *((int*) pCurStackArgValue);
pCurFixedArgValue += 4;
pCurStackArgValue += 4;
}
}
}
// Add the arg list end indicator
ppcArgsType[argsCnt] = ppcENDARG;
switch( callConv )
{
case ICC_CDECL:
case ICC_CDECL_RETURNINMEM:
case ICC_STDCALL:
case ICC_STDCALL_RETURNINMEM:
case ICC_THISCALL:
case ICC_THISCALL_RETURNINMEM:
case ICC_CDECL_OBJFIRST:
case ICC_CDECL_OBJFIRST_RETURNINMEM:
{
retQW = ppcFunc( ppcArgs, (asDWORD)func, ppcArgsType );
break;
}
case ICC_VIRTUAL_THISCALL:
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
{
// Get virtual function table from the object pointer
vftable = *(asDWORD**)obj;
retQW = ppcFunc( ppcArgs, vftable[asDWORD(func)>>2], ppcArgsType );
break;
}
case ICC_CDECL_OBJLAST:
case ICC_CDECL_OBJLAST_RETURNINMEM:
{
// Add the object pointer as the last argument
ppcArgsType[argsCnt++] = ppcINTARG;
ppcArgsType[argsCnt] = ppcENDARG;
*((asQWORD*)pCurFixedArgValue) = (asPWORD)obj;
retQW = ppcFunc( ppcArgs, (asDWORD)func, ppcArgsType );
break;
}
default:
context->SetInternalException( TXT_INVALID_CALLING_CONVENTION );
}
// If the return is a float value we need to get the value from the FP register
if( sysFunc->hostReturnFloat )
{
if( sysFunc->hostReturnSize == 1 )
*(asDWORD*)&retQW = GetReturnedFloat();
else
retQW = GetReturnedDouble();
}
else if( sysFunc->hostReturnSize == 1 )
{
// Move the bits to the higher value to compensate for the adjustment that the caller does
retQW <<= 32;
}
return retQW;
}
END_AS_NAMESPACE
#endif // AS_XENON
#endif // AS_MAX_PORTABILITY

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,439 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2020 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_compiler.h
//
// The class that does the actual compilation of the functions
//
#ifndef AS_COMPILER_H
#define AS_COMPILER_H
#include "as_config.h"
#ifndef AS_NO_COMPILER
#include "as_builder.h"
#include "as_scriptfunction.h"
#include "as_variablescope.h"
#include "as_bytecode.h"
#include "as_array.h"
#include "as_datatype.h"
BEGIN_AS_NAMESPACE
// This class represents the value of an expression as evaluated by the compiler.
// It holds information such as the type of the value, stack offset for a local
// variable, value of constants, whether the value can be modified (i.e. lvalue), etc.
struct asCExprValue
{
asCExprValue();
void Set(const asCDataType &dataType);
void SetVariable(const asCDataType &dataType, int stackOffset, bool isTemporary);
void SetConstantB(const asCDataType &dataType, asBYTE value);
void SetConstantQW(const asCDataType &dataType, asQWORD value);
void SetConstantDW(const asCDataType &dataType, asDWORD value);
void SetConstantW(const asCDataType &dataType, asWORD value);
void SetConstantF(const asCDataType &dataType, float value);
void SetConstantD(const asCDataType &dataType, double value);
void SetConstantB(asBYTE value);
void SetConstantW(asWORD value);
void SetConstantQW(asQWORD value);
void SetConstantDW(asDWORD value);
void SetConstantF(float value);
void SetConstantD(double value);
asBYTE GetConstantB();
asWORD GetConstantW();
asQWORD GetConstantQW();
asDWORD GetConstantDW();
float GetConstantF();
double GetConstantD();
void SetConstantData(const asCDataType &dataType, asQWORD value);
asQWORD GetConstantData();
void SetNullConstant();
void SetUndefinedFuncHandle(asCScriptEngine *engine);
void SetVoid();
void SetDummy();
bool IsUndefinedFuncHandle() const;
bool IsNullConstant() const;
bool IsVoid() const;
asCDataType dataType;
bool isLValue : 1; // Can this value be updated in assignment, or increment operators, etc
bool isTemporary : 1;
bool isConstant : 1;
bool isVariable : 1;
bool isExplicitHandle : 1;
bool isRefToLocal : 1; // The reference may be to a local variable
bool isRefSafe : 1; // the life-time of the ref is guaranteed for the duration of the access
short dummy : 9;
short stackOffset;
private:
// These values must not be accessed directly in order to avoid problems with endianess.
// Use the appropriate accessor methods instead
union
{
asQWORD qwordValue;
double doubleValue;
asDWORD dwordValue;
float floatValue;
asWORD wordValue;
asBYTE byteValue;
};
};
struct asCExprContext;
// This class holds information for arguments that needs to be
// cleaned up after the result of a function has been evaluated.
struct asSDeferredParam
{
asSDeferredParam() {argNode = 0; origExpr = 0;}
asCScriptNode *argNode;
asCExprValue argType;
int argInOutFlags;
asCExprContext *origExpr;
};
// TODO: refactor: asCExprContext should have indicators to inform where the value is,
// i.e. if the reference to an object is pushed on the stack or not, etc
// This class holds information about an expression that is being evaluated, e.g.
// the current bytecode, ambiguous symbol names, property accessors, etc.
struct asCExprContext
{
asCExprContext(asCScriptEngine *engine);
~asCExprContext();
void Clear();
bool IsClassMethod() const;
bool IsGlobalFunc() const;
void SetLambda(asCScriptNode *funcDecl);
bool IsLambda() const;
void SetVoidExpression();
bool IsVoidExpression() const;
void Merge(asCExprContext *after);
void Copy(asCExprContext *other);
void SetAnonymousInitList(asCScriptNode *initList, asCScriptCode *script);
bool IsAnonymousInitList() const;
asCByteCode bc;
asCExprValue type;
int property_get;
int property_set;
bool property_const; // If the object that is being accessed through property accessor is read-only
bool property_handle; // If the property accessor is called on an object stored in a handle
bool property_ref; // If the property accessor is called on a reference
bool isVoidExpression; // Set to true if the expression is an explicit 'void', e.g. used to ignore out parameters in func calls
bool isCleanArg; // Set to true if the expression has only been initialized with default constructor
asCExprContext *property_arg;
asCArray<asSDeferredParam> deferredParams;
asCScriptNode *exprNode;
asCExprContext *origExpr;
asCScriptCode *origCode;
// TODO: cleanup: use ambiguousName and an enum to say if it is a method, global func, or enum value
asCString methodName;
asCString enumValue;
asSNameSpace *symbolNamespace; // The namespace in which the ambiguous symbol was found
bool isAnonymousInitList; // Set to true if the expression is an init list for which the type has not yet been determined
};
struct asSOverloadCandidate
{
asSOverloadCandidate() : funcId(0), cost(0) {}
asSOverloadCandidate(int _id, asUINT _cost) : funcId(_id), cost(_cost) {}
int funcId;
asUINT cost;
};
struct asSNamedArgument
{
asCString name;
asCExprContext *ctx;
asUINT match;
};
enum EImplicitConv
{
asIC_IMPLICIT_CONV,
asIC_EXPLICIT_REF_CAST,
asIC_EXPLICIT_VAL_CAST
};
enum EConvCost
{
asCC_NO_CONV = 0,
asCC_CONST_CONV = 1,
asCC_ENUM_SAME_SIZE_CONV = 2,
asCC_ENUM_DIFF_SIZE_CONV = 3,
asCC_PRIMITIVE_SIZE_CONV = 4,
asCC_SIGNED_CONV = 5,
asCC_INT_FLOAT_CONV = 6,
asCC_REF_CONV = 7,
asCC_OBJ_TO_PRIMITIVE_CONV = 8,
asCC_TO_OBJECT_CONV = 9,
asCC_VARIABLE_CONV = 10
};
class asCCompiler
{
public:
asCCompiler(asCScriptEngine *engine);
~asCCompiler();
int CompileFunction(asCBuilder *builder, asCScriptCode *script, asCArray<asCString> &parameterNames, asCScriptNode *func, asCScriptFunction *outFunc, sClassDeclaration *classDecl);
int CompileDefaultConstructor(asCBuilder *builder, asCScriptCode *script, asCScriptNode *node, asCScriptFunction *outFunc, sClassDeclaration *classDecl);
int CompileFactory(asCBuilder *builder, asCScriptCode *script, asCScriptFunction *outFunc);
int CompileGlobalVariable(asCBuilder *builder, asCScriptCode *script, asCScriptNode *expr, sGlobalVariableDescription *gvar, asCScriptFunction *outFunc);
protected:
friend class asCBuilder;
void Reset(asCBuilder *builder, asCScriptCode *script, asCScriptFunction *outFunc);
// Statements
void CompileStatementBlock(asCScriptNode *block, bool ownVariableScope, bool *hasReturn, asCByteCode *bc);
void CompileDeclaration(asCScriptNode *decl, asCByteCode *bc);
void CompileStatement(asCScriptNode *statement, bool *hasReturn, asCByteCode *bc);
void CompileIfStatement(asCScriptNode *node, bool *hasReturn, asCByteCode *bc);
void CompileSwitchStatement(asCScriptNode *node, bool *hasReturn, asCByteCode *bc);
void CompileCase(asCScriptNode *node, asCByteCode *bc);
void CompileForStatement(asCScriptNode *node, asCByteCode *bc);
void CompileWhileStatement(asCScriptNode *node, asCByteCode *bc);
void CompileDoWhileStatement(asCScriptNode *node, asCByteCode *bc);
void CompileBreakStatement(asCScriptNode *node, asCByteCode *bc);
void CompileContinueStatement(asCScriptNode *node, asCByteCode *bc);
void CompileReturnStatement(asCScriptNode *node, asCByteCode *bc);
void CompileExpressionStatement(asCScriptNode *node, asCByteCode *bc);
void CompileTryCatch(asCScriptNode *node, bool *hasReturn, asCByteCode *bc);
// Expressions
int CompileAssignment(asCScriptNode *expr, asCExprContext *out);
int CompileCondition(asCScriptNode *expr, asCExprContext *out);
int CompileExpression(asCScriptNode *expr, asCExprContext *out);
int CompilePostFixExpression(asCArray<asCScriptNode *> *postfix, asCExprContext *out);
int CompileExpressionTerm(asCScriptNode *node, asCExprContext *out);
int CompileExpressionPreOp(asCScriptNode *node, asCExprContext *out);
int CompileExpressionPostOp(asCScriptNode *node, asCExprContext *out);
int CompileExpressionValue(asCScriptNode *node, asCExprContext *out);
int CompileFunctionCall(asCScriptNode *node, asCExprContext *out, asCObjectType *objectType, bool objIsConst, const asCString &scope = "");
int CompileConstructCall(asCScriptNode *node, asCExprContext *out);
int CompileConversion(asCScriptNode *node, asCExprContext *out);
int CompileOperator(asCScriptNode *node, asCExprContext *l, asCExprContext *r, asCExprContext *out, eTokenType opToken = ttUnrecognizedToken, bool leftToRight = true);
void CompileOperatorOnHandles(asCScriptNode *node, asCExprContext *l, asCExprContext *r, asCExprContext *out, eTokenType opToken = ttUnrecognizedToken);
void CompileMathOperator(asCScriptNode *node, asCExprContext *l, asCExprContext *r, asCExprContext *out, eTokenType opToken = ttUnrecognizedToken);
void CompileBitwiseOperator(asCScriptNode *node, asCExprContext *l, asCExprContext *r, asCExprContext *out, eTokenType opToken = ttUnrecognizedToken);
void CompileComparisonOperator(asCScriptNode *node, asCExprContext *l, asCExprContext *r, asCExprContext *out, eTokenType opToken = ttUnrecognizedToken);
void CompileBooleanOperator(asCScriptNode *node, asCExprContext *l, asCExprContext *r, asCExprContext *out, eTokenType opToken = ttUnrecognizedToken);
bool CompileOverloadedDualOperator(asCScriptNode *node, asCExprContext *l, asCExprContext *r, bool leftToRight, asCExprContext *out, bool isHandle = false, eTokenType opToken = ttUnrecognizedToken);
int CompileOverloadedDualOperator2(asCScriptNode *node, const char *methodName, asCExprContext *l, asCExprContext *r, bool leftToRight, asCExprContext *out, bool specificReturn = false, const asCDataType &returnType = asCDataType::CreatePrimitive(ttVoid, false));
void CompileInitList(asCExprValue *var, asCScriptNode *node, asCByteCode *bc, int isVarGlobOrMem);
int CompileInitListElement(asSListPatternNode *&patternNode, asCScriptNode *&valueNode, int bufferTypeId, short bufferVar, asUINT &bufferSize, asCByteCode &byteCode, int &elementsInSubList);
int CompileAnonymousInitList(asCScriptNode *listNode, asCExprContext *ctx, const asCDataType &dt);
int CallDefaultConstructor(const asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc, asCScriptNode *node, int isVarGlobOrMem = 0, bool derefDest = false);
int CallCopyConstructor(asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc, asCExprContext *arg, asCScriptNode *node, bool isGlobalVar = false, bool derefDestination = false);
void CallDestructor(asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc);
int CompileArgumentList(asCScriptNode *node, asCArray<asCExprContext *> &args, asCArray<asSNamedArgument> &namedArgs);
int CompileDefaultAndNamedArgs(asCScriptNode *node, asCArray<asCExprContext*> &args, int funcId, asCObjectType *type, asCArray<asSNamedArgument> *namedArgs = 0);
asUINT MatchFunctions(asCArray<int> &funcs, asCArray<asCExprContext*> &args, asCScriptNode *node, const char *name, asCArray<asSNamedArgument> *namedArgs = NULL, asCObjectType *objectType = NULL, bool isConstMethod = false, bool silent = false, bool allowObjectConstruct = true, const asCString &scope = "");
int CompileVariableAccess(const asCString &name, const asCString &scope, asCExprContext *ctx, asCScriptNode *errNode, bool isOptional = false, asCObjectType *objType = 0);
void CompileMemberInitialization(asCByteCode *bc, bool onlyDefaults);
bool CompileAutoType(asCDataType &autoType, asCExprContext &compiledCtx, asCScriptNode *exprNode, asCScriptNode *errNode);
bool CompileInitialization(asCScriptNode *node, asCByteCode *bc, const asCDataType &type, asCScriptNode *errNode, int offset, asQWORD *constantValue, int isVarGlobOrMem, asCExprContext *preCompiled = 0);
void CompileInitAsCopy(asCDataType &type, int offset, asCByteCode *bc, asCExprContext *arg, asCScriptNode *node, bool derefDestination);
// Helper functions
void ConvertToPostFix(asCScriptNode *expr, asCArray<asCScriptNode *> &postfix);
int ProcessPropertyGetAccessor(asCExprContext *ctx, asCScriptNode *node);
int ProcessPropertySetAccessor(asCExprContext *ctx, asCExprContext *arg, asCScriptNode *node);
int ProcessPropertyGetSetAccessor(asCExprContext *ctx, asCExprContext *lctx, asCExprContext *rctx, eTokenType op, asCScriptNode *errNode);
int FindPropertyAccessor(const asCString &name, asCExprContext *ctx, asCScriptNode *node, asSNameSpace *ns, bool isThisAccess = false);
int FindPropertyAccessor(const asCString &name, asCExprContext *ctx, asCExprContext *arg, asCScriptNode *node, asSNameSpace *ns, bool isThisAccess = false);
void PrepareTemporaryVariable(asCScriptNode *node, asCExprContext *ctx, bool forceOnHeap = false);
void PrepareOperand(asCExprContext *ctx, asCScriptNode *node);
void PrepareForAssignment(asCDataType *lvalue, asCExprContext *rvalue, asCScriptNode *node, bool toTemporary, asCExprContext *lvalueExpr = 0);
int PerformAssignment(asCExprValue *lvalue, asCExprValue *rvalue, asCByteCode *bc, asCScriptNode *node);
bool IsVariableInitialized(asCExprValue *type, asCScriptNode *node);
void Dereference(asCExprContext *ctx, bool generateCode);
bool CompileRefCast(asCExprContext *ctx, const asCDataType &to, bool isExplicit, asCScriptNode *node, bool generateCode = true);
asUINT MatchArgument(asCArray<int> &funcs, asCArray<asSOverloadCandidate> &matches, const asCExprContext *argExpr, int paramNum, bool allowObjectConstruct = true);
int MatchArgument(asCScriptFunction *desc, const asCExprContext *argExpr, int paramNum, bool allowObjectConstruct = true);
void PerformFunctionCall(int funcId, asCExprContext *out, bool isConstructor = false, asCArray<asCExprContext*> *args = 0, asCObjectType *objTypeForConstruct = 0, bool useVariable = false, int varOffset = 0, int funcPtrVar = 0);
void MoveArgsToStack(int funcId, asCByteCode *bc, asCArray<asCExprContext *> &args, bool addOneToOffset);
int MakeFunctionCall(asCExprContext *ctx, int funcId, asCObjectType *objectType, asCArray<asCExprContext*> &args, asCScriptNode *node, bool useVariable = false, int stackOffset = 0, int funcPtrVar = 0);
int PrepareFunctionCall(int funcId, asCByteCode *bc, asCArray<asCExprContext *> &args);
void AfterFunctionCall(int funcId, asCArray<asCExprContext*> &args, asCExprContext *ctx, bool deferAll);
void ProcessDeferredParams(asCExprContext *ctx);
int PrepareArgument(asCDataType *paramType, asCExprContext *ctx, asCScriptNode *node, bool isFunction = false, int refType = 0, bool isMakingCopy = false);
int PrepareArgument2(asCExprContext *ctx, asCExprContext *arg, asCDataType *paramType, bool isFunction = false, int refType = 0, bool isMakingCopy = false);
bool IsLValue(asCExprValue &type);
int DoAssignment(asCExprContext *out, asCExprContext *lctx, asCExprContext *rctx, asCScriptNode *lexpr, asCScriptNode *rexpr, eTokenType op, asCScriptNode *opNode);
void MergeExprBytecode(asCExprContext *before, asCExprContext *after);
void MergeExprBytecodeAndType(asCExprContext *before, asCExprContext *after);
void FilterConst(asCArray<int> &funcs, bool removeConst = true);
void ConvertToVariable(asCExprContext *ctx);
void ConvertToVariableNotIn(asCExprContext *ctx, asCExprContext *exclude);
void ConvertToTempVariable(asCExprContext *ctx);
void ConvertToTempVariableNotIn(asCExprContext *ctx, asCExprContext *exclude);
void ConvertToReference(asCExprContext *ctx);
void PushVariableOnStack(asCExprContext *ctx, bool asReference);
void DestroyVariables(asCByteCode *bc);
asSNameSpace *DetermineNameSpace(const asCString &scope);
int SetupParametersAndReturnVariable(asCArray<asCString> &parameterNames, asCScriptNode *func);
enum SYMBOLTYPE
{
SL_NOMATCH,
SL_LOCALCONST,
SL_LOCALVAR,
SL_THISPTR,
SL_CLASSPROPACCESS,
SL_CLASSPROP,
SL_CLASSMETHOD,
SL_CLASSTYPE,
SL_GLOBALPROPACCESS,
SL_GLOBALCONST,
SL_GLOBALVAR,
SL_GLOBALFUNC,
SL_GLOBALTYPE,
SL_ENUMVAL,
SL_ERROR = -1
};
SYMBOLTYPE SymbolLookup(const asCString &name, const asCString &scope, asCObjectType *objType, asCExprContext *outResult);
SYMBOLTYPE SymbolLookupLocalVar(const asCString &name, asCExprContext *outResult);
SYMBOLTYPE SymbolLookupMember(const asCString &name, asCObjectType *objType, asCExprContext *outResult);
void DetermineSingleFunc(asCExprContext *ctx, asCScriptNode *node);
// Returns the cost of the conversion (the sum of the EConvCost performed)
asUINT ImplicitConversion(asCExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode = true, bool allowObjectConstruct = true);
asUINT ImplicitConvPrimitiveToPrimitive(asCExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode = true);
asUINT ImplicitConvObjectToPrimitive(asCExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode = true);
asUINT ImplicitConvPrimitiveToObject(asCExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode = true, bool allowObjectConstruct = true);
asUINT ImplicitConvObjectToObject(asCExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode = true, bool allowObjectConstruct = true);
asUINT ImplicitConvObjectRef(asCExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode);
asUINT ImplicitConvObjectValue(asCExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode);
void ImplicitConversionConstant(asCExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType);
void ImplicitConvObjectToBestMathType(asCExprContext *ctx, asCScriptNode *node);
asUINT ImplicitConvLambdaToFunc(asCExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode = true);
void LineInstr(asCByteCode *bc, size_t pos);
asUINT ProcessStringConstant(asCString &str, asCScriptNode *node, bool processEscapeSequences = true);
void ProcessHeredocStringConstant(asCString &str, asCScriptNode *node);
int GetPrecedence(asCScriptNode *op);
void Error(const asCString &msg, asCScriptNode *node);
void Warning(const asCString &msg, asCScriptNode *node);
void Information(const asCString &msg, asCScriptNode *node);
void PrintMatchingFuncs(asCArray<int> &funcs, asCScriptNode *node, asCObjectType *inType = 0);
void AddVariableScope(bool isBreakScope = false, bool isContinueScope = false);
void RemoveVariableScope();
void FinalizeFunction();
asCByteCode byteCode;
bool hasCompileErrors;
int nextLabel;
int numLambdas;
asCVariableScope *variables;
asCBuilder *builder;
asCScriptEngine *engine;
asCScriptCode *script;
asCScriptFunction *outFunc;
bool m_isConstructor;
bool m_isConstructorCalled;
sClassDeclaration *m_classDecl;
sGlobalVariableDescription *m_globalVar;
asCArray<int> breakLabels;
asCArray<int> continueLabels;
int AllocateVariable(const asCDataType &type, bool isTemporary, bool forceOnHeap = false, bool asReference = false);
int AllocateVariableNotIn(const asCDataType &type, bool isTemporary, bool forceOnHeap, asCExprContext *ctx);
int GetVariableOffset(int varIndex);
int GetVariableSlot(int varOffset);
void DeallocateVariable(int pos);
void ReleaseTemporaryVariable(asCExprValue &t, asCByteCode *bc);
void ReleaseTemporaryVariable(int offset, asCByteCode *bc);
bool IsVariableOnHeap(int offset);
// This ordered array indicates the type of each variable
asCArray<asCDataType> variableAllocations;
// This ordered array indicates which variables are temporaries or not
asCArray<bool> variableIsTemporary;
// This unordered array gives the offsets of all temporary variables, whether currently allocated or not
asCArray<int> tempVariableOffsets;
// This ordered array indicated if the variable is on the heap or not
asCArray<bool> variableIsOnHeap;
// This unordered array gives the indexes of the currently unused variables
asCArray<int> freeVariables;
// This array holds the offsets of the currently allocated temporary variables
asCArray<int> tempVariables;
// This array holds the indices of variables that must not be used in an allocation
asCArray<int> reservedVariables;
// This array holds the string constants that were allocated during the compilation,
// so they can be released upon completion, whether the compilation was successful or not.
asCArray<void*> usedStringConstants;
// This array holds the nodes that have been allocated temporarily
asCArray<asCScriptNode*> nodesToFreeUponComplete;
bool isCompilingDefaultArg;
bool isProcessingDeferredParams;
int noCodeOutput;
};
END_AS_NAMESPACE
#endif // AS_NO_COMPILER
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,209 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2020 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_configgroup.cpp
//
// This class holds configuration groups for the engine
//
#include "as_config.h"
#include "as_configgroup.h"
#include "as_scriptengine.h"
#include "as_texts.h"
BEGIN_AS_NAMESPACE
asCConfigGroup::asCConfigGroup()
{
refCount = 0;
}
asCConfigGroup::~asCConfigGroup()
{
}
int asCConfigGroup::AddRef()
{
refCount++;
return refCount;
}
int asCConfigGroup::Release()
{
// Don't delete the object here, the engine will delete the object when ready
refCount--;
return refCount;
}
asCTypeInfo *asCConfigGroup::FindType(const char *obj)
{
for( asUINT n = 0; n < types.GetLength(); n++ )
if( types[n]->name == obj )
return types[n];
return 0;
}
void asCConfigGroup::RefConfigGroup(asCConfigGroup *group)
{
if( group == this || group == 0 ) return;
// Verify if the group is already referenced
for( asUINT n = 0; n < referencedConfigGroups.GetLength(); n++ )
if( referencedConfigGroups[n] == group )
return;
referencedConfigGroups.PushLast(group);
group->AddRef();
}
void asCConfigGroup::AddReferencesForFunc(asCScriptEngine *engine, asCScriptFunction *func)
{
AddReferencesForType(engine, func->returnType.GetTypeInfo());
for( asUINT n = 0; n < func->parameterTypes.GetLength(); n++ )
AddReferencesForType(engine, func->parameterTypes[n].GetTypeInfo());
}
void asCConfigGroup::AddReferencesForType(asCScriptEngine *engine, asCTypeInfo *type)
{
if( type == 0 ) return;
// Keep reference to other groups
RefConfigGroup(engine->FindConfigGroupForTypeInfo(type));
// Keep track of which generated template instances the config group uses
if( type->flags & asOBJ_TEMPLATE && engine->generatedTemplateTypes.Exists(CastToObjectType(type)) && !generatedTemplateInstances.Exists(CastToObjectType(type)) )
generatedTemplateInstances.PushLast(CastToObjectType(type));
}
bool asCConfigGroup::HasLiveObjects()
{
for( asUINT n = 0; n < types.GetLength(); n++ )
if( types[n]->externalRefCount.get() != 0 )
return true;
return false;
}
void asCConfigGroup::RemoveConfiguration(asCScriptEngine *engine, bool notUsed)
{
asASSERT( refCount == 0 );
asUINT n;
// Remove global variables
for( n = 0; n < globalProps.GetLength(); n++ )
{
int index = engine->registeredGlobalProps.GetIndex(globalProps[n]);
if( index >= 0 )
{
globalProps[n]->Release();
engine->registeredGlobalProps.Erase(index);
}
}
globalProps.SetLength(0);
// Remove global functions
for( n = 0; n < scriptFunctions.GetLength(); n++ )
{
int index = engine->registeredGlobalFuncs.GetIndex(scriptFunctions[n]);
if( index >= 0 )
engine->registeredGlobalFuncs.Erase(index);
scriptFunctions[n]->ReleaseInternal();
}
scriptFunctions.SetLength(0);
// Remove behaviours and members of object types
for( n = 0; n < types.GetLength(); n++ )
{
asCObjectType *obj = CastToObjectType(types[n]);
if( obj )
obj->ReleaseAllFunctions();
}
// Remove object types (skip this if it is possible other groups are still using the types)
if( !notUsed )
{
for( n = asUINT(types.GetLength()); n-- > 0; )
{
asCTypeInfo *t = types[n];
asSMapNode<asSNameSpaceNamePair, asCTypeInfo*> *cursor;
if( engine->allRegisteredTypes.MoveTo(&cursor, asSNameSpaceNamePair(t->nameSpace, t->name)) &&
cursor->value == t )
{
engine->allRegisteredTypes.Erase(cursor);
if( engine->defaultArrayObjectType == t )
engine->defaultArrayObjectType = 0;
if( t->flags & asOBJ_TYPEDEF )
engine->registeredTypeDefs.RemoveValue(CastToTypedefType(t));
else if( t->flags & asOBJ_ENUM )
engine->registeredEnums.RemoveValue(CastToEnumType(t));
else if (t->flags & asOBJ_TEMPLATE)
engine->registeredTemplateTypes.RemoveValue(CastToObjectType(t));
else if (t->flags & asOBJ_FUNCDEF)
{
engine->registeredFuncDefs.RemoveValue(CastToFuncdefType(t));
engine->RemoveFuncdef(CastToFuncdefType(t));
}
else
engine->registeredObjTypes.RemoveValue(CastToObjectType(t));
t->DestroyInternal();
t->ReleaseInternal();
}
else
{
int idx = engine->templateInstanceTypes.IndexOf(CastToObjectType(t));
if( idx >= 0 )
{
engine->templateInstanceTypes.RemoveIndexUnordered(idx);
asCObjectType *ot = CastToObjectType(t);
ot->DestroyInternal();
ot->ReleaseInternal();
}
}
}
types.SetLength(0);
}
// Release other config groups
for( n = 0; n < referencedConfigGroups.GetLength(); n++ )
referencedConfigGroups[n]->refCount--;
referencedConfigGroups.SetLength(0);
}
END_AS_NAMESPACE

View File

@@ -0,0 +1,84 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_configgroup.h
//
// This class holds configuration groups for the engine
//
#ifndef AS_CONFIGGROUP_H
#define AS_CONFIGGROUP_H
#include "as_config.h"
#include "as_string.h"
#include "as_array.h"
#include "as_objecttype.h"
BEGIN_AS_NAMESPACE
class asCConfigGroup
{
public:
asCConfigGroup();
~asCConfigGroup();
// Memory management
int AddRef();
int Release();
asCTypeInfo *FindType(const char *name);
void RefConfigGroup(asCConfigGroup *group);
bool HasLiveObjects();
void RemoveConfiguration(asCScriptEngine *engine, bool notUsed = false);
void AddReferencesForFunc(asCScriptEngine *engine, asCScriptFunction *func);
void AddReferencesForType(asCScriptEngine *engine, asCTypeInfo *type);
asCString groupName;
int refCount;
asCArray<asCTypeInfo*> types;
asCArray<asCScriptFunction*> scriptFunctions;
asCArray<asCGlobalProperty*> globalProps;
asCArray<asCConfigGroup*> referencedConfigGroups;
// This array holds the generated template instances that are used
// by the config group as part of function signature or property
asCArray<asCObjectType*> generatedTemplateInstances;
};
END_AS_NAMESPACE
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,250 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2018 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_context.h
//
// This class handles the execution of the byte code
//
#ifndef AS_CONTEXT_H
#define AS_CONTEXT_H
#include "as_config.h"
#include "as_atomic.h"
#include "as_array.h"
#include "as_string.h"
#include "as_objecttype.h"
#include "as_callfunc.h"
BEGIN_AS_NAMESPACE
class asCScriptFunction;
class asCScriptEngine;
class asCContext : public asIScriptContext
{
public:
// Memory management
int AddRef() const;
int Release() const;
// Miscellaneous
asIScriptEngine *GetEngine() const;
// Execution
int Prepare(asIScriptFunction *func);
int Unprepare();
int Execute();
int Abort();
int Suspend();
asEContextState GetState() const;
int PushState();
int PopState();
bool IsNested(asUINT *nestCount = 0) const;
// Object pointer for calling class methods
int SetObject(void *obj);
// Arguments
int SetArgByte(asUINT arg, asBYTE value);
int SetArgWord(asUINT arg, asWORD value);
int SetArgDWord(asUINT arg, asDWORD value);
int SetArgQWord(asUINT arg, asQWORD value);
int SetArgFloat(asUINT arg, float value);
int SetArgDouble(asUINT arg, double value);
int SetArgAddress(asUINT arg, void *addr);
int SetArgObject(asUINT arg, void *obj);
int SetArgVarType(asUINT arg, void *ptr, int typeId);
void *GetAddressOfArg(asUINT arg);
// Return value
asBYTE GetReturnByte();
asWORD GetReturnWord();
asDWORD GetReturnDWord();
asQWORD GetReturnQWord();
float GetReturnFloat();
double GetReturnDouble();
void *GetReturnAddress();
void *GetReturnObject();
void *GetAddressOfReturnValue();
// Exception handling
int SetException(const char *descr, bool allowCatch = true);
int GetExceptionLineNumber(int *column, const char **sectionName);
asIScriptFunction *GetExceptionFunction();
const char * GetExceptionString();
bool WillExceptionBeCaught();
int SetExceptionCallback(asSFuncPtr callback, void *obj, int callConv);
void ClearExceptionCallback();
// Debugging
int SetLineCallback(asSFuncPtr callback, void *obj, int callConv);
void ClearLineCallback();
asUINT GetCallstackSize() const;
asIScriptFunction *GetFunction(asUINT stackLevel);
int GetLineNumber(asUINT stackLevel, int *column, const char **sectionName);
int GetVarCount(asUINT stackLevel);
const char *GetVarName(asUINT varIndex, asUINT stackLevel);
const char *GetVarDeclaration(asUINT varIndex, asUINT stackLevel, bool includeNamespace);
int GetVarTypeId(asUINT varIndex, asUINT stackLevel);
void *GetAddressOfVar(asUINT varIndex, asUINT stackLevel);
bool IsVarInScope(asUINT varIndex, asUINT stackLevel);
int GetThisTypeId(asUINT stackLevel);
void *GetThisPointer(asUINT stackLevel);
asIScriptFunction *GetSystemFunction();
// User data
void *SetUserData(void *data, asPWORD type);
void *GetUserData(asPWORD type) const;
public:
// Internal public functions
asCContext(asCScriptEngine *engine, bool holdRef);
virtual ~asCContext();
//protected:
friend class asCScriptEngine;
void CallLineCallback();
void CallExceptionCallback();
int CallGeneric(asCScriptFunction *func);
#ifndef AS_NO_EXCEPTIONS
void HandleAppException();
#endif
void DetachEngine();
void ExecuteNext();
void CleanStack(bool catchException = false);
bool CleanStackFrame(bool catchException = false);
void CleanArgsOnStack();
void CleanReturnObject();
void DetermineLiveObjects(asCArray<int> &liveObjects, asUINT stackLevel);
int PushCallState();
void PopCallState();
void CallScriptFunction(asCScriptFunction *func);
void CallInterfaceMethod(asCScriptFunction *func);
void PrepareScriptFunction();
bool ReserveStackSpace(asUINT size);
void SetInternalException(const char *descr, bool allowCatch = true);
bool FindExceptionTryCatch();
// Must be protected for multiple accesses
mutable asCAtomic m_refCount;
bool m_holdEngineRef;
asCScriptEngine *m_engine;
asEContextState m_status;
bool m_doSuspend;
bool m_doAbort;
bool m_externalSuspendRequest;
asCScriptFunction *m_currentFunction;
asCScriptFunction *m_callingSystemFunction;
// The call stack holds program pointer, stack pointer, etc for caller functions
asCArray<size_t> m_callStack;
// Dynamically growing local stack
asCArray<asDWORD *> m_stackBlocks;
asUINT m_stackBlockSize;
asUINT m_stackIndex;
asDWORD *m_originalStackPointer;
// Exception handling
bool m_isStackMemoryNotAllocated;
bool m_needToCleanupArgs;
bool m_inExceptionHandler;
asCString m_exceptionString;
int m_exceptionFunction;
int m_exceptionSectionIdx;
int m_exceptionLine;
int m_exceptionColumn;
bool m_exceptionWillBeCaught;
// The last prepared function, and some cached values related to it
asCScriptFunction *m_initialFunction;
int m_returnValueSize;
int m_argumentsSize;
// callbacks
bool m_lineCallback;
asSSystemFunctionInterface m_lineCallbackFunc;
void * m_lineCallbackObj;
bool m_exceptionCallback;
asSSystemFunctionInterface m_exceptionCallbackFunc;
void * m_exceptionCallbackObj;
asCArray<asPWORD> m_userData;
// Registers available to JIT compiler functions
asSVMRegisters m_regs;
};
// TODO: Move these to as_utils.h
int as_powi(int base, int exponent, bool& isOverflow);
asDWORD as_powu(asDWORD base, asDWORD exponent, bool& isOverflow);
asINT64 as_powi64(asINT64 base, asINT64 exponent, bool& isOverflow);
asQWORD as_powu64(asQWORD base, asQWORD exponent, bool& isOverflow);
// Optional template version of powi if overflow detection is not used.
#if 0
template <class T>
T as_powi(T base, T exponent)
{
// Test for sign bit (huge number is OK)
if( exponent & (T(1)<<(sizeof(T)*8-1)) )
return 0;
else
{
int result = 1;
while( exponent )
{
if( exponent & 1 )
result *= base;
exponent >>= 1;
base *= base;
}
return result;
}
}
#endif
END_AS_NAMESPACE
#endif

View File

@@ -0,0 +1,189 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2017 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_criticalsection.h
//
// Classes for multi threading support
//
#ifndef AS_CRITICALSECTION_H
#define AS_CRITICALSECTION_H
#include "as_config.h"
BEGIN_AS_NAMESPACE
#ifdef AS_NO_THREADS
#define DECLARECRITICALSECTION(x)
#define ENTERCRITICALSECTION(x)
#define LEAVECRITICALSECTION(x)
inline bool tryEnter() { return true; }
#define TRYENTERCRITICALSECTION(x) tryEnter()
#define DECLAREREADWRITELOCK(x)
#define ACQUIREEXCLUSIVE(x)
#define RELEASEEXCLUSIVE(x)
#define ACQUIRESHARED(x)
#define RELEASESHARED(x)
#else
#define DECLARECRITICALSECTION(x) asCThreadCriticalSection x;
#define ENTERCRITICALSECTION(x) x.Enter()
#define LEAVECRITICALSECTION(x) x.Leave()
#define TRYENTERCRITICALSECTION(x) x.TryEnter()
#define DECLAREREADWRITELOCK(x) asCThreadReadWriteLock x;
#define ACQUIREEXCLUSIVE(x) x.AcquireExclusive()
#define RELEASEEXCLUSIVE(x) x.ReleaseExclusive()
#define ACQUIRESHARED(x) x.AcquireShared()
#define RELEASESHARED(x) x.ReleaseShared()
#ifdef AS_POSIX_THREADS
END_AS_NAMESPACE
#include <pthread.h>
BEGIN_AS_NAMESPACE
class asCThreadCriticalSection
{
public:
asCThreadCriticalSection();
~asCThreadCriticalSection();
void Enter();
void Leave();
bool TryEnter();
protected:
pthread_mutex_t cs;
};
class asCThreadReadWriteLock
{
public:
asCThreadReadWriteLock();
~asCThreadReadWriteLock();
void AcquireExclusive();
void ReleaseExclusive();
bool TryAcquireExclusive();
void AcquireShared();
void ReleaseShared();
bool TryAcquireShared();
protected:
pthread_rwlock_t lock;
};
#elif defined(AS_WINDOWS_THREADS)
END_AS_NAMESPACE
#ifdef AS_XBOX360
#include <xtl.h>
#else
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0600 // We need this to get the declaration for Windows Phone compatible Ex functions
#endif
#include <windows.h>
#endif
BEGIN_AS_NAMESPACE
// Undefine macros that cause problems in our code
#undef GetObject
#undef RegisterClass
class asCThreadCriticalSection
{
public:
asCThreadCriticalSection();
~asCThreadCriticalSection();
void Enter();
void Leave();
bool TryEnter();
protected:
CRITICAL_SECTION cs;
};
class asCThreadReadWriteLock
{
public:
asCThreadReadWriteLock();
~asCThreadReadWriteLock();
void AcquireExclusive();
void ReleaseExclusive();
void AcquireShared();
void ReleaseShared();
protected:
// The Slim Read Write Lock object, SRWLOCK, is more efficient
// but it is only available from Windows Vista so we cannot use it and
// maintain compatibility with olders versions of Windows.
// Critical sections and semaphores are available on Windows XP and onwards.
// Windows XP is oldest version we support with multithreading.
// The implementation is based on the following article, that shows
// how to implement a fair read/write lock that doesn't risk starving
// the writers:
// http://doc.qt.nokia.com/qq/qq11-mutex.html
// TODO: Allow use of SRWLOCK through configuration in as_config.h
CRITICAL_SECTION writeLock;
HANDLE readLocks;
};
// This constant really should be a member of asCThreadReadWriteLock,
// but it gives a compiler error on MSVC6 so I'm leaving it outside
static const asUINT maxReaders = 10;
#endif
#endif
END_AS_NAMESPACE
#endif

View File

@@ -0,0 +1,690 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2017 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_datatype.cpp
//
// This class describes the datatype for expressions during compilation
//
#include "as_config.h"
#include "as_datatype.h"
#include "as_tokendef.h"
#include "as_typeinfo.h"
#include "as_objecttype.h"
#include "as_scriptengine.h"
#include "as_tokenizer.h"
BEGIN_AS_NAMESPACE
asCDataType::asCDataType()
{
tokenType = ttUnrecognizedToken;
typeInfo = 0;
isReference = false;
isReadOnly = false;
isAuto = false;
isObjectHandle = false;
isConstHandle = false;
isHandleToAsHandleType = false;
ifHandleThenConst = false;
}
asCDataType::asCDataType(const asCDataType &dt)
{
tokenType = dt.tokenType;
typeInfo = dt.typeInfo;
isReference = dt.isReference;
isReadOnly = dt.isReadOnly;
isAuto = dt.isAuto;
isObjectHandle = dt.isObjectHandle;
isConstHandle = dt.isConstHandle;
isHandleToAsHandleType = dt.isHandleToAsHandleType;
ifHandleThenConst = dt.ifHandleThenConst;
}
asCDataType::~asCDataType()
{
}
bool asCDataType::IsValid() const
{
if( tokenType == ttUnrecognizedToken &&
!isObjectHandle )
return false;
return true;
}
asCDataType asCDataType::CreateType(asCTypeInfo *ti, bool isConst)
{
asCDataType dt;
dt.tokenType = ttIdentifier;
dt.typeInfo = ti;
dt.isReadOnly = isConst;
return dt;
}
asCDataType asCDataType::CreateAuto(bool isConst)
{
asCDataType dt;
dt.tokenType = ttIdentifier;
dt.isReadOnly = isConst;
dt.isAuto = true;
return dt;
}
asCDataType asCDataType::CreateObjectHandle(asCTypeInfo *ot, bool isConst)
{
asCDataType dt;
asASSERT(CastToObjectType(ot));
dt.tokenType = ttIdentifier;
dt.typeInfo = ot;
dt.isObjectHandle = true;
dt.isConstHandle = isConst;
return dt;
}
asCDataType asCDataType::CreatePrimitive(eTokenType tt, bool isConst)
{
asCDataType dt;
dt.tokenType = tt;
dt.isReadOnly = isConst;
return dt;
}
asCDataType asCDataType::CreateNullHandle()
{
asCDataType dt;
dt.tokenType = ttUnrecognizedToken;
dt.isReadOnly = true;
dt.isObjectHandle = true;
dt.isConstHandle = true;
return dt;
}
bool asCDataType::IsNullHandle() const
{
if( tokenType == ttUnrecognizedToken &&
typeInfo == 0 &&
isObjectHandle )
return true;
return false;
}
asCString asCDataType::Format(asSNameSpace *currNs, bool includeNamespace) const
{
if( IsNullHandle() )
return "<null handle>";
asCString str;
if( isReadOnly )
str = "const ";
// If the type is not declared in the current namespace, then the namespace
// must always be informed to guarantee that the correct type is informed
if (includeNamespace || (typeInfo && typeInfo->nameSpace != currNs))
{
if (typeInfo && typeInfo->nameSpace && typeInfo->nameSpace->name != "")
str += typeInfo->nameSpace->name + "::";
}
if (typeInfo && typeInfo->nameSpace == 0)
{
// If funcDef->nameSpace is null it means the funcDef was declared as member of
// another type, in which case the scope should be built with the name of that type
str += CastToFuncdefType(typeInfo)->parentClass->name + "::";
}
if( tokenType != ttIdentifier )
{
str += asCTokenizer::GetDefinition(tokenType);
}
else if( IsArrayType() && typeInfo && !typeInfo->engine->ep.expandDefaultArrayToTemplate )
{
asCObjectType *ot = CastToObjectType(typeInfo);
asASSERT( ot && ot->templateSubTypes.GetLength() == 1 );
str += ot->templateSubTypes[0].Format(currNs, includeNamespace);
str += "[]";
}
else if(typeInfo)
{
str += typeInfo->name;
asCObjectType *ot = CastToObjectType(typeInfo);
if( ot && ot->templateSubTypes.GetLength() > 0 )
{
str += "<";
for( asUINT subtypeIndex = 0; subtypeIndex < ot->templateSubTypes.GetLength(); subtypeIndex++ )
{
str += ot->templateSubTypes[subtypeIndex].Format(currNs, includeNamespace);
if( subtypeIndex != ot->templateSubTypes.GetLength()-1 )
str += ",";
}
str += ">";
}
}
else if( isAuto )
{
str += "<auto>";
}
else
{
str = "<unknown>";
}
if( isObjectHandle )
{
str += "@";
if( isConstHandle )
str += "const";
}
if( isReference )
str += "&";
return str;
}
asCDataType &asCDataType::operator =(const asCDataType &dt)
{
tokenType = dt.tokenType;
isReference = dt.isReference;
typeInfo = dt.typeInfo;
isReadOnly = dt.isReadOnly;
isObjectHandle = dt.isObjectHandle;
isConstHandle = dt.isConstHandle;
isAuto = dt.isAuto;
isHandleToAsHandleType = dt.isHandleToAsHandleType;
ifHandleThenConst = dt.ifHandleThenConst;
return (asCDataType &)*this;
}
int asCDataType::MakeHandle(bool b, bool acceptHandleForScope)
{
if( !b )
{
isObjectHandle = false;
isConstHandle = false;
isHandleToAsHandleType = false;
}
else
{
if( isAuto )
{
isObjectHandle = true;
}
else if( !isObjectHandle )
{
// Only reference types are allowed to be handles,
// but not nohandle reference types, and not scoped references
// (except when returned from registered function)
// funcdefs are special reference types and support handles
// value types with asOBJ_ASHANDLE are treated as a handle
if( (!typeInfo ||
!((typeInfo->flags & asOBJ_REF) || (typeInfo->flags & asOBJ_TEMPLATE_SUBTYPE) || (typeInfo->flags & asOBJ_ASHANDLE) || (typeInfo->flags & asOBJ_FUNCDEF)) ||
(typeInfo->flags & asOBJ_NOHANDLE) ||
((typeInfo->flags & asOBJ_SCOPED) && !acceptHandleForScope)) )
return -1;
isObjectHandle = b;
isConstHandle = false;
// ASHANDLE supports being handle, but as it really is a value type it will not be marked as a handle
if( (typeInfo->flags & asOBJ_ASHANDLE) )
{
isObjectHandle = false;
isHandleToAsHandleType = true;
}
}
}
return 0;
}
int asCDataType::MakeArray(asCScriptEngine *engine, asCModule *module)
{
if( engine->defaultArrayObjectType == 0 )
return asINVALID_TYPE;
bool tmpIsReadOnly = isReadOnly;
isReadOnly = false;
asCArray<asCDataType> subTypes;
subTypes.PushLast(*this);
asCObjectType *at = engine->GetTemplateInstanceType(engine->defaultArrayObjectType, subTypes, module);
isReadOnly = tmpIsReadOnly;
isObjectHandle = false;
isConstHandle = false;
typeInfo = at;
tokenType = ttIdentifier;
return 0;
}
int asCDataType::MakeReference(bool b)
{
isReference = b;
return 0;
}
int asCDataType::MakeReadOnly(bool b)
{
if( isObjectHandle )
{
isConstHandle = b;
return 0;
}
isReadOnly = b;
return 0;
}
int asCDataType::MakeHandleToConst(bool b)
{
if( !isObjectHandle ) return -1;
isReadOnly = b;
return 0;
}
bool asCDataType::SupportHandles() const
{
if( typeInfo &&
(typeInfo->flags & (asOBJ_REF | asOBJ_ASHANDLE | asOBJ_FUNCDEF)) &&
!(typeInfo->flags & asOBJ_NOHANDLE) &&
!isObjectHandle )
return true;
return false;
}
bool asCDataType::CanBeInstantiated() const
{
if( GetSizeOnStackDWords() == 0 ) // Void
return false;
if( !IsObject() && !IsFuncdef() ) // Primitives
return true;
if (IsNullHandle()) // null
return false;
if( IsObjectHandle() && !(typeInfo->flags & asOBJ_NOHANDLE) ) // Handles
return true;
// Funcdefs cannot be instantiated without being handles
// The exception being delegates, but these can only be created as temporary objects
if (IsFuncdef())
return false;
asCObjectType *ot = CastToObjectType(typeInfo);
if( ot && (ot->flags & asOBJ_REF) && ot->beh.factories.GetLength() == 0 ) // ref types without factories
return false;
if( ot && (ot->flags & asOBJ_ABSTRACT) && !IsObjectHandle() ) // Can't instantiate abstract classes
return false;
return true;
}
bool asCDataType::IsAbstractClass() const
{
return typeInfo && (typeInfo->flags & asOBJ_ABSTRACT) ? true : false;
}
bool asCDataType::IsInterface() const
{
if (typeInfo == 0)
return false;
asCObjectType *ot = CastToObjectType(typeInfo);
return ot && ot->IsInterface();
}
bool asCDataType::CanBeCopied() const
{
// All primitives can be copied
if( IsPrimitive() ) return true;
// Plain-old-data structures can always be copied
if( typeInfo->flags & asOBJ_POD ) return true;
// It must be possible to instantiate the type
if( !CanBeInstantiated() ) return false;
// It must have a default constructor or factory and the opAssign
// Alternatively it must have the copy constructor
asCObjectType *ot = CastToObjectType(typeInfo);
if (ot && (((ot->beh.construct != 0 || ot->beh.factory != 0) && ot->beh.copy != 0) ||
(ot->beh.copyconstruct != 0 || ot->beh.copyfactory != 0)) )
return true;
return false;
}
bool asCDataType::IsReadOnly() const
{
if( isObjectHandle )
return isConstHandle;
return isReadOnly;
}
bool asCDataType::IsHandleToConst() const
{
if( !isObjectHandle ) return false;
return isReadOnly;
}
bool asCDataType::IsObjectConst() const
{
if( IsObjectHandle() )
return IsHandleToConst();
return IsReadOnly();
}
// TODO: 3.0.0: This should be removed
bool asCDataType::IsArrayType() const
{
// This is only true if the type used is the default array type, i.e. the one used for the [] syntax form
if( typeInfo && typeInfo->engine->defaultArrayObjectType )
return typeInfo->name == typeInfo->engine->defaultArrayObjectType->name;
return false;
}
bool asCDataType::IsTemplate() const
{
if( typeInfo && (typeInfo->flags & asOBJ_TEMPLATE) )
return true;
return false;
}
bool asCDataType::IsScriptObject() const
{
if( typeInfo && (typeInfo->flags & asOBJ_SCRIPT_OBJECT) )
return true;
return false;
}
asCDataType asCDataType::GetSubType(asUINT subtypeIndex) const
{
asASSERT(typeInfo);
asCObjectType *ot = CastToObjectType(typeInfo);
return ot->templateSubTypes[subtypeIndex];
}
bool asCDataType::operator !=(const asCDataType &dt) const
{
return !(*this == dt);
}
bool asCDataType::operator ==(const asCDataType &dt) const
{
if( !IsEqualExceptRefAndConst(dt) ) return false;
if( isReference != dt.isReference ) return false;
if( isReadOnly != dt.isReadOnly ) return false;
if( isConstHandle != dt.isConstHandle ) return false;
return true;
}
bool asCDataType::IsEqualExceptRef(const asCDataType &dt) const
{
if( !IsEqualExceptRefAndConst(dt) ) return false;
if( isReadOnly != dt.isReadOnly ) return false;
if( isConstHandle != dt.isConstHandle ) return false;
return true;
}
bool asCDataType::IsEqualExceptRefAndConst(const asCDataType &dt) const
{
// Check base type
if( tokenType != dt.tokenType ) return false;
if( typeInfo != dt.typeInfo ) return false;
if( isObjectHandle != dt.isObjectHandle ) return false;
if( isObjectHandle )
if( isReadOnly != dt.isReadOnly ) return false;
return true;
}
bool asCDataType::IsEqualExceptConst(const asCDataType &dt) const
{
if( !IsEqualExceptRefAndConst(dt) ) return false;
if( isReference != dt.isReference ) return false;
return true;
}
bool asCDataType::IsPrimitive() const
{
// Enumerations are primitives
if( IsEnumType() )
return true;
// A registered object is never a primitive neither is a pointer nor an array
if( typeInfo )
return false;
// Null handle doesn't have a typeInfo, but it is not a primitive
if( tokenType == ttUnrecognizedToken )
return false;
return true;
}
bool asCDataType::IsMathType() const
{
if( tokenType == ttInt || tokenType == ttInt8 || tokenType == ttInt16 || tokenType == ttInt64 ||
tokenType == ttUInt || tokenType == ttUInt8 || tokenType == ttUInt16 || tokenType == ttUInt64 ||
tokenType == ttFloat || tokenType == ttDouble )
return true;
return false;
}
bool asCDataType::IsIntegerType() const
{
if( tokenType == ttInt ||
tokenType == ttInt8 ||
tokenType == ttInt16 ||
tokenType == ttInt64 )
return true;
// Enums are also integer types
return IsEnumType();
}
bool asCDataType::IsUnsignedType() const
{
if( tokenType == ttUInt ||
tokenType == ttUInt8 ||
tokenType == ttUInt16 ||
tokenType == ttUInt64 )
return true;
return false;
}
bool asCDataType::IsFloatType() const
{
if( tokenType == ttFloat )
return true;
return false;
}
bool asCDataType::IsDoubleType() const
{
if( tokenType == ttDouble )
return true;
return false;
}
bool asCDataType::IsBooleanType() const
{
if( tokenType == ttBool )
return true;
return false;
}
bool asCDataType::IsObject() const
{
if( IsPrimitive() )
return false;
// Null handle doesn't have an object type but should still be considered an object
if( typeInfo == 0 )
return IsNullHandle();
// Template subtypes shouldn't be considered objects
return CastToObjectType(typeInfo) ? true : false;
}
bool asCDataType::IsFuncdef() const
{
if (typeInfo && (typeInfo->flags & asOBJ_FUNCDEF))
return true;
return false;
}
int asCDataType::GetSizeInMemoryBytes() const
{
if( typeInfo != 0 )
return typeInfo->size;
if( tokenType == ttVoid )
return 0;
if( tokenType == ttInt8 ||
tokenType == ttUInt8 )
return 1;
if( tokenType == ttInt16 ||
tokenType == ttUInt16 )
return 2;
if( tokenType == ttDouble ||
tokenType == ttInt64 ||
tokenType == ttUInt64 )
return 8;
if( tokenType == ttBool )
return AS_SIZEOF_BOOL;
// null handle
if( tokenType == ttUnrecognizedToken )
return 4*AS_PTR_SIZE;
return 4;
}
int asCDataType::GetSizeInMemoryDWords() const
{
int s = GetSizeInMemoryBytes();
if( s == 0 ) return 0;
if( s <= 4 ) return 1;
// Pad the size to 4 bytes
if( s & 0x3 )
s += 4 - (s & 0x3);
return s/4;
}
int asCDataType::GetSizeOnStackDWords() const
{
// If the type is the variable type then the typeid is stored on the stack too
int size = tokenType == ttQuestion ? 1 : 0;
if( isReference ) return AS_PTR_SIZE + size;
if( typeInfo && !IsEnumType() ) return AS_PTR_SIZE + size;
return GetSizeInMemoryDWords() + size;
}
#ifdef WIP_16BYTE_ALIGN
int asCDataType::GetAlignment() const
{
if( typeInfo == NULL )
{
// TODO: Small primitives should not be aligned to 4 byte boundaries
return 4; //Default alignment
}
return typeInfo->alignment;
}
#endif
asSTypeBehaviour *asCDataType::GetBehaviour() const
{
if (!typeInfo) return 0;
asCObjectType *ot = CastToObjectType(typeInfo);
return ot ? &ot->beh : 0;
}
bool asCDataType::IsEnumType() const
{
// Do a sanity check on the objectType, to verify that we aren't trying to access memory after it has been released
asASSERT(typeInfo == 0 || typeInfo->name.GetLength() < 100);
if (typeInfo && (typeInfo->flags & asOBJ_ENUM))
return true;
return false;
}
END_AS_NAMESPACE

View File

@@ -0,0 +1,161 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2016 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_datatype.h
//
// This class describes the datatype for expressions during compilation
//
#ifndef AS_DATATYPE_H
#define AS_DATATYPE_H
#include "as_tokendef.h"
#include "as_string.h"
BEGIN_AS_NAMESPACE
struct asSTypeBehaviour;
class asCScriptEngine;
class asCTypeInfo;
class asCScriptFunction;
class asCModule;
class asCObjectType;
class asCEnumType;
struct asSNameSpace;
// TODO: refactor: Reference should not be part of the datatype. This should be stored separately, e.g. in asCExprValue
// MakeReference, MakeReadOnly, IsReference, IsReadOnly should be removed
class asCDataType
{
public:
asCDataType();
asCDataType(const asCDataType &);
~asCDataType();
bool IsValid() const;
asCString Format(asSNameSpace *currNs, bool includeNamespace = false) const;
static asCDataType CreatePrimitive(eTokenType tt, bool isConst);
static asCDataType CreateType(asCTypeInfo *ti, bool isConst);
static asCDataType CreateAuto(bool isConst);
static asCDataType CreateObjectHandle(asCTypeInfo *ot, bool isConst);
static asCDataType CreateNullHandle();
int MakeHandle(bool b, bool acceptHandleForScope = false);
int MakeArray(asCScriptEngine *engine, asCModule *requestingModule);
int MakeReference(bool b);
int MakeReadOnly(bool b);
int MakeHandleToConst(bool b);
void SetIfHandleThenConst(bool b) { ifHandleThenConst = b; }
bool HasIfHandleThenConst() const { return ifHandleThenConst; }
bool IsTemplate() const;
bool IsScriptObject() const;
bool IsPrimitive() const;
bool IsMathType() const;
bool IsObject() const;
bool IsReference() const {return isReference;}
bool IsAuto() const {return isAuto;}
bool IsReadOnly() const;
bool IsIntegerType() const;
bool IsUnsignedType() const;
bool IsFloatType() const;
bool IsDoubleType() const;
bool IsBooleanType() const;
bool IsObjectHandle() const {return isObjectHandle;}
bool IsHandleToAuto() const {return isAuto && isObjectHandle;}
bool IsHandleToConst() const;
bool IsArrayType() const;
bool IsEnumType() const;
bool IsAnyType() const {return tokenType == ttQuestion;}
bool IsHandleToAsHandleType() const {return isHandleToAsHandleType;}
bool IsAbstractClass() const;
bool IsInterface() const;
bool IsFuncdef() const;
bool IsObjectConst() const;
bool IsEqualExceptRef(const asCDataType &) const;
bool IsEqualExceptRefAndConst(const asCDataType &) const;
bool IsEqualExceptConst(const asCDataType &) const;
bool IsNullHandle() const;
bool SupportHandles() const;
bool CanBeInstantiated() const;
bool CanBeCopied() const;
bool operator ==(const asCDataType &) const;
bool operator !=(const asCDataType &) const;
asCDataType GetSubType(asUINT subtypeIndex = 0) const;
eTokenType GetTokenType() const {return tokenType;}
asCTypeInfo *GetTypeInfo() const { return typeInfo; }
int GetSizeOnStackDWords() const;
int GetSizeInMemoryBytes() const;
int GetSizeInMemoryDWords() const;
#ifdef WIP_16BYTE_ALIGN
int GetAlignment() const;
#endif
void SetTokenType(eTokenType tt) {tokenType = tt;}
void SetTypeInfo(asCTypeInfo *ti) {typeInfo = ti;}
asCDataType &operator =(const asCDataType &);
asSTypeBehaviour *GetBehaviour() const;
protected:
// Base object type
eTokenType tokenType;
// Behaviour type
asCTypeInfo *typeInfo;
// Top level
bool isReference:1;
bool isReadOnly:1;
bool isObjectHandle:1;
bool isConstHandle:1;
bool isAuto:1;
bool isHandleToAsHandleType:1; // Used by the compiler to know how to initialize the object
bool ifHandleThenConst:1; // Used when creating template instances to determine if a handle should be const or not
char dummy:1;
};
END_AS_NAMESPACE
#endif

View File

@@ -0,0 +1,270 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2016 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_debug.h
//
#ifndef AS_DEBUG_H
#define AS_DEBUG_H
#include "as_config.h"
#if defined(AS_DEBUG)
#ifndef AS_WII
// The Wii SDK doesn't have these, we'll survive without AS_DEBUG
#ifndef _WIN32_WCE
// Neither does WinCE
#ifndef AS_PSVITA
// Possible on PSVita, but requires SDK access
#if !defined(_MSC_VER) && (defined(__GNUC__) || defined(AS_MARMALADE))
#ifdef __ghs__
// WIIU defines __GNUC__ but types are not defined here in 'conventional' way
#include <types.h>
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int16_t;
typedef unsigned short uint16_t;
typedef signed int int32_t;
typedef unsigned int uint32_t;
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
typedef float float32_t;
typedef double float64_t;
#else
// Define mkdir for GNUC
#include <sys/stat.h>
#include <sys/types.h>
#define _mkdir(dirname) mkdir(dirname, S_IRWXU)
#endif
#else
#include <direct.h>
#endif
#endif // AS_PSVITA
#endif // _WIN32_WCE
#endif // AS_WII
#endif // !defined(AS_DEBUG)
#if defined(_MSC_VER) && defined(AS_PROFILE)
// Currently only do profiling with MSVC++
#include <mmsystem.h>
#include <direct.h>
#include "as_string.h"
#include "as_map.h"
#include "as_string_util.h"
BEGIN_AS_NAMESPACE
struct TimeCount
{
double time;
int count;
double max;
double min;
};
class CProfiler
{
public:
CProfiler()
{
// We need to know how often the clock is updated
__int64 tps;
if( !QueryPerformanceFrequency((LARGE_INTEGER *)&tps) )
usePerformance = false;
else
{
usePerformance = true;
ticksPerSecond = double(tps);
}
timeOffset = GetTime();
}
~CProfiler()
{
WriteSummary();
}
double GetTime()
{
if( usePerformance )
{
__int64 ticks;
QueryPerformanceCounter((LARGE_INTEGER *)&ticks);
return double(ticks)/ticksPerSecond - timeOffset;
}
return double(timeGetTime())/1000.0 - timeOffset;
}
double Begin(const char *name)
{
double time = GetTime();
// Add the scope to the key
if( key.GetLength() )
key += "|";
key += name;
// Compensate for the time spent writing to the file
timeOffset += GetTime() - time;
return time;
}
void End(const char * /*name*/, double beginTime)
{
double time = GetTime();
double elapsed = time - beginTime;
// Update the profile info for this scope
asSMapNode<asCString, TimeCount> *cursor;
if( map.MoveTo(&cursor, key) )
{
cursor->value.time += elapsed;
cursor->value.count++;
if( cursor->value.max < elapsed )
cursor->value.max = elapsed;
if( cursor->value.min > elapsed )
cursor->value.min = elapsed;
}
else
{
TimeCount tc = {elapsed, 1, elapsed, elapsed};
map.Insert(key, tc);
}
// Remove the inner most scope from the key
int n = key.FindLast("|");
if( n > 0 )
key.SetLength(n);
else
key.SetLength(0);
// Compensate for the time spent writing to the file
timeOffset += GetTime() - time;
}
protected:
void WriteSummary()
{
// Write the analyzed info into a file for inspection
_mkdir("AS_DEBUG");
FILE *fp;
#if _MSC_VER >= 1500 && !defined(AS_MARMALADE)
fopen_s(&fp, "AS_DEBUG/profiling_summary.txt", "wt");
#else
fp = fopen("AS_DEBUG/profiling_summary.txt", "wt");
#endif
if( fp == 0 )
return;
fprintf(fp, "%-60s %10s %15s %15s %15s %15s\n\n", "Scope", "Count", "Tot time", "Avg time", "Max time", "Min time");
asSMapNode<asCString, TimeCount> *cursor;
map.MoveLast(&cursor);
while( cursor )
{
asCString key = cursor->key;
int count;
int n = key.FindLast("|", &count);
if( count )
{
key = asCString(" ", count) + key.SubString(n+1);
}
fprintf(fp, "%-60s %10d %15.6f %15.6f %15.6f %15.6f\n", key.AddressOf(), cursor->value.count, cursor->value.time, cursor->value.time / cursor->value.count, cursor->value.max, cursor->value.min);
map.MovePrev(&cursor, cursor);
}
fclose(fp);
}
double timeOffset;
double ticksPerSecond;
bool usePerformance;
asCString key;
asCMap<asCString, TimeCount> map;
};
extern CProfiler g_profiler;
class CProfilerScope
{
public:
CProfilerScope(const char *name)
{
this->name = name;
beginTime = g_profiler.Begin(name);
}
~CProfilerScope()
{
g_profiler.End(name, beginTime);
}
protected:
const char *name;
double beginTime;
};
#define TimeIt(x) CProfilerScope profilescope(x)
END_AS_NAMESPACE
#else // !(_MSC_VER && AS_PROFILE)
// Define it so nothing is done
#define TimeIt(x)
#endif // !(_MSC_VER && AS_PROFILE)
#endif // defined(AS_DEBUG_H)

View File

@@ -0,0 +1,997 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2018 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_gc.cpp
//
// The implementation of the garbage collector
//
#include <stdlib.h>
#include "as_gc.h"
#include "as_scriptengine.h"
#include "as_scriptobject.h"
#include "as_texts.h"
BEGIN_AS_NAMESPACE
asCGarbageCollector::asCGarbageCollector()
{
engine = 0;
detectState = clearCounters_init;
destroyNewState = destroyGarbage_init;
destroyOldState = destroyGarbage_init;
numDestroyed = 0;
numNewDestroyed = 0;
numDetected = 0;
numAdded = 0;
isProcessing = false;
seqAtSweepStart[0] = 0;
seqAtSweepStart[1] = 0;
seqAtSweepStart[2] = 0;
circularRefDetectCallbackFunc = 0;
circularRefDetectCallbackParam = 0;
}
asCGarbageCollector::~asCGarbageCollector()
{
// This local typedef is done to workaround a compiler error on
// MSVC6 when using the typedef declared in the class definition
typedef asSMapNode_t node_t;
for( asUINT n = 0; n < freeNodes.GetLength(); n++ )
asDELETE(freeNodes[n], node_t);
freeNodes.SetLength(0);
}
int asCGarbageCollector::AddScriptObjectToGC(void *obj, asCObjectType *objType)
{
if( obj == 0 || objType == 0 )
{
engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_GC_RECEIVED_NULL_PTR);
return asINVALID_ARG;
}
engine->CallObjectMethod(obj, objType->beh.addref);
asSObjTypePair ot = {obj, objType, 0};
// Invoke the garbage collector to destroy a little garbage as new comes in
// This will maintain the number of objects in the GC at a maintainable level without
// halting the application, and without burdening the application with manually invoking the
// garbage collector.
if( engine->ep.autoGarbageCollect && gcNewObjects.GetLength() )
{
// If the GC is already processing in another thread, then don't try this again
if( TRYENTERCRITICALSECTION(gcCollecting) )
{
// Skip this if the GC is already running in this thread
if( !isProcessing )
{
isProcessing = true;
// TODO: The number of iterations should be dynamic, and increase
// if the number of objects in the garbage collector grows high
// Run one step of DetectGarbage
if( gcOldObjects.GetLength() )
{
IdentifyGarbageWithCyclicRefs();
DestroyOldGarbage();
}
// Run a few steps of DestroyGarbage
int iter = (int)gcNewObjects.GetLength();
if( iter > 10 ) iter = 10;
while( iter-- > 0 )
DestroyNewGarbage();
isProcessing = false;
}
LEAVECRITICALSECTION(gcCollecting);
}
}
// Add the data to the gcObjects array in a critical section as
// another thread might be calling this method at the same time
ENTERCRITICALSECTION(gcCritical);
ot.seqNbr = numAdded++;
gcNewObjects.PushLast(ot);
LEAVECRITICALSECTION(gcCritical);
return ot.seqNbr;
}
int asCGarbageCollector::GetObjectInGC(asUINT idx, asUINT *seqNbr, void **obj, asITypeInfo **type)
{
if( seqNbr ) *seqNbr = 0;
if( obj ) *obj = 0;
if( type ) *type = 0;
ENTERCRITICALSECTION(gcCritical);
asSObjTypePair *o = 0;
asUINT newObjs = asUINT(gcNewObjects.GetLength());
if( idx < newObjs )
o = &gcNewObjects[idx];
else if( idx < gcOldObjects.GetLength() + newObjs )
o = &gcOldObjects[idx-newObjs];
else
{
LEAVECRITICALSECTION(gcCritical);
return asINVALID_ARG;
}
if( seqNbr ) *seqNbr = o->seqNbr;
if( obj ) *obj = o->obj;
if( type ) *type = o->type;
LEAVECRITICALSECTION(gcCritical);
return asSUCCESS;
}
// TODO: Should have a flag to tell the garbage collector to automatically determine how many iterations are needed
// It should then gather statistics such as how many objects has been created since last run, and how many objects
// are destroyed per iteration, and how many objects are detected as cyclic garbage per iteration.
// It should try to reach a stable number of objects, i.e. so that on average the number of objects added to
// the garbage collector is the same as the number of objects destroyed. And it should try to minimize the number
// of iterations of detections that must be executed per cycle while still identifying the cyclic garbage
// These variables should also be available for inspection through the gcstatistics.
int asCGarbageCollector::GarbageCollect(asDWORD flags, asUINT iterations)
{
// If the GC is already processing in another thread, then don't enter here again
if( TRYENTERCRITICALSECTION(gcCollecting) )
{
// If the GC is already processing in this thread, then don't enter here again
if( isProcessing )
{
LEAVECRITICALSECTION(gcCollecting);
return 1;
}
isProcessing = true;
bool doDetect = (flags & asGC_DETECT_GARBAGE) || !(flags & asGC_DESTROY_GARBAGE);
bool doDestroy = (flags & asGC_DESTROY_GARBAGE) || !(flags & asGC_DETECT_GARBAGE);
if( flags & asGC_FULL_CYCLE )
{
// Reset the state
if( doDetect )
{
// Move all new objects to the old list, so we guarantee that all is detected
MoveAllObjectsToOldList();
detectState = clearCounters_init;
}
if( doDestroy )
{
destroyNewState = destroyGarbage_init;
destroyOldState = destroyGarbage_init;
}
// The full cycle only works with the objects in the old list so that the
// set of objects scanned for garbage is fixed even if new objects are added
// by other threads in parallel.
unsigned int count = (unsigned int)(gcOldObjects.GetLength());
for(;;)
{
// Detect all garbage with cyclic references
if( doDetect )
while( IdentifyGarbageWithCyclicRefs() == 1 ) {}
// Now destroy all known garbage
if( doDestroy )
{
if( !doDetect )
while( DestroyNewGarbage() == 1 ) {}
while( DestroyOldGarbage() == 1 ) {}
}
// Run another iteration if any garbage was destroyed
if( count != (unsigned int)(gcOldObjects.GetLength()) )
count = (unsigned int)(gcOldObjects.GetLength());
else
break;
}
isProcessing = false;
LEAVECRITICALSECTION(gcCollecting);
return 0;
}
else
{
while( iterations-- > 0 )
{
// Destroy the garbage that we know of
if( doDestroy )
{
DestroyNewGarbage();
DestroyOldGarbage();
}
// Run another incremental step of the identification of cyclic references
if( doDetect && gcOldObjects.GetLength() > 0 )
IdentifyGarbageWithCyclicRefs();
}
}
isProcessing = false;
LEAVECRITICALSECTION(gcCollecting);
}
// Return 1 to indicate that the cycle wasn't finished
return 1;
}
// TODO: Additional statistics to gather
//
// - How many objects are added on average between each destroyed object
// - How many objects are added on average between each detected object
// - how many iterations are needed for each destroyed object
// - how many iterations are needed for each detected object
//
// The average must have a decay so that long running applications will not suffer
// from objects being created early on in the application and then never destroyed.
//
// This ought to be possible to accomplish by holding two buckets.
// Numbers will be accumulated in one bucket while the other is held fixed.
// When returning the average it should use a weighted average between the two buckets using the size as weight.
// When a bucket is filled up, the buckets are switched, and then new bucket is emptied to gather new statistics.
void asCGarbageCollector::GetStatistics(asUINT *currentSize, asUINT *totalDestroyed, asUINT *totalDetected, asUINT *newObjects, asUINT *totalNewDestroyed) const
{
// It is not necessary to protect this with critical sections, however
// as it is not protected the variables can be filled in slightly different
// moments and might not match perfectly when inspected by the application
// afterwards.
if( currentSize )
*currentSize = (asUINT)(gcNewObjects.GetLength() + gcOldObjects.GetLength());
if( totalDestroyed )
*totalDestroyed = numDestroyed;
if( totalDetected )
*totalDetected = numDetected;
if( newObjects )
*newObjects = (asUINT)gcNewObjects.GetLength();
if( totalNewDestroyed )
*totalNewDestroyed = numNewDestroyed;
}
asCGarbageCollector::asSObjTypePair asCGarbageCollector::GetNewObjectAtIdx(int idx)
{
// We need to protect this access with a critical section as
// another thread might be appending an object at the same time
ENTERCRITICALSECTION(gcCritical);
asSObjTypePair gcObj = gcNewObjects[idx];
LEAVECRITICALSECTION(gcCritical);
return gcObj;
}
asCGarbageCollector::asSObjTypePair asCGarbageCollector::GetOldObjectAtIdx(int idx)
{
// We need to protect this access with a critical section as
// another thread might be appending an object at the same time
ENTERCRITICALSECTION(gcCritical);
asSObjTypePair gcObj = gcOldObjects[idx];
LEAVECRITICALSECTION(gcCritical);
return gcObj;
}
void asCGarbageCollector::RemoveNewObjectAtIdx(int idx)
{
// We need to protect this update with a critical section as
// another thread might be appending an object at the same time
ENTERCRITICALSECTION(gcCritical);
if( idx == (int)gcNewObjects.GetLength() - 1)
gcNewObjects.PopLast();
else
gcNewObjects[idx] = gcNewObjects.PopLast();
LEAVECRITICALSECTION(gcCritical);
}
void asCGarbageCollector::RemoveOldObjectAtIdx(int idx)
{
// We need to protect this update with a critical section as
// another thread might be appending an object at the same time
ENTERCRITICALSECTION(gcCritical);
if( idx == (int)gcOldObjects.GetLength() - 1)
gcOldObjects.PopLast();
else
gcOldObjects[idx] = gcOldObjects.PopLast();
LEAVECRITICALSECTION(gcCritical);
}
void asCGarbageCollector::MoveObjectToOldList(int idx)
{
// We need to protect this update with a critical section as
// another thread might be appending an object at the same time
ENTERCRITICALSECTION(gcCritical);
gcOldObjects.PushLast(gcNewObjects[idx]);
if( idx == (int)gcNewObjects.GetLength() - 1)
gcNewObjects.PopLast();
else
gcNewObjects[idx] = gcNewObjects.PopLast();
LEAVECRITICALSECTION(gcCritical);
}
void asCGarbageCollector::MoveAllObjectsToOldList()
{
// We need to protect this update with a critical section as
// another thread might be appending an object at the same time
ENTERCRITICALSECTION(gcCritical);
if( gcOldObjects.Concatenate(gcNewObjects) )
gcNewObjects.SetLength(0);
LEAVECRITICALSECTION(gcCritical);
}
int asCGarbageCollector::DestroyNewGarbage()
{
// This function will only be called within the critical section gcCollecting
asASSERT(isProcessing);
for(;;)
{
switch( destroyNewState )
{
case destroyGarbage_init:
{
// If there are no objects to be freed then don't start
if( gcNewObjects.GetLength() == 0 )
return 0;
// Update the seqAtSweepStart which is used to determine when
// to move an object from the new set to the old set
seqAtSweepStart[0] = seqAtSweepStart[1];
seqAtSweepStart[1] = seqAtSweepStart[2];
seqAtSweepStart[2] = numAdded;
destroyNewIdx = (asUINT)-1;
destroyNewState = destroyGarbage_loop;
}
break;
case destroyGarbage_loop:
case destroyGarbage_haveMore:
{
// If the refCount has reached 1, then only the GC still holds a
// reference to the object, thus we don't need to worry about the
// application touching the objects during collection.
// Destroy all objects that have refCount == 1. If any objects are
// destroyed, go over the list again, because it may have made more
// objects reach refCount == 1.
if( ++destroyNewIdx < gcNewObjects.GetLength() )
{
asSObjTypePair gcObj = GetNewObjectAtIdx(destroyNewIdx);
if( engine->CallObjectMethodRetInt(gcObj.obj, gcObj.type->beh.gcGetRefCount) == 1 )
{
// Release the object immediately
// Make sure the refCount is really 0, because the
// destructor may have increased the refCount again.
bool addRef = false;
if( gcObj.type->flags & asOBJ_SCRIPT_OBJECT )
{
// Script objects may actually be resurrected in the destructor
int refCount = ((asCScriptObject*)gcObj.obj)->Release();
if( refCount > 0 ) addRef = true;
}
else
engine->CallObjectMethod(gcObj.obj, gcObj.type->beh.release);
// Was the object really destroyed?
if( !addRef )
{
numDestroyed++;
numNewDestroyed++;
RemoveNewObjectAtIdx(destroyNewIdx);
destroyNewIdx--;
}
else
{
// Since the object was resurrected in the
// destructor, we must add our reference again
engine->CallObjectMethod(gcObj.obj, gcObj.type->beh.addref);
}
destroyNewState = destroyGarbage_haveMore;
}
// Check if this object has been inspected 3 times already, and if so move it to the
// set of old objects that are less likely to become garbage in a short time
// TODO: Is 3 really a good value? Should the number of times be dynamic?
else if( gcObj.seqNbr < seqAtSweepStart[0] )
{
// We've already verified this object multiple times. It is likely
// to live for quite a long time so we'll move it to the list if old objects
MoveObjectToOldList(destroyNewIdx);
destroyNewIdx--;
}
// Allow the application to work a little
return 1;
}
else
{
if( destroyNewState == destroyGarbage_haveMore )
{
// Restart the cycle
destroyNewState = destroyGarbage_init;
}
else
{
// Restart the cycle
destroyNewState = destroyGarbage_init;
// Return 0 to tell the application that there
// is no more garbage to destroy at the moment
return 0;
}
}
}
break;
}
}
// Shouldn't reach this point
UNREACHABLE_RETURN;
}
int asCGarbageCollector::ReportAndReleaseUndestroyedObjects()
{
// This function will only be called as the engine is shutting down
int items = 0;
for( asUINT n = 0; n < gcOldObjects.GetLength(); n++ )
{
asSObjTypePair gcObj = GetOldObjectAtIdx(n);
int refCount = 0;
if( gcObj.type->beh.gcGetRefCount && engine->scriptFunctions[gcObj.type->beh.gcGetRefCount] )
refCount = engine->CallObjectMethodRetInt(gcObj.obj, gcObj.type->beh.gcGetRefCount);
// Report the object as not being properly destroyed
asCString msg;
msg.Format(TXT_d_GC_CANNOT_FREE_OBJ_OF_TYPE_s_REF_COUNT_d, gcObj.seqNbr, gcObj.type->name.AddressOf(), refCount - 1);
engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, msg.AddressOf());
// Add additional info for builtin types
if( gcObj.type->name == "$func" )
{
// Unfortunately we can't show the function declaration here, because the engine may have released the parameter list already so the declaration would only be misleading
// We need to show the function type too as for example delegates do not have a name
msg.Format(TXT_PREV_FUNC_IS_NAMED_s_TYPE_IS_d, reinterpret_cast<asCScriptFunction*>(gcObj.obj)->GetName(), reinterpret_cast<asCScriptFunction*>(gcObj.obj)->GetFuncType());
engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, msg.AddressOf());
}
else if( gcObj.type->name == "$obj" )
{
msg.Format(TXT_PREV_TYPE_IS_NAMED_s, reinterpret_cast<asCObjectType*>(gcObj.obj)->GetName());
engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, msg.AddressOf());
}
// Release the reference that the GC holds if the release functions is still available
if( gcObj.type->beh.release && engine->scriptFunctions[gcObj.type->beh.release] )
engine->CallObjectMethod(gcObj.obj, gcObj.type->beh.release);
items++;
}
return items;
}
int asCGarbageCollector::DestroyOldGarbage()
{
// This function will only be called within the critical section gcCollecting
asASSERT(isProcessing);
for(;;)
{
switch( destroyOldState )
{
case destroyGarbage_init:
{
// If there are no objects to be freed then don't start
if( gcOldObjects.GetLength() == 0 )
return 0;
destroyOldIdx = (asUINT)-1;
destroyOldState = destroyGarbage_loop;
}
break;
case destroyGarbage_loop:
case destroyGarbage_haveMore:
{
// If the refCount has reached 1, then only the GC still holds a
// reference to the object, thus we don't need to worry about the
// application touching the objects during collection.
// Destroy all objects that have refCount == 1. If any objects are
// destroyed, go over the list again, because it may have made more
// objects reach refCount == 1.
if( ++destroyOldIdx < gcOldObjects.GetLength() )
{
asSObjTypePair gcObj = GetOldObjectAtIdx(destroyOldIdx);
if( gcObj.type->beh.gcGetRefCount == 0 )
{
// If circular references are formed with registered types that hasn't
// registered the GC behaviours, then the engine may be forced to free
// the object type before the actual object instance. In this case we
// will be forced to skip the destruction of the objects, so as not to
// crash the application.
asCString msg;
msg.Format(TXT_d_GC_CANNOT_FREE_OBJ_OF_TYPE_s, gcObj.seqNbr, gcObj.type->name.AddressOf());
engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, msg.AddressOf());
// Just remove the object, as we will not bother to destroy it
numDestroyed++;
RemoveOldObjectAtIdx(destroyOldIdx);
destroyOldIdx--;
}
else if( engine->CallObjectMethodRetInt(gcObj.obj, gcObj.type->beh.gcGetRefCount) == 1 )
{
// Release the object immediately
// Make sure the refCount is really 0, because the
// destructor may have increased the refCount again.
bool addRef = false;
if( gcObj.type->flags & asOBJ_SCRIPT_OBJECT )
{
// Script objects may actually be resurrected in the destructor
int refCount = ((asCScriptObject*)gcObj.obj)->Release();
if( refCount > 0 ) addRef = true;
}
else
engine->CallObjectMethod(gcObj.obj, gcObj.type->beh.release);
// Was the object really destroyed?
if( !addRef )
{
numDestroyed++;
RemoveOldObjectAtIdx(destroyOldIdx);
destroyOldIdx--;
}
else
{
// Since the object was resurrected in the
// destructor, we must add our reference again
engine->CallObjectMethod(gcObj.obj, gcObj.type->beh.addref);
}
destroyOldState = destroyGarbage_haveMore;
}
// Allow the application to work a little
return 1;
}
else
{
if( destroyOldState == destroyGarbage_haveMore )
{
// Restart the cycle
destroyOldState = destroyGarbage_init;
}
else
{
// Restart the cycle
destroyOldState = destroyGarbage_init;
// Return 0 to tell the application that there
// is no more garbage to destroy at the moment
return 0;
}
}
}
break;
}
}
// Shouldn't reach this point
UNREACHABLE_RETURN;
}
int asCGarbageCollector::IdentifyGarbageWithCyclicRefs()
{
// This function will only be called within the critical section gcCollecting
asASSERT(isProcessing);
for(;;)
{
switch( detectState )
{
case clearCounters_init:
detectState = clearCounters_loop;
break;
case clearCounters_loop:
{
// Decrease reference counter for all objects removed from the map
asSMapNode<void*, asSIntTypePair> *cursor = 0;
gcMap.MoveFirst(&cursor);
if( cursor )
{
void *obj = gcMap.GetKey(cursor);
asSIntTypePair it = gcMap.GetValue(cursor);
engine->CallObjectMethod(obj, it.type->beh.release);
ReturnNode(gcMap.Remove(cursor));
return 1;
}
detectState = buildMap_init;
}
break;
case buildMap_init:
detectIdx = 0;
detectState = buildMap_loop;
break;
case buildMap_loop:
{
// Build a map of objects that will be checked, the map will
// hold the object pointer as key, and the gcCount and the
// object's type as value. As objects are added to the map the
// gcFlag must be set in the objects, so we can be verify if
// the object is accessed during the GC cycle.
// If an object is removed from the gcObjects list during the
// iteration of this step, it is possible that an object won't
// be used during the analyzing for cyclic references. This
// isn't a problem, as the next time the GC cycle starts the
// object will be verified.
if( detectIdx < gcOldObjects.GetLength() )
{
// Add the gc count for this object
asSObjTypePair gcObj = GetOldObjectAtIdx(detectIdx);
int refCount = 0;
if( gcObj.type->beh.gcGetRefCount )
refCount = engine->CallObjectMethodRetInt(gcObj.obj, gcObj.type->beh.gcGetRefCount);
if( refCount > 1 )
{
asSIntTypePair it = {refCount-1, gcObj.type};
gcMap.Insert(GetNode(gcObj.obj, it));
// Increment the object's reference counter when putting it in the map
engine->CallObjectMethod(gcObj.obj, gcObj.type->beh.addref);
// Mark the object so that we can
// see if it has changed since read
engine->CallObjectMethod(gcObj.obj, gcObj.type->beh.gcSetFlag);
}
detectIdx++;
// Let the application work a little
return 1;
}
else
detectState = countReferences_init;
}
break;
case countReferences_init:
{
gcMap.MoveFirst(&gcMapCursor);
detectState = countReferences_loop;
}
break;
case countReferences_loop:
{
// Call EnumReferences on all objects in the map to count the number
// of references reachable from between objects in the map. If all
// references for an object in the map is reachable from other objects
// in the map, then we know that no outside references are held for
// this object, thus it is a potential dead object in a circular reference.
// If the gcFlag is cleared for an object we consider the object alive
// and referenced from outside the GC, thus we don't enumerate its references.
// Any new objects created after this step in the GC cycle won't be
// in the map, and is thus automatically considered alive.
if( gcMapCursor )
{
void *obj = gcMap.GetKey(gcMapCursor);
asCObjectType *type = gcMap.GetValue(gcMapCursor).type;
gcMap.MoveNext(&gcMapCursor, gcMapCursor);
if( engine->CallObjectMethodRetBool(obj, type->beh.gcGetFlag) )
{
engine->CallObjectMethod(obj, engine, type->beh.gcEnumReferences);
}
// Allow the application to work a little
return 1;
}
else
detectState = detectGarbage_init;
}
break;
case detectGarbage_init:
{
gcMap.MoveFirst(&gcMapCursor);
liveObjects.SetLength(0);
detectState = detectGarbage_loop1;
}
break;
case detectGarbage_loop1:
{
// All objects that are known not to be dead must be removed from the map,
// along with all objects they reference. What remains in the map after
// this pass is sure to be dead objects in circular references.
// An object is considered alive if its gcFlag is cleared, or all the
// references were not found in the map.
// Add all alive objects from the map to the liveObjects array
if( gcMapCursor )
{
asSMapNode<void*, asSIntTypePair> *cursor = gcMapCursor;
gcMap.MoveNext(&gcMapCursor, gcMapCursor);
void *obj = gcMap.GetKey(cursor);
asSIntTypePair it = gcMap.GetValue(cursor);
bool gcFlag = engine->CallObjectMethodRetBool(obj, it.type->beh.gcGetFlag);
if( !gcFlag || it.i > 0 )
{
liveObjects.PushLast(obj);
}
// Allow the application to work a little
return 1;
}
else
detectState = detectGarbage_loop2;
}
break;
case detectGarbage_loop2:
{
// In this step we are actually removing the alive objects from the map.
// As the object is removed, all the objects it references are added to the
// liveObjects list, by calling EnumReferences. Only objects still in the map
// will be added to the liveObjects list.
if( liveObjects.GetLength() )
{
void *gcObj = liveObjects.PopLast();
asCObjectType *type = 0;
// Remove the object from the map to mark it as alive
asSMapNode<void*, asSIntTypePair> *cursor = 0;
if( gcMap.MoveTo(&cursor, gcObj) )
{
type = gcMap.GetValue(cursor).type;
ReturnNode(gcMap.Remove(cursor));
// We need to decrease the reference count again as we remove the object from the map
engine->CallObjectMethod(gcObj, type->beh.release);
// Enumerate all the object's references so that they too can be marked as alive
engine->CallObjectMethod(gcObj, engine, type->beh.gcEnumReferences);
}
// Allow the application to work a little
return 1;
}
else
detectState = verifyUnmarked_init;
}
break;
case verifyUnmarked_init:
gcMap.MoveFirst(&gcMapCursor);
detectState = verifyUnmarked_loop;
break;
case verifyUnmarked_loop:
{
// In this step we must make sure that none of the objects still in the map
// has been touched by the application. If they have then we must run the
// detectGarbage loop once more.
if( gcMapCursor )
{
void *gcObj = gcMap.GetKey(gcMapCursor);
asCObjectType *type = gcMap.GetValue(gcMapCursor).type;
bool gcFlag = engine->CallObjectMethodRetBool(gcObj, type->beh.gcGetFlag);
if( !gcFlag )
{
// The unmarked object was touched, rerun the detectGarbage loop
detectState = detectGarbage_init;
}
else
gcMap.MoveNext(&gcMapCursor, gcMapCursor);
// Allow the application to work a little
return 1;
}
else
{
// No unmarked object was touched, we can now be sure
// that objects that have gcCount == 0 really is garbage
detectState = breakCircles_init;
}
}
break;
case breakCircles_init:
{
gcMap.MoveFirst(&gcMapCursor);
detectState = breakCircles_loop;
// If the application has requested a callback for detected circular references,
// then make that callback now for all the objects in the list. This step is not
// done in incremental steps as it is only meant for debugging purposes and thus
// doesn't require interactivity
if (gcMapCursor && circularRefDetectCallbackFunc)
{
while (gcMapCursor)
{
void *gcObj = gcMap.GetKey(gcMapCursor);
asCObjectType *type = gcMap.GetValue(gcMapCursor).type;
circularRefDetectCallbackFunc(type, gcObj, circularRefDetectCallbackParam);
gcMap.MoveNext(&gcMapCursor, gcMapCursor);
}
// Reset iterator
gcMap.MoveFirst(&gcMapCursor);
}
}
break;
case breakCircles_loop:
case breakCircles_haveGarbage:
{
// All objects in the map are now known to be dead objects
// kept alive through circular references. To be able to free
// these objects we need to force the breaking of the circle
// by having the objects release their references.
if( gcMapCursor )
{
numDetected++;
void *gcObj = gcMap.GetKey(gcMapCursor);
asCObjectType *type = gcMap.GetValue(gcMapCursor).type;
if( type->flags & asOBJ_SCRIPT_OBJECT )
{
// For script objects we must call the class destructor before
// releasing the references, otherwise the destructor may not
// be able to perform the necessary clean-up as the handles will
// be null.
reinterpret_cast<asCScriptObject*>(gcObj)->CallDestructor();
}
engine->CallObjectMethod(gcObj, engine, type->beh.gcReleaseAllReferences);
gcMap.MoveNext(&gcMapCursor, gcMapCursor);
detectState = breakCircles_haveGarbage;
// Allow the application to work a little
return 1;
}
else
{
// If no garbage was detected we can finish now
if( detectState != breakCircles_haveGarbage )
{
// Restart the GC
detectState = clearCounters_init;
return 0;
}
else
{
// Restart the GC
detectState = clearCounters_init;
return 1;
}
}
}
} // switch
}
// Shouldn't reach this point
UNREACHABLE_RETURN;
}
asCGarbageCollector::asSMapNode_t *asCGarbageCollector::GetNode(void *obj, asSIntTypePair it)
{
// This function will only be called within the critical section gcCollecting
asASSERT(isProcessing);
asSMapNode_t *node;
if( freeNodes.GetLength() )
node = freeNodes.PopLast();
else
{
node = asNEW(asSMapNode_t);
if( !node )
{
// Out of memory
return 0;
}
}
node->Init(obj, it);
return node;
}
void asCGarbageCollector::ReturnNode(asSMapNode_t *node)
{
// This function will only be called within the critical section gcCollecting
asASSERT(isProcessing);
if( node )
freeNodes.PushLast(node);
}
void asCGarbageCollector::GCEnumCallback(void *reference)
{
// This function will only be called within the critical section gcCollecting
asASSERT(isProcessing);
if( detectState == countReferences_loop )
{
// Find the reference in the map
asSMapNode<void*, asSIntTypePair> *cursor = 0;
if( gcMap.MoveTo(&cursor, reference) )
{
// Decrease the counter in the map for the reference
gcMap.GetValue(cursor).i--;
}
}
else if( detectState == detectGarbage_loop2 )
{
// Find the reference in the map
asSMapNode<void*, asSIntTypePair> *cursor = 0;
if( gcMap.MoveTo(&cursor, reference) )
{
// Add the object to the list of objects to mark as alive
liveObjects.PushLast(reference);
}
}
}
END_AS_NAMESPACE

151
angelscript/source/as_gc.h Normal file
View File

@@ -0,0 +1,151 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2018 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_gc.h
//
// The garbage collector is used to resolve cyclic references
//
#ifndef AS_GC_H
#define AS_GC_H
#include "as_config.h"
#include "as_array.h"
#include "as_map.h"
#include "as_thread.h"
BEGIN_AS_NAMESPACE
class asCScriptEngine;
class asCObjectType;
class asCGarbageCollector
{
public:
asCGarbageCollector();
~asCGarbageCollector();
int GarbageCollect(asDWORD flags, asUINT iterations);
void GetStatistics(asUINT *currentSize, asUINT *totalDestroyed, asUINT *totalDetected, asUINT *newObjects, asUINT *totalNewDestroyed) const;
void GCEnumCallback(void *reference);
int AddScriptObjectToGC(void *obj, asCObjectType *objType);
int GetObjectInGC(asUINT idx, asUINT *seqNbr, void **obj, asITypeInfo **type);
int ReportAndReleaseUndestroyedObjects();
asCScriptEngine *engine;
// Callback for when circular reference are detected
asCIRCULARREFFUNC_t circularRefDetectCallbackFunc;
void * circularRefDetectCallbackParam;
protected:
struct asSObjTypePair {void *obj; asCObjectType *type; asUINT seqNbr;};
struct asSIntTypePair {int i; asCObjectType *type;};
typedef asSMapNode<void*, asSIntTypePair> asSMapNode_t;
enum egcDestroyState
{
destroyGarbage_init = 0,
destroyGarbage_loop,
destroyGarbage_haveMore
};
enum egcDetectState
{
clearCounters_init = 0,
clearCounters_loop,
buildMap_init,
buildMap_loop,
countReferences_init,
countReferences_loop,
detectGarbage_init,
detectGarbage_loop1,
detectGarbage_loop2,
verifyUnmarked_init,
verifyUnmarked_loop,
breakCircles_init,
breakCircles_loop,
breakCircles_haveGarbage
};
int DestroyNewGarbage();
int DestroyOldGarbage();
int IdentifyGarbageWithCyclicRefs();
asSObjTypePair GetNewObjectAtIdx(int idx);
asSObjTypePair GetOldObjectAtIdx(int idx);
void RemoveNewObjectAtIdx(int idx);
void RemoveOldObjectAtIdx(int idx);
void MoveObjectToOldList(int idx);
void MoveAllObjectsToOldList();
// Holds all the objects known by the garbage collector
asCArray<asSObjTypePair> gcNewObjects;
asCArray<asSObjTypePair> gcOldObjects;
// This array temporarily holds references to objects known to be live objects
asCArray<void*> liveObjects;
// This map holds objects currently being searched for cyclic references, it also holds a
// counter that gives the number of references to the object that the GC can't reach
asCMap<void*, asSIntTypePair> gcMap;
// State variables
egcDestroyState destroyNewState;
egcDestroyState destroyOldState;
asUINT destroyNewIdx;
asUINT destroyOldIdx;
asUINT numDestroyed;
asUINT numNewDestroyed;
egcDetectState detectState;
asUINT detectIdx;
asUINT numDetected;
asUINT numAdded;
asUINT seqAtSweepStart[3];
asSMapNode_t *gcMapCursor;
bool isProcessing;
// We'll keep a pool of nodes to avoid allocating memory all the time
asSMapNode_t *GetNode(void *obj, asSIntTypePair it);
void ReturnNode(asSMapNode_t *node);
asCArray<asSMapNode_t*> freeNodes;
// Critical section for multithreaded access
DECLARECRITICALSECTION(gcCritical) // Used for adding/removing objects
DECLARECRITICALSECTION(gcCollecting) // Used for processing
};
END_AS_NAMESPACE
#endif

View File

@@ -0,0 +1,534 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2016 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_generic.cpp
//
// This class handles the call to a function registered with asCALL_GENERIC
//
#include "as_generic.h"
#include "as_scriptfunction.h"
#include "as_objecttype.h"
#include "as_scriptengine.h"
BEGIN_AS_NAMESPACE
// TODO: runtime optimize: The access to the arguments should be optimized so that code
// doesn't have to count the position of the argument with every call
// internal
asCGeneric::asCGeneric(asCScriptEngine *engine, asCScriptFunction *sysFunction, void *currentObject, asDWORD *stackPointer)
{
this->engine = engine;
this->sysFunction = sysFunction;
this->currentObject = currentObject;
this->stackPointer = stackPointer;
objectRegister = 0;
returnVal = 0;
}
// internal
asCGeneric::~asCGeneric()
{
}
// interface
void *asCGeneric::GetAuxiliary() const
{
return sysFunction->GetAuxiliary();
}
// interface
asIScriptEngine *asCGeneric::GetEngine() const
{
return (asIScriptEngine*)engine;
}
// interface
asIScriptFunction *asCGeneric::GetFunction() const
{
return sysFunction;
}
// interface
void *asCGeneric::GetObject()
{
return currentObject;
}
// interface
int asCGeneric::GetObjectTypeId() const
{
asCDataType dt = asCDataType::CreateType(sysFunction->objectType, false);
return engine->GetTypeIdFromDataType(dt);
}
// interface
int asCGeneric::GetArgCount() const
{
return (int)sysFunction->parameterTypes.GetLength();
}
// interface
asBYTE asCGeneric::GetArgByte(asUINT arg)
{
if( arg >= (unsigned)sysFunction->parameterTypes.GetLength() )
return 0;
// Verify that the type is correct
asCDataType *dt = &sysFunction->parameterTypes[arg];
if( (dt->IsObject() || dt->IsFuncdef()) || dt->IsReference() )
return 0;
if( dt->GetSizeInMemoryBytes() != 1 )
return 0;
// Determine the position of the argument
int offset = 0;
for( asUINT n = 0; n < arg; n++ )
offset += sysFunction->parameterTypes[n].GetSizeOnStackDWords();
// Get the value
return *(asBYTE*)&stackPointer[offset];
}
// interface
asWORD asCGeneric::GetArgWord(asUINT arg)
{
if( arg >= (unsigned)sysFunction->parameterTypes.GetLength() )
return 0;
// Verify that the type is correct
asCDataType *dt = &sysFunction->parameterTypes[arg];
if( (dt->IsObject() || dt->IsFuncdef()) || dt->IsReference() )
return 0;
if( dt->GetSizeInMemoryBytes() != 2 )
return 0;
// Determine the position of the argument
int offset = 0;
for( asUINT n = 0; n < arg; n++ )
offset += sysFunction->parameterTypes[n].GetSizeOnStackDWords();
// Get the value
return *(asWORD*)&stackPointer[offset];
}
// interface
asDWORD asCGeneric::GetArgDWord(asUINT arg)
{
if( arg >= (unsigned)sysFunction->parameterTypes.GetLength() )
return 0;
// Verify that the type is correct
asCDataType *dt = &sysFunction->parameterTypes[arg];
if( (dt->IsObject() || dt->IsFuncdef()) || dt->IsReference() )
return 0;
if( dt->GetSizeInMemoryBytes() != 4 )
return 0;
// Determine the position of the argument
int offset = 0;
for( asUINT n = 0; n < arg; n++ )
offset += sysFunction->parameterTypes[n].GetSizeOnStackDWords();
// Get the value
return *(asDWORD*)&stackPointer[offset];
}
// interface
asQWORD asCGeneric::GetArgQWord(asUINT arg)
{
if( arg >= (unsigned)sysFunction->parameterTypes.GetLength() )
return 0;
// Verify that the type is correct
asCDataType *dt = &sysFunction->parameterTypes[arg];
if( (dt->IsObject() || dt->IsFuncdef()) || dt->IsReference() )
return 0;
if( dt->GetSizeInMemoryBytes() != 8 )
return 0;
// Determine the position of the argument
int offset = 0;
for( asUINT n = 0; n < arg; n++ )
offset += sysFunction->parameterTypes[n].GetSizeOnStackDWords();
// Get the value
return *(asQWORD*)(&stackPointer[offset]);
}
// interface
float asCGeneric::GetArgFloat(asUINT arg)
{
if( arg >= (unsigned)sysFunction->parameterTypes.GetLength() )
return 0;
// Verify that the type is correct
asCDataType *dt = &sysFunction->parameterTypes[arg];
if( (dt->IsObject() || dt->IsFuncdef()) || dt->IsReference() )
return 0;
if( dt->GetSizeInMemoryBytes() != 4 )
return 0;
// Determine the position of the argument
int offset = 0;
for( asUINT n = 0; n < arg; n++ )
offset += sysFunction->parameterTypes[n].GetSizeOnStackDWords();
// Get the value
return *(float*)(&stackPointer[offset]);
}
// interface
double asCGeneric::GetArgDouble(asUINT arg)
{
if( arg >= (unsigned)sysFunction->parameterTypes.GetLength() )
return 0;
// Verify that the type is correct
asCDataType *dt = &sysFunction->parameterTypes[arg];
if( (dt->IsObject() || dt->IsFuncdef()) || dt->IsReference() )
return 0;
if( dt->GetSizeInMemoryBytes() != 8 )
return 0;
// Determine the position of the argument
int offset = 0;
for( asUINT n = 0; n < arg; n++ )
offset += sysFunction->parameterTypes[n].GetSizeOnStackDWords();
// Get the value
return *(double*)(&stackPointer[offset]);
}
// interface
void *asCGeneric::GetArgAddress(asUINT arg)
{
if( arg >= (unsigned)sysFunction->parameterTypes.GetLength() )
return 0;
// Verify that the type is correct
asCDataType *dt = &sysFunction->parameterTypes[arg];
if( !dt->IsReference() && !dt->IsObjectHandle() )
return 0;
// Determine the position of the argument
int offset = 0;
for( asUINT n = 0; n < arg; n++ )
offset += sysFunction->parameterTypes[n].GetSizeOnStackDWords();
// Get the value
return (void*)*(asPWORD*)(&stackPointer[offset]);
}
// interface
void *asCGeneric::GetArgObject(asUINT arg)
{
if( arg >= (unsigned)sysFunction->parameterTypes.GetLength() )
return 0;
// Verify that the type is correct
asCDataType *dt = &sysFunction->parameterTypes[arg];
if( !dt->IsObject() && !dt->IsFuncdef() )
return 0;
// Determine the position of the argument
int offset = 0;
for( asUINT n = 0; n < arg; n++ )
offset += sysFunction->parameterTypes[n].GetSizeOnStackDWords();
// Get the value
return *(void**)(&stackPointer[offset]);
}
// interface
void *asCGeneric::GetAddressOfArg(asUINT arg)
{
if( arg >= (unsigned)sysFunction->parameterTypes.GetLength() )
return 0;
// Determine the position of the argument
int offset = 0;
for( asUINT n = 0; n < arg; n++ )
offset += sysFunction->parameterTypes[n].GetSizeOnStackDWords();
// For object variables it's necessary to dereference the pointer to get the address of the value
if( !sysFunction->parameterTypes[arg].IsReference() &&
sysFunction->parameterTypes[arg].IsObject() &&
!sysFunction->parameterTypes[arg].IsObjectHandle() )
return *(void**)&stackPointer[offset];
// Get the address of the value
return &stackPointer[offset];
}
// interface
int asCGeneric::GetArgTypeId(asUINT arg, asDWORD *flags) const
{
if( arg >= (unsigned)sysFunction->parameterTypes.GetLength() )
return 0;
if( flags )
{
*flags = sysFunction->inOutFlags[arg];
*flags |= sysFunction->parameterTypes[arg].IsReadOnly() ? asTM_CONST : 0;
}
asCDataType *dt = &sysFunction->parameterTypes[arg];
if( dt->GetTokenType() != ttQuestion )
return engine->GetTypeIdFromDataType(*dt);
else
{
int offset = 0;
for( asUINT n = 0; n < arg; n++ )
offset += sysFunction->parameterTypes[n].GetSizeOnStackDWords();
// Skip the actual value to get to the type id
offset += AS_PTR_SIZE;
// Get the value
return stackPointer[offset];
}
}
// interface
int asCGeneric::SetReturnByte(asBYTE val)
{
// Verify the type of the return value
if( (sysFunction->returnType.IsObject() || sysFunction->returnType.IsFuncdef()) || sysFunction->returnType.IsReference() )
return asINVALID_TYPE;
if( sysFunction->returnType.GetSizeInMemoryBytes() != 1 )
return asINVALID_TYPE;
// Store the value
*(asBYTE*)&returnVal = val;
return 0;
}
// interface
int asCGeneric::SetReturnWord(asWORD val)
{
// Verify the type of the return value
if( (sysFunction->returnType.IsObject() || sysFunction->returnType.IsFuncdef()) || sysFunction->returnType.IsReference() )
return asINVALID_TYPE;
if( sysFunction->returnType.GetSizeInMemoryBytes() != 2 )
return asINVALID_TYPE;
// Store the value
*(asWORD*)&returnVal = val;
return 0;
}
// interface
int asCGeneric::SetReturnDWord(asDWORD val)
{
// Verify the type of the return value
if( (sysFunction->returnType.IsObject() || sysFunction->returnType.IsFuncdef()) || sysFunction->returnType.IsReference() )
return asINVALID_TYPE;
if( sysFunction->returnType.GetSizeInMemoryBytes() != 4 )
return asINVALID_TYPE;
// Store the value
*(asDWORD*)&returnVal = val;
return 0;
}
// interface
int asCGeneric::SetReturnQWord(asQWORD val)
{
// Verify the type of the return value
if( (sysFunction->returnType.IsObject() || sysFunction->returnType.IsFuncdef()) || sysFunction->returnType.IsReference() )
return asINVALID_TYPE;
if( sysFunction->returnType.GetSizeOnStackDWords() != 2 )
return asINVALID_TYPE;
// Store the value
returnVal = val;
return 0;
}
// interface
int asCGeneric::SetReturnFloat(float val)
{
// Verify the type of the return value
if( (sysFunction->returnType.IsObject() || sysFunction->returnType.IsFuncdef()) || sysFunction->returnType.IsReference() )
return asINVALID_TYPE;
if( sysFunction->returnType.GetSizeOnStackDWords() != 1 )
return asINVALID_TYPE;
// Store the value
*(float*)&returnVal = val;
return 0;
}
// interface
int asCGeneric::SetReturnDouble(double val)
{
// Verify the type of the return value
if( (sysFunction->returnType.IsObject() || sysFunction->returnType.IsFuncdef()) || sysFunction->returnType.IsReference() )
return asINVALID_TYPE;
if( sysFunction->returnType.GetSizeOnStackDWords() != 2 )
return asINVALID_TYPE;
// Store the value
*(double*)&returnVal = val;
return 0;
}
// interface
int asCGeneric::SetReturnAddress(void *val)
{
// Verify the type of the return value
if( sysFunction->returnType.IsReference() )
{
// Store the value
*(void**)&returnVal = val;
return 0;
}
else if( sysFunction->returnType.IsObjectHandle() )
{
// Store the handle without increasing reference
objectRegister = val;
return 0;
}
return asINVALID_TYPE;
}
// interface
int asCGeneric::SetReturnObject(void *obj)
{
asCDataType *dt = &sysFunction->returnType;
if( !dt->IsObject() && !dt->IsFuncdef() )
return asINVALID_TYPE;
if( dt->IsReference() )
{
*(void**)&returnVal = obj;
return 0;
}
if( dt->IsObjectHandle() )
{
// Increase the reference counter
if (dt->IsFuncdef())
{
if (obj)
reinterpret_cast<asIScriptFunction*>(obj)->AddRef();
}
else
{
asSTypeBehaviour *beh = &CastToObjectType(dt->GetTypeInfo())->beh;
if (obj && beh && beh->addref)
engine->CallObjectMethod(obj, beh->addref);
}
}
else
{
// If function returns object by value the memory is already allocated.
// Here we should just initialize that memory by calling the copy constructor
// or the default constructor followed by the assignment operator
void *mem = (void*)*(asPWORD*)&stackPointer[-AS_PTR_SIZE];
engine->ConstructScriptObjectCopy(mem, obj, CastToObjectType(dt->GetTypeInfo()));
return 0;
}
objectRegister = obj;
return 0;
}
// internal
void *asCGeneric::GetReturnPointer()
{
asCDataType &dt = sysFunction->returnType;
if( (dt.IsObject() ||dt.IsFuncdef()) && !dt.IsReference() )
{
// This function doesn't support returning on the stack but the use of
// the function doesn't require it so we don't need to implement it here.
asASSERT( !sysFunction->DoesReturnOnStack() );
return &objectRegister;
}
return &returnVal;
}
// interface
void *asCGeneric::GetAddressOfReturnLocation()
{
asCDataType &dt = sysFunction->returnType;
if( (dt.IsObject() || dt.IsFuncdef()) && !dt.IsReference() )
{
if( sysFunction->DoesReturnOnStack() )
{
// The memory is already preallocated on the stack,
// and the pointer to the location is found before the first arg
return (void*)*(asPWORD*)&stackPointer[-AS_PTR_SIZE];
}
// Reference types store the handle in the objectReference
return &objectRegister;
}
// Primitive types and references are stored in the returnVal property
return &returnVal;
}
// interface
int asCGeneric::GetReturnTypeId(asDWORD *flags) const
{
return sysFunction->GetReturnTypeId(flags);
}
END_AS_NAMESPACE

View File

@@ -0,0 +1,108 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_generic.h
//
// This class handles the call to a function registered with asCALL_GENERIC
//
#ifndef AS_GENERIC_H
#define AS_GENERIC_H
#include "as_config.h"
BEGIN_AS_NAMESPACE
class asCScriptEngine;
class asCScriptFunction;
class asCGeneric : public asIScriptGeneric
{
public:
//------------------------------
// asIScriptGeneric
//------------------------------
// Miscellaneous
asIScriptEngine *GetEngine() const;
asIScriptFunction *GetFunction() const;
void *GetAuxiliary() const;
// Object
void *GetObject();
int GetObjectTypeId() const;
// Arguments
int GetArgCount() const;
int GetArgTypeId(asUINT arg, asDWORD *flags = 0) const;
asBYTE GetArgByte(asUINT arg);
asWORD GetArgWord(asUINT arg);
asDWORD GetArgDWord(asUINT arg);
asQWORD GetArgQWord(asUINT arg);
float GetArgFloat(asUINT arg);
double GetArgDouble(asUINT arg);
void *GetArgAddress(asUINT arg);
void *GetArgObject(asUINT arg);
void *GetAddressOfArg(asUINT arg);
// Return value
int GetReturnTypeId(asDWORD *flags = 0) const;
int SetReturnByte(asBYTE val);
int SetReturnWord(asWORD val);
int SetReturnDWord(asDWORD val);
int SetReturnQWord(asQWORD val);
int SetReturnFloat(float val);
int SetReturnDouble(double val);
int SetReturnAddress(void *addr);
int SetReturnObject(void *obj);
void *GetAddressOfReturnLocation();
//------------------------
// internal
//-------------------------
asCGeneric(asCScriptEngine *engine, asCScriptFunction *sysFunction, void *currentObject, asDWORD *stackPointer);
virtual ~asCGeneric();
void *GetReturnPointer();
asCScriptEngine *engine;
asCScriptFunction *sysFunction;
void *currentObject;
asDWORD *stackPointer;
void *objectRegister;
asQWORD returnVal;
};
END_AS_NAMESPACE
#endif

View File

@@ -0,0 +1,137 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
#include "as_config.h"
#include "as_property.h"
#include "as_scriptengine.h"
BEGIN_AS_NAMESPACE
asCGlobalProperty::asCGlobalProperty()
{
memory = &storage;
memoryAllocated = false;
realAddress = 0;
initFunc = 0;
accessMask = 0xFFFFFFFF;
refCount.set(1);
}
asCGlobalProperty::~asCGlobalProperty()
{
#ifndef WIP_16BYTE_ALIGNED
if( memoryAllocated ) { asDELETEARRAY(memory); }
#else
if( memoryAllocated ) { asDELETEARRAYALIGNED(memory); }
#endif
if( initFunc )
initFunc->ReleaseInternal();
}
void asCGlobalProperty::AddRef()
{
refCount.atomicInc();
}
void asCGlobalProperty::Release()
{
if( refCount.atomicDec() == 0 )
asDELETE(this, asCGlobalProperty);
}
void asCGlobalProperty::DestroyInternal()
{
if( initFunc )
{
initFunc->ReleaseInternal();
initFunc = 0;
}
}
void *asCGlobalProperty::GetAddressOfValue()
{
return memory;
}
// The global property structure is responsible for allocating the storage
// method for script declared variables. Each allocation is independent of
// other global properties, so that variables can be added and removed at
// any time.
void asCGlobalProperty::AllocateMemory()
{
if( type.GetSizeOnStackDWords() > 2 )
{
#ifndef WIP_16BYTE_ALIGNED
memory = asNEWARRAY(asDWORD, type.GetSizeOnStackDWords());
#else
// TODO: Avoid aligned allocation if not needed to reduce the waste of memory for the alignment
memory = asNEWARRAYALIGNED(asDWORD, type.GetSizeOnStackDWords(), type.GetAlignment());
#endif
memoryAllocated = true;
}
}
void asCGlobalProperty::SetRegisteredAddress(void *p)
{
realAddress = p;
if( type.IsObject() && !type.IsReference() && !type.IsObjectHandle() )
{
// The global property is a pointer to a pointer
memory = &realAddress;
}
else
memory = p;
}
void *asCGlobalProperty::GetRegisteredAddress() const
{
return realAddress;
}
void asCGlobalProperty::SetInitFunc(asCScriptFunction *in_initFunc)
{
// This should only be done once
asASSERT( initFunc == 0 );
initFunc = in_initFunc;
initFunc->AddRefInternal();
}
asCScriptFunction *asCGlobalProperty::GetInitFunc()
{
return initFunc;
}
END_AS_NAMESPACE

786
angelscript/source/as_map.h Normal file
View File

@@ -0,0 +1,786 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2013 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_map.h
//
// This class is used for mapping a value to another
//
#ifndef AS_MAP_H
#define AS_MAP_H
template <class KEY, class VAL> struct asSMapNode;
template <class KEY, class VAL> class asCMap
{
public:
asCMap();
~asCMap();
int Insert(const KEY &key, const VAL &value);
int Insert(asSMapNode<KEY,VAL> *node);
int GetCount() const;
const KEY &GetKey(const asSMapNode<KEY,VAL> *cursor) const;
const VAL &GetValue(const asSMapNode<KEY,VAL> *cursor) const;
VAL &GetValue(asSMapNode<KEY,VAL> *cursor);
void Erase(asSMapNode<KEY,VAL> *cursor);
asSMapNode<KEY,VAL> *Remove(asSMapNode<KEY,VAL> *cursor);
void EraseAll();
void SwapWith(asCMap<KEY,VAL> &other);
// Returns true as long as cursor is valid
bool MoveTo(asSMapNode<KEY,VAL> **out, const KEY &key) const;
bool MoveFirst(asSMapNode<KEY,VAL> **out) const;
bool MoveLast(asSMapNode<KEY,VAL> **out) const;
bool MoveNext(asSMapNode<KEY,VAL> **out, asSMapNode<KEY,VAL> *cursor) const;
bool MovePrev(asSMapNode<KEY,VAL> **out, asSMapNode<KEY,VAL> *cursor) const;
// For debugging only
int CheckIntegrity(asSMapNode<KEY,VAL> *node) const;
protected:
// Don't allow value assignment
asCMap &operator=(const asCMap &) { return *this; }
void BalanceInsert(asSMapNode<KEY,VAL> *node);
void BalanceErase(asSMapNode<KEY,VAL> *child, asSMapNode<KEY,VAL> *parent);
int EraseAll(asSMapNode<KEY,VAL> *node);
int RotateLeft(asSMapNode<KEY,VAL> *node);
int RotateRight(asSMapNode<KEY,VAL> *node);
asSMapNode<KEY,VAL> *root;
asSMapNode<KEY,VAL> dummy;
int count;
};
//---------------------------------------------------------------------------
// Implementation
// Properties of a Red-Black Tree
//
// 1. The root is always black
// 2. All single paths from the root to leafs
// contain the same amount of black nodes
// 3. No red node can have a red node as parent
#define ISRED(x) ((x != 0) && (x)->isRed)
#define ISBLACK(x) (!ISRED(x))
template <class KEY, class VAL> struct asSMapNode
{
asSMapNode() {parent = 0; left = 0; right = 0; isRed = true;}
void Init(KEY k, VAL v) {key = k; value = v; parent = 0; left = 0; right = 0; isRed = true;}
asSMapNode *parent;
asSMapNode *left;
asSMapNode *right;
bool isRed;
KEY key;
VAL value;
};
template <class KEY, class VAL>
asCMap<KEY, VAL>::asCMap()
{
root = 0;
count = 0;
}
template <class KEY, class VAL>
asCMap<KEY, VAL>::~asCMap()
{
EraseAll();
}
template <class KEY, class VAL>
void asCMap<KEY,VAL>::SwapWith(asCMap<KEY,VAL> &other)
{
asSMapNode<KEY,VAL> *tmpRoot = root;
int tmpCount = count;
root = other.root;
count = other.count;
other.root = tmpRoot;
other.count = tmpCount;
}
template <class KEY, class VAL>
void asCMap<KEY, VAL>::EraseAll()
{
EraseAll(root);
root = 0;
}
template <class KEY, class VAL>
int asCMap<KEY, VAL>::EraseAll(asSMapNode<KEY, VAL> *p)
{
if( p == 0 ) return -1;
EraseAll( p->left );
EraseAll( p->right );
typedef asSMapNode<KEY,VAL> node_t;
asDELETE(p,node_t);
count--;
return 0;
}
template <class KEY, class VAL>
int asCMap<KEY, VAL>::GetCount() const
{
return count;
}
template <class KEY, class VAL>
int asCMap<KEY, VAL>::Insert(const KEY &key, const VAL &value)
{
typedef asSMapNode<KEY,VAL> node_t;
asSMapNode<KEY,VAL> *nnode = asNEW(node_t);
if( nnode == 0 )
{
// Out of memory
return -1;
}
nnode->key = key;
nnode->value = value;
return Insert(nnode);
}
template <class KEY, class VAL>
int asCMap<KEY, VAL>::Insert(asSMapNode<KEY,VAL> *nnode)
{
// Insert the node
if( root == 0 )
root = nnode;
else
{
asSMapNode<KEY,VAL> *p = root;
for(;;)
{
if( nnode->key < p->key )
{
if( p->left == 0 )
{
nnode->parent = p;
p->left = nnode;
break;
}
else
p = p->left;
}
else
{
if( p->right == 0 )
{
nnode->parent = p;
p->right = nnode;
break;
}
else
p = p->right;
}
}
}
BalanceInsert(nnode);
count++;
return 0;
}
template <class KEY, class VAL>
void asCMap<KEY, VAL>::BalanceInsert(asSMapNode<KEY, VAL> *node)
{
// The node, that is red, can't have a red parent
while( node != root && node->parent->isRed )
{
// Check color of uncle
if( node->parent == node->parent->parent->left )
{
asSMapNode<KEY,VAL> *uncle = node->parent->parent->right;
if( ISRED(uncle) )
{
// B
// R R
// N
// Change color on parent, uncle, and grand parent
node->parent->isRed = false;
uncle->isRed = false;
node->parent->parent->isRed = true;
// Continue balancing from grand parent
node = node->parent->parent;
}
else
{
// B
// R B
// N
if( node == node->parent->right )
{
// Make the node a left child
node = node->parent;
RotateLeft(node);
}
// Change color on parent and grand parent
// Then rotate grand parent to the right
node->parent->isRed = false;
node->parent->parent->isRed = true;
RotateRight(node->parent->parent);
}
}
else
{
asSMapNode<KEY,VAL> *uncle = node->parent->parent->left;
if( ISRED(uncle) )
{
// B
// R R
// N
// Change color on parent, uncle, and grand parent
// Continue balancing from grand parent
node->parent->isRed = false;
uncle->isRed = false;
node = node->parent->parent;
node->isRed = true;
}
else
{
// B
// B R
// N
if( node == node->parent->left )
{
// Make the node a right child
node = node->parent;
RotateRight(node);
}
// Change color on parent and grand parent
// Then rotate grand parent to the right
node->parent->isRed = false;
node->parent->parent->isRed = true;
RotateLeft(node->parent->parent);
}
}
}
root->isRed = false;
}
// For debugging purposes only
template <class KEY, class VAL>
int asCMap<KEY, VAL>::CheckIntegrity(asSMapNode<KEY, VAL> *node) const
{
if( node == 0 )
{
if( root == 0 )
return 0;
else if( ISRED(root) )
return -1;
else
node = root;
}
int left = 0, right = 0;
if( node->left )
left = CheckIntegrity(node->left);
if( node->right )
right = CheckIntegrity(node->right);
if( left != right || left == -1 )
return -1;
if( ISBLACK(node) )
return left+1;
return left;
}
// Returns true if successful
template <class KEY, class VAL>
bool asCMap<KEY, VAL>::MoveTo(asSMapNode<KEY,VAL> **out, const KEY &key) const
{
asSMapNode<KEY,VAL> *p = root;
while( p )
{
if( key < p->key )
p = p->left;
else if( key == p->key )
{
if( out ) *out = p;
return true;
}
else
p = p->right;
}
if( out ) *out = 0;
return false;
}
template <class KEY, class VAL>
void asCMap<KEY, VAL>::Erase(asSMapNode<KEY,VAL> *cursor)
{
asSMapNode<KEY,VAL> *node = Remove(cursor);
asASSERT( node == cursor );
typedef asSMapNode<KEY,VAL> node_t;
asDELETE(node,node_t);
}
template <class KEY, class VAL>
asSMapNode<KEY,VAL> *asCMap<KEY, VAL>::Remove(asSMapNode<KEY,VAL> *cursor)
{
if( cursor == 0 ) return 0;
asSMapNode<KEY,VAL> *node = cursor;
//---------------------------------------------------
// Choose the node that will replace the erased one
asSMapNode<KEY,VAL> *remove;
if( node->left == 0 || node->right == 0 )
remove = node;
else
{
remove = node->right;
while( remove->left ) remove = remove->left;
}
//--------------------------------------------------
// Remove the node
asSMapNode<KEY,VAL> *child;
if( remove->left )
child = remove->left;
else
child = remove->right;
if( child ) child->parent = remove->parent;
if( remove->parent )
{
if( remove == remove->parent->left )
remove->parent->left = child;
else
remove->parent->right = child;
}
else
root = child;
// If we remove a black node we must make sure the tree is balanced
if( ISBLACK(remove) )
BalanceErase(child, remove->parent);
//----------------------------------------
// Replace the erased node with the removed one
if( remove != node )
{
if( node->parent )
{
if( node->parent->left == node )
node->parent->left = remove;
else
node->parent->right = remove;
}
else
root = remove;
remove->isRed = node->isRed;
remove->parent = node->parent;
remove->left = node->left;
if( remove->left ) remove->left->parent = remove;
remove->right = node->right;
if( remove->right ) remove->right->parent = remove;
}
count--;
return node;
}
// Call method only if removed node was black
// child is the child of the removed node
template <class KEY, class VAL>
void asCMap<KEY, VAL>::BalanceErase(asSMapNode<KEY, VAL> *child, asSMapNode<KEY, VAL> *parent)
{
// If child is red
// Color child black
// Terminate
// These tests assume brother is to the right.
// 1. Brother is red
// Color parent red and brother black
// Rotate parent left
// Transforms to 2b
// 2a. Parent and brother is black, brother's children are black
// Color brother red
// Continue test with parent as child
// 2b. Parent is red, brother is black, brother's children are black
// Color parent black and brother red
// Terminate
// 3. Brother is black, and brother's left is red and brother's right is black
// Color brother red and brother's left black
// Rotate brother to right
// Transforms to 4.
// 4. Brother is black, brother's right is red
// Color brother's right black
// Color brother to color of parent
// Color parent black
// Rotate parent left
// Terminate
while( child != root && ISBLACK(child) )
{
if( child == parent->left )
{
asSMapNode<KEY,VAL> *brother = parent->right;
// Case 1
if( ISRED(brother) )
{
brother->isRed = false;
parent->isRed = true;
RotateLeft(parent);
brother = parent->right;
}
// Case 2
if( brother == 0 ) break;
if( ISBLACK(brother->left) && ISBLACK(brother->right) )
{
// Case 2b
if( ISRED(parent) )
{
parent->isRed = false;
brother->isRed = true;
break;
}
brother->isRed = true;
child = parent;
parent = child->parent;
}
else
{
// Case 3
if( ISBLACK(brother->right) )
{
brother->left->isRed = false;
brother->isRed = true;
RotateRight(brother);
brother = parent->right;
}
// Case 4
brother->isRed = parent->isRed;
parent->isRed = false;
brother->right->isRed = false;
RotateLeft(parent);
break;
}
}
else
{
asSMapNode<KEY,VAL> *brother = parent->left;
// Case 1
if( ISRED(brother) )
{
brother->isRed = false;
parent->isRed = true;
RotateRight(parent);
brother = parent->left;
}
// Case 2
if( brother == 0 ) break;
if( ISBLACK(brother->left) && ISBLACK(brother->right) )
{
// Case 2b
if( ISRED(parent) )
{
parent->isRed = false;
brother->isRed = true;
break;
}
brother->isRed = true;
child = parent;
parent = child->parent;
}
else
{
// Case 3
if( ISBLACK(brother->left) )
{
brother->right->isRed = false;
brother->isRed = true;
RotateLeft(brother);
brother = parent->left;
}
// Case 4
brother->isRed = parent->isRed;
parent->isRed = false;
brother->left->isRed = false;
RotateRight(parent);
break;
}
}
}
if( child )
child->isRed = false;
}
template <class KEY, class VAL>
int asCMap<KEY, VAL>::RotateRight(asSMapNode<KEY, VAL> *node)
{
// P L //
// / \ / \ //
// L R => Ll P //
// / \ / \ //
// Ll Lr Lr R //
if( node->left == 0 ) return -1;
asSMapNode<KEY,VAL> *left = node->left;
// Update parent
if( node->parent )
{
asSMapNode<KEY,VAL> *parent = node->parent;
if( parent->left == node )
parent->left = left;
else
parent->right = left;
left->parent = parent;
}
else
{
root = left;
left->parent = 0;
}
// Move left's right child to node's left child
node->left = left->right;
if( node->left ) node->left->parent = node;
// Put node as left's right child
left->right = node;
node->parent = left;
return 0;
}
template <class KEY, class VAL>
int asCMap<KEY, VAL>::RotateLeft(asSMapNode<KEY, VAL> *node)
{
// P R //
// / \ / \ //
// L R => P Rr //
// / \ / \ //
// Rl Rr L Rl //
if( node->right == 0 ) return -1;
asSMapNode<KEY,VAL> *right = node->right;
// Update parent
if( node->parent )
{
asSMapNode<KEY,VAL> *parent = node->parent;
if( parent->right == node )
parent->right = right;
else
parent->left = right;
right->parent = parent;
}
else
{
root = right;
right->parent = 0;
}
// Move right's left child to node's right child
node->right = right->left;
if( node->right ) node->right->parent = node;
// Put node as right's left child
right->left = node;
node->parent = right;
return 0;
}
template <class KEY, class VAL>
const VAL &asCMap<KEY, VAL>::GetValue(const asSMapNode<KEY,VAL> *cursor) const
{
if( cursor == 0 )
return dummy.value;
return cursor->value;
}
template <class KEY, class VAL>
VAL &asCMap<KEY, VAL>::GetValue(asSMapNode<KEY,VAL> *cursor)
{
if( cursor == 0 )
return dummy.value;
return cursor->value;
}
template <class KEY, class VAL>
const KEY &asCMap<KEY, VAL>::GetKey(const asSMapNode<KEY,VAL> *cursor) const
{
if( cursor == 0 )
return dummy.key;
return cursor->key;
}
template <class KEY, class VAL>
bool asCMap<KEY, VAL>::MoveFirst(asSMapNode<KEY,VAL> **out) const
{
*out = root;
if( root == 0 ) return false;
while( (*out)->left )
*out = (*out)->left;
return true;
}
template <class KEY, class VAL>
bool asCMap<KEY, VAL>::MoveLast(asSMapNode<KEY,VAL> **out) const
{
*out = root;
if( root == 0 ) return false;
while( (*out)->right )
*out = (*out)->right;
return true;
}
template <class KEY, class VAL>
bool asCMap<KEY, VAL>::MoveNext(asSMapNode<KEY,VAL> **out, asSMapNode<KEY,VAL> *cursor) const
{
if( cursor == 0 )
{
*out = 0;
return false;
}
if( cursor->right == 0 )
{
// Move upwards until we find a parent node to the right
while( cursor->parent && cursor->parent->right == cursor )
cursor = cursor->parent;
cursor = cursor->parent;
*out = cursor;
if( cursor == 0 )
return false;
return true;
}
cursor = cursor->right;
while( cursor->left )
cursor = cursor->left;
*out = cursor;
return true;
}
template <class KEY, class VAL>
bool asCMap<KEY, VAL>::MovePrev(asSMapNode<KEY,VAL> **out, asSMapNode<KEY,VAL> *cursor) const
{
if( cursor == 0 )
{
*out = 0;
return false;
}
if( cursor->left == 0 )
{
// Move upwards until we find a parent node to the left
while( cursor->parent && cursor->parent->left == cursor )
cursor = cursor->parent;
cursor = cursor->parent;
*out = cursor;
if( cursor == 0 )
return false;
return true;
}
cursor = cursor->left;
while( cursor->right )
cursor = cursor->right;
*out = cursor;
return true;
}
#endif

View File

@@ -0,0 +1,288 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2020 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_memory.cpp
//
// Overload the default memory management functions so that we
// can let the application decide how to do it.
//
#include <stdlib.h>
#if !defined(__APPLE__) && !defined(__SNC__) && !defined(__ghs__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__DragonFly__)
#include <malloc.h>
#endif
#include "as_config.h"
#include "as_memory.h"
#include "as_scriptnode.h"
#include "as_bytecode.h"
BEGIN_AS_NAMESPACE
#ifdef WIP_16BYTE_ALIGN
// TODO: Add support for 16byte aligned application types (e.g. __m128). The following is a list of things that needs to be implemented:
//
// ok - The script context must make sure to always allocate the local stack memory buffer on 16byte aligned boundaries (asCContext::ReserveStackSpace)
// ok - The engine must make sure to always allocate the memory for the script objects on 16byte aligned boundaries (asCScriptEngine::CallAlloc)
// ok - The application needs to inform a new flag when registering types that require 16byte alignment, e.g. asOBJ_APP_ALIGN16 (asCScriptEngine::RegisterObjectType)
// ok - The script object type must make sure to align member properties of these types correctly (asCObjectType::AddPropertyToClass)
// ok - Script global properties must allocate memory on 16byte boundaries if holding these types (asCGlobalProperty::AllocateMemory)
// TODO - The script compiler must make sure to allocate the local variables on 16byte boundaries (asCCompiler::AllocateVariable)
// TODO - The script compiler must add pad bytes on the stack for all function calls to guarantee that the stack position is 16byte aligned on entry in the called function (asCCompiler)
// TODO - The bytecode serializer must be capable of adjusting these pad bytes to guarantee platform independent saved bytecode. Remember that the registered type may not be 16byte aligned on all platforms (asCWriter & asCReader)
// TODO - The bytecode serializer must also be prepared to adjust the position of the local variables according to the need fro 16byte alignment (asCWriter & asCReader)
// TODO - The code for the native calling conventions must be adjusted for all platforms that should support 16byte aligned types (as_callfunc...)
// ok - When the context needs to grow the local stack memory it must copy the function arguments so that the stack entry position is 16byte aligned (asCContext::CallScriptFunction)
// TODO - When the context is prepared for a new call, it must set the initial stack position so the stack entry position is 16byte aligned (asCContext::Prepare)
//
// http://www.gamedev.net/topic/650555-alignment-requirements/
// TODO: Allow user to register its own aligned memory routines
// Wrappers for aligned allocations
void *debugAlignedMalloc(size_t size, size_t align, const char *file, int line)
{
void *mem = ((asALLOCFUNCDEBUG_t)userAlloc)(size + (align-1) + sizeof(void*), file, line);
char *amem = ((char*)mem) + sizeof(void*);
if( (uintptr_t)amem & (align - 1) )
amem += align - ((uintptr_t)amem & (align - 1));
((void**)amem)[-1] = mem;
return amem;
}
void *alignedMalloc(size_t size, size_t align)
{
void *mem = userAlloc(size + (align-1) + sizeof(void*));
char *amem = ((char*)mem) + sizeof(void*);
if( (uintptr_t)amem & (align - 1) )
amem += align - ((uintptr_t)amem & (align - 1));
((void**)amem)[-1] = mem;
return amem;
}
void alignedFree(void *mem)
{
userFree( ((void**)mem)[-1] );
}
bool isAligned(const void* const pointer, asUINT alignment)
{
return (uintptr_t(pointer) % alignment) == 0;
}
#endif
// By default we'll use the standard memory management functions
// Make sure these globals are initialized first. Otherwise the
// library may crash in case the application initializes the engine
// as a global variable.
#ifdef _MSC_VER
// MSVC let's us choose between a couple of different initialization orders.
#pragma warning(disable: 4073)
#pragma init_seg(lib)
asALLOCFUNC_t userAlloc = malloc;
asFREEFUNC_t userFree = free;
#ifdef WIP_16BYTE_ALIGN
#ifdef AS_DEBUG
asALLOCALIGNEDFUNC_t userAllocAligned = (asALLOCALIGNEDFUNC_t)debugAlignedMalloc;
#else
asALLOCALIGNEDFUNC_t userAllocAligned = alignedMalloc;
#endif
asFREEALIGNEDFUNC_t userFreeAligned = alignedFree;
#endif
#else
// Other compilers will just have to rely on luck.
asALLOCFUNC_t userAlloc = malloc;
asFREEFUNC_t userFree = free;
#ifdef WIP_16BYTE_ALIGN
asALLOCALIGNEDFUNC_t userAllocAligned = alignedMalloc;
asFREEALIGNEDFUNC_t userFreeAligned = alignedFree;
#endif
#endif
extern "C"
{
// interface
int asSetGlobalMemoryFunctions(asALLOCFUNC_t allocFunc, asFREEFUNC_t freeFunc)
{
// Clean-up thread local memory before changing the allocation routines to avoid
// potential problem with trying to free memory using a different allocation
// routine than used when allocating it.
asThreadCleanup();
userAlloc = allocFunc;
userFree = freeFunc;
return 0;
}
// interface
int asResetGlobalMemoryFunctions()
{
// Clean-up thread local memory before changing the allocation routines to avoid
// potential problem with trying to free memory using a different allocation
// routine than used when allocating it.
asThreadCleanup();
userAlloc = malloc;
userFree = free;
return 0;
}
// interface
void *asAllocMem(size_t size)
{
return asNEWARRAY(asBYTE, size);
}
// interface
void asFreeMem(void *mem)
{
asDELETEARRAY(mem);
}
} // extern "C"
asCMemoryMgr::asCMemoryMgr()
{
}
asCMemoryMgr::~asCMemoryMgr()
{
FreeUnusedMemory();
}
void asCMemoryMgr::FreeUnusedMemory()
{
// It's necessary to protect the scriptNodePool from multiple
// simultaneous accesses, as the parser is used by several methods
// that can be executed simultaneously.
ENTERCRITICALSECTION(cs);
int n;
for( n = 0; n < (signed)scriptNodePool.GetLength(); n++ )
userFree(scriptNodePool[n]);
scriptNodePool.Allocate(0, false);
LEAVECRITICALSECTION(cs);
// The engine already protects against multiple threads
// compiling scripts simultaneously so this pool doesn't have
// to be protected again.
for( n = 0; n < (signed)byteInstructionPool.GetLength(); n++ )
userFree(byteInstructionPool[n]);
byteInstructionPool.Allocate(0, false);
}
void *asCMemoryMgr::AllocScriptNode()
{
ENTERCRITICALSECTION(cs);
if( scriptNodePool.GetLength() )
{
void *tRet = scriptNodePool.PopLast();
LEAVECRITICALSECTION(cs);
return tRet;
}
LEAVECRITICALSECTION(cs);
#if defined(AS_DEBUG)
return ((asALLOCFUNCDEBUG_t)(userAlloc))(sizeof(asCScriptNode), __FILE__, __LINE__);
#else
return userAlloc(sizeof(asCScriptNode));
#endif
}
void asCMemoryMgr::FreeScriptNode(void *ptr)
{
ENTERCRITICALSECTION(cs);
// Pre allocate memory for the array to avoid slow growth
if( scriptNodePool.GetLength() == 0 )
scriptNodePool.Allocate(100, 0);
scriptNodePool.PushLast(ptr);
#ifdef AS_DEBUG
// clear the memory to facilitate identification of use after free
memset(ptr, 0xCDCDCDCD, sizeof(asCScriptNode));
#endif
LEAVECRITICALSECTION(cs);
}
#ifndef AS_NO_COMPILER
void *asCMemoryMgr::AllocByteInstruction()
{
// This doesn't need a critical section because, only one compilation is allowed at a time
if( byteInstructionPool.GetLength() )
return byteInstructionPool.PopLast();
#if defined(AS_DEBUG)
return ((asALLOCFUNCDEBUG_t)(userAlloc))(sizeof(asCByteInstruction), __FILE__, __LINE__);
#else
return userAlloc(sizeof(asCByteInstruction));
#endif
}
void asCMemoryMgr::FreeByteInstruction(void *ptr)
{
// Pre allocate memory for the array to avoid slow growth
if( byteInstructionPool.GetLength() == 0 )
byteInstructionPool.Allocate(100, 0);
byteInstructionPool.PushLast(ptr);
#ifdef AS_DEBUG
// clear the memory to facilitate identification of use after free
memset(ptr, 0xCDCDCDCD, sizeof(asCByteInstruction));
#endif
}
#endif // AS_NO_COMPILER
END_AS_NAMESPACE

View File

@@ -0,0 +1,135 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2014 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_memory.h
//
// Overload the default memory management functions so that we
// can let the application decide how to do it.
//
#ifndef AS_MEMORY_H
#define AS_MEMORY_H
#include "as_config.h"
BEGIN_AS_NAMESPACE
extern asALLOCFUNC_t userAlloc;
extern asFREEFUNC_t userFree;
#ifdef WIP_16BYTE_ALIGN
// TODO: This declaration should be in angelscript.h
// when the application can register it's own
// aligned memory routines
typedef void *(*asALLOCALIGNEDFUNC_t)(size_t, size_t);
typedef void (*asFREEALIGNEDFUNC_t)(void *);
extern asALLOCALIGNEDFUNC_t userAllocAligned;
extern asFREEALIGNEDFUNC_t userFreeAligned;
typedef void *(*asALLOCALIGNEDFUNCDEBUG_t)(size_t, size_t, const char *, unsigned int);
// The maximum type alignment supported.
const int MAX_TYPE_ALIGNMENT = 16;
// Utility function used for assertions.
bool isAligned(const void* const pointer, asUINT alignment);
#endif // WIP_16BYTE_ALIGN
// We don't overload the new operator as that would affect the application as well
#ifndef AS_DEBUG
#define asNEW(x) new(userAlloc(sizeof(x))) x
#define asDELETE(ptr,x) {void *tmp = ptr; (ptr)->~x(); userFree(tmp);}
#define asNEWARRAY(x,cnt) (x*)userAlloc(sizeof(x)*cnt)
#define asDELETEARRAY(ptr) userFree(ptr)
#ifdef WIP_16BYTE_ALIGN
#define asNEWARRAYALIGNED(x,cnt, alignment) (x*)userAllocAligned(sizeof(x)*cnt, alignment)
#define asDELETEARRAYALIGNED(ptr) userFreeAligned(ptr)
#endif
#else
typedef void *(*asALLOCFUNCDEBUG_t)(size_t, const char *, unsigned int);
#define asNEW(x) new(((asALLOCFUNCDEBUG_t)(userAlloc))(sizeof(x), __FILE__, __LINE__)) x
#define asDELETE(ptr,x) {void *tmp = ptr; (ptr)->~x(); userFree(tmp);}
#define asNEWARRAY(x,cnt) (x*)((asALLOCFUNCDEBUG_t)(userAlloc))(sizeof(x)*cnt, __FILE__, __LINE__)
#define asDELETEARRAY(ptr) userFree(ptr)
#ifdef WIP_16BYTE_ALIGN
//TODO: Equivalent of debug allocation function with alignment?
#define asNEWARRAYALIGNED(x,cnt, alignment) (x*)userAllocAligned(sizeof(x)*cnt, alignment)
#define asDELETEARRAYALIGNED(ptr) userFreeAligned(ptr)
#endif
#endif
END_AS_NAMESPACE
#include <new>
#include "as_criticalsection.h"
#include "as_array.h"
BEGIN_AS_NAMESPACE
class asCMemoryMgr
{
public:
asCMemoryMgr();
~asCMemoryMgr();
void FreeUnusedMemory();
void *AllocScriptNode();
void FreeScriptNode(void *ptr);
#ifndef AS_NO_COMPILER
void *AllocByteInstruction();
void FreeByteInstruction(void *ptr);
#endif
protected:
DECLARECRITICALSECTION(cs)
asCArray<void *> scriptNodePool;
asCArray<void *> byteInstructionPool;
};
END_AS_NAMESPACE
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,257 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2020 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_module.h
//
// A class that holds a script module
//
#ifndef AS_MODULE_H
#define AS_MODULE_H
#include "as_config.h"
#include "as_symboltable.h"
#include "as_atomic.h"
#include "as_string.h"
#include "as_array.h"
#include "as_datatype.h"
#include "as_scriptfunction.h"
#include "as_property.h"
BEGIN_AS_NAMESPACE
// TODO: import: Remove this when the imported functions are removed
const int FUNC_IMPORTED = 0x40000000;
class asCScriptEngine;
class asCCompiler;
class asCBuilder;
class asCContext;
class asCConfigGroup;
class asCTypedefType;
class asCFuncdefType;
struct asSNameSpace;
struct sBindInfo
{
asCScriptFunction *importedFunctionSignature;
asCString importFromModule;
int boundFunctionId;
};
struct sObjectTypePair
{
asCObjectType *a;
asCObjectType *b;
};
// TODO: import: Remove function imports. When I have implemented function
// pointers the function imports should be deprecated.
// TODO: Need a separate interface for compiling scripts. The asIScriptCompiler
// will have a target module, and will allow the compilation of an entire
// script or just individual functions within the scope of the module
//
// With this separation it will be possible to compile the library without
// the compiler, thus giving a much smaller binary executable.
// TODO: There should be a special compile option that will let the application
// recompile an already compiled script. The compiler should check if no
// destructive changes have been made (changing function signatures, etc)
// then it should simply replace the bytecode within the functions without
// changing the values of existing global properties, etc.
class asCModule : public asIScriptModule
{
//-------------------------------------------
// Public interface
//--------------------------------------------
public:
virtual asIScriptEngine *GetEngine() const;
virtual void SetName(const char *name);
virtual const char *GetName() const;
virtual void Discard();
// Compilation
virtual int AddScriptSection(const char *name, const char *code, size_t codeLength, int lineOffset);
virtual int Build();
virtual int CompileFunction(const char *sectionName, const char *code, int lineOffset, asDWORD reserved, asIScriptFunction **outFunc);
virtual int CompileGlobalVar(const char *sectionName, const char *code, int lineOffset);
virtual asDWORD SetAccessMask(asDWORD accessMask);
virtual int SetDefaultNamespace(const char *nameSpace);
virtual const char *GetDefaultNamespace() const;
// Script functions
virtual asUINT GetFunctionCount() const;
virtual asIScriptFunction *GetFunctionByIndex(asUINT index) const;
virtual asIScriptFunction *GetFunctionByDecl(const char *decl) const;
virtual asIScriptFunction *GetFunctionByName(const char *name) const;
virtual int RemoveFunction(asIScriptFunction *func);
// Script global variables
// TODO: interface: Should be called InitGlobalVars, and should have a bool to reset in case already initialized
virtual int ResetGlobalVars(asIScriptContext *ctx);
virtual asUINT GetGlobalVarCount() const;
virtual int GetGlobalVarIndexByName(const char *name) const;
virtual int GetGlobalVarIndexByDecl(const char *decl) const;
virtual const char *GetGlobalVarDeclaration(asUINT index, bool includeNamespace) const;
virtual int GetGlobalVar(asUINT index, const char **name, const char **nameSpace, int *typeId, bool *isConst) const;
virtual void *GetAddressOfGlobalVar(asUINT index);
virtual int RemoveGlobalVar(asUINT index);
// Type identification
virtual asUINT GetObjectTypeCount() const;
virtual asITypeInfo *GetObjectTypeByIndex(asUINT index) const;
virtual int GetTypeIdByDecl(const char *decl) const;
virtual asITypeInfo *GetTypeInfoByName(const char *name) const;
virtual asITypeInfo *GetTypeInfoByDecl(const char *decl) const;
// Enums
virtual asUINT GetEnumCount() const;
virtual asITypeInfo *GetEnumByIndex(asUINT index) const;
// Typedefs
virtual asUINT GetTypedefCount() const;
virtual asITypeInfo *GetTypedefByIndex(asUINT index) const;
// Dynamic binding between modules
virtual asUINT GetImportedFunctionCount() const;
virtual int GetImportedFunctionIndexByDecl(const char *decl) const;
virtual const char *GetImportedFunctionDeclaration(asUINT importIndex) const;
virtual const char *GetImportedFunctionSourceModule(asUINT importIndex) const;
virtual int BindImportedFunction(asUINT index, asIScriptFunction *func);
virtual int UnbindImportedFunction(asUINT importIndex);
virtual int BindAllImportedFunctions();
virtual int UnbindAllImportedFunctions();
// Bytecode Saving/Loading
virtual int SaveByteCode(asIBinaryStream *out, bool stripDebugInfo) const;
virtual int LoadByteCode(asIBinaryStream *in, bool *wasDebugInfoStripped);
// User data
virtual void *SetUserData(void *data, asPWORD type);
virtual void *GetUserData(asPWORD type) const;
//-----------------------------------------------
// Internal
//-----------------------------------------------
asCModule(const char *name, asCScriptEngine *engine);
~asCModule();
//protected:
friend class asCScriptEngine;
friend class asCBuilder;
friend class asCCompiler;
friend class asCContext;
friend class asCRestore;
void InternalReset();
bool IsEmpty() const;
bool HasExternalReferences(bool shuttingDown);
int CallInit(asIScriptContext *ctx);
void CallExit();
int InitGlobalProp(asCGlobalProperty *prop, asIScriptContext *ctx);
void JITCompile();
#ifndef AS_NO_COMPILER
int AddScriptFunction(int sectionIdx, int declaredAt, int id, const asCString &name, const asCDataType &returnType, const asCArray<asCDataType> &params, const asCArray<asCString> &paramNames, const asCArray<asETypeModifiers> &inOutFlags, const asCArray<asCString *> &defaultArgs, bool isInterface, asCObjectType *objType = 0, bool isGlobalFunction = false, asSFunctionTraits funcTraits = asSFunctionTraits(), asSNameSpace *ns = 0);
int AddScriptFunction(asCScriptFunction *func);
int AddImportedFunction(int id, const asCString &name, const asCDataType &returnType, const asCArray<asCDataType> &params, const asCArray<asETypeModifiers> &inOutFlags, const asCArray<asCString *> &defaultArgs, asSFunctionTraits funcTraits, asSNameSpace *ns, const asCString &moduleName);
int AddFuncDef(const asCString &name, asSNameSpace *ns, asCObjectType *parent);
#endif
int GetNextImportedFunctionId();
asCScriptFunction *GetImportedFunction(int funcId) const;
asCTypeInfo *GetType(const asCString &type, asSNameSpace *ns) const;
asCObjectType *GetObjectType(const char *type, asSNameSpace *ns) const;
asCGlobalProperty *AllocateGlobalProperty(const char *name, const asCDataType &dt, asSNameSpace *ns);
void UninitializeGlobalProp(asCGlobalProperty *prop);
// Adds the class type to the module. The module assumes ownership of the reference without increasing it
void AddClassType(asCObjectType*);
// Adds the enum type to the module. The module assumes ownership of the reference without increasing it
void AddEnumType(asCEnumType*);
// Adds the typedef to the module. The module assumes ownership of the reference without increasing it
void AddTypeDef(asCTypedefType*);
// Adds the funcdef to the module. The module assumes ownership of the reference without increasing it
void AddFuncDef(asCFuncdefType*);
// Replaces an existing funcdef with another (used for shared funcdefs). Doesn't add or release refCounts
void ReplaceFuncDef(asCFuncdefType *oldType, asCFuncdefType *newType);
asCString m_name;
asCScriptEngine *m_engine;
asCBuilder *m_builder;
asCArray<asPWORD> m_userData;
asDWORD m_accessMask;
asSNameSpace *m_defaultNamespace;
// This array holds all functions, class members, factories, etc that were compiled with the module.
// These references hold an internal reference to the function object.
asCArray<asCScriptFunction *> m_scriptFunctions; // increases ref count
// This array holds global functions declared in the module. These references are not counted,
// as the same pointer is always present in the scriptFunctions array too.
asCSymbolTable<asCScriptFunction> m_globalFunctions; // doesn't increase ref count
// This array holds imported functions in the module.
asCArray<sBindInfo *> m_bindInformations; // increases ref count
// This array holds template instance types created for the module's object types
asCArray<asCObjectType*> m_templateInstances; // increases ref count
// This array holds the global variables declared in the script
asCSymbolTable<asCGlobalProperty> m_scriptGlobals; // increases ref count
bool m_isGlobalVarInitialized;
// This array holds class and interface types
asCArray<asCObjectType*> m_classTypes; // increases ref count
// This array holds enum types
asCArray<asCEnumType*> m_enumTypes; // increases ref count
// This array holds typedefs
asCArray<asCTypedefType*> m_typeDefs; // increases ref count
// This array holds the funcdefs declared in the module
asCArray<asCFuncdefType*> m_funcDefs; // increases ref count
// This map contains all the types (also contained in the arrays above) for quick lookup
// TODO: memory: Can we eliminate the arrays above?
asCMap<asSNameSpaceNamePair, asCTypeInfo*> m_typeLookup; // doesn't increase ref count
// This array holds types that have been explicitly declared with 'external'
asCArray<asCTypeInfo*> m_externalTypes; // doesn't increase ref count
// This array holds functions that have been explicitly declared with 'external'
asCArray<asCScriptFunction*> m_externalFunctions; // doesn't increase ref count
};
END_AS_NAMESPACE
#endif

View File

@@ -0,0 +1,77 @@
/*
AngelCode Scripting Library
Copyright (c) 2013-2014 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
#ifndef AS_NAMESPACE_H
#define AS_NAMESPACE_H
#include "as_string.h"
BEGIN_AS_NAMESPACE
struct asSNameSpace
{
asCString name;
// TODO: namespace: A namespace should have access masks. The application should be
// able to restrict specific namespaces from access to specific modules
};
struct asSNameSpaceNamePair
{
const asSNameSpace *ns;
asCString name;
asSNameSpaceNamePair() : ns(0) {}
asSNameSpaceNamePair(const asSNameSpace *_ns, const asCString &_name) : ns(_ns), name(_name) {}
asSNameSpaceNamePair &operator=(const asSNameSpaceNamePair &other)
{
ns = other.ns;
name = other.name;
return *this;
}
bool operator==(const asSNameSpaceNamePair &other) const
{
return (ns == other.ns && name == other.name);
}
bool operator<(const asSNameSpaceNamePair &other) const
{
return (ns < other.ns || (ns == other.ns && name < other.name));
}
};
END_AS_NAMESPACE
#endif

View File

@@ -0,0 +1,707 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2017 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_objecttype.cpp
//
// A class for storing object type information
//
#include <stdio.h>
#include "as_config.h"
#include "as_objecttype.h"
#include "as_configgroup.h"
#include "as_scriptengine.h"
BEGIN_AS_NAMESPACE
asCObjectType::asCObjectType() : asCTypeInfo()
{
derivedFrom = 0;
acceptValueSubType = true;
acceptRefSubType = true;
#ifdef WIP_16BYTE_ALIGN
alignment = 4;
#endif
}
asCObjectType::asCObjectType(asCScriptEngine *in_engine) : asCTypeInfo(in_engine)
{
derivedFrom = 0;
acceptValueSubType = true;
acceptRefSubType = true;
#ifdef WIP_16BYTE_ALIGN
alignment = 4;
#endif
}
// interface
asUINT asCObjectType::GetChildFuncdefCount() const
{
return childFuncDefs.GetLength();
}
// interface
asITypeInfo *asCObjectType::GetChildFuncdef(asUINT index) const
{
if (index >= childFuncDefs.GetLength())
return 0;
return childFuncDefs[index];
}
// internal
void asCObjectType::DestroyInternal()
{
if( engine == 0 ) return;
// Skip this for list patterns as they do not increase the references
if( flags & asOBJ_LIST_PATTERN )
{
// Clear the engine pointer to mark the object type as invalid
engine = 0;
return;
}
// Release the object types held by the templateSubTypes
bool isTemplateInstance = templateSubTypes.GetLength() > 0;
for( asUINT subtypeIndex = 0; subtypeIndex < templateSubTypes.GetLength(); subtypeIndex++ )
{
if( templateSubTypes[subtypeIndex].GetTypeInfo() )
templateSubTypes[subtypeIndex].GetTypeInfo()->ReleaseInternal();
}
templateSubTypes.SetLength(0);
// Clear the child types
for (asUINT n = 0; n < childFuncDefs.GetLength(); n++)
{
asCFuncdefType *func = childFuncDefs[n];
if (func)
{
func->parentClass = 0;
if (isTemplateInstance)
{
// Any child funcdefs that have been created as part of the template
// instantiation must be destroyed too
// TODO: Before destroying the funcdef, make sure no external references to it is held
if (func->externalRefCount.get() == 0)
{
func->DestroyInternal();
engine->RemoveFuncdef(func);
func->module = 0;
func->ReleaseInternal();
}
}
}
}
childFuncDefs.SetLength(0);
if( derivedFrom )
derivedFrom->ReleaseInternal();
derivedFrom = 0;
ReleaseAllProperties();
ReleaseAllFunctions();
CleanUserData();
// Remove the type from the engine
if( typeId != -1 )
engine->RemoveFromTypeIdMap(this);
// Clear the engine pointer to mark the object type as invalid
engine = 0;
}
asCObjectType::~asCObjectType()
{
DestroyInternal();
}
// interface
bool asCObjectType::Implements(const asITypeInfo *objType) const
{
if( this == objType )
return true;
for( asUINT n = 0; n < interfaces.GetLength(); n++ )
if( interfaces[n] == objType ) return true;
return false;
}
// interface
bool asCObjectType::DerivesFrom(const asITypeInfo *objType) const
{
if( this == objType )
return true;
asCObjectType *base = derivedFrom;
while( base )
{
if( base == objType )
return true;
base = base->derivedFrom;
}
return false;
}
// interface
int asCObjectType::GetSubTypeId(asUINT subtypeIndex) const
{
// This method is only supported for templates and template specializations
if( templateSubTypes.GetLength() == 0 )
return asERROR;
if( subtypeIndex >= templateSubTypes.GetLength() )
return asINVALID_ARG;
return engine->GetTypeIdFromDataType(templateSubTypes[subtypeIndex]);
}
// interface
asITypeInfo *asCObjectType::GetSubType(asUINT subtypeIndex) const
{
if( subtypeIndex >= templateSubTypes.GetLength() )
return 0;
return templateSubTypes[subtypeIndex].GetTypeInfo();
}
asUINT asCObjectType::GetSubTypeCount() const
{
return asUINT(templateSubTypes.GetLength());
}
asUINT asCObjectType::GetInterfaceCount() const
{
return asUINT(interfaces.GetLength());
}
asITypeInfo *asCObjectType::GetInterface(asUINT index) const
{
return interfaces[index];
}
// internal
bool asCObjectType::IsInterface() const
{
if( (flags & asOBJ_SCRIPT_OBJECT) && size == 0 )
return true;
return false;
}
// interface
asUINT asCObjectType::GetFactoryCount() const
{
return (asUINT)beh.factories.GetLength();
}
// interface
asIScriptFunction *asCObjectType::GetFactoryByIndex(asUINT index) const
{
if( index >= beh.factories.GetLength() )
return 0;
return engine->GetFunctionById(beh.factories[index]);
}
// interface
asIScriptFunction *asCObjectType::GetFactoryByDecl(const char *decl) const
{
if( beh.factories.GetLength() == 0 )
return 0;
// Let the engine parse the string and find the appropriate factory function
return engine->GetFunctionById(engine->GetFactoryIdByDecl(this, decl));
}
// interface
asUINT asCObjectType::GetMethodCount() const
{
return (asUINT)methods.GetLength();
}
// interface
asIScriptFunction *asCObjectType::GetMethodByIndex(asUINT index, bool getVirtual) const
{
if( index >= methods.GetLength() )
return 0;
asCScriptFunction *func = engine->scriptFunctions[methods[index]];
if( !getVirtual )
{
if( func && func->funcType == asFUNC_VIRTUAL )
return virtualFunctionTable[func->vfTableIdx];
}
return func;
}
// interface
asIScriptFunction *asCObjectType::GetMethodByName(const char *in_name, bool in_getVirtual) const
{
int id = -1;
for( asUINT n = 0; n < methods.GetLength(); n++ )
{
if( engine->scriptFunctions[methods[n]]->name == in_name )
{
if( id == -1 )
id = methods[n];
else
return 0;
}
}
if( id == -1 ) return 0;
asCScriptFunction *func = engine->scriptFunctions[id];
if( !in_getVirtual )
{
if( func && func->funcType == asFUNC_VIRTUAL )
return virtualFunctionTable[func->vfTableIdx];
}
return func;
}
// interface
asIScriptFunction *asCObjectType::GetMethodByDecl(const char *decl, bool getVirtual) const
{
if( methods.GetLength() == 0 )
return 0;
// Get the module from one of the methods, but it will only be
// used to allow the parsing of types not already known by the object.
// It is possible for object types to be orphaned, e.g. by discarding
// the module that created it. In this case it is still possible to
// find the methods, but any type not known by the object will result in
// an invalid declaration.
asCModule *mod = engine->scriptFunctions[methods[0]]->module;
int id = engine->GetMethodIdByDecl(this, decl, mod);
if( id <= 0 )
return 0;
if( !getVirtual )
{
asCScriptFunction *func = engine->scriptFunctions[id];
if( func && func->funcType == asFUNC_VIRTUAL )
return virtualFunctionTable[func->vfTableIdx];
}
return engine->scriptFunctions[id];
}
// interface
asUINT asCObjectType::GetPropertyCount() const
{
return (asUINT)properties.GetLength();
}
// interface
int asCObjectType::GetProperty(asUINT index, const char **out_name, int *out_typeId, bool *out_isPrivate, bool *out_isProtected, int *out_offset, bool *out_isReference, asDWORD *out_accessMask, int *out_compositeOffset, bool *out_isCompositeIndirect) const
{
if( index >= properties.GetLength() )
return asINVALID_ARG;
asCObjectProperty *prop = properties[index];
if( out_name )
*out_name = prop->name.AddressOf();
if( out_typeId )
*out_typeId = engine->GetTypeIdFromDataType(prop->type);
if( out_isPrivate )
*out_isPrivate = prop->isPrivate;
if( out_isProtected )
*out_isProtected = prop->isProtected;
if( out_offset )
*out_offset = prop->byteOffset;
if( out_isReference )
*out_isReference = prop->type.IsReference();
if( out_accessMask )
*out_accessMask = prop->accessMask;
if (out_compositeOffset)
*out_compositeOffset = prop->compositeOffset;
if (out_isCompositeIndirect)
*out_isCompositeIndirect = prop->isCompositeIndirect;
return 0;
}
// interface
const char *asCObjectType::GetPropertyDeclaration(asUINT index, bool includeNamespace) const
{
if( index >= properties.GetLength() )
return 0;
asCString *tempString = &asCThreadManager::GetLocalData()->string;
if( properties[index]->isPrivate )
*tempString = "private ";
else if( properties[index]->isProtected )
*tempString = "protected ";
else
*tempString = "";
*tempString += properties[index]->type.Format(nameSpace, includeNamespace);
*tempString += " ";
*tempString += properties[index]->name;
return tempString->AddressOf();
}
asITypeInfo *asCObjectType::GetBaseType() const
{
return derivedFrom;
}
asUINT asCObjectType::GetBehaviourCount() const
{
// Count the number of behaviours (except factory functions)
asUINT count = 0;
if( beh.destruct ) count++;
if( beh.addref ) count++;
if( beh.release ) count++;
if( beh.gcGetRefCount ) count++;
if( beh.gcSetFlag ) count++;
if( beh.gcGetFlag ) count++;
if( beh.gcEnumReferences ) count++;
if( beh.gcReleaseAllReferences ) count++;
if( beh.templateCallback ) count++;
if( beh.listFactory ) count++;
if( beh.getWeakRefFlag ) count++;
// For reference types, the factories are also stored in the constructor
// list, so it is sufficient to enumerate only those
count += (asUINT)beh.constructors.GetLength();
return count;
}
asIScriptFunction *asCObjectType::GetBehaviourByIndex(asUINT index, asEBehaviours *outBehaviour) const
{
// Find the correct behaviour
asUINT count = 0;
if( beh.destruct && count++ == index ) // only increase count if the behaviour is registered
{
if( outBehaviour ) *outBehaviour = asBEHAVE_DESTRUCT;
return engine->scriptFunctions[beh.destruct];
}
if( beh.addref && count++ == index )
{
if( outBehaviour ) *outBehaviour = asBEHAVE_ADDREF;
return engine->scriptFunctions[beh.addref];
}
if( beh.release && count++ == index )
{
if( outBehaviour ) *outBehaviour = asBEHAVE_RELEASE;
return engine->scriptFunctions[beh.release];
}
if( beh.gcGetRefCount && count++ == index )
{
if( outBehaviour ) *outBehaviour = asBEHAVE_GETREFCOUNT;
return engine->scriptFunctions[beh.gcGetRefCount];
}
if( beh.gcSetFlag && count++ == index )
{
if( outBehaviour ) *outBehaviour = asBEHAVE_SETGCFLAG;
return engine->scriptFunctions[beh.gcSetFlag];
}
if( beh.gcGetFlag && count++ == index )
{
if( outBehaviour ) *outBehaviour = asBEHAVE_GETGCFLAG;
return engine->scriptFunctions[beh.gcGetFlag];
}
if( beh.gcEnumReferences && count++ == index )
{
if( outBehaviour ) *outBehaviour = asBEHAVE_ENUMREFS;
return engine->scriptFunctions[beh.gcEnumReferences];
}
if( beh.gcReleaseAllReferences && count++ == index )
{
if( outBehaviour ) *outBehaviour = asBEHAVE_RELEASEREFS;
return engine->scriptFunctions[beh.gcReleaseAllReferences];
}
if( beh.templateCallback && count++ == index )
{
if( outBehaviour ) *outBehaviour = asBEHAVE_TEMPLATE_CALLBACK;
return engine->scriptFunctions[beh.templateCallback];
}
if( beh.listFactory && count++ == index )
{
if( outBehaviour )
{
if( flags & asOBJ_VALUE )
*outBehaviour = asBEHAVE_LIST_CONSTRUCT;
else
*outBehaviour = asBEHAVE_LIST_FACTORY;
}
return engine->scriptFunctions[beh.listFactory];
}
if( beh.getWeakRefFlag && count++ == index )
{
if( outBehaviour ) *outBehaviour = asBEHAVE_GET_WEAKREF_FLAG;
return engine->scriptFunctions[beh.getWeakRefFlag];
}
// For reference types, the factories are also stored in the constructor
// list, so it is sufficient to enumerate only those
if( index - count < beh.constructors.GetLength() )
{
if( outBehaviour ) *outBehaviour = asBEHAVE_CONSTRUCT;
return engine->scriptFunctions[beh.constructors[index - count]];
}
else
count += (asUINT)beh.constructors.GetLength();
return 0;
}
// internal
asCObjectProperty *asCObjectType::AddPropertyToClass(const asCString &propName, const asCDataType &dt, bool isPrivate, bool isProtected, bool isInherited)
{
asASSERT( flags & asOBJ_SCRIPT_OBJECT );
asASSERT( dt.CanBeInstantiated() );
asASSERT( !IsInterface() );
// Store the properties in the object type descriptor
asCObjectProperty *prop = asNEW(asCObjectProperty);
if( prop == 0 )
{
// Out of memory
return 0;
}
prop->name = propName;
prop->type = dt;
prop->isPrivate = isPrivate;
prop->isProtected = isProtected;
prop->isInherited = isInherited;
int propSize;
if( dt.IsObject() )
{
// Non-POD value types can't be allocated inline,
// because there is a risk that the script might
// try to access the content without knowing that
// it hasn't been initialized yet.
if( dt.GetTypeInfo()->flags & asOBJ_POD )
propSize = dt.GetSizeInMemoryBytes();
else
{
propSize = dt.GetSizeOnStackDWords()*4;
if( !dt.IsObjectHandle() )
prop->type.MakeReference(true);
}
}
else if (dt.IsFuncdef())
{
// Funcdefs don't have a size, as they must always be stored as handles
asASSERT(dt.IsObjectHandle());
propSize = AS_PTR_SIZE * 4;
}
else
propSize = dt.GetSizeInMemoryBytes();
// Add extra bytes so that the property will be properly aligned
#ifndef WIP_16BYTE_ALIGN
if( propSize == 2 && (size & 1) ) size += 1;
if( propSize > 2 && (size & 3) ) size += 4 - (size & 3);
#else
asUINT alignment = dt.GetAlignment();
const asUINT propSizeAlignmentDifference = size & (alignment-1);
if( propSizeAlignmentDifference != 0 )
{
size += (alignment - propSizeAlignmentDifference);
}
asASSERT((size % alignment) == 0);
#endif
prop->byteOffset = size;
size += propSize;
properties.PushLast(prop);
// Make sure the struct holds a reference to the config group where the object is registered
asCConfigGroup *group = engine->FindConfigGroupForTypeInfo(prop->type.GetTypeInfo());
if( group != 0 ) group->AddRef();
// Add reference to object types
asCTypeInfo *type = prop->type.GetTypeInfo();
if( type )
type->AddRefInternal();
return prop;
}
// internal
void asCObjectType::ReleaseAllProperties()
{
for( asUINT n = 0; n < properties.GetLength(); n++ )
{
if( properties[n] )
{
if( flags & asOBJ_SCRIPT_OBJECT )
{
// Release the config group for script classes that are being destroyed
asCConfigGroup *group = engine->FindConfigGroupForTypeInfo(properties[n]->type.GetTypeInfo());
if( group != 0 ) group->Release();
// Release references to objects types
asCTypeInfo *type = properties[n]->type.GetTypeInfo();
if( type )
type->ReleaseInternal();
}
else
{
// Release template instance types (ref increased by RegisterObjectProperty)
asCTypeInfo *type = properties[n]->type.GetTypeInfo();
if( type )
type->ReleaseInternal();
}
asDELETE(properties[n],asCObjectProperty);
}
}
properties.SetLength(0);
}
// internal
void asCObjectType::ReleaseAllFunctions()
{
beh.factory = 0;
beh.copyfactory = 0;
for( asUINT a = 0; a < beh.factories.GetLength(); a++ )
{
if( engine->scriptFunctions[beh.factories[a]] )
engine->scriptFunctions[beh.factories[a]]->ReleaseInternal();
}
beh.factories.SetLength(0);
beh.construct = 0;
beh.copyconstruct = 0;
for( asUINT b = 0; b < beh.constructors.GetLength(); b++ )
{
if( engine->scriptFunctions[beh.constructors[b]] )
engine->scriptFunctions[beh.constructors[b]]->ReleaseInternal();
}
beh.constructors.SetLength(0);
if( beh.templateCallback )
engine->scriptFunctions[beh.templateCallback]->ReleaseInternal();
beh.templateCallback = 0;
if( beh.listFactory )
engine->scriptFunctions[beh.listFactory]->ReleaseInternal();
beh.listFactory = 0;
if( beh.destruct )
engine->scriptFunctions[beh.destruct]->ReleaseInternal();
beh.destruct = 0;
if( beh.copy )
engine->scriptFunctions[beh.copy]->ReleaseInternal();
beh.copy = 0;
for( asUINT c = 0; c < methods.GetLength(); c++ )
{
if( engine->scriptFunctions[methods[c]] )
engine->scriptFunctions[methods[c]]->ReleaseInternal();
}
methods.SetLength(0);
for( asUINT d = 0; d < virtualFunctionTable.GetLength(); d++ )
{
if( virtualFunctionTable[d] )
virtualFunctionTable[d]->ReleaseInternal();
}
virtualFunctionTable.SetLength(0);
// GC behaviours
if( beh.addref )
engine->scriptFunctions[beh.addref]->ReleaseInternal();
beh.addref = 0;
if( beh.release )
engine->scriptFunctions[beh.release]->ReleaseInternal();
beh.release = 0;
if( beh.gcEnumReferences )
engine->scriptFunctions[beh.gcEnumReferences]->ReleaseInternal();
beh.gcEnumReferences = 0;
if( beh.gcGetFlag )
engine->scriptFunctions[beh.gcGetFlag]->ReleaseInternal();
beh.gcGetFlag = 0;
if( beh.gcGetRefCount )
engine->scriptFunctions[beh.gcGetRefCount]->ReleaseInternal();
beh.gcGetRefCount = 0;
if( beh.gcReleaseAllReferences )
engine->scriptFunctions[beh.gcReleaseAllReferences]->ReleaseInternal();
beh.gcReleaseAllReferences = 0;
if( beh.gcSetFlag )
engine->scriptFunctions[beh.gcSetFlag]->ReleaseInternal();
beh.gcSetFlag = 0;
if ( beh.getWeakRefFlag )
engine->scriptFunctions[beh.getWeakRefFlag]->ReleaseInternal();
beh.getWeakRefFlag = 0;
}
END_AS_NAMESPACE

View File

@@ -0,0 +1,171 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2017 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_objecttype.h
//
// A class for storing object type information
//
#ifndef AS_OBJECTTYPE_H
#define AS_OBJECTTYPE_H
#include "as_property.h"
#include "as_array.h"
#include "as_scriptfunction.h"
#include "as_typeinfo.h"
BEGIN_AS_NAMESPACE
struct asSTypeBehaviour
{
asSTypeBehaviour()
{
factory = 0;
listFactory = 0;
copyfactory = 0;
construct = 0;
copyconstruct = 0;
destruct = 0;
copy = 0;
addref = 0;
release = 0;
gcGetRefCount = 0;
gcSetFlag = 0;
gcGetFlag = 0;
gcEnumReferences = 0;
gcReleaseAllReferences = 0;
templateCallback = 0;
getWeakRefFlag = 0;
}
int factory;
int listFactory; // Used for initialization lists only
int copyfactory;
int construct;
int copyconstruct;
int destruct;
int copy;
int addref;
int release;
int templateCallback;
// GC behaviours
int gcGetRefCount;
int gcSetFlag;
int gcGetFlag;
int gcEnumReferences;
int gcReleaseAllReferences;
// Weakref behaviours
int getWeakRefFlag;
asCArray<int> factories;
asCArray<int> constructors;
};
class asCScriptEngine;
struct asSNameSpace;
class asCObjectType : public asCTypeInfo
{
public:
asITypeInfo *GetBaseType() const;
bool DerivesFrom(const asITypeInfo *objType) const;
int GetSubTypeId(asUINT subtypeIndex = 0) const;
asITypeInfo *GetSubType(asUINT subtypeIndex = 0) const;
asUINT GetSubTypeCount() const;
asUINT GetInterfaceCount() const;
asITypeInfo *GetInterface(asUINT index) const;
bool Implements(const asITypeInfo *objType) const;
asUINT GetFactoryCount() const;
asIScriptFunction *GetFactoryByIndex(asUINT index) const;
asIScriptFunction *GetFactoryByDecl(const char *decl) const;
asUINT GetMethodCount() const;
asIScriptFunction *GetMethodByIndex(asUINT index, bool getVirtual) const;
asIScriptFunction *GetMethodByName(const char *name, bool getVirtual) const;
asIScriptFunction *GetMethodByDecl(const char *decl, bool getVirtual) const;
asUINT GetPropertyCount() const;
int GetProperty(asUINT index, const char **name, int *typeId, bool *isPrivate, bool *isProtected, int *offset, bool *isReference, asDWORD *accessMask, int *compositeOffset, bool *isCompositeIndirect) const;
const char *GetPropertyDeclaration(asUINT index, bool includeNamespace = false) const;
asUINT GetBehaviourCount() const;
asIScriptFunction *GetBehaviourByIndex(asUINT index, asEBehaviours *outBehaviour) const;
asUINT GetChildFuncdefCount() const;
asITypeInfo *GetChildFuncdef(asUINT index) const;
public:
asCObjectType(asCScriptEngine *engine);
~asCObjectType();
void DestroyInternal();
void ReleaseAllFunctions();
bool IsInterface() const;
asCObjectProperty *AddPropertyToClass(const asCString &name, const asCDataType &dt, bool isPrivate, bool isProtected, bool isInherited);
void ReleaseAllProperties();
#ifdef WIP_16BYTE_ALIGN
int alignment;
#endif
asCArray<asCObjectProperty*> properties;
asCArray<int> methods;
// TODO: These are not used by template types. Should perhaps create a derived class to save memory on ordinary object types
asCArray<asCObjectType*> interfaces;
asCArray<asUINT> interfaceVFTOffsets;
asCObjectType * derivedFrom;
asCArray<asCScriptFunction*> virtualFunctionTable;
// Used for funcdefs declared as members of class.
// TODO: child funcdef: Should be possible to enumerate these from application
asCArray<asCFuncdefType*> childFuncDefs;
asSTypeBehaviour beh;
// Used for template types
asCArray<asCDataType> templateSubTypes; // increases refCount for typeinfo held in datatype
bool acceptValueSubType;
bool acceptRefSubType;
protected:
friend class asCScriptEngine;
friend class asCConfigGroup;
friend class asCModule;
asCObjectType();
};
END_AS_NAMESPACE
#endif

View File

@@ -0,0 +1,109 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2012 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_outputbuffer.cpp
//
// This class appends strings to one large buffer that can later
// be sent to the real output stream
//
#include "as_config.h"
#ifndef AS_NO_COMPILER
#include "as_outputbuffer.h"
#include "as_scriptengine.h"
BEGIN_AS_NAMESPACE
asCOutputBuffer::~asCOutputBuffer()
{
Clear();
}
void asCOutputBuffer::Clear()
{
for( asUINT n = 0; n < messages.GetLength(); n++ )
{
if( messages[n] )
{
asDELETE(messages[n],message_t);
}
}
messages.SetLength(0);
}
void asCOutputBuffer::Callback(asSMessageInfo *msg)
{
message_t *msgInfo = asNEW(message_t);
if( msgInfo == 0 )
return;
msgInfo->section = msg->section;
msgInfo->row = msg->row;
msgInfo->col = msg->col;
msgInfo->type = msg->type;
msgInfo->msg = msg->message;
messages.PushLast(msgInfo);
}
void asCOutputBuffer::Append(asCOutputBuffer &in)
{
for( asUINT n = 0; n < in.messages.GetLength(); n++ )
messages.PushLast(in.messages[n]);
in.messages.SetLength(0);
}
void asCOutputBuffer::SendToCallback(asCScriptEngine *engine, asSSystemFunctionInterface *func, void *obj)
{
for( asUINT n = 0; n < messages.GetLength(); n++ )
{
asSMessageInfo msg;
msg.section = messages[n]->section.AddressOf();
msg.row = messages[n]->row;
msg.col = messages[n]->col;
msg.type = messages[n]->type;
msg.message = messages[n]->msg.AddressOf();
if( func->callConv < ICC_THISCALL )
engine->CallGlobalFunction(&msg, obj, func, 0);
else
engine->CallObjectMethod(obj, &msg, func, 0);
}
Clear();
}
END_AS_NAMESPACE
#endif // AS_NO_COMPILER

View File

@@ -0,0 +1,80 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2012 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
http://www.angelcode.com/angelscript/
Andreas Jonsson
andreas@angelcode.com
*/
//
// as_outputbuffer.h
//
// This class appends strings to one large buffer that can later
// be sent to the real output stream
//
#ifndef AS_OUTPUTBUFFER_H
#define AS_OUTPUTBUFFER_H
#include "as_config.h"
#ifndef AS_NO_COMPILER
#include "as_string.h"
#include "as_array.h"
BEGIN_AS_NAMESPACE
struct asSSystemFunctionInterface;
class asCScriptEngine;
class asCOutputBuffer
{
public:
~asCOutputBuffer ();
void Clear();
void Callback(asSMessageInfo *msg);
void Append(asCOutputBuffer &in);
void SendToCallback(asCScriptEngine *engine, asSSystemFunctionInterface *func, void *obj);
struct message_t
{
asCString section;
int row;
int col;
asEMsgType type;
asCString msg;
};
asCArray<message_t*> messages;
};
END_AS_NAMESPACE
#endif // AS_NO_COMPILER
#endif

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More