Merge branch 'speed-cap-to-physics' into game_protocol

This commit is contained in:
hiker 2018-02-09 16:03:58 +11:00
commit 8eddff3e34
229 changed files with 13861 additions and 33250 deletions

View File

@ -11,15 +11,8 @@ endif()
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake")
include(CMakeDependentOption)
set(DEPENDENCIES "dependencies")
# In case of 64-bit windows, use a different path for dependencies
# so that both dependencies can be installed next to each other
if ( WIN32 AND (CMAKE_SIZEOF_VOID_P EQUAL 8 ) )
set(DEPENDENCIES "dependencies-64bit")
endif()
include(BuildTypeSTKRelease)
if (NOT CMAKE_BUILD_TYPE)
if(NOT CMAKE_BUILD_TYPE)
message(STATUS "No build type selected, default to STKRelease")
set(CMAKE_BUILD_TYPE "STKRelease")
endif()
@ -28,12 +21,13 @@ option(SERVER_ONLY "Create a server only (i.e. no graphics or sound)" OFF)
option(USE_FRIBIDI "Support for right-to-left languages" ON)
option(CHECK_ASSETS "Check if assets are installed in ../stk-assets" ON)
option(USE_SYSTEM_ANGELSCRIPT "Use system angelscript instead of built-in angelscript. If you enable this option, make sure to use a compatible version." OFF)
option(USE_SYSTEM_ENET "Use system ENET instead of the built-in version, when available." ON)
option(USE_SYSTEM_GLEW "Use system GLEW instead of the built-in version, when available." ON)
CMAKE_DEPENDENT_OPTION(BUILD_RECORDER "Build opengl recorder" ON
"NOT SERVER_ONLY;NOT USE_GLES2;NOT APPLE" OFF)
if ((UNIX AND NOT APPLE) AND NOT SERVER_ONLY)
if((UNIX AND NOT APPLE) AND NOT SERVER_ONLY)
option(ENABLE_WAYLAND_DEVICE "Enable Wayland device for linux build" ON)
option(USE_GLES2 "Use OpenGL ES2 renderer" OFF)
endif()
@ -73,6 +67,32 @@ set(STK_INSTALL_BINARY_DIR "bin" CACHE
set(STK_INSTALL_DATA_DIR "share/supertuxkart" CACHE
STRING "Install data folder to this directory, absolute or relative to CMAKE_INSTALL_PREFIX")
# Define dependencies path
if(MSVC)
set(DEPENDENCIES "dependencies-vs")
elseif(MINGW)
set(DEPENDENCIES "dependencies-mingw")
else()
set(DEPENDENCIES "dependencies")
endif()
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(DEPENDENCIES "${DEPENDENCIES}-64bit")
endif()
if(WIN32)
if(NOT IS_DIRECTORY "${PROJECT_SOURCE_DIR}/${DEPENDENCIES}")
set(DEPENDENCIES "dependencies")
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(DEPENDENCIES "${DEPENDENCIES}-64bit")
endif()
endif()
if(NOT IS_DIRECTORY "${PROJECT_SOURCE_DIR}/${DEPENDENCIES}")
message(FATAL_ERROR "Dependencies directory not found.")
endif()
endif()
# These variables enable MSVC to find libraries located in "dependencies"
if(WIN32)
set(ENV{PATH} "$ENV{PATH};${PROJECT_SOURCE_DIR}/${DEPENDENCIES}/include")
@ -107,14 +127,24 @@ endif()
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/bullet")
include_directories("${PROJECT_SOURCE_DIR}/lib/bullet/src")
# Build the ENet UDP network library
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/enet")
include_directories("${PROJECT_SOURCE_DIR}/lib/enet/include")
# Find system ENet library or build it if missing
if((UNIX AND NOT APPLE) AND USE_SYSTEM_ENET)
find_package(ENet)
endif()
if(ENET_FOUND)
include_directories(${ENet_INCLUDE_DIRS})
else()
# Fallback to built-in version
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/enet")
include_directories("${PROJECT_SOURCE_DIR}/lib/enet/include")
set(ENet_LIBRARIES "enet")
endif()
# Find system GLEW library or build it if missing
if(NOT USE_GLES2 AND NOT SERVER_ONLY)
add_definitions(-DGLEW_NO_GLU)
if(USE_SYSTEM_GLEW)
if((UNIX AND NOT APPLE) AND USE_SYSTEM_GLEW)
find_package(PkgConfig)
if(PKGCONFIG_FOUND)
pkg_check_modules(GLEW glew>=2.1)
@ -434,7 +464,7 @@ target_link_libraries(supertuxkart
bulletdynamics
bulletcollision
bulletmath
enet
${ENet_LIBRARIES}
stkirrlicht
${Angelscript_LIBRARIES}
${CURL_LIBRARIES}
@ -575,7 +605,7 @@ install(FILES ${STK_DATA_DIR}/supertuxkart.desktop DESTINATION share/application
install(FILES data/supertuxkart_48.png DESTINATION share/icons/hicolor/48x48/apps RENAME supertuxkart.png)
install(FILES data/supertuxkart_128.png DESTINATION share/icons/hicolor/128x128/apps RENAME supertuxkart.png)
install(FILES data/supertuxkart_48.png DESTINATION share/pixmaps RENAME supertuxkart.png)
install(FILES data/supertuxkart.appdata.xml DESTINATION share/appdata)
install(FILES data/supertuxkart.appdata.xml DESTINATION share/metainfo)
if(MINGW)
install(DIRECTORY ${CMAKE_BINARY_DIR}/bin/ DESTINATION ${STK_INSTALL_BINARY_DIR}

View File

@ -108,10 +108,10 @@ To Build SuperTuxKart on Windows, follow these instructions:
1. Download and install Visual Studio from here: [Visual Studio - Download](https://www.visualstudio.com/downloads/). The free Visual Studio Community edition works fine.
2. Download the SuperTuxKart source package from either [SuperTuxKart download area - SourceForge.net](https://sourceforge.net/projects/supertuxkart/files/SuperTuxKart/0.9.2) or [SuperTuxKart.net - Source Control](https://supertuxkart.net/Source_control), and unpack it.
*Note: If you downloaded the source package from here: [SuperTuxKart.net - Source Control](https://supertuxkart.net/Source_control), then both `stk-code` and `stk-assets` **must** be in the same directory, otherwise the build can result in failure*
3. Download the Windows dependencies package from either [SuperTuxKart download area: Dependecies - SourceForge.net](https://sourceforge.net/projects/supertuxkart/files/SuperTuxKart%20Dependencies/Windows/)
3. Download the Windows dependencies package from either [SuperTuxKart download area: Dependencies - SourceForge.net](https://sourceforge.net/projects/supertuxkart/files/SuperTuxKart%20Dependencies/Windows/)
or [SuperTuxKart on GitHub - Dependencies](https://github.com/supertuxkart/dependencies), and unpack it; then, copy the `dependencies` directory from either the `windows` or the `windows_64bit` directories into the `stk-code` directory, rename it to `dependencies-64bit` if you want to compile a 64bit build.
4. Download CMake from here: [CMake - download page](https://cmake.org/download/), install it; once CMake is installed, double click on the CMake icon on your desktop, and point it towards your `stk-code` directory in the 'Where is the source code' field, and point it to a directory called `build` or `bld` inside the stk-code directory.
5. Press 'Configure'; CMake will ask you if it is OK to create the aformentioned directory, press `Yes`. CMake will then ask you about your version of Visual Studio.
5. Press 'Configure'; CMake will ask you if it is OK to create the aforementioned directory, press `Yes`. CMake will then ask you about your version of Visual Studio.
Confirm your selection; *Please look at the table below to avoid confusion between version numbers and releases of Visual Studio*;
CMake will begin creating the required files for the build in the directory.
6. Navigate to your build directory and open the `SuperTuxKart.sln` file; Visual Studio will now load the solution.

View File

@ -162,6 +162,8 @@ LOCAL_CFLAGS := -I../lib/angelscript/include \
-DUSE_GLES2 \
-DHAVE_OGGVORBIS \
-DNDEBUG \
-DANDROID_PACKAGE_NAME=\"$(PACKAGE_NAME)\" \
-DANDROID_APP_DIR_NAME=\"$(APP_DIR_NAME)\" \
-std=gnu++0x
LOCAL_STATIC_LIBRARIES := irrlicht bullet enet freetype ifaddrs angelscript \

View File

@ -8,6 +8,7 @@
<!-- This .apk has no Java code itself, so set hasCode to false. -->
<application android:label="@string/app_name"
android:icon="@drawable/icon"
android:banner="@drawable/banner"
android:hasCode="false"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:hardwareAccelerated="true">
@ -24,12 +25,16 @@
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="19" />
<uses-sdk android:targetSdkVersion="21" />
<uses-feature android:glEsVersion="0x00020000" />
<uses-feature android:name="android.software.leanback" android:required="false" />
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_MEDIA_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

BIN
android/banner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

View File

@ -15,7 +15,7 @@ apply plugin: 'com.android.application'
android
{
compileSdkVersion sdk_version.toInteger()
compileSdkVersion compile_sdk_version.toInteger()
buildToolsVersion build_tools_ver
sourceSets

View File

@ -22,25 +22,39 @@ export NDK_ABI_ARMV7=armeabi-v7a
export ARCH_ARMV7=arm
export HOST_ARMV7=arm-linux-androideabi
export NDK_PLATFORM_ARMV7=android-19
export SDK_VERSION_ARMV7=19
export MIN_SDK_VERSION_ARMV7=19
export TARGET_SDK_VERSION_ARMV7=21
export COMPILE_SDK_VERSION_ARMV7=21
export NDK_ABI_X86=x86
export ARCH_X86=x86
export HOST_X86=i686-linux-android
export NDK_PLATFORM_X86=android-19
export SDK_VERSION_X86=19
export MIN_SDK_VERSION_X86=19
export TARGET_SDK_VERSION_X86=21
export COMPILE_SDK_VERSION_X86=21
export NDK_ABI_AARCH64=arm64-v8a
export ARCH_AARCH64=arm64
export HOST_AARCH64=aarch64-linux-android
export NDK_PLATFORM_AARCH64=android-21
export SDK_VERSION_AARCH64=21
export MIN_SDK_VERSION_AARCH64=21
export TARGET_SDK_VERSION_AARCH64=21
export COMPILE_SDK_VERSION_AARCH64=21
export APP_NAME_RELEASE="SuperTuxKart"
export APP_NAME_DEBUG="SuperTuxKart Debug"
export PACKAGE_NAME_RELEASE="org.supertuxkart.stk"
export PACKAGE_NAME_DEBUG="org.supertuxkart.stk_dev"
export APP_DIR_NAME_RELEASE="supertuxkart"
export APP_ICON_RELEASE="$DIRNAME/icon.png"
export APP_NAME_BETA="SuperTuxKart Beta"
export PACKAGE_NAME_BETA="org.supertuxkart.stk_beta"
export APP_DIR_NAME_BETA="supertuxkart-beta"
export APP_ICON_BETA="$DIRNAME/icon-dbg.png"
export APP_NAME_DEBUG="SuperTuxKart Debug"
export PACKAGE_NAME_DEBUG="org.supertuxkart.stk_dbg"
export APP_DIR_NAME_DEBUG="supertuxkart-dbg"
export APP_ICON_DEBUG="$DIRNAME/icon-dbg.png"
@ -88,19 +102,25 @@ if [ "$COMPILE_ARCH" = "armv7" ]; then
export NDK_ABI=$NDK_ABI_ARMV7
export ARCH=$ARCH_ARMV7
export HOST=$HOST_ARMV7
export SDK_VERSION=$SDK_VERSION_ARMV7
export MIN_SDK_VERSION=$MIN_SDK_VERSION_ARMV7
export TARGET_SDK_VERSION=$TARGET_SDK_VERSION_ARMV7
export COMPILE_SDK_VERSION=$COMPILE_SDK_VERSION_ARMV7
elif [ "$COMPILE_ARCH" = "x86" ]; then
export NDK_PLATFORM=$NDK_PLATFORM_X86
export NDK_ABI=$NDK_ABI_X86
export ARCH=$ARCH_X86
export HOST=$HOST_X86
export SDK_VERSION=$SDK_VERSION_X86
export MIN_SDK_VERSION=$MIN_SDK_VERSION_X86
export TARGET_SDK_VERSION=$TARGET_SDK_VERSION_X86
export COMPILE_SDK_VERSION=$COMPILE_SDK_VERSION_X86
elif [ "$COMPILE_ARCH" = "aarch64" ]; then
export NDK_PLATFORM=$NDK_PLATFORM_AARCH64
export NDK_ABI=$NDK_ABI_AARCH64
export ARCH=$ARCH_AARCH64
export HOST=$HOST_AARCH64
export SDK_VERSION=$SDK_VERSION_AARCH64
export MIN_SDK_VERSION=$MIN_SDK_VERSION_AARCH64
export TARGET_SDK_VERSION=$TARGET_SDK_VERSION_AARCH64
export COMPILE_SDK_VERSION=$COMPILE_SDK_VERSION_AARCH64
else
echo "Unknow COMPILE_ARCH: $COMPILE_ARCH. Possible values are: " \
"armv7, aarch64, x86"
@ -118,6 +138,7 @@ if [ "$BUILD_TYPE" = "debug" ] || [ "$BUILD_TYPE" = "Debug" ]; then
export IS_DEBUG_BUILD=1
export APP_NAME="$APP_NAME_DEBUG"
export PACKAGE_NAME="$PACKAGE_NAME_DEBUG"
export APP_DIR_NAME="$APP_DIR_NAME_DEBUG"
export APP_ICON="$APP_ICON_DEBUG"
elif [ "$BUILD_TYPE" = "release" ] || [ "$BUILD_TYPE" = "Release" ]; then
export ANT_BUILD_TYPE="release"
@ -125,7 +146,16 @@ elif [ "$BUILD_TYPE" = "release" ] || [ "$BUILD_TYPE" = "Release" ]; then
export IS_DEBUG_BUILD=0
export APP_NAME="$APP_NAME_RELEASE"
export PACKAGE_NAME="$PACKAGE_NAME_RELEASE"
export APP_DIR_NAME="$APP_DIR_NAME_RELEASE"
export APP_ICON="$APP_ICON_RELEASE"
elif [ "$BUILD_TYPE" = "beta" ] || [ "$BUILD_TYPE" = "Beta" ]; then
export ANT_BUILD_TYPE="release"
export GRADLE_BUILD_TYPE="assembleRelease"
export IS_DEBUG_BUILD=0
export APP_NAME="$APP_NAME_BETA"
export PACKAGE_NAME="$PACKAGE_NAME_BETA"
export APP_DIR_NAME="$APP_DIR_NAME_BETA"
export APP_ICON="$APP_ICON_BETA"
else
echo "Unsupported BUILD_TYPE: $BUILD_TYPE. Possible values are: " \
"debug, release"
@ -370,12 +400,16 @@ echo "<resources>" >> "$STRINGS_FILE"
echo " <string name=\"app_name\">$APP_NAME</string>" >> "$STRINGS_FILE"
echo "</resources>" >> "$STRINGS_FILE"
sed -i "s/minSdkVersion=\".*\"/minSdkVersion=\"$SDK_VERSION\"/g" \
sed -i "s/minSdkVersion=\".*\"/minSdkVersion=\"$MIN_SDK_VERSION\"/g" \
"$DIRNAME/AndroidManifest.xml"
sed -i "s/targetSdkVersion=\".*\"/targetSdkVersion=\"$TARGET_SDK_VERSION\"/g" \
"$DIRNAME/AndroidManifest.xml"
sed -i "s/package=\".*\"/package=\"$PACKAGE_NAME\"/g" \
"$DIRNAME/AndroidManifest.xml"
cp "banner.png" "$DIRNAME/res/drawable/banner.png"
cp "$APP_ICON" "$DIRNAME/res/drawable/icon.png"
convert -scale 72x72 "$APP_ICON" "$DIRNAME/res/drawable-hdpi/icon.png"
convert -scale 48x48 "$APP_ICON" "$DIRNAME/res/drawable-mdpi/icon.png"
@ -385,12 +419,12 @@ convert -scale 144x144 "$APP_ICON" "$DIRNAME/res/drawable-xxhdpi/icon.png"
if [ "$BUILD_TOOL" = "gradle" ]; then
export ANDROID_HOME="$SDK_PATH"
gradle -Psdk_version=$SDK_VERSION \
-Pbuild_tools_ver="$BUILD_TOOLS_VER" \
gradle -Pcompile_sdk_version=$COMPILE_SDK_VERSION \
-Pbuild_tools_ver="$BUILD_TOOLS_VER" \
$GRADLE_BUILD_TYPE
elif [ "$BUILD_TOOL" = "ant" ]; then
ant -Dsdk.dir="$SDK_PATH" \
-Dtarget=$NDK_PLATFORM \
-Dtarget="android-$TARGET_SDK_VERSION" \
$ANT_BUILD_TYPE
fi

48
cmake/FindENet.cmake Normal file
View File

@ -0,0 +1,48 @@
# - Try to find enet
# Once done this will define
#
# ENET_FOUND - system has enet
# ENet_INCLUDE_DIRS - the enet include directory
# ENet_LIBRARIES - the libraries needed to use enet
#
# $ENETDIR is an environment variable used for finding enet.
#
# Borrowed from The Mana World
# http://themanaworld.org/
#
# Several changes and additions by Fabian 'x3n' Landau
# Lots of simplifications by Adrian Friedli
# > www.orxonox.net <
FIND_PATH(ENet_INCLUDE_DIRS enet/enet.h
PATHS
$ENV{ENETDIR}
/usr/local
/usr
PATH_SUFFIXES include
)
FIND_LIBRARY(ENet_LIBRARY
NAMES enet
PATHS
$ENV{ENETDIR}
/usr/local
/usr
PATH_SUFFIXES lib
)
# handle the QUIETLY and REQUIRED arguments and set ENET_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(ENet DEFAULT_MSG ENet_LIBRARY ENet_INCLUDE_DIRS)
IF (ENET_FOUND)
IF(WIN32)
SET(WINDOWS_ENET_DEPENDENCIES "ws2_32;winmm")
SET(ENet_LIBRARIES ${ENet_LIBRARY} ${WINDOWS_ENET_DEPENDENCIES})
ELSE(WIN32)
SET(ENet_LIBRARIES ${ENet_LIBRARY})
ENDIF(WIN32)
ENDIF (ENET_FOUND)
MARK_AS_ADVANCED(ENet_LIBRARY ENet_LIBRARIES ENet_INCLUDE_DIRS)

View File

@ -3,10 +3,9 @@
<track id="mansion" laps="3"/>
<mode major="single" minor="quickrace"/>
<requirements trophies="110"/>
<hard>
<karts number="5"/>
<requirements time="130"/>
<requirements time="110"/>
</hard>
<medium>
<karts number="4"/>

View File

@ -6,7 +6,7 @@
<hard>
<karts number="4"/>
<requirements time="170"/>
<requirements time="160"/>
</hard>
<medium>
<karts number="4"/>

View File

@ -3,10 +3,9 @@
<track id="snowmountain" laps="3"/>
<mode major="single" minor="quickrace"/>
<requirements trophies="60"/>
<hard>
<karts number="5"/>
<requirements time="160"/>
<requirements time="145"/>
</hard>
<medium>
<karts number="4"/>

View File

@ -72,8 +72,12 @@
</div>
<spacer height="4" width="10" />
<!-- Nothing here yet -->
<div layout="horizontal-row" proportion="1" height="fit">
<checkbox id="split_screen_horizontally"/>
<spacer width="20" height="100%" />
<label height="100%" I18N="In the ui settings" text="Multiplayer splits screen horizontally"/>
</div>
</div>
<spacer height="18" width="4"/>

View File

@ -4,6 +4,9 @@ uniform sampler2D ssao_tex;
uniform sampler2D gloss_map;
uniform sampler2D diffuse_color;
uniform sampler2D depth_stencil;
uniform sampler2D light_scatter;
uniform vec4 bg_color;
out vec4 o_final_color;
@ -31,13 +34,28 @@ void main()
vec4 color_1 = vec4(tmp * ao + (emitMapValue * emitCol), diffuseMatColor.a);
// Fog
float z = texture(depth_stencil, tc).x;
vec4 xpos = getPosFromUVDepth(vec3(tc, z), u_inverse_projection_matrix);
float depth = texture(depth_stencil, tc).x;
vec4 xpos = getPosFromUVDepth(vec3(tc, depth), u_inverse_projection_matrix);
float dist = length(xpos.xyz);
// fog density
float factor = (1.0 - exp(u_fog_data.w * dist));
vec3 fog = u_fog_color.xyz * factor;
// Additively blend the color by fog
o_final_color = color_1 + vec4(fog, factor);
color_1 = color_1 + vec4(fog, factor);
// For skybox blending later
if (depth == 1.0)
{
color_1 = bg_color;
}
// Light scatter (alpha blend function: (GL_ONE, GL_ONE_MINUS_SRC_ALPHA))
vec4 ls = texture(light_scatter, tc);
vec4 color_2;
color_2.r = ls.r + color_1.r * (1.0 - ls.a);
color_2.g = ls.g + color_1.g * (1.0 - ls.a);
color_2.b = ls.b + color_1.b * (1.0 - ls.a);
color_2.a = ls.a + color_1.a * (1.0 - ls.a);
o_final_color = color_2;
}

View File

@ -1,21 +1,25 @@
uniform sampler2D tex;
uniform sampler2D dtex;
uniform float billboard;
in vec2 tc;
in vec4 pc;
flat in float billboard_mix;
out vec4 FragColor;
#stk_include "utils/getPosFromUVDepth.frag"
void main(void)
{
float billboard_alpha = mix(1.0, texture(tex, tc).a, billboard);
#if defined(Advanced_Lighting_Enabled)
vec2 xy = gl_FragCoord.xy / u_screen;
float FragZ = gl_FragCoord.z;
vec4 FragmentPos = getPosFromUVDepth(vec3(xy, FragZ), u_inverse_projection_matrix);
float EnvZ = texture(dtex, xy).x;
vec4 EnvPos = getPosFromUVDepth(vec3(xy, EnvZ), u_inverse_projection_matrix);
float alpha = clamp((EnvPos.z - FragmentPos.z) * 0.3, 0., 1.);
float billboard_alpha = mix(1.0, texture(tex, tc).a, billboard_mix);
#else
float alpha = 1.0;
#endif
FragColor = texture(tex, tc) * billboard_alpha * pc * alpha;
}

View File

@ -23,7 +23,6 @@ in vec2 quadcorner;
in float anglespeed;
#endif
flat out float billboard_mix;
out vec2 tc;
out vec4 pc;
@ -34,13 +33,11 @@ void main(void)
gl_Position = vec4(0.);
pc = vec4(0.0);
tc = vec2(0.0);
billboard_mix = 0.0;
return;
}
float lifetime = color_lifetime.w;
float alpha = mix(smoothstep(1.0, 0.8, lifetime), lifetime, billboard);
billboard_mix = billboard;
vec4 particle_color = vec4(color_lifetime.zyx, 1.0) * alpha;
tc = Texcoord;

View File

@ -1,4 +1,4 @@
flat in float hue_change;
in float hue_change;
in vec4 color;
in vec3 normal;
@ -28,9 +28,7 @@ void main(void)
vec3 new_color = hsvToRgb(vec3(new_xy.x, new_xy.y, old_hsv.z));
col = vec4(new_color.r, new_color.g, new_color.b, col.a);
}
vec3 final_color = col.xyz * color.xyz;
o_diffuse_color = vec4(final_color, 1.0);
o_diffuse_color = vec4(col.xyz, 1.0);
#if defined(Advanced_Lighting_Enabled)
vec4 layer_2 = sampleTextureLayer2(uv);

View File

@ -1,6 +1,6 @@
uniform float custom_alpha;
flat in float hue_change;
in float hue_change;
in vec2 uv;
in vec4 color;

View File

@ -1,4 +1,4 @@
flat in float hue_change;
in float hue_change;
in vec3 normal;
in vec2 uv;
@ -26,9 +26,7 @@ void main(void)
vec3 new_color = hsvToRgb(vec3(new_xy.x, new_xy.y, old_hsv.z));
col = vec4(new_color.r, new_color.g, new_color.b, col.a);
}
vec3 final_color = col.xyz;
o_diffuse_color = vec4(final_color, 1.0);
o_diffuse_color = vec4(col.xyz, 1.0);
#if defined(Advanced_Lighting_Enabled)
vec4 layer_2 = sampleTextureLayer2(uv);

View File

@ -25,7 +25,7 @@ layout(location = 12) in ivec2 i_misc_data;
out vec3 normal;
out vec2 uv;
flat out float hue_change;
out float hue_change;
void main()
{

View File

@ -1,9 +1,6 @@
flat in float hue_change;
in float hue_change;
in vec4 color;
in vec3 tangent;
in vec3 bitangent;
in vec3 normal;
in vec2 uv;
layout(location = 0) out vec4 o_diffuse_color;
@ -13,6 +10,7 @@ layout(location = 2) out vec2 o_gloss_map;
#stk_include "utils/encode_normal.frag"
#stk_include "utils/rgb_conversion.frag"
#stk_include "utils/sp_texture_sampling.frag"
#stk_include "utils/sp_normalMapOutput.frag"
void main()
{
@ -39,16 +37,7 @@ void main()
#if defined(Advanced_Lighting_Enabled)
vec4 layer_3 = sampleTextureLayer3(uv);
vec3 tangent_space_normal = 2.0 * layer_3.xyz - 1.0;
vec3 frag_tangent = normalize(tangent);
vec3 frag_bitangent = normalize(bitangent);
vec3 frag_normal = normalize(normal);
mat3 t_b_n = mat3(frag_tangent, frag_bitangent, frag_normal);
vec3 world_normal = t_b_n * tangent_space_normal;
vec4 layer_2 = sampleTextureLayer2(uv);
o_normal_depth.xy = 0.5 * EncodeNormal(normalize(world_normal)) + 0.5;
o_normal_depth.z = layer_2.x;
o_gloss_map = layer_2.yz;
outputNormalMapPbrData(layer_3.rgb, layer_2.rgb);
#endif
}

View File

@ -1,3 +1,9 @@
uniform int enable_normals;
uniform int enable_tangents;
uniform int enable_bitangents;
uniform int enable_wireframe;
uniform int enable_triangle_normals;
layout(triangles) in;
layout(line_strip, max_vertices = 24) out;
@ -9,6 +15,13 @@ flat out vec4 o_color;
void main()
{
if (enable_normals == 0 && enable_tangents == 0 &&
enable_bitangents == 0 && enable_wireframe == 0 &&
enable_triangle_normals == 0)
{
return;
}
// colors for different type of new lines
vec4 edge_color = vec4(0.2, 0.1, 0.1, 1.0);
vec4 face_normal_color = vec4(0.5, 0.7, 0.2, 1.0);
@ -47,56 +60,71 @@ void main()
// get position of the vertex
vec3 P = gl_in[i].gl_Position.xyz;
// create normal for vertex
o_color = normal_color;
gl_Position = pos[i];
EmitVertex();
gl_Position = u_projection_view_matrix * vec4(P + o_normal[i].xyz
* normal_scale, 1.0);
EmitVertex();
EndPrimitive();
if (enable_normals > 0)
{
// create normal for vertex
o_color = normal_color;
gl_Position = pos[i];
EmitVertex();
gl_Position = u_projection_view_matrix * vec4(P + o_normal[i].xyz
* normal_scale, 1.0);
EmitVertex();
EndPrimitive();
}
// create tangent for vertex
o_color = tangent_color;
gl_Position = pos[i];
EmitVertex();
gl_Position = u_projection_view_matrix *
vec4(P + o_tangent[i].xyz * normal_scale, 1.0);
EmitVertex();
EndPrimitive();
if (enable_tangents > 0)
{
// create tangent for vertex
o_color = tangent_color;
gl_Position = pos[i];
EmitVertex();
gl_Position = u_projection_view_matrix *
vec4(P + o_tangent[i].xyz * normal_scale, 1.0);
EmitVertex();
EndPrimitive();
}
// create bitangent for vertex
o_color = bitangent_color;
gl_Position = pos[i];
if (enable_bitangents > 0)
{
// create bitangent for vertex
o_color = bitangent_color;
gl_Position = pos[i];
EmitVertex();
gl_Position = u_projection_view_matrix * vec4(P +
o_bitangent[i].xyz * normal_scale, 1.0);
EmitVertex();
EndPrimitive();
}
}
if (enable_wireframe > 0)
{
// create edges for triangle
o_color = edge_color;
gl_Position = pos[0];
EmitVertex();
gl_Position = u_projection_view_matrix * vec4(P +
o_bitangent[i].xyz * normal_scale, 1.0);
gl_Position = pos[1];
EmitVertex();
gl_Position = pos[2];
EmitVertex();
gl_Position = pos[0];
EmitVertex();
// end line strip after four added vertices, so we will get three lines
EndPrimitive();
}
// create edges for triangle
o_color = edge_color;
gl_Position = pos[0];
EmitVertex();
gl_Position = pos[1];
EmitVertex();
gl_Position = pos[2];
EmitVertex();
gl_Position = pos[0];
EmitVertex();
// end line strip after four added vertices, so we will get three lines
EndPrimitive();
if (enable_triangle_normals > 0)
{
// create normal for triangle
o_color = face_normal_color;
// create normal for triangle
o_color = face_normal_color;
// position as arithmetic average
vec3 P = (gl_in[0].gl_Position.xyz + gl_in[1].gl_Position.xyz
+ gl_in[2].gl_Position.xyz) / 3.0;
gl_Position = u_projection_view_matrix * vec4(P, 1.0);
EmitVertex();
gl_Position = u_projection_view_matrix * vec4(P + N * normal_scale, 1.0);
EmitVertex();
EndPrimitive();
// position as arithmetic average
vec3 P = (gl_in[0].gl_Position.xyz + gl_in[1].gl_Position.xyz
+ gl_in[2].gl_Position.xyz) / 3.0;
gl_Position = u_projection_view_matrix * vec4(P, 1.0);
EmitVertex();
gl_Position = u_projection_view_matrix * vec4(P + N * normal_scale, 1.0);
EmitVertex();
EndPrimitive();
}
}

View File

@ -50,21 +50,55 @@ void main()
vec4 skinned_tangent = vec4(0.0);
int skinning_offset = i_misc_data.x;
for (int i = 0; i < 4; i++)
{
mat4 joint_matrix = mat4(
texelFetch(skinning_tex,
clamp(i_joint[i] + skinning_offset, 0, MAX_BONES) * 4),
texelFetch(skinning_tex,
clamp(i_joint[i] + skinning_offset, 0, MAX_BONES) * 4 + 1),
texelFetch(skinning_tex,
clamp(i_joint[i] + skinning_offset, 0, MAX_BONES) * 4 + 2),
texelFetch(skinning_tex,
clamp(i_joint[i] + skinning_offset, 0, MAX_BONES) * 4 + 3));
skinned_position += i_weight[i] * joint_matrix * idle_position;
skinned_normal += i_weight[i] * joint_matrix * idle_normal;
skinned_tangent += i_weight[i] * joint_matrix * idle_tangent;
}
#ifdef GL_ES
mat4 joint_matrix =
i_weight[0] * mat4(
texelFetch(skinning_tex, ivec2(0, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(1, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(2, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(3, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES)), 0)) +
i_weight[1] * mat4(
texelFetch(skinning_tex, ivec2(0, clamp(i_joint[1] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(1, clamp(i_joint[1] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(2, clamp(i_joint[1] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(3, clamp(i_joint[1] + skinning_offset, 0, MAX_BONES)), 0)) +
i_weight[2] * mat4(
texelFetch(skinning_tex, ivec2(0, clamp(i_joint[2] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(1, clamp(i_joint[2] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(2, clamp(i_joint[2] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(3, clamp(i_joint[2] + skinning_offset, 0, MAX_BONES)), 0)) +
i_weight[3] * mat4(
texelFetch(skinning_tex, ivec2(0, clamp(i_joint[3] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(1, clamp(i_joint[3] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(2, clamp(i_joint[3] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(3, clamp(i_joint[3] + skinning_offset, 0, MAX_BONES)), 0));
#else
mat4 joint_matrix =
i_weight[0] * mat4(
texelFetch(skinning_tex, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES) * 4),
texelFetch(skinning_tex, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES) * 4 + 1),
texelFetch(skinning_tex, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES) * 4 + 2),
texelFetch(skinning_tex, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES) * 4 + 3)) +
i_weight[1] * mat4(
texelFetch(skinning_tex, clamp(i_joint[1] + skinning_offset, 0, MAX_BONES) * 4),
texelFetch(skinning_tex, clamp(i_joint[1] + skinning_offset, 0, MAX_BONES) * 4 + 1),
texelFetch(skinning_tex, clamp(i_joint[1] + skinning_offset, 0, MAX_BONES) * 4 + 2),
texelFetch(skinning_tex, clamp(i_joint[1] + skinning_offset, 0, MAX_BONES) * 4 + 3)) +
i_weight[2] * mat4(
texelFetch(skinning_tex, clamp(i_joint[2] + skinning_offset, 0, MAX_BONES) * 4),
texelFetch(skinning_tex, clamp(i_joint[2] + skinning_offset, 0, MAX_BONES) * 4 + 1),
texelFetch(skinning_tex, clamp(i_joint[2] + skinning_offset, 0, MAX_BONES) * 4 + 2),
texelFetch(skinning_tex, clamp(i_joint[2] + skinning_offset, 0, MAX_BONES) * 4 + 3)) +
i_weight[3] * mat4(
texelFetch(skinning_tex, clamp(i_joint[3] + skinning_offset, 0, MAX_BONES) * 4),
texelFetch(skinning_tex, clamp(i_joint[3] + skinning_offset, 0, MAX_BONES) * 4 + 1),
texelFetch(skinning_tex, clamp(i_joint[3] + skinning_offset, 0, MAX_BONES) * 4 + 2),
texelFetch(skinning_tex, clamp(i_joint[3] + skinning_offset, 0, MAX_BONES) * 4 + 3));
#endif
skinned_position = joint_matrix * idle_position;
skinned_normal = joint_matrix * idle_normal;
skinned_tangent = joint_matrix * idle_tangent;
float step_mix = step(float(skinning_offset), 0.0);
skinned_position = mix(skinned_position, idle_position, step_mix);

View File

@ -36,8 +36,9 @@ out vec3 normal;
out vec2 uv;
out vec2 uv_two;
out vec4 color;
out vec4 world_position;
out float camdist;
flat out float hue_change;
out float hue_change;
void main()
{
@ -49,7 +50,7 @@ void main()
#endif
vec4 quaternion = normalize(vec4(i_rotation.xyz, i_scale.w));
vec4 world_position = getWorldPosition(i_origin, quaternion, i_scale.xyz,
vec4 v_world_position = getWorldPosition(i_origin, quaternion, i_scale.xyz,
i_position);
vec3 world_normal = rotateVector(quaternion, i_normal.xyz);
vec3 world_tangent = rotateVector(quaternion, i_tangent.xyz);
@ -66,7 +67,8 @@ void main()
uv_two = i_uv_two;
color = i_color.zyxw;
camdist = length(u_view_matrix * world_position);
camdist = length(u_view_matrix * v_world_position);
hue_change = float(i_misc_data.y) * 0.01;
gl_Position = u_projection_view_matrix * world_position;
gl_Position = u_projection_view_matrix * v_world_position;
world_position = v_world_position;
}

View File

@ -44,7 +44,7 @@ out vec2 uv;
out vec2 uv_two;
out vec4 color;
out float camdist;
flat out float hue_change;
out float hue_change;
void main()
{
@ -63,33 +63,55 @@ void main()
vec4 skinned_tangent = vec4(0.0);
int skinning_offset = i_misc_data.x;
for (int i = 0; i < 4; i++)
{
#ifdef GL_ES
mat4 joint_matrix = mat4(
texelFetch(skinning_tex, ivec2
(0 , clamp(i_joint[i] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2
(1, clamp(i_joint[i] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2
(2, clamp(i_joint[i] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2
(3, clamp(i_joint[i] + skinning_offset, 0, MAX_BONES)), 0));
mat4 joint_matrix =
i_weight[0] * mat4(
texelFetch(skinning_tex, ivec2(0, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(1, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(2, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(3, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES)), 0)) +
i_weight[1] * mat4(
texelFetch(skinning_tex, ivec2(0, clamp(i_joint[1] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(1, clamp(i_joint[1] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(2, clamp(i_joint[1] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(3, clamp(i_joint[1] + skinning_offset, 0, MAX_BONES)), 0)) +
i_weight[2] * mat4(
texelFetch(skinning_tex, ivec2(0, clamp(i_joint[2] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(1, clamp(i_joint[2] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(2, clamp(i_joint[2] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(3, clamp(i_joint[2] + skinning_offset, 0, MAX_BONES)), 0)) +
i_weight[3] * mat4(
texelFetch(skinning_tex, ivec2(0, clamp(i_joint[3] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(1, clamp(i_joint[3] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(2, clamp(i_joint[3] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(3, clamp(i_joint[3] + skinning_offset, 0, MAX_BONES)), 0));
#else
mat4 joint_matrix = mat4(
texelFetch(skinning_tex,
clamp(i_joint[i] + skinning_offset, 0, MAX_BONES) * 4),
texelFetch(skinning_tex,
clamp(i_joint[i] + skinning_offset, 0, MAX_BONES) * 4 + 1),
texelFetch(skinning_tex,
clamp(i_joint[i] + skinning_offset, 0, MAX_BONES) * 4 + 2),
texelFetch(skinning_tex,
clamp(i_joint[i] + skinning_offset, 0, MAX_BONES) * 4 + 3));
mat4 joint_matrix =
i_weight[0] * mat4(
texelFetch(skinning_tex, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES) * 4),
texelFetch(skinning_tex, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES) * 4 + 1),
texelFetch(skinning_tex, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES) * 4 + 2),
texelFetch(skinning_tex, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES) * 4 + 3)) +
i_weight[1] * mat4(
texelFetch(skinning_tex, clamp(i_joint[1] + skinning_offset, 0, MAX_BONES) * 4),
texelFetch(skinning_tex, clamp(i_joint[1] + skinning_offset, 0, MAX_BONES) * 4 + 1),
texelFetch(skinning_tex, clamp(i_joint[1] + skinning_offset, 0, MAX_BONES) * 4 + 2),
texelFetch(skinning_tex, clamp(i_joint[1] + skinning_offset, 0, MAX_BONES) * 4 + 3)) +
i_weight[2] * mat4(
texelFetch(skinning_tex, clamp(i_joint[2] + skinning_offset, 0, MAX_BONES) * 4),
texelFetch(skinning_tex, clamp(i_joint[2] + skinning_offset, 0, MAX_BONES) * 4 + 1),
texelFetch(skinning_tex, clamp(i_joint[2] + skinning_offset, 0, MAX_BONES) * 4 + 2),
texelFetch(skinning_tex, clamp(i_joint[2] + skinning_offset, 0, MAX_BONES) * 4 + 3)) +
i_weight[3] * mat4(
texelFetch(skinning_tex, clamp(i_joint[3] + skinning_offset, 0, MAX_BONES) * 4),
texelFetch(skinning_tex, clamp(i_joint[3] + skinning_offset, 0, MAX_BONES) * 4 + 1),
texelFetch(skinning_tex, clamp(i_joint[3] + skinning_offset, 0, MAX_BONES) * 4 + 2),
texelFetch(skinning_tex, clamp(i_joint[3] + skinning_offset, 0, MAX_BONES) * 4 + 3));
#endif
skinned_position += i_weight[i] * joint_matrix * idle_position;
skinned_normal += i_weight[i] * joint_matrix * idle_normal;
skinned_tangent += i_weight[i] * joint_matrix * idle_tangent;
}
skinned_position = joint_matrix * idle_position;
skinned_normal = joint_matrix * idle_normal;
skinned_tangent = joint_matrix * idle_tangent;
vec4 quaternion = normalize(vec4(i_rotation.xyz, i_scale.w));
vec4 world_position = getWorldPosition(i_origin, quaternion, i_scale.xyz,

View File

@ -36,31 +36,53 @@ void main()
vec4 skinned_position = vec4(0.0);
int skinning_offset = i_misc_data.x;
for (int i = 0; i < 4; i++)
{
#ifdef GL_ES
mat4 joint_matrix = mat4(
texelFetch(skinning_tex, ivec2
(0, clamp(i_joint[i] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2
(1, clamp(i_joint[i] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2
(2, clamp(i_joint[i] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2
(3, clamp(i_joint[i] + skinning_offset, 0, MAX_BONES)), 0));
mat4 joint_matrix =
i_weight[0] * mat4(
texelFetch(skinning_tex, ivec2(0, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(1, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(2, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(3, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES)), 0)) +
i_weight[1] * mat4(
texelFetch(skinning_tex, ivec2(0, clamp(i_joint[1] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(1, clamp(i_joint[1] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(2, clamp(i_joint[1] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(3, clamp(i_joint[1] + skinning_offset, 0, MAX_BONES)), 0)) +
i_weight[2] * mat4(
texelFetch(skinning_tex, ivec2(0, clamp(i_joint[2] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(1, clamp(i_joint[2] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(2, clamp(i_joint[2] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(3, clamp(i_joint[2] + skinning_offset, 0, MAX_BONES)), 0)) +
i_weight[3] * mat4(
texelFetch(skinning_tex, ivec2(0, clamp(i_joint[3] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(1, clamp(i_joint[3] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(2, clamp(i_joint[3] + skinning_offset, 0, MAX_BONES)), 0),
texelFetch(skinning_tex, ivec2(3, clamp(i_joint[3] + skinning_offset, 0, MAX_BONES)), 0));
#else
mat4 joint_matrix = mat4(
texelFetch(skinning_tex,
clamp(i_joint[i] + skinning_offset, 0, MAX_BONES) * 4),
texelFetch(skinning_tex,
clamp(i_joint[i] + skinning_offset, 0, MAX_BONES) * 4 + 1),
texelFetch(skinning_tex,
clamp(i_joint[i] + skinning_offset, 0, MAX_BONES) * 4 + 2),
texelFetch(skinning_tex,
clamp(i_joint[i] + skinning_offset, 0, MAX_BONES) * 4 + 3));
mat4 joint_matrix =
i_weight[0] * mat4(
texelFetch(skinning_tex, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES) * 4),
texelFetch(skinning_tex, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES) * 4 + 1),
texelFetch(skinning_tex, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES) * 4 + 2),
texelFetch(skinning_tex, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES) * 4 + 3)) +
i_weight[1] * mat4(
texelFetch(skinning_tex, clamp(i_joint[1] + skinning_offset, 0, MAX_BONES) * 4),
texelFetch(skinning_tex, clamp(i_joint[1] + skinning_offset, 0, MAX_BONES) * 4 + 1),
texelFetch(skinning_tex, clamp(i_joint[1] + skinning_offset, 0, MAX_BONES) * 4 + 2),
texelFetch(skinning_tex, clamp(i_joint[1] + skinning_offset, 0, MAX_BONES) * 4 + 3)) +
i_weight[2] * mat4(
texelFetch(skinning_tex, clamp(i_joint[2] + skinning_offset, 0, MAX_BONES) * 4),
texelFetch(skinning_tex, clamp(i_joint[2] + skinning_offset, 0, MAX_BONES) * 4 + 1),
texelFetch(skinning_tex, clamp(i_joint[2] + skinning_offset, 0, MAX_BONES) * 4 + 2),
texelFetch(skinning_tex, clamp(i_joint[2] + skinning_offset, 0, MAX_BONES) * 4 + 3)) +
i_weight[3] * mat4(
texelFetch(skinning_tex, clamp(i_joint[3] + skinning_offset, 0, MAX_BONES) * 4),
texelFetch(skinning_tex, clamp(i_joint[3] + skinning_offset, 0, MAX_BONES) * 4 + 1),
texelFetch(skinning_tex, clamp(i_joint[3] + skinning_offset, 0, MAX_BONES) * 4 + 2),
texelFetch(skinning_tex, clamp(i_joint[3] + skinning_offset, 0, MAX_BONES) * 4 + 3));
#endif
skinned_position += i_weight[i] * joint_matrix * idle_position;
}
skinned_position = joint_matrix * idle_position;
vec4 quaternion = normalize(vec4(i_rotation.xyz, i_scale.w));
vec4 world_position = getWorldPosition(i_origin, quaternion, i_scale.xyz,

View File

@ -1,4 +1,4 @@
flat in float hue_change;
in float hue_change;
in vec4 color;
in vec3 normal;

View File

@ -100,18 +100,11 @@
<shadow-pass use-function="" unuse-function=""
vertex-shader="sp_shadow.vert" fragment-shader="white.frag"
skinned-mesh-shader="sp_skinning_shadow.vert">
<uniforms>
<!--
uniforms: Define the uniforms in shader with the name of the
type (int, float, mat4, vec4, vec3, vec2).
-->
<uniform name="layer" type="int"/>
</uniforms>
</shadow-pass>
<!--
uniform-assigners: List of uniform assigners functions to be auto-run
when "use" the shader which set the above uniforms,
currently there are:
when "use" the shader which set the uniform
variables in shader, currently there are:
shadowCascadeUniformAssigner will set the current shadow
cascade being drawn.
@ -127,6 +120,9 @@
You have to specify the uniform name in shader together with the
bundled uniform-assigners.
Currently you can automatically assign to uniform type int, float,
mat4, vec4, vec3 and vec2 only.
-->
<uniform-assigners>
<uniform-assigner name="layer"

View File

@ -7,9 +7,6 @@
<shadow-pass vertex-shader="sp_shadow.vert"
fragment-shader="white.frag"
skinned-mesh-shader="sp_skinning_shadow.vert">
<uniforms>
<uniform name="layer" type="int"/>
</uniforms>
</shadow-pass>
<uniform-assigners>
<uniform-assigner name="layer"

View File

@ -7,9 +7,6 @@
<shadow-pass vertex-shader="sp_shadow.vert"
fragment-shader="sp_shadow_alpha_test.frag"
skinned-mesh-shader="sp_skinning_shadow.vert">
<uniforms>
<uniform name="layer" type="int"/>
</uniforms>
</shadow-pass>
<uniform-assigners>
<uniform-assigner name="layer"

View File

@ -5,9 +5,6 @@
</first-pass>
<shadow-pass vertex-shader="sp_shadow.vert" fragment-shader="white.frag"
skinned-mesh-shader="sp_skinning_shadow.vert">
<uniforms>
<uniform name="layer" type="int"/>
</uniforms>
</shadow-pass>
<uniform-assigners>
<uniform-assigner name="layer"

View File

@ -2,16 +2,9 @@
<shader-info name="grass" use-alpha-channel="Y"/>
<first-pass vertex-shader="sp_grass_pass.vert"
fragment-shader="sp_grass.frag">
<uniforms>
<uniform name="wind_direction" type="vec3"/>
</uniforms>
</first-pass>
<shadow-pass vertex-shader="sp_grass_shadow.vert"
fragment-shader="sp_shadow_alpha_test.frag">
<uniforms>
<uniform name="wind_direction" type="vec3"/>
<uniform name="layer" type="int"/>
</uniforms>
</shadow-pass>
<uniform-assigners>
<uniform-assigner name="layer"

View File

@ -6,9 +6,6 @@
<shadow-pass vertex-shader="sp_shadow.vert"
fragment-shader="sp_shadow_alpha_test.frag"
skinned-mesh-shader="sp_skinning_shadow.vert">
<uniforms>
<uniform name="layer" type="int"/>
</uniforms>
</shadow-pass>
<uniform-assigners>
<uniform-assigner name="layer"

View File

@ -3,10 +3,6 @@
<first-pass use-function="alphaBlendUse" vertex-shader="sp_pass.vert"
fragment-shader="sp_transparent.frag"
skinned-mesh-shader="sp_skinning.vert">
<uniforms>
<uniform name="fog_enabled" type="int"/>
<uniform name="custom_alpha" type="float"/>
</uniforms>
</first-pass>
<uniform-assigners>
<uniform-assigner name="fog_enabled"

View File

@ -3,10 +3,6 @@
<first-pass use-function="additiveUse" vertex-shader="sp_pass.vert"
fragment-shader="sp_transparent.frag"
skinned-mesh-shader="sp_skinning.vert">
<uniforms>
<uniform name="fog_enabled" type="int"/>
<uniform name="custom_alpha" type="float"/>
</uniforms>
</first-pass>
<uniform-assigners>
<uniform-assigner name="fog_enabled"

View File

@ -3,9 +3,6 @@
<first-pass use-function="ghostUse" vertex-shader="sp_pass.vert"
fragment-shader="sp_ghost.frag"
skinned-mesh-shader="sp_skinning.vert">
<uniforms>
<uniform name="custom_alpha" type="float"/>
</uniforms>
</first-pass>
<uniform-assigners>
<uniform-assigner name="custom_alpha"

View File

@ -0,0 +1,21 @@
// This function encapsulate the computation of normal maps
in vec3 tangent;
in vec3 bitangent;
in vec3 normal;
void outputNormalMapPbrData(vec3 layer_3, vec3 layer_2)
{
vec3 tangent_space_normal = 2.0 * layer_3.xyz - 1.0;
vec3 frag_tangent = normalize(tangent);
vec3 frag_bitangent = normalize(bitangent);
vec3 frag_normal = normalize(normal);
mat3 t_b_n = mat3(frag_tangent, frag_bitangent, frag_normal);
vec3 world_normal = t_b_n * tangent_space_normal;
o_normal_depth.xy = 0.5 * EncodeNormal(normalize(world_normal)) + 0.5;
o_normal_depth.z = layer_2.x;
o_gloss_map = layer_2.yz;
}

View File

@ -129,6 +129,9 @@ when the border that intersect at this corner are enabled.
hborder_out_portion="0.2" />
<!-- Stateless -->
<element type="squareFocusHaloBW" image="forest/glass_square_focused_bw.png"
left_border="6" right_border ="6" top_border="6" bottom_border="6"
hborder_out_portion="1.0" />
<element type="squareFocusHalo" image="forest/glass_square_focused.png"
left_border="6" right_border ="6" top_border="6" bottom_border="6"
hborder_out_portion="1.0" />

View File

@ -128,6 +128,9 @@ when the border that intersect at this corner are enabled.
hborder_out_portion="0.2" />
<!-- Stateless -->
<element type="squareFocusHaloBW" image="ocean/glass_square_focused_bw.png"
left_border="6" right_border ="6" top_border="6" bottom_border="6"
hborder_out_portion="1.0" />
<element type="squareFocusHalo" image="ocean/glass_square_focused.png"
left_border="6" right_border ="6" top_border="6" bottom_border="6"
hborder_out_portion="1.0" />

View File

@ -129,6 +129,9 @@ when the border that intersect at this corner are enabled.
<!-- Stateless -->
<element type="squareFocusHaloBW" image="peach/glass_square_focused_bw.png"
left_border="6" right_border ="6" top_border="6" bottom_border="6"
hborder_out_portion="1.0" />
<element type="squareFocusHalo" image="peach/glass_square_focused.png"
left_border="6" right_border ="6" top_border="6" bottom_border="6"
hborder_out_portion="1.0" />

View File

@ -130,6 +130,9 @@ when the border that intersect at this corner are enabled.
<!-- Stateless -->
<element type="squareFocusHaloBW" image="ruby/glass_square_focused_bw.png"
left_border="6" right_border ="6" top_border="6" bottom_border="6"
hborder_out_portion="1.0" />
<element type="squareFocusHalo" image="ruby/glass_square_focused.png"
left_border="6" right_border ="6" top_border="6" bottom_border="6"
hborder_out_portion="1.0" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 942 B

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
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
@ -58,8 +58,8 @@ BEGIN_AS_NAMESPACE
// AngelScript version
#define ANGELSCRIPT_VERSION 23002
#define ANGELSCRIPT_VERSION_STRING "2.30.2"
#define ANGELSCRIPT_VERSION 23200
#define ANGELSCRIPT_VERSION_STRING "2.32.0"
// Data types
@ -68,12 +68,13 @@ class asIScriptModule;
class asIScriptContext;
class asIScriptGeneric;
class asIScriptObject;
class asIObjectType;
class asITypeInfo;
class asIScriptFunction;
class asIBinaryStream;
class asIJITCompiler;
class asIThreadManager;
class asILockableSharedBool;
class asIStringFactory;
// Enumerations and constants
@ -138,6 +139,9 @@ enum asEEngineProp
asEP_DISABLE_INTEGER_DIVISION = 22,
asEP_DISALLOW_EMPTY_LIST_ELEMENTS = 23,
asEP_PRIVATE_PROP_AS_PROTECTED = 24,
asEP_ALLOW_UNICODE_IDENTIFIERS = 25,
asEP_HEREDOC_TRIM_MODE = 26,
asEP_MAX_NESTED_CALLS = 27,
asEP_LAST_PROPERTY
};
@ -200,7 +204,7 @@ enum asEObjTypeFlags
asOBJ_SCRIPT_OBJECT = (1<<21),
asOBJ_SHARED = (1<<22),
asOBJ_NOINHERIT = (1<<23),
asOBJ_SCRIPT_FUNCTION = (1<<24),
asOBJ_FUNCDEF = (1<<24),
asOBJ_LIST_PATTERN = (1<<25),
asOBJ_ENUM = (1<<26),
asOBJ_TEMPLATE_SUBTYPE = (1<<27),
@ -225,14 +229,6 @@ enum asEBehaviours
asBEHAVE_GET_WEAKREF_FLAG,
// Object operators
#ifdef AS_DEPRECATED
// Deprecated since 2.30.0, 2014-10-24
asBEHAVE_VALUE_CAST,
asBEHAVE_IMPLICIT_VALUE_CAST,
// Deprecated since 2.30.0, 2014-12-30
asBEHAVE_REF_CAST,
asBEHAVE_IMPLICIT_REF_CAST,
#endif
asBEHAVE_TEMPLATE_CALLBACK,
// Garbage collection behaviours
@ -356,29 +352,31 @@ enum asEFuncType
// asQWORD = 64 bits
// asPWORD = size of pointer
//
typedef signed char asINT8;
typedef signed short asINT16;
typedef unsigned char asBYTE;
typedef unsigned short asWORD;
typedef unsigned int asUINT;
#if (defined(_MSC_VER) && _MSC_VER <= 1200) || defined(__S3E__)
#if (defined(_MSC_VER) && _MSC_VER <= 1200) || defined(__S3E__) || (defined(_MSC_VER) && defined(__clang__))
// size_t is not really correct, since it only guaranteed to be large enough to hold the segment size.
// For example, on 16bit systems the size_t may be 16bits only even if pointers are 32bit. But nobody
// is likely to use MSVC6 to compile for 16bit systems anymore, so this should be ok.
typedef size_t asPWORD;
typedef size_t asPWORD;
#else
typedef uintptr_t asPWORD;
#endif
#ifdef __LP64__
typedef unsigned int asDWORD;
typedef unsigned long asQWORD;
typedef long asINT64;
typedef unsigned int asDWORD;
typedef unsigned long asQWORD;
typedef long asINT64;
#else
typedef unsigned long asDWORD;
#if defined(__GNUC__) || defined(__MWERKS__) || defined(__SUNPRO_CC) || defined(__psp2__)
typedef uint64_t asQWORD;
typedef int64_t asINT64;
typedef unsigned long asDWORD;
#if !defined(_MSC_VER) && (defined(__GNUC__) || defined(__MWERKS__) || defined(__SUNPRO_CC) || defined(__psp2__))
typedef uint64_t asQWORD;
typedef int64_t asINT64;
#else
typedef unsigned __int64 asQWORD;
typedef __int64 asINT64;
typedef unsigned __int64 asQWORD;
typedef __int64 asINT64;
#endif
#endif
@ -397,7 +395,7 @@ typedef void (*asCLEANENGINEFUNC_t)(asIScriptEngine *);
typedef void (*asCLEANMODULEFUNC_t)(asIScriptModule *);
typedef void (*asCLEANCONTEXTFUNC_t)(asIScriptContext *);
typedef void (*asCLEANFUNCTIONFUNC_t)(asIScriptFunction *);
typedef void (*asCLEANOBJECTTYPEFUNC_t)(asIObjectType *);
typedef void (*asCLEANTYPEINFOFUNC_t)(asITypeInfo *);
typedef void (*asCLEANSCRIPTOBJECTFUNC_t)(asIScriptObject *);
typedef asIScriptContext *(*asREQUESTCONTEXTFUNC_t)(asIScriptEngine *, void *);
typedef void (*asRETURNCONTEXTFUNC_t)(asIScriptEngine *, asIScriptContext *, void *);
@ -425,7 +423,7 @@ typedef void (*asRETURNCONTEXTFUNC_t)(asIScriptEngine *, asIScriptContext *, voi
// BCC v5.8 (C++Builder 2006) and earlier have a similar bug which forces us to fall back to a C-style cast.
#define asFUNCTIONPR(f,p,r) asFunctionPtr((void (*)())((r (*)p)(f)))
#else
#define asFUNCTIONPR(f,p,r) asFunctionPtr((void (*)())(static_cast<r (*)p>(f)))
#define asFUNCTIONPR(f,p,r) asFunctionPtr(reinterpret_cast<void (*)()>(static_cast<r (*)p>(f)))
#endif
#ifndef AS_NO_CLASS_METHODS
@ -584,7 +582,7 @@ BEGIN_AS_NAMESPACE
template<typename T>
asUINT asGetTypeTraits()
{
#if defined(_MSC_VER) || defined(_LIBCPP_TYPE_TRAITS) || (__GNUC__ >= 5)
#if defined(_MSC_VER) || defined(_LIBCPP_TYPE_TRAITS) || (__GNUC__ >= 5) || defined(__clang__)
// MSVC, XCode/Clang, and gnuc 5+
// C++11 compliant code
bool hasConstructor = std::is_default_constructible<T>::value && !std::is_trivially_default_constructible<T>::value;
@ -665,7 +663,7 @@ public:
virtual asIJITCompiler *GetJITCompiler() const = 0;
// Global functions
virtual int RegisterGlobalFunction(const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv, void *objForThiscall = 0) = 0;
virtual int RegisterGlobalFunction(const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv, void *auxiliary = 0) = 0;
virtual asUINT GetGlobalFunctionCount() const = 0;
virtual asIScriptFunction *GetGlobalFunctionByIndex(asUINT index) const = 0;
virtual asIScriptFunction *GetGlobalFunctionByDecl(const char *declaration) const = 0;
@ -679,18 +677,16 @@ public:
// Object types
virtual int RegisterObjectType(const char *obj, int byteSize, asDWORD flags) = 0;
virtual int RegisterObjectProperty(const char *obj, const char *declaration, int byteOffset) = 0;
virtual int RegisterObjectMethod(const char *obj, const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv, void *objForThiscall = 0) = 0;
virtual int RegisterObjectBehaviour(const char *obj, asEBehaviours behaviour, const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv, void *objForThiscall = 0) = 0;
virtual int RegisterObjectProperty(const char *obj, const char *declaration, int byteOffset, int compositeOffset = 0, bool isCompositeIndirect = false) = 0;
virtual int RegisterObjectMethod(const char *obj, const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv, void *auxiliary = 0, int compositeOffset = 0, bool isCompositeIndirect = false) = 0;
virtual int RegisterObjectBehaviour(const char *obj, asEBehaviours behaviour, const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv, void *auxiliary = 0, int compositeOffset = 0, bool isCompositeIndirect = false) = 0;
virtual int RegisterInterface(const char *name) = 0;
virtual int RegisterInterfaceMethod(const char *intf, const char *declaration) = 0;
virtual asUINT GetObjectTypeCount() const = 0;
virtual asIObjectType *GetObjectTypeByIndex(asUINT index) const = 0;
virtual asIObjectType *GetObjectTypeByName(const char *name) const = 0;
virtual asIObjectType *GetObjectTypeByDecl(const char *decl) const = 0;
virtual asITypeInfo *GetObjectTypeByIndex(asUINT index) const = 0;
// String factory
virtual int RegisterStringFactory(const char *datatype, const asSFuncPtr &factoryFunc, asDWORD callConv, void *objForThiscall = 0) = 0;
virtual int RegisterStringFactory(const char *datatype, asIStringFactory *factory) = 0;
virtual int GetStringFactoryReturnTypeId(asDWORD *flags = 0) const = 0;
// Default array type
@ -698,22 +694,20 @@ public:
virtual int GetDefaultArrayTypeId() const = 0;
// Enums
virtual int RegisterEnum(const char *type) = 0;
virtual int RegisterEnumValue(const char *type, const char *name, int value) = 0;
virtual asUINT GetEnumCount() const = 0;
virtual const char *GetEnumByIndex(asUINT index, int *enumTypeId, const char **nameSpace = 0, const char **configGroup = 0, asDWORD *accessMask = 0) const = 0;
virtual int GetEnumValueCount(int enumTypeId) const = 0;
virtual const char *GetEnumValueByIndex(int enumTypeId, asUINT index, int *outValue) const = 0;
virtual int RegisterEnum(const char *type) = 0;
virtual int RegisterEnumValue(const char *type, const char *name, int value) = 0;
virtual asUINT GetEnumCount() const = 0;
virtual asITypeInfo *GetEnumByIndex(asUINT index) const = 0;
// Funcdefs
virtual int RegisterFuncdef(const char *decl) = 0;
virtual asUINT GetFuncdefCount() const = 0;
virtual asIScriptFunction *GetFuncdefByIndex(asUINT index) const = 0;
virtual int RegisterFuncdef(const char *decl) = 0;
virtual asUINT GetFuncdefCount() const = 0;
virtual asITypeInfo *GetFuncdefByIndex(asUINT index) const = 0;
// Typedefs
virtual int RegisterTypedef(const char *type, const char *decl) = 0;
virtual asUINT GetTypedefCount() const = 0;
virtual const char *GetTypedefByIndex(asUINT index, int *typeId, const char **nameSpace = 0, const char **configGroup = 0, asDWORD *accessMask = 0) const = 0;
virtual int RegisterTypedef(const char *type, const char *decl) = 0;
virtual asUINT GetTypedefCount() const = 0;
virtual asITypeInfo *GetTypedefByIndex(asUINT index) const = 0;
// Configuration groups
virtual int BeginConfigGroup(const char *groupName) = 0;
@ -731,29 +725,26 @@ public:
// Script functions
virtual asIScriptFunction *GetFunctionById(int funcId) const = 0;
virtual asIScriptFunction *GetFuncDefFromTypeId(int typeId) const = 0;
// Type identification
virtual asIObjectType *GetObjectTypeById(int typeId) const = 0;
virtual int GetTypeIdByDecl(const char *decl) const = 0;
virtual const char *GetTypeDeclaration(int typeId, bool includeNamespace = false) const = 0;
virtual int GetSizeOfPrimitiveType(int typeId) const = 0;
virtual asITypeInfo *GetTypeInfoById(int typeId) const = 0;
virtual asITypeInfo *GetTypeInfoByName(const char *name) const = 0;
virtual asITypeInfo *GetTypeInfoByDecl(const char *decl) const = 0;
// Script execution
virtual asIScriptContext *CreateContext() = 0;
virtual void *CreateScriptObject(const asIObjectType *type) = 0;
virtual void *CreateScriptObjectCopy(void *obj, const asIObjectType *type) = 0;
virtual void *CreateUninitializedScriptObject(const asIObjectType *type) = 0;
virtual void *CreateScriptObject(const asITypeInfo *type) = 0;
virtual void *CreateScriptObjectCopy(void *obj, const asITypeInfo *type) = 0;
virtual void *CreateUninitializedScriptObject(const asITypeInfo *type) = 0;
virtual asIScriptFunction *CreateDelegate(asIScriptFunction *func, void *obj) = 0;
virtual int AssignScriptObject(void *dstObj, void *srcObj, const asIObjectType *type) = 0;
virtual void ReleaseScriptObject(void *obj, const asIObjectType *type) = 0;
virtual void AddRefScriptObject(void *obj, const asIObjectType *type) = 0;
virtual int RefCastObject(void *obj, asIObjectType *fromType, asIObjectType *toType, void **newPtr, bool useOnlyImplicitCast = false) = 0;
#ifdef AS_DEPRECATED
// Deprecated since 2.30.0, 2014-11-04
virtual bool IsHandleCompatibleWithObject(void *obj, int objTypeId, int handleTypeId) const = 0;
#endif
virtual asILockableSharedBool *GetWeakRefFlagOfScriptObject(void *obj, const asIObjectType *type) const = 0;
virtual int AssignScriptObject(void *dstObj, void *srcObj, const asITypeInfo *type) = 0;
virtual void ReleaseScriptObject(void *obj, const asITypeInfo *type) = 0;
virtual void AddRefScriptObject(void *obj, const asITypeInfo *type) = 0;
virtual int RefCastObject(void *obj, asITypeInfo *fromType, asITypeInfo *toType, void **newPtr, bool useOnlyImplicitCast = false) = 0;
virtual asILockableSharedBool *GetWeakRefFlagOfScriptObject(void *obj, const asITypeInfo *type) const = 0;
// Context pooling
virtual asIScriptContext *RequestContext() = 0;
@ -766,8 +757,8 @@ public:
// Garbage collection
virtual int GarbageCollect(asDWORD flags = asGC_FULL_CYCLE, asUINT numIterations = 1) = 0;
virtual void GetGCStatistics(asUINT *currentSize, asUINT *totalDestroyed = 0, asUINT *totalDetected = 0, asUINT *newObjects = 0, asUINT *totalNewDestroyed = 0) const = 0;
virtual int NotifyGarbageCollectorOfNewObject(void *obj, asIObjectType *type) = 0;
virtual int GetObjectInGC(asUINT idx, asUINT *seqNbr = 0, void **obj = 0, asIObjectType **type = 0) = 0;
virtual int NotifyGarbageCollectorOfNewObject(void *obj, asITypeInfo *type) = 0;
virtual int GetObjectInGC(asUINT idx, asUINT *seqNbr = 0, void **obj = 0, asITypeInfo **type = 0) = 0;
virtual void GCEnumCallback(void *reference) = 0;
// User data
@ -777,13 +768,24 @@ public:
virtual void SetModuleUserDataCleanupCallback(asCLEANMODULEFUNC_t callback, asPWORD type = 0) = 0;
virtual void SetContextUserDataCleanupCallback(asCLEANCONTEXTFUNC_t callback, asPWORD type = 0) = 0;
virtual void SetFunctionUserDataCleanupCallback(asCLEANFUNCTIONFUNC_t callback, asPWORD type = 0) = 0;
virtual void SetObjectTypeUserDataCleanupCallback(asCLEANOBJECTTYPEFUNC_t callback, asPWORD type = 0) = 0;
virtual void SetTypeInfoUserDataCleanupCallback(asCLEANTYPEINFOFUNC_t callback, asPWORD type = 0) = 0;
virtual void SetScriptObjectUserDataCleanupCallback(asCLEANSCRIPTOBJECTFUNC_t callback, asPWORD type = 0) = 0;
protected:
virtual ~asIScriptEngine() {}
};
class asIStringFactory
{
public:
virtual const void *GetStringConstant(const char *data, asUINT length) = 0;
virtual int ReleaseStringConstant(const void *str) = 0;
virtual int GetRawStringData(const void *str, char *data, asUINT *length) const = 0;
protected:
virtual ~asIStringFactory() {}
};
class asIThreadManager
{
protected:
@ -826,20 +828,18 @@ public:
// Type identification
virtual asUINT GetObjectTypeCount() const = 0;
virtual asIObjectType *GetObjectTypeByIndex(asUINT index) const = 0;
virtual asIObjectType *GetObjectTypeByName(const char *name) const = 0;
virtual asIObjectType *GetObjectTypeByDecl(const char *decl) const = 0;
virtual asITypeInfo *GetObjectTypeByIndex(asUINT index) const = 0;
virtual int GetTypeIdByDecl(const char *decl) const = 0;
virtual asITypeInfo *GetTypeInfoByName(const char *name) const = 0;
virtual asITypeInfo *GetTypeInfoByDecl(const char *decl) const = 0;
// Enums
virtual asUINT GetEnumCount() const = 0;
virtual const char *GetEnumByIndex(asUINT index, int *enumTypeId, const char **nameSpace = 0) const = 0;
virtual int GetEnumValueCount(int enumTypeId) const = 0;
virtual const char *GetEnumValueByIndex(int enumTypeId, asUINT index, int *outValue) const = 0;
virtual asUINT GetEnumCount() const = 0;
virtual asITypeInfo *GetEnumByIndex(asUINT index) const = 0;
// Typedefs
virtual asUINT GetTypedefCount() const = 0;
virtual const char *GetTypedefByIndex(asUINT index, int *typeId, const char **nameSpace = 0) const = 0;
virtual asUINT GetTypedefCount() const = 0;
virtual asITypeInfo *GetTypedefByIndex(asUINT index) const = 0;
// Dynamic binding between modules
virtual asUINT GetImportedFunctionCount() const = 0;
@ -948,6 +948,7 @@ public:
// Miscellaneous
virtual asIScriptEngine *GetEngine() const = 0;
virtual asIScriptFunction *GetFunction() const = 0;
virtual void *GetAuxiliary() const = 0;
// Object
virtual void *GetObject() = 0;
@ -992,7 +993,7 @@ public:
// Type info
virtual int GetTypeId() const = 0;
virtual asIObjectType *GetObjectType() const = 0;
virtual asITypeInfo *GetObjectType() const = 0;
// Class properties
virtual asUINT GetPropertyCount() const = 0;
@ -1012,7 +1013,7 @@ protected:
virtual ~asIScriptObject() {}
};
class asIObjectType
class asITypeInfo
{
public:
// Miscellaneous
@ -1028,19 +1029,19 @@ public:
// Type info
virtual const char *GetName() const = 0;
virtual const char *GetNamespace() const = 0;
virtual asIObjectType *GetBaseType() const = 0;
virtual bool DerivesFrom(const asIObjectType *objType) const = 0;
virtual asITypeInfo *GetBaseType() const = 0;
virtual bool DerivesFrom(const asITypeInfo *objType) const = 0;
virtual asDWORD GetFlags() const = 0;
virtual asUINT GetSize() const = 0;
virtual int GetTypeId() const = 0;
virtual int GetSubTypeId(asUINT subTypeIndex = 0) const = 0;
virtual asIObjectType *GetSubType(asUINT subTypeIndex = 0) const = 0;
virtual asITypeInfo *GetSubType(asUINT subTypeIndex = 0) const = 0;
virtual asUINT GetSubTypeCount() const = 0;
// Interfaces
virtual asUINT GetInterfaceCount() const = 0;
virtual asIObjectType *GetInterface(asUINT index) const = 0;
virtual bool Implements(const asIObjectType *objType) const = 0;
virtual asITypeInfo *GetInterface(asUINT index) const = 0;
virtual bool Implements(const asITypeInfo *objType) const = 0;
// Factories
virtual asUINT GetFactoryCount() const = 0;
@ -1055,19 +1056,34 @@ public:
// Properties
virtual asUINT GetPropertyCount() const = 0;
virtual int GetProperty(asUINT index, const char **name, int *typeId = 0, bool *isPrivate = 0, bool *isProtected = 0, int *offset = 0, bool *isReference = 0, asDWORD *accessMask = 0) const = 0;
virtual int GetProperty(asUINT index, const char **name, int *typeId = 0, bool *isPrivate = 0, bool *isProtected = 0, int *offset = 0, bool *isReference = 0, asDWORD *accessMask = 0, int *compositeOffset = 0, bool *isCompositeIndirect = 0) const = 0;
virtual const char *GetPropertyDeclaration(asUINT index, bool includeNamespace = false) const = 0;
// Behaviours
virtual asUINT GetBehaviourCount() const = 0;
virtual asIScriptFunction *GetBehaviourByIndex(asUINT index, asEBehaviours *outBehaviour) const = 0;
// Child types
virtual asUINT GetChildFuncdefCount() const = 0;
virtual asITypeInfo *GetChildFuncdef(asUINT index) const = 0;
virtual asITypeInfo *GetParentType() const = 0;
// Enums
virtual asUINT GetEnumValueCount() const = 0;
virtual const char *GetEnumValueByIndex(asUINT index, int *outValue) const = 0;
// Typedef
virtual int GetTypedefTypeId() const = 0;
// Funcdef
virtual asIScriptFunction *GetFuncdefSignature() const = 0;
// User data
virtual void *SetUserData(void *data, asPWORD type = 0) = 0;
virtual void *GetUserData(asPWORD type = 0) const = 0;
protected:
virtual ~asIObjectType() {}
virtual ~asITypeInfo() {}
};
class asIScriptFunction
@ -1087,9 +1103,10 @@ public:
virtual const char *GetScriptSectionName() const = 0;
virtual const char *GetConfigGroup() const = 0;
virtual asDWORD GetAccessMask() const = 0;
virtual void *GetAuxiliary() const = 0;
// Function signature
virtual asIObjectType *GetObjectType() const = 0;
virtual asITypeInfo *GetObjectType() const = 0;
virtual const char *GetObjectName() const = 0;
virtual const char *GetName() const = 0;
virtual const char *GetNamespace() const = 0;
@ -1102,10 +1119,6 @@ public:
virtual bool IsShared() const = 0;
virtual asUINT GetParamCount() const = 0;
virtual int GetParam(asUINT index, int *typeId, asDWORD *flags = 0, const char **name = 0, const char **defaultArg = 0) const = 0;
#ifdef AS_DEPRECATED
// Deprecated since 2.29.0, 2014-04-06
virtual int GetParamTypeId(asUINT index, asDWORD *flags = 0) const = 0;
#endif
virtual int GetReturnTypeId(asDWORD *flags = 0) const = 0;
// Type id for function pointers
@ -1114,7 +1127,7 @@ public:
// Delegates
virtual void *GetDelegateObject() const = 0;
virtual asIObjectType *GetDelegateObjectType() const = 0;
virtual asITypeInfo *GetDelegateObjectType() const = 0;
virtual asIScriptFunction *GetDelegateFunction() const = 0;
// Debug information
@ -1137,8 +1150,8 @@ protected:
class asIBinaryStream
{
public:
virtual void Read(void *ptr, asUINT size) = 0;
virtual void Write(const void *ptr, asUINT size) = 0;
virtual int Read(void *ptr, asUINT size) = 0;
virtual int Write(const void *ptr, asUINT size) = 0;
public:
virtual ~asIBinaryStream() {}
@ -1337,7 +1350,7 @@ struct asSVMRegisters
asDWORD *stackPointer; // top of stack (grows downward)
asQWORD valueRegister; // temp register for primitives
void *objectRegister; // temp register for objects and handles
asIObjectType *objectType; // type of object held in object register
asITypeInfo *objectType; // type of object held in object register
bool doProcessSuspend; // whether or not the JIT should break out when it encounters a suspend instruction
asIScriptContext *ctx; // the active context
};

View File

@ -137,8 +137,10 @@ 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})
# 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)
target_link_libraries(${ANGELSCRIPT_LIBRARY_NAME} ${CMAKE_THREAD_LIBS_INIT})
@ -160,7 +162,7 @@ if(MSVC)
set_target_properties(${ANGELSCRIPT_LIBRARY_NAME} PROPERTIES COMPILE_FLAGS "/MP")
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)
#add_subdirectory(../../../samples/game/projects/cmake/ ./game)

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2014 Andreas Jonsson
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
@ -468,10 +468,10 @@ bool asCArray<T>::Concatenate(const asCArray<T> &other)
}
template <class T>
void asCArray<T>::Concatenate(T* array, unsigned int count)
void asCArray<T>::Concatenate(T* other, unsigned int count)
{
for( unsigned int c = 0; c < count; c++ )
PushLast(array[c]);
PushLast(other[c]);
}
template <class T>

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +1,24 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
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
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
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
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
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
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
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
@ -99,13 +99,13 @@ struct sPropertyInitializer
struct sClassDeclaration
{
sClassDeclaration() {script = 0; node = 0; validState = 0; objType = 0; isExistingShared = false; isFinal = false;}
sClassDeclaration() {script = 0; node = 0; validState = 0; typeInfo = 0; isExistingShared = false; isFinal = false;}
asCScriptCode *script;
asCScriptNode *node;
asCString name;
int validState;
asCObjectType *objType;
asCTypeInfo *typeInfo;
bool isExistingShared;
bool isFinal;
@ -140,10 +140,10 @@ public:
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 **listPattern = 0);
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);
int CheckNameConflictMember(asCObjectType *type, const char *name, asCScriptNode *node, asCScriptCode *code, bool isProperty);
int CheckNameConflictMember(asCTypeInfo *type, const char *name, asCScriptNode *node, asCScriptCode *code, bool isProperty);
#ifndef AS_NO_COMPILER
int AddCode(const char *name, const char *code, int codeLength, int lineOffset, int sectionIdx, bool makeCopy);
@ -173,14 +173,16 @@ protected:
int ValidateDefaultArgs(asCScriptCode *script, asCScriptNode *node, asCScriptFunction *func);
asCString GetCleanExpressionString(asCScriptNode *n, asCScriptCode *file);
asSNameSpace *GetNameSpaceFromNode(asCScriptNode *node, asCScriptCode *script, asSNameSpace *implicitNs, asCScriptNode **next);
asSNameSpace *GetNameSpaceByString(const asCString &nsName, asSNameSpace *implicitNs, asCScriptNode *errNode, asCScriptCode *script, bool isRequired = true);
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);
asCScriptFunction *GetFuncDef(const char *type);
asCObjectType *GetObjectTypeFromTypesKnownByObject(const char *type, asCObjectType *currentType);
asCDataType CreateDataTypeFromNode(asCScriptNode *node, asCScriptCode *file, asSNameSpace *implicitNamespace, bool acceptHandleForScope = false, asCObjectType *currentType = 0);
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;
@ -204,7 +206,7 @@ protected:
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, bool isConstMethod, bool isConstructor, bool isDestructor, bool isPrivate, bool isProtected, bool isOverride, bool isFinal, bool isShared);
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);
@ -212,12 +214,13 @@ protected:
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);
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 GetParsedFunctionDetails(asCScriptNode *node, asCScriptCode *file, asCObjectType *objType, asCString &name, asCDataType &returnType, asCArray<asCString> &parameterNames, asCArray<asCDataType> &parameterTypes, asCArray<asETypeModifiers> &inOutFlags, asCArray<asCString *> &defaultArgs, bool &isConstMethod, bool &isConstructor, bool &isDestructor, bool &isPrivate, bool &isProtected, bool &isOverride, bool &isFinal, bool &isShared, asSNameSpace *implicitNamespace);
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);
@ -227,7 +230,7 @@ protected:
void RegisterNonTypesFromScript(asCScriptNode *node, asCScriptCode *script, asSNameSpace *ns);
void CompileFunctions();
void CompileGlobalVariables();
int GetEnumValueFromObjectType(asCObjectType *objType, const char *name, asCDataType &outDt, asDWORD &outValue);
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);

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
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
@ -1045,7 +1045,7 @@ void asCByteCode::OptimizeLocally(const asCArray<int> &tempVariableOffsets)
short tempVar = last->wArg[0];
asCArray<short> freedVars;
asCByteInstruction *instr = last->prev;
instr = last->prev;
asASSERT( instr && instr->op == asBC_Block );
instr = instr->prev;
while( instr && instr->op == asBC_FREE )
@ -1164,6 +1164,12 @@ void asCByteCode::Optimize()
DeleteInstruction(instr);
instr = GoBack(DeleteInstruction(curr));
}
// LINE, VarDecl, LINE -> VarDecl, LINE
else if (instrOp == asBC_VarDecl && instr->next && instr->next->op == asBC_LINE )
{
// Delete the first instruction
instr = GoBack(DeleteInstruction(curr));
}
// LINE, LINE -> LINE
else if( instrOp == asBC_LINE )
{
@ -1390,6 +1396,7 @@ bool asCByteCode::IsTempRegUsed(asCByteInstruction *curr)
curr->op == asBC_PopRPtr ||
curr->op == asBC_CALLSYS ||
curr->op == asBC_CALLBND ||
curr->op == asBC_Thiscall1 ||
curr->op == asBC_SUSPEND ||
curr->op == asBC_ALLOC ||
curr->op == asBC_CpyVtoR4 ||
@ -1444,7 +1451,8 @@ bool asCByteCode::IsSimpleExpression()
instr->op == asBC_FREE ||
instr->op == asBC_CallPtr ||
instr->op == asBC_CALLINTF ||
instr->op == asBC_CALLBND )
instr->op == asBC_CALLBND ||
instr->op == asBC_Thiscall1 )
return false;
instr = instr->next;
@ -1536,7 +1544,7 @@ void asCByteCode::ExtractObjectVariableInfo(asCScriptFunction *outFunc)
asSObjectVariableInfo info;
info.programPos = pos;
info.variableOffset = (short)instr->wArg[0];
info.option = *(int*)ARG_DW(instr->arg);
info.option = (asEObjVarInfoOption)*(int*)ARG_DW(instr->arg);
outFunc->scriptData->objVariableInfo.PushLast(info);
}
else if( instr->op == asBC_VarDecl )
@ -2064,18 +2072,23 @@ void asCByteCode::PostProcess()
}
#ifdef AS_DEBUG
void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScriptFunction *func)
void asCByteCode::DebugOutput(const char *name, asCScriptFunction *func)
{
_mkdir("AS_DEBUG");
asCString str = "AS_DEBUG/";
str += name;
asCString path = "AS_DEBUG/";
path += name;
// Anonymous functions created from within class methods will contain :: as part of the name
// Replace :: with __ to avoid error when creating the file for debug output
for (asUINT n = 0; n < path.GetLength(); n++)
if (path[n] == ':') path[n] = '_';
#if _MSC_VER >= 1500 && !defined(AS_MARMALADE)
FILE *file;
fopen_s(&file, str.AddressOf(), "w");
fopen_s(&file, path.AddressOf(), "w");
#else
FILE *file = fopen(str.AddressOf(), "w");
FILE *file = fopen(path.AddressOf(), "w");
#endif
#if !defined(AS_XENON) // XBox 360: When running in DVD Emu, no write is allowed
@ -2186,14 +2199,7 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
switch( asBCInfo[instr->op].type )
{
case asBCTYPE_W_ARG:
if( instr->op == asBC_STR )
{
int id = asWORD(instr->wArg[0]);
const asCString &str = engine->GetConstantString(id);
fprintf(file, " %-8s %d (l:%ld s:\"%.10s\")\n", asBCInfo[instr->op].name, asWORD(instr->wArg[0]), (long int)str.GetLength(), str.AddressOf());
}
else
fprintf(file, " %-8s %d\n", asBCInfo[instr->op].name, instr->wArg[0]);
fprintf(file, " %-8s %d\n", asBCInfo[instr->op].name, instr->wArg[0]);
break;
case asBCTYPE_wW_ARG:
@ -2237,8 +2243,8 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
case asBC_FuncPtr:
{
asCScriptFunction *func = *(asCScriptFunction**)ARG_DW(instr->arg);
fprintf(file, " %-8s 0x%x (func:%s)\n", asBCInfo[instr->op].name, (asUINT)*ARG_DW(instr->arg), func->GetDeclaration());
asCScriptFunction *f = *(asCScriptFunction**)ARG_DW(instr->arg);
fprintf(file, " %-8s 0x%x (func:%s)\n", asBCInfo[instr->op].name, (asUINT)*ARG_DW(instr->arg), f->GetDeclaration());
}
break;
@ -2298,8 +2304,8 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
case asBC_FuncPtr:
{
asCScriptFunction *func = *(asCScriptFunction**)ARG_QW(instr->arg);
fprintf(file, " %-8s 0x%x (func:%s)\n", asBCInfo[instr->op].name, (asUINT)*ARG_QW(instr->arg), func->GetDeclaration());
asCScriptFunction *f = *(asCScriptFunction**)ARG_QW(instr->arg);
fprintf(file, " %-8s 0x%x (func:%s)\n", asBCInfo[instr->op].name, (asUINT)*ARG_QW(instr->arg), f->GetDeclaration());
}
break;
@ -2345,8 +2351,8 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
if( instr->op == asBC_ALLOC )
{
asCObjectType *ot = *(asCObjectType**)ARG_DW(instr->arg);
asCScriptFunction *func = engine->scriptFunctions[instr->wArg[0]];
fprintf(file, " %-8s 0x%x, %d (type:%s, %s)\n", asBCInfo[instr->op].name, *(int*)ARG_DW(instr->arg), *(int*)(ARG_DW(instr->arg)+1), ot->GetName(), func ? func->GetDeclaration() : "{no func}");
asCScriptFunction *f = engine->scriptFunctions[instr->wArg[0]];
fprintf(file, " %-8s 0x%x, %d (type:%s, %s)\n", asBCInfo[instr->op].name, *(int*)ARG_DW(instr->arg), *(int*)(ARG_DW(instr->arg)+1), ot->GetName(), f ? f->GetDeclaration() : "{no func}");
}
else
fprintf(file, " %-8s %u, %d\n", asBCInfo[instr->op].name, *(int*)ARG_DW(instr->arg), *(int*)(ARG_DW(instr->arg)+1));
@ -2360,19 +2366,19 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
if( instr->op == asBC_ALLOC )
{
asCObjectType *ot = *(asCObjectType**)ARG_QW(instr->arg);
asCScriptFunction *func = engine->scriptFunctions[instr->wArg[0]];
#ifdef __GNUC__
asCScriptFunction *f = engine->scriptFunctions[instr->wArg[0]];
#if defined(__GNUC__) && !defined(_MSC_VER)
#ifdef AS_64BIT_PTR
fprintf(file, " %-8s 0x%lx, %d (type:%s, %s)\n", asBCInfo[instr->op].name, *(asINT64*)ARG_QW(instr->arg), *(int*)(ARG_DW(instr->arg)+2), ot->GetName(), func ? func->GetDeclaration() : "{no func}");
fprintf(file, " %-8s 0x%lx, %d (type:%s, %s)\n", asBCInfo[instr->op].name, *(asINT64*)ARG_QW(instr->arg), *(int*)(ARG_DW(instr->arg)+2), ot->GetName(), f ? f->GetDeclaration() : "{no func}");
#else
fprintf(file, " %-8s 0x%llx, %d (type:%s, %s)\n", asBCInfo[instr->op].name, *(asINT64*)ARG_QW(instr->arg), *(int*)(ARG_DW(instr->arg)+2), ot->GetName(), func ? func->GetDeclaration() : "{no func}");
fprintf(file, " %-8s 0x%llx, %d (type:%s, %s)\n", asBCInfo[instr->op].name, *(asINT64*)ARG_QW(instr->arg), *(int*)(ARG_DW(instr->arg)+2), ot->GetName(), f ? f->GetDeclaration() : "{no func}");
#endif
#else
fprintf(file, " %-8s 0x%I64x, %d (type:%s, %s)\n", asBCInfo[instr->op].name, *(asINT64*)ARG_QW(instr->arg), *(int*)(ARG_DW(instr->arg)+2), ot->GetName(), func ? func->GetDeclaration() : "{no func}");
fprintf(file, " %-8s 0x%I64x, %d (type:%s, %s)\n", asBCInfo[instr->op].name, *(asINT64*)ARG_QW(instr->arg), *(int*)(ARG_DW(instr->arg)+2), ot->GetName(), f ? f->GetDeclaration() : "{no func}");
#endif
}
else
#ifdef __GNUC__
#if defined(__GNUC__) && !defined(_MSC_VER)
#ifdef AS_64BIT_PTR
fprintf(file, " %-8s %lu, %d\n", asBCInfo[instr->op].name, *(asINT64*)ARG_QW(instr->arg), *(int*)(ARG_DW(instr->arg)+2));
#else

View File

@ -83,7 +83,7 @@ public:
void PostProcess();
#ifdef AS_DEBUG
void DebugOutput(const char *name, asCScriptEngine *engine, asCScriptFunction *func);
void DebugOutput(const char *name, asCScriptFunction *func);
#endif
int GetLastInstr();

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
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
@ -53,12 +53,12 @@ BEGIN_AS_NAMESPACE
// 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 *objForThiscall, asSSystemFunctionInterface *internal)
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->objForThiscall = 0;
internal->func = ptr.ptr.f.func;
internal->auxiliary = 0;
// Was a compatible calling convention specified?
if( internal->func )
@ -80,21 +80,26 @@ int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv,
internal->callConv = ICC_STDCALL;
else if( base == asCALL_THISCALL_ASGLOBAL )
{
if( objForThiscall == 0 )
if(auxiliary == 0)
return asINVALID_ARG;
internal->objForThiscall = objForThiscall;
internal->callConv = ICC_THISCALL;
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 )
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
@ -103,7 +108,7 @@ int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv,
internalCallConv thisCallConv;
if( base == asCALL_THISCALL )
{
if( callConv != asCALL_THISCALL_ASGLOBAL && objForThiscall )
if(callConv != asCALL_THISCALL_ASGLOBAL && auxiliary)
return asINVALID_ARG;
thisCallConv = ICC_THISCALL;
@ -113,10 +118,10 @@ int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv,
#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
return asNOT_SUPPORTED;
#else
if( objForThiscall == 0 )
if(auxiliary == 0)
return asINVALID_ARG;
internal->objForThiscall = objForThiscall;
internal->auxiliary = auxiliary;
if( base == asCALL_THISCALL_OBJFIRST )
thisCallConv = ICC_THISCALL_OBJFIRST;
else //if( base == asCALL_THISCALL_OBJLAST )
@ -151,8 +156,11 @@ int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv,
internal->callConv = ICC_CDECL_OBJLAST;
else if( base == asCALL_CDECL_OBJFIRST )
internal->callConv = ICC_CDECL_OBJFIRST;
else if( base == asCALL_GENERIC )
else if (base == asCALL_GENERIC)
{
internal->callConv = ICC_GENERIC_METHOD;
internal->auxiliary = auxiliary;
}
else
return asNOT_SUPPORTED;
}
@ -161,7 +169,7 @@ int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv,
}
// This function should prepare system functions so that it will be faster to call them
int PrepareSystemFunctionGeneric(asCScriptFunction *func, asSSystemFunctionInterface *internal, asCScriptEngine * /*engine*/)
int PrepareSystemFunctionGeneric(asCScriptFunction *func, asSSystemFunctionInterface *internal, asCScriptEngine *engine)
{
asASSERT(internal->callConv == ICC_GENERIC_METHOD || internal->callConv == ICC_GENERIC_FUNC);
@ -175,17 +183,25 @@ int PrepareSystemFunctionGeneric(asCScriptFunction *func, asSSystemFunctionInter
{
asCDataType &dt = func->parameterTypes[n];
if( dt.IsObject() && !dt.IsReference() )
if( (dt.IsObject() || dt.IsFuncdef()) && !dt.IsReference() )
{
asSTypeBehaviour *beh = &dt.GetObjectType()->beh;
if( dt.GetObjectType()->flags & asOBJ_REF )
if (dt.IsFuncdef())
{
asASSERT( (dt.GetObjectType()->flags & asOBJ_NOCOUNT) || beh->release );
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 )
{
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 = dt.GetObjectType();
clean.ot = CastToObjectType(dt.GetTypeInfo());
clean.off = short(offset);
internal->cleanArgs.PushLast(clean);
}
@ -194,10 +210,11 @@ int PrepareSystemFunctionGeneric(asCScriptFunction *func, asSSystemFunctionInter
{
asSSystemFunctionInterface::SClean clean;
clean.op = 1; // call free
clean.ot = dt.GetObjectType();
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
@ -222,7 +239,7 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
UNUSED_VAR(internal);
UNUSED_VAR(engine);
// This should never happen, as when AS_MAX_PORTABILITY is on, all functions
// This should never happen, as when AS_MAX_PORTABILITY is on, all functions
// are asCALL_GENERIC, which are prepared by PrepareSystemFunctionGeneric
asASSERT(false);
#else
@ -236,8 +253,8 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
// Registered types have special flags that determine how they are returned
else if( func->returnType.IsObject() )
{
asDWORD objType = func->returnType.GetObjectType()->flags;
asDWORD objType = func->returnType.GetTypeInfo()->flags;
// Only value types can be returned by value
asASSERT( objType & asOBJ_VALUE );
@ -247,7 +264,7 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, func->GetDeclarationStr().AddressOf());
asCString str;
str.Format(TXT_CANNOT_RET_TYPE_s_BY_VAL, func->returnType.GetObjectType()->name.AddressOf());
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);
}
@ -282,7 +299,7 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
internal->hostReturnInMemory = false;
internal->hostReturnSize = func->returnType.GetSizeInMemoryDWords();
#ifdef SPLIT_OBJS_BY_MEMBER_TYPES
if( func->returnType.GetObjectType()->flags & asOBJ_APP_CLASS_ALLFLOATS )
if( func->returnType.GetTypeInfo()->flags & asOBJ_APP_CLASS_ALLFLOATS )
internal->hostReturnFloat = true;
#endif
}
@ -329,7 +346,7 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
// 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.GetObjectType()->flags & (asOBJ_APP_CLASS_ALLINTS | asOBJ_APP_CLASS_ALLFLOATS)) )
!(func->returnType.GetTypeInfo()->flags & (asOBJ_APP_CLASS_ALLINTS | asOBJ_APP_CLASS_ALLFLOATS)) )
{
engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, func->GetDeclarationStr().AddressOf());
@ -405,12 +422,12 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
internal->takesObjByVal = true;
// Can't pass objects by value unless the application type is informed
if( !(func->parameterTypes[n].GetObjectType()->flags & (asOBJ_APP_CLASS | asOBJ_APP_PRIMITIVE | asOBJ_APP_FLOAT | asOBJ_APP_ARRAY)) )
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].GetObjectType()->name.AddressOf());
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);
}
@ -421,19 +438,19 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
// 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(
if(
#ifdef COMPLEX_OBJS_PASSED_BY_REF
!(func->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK) &&
!(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].GetObjectType()->flags & (asOBJ_APP_PRIMITIVE | asOBJ_APP_FLOAT | asOBJ_APP_CLASS_ALLINTS | asOBJ_APP_CLASS_ALLFLOATS)) )
!(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].GetObjectType()->name.AddressOf());
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);
}
@ -452,24 +469,24 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
#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.GetObjectType() && dt.GetObjectType()->flags & COMPLEX_MASK ) needFree = true;
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.IsObjectHandle() &&
!dt.IsReference() )
{
asSSystemFunctionInterface::SClean clean;
clean.op = 1; // call free
clean.ot = dt.GetObjectType();
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 = &dt.GetObjectType()->beh;
asSTypeBehaviour *beh = &CastToObjectType(dt.GetTypeInfo())->beh;
if( beh->destruct )
clean.op = 2; // call destruct, then free
#endif
@ -482,7 +499,10 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
{
asSSystemFunctionInterface::SClean clean;
clean.op = 0; // call release
clean.ot = dt.GetObjectType();
if (dt.IsFuncdef())
clean.ot = &engine->functionBehaviours;
else
clean.ot = CastToObjectType(dt.GetTypeInfo());
clean.off = short(offset);
internal->cleanArgs.PushLast(clean);
}
@ -533,7 +553,7 @@ int CallSystemFunction(int id, asCContext *context)
//
// Return value:
//
// The function should return the value that is returned in registers.
// 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);
@ -553,16 +573,22 @@ int CallSystemFunction(int id, asCContext *context)
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
void *obj = 0;
void *secondObj = 0;
if( callConv >= ICC_THISCALL )
{
if( sysFunc->objForThiscall )
if(sysFunc->auxiliary)
{
// This class method is being called as if it is a global function
obj = sysFunc->objForThiscall;
obj = sysFunc->auxiliary;
}
else
{
@ -593,13 +619,6 @@ int CallSystemFunction(int id, asCContext *context)
}
}
#else
// 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;
if( callConv >= ICC_THISCALL )
{
@ -608,15 +627,15 @@ int CallSystemFunction(int id, asCContext *context)
if( callConv >= ICC_THISCALL_OBJLAST )
{
asASSERT( sysFunc->objForThiscall != 0 );
// This class method is being called as object method (sysFunc->objForThiscall must be set).
obj = sysFunc->objForThiscall;
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->objForThiscall )
else if(sysFunc->auxiliary)
{
// This class method is being called as if it is a global function
obj = sysFunc->objForThiscall;
obj = sysFunc->auxiliary;
continueCheck = false;
}
@ -667,14 +686,21 @@ int CallSystemFunction(int id, asCContext *context)
popSize += AS_PTR_SIZE;
args += AS_PTR_SIZE;
// When returning the value on the location allocated by the called
// 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.GetObjectType();
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;
@ -682,10 +708,10 @@ int CallSystemFunction(int id, asCContext *context)
#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
// 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
// clean-up after the call to the real function, or that won't be
// executed in case of an exception.
try
{
@ -695,7 +721,7 @@ int CallSystemFunction(int id, asCContext *context)
{
cppException = true;
// Convert the exception to a script exception so the VM can
// Convert the exception to a script exception so the VM can
// properly report the error to the application and then clean up
context->SetException(TXT_EXCEPTION_CAUGHT);
}
@ -703,7 +729,7 @@ int CallSystemFunction(int id, asCContext *context)
context->m_callingSystemFunction = 0;
// Store the returned value in our stack
if( descr->returnType.IsObject() && !descr->returnType.IsReference() )
if( (descr->returnType.IsObject() || descr->returnType.IsFuncdef()) && !descr->returnType.IsReference() )
{
if( descr->returnType.IsObjectHandle() )
{
@ -717,8 +743,8 @@ int CallSystemFunction(int id, asCContext *context)
if( sysFunc->returnAutoHandle && context->m_regs.objectRegister )
{
asASSERT( !(descr->returnType.GetObjectType()->flags & asOBJ_NOCOUNT) );
engine->CallObjectMethod(context->m_regs.objectRegister, descr->returnType.GetObjectType()->beh.addref);
asASSERT( !(descr->returnType.GetTypeInfo()->flags & asOBJ_NOCOUNT) );
engine->CallObjectMethod(context->m_regs.objectRegister, CastToObjectType(descr->returnType.GetTypeInfo())->beh.addref);
}
}
else
@ -754,12 +780,12 @@ int CallSystemFunction(int id, asCContext *context)
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
// 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( descr->returnType.GetObjectType()->beh.destruct )
engine->CallObjectMethod(retPointer, descr->returnType.GetObjectType()->beh.destruct);
if(CastToObjectType(descr->returnType.GetTypeInfo())->beh.destruct )
engine->CallObjectMethod(retPointer, CastToObjectType(descr->returnType.GetTypeInfo())->beh.destruct);
}
}
}
@ -833,7 +859,7 @@ int CallSystemFunction(int id, asCContext *context)
// 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->objForThiscall == 0 )
if( callConv >= ICC_THISCALL && sysFunc->auxiliary == 0 )
args += AS_PTR_SIZE;
asSSystemFunctionInterface::SClean *clean = sysFunc->cleanArgs.AddressOf();
@ -848,14 +874,14 @@ int CallSystemFunction(int id, asCContext *context)
*addr = 0;
}
}
else
else
{
asASSERT( clean->op == 1 || clean->op == 2 );
asASSERT( *addr );
if( clean->op == 2 )
engine->CallObjectMethod(*addr, clean->ot->beh.destruct);
engine->CallFree(*addr);
}
}

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2014 Andreas Jonsson
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
@ -49,7 +49,7 @@ class asCScriptFunction;
class asCObjectType;
struct asSSystemFunctionInterface;
int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv, void *objForThiscall, asSSystemFunctionInterface *internal);
int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv, void *auxiliary, asSSystemFunctionInterface *internal);
int PrepareSystemFunctionGeneric(asCScriptFunction *func, asSSystemFunctionInterface *internal, asCScriptEngine *engine);
@ -59,7 +59,7 @@ int CallSystemFunction(int id, asCContext *context);
inline asPWORD FuncPtrToUInt(asFUNCTION_t func)
{
// A little trickery as the C++ standard doesn't allow direct
// 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;
@ -108,7 +108,9 @@ struct asSSystemFunctionInterface
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;
void *objForThiscall;
int compositeOffset;
bool isCompositeIndirect;
void *auxiliary; // can be used for functors, e.g. by asCALL_THISCALL_ASGLOBAL or asCALL_THISCALL_OBJFIRST
struct SClean
{
@ -118,7 +120,7 @@ struct asSSystemFunctionInterface
};
asCArray<SClean> cleanArgs;
asSSystemFunctionInterface() {}
asSSystemFunctionInterface() : func(0), baseOffset(0), callConv(ICC_GENERIC_FUNC), scriptReturnSize(0), hostReturnInMemory(false), hostReturnFloat(false), hostReturnSize(0), paramSize(0), takesObjByVal(false), returnAutoHandle(false), compositeOffset(0), isCompositeIndirect(false), auxiliary(0) {}
asSSystemFunctionInterface(const asSSystemFunctionInterface &in)
{
@ -127,19 +129,21 @@ struct asSSystemFunctionInterface
asSSystemFunctionInterface &operator=(const asSSystemFunctionInterface &in)
{
func = in.func;
baseOffset = in.baseOffset;
callConv = in.callConv;
scriptReturnSize = in.scriptReturnSize;
hostReturnInMemory = in.hostReturnInMemory;
hostReturnFloat = in.hostReturnFloat;
hostReturnSize = in.hostReturnSize;
paramSize = in.paramSize;
takesObjByVal = in.takesObjByVal;
paramAutoHandles = in.paramAutoHandles;
returnAutoHandle = in.returnAutoHandle;
objForThiscall = in.objForThiscall;
cleanArgs = in.cleanArgs;
func = in.func;
baseOffset = in.baseOffset;
callConv = in.callConv;
scriptReturnSize = in.scriptReturnSize;
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;
}
};

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2014 Andreas Jonsson
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
@ -150,7 +150,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
{
#ifdef COMPLEX_OBJS_PASSED_BY_REF
if( descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK )
if( descr->parameterTypes[n].GetTypeInfo()->flags & COMPLEX_MASK )
{
paramBuffer[dpos++] = args[spos++];
paramSize++;
@ -159,7 +159,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
#endif
{
#if defined(AS_ANDROID) || defined(AS_LINUX)
if( (descr->parameterTypes[n].GetObjectType()->flags & asOBJ_APP_CLASS_ALIGN8) &&
if( (descr->parameterTypes[n].GetTypeInfo()->flags & asOBJ_APP_CLASS_ALIGN8) &&
((dpos & 1) == mask) )
{
// 64 bit value align
@ -337,8 +337,8 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
if( sysFunc->hostReturnInMemory )
{
// TODO: runtime optimize: This check should be done in PrepareSystemFunction
if ( !( descr->returnType.GetObjectType()->flags & COMPLEX_RETURN_MASK ) &&
( descr->returnType.GetObjectType()->flags & asOBJ_APP_CLASS_ALLFLOATS ) &&
if ( !( descr->returnType.GetTypeInfo()->flags & COMPLEX_RETURN_MASK ) &&
( descr->returnType.GetTypeInfo()->flags & asOBJ_APP_CLASS_ALLFLOATS ) &&
descr->returnType.GetSizeInMemoryBytes() <= 8 )
callConv--;
@ -396,10 +396,10 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
{
// 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].GetObjectType()->flags & asOBJ_APP_ARRAY) )
!(descr->parameterTypes[n].GetTypeInfo()->flags & asOBJ_APP_ARRAY) )
{
#ifdef COMPLEX_OBJS_PASSED_BY_REF
if( descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK )
if( descr->parameterTypes[n].GetTypeInfo()->flags & COMPLEX_MASK )
{
paramBuffer[dpos++] = args[spos++];
paramSize++;
@ -407,7 +407,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
else
#endif
{
if( (descr->parameterTypes[n].GetObjectType()->flags & asOBJ_APP_CLASS_ALIGN8) )
if( (descr->parameterTypes[n].GetTypeInfo()->flags & asOBJ_APP_CLASS_ALIGN8) )
{
if ( (dpos & 1) == mask )
{
@ -425,7 +425,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
}
// Copy the object's memory to the buffer
if (descr->parameterTypes[n].GetObjectType()->flags & asOBJ_APP_CLASS_ALLFLOATS)
if (descr->parameterTypes[n].GetTypeInfo()->flags & asOBJ_APP_CLASS_ALLFLOATS)
{
int target = (freeFloatSlot > freeDoubleSlot) ? freeFloatSlot : freeDoubleSlot;
@ -645,8 +645,8 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
// TODO: runtime optimize: This should be identified with a flag determined in PrepareSystemFunction
if ( !descr->returnType.IsObjectHandle() &&
!descr->returnType.IsReference() &&
!(descr->returnType.GetObjectType()->flags & COMPLEX_RETURN_MASK) &&
(descr->returnType.GetObjectType()->flags & asOBJ_APP_CLASS_ALLFLOATS) )
!(descr->returnType.GetTypeInfo()->flags & COMPLEX_RETURN_MASK) &&
(descr->returnType.GetTypeInfo()->flags & asOBJ_APP_CLASS_ALLFLOATS) )
memcpy( retPointer, &paramBuffer[VFP_OFFSET], descr->returnType.GetSizeInMemoryBytes() );
}

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
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
@ -717,13 +717,14 @@ nomoreargsarmFuncR0R1:
#endif /* hard float abi */
#endif /* arm */
#if defined(__linux__) && defined(__ELF__)
/* ref: http://hardened.gentoo.org/gnu-stack.xml */
/* 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 /* arm */
#endif /* !AS_MAX_PORTABILITY */

View File

@ -135,7 +135,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
asCDataType &paramType = descr->parameterTypes[n];
if( paramType.IsObject() && !paramType.IsObjectHandle() && !paramType.IsReference() )
{
if( paramType.GetObjectType()->flags & COMPLEX_MASK )
if( paramType.GetTypeInfo()->flags & COMPLEX_MASK )
{
// The object is passed by reference
argBuffer[argOffset++] = args[spos++];
@ -143,7 +143,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
else
{
// Ensure 8byte alignment for classes that need it
if( (paramType.GetObjectType()->flags & asOBJ_APP_CLASS_ALIGN8) && (argOffset & 1) )
if( (paramType.GetTypeInfo()->flags & asOBJ_APP_CLASS_ALIGN8) && (argOffset & 1) )
argOffset++;
// Copy the object's memory to the buffer
@ -557,7 +557,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
{
#ifdef COMPLEX_OBJS_PASSED_BY_REF
if( descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK )
if( descr->parameterTypes[n].GetTypeInfo()->flags & COMPLEX_MASK )
{
paramBuffer[dpos++] = args[spos++];
paramSize++;

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2014 Andreas Jonsson
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
@ -576,7 +576,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
{
#ifdef COMPLEX_OBJS_PASSED_BY_REF
if( descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK )
if( descr->parameterTypes[n].GetTypeInfo()->flags & COMPLEX_MASK )
{
argsType[a++] = ppcINTARG;
paramBuffer[dpos++] = args[spos++];

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2014 Andreas Jonsson
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
@ -41,6 +41,10 @@
#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"
@ -666,10 +670,10 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
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].GetObjectType()->flags & asOBJ_APP_ARRAY) )
!(descr->parameterTypes[n].GetTypeInfo()->flags & asOBJ_APP_ARRAY) )
{
#ifdef COMPLEX_OBJS_PASSED_BY_REF
if( descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK )
if( descr->parameterTypes[n].GetTypeInfo()->flags & COMPLEX_MASK )
{
paramBuffer[dpos++] = args[spos++];
++paramSize;
@ -763,6 +767,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
END_AS_NAMESPACE
#endif // AS_PTR_SIZE == 2
#endif // AS_PPC_64
#endif // AS_MAX_PORTABILITY

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2014 Andreas Jonsson
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
@ -313,7 +313,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
{
#ifdef COMPLEX_OBJS_PASSED_BY_REF
if( descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK )
if( descr->parameterTypes[n].GetTypeInfo()->flags & COMPLEX_MASK )
{
paramBuffer[dpos++] = args[spos++];
paramSize++;

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
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
@ -157,7 +157,7 @@ static asQWORD __attribute__((noinline)) X64_CallFunction(const asQWORD *args, i
" movq %%rdx, %4 \n"
"endcall: \n"
: : "r" ((asQWORD)cnt), "r" (args), "r" (func), "m" (retQW1), "m" (retQW2), "m" (returnFloat)
: : "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");
@ -345,7 +345,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
else
{
// An object is being passed by value
if( (parmType.GetObjectType()->flags & COMPLEX_MASK) ||
if( (parmType.GetTypeInfo()->flags & COMPLEX_MASK) ||
parmType.GetSizeInMemoryDWords() > 4 )
{
// Copy the address of the object
@ -353,8 +353,8 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
memcpy(paramBuffer + argIndex, stack_pointer, sizeof(asQWORD));
argIndex++;
}
else if( (parmType.GetObjectType()->flags & asOBJ_APP_CLASS_ALLINTS) ||
(parmType.GetObjectType()->flags & asOBJ_APP_PRIMITIVE) )
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 )
@ -373,8 +373,8 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
// Delete the original memory
engine->CallFree(*(void**)stack_pointer);
}
else if( (parmType.GetObjectType()->flags & asOBJ_APP_CLASS_ALLFLOATS) ||
(parmType.GetObjectType()->flags & asOBJ_APP_FLOAT) )
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 )

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2014 Andreas Jonsson
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
@ -248,7 +248,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
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].GetObjectType()->flags & COMPLEX_MASK) )
(descr->parameterTypes[n].GetTypeInfo()->flags & COMPLEX_MASK) )
{
allArgBuffer[dpos++] = *(asQWORD*)&args[spos];
spos += AS_PTR_SIZE;

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2014 Andreas Jonsson
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
@ -119,7 +119,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
if( dt.IsObject() && !dt.IsObjectHandle() && !dt.IsReference() )
{
if( dt.GetSizeInMemoryDWords() >= AS_LARGE_OBJ_MIN_SIZE ||
(dt.GetObjectType()->flags & COMPLEX_MASK) )
(dt.GetTypeInfo()->flags & COMPLEX_MASK) )
{
allArgBuffer[dpos++] = *(asQWORD*)&args[spos];
spos += AS_PTR_SIZE;

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
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
@ -126,7 +126,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
{
#ifdef COMPLEX_OBJS_PASSED_BY_REF
if( descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK )
if( descr->parameterTypes[n].GetTypeInfo()->flags & COMPLEX_MASK )
{
paramBuffer[dpos++] = args[spos++];
paramSize++;
@ -340,6 +340,17 @@ endcopy:
volatile asPWORD a[] = {asPWORD(args), asPWORD(paramSize), asPWORD(func)};
asm __volatile__(
#ifdef __OPTIMIZE__
// When compiled with optimizations the stack unwind doesn't work properly,
// causing exceptions to crash the application. By adding this prologue
// and the epilogue below, the stack unwind works as it should.
// TODO: runtime optimize: The prologue/epilogue shouldn't be needed if the correct cfi directives are used below
"pushl %%ebp \n"
".cfi_adjust_cfa_offset 4 \n"
".cfi_rel_offset ebp, 0 \n"
"movl %%esp, %%ebp \n"
".cfi_def_cfa_register ebp \n"
#endif
_S(CLEAR_FPU_STACK) "\n"
"pushl %%ebx \n"
"movl %%edx, %%ebx \n"
@ -374,7 +385,14 @@ endcopy:
// Pop the alignment bytes
"popl %%esp \n"
"popl %%ebx \n"
#ifdef __OPTIMIZE__
// Epilogue
"movl %%ebp, %%esp \n"
".cfi_def_cfa_register esp \n"
"popl %%ebp \n"
".cfi_adjust_cfa_offset -4 \n"
".cfi_restore ebp \n"
#endif
// Copy EAX:EDX to retQW. As the stack pointer has been
// restored it is now safe to access the local variable
"leal %1, %%ecx \n"
@ -444,6 +462,17 @@ endcopy:
volatile asPWORD a[] = {asPWORD(obj), asPWORD(args), asPWORD(paramSize), asPWORD(func)};
asm __volatile__ (
#ifdef __OPTIMIZE__
// When compiled with optimizations the stack unwind doesn't work properly,
// causing exceptions to crash the application. By adding this prologue
// and the epilogue below, the stack unwind works as it should.
// TODO: runtime optimize: The prologue/epilogue shouldn't be needed if the correct cfi directives are used below
"pushl %%ebp \n"
".cfi_adjust_cfa_offset 4 \n"
".cfi_rel_offset ebp, 0 \n"
"movl %%esp, %%ebp \n"
".cfi_def_cfa_register ebp \n"
#endif
_S(CLEAR_FPU_STACK) "\n"
"pushl %%ebx \n"
"movl %%edx, %%ebx \n"
@ -479,7 +508,14 @@ endcopy:
// Pop the alignment bytes
"popl %%esp \n"
"popl %%ebx \n"
#ifdef __OPTIMIZE__
// Epilogue
"movl %%ebp, %%esp \n"
".cfi_def_cfa_register esp \n"
"popl %%ebp \n"
".cfi_adjust_cfa_offset -4 \n"
".cfi_restore ebp \n"
#endif
// Copy EAX:EDX to retQW. As the stack pointer has been
// restored it is now safe to access the local variable
"leal %1, %%ecx \n"
@ -549,6 +585,17 @@ endcopy:
volatile asPWORD a[] = {asPWORD(obj), asPWORD(args), asPWORD(paramSize), asPWORD(func)};
asm __volatile__ (
#ifdef __OPTIMIZE__
// When compiled with optimizations the stack unwind doesn't work properly,
// causing exceptions to crash the application. By adding this prologue
// and the epilogue below, the stack unwind works as it should.
// TODO: runtime optimize: The prologue/epilogue shouldn't be needed if the correct cfi directives are used below
"pushl %%ebp \n"
".cfi_adjust_cfa_offset 4 \n"
".cfi_rel_offset ebp, 0 \n"
"movl %%esp, %%ebp \n"
".cfi_def_cfa_register ebp \n"
#endif
_S(CLEAR_FPU_STACK) "\n"
"pushl %%ebx \n"
"movl %%edx, %%ebx \n"
@ -584,7 +631,14 @@ endcopy:
// Pop the alignment bytes
"popl %%esp \n"
"popl %%ebx \n"
#ifdef __OPTIMIZE__
// Epilogue
"movl %%ebp, %%esp \n"
".cfi_def_cfa_register esp \n"
"popl %%ebp \n"
".cfi_adjust_cfa_offset -4 \n"
".cfi_restore ebp \n"
#endif
// Copy EAX:EDX to retQW. As the stack pointer has been
// restored it is now safe to access the local variable
"leal %1, %%ecx \n"
@ -663,6 +717,17 @@ endcopy:
volatile asPWORD a[] = {asPWORD(obj), asPWORD(args), asPWORD(paramSize), asPWORD(func), asPWORD(retPtr)};
asm __volatile__ (
#ifdef __OPTIMIZE__
// When compiled with optimizations the stack unwind doesn't work properly,
// causing exceptions to crash the application. By adding this prologue
// and the epilogue below, the stack unwind works as it should.
// TODO: runtime optimize: The prologue/epilogue shouldn't be needed if the correct cfi directives are used below
"pushl %%ebp \n"
".cfi_adjust_cfa_offset 4 \n"
".cfi_rel_offset ebp, 0 \n"
"movl %%esp, %%ebp \n"
".cfi_def_cfa_register ebp \n"
#endif
_S(CLEAR_FPU_STACK) "\n"
"pushl %%ebx \n"
"movl %%edx, %%ebx \n"
@ -702,7 +767,14 @@ endcopy:
// Pop the alignment bytes
"popl %%esp \n"
"popl %%ebx \n"
#ifdef __OPTIMIZE__
// Epilogue
"movl %%ebp, %%esp \n"
".cfi_def_cfa_register esp \n"
"popl %%ebp \n"
".cfi_adjust_cfa_offset -4 \n"
".cfi_restore ebp \n"
#endif
// Copy EAX:EDX to retQW. As the stack pointer has been
// restored it is now safe to access the local variable
"leal %1, %%ecx \n"
@ -777,6 +849,17 @@ endcopy:
volatile asPWORD a[] = {asPWORD(args), asPWORD(paramSize), asPWORD(func), asPWORD(retPtr)};
asm __volatile__ (
#ifdef __OPTIMIZE__
// When compiled with optimizations the stack unwind doesn't work properly,
// causing exceptions to crash the application. By adding this prologue
// and the epilogue below, the stack unwind works as it should.
// TODO: runtime optimize: The prologue/epilogue shouldn't be needed if the correct cfi directives are used below
"pushl %%ebp \n"
".cfi_adjust_cfa_offset 4 \n"
".cfi_rel_offset ebp, 0 \n"
"movl %%esp, %%ebp \n"
".cfi_def_cfa_register ebp \n"
#endif
_S(CLEAR_FPU_STACK) "\n"
"pushl %%ebx \n"
"movl %%edx, %%ebx \n"
@ -813,7 +896,14 @@ endcopy:
// Pop the alignment bytes
"popl %%esp \n"
"popl %%ebx \n"
#ifdef __OPTIMIZE__
// Epilogue
"movl %%ebp, %%esp \n"
".cfi_def_cfa_register esp \n"
"popl %%ebp \n"
".cfi_adjust_cfa_offset -4 \n"
".cfi_restore ebp \n"
#endif
// Copy EAX:EDX to retQW. As the stack pointer has been
// restored it is now safe to access the local variable
"leal %1, %%ecx \n"
@ -890,6 +980,17 @@ endcopy:
volatile asPWORD a[] = {asPWORD(obj), asPWORD(args), asPWORD(paramSize), asPWORD(func), asPWORD(retPtr)};
asm __volatile__ (
#ifdef __OPTIMIZE__
// When compiled with optimizations the stack unwind doesn't work properly,
// causing exceptions to crash the application. By adding this prologue
// and the epilogue below, the stack unwind works as it should.
// TODO: runtime optimize: The prologue/epilogue shouldn't be needed if the correct cfi directives are used below
"pushl %%ebp \n"
".cfi_adjust_cfa_offset 4 \n"
".cfi_rel_offset ebp, 0 \n"
"movl %%esp, %%ebp \n"
".cfi_def_cfa_register ebp \n"
#endif
_S(CLEAR_FPU_STACK) "\n"
"pushl %%ebx \n"
"movl %%edx, %%ebx \n"
@ -929,7 +1030,14 @@ endcopy:
// Pop the alignment bytes
"popl %%esp \n"
"popl %%ebx \n"
#ifdef __OPTIMIZE__
// Epilogue
"movl %%ebp, %%esp \n"
".cfi_def_cfa_register esp \n"
"popl %%ebp \n"
".cfi_adjust_cfa_offset -4 \n"
".cfi_restore ebp \n"
#endif
// Copy EAX:EDX to retQW. As the stack pointer has been
// restored it is now safe to access the local variable
"leal %1, %%ecx \n"
@ -994,6 +1102,17 @@ endcopy:
volatile asPWORD a[] = {asPWORD(args), asPWORD(paramSize), asPWORD(func)};
asm __volatile__ (
#ifdef __OPTIMIZE__
// When compiled with optimizations the stack unwind doesn't work properly,
// causing exceptions to crash the application. By adding this prologue
// and the epilogue below, the stack unwind works as it should.
// TODO: runtime optimize: The prologue/epilogue shouldn't be needed if the correct cfi directives are used below
"pushl %%ebp \n"
".cfi_adjust_cfa_offset 4 \n"
".cfi_rel_offset ebp, 0 \n"
"movl %%esp, %%ebp \n"
".cfi_def_cfa_register ebp \n"
#endif
_S(CLEAR_FPU_STACK) "\n"
"pushl %%ebx \n"
"movl %%edx, %%ebx \n"
@ -1026,7 +1145,14 @@ endcopy:
// Pop the alignment bytes
"popl %%esp \n"
"popl %%ebx \n"
#ifdef __OPTIMIZE__
// Epilogue
"movl %%ebp, %%esp \n"
".cfi_def_cfa_register esp \n"
"popl %%ebp \n"
".cfi_adjust_cfa_offset -4 \n"
".cfi_restore ebp \n"
#endif
// Copy EAX:EDX to retQW. As the stack pointer has been
// restored it is now safe to access the local variable
"leal %1, %%ecx \n"
@ -1107,6 +1233,17 @@ endcopy:
volatile asPWORD a[] = {asPWORD(obj), asPWORD(args), asPWORD(paramSize), asPWORD(func)};
asm __volatile__ (
#ifdef __OPTIMIZE__
// When compiled with optimizations the stack unwind doesn't work properly,
// causing exceptions to crash the application. By adding this prologue
// and the epilogue below, the stack unwind works as it should.
// TODO: runtime optimize: The prologue/epilogue shouldn't be needed if the correct cfi directives are used below
"pushl %%ebp \n"
".cfi_adjust_cfa_offset 4 \n"
".cfi_rel_offset ebp, 0 \n"
"movl %%esp, %%ebp \n"
".cfi_def_cfa_register ebp \n"
#endif
_S(CLEAR_FPU_STACK) "\n"
"pushl %%ebx \n"
"movl %%edx, %%ebx \n"
@ -1148,7 +1285,14 @@ endcopy:
// Pop the alignment bytes
"popl %%esp \n"
"popl %%ebx \n"
#ifdef __OPTIMIZE__
// Epilogue
"movl %%ebp, %%esp \n"
".cfi_def_cfa_register esp \n"
"popl %%ebp \n"
".cfi_adjust_cfa_offset -4 \n"
".cfi_restore ebp \n"
#endif
// Copy EAX:EDX to retQW. As the stack pointer has been
// restored it is now safe to access the local variable
"leal %1, %%ecx \n"
@ -1236,6 +1380,17 @@ endcopy:
volatile asPWORD a[] = {asPWORD(obj), asPWORD(args), asPWORD(paramSize), asPWORD(func), asPWORD(retPtr)};
asm __volatile__ (
#ifdef __OPTIMIZE__
// When compiled with optimizations the stack unwind doesn't work properly,
// causing exceptions to crash the application. By adding this prologue
// and the epilogue below, the stack unwind works as it should.
// TODO: runtime optimize: The prologue/epilogue shouldn't be needed if the correct cfi directives are used below
"pushl %%ebp \n"
".cfi_adjust_cfa_offset 4 \n"
".cfi_rel_offset ebp, 0 \n"
"movl %%esp, %%ebp \n"
".cfi_def_cfa_register ebp \n"
#endif
_S(CLEAR_FPU_STACK) "\n"
"pushl %%ebx \n"
"movl %%edx, %%ebx \n"
@ -1290,7 +1445,14 @@ endcopy:
// Pop the alignment bytes
"popl %%esp \n"
"popl %%ebx \n"
#ifdef __OPTIMIZE__
// Epilogue
"movl %%ebp, %%esp \n"
".cfi_def_cfa_register esp \n"
"popl %%ebp \n"
".cfi_adjust_cfa_offset -4 \n"
".cfi_restore ebp \n"
#endif
// Copy EAX:EDX to retQW. As the stack pointer has been
// restored it is now safe to access the local variable
"leal %1, %%ecx \n"

View File

@ -552,7 +552,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
!descr->parameterTypes[n].IsReference() )
{
#ifdef COMPLEX_OBJS_PASSED_BY_REF
if( descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK )
if( descr->parameterTypes[n].GetTypeInfo()->flags & COMPLEX_MASK )
{
paramBuffer[dpos++] = args[spos++];
paramSize++;

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
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
@ -50,123 +50,110 @@
#include "as_bytecode.h"
#include "as_array.h"
#include "as_datatype.h"
#include "as_typeinfo.h"
BEGIN_AS_NAMESPACE
struct asSExprContext;
// 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 isHandleSafe : 1; // the life-time of the handle 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;
asCTypeInfo argType;
asCExprValue argType;
int argInOutFlags;
asSExprContext *origExpr;
asCExprContext *origExpr;
};
// TODO: refactor: asSExprContext should have indicators to inform where the value is,
// 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
struct asSExprContext
// This class holds information about an expression that is being evaluated, e.g.
// the current bytecode, ambiguous symbol names, property accessors, etc.
struct asCExprContext
{
asSExprContext(asCScriptEngine *engine) : bc(engine)
{
property_arg = 0;
Clear();
}
~asSExprContext()
{
if( property_arg )
asDELETE(property_arg, asSExprContext);
}
void Clear()
{
bc.ClearAll();
type.Set(asCDataType());
deferredParams.SetLength(0);
if( property_arg )
asDELETE(property_arg, asSExprContext);
property_arg = 0;
exprNode = 0;
origExpr = 0;
property_get = 0;
property_set = 0;
property_const = false;
property_handle = false;
property_ref = false;
methodName = "";
enumValue = "";
isVoidExpression = false;
isCleanArg = false;
}
bool IsClassMethod() const
{
if( type.dataType.GetObjectType() == 0 ) return false;
if( methodName == "" ) return false;
if( type.dataType.GetObjectType() == &type.dataType.GetObjectType()->engine->functionBehaviours ) return false;
return true;
}
bool IsGlobalFunc() const
{
if( type.dataType.GetObjectType() == 0 ) return false;
if( methodName == "" ) return false;
if( type.dataType.GetObjectType() != &type.dataType.GetObjectType()->engine->functionBehaviours ) return false;
return true;
}
void SetLambda(asCScriptNode *funcDecl)
{
asASSERT( funcDecl && funcDecl->nodeType == snFunction );
asASSERT( bc.GetLastInstr() == -1 );
Clear();
type.SetUndefinedFuncHandle(bc.GetEngine());
exprNode = funcDecl;
}
bool IsLambda() const
{
if( type.IsUndefinedFuncHandle() && exprNode && exprNode->nodeType == snFunction )
return true;
return false;
}
void SetVoidExpression()
{
Clear();
type.SetVoid();
isVoidExpression = true;
}
bool IsVoidExpression() const
{
if( isVoidExpression && type.IsVoid() && exprNode == 0 )
return true;
return false;
}
void Merge(asSExprContext *after)
{
type = after->type;
property_get = after->property_get;
property_set = after->property_set;
property_const = after->property_const;
property_handle = after->property_handle;
property_ref = after->property_ref;
property_arg = after->property_arg;
exprNode = after->exprNode;
methodName = after->methodName;
enumValue = after->enumValue;
isVoidExpression = after->isVoidExpression;
isCleanArg = after->isCleanArg;
after->property_arg = 0;
// Do not copy the origExpr member
}
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 SetAnonymousInitList(asCScriptNode *initList);
bool IsAnonymousInitList() const;
asCByteCode bc;
asCTypeInfo type;
asCExprValue type;
int property_get;
int property_set;
bool property_const; // If the object that is being accessed through property accessor is read-only
@ -174,19 +161,20 @@ struct asSExprContext
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
asSExprContext *property_arg;
asCExprContext *property_arg;
asCArray<asSDeferredParam> deferredParams;
asCScriptNode *exprNode;
asSExprContext *origExpr;
asCExprContext *origExpr;
// TODO: cleanup: use ambiguousName and an enum to say if it is a method, global func, or enum value
asCString methodName;
asCString enumValue;
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) {}
asSOverloadCandidate(int _id, asUINT _cost) : funcId(_id), cost(_cost) {}
int funcId;
asUINT cost;
};
@ -194,7 +182,7 @@ struct asSOverloadCandidate
struct asSNamedArgument
{
asCString name;
asSExprContext *ctx;
asCExprContext *ctx;
asUINT match;
};
@ -209,13 +197,15 @@ enum EConvCost
{
asCC_NO_CONV = 0,
asCC_CONST_CONV = 1,
asCC_PRIMITIVE_SIZE_CONV = 2,
asCC_SIGNED_CONV = 3,
asCC_INT_FLOAT_CONV = 4,
asCC_REF_CONV = 5,
asCC_OBJ_TO_PRIMITIVE_CONV = 6,
asCC_TO_OBJECT_CONV = 7,
asCC_VARIABLE_CONV = 8
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
@ -250,93 +240,94 @@ protected:
void CompileExpressionStatement(asCScriptNode *node, asCByteCode *bc);
// Expressions
int CompileAssignment(asCScriptNode *expr, asSExprContext *out);
int CompileCondition(asCScriptNode *expr, asSExprContext *out);
int CompileExpression(asCScriptNode *expr, asSExprContext *out);
int CompilePostFixExpression(asCArray<asCScriptNode *> *postfix, asSExprContext *out);
int CompileExpressionTerm(asCScriptNode *node, asSExprContext *out);
int CompileExpressionPreOp(asCScriptNode *node, asSExprContext *out);
int CompileExpressionPostOp(asCScriptNode *node, asSExprContext *out);
int CompileExpressionValue(asCScriptNode *node, asSExprContext *out);
int CompileFunctionCall(asCScriptNode *node, asSExprContext *out, asCObjectType *objectType, bool objIsConst, const asCString &scope = "");
int CompileConstructCall(asCScriptNode *node, asSExprContext *out);
int CompileConversion(asCScriptNode *node, asSExprContext *out);
int CompileOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out, eTokenType opToken = ttUnrecognizedToken);
void CompileOperatorOnHandles(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out, eTokenType opToken = ttUnrecognizedToken);
void CompileMathOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out, eTokenType opToken = ttUnrecognizedToken);
void CompileBitwiseOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out, eTokenType opToken = ttUnrecognizedToken);
void CompileComparisonOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out, eTokenType opToken = ttUnrecognizedToken);
void CompileBooleanOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out, eTokenType opToken = ttUnrecognizedToken);
bool CompileOverloadedDualOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out, bool isHandle = false, eTokenType opToken = ttUnrecognizedToken);
int CompileOverloadedDualOperator2(asCScriptNode *node, const char *methodName, asSExprContext *l, asSExprContext *r, asSExprContext *out, bool specificReturn = false, const asCDataType &returnType = asCDataType::CreatePrimitive(ttVoid, false));
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(asCTypeInfo *var, asCScriptNode *node, asCByteCode *bc, int isVarGlobOrMem);
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 CompilerAnonymousInitList(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, asSExprContext *arg, asCScriptNode *node, bool isGlobalVar = false, bool derefDestination = 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<asSExprContext *> &args, asCArray<asSNamedArgument> &namedArgs);
int CompileDefaultAndNamedArgs(asCScriptNode *node, asCArray<asSExprContext*> &args, int funcId, asCObjectType *type, asCArray<asSNamedArgument> *namedArgs = 0);
asUINT MatchFunctions(asCArray<int> &funcs, asCArray<asSExprContext*> &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, asSExprContext *ctx, asCScriptNode *errNode, bool isOptional = false, bool noFunction = false, bool noGlobal = false, asCObjectType *objType = 0);
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, bool noFunction = false, bool noGlobal = false, asCObjectType *objType = 0);
void CompileMemberInitialization(asCByteCode *bc, bool onlyDefaults);
bool CompileAutoType(asCDataType &autoType, asSExprContext &compiledCtx, asCScriptNode *exprNode, asCScriptNode *errNode);
bool CompileInitialization(asCScriptNode *node, asCByteCode *bc, asCDataType &type, asCScriptNode *errNode, int offset, asQWORD *constantValue, int isVarGlobOrMem, asSExprContext *preCompiled = 0);
void CompileInitAsCopy(asCDataType &type, int offset, asCByteCode *bc, asSExprContext *arg, asCScriptNode *node, bool derefDestination);
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);
void ProcessPropertyGetAccessor(asSExprContext *ctx, asCScriptNode *node);
int ProcessPropertySetAccessor(asSExprContext *ctx, asSExprContext *arg, asCScriptNode *node);
int ProcessPropertyGetSetAccessor(asSExprContext *ctx, asSExprContext *lctx, asSExprContext *rctx, eTokenType op, asCScriptNode *errNode);
int FindPropertyAccessor(const asCString &name, asSExprContext *ctx, asCScriptNode *node, asSNameSpace *ns, bool isThisAccess = false);
int FindPropertyAccessor(const asCString &name, asSExprContext *ctx, asSExprContext *arg, asCScriptNode *node, asSNameSpace *ns, bool isThisAccess = false);
void PrepareTemporaryObject(asCScriptNode *node, asSExprContext *ctx, bool forceOnHeap = false);
void PrepareOperand(asSExprContext *ctx, asCScriptNode *node);
void PrepareForAssignment(asCDataType *lvalue, asSExprContext *rvalue, asCScriptNode *node, bool toTemporary, asSExprContext *lvalueExpr = 0);
int PerformAssignment(asCTypeInfo *lvalue, asCTypeInfo *rvalue, asCByteCode *bc, asCScriptNode *node);
bool IsVariableInitialized(asCTypeInfo *type, asCScriptNode *node);
void Dereference(asSExprContext *ctx, bool generateCode);
bool CompileRefCast(asSExprContext *ctx, const asCDataType &to, bool isExplicit, asCScriptNode *node, bool generateCode = true);
asUINT MatchArgument(asCArray<int> &funcs, asCArray<asSOverloadCandidate> &matches, const asSExprContext *argExpr, int paramNum, bool allowObjectConstruct = true);
int MatchArgument(asCScriptFunction *desc, const asSExprContext *argExpr, int paramNum, bool allowObjectConstruct = true);
void PerformFunctionCall(int funcId, asSExprContext *out, bool isConstructor = false, asCArray<asSExprContext*> *args = 0, asCObjectType *objTypeForConstruct = 0, bool useVariable = false, int varOffset = 0, int funcPtrVar = 0);
void MoveArgsToStack(int funcId, asCByteCode *bc, asCArray<asSExprContext *> &args, bool addOneToOffset);
void MakeFunctionCall(asSExprContext *ctx, int funcId, asCObjectType *objectType, asCArray<asSExprContext*> &args, asCScriptNode *node, bool useVariable = false, int stackOffset = 0, int funcPtrVar = 0);
void PrepareFunctionCall(int funcId, asCByteCode *bc, asCArray<asSExprContext *> &args);
void AfterFunctionCall(int funcId, asCArray<asSExprContext*> &args, asSExprContext *ctx, bool deferAll);
void ProcessDeferredParams(asSExprContext *ctx);
int PrepareArgument(asCDataType *paramType, asSExprContext *ctx, asCScriptNode *node, bool isFunction = false, int refType = 0, bool isMakingCopy = false);
void PrepareArgument2(asSExprContext *ctx, asSExprContext *arg, asCDataType *paramType, bool isFunction = false, int refType = 0, bool isMakingCopy = false);
bool IsLValue(asCTypeInfo &type);
int DoAssignment(asSExprContext *out, asSExprContext *lctx, asSExprContext *rctx, asCScriptNode *lexpr, asCScriptNode *rexpr, eTokenType op, asCScriptNode *opNode);
void MergeExprBytecode(asSExprContext *before, asSExprContext *after);
void MergeExprBytecodeAndType(asSExprContext *before, asSExprContext *after);
void 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);
void MakeFunctionCall(asCExprContext *ctx, int funcId, asCObjectType *objectType, asCArray<asCExprContext*> &args, asCScriptNode *node, bool useVariable = false, int stackOffset = 0, int funcPtrVar = 0);
void 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);
void 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(asSExprContext *ctx);
void ConvertToVariableNotIn(asSExprContext *ctx, asSExprContext *exclude);
void ConvertToTempVariable(asSExprContext *ctx);
void ConvertToTempVariableNotIn(asSExprContext *ctx, asSExprContext *exclude);
void ConvertToReference(asSExprContext *ctx);
void PushVariableOnStack(asSExprContext *ctx, bool asReference);
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);
void DetermineSingleFunc(asSExprContext *ctx, asCScriptNode *node);
void DetermineSingleFunc(asCExprContext *ctx, asCScriptNode *node);
// Returns the cost of the conversion (the sum of the EConvCost performed)
asUINT ImplicitConversion(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode = true, bool allowObjectConstruct = true);
asUINT ImplicitConvPrimitiveToPrimitive(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode = true);
asUINT ImplicitConvObjectToPrimitive(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode = true);
asUINT ImplicitConvPrimitiveToObject(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode = true, bool allowObjectConstruct = true);
asUINT ImplicitConvObjectToObject(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode = true, bool allowObjectConstruct = true);
asUINT ImplicitConvObjectRef(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode);
asUINT ImplicitConvObjectValue(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode);
void ImplicitConversionConstant(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType);
void ImplicitConvObjectToBestMathType(asSExprContext *ctx, asCScriptNode *node);
asUINT ImplicitConvLambdaToFunc(asSExprContext *ctx, const asCDataType &to, asCScriptNode *node, EImplicitConv convType, bool generateCode = true);
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);
@ -373,11 +364,11 @@ protected:
asCArray<int> continueLabels;
int AllocateVariable(const asCDataType &type, bool isTemporary, bool forceOnHeap = false);
int AllocateVariableNotIn(const asCDataType &type, bool isTemporary, bool forceOnHeap, asSExprContext *ctx);
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(asCTypeInfo &t, asCByteCode *bc);
void ReleaseTemporaryVariable(asCExprValue &t, asCByteCode *bc);
void ReleaseTemporaryVariable(int offset, asCByteCode *bc);
bool IsVariableOnHeap(int offset);
@ -402,6 +393,10 @@ protected:
// 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;
bool isCompilingDefaultArg;
bool isProcessingDeferredParams;
int noCodeOutput;

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
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
@ -155,6 +155,7 @@
//
// How to identify different compilers
//-----------------------------------------
// Ref: http://nadeausoftware.com/articles/2012/10/c_c_tip_how_detect_compiler_name_and_version_using_compiler_predefined_macros
// MS Visual C++
// _MSC_VER is defined
@ -167,10 +168,13 @@
// GNU C based compilers
// __GNUC__ is defined
// CLang/LLVM
// __clang__ is defined
// Embarcadero C++Builder
// __BORLANDC__ is defined
// Sun CC compiler
// Oracle Solaris Studio (previously known as Sun CC compiler)
// __SUNPRO_CC is defined
@ -602,7 +606,8 @@
// GNU C (and MinGW or Cygwin on Windows)
// Use the following command to determine predefined macros: echo . | g++ -dM -E -
#if (defined(__GNUC__) && !defined(__SNC__)) || defined(EPPC) || defined(__CYGWIN__) // JWC -- use this instead for Wii
// MSVC2015 can now use CLang too, but it shouldn't go in here
#if (defined(__GNUC__) && !defined(__SNC__) && !defined(_MSC_VER)) || defined(EPPC) || defined(__CYGWIN__) // JWC -- use this instead for Wii
#define GNU_STYLE_VIRTUAL_METHOD
#define MULTI_BASE_OFFSET(x) (*((asPWORD*)(&x)+1))
#define asVSNPRINTF(a, b, c, d) vsnprintf(a, b, c, d)
@ -836,6 +841,7 @@
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
#if (defined(i386) || defined(__i386) || defined(__i386__)) && !defined(__LP64__)
// x86 32bit
#define THISCALL_RETURN_SIMPLE_IN_MEMORY
#define CDECL_RETURN_SIMPLE_IN_MEMORY
#define STDCALL_RETURN_SIMPLE_IN_MEMORY
@ -845,6 +851,7 @@
#define AS_X86
#undef AS_NO_THISCALL_FUNCTOR_METHOD
#elif defined(__x86_64__)
// x86 64bit
#define AS_X64_GCC
#undef AS_NO_THISCALL_FUNCTOR_METHOD
#define HAS_128_BIT_PRIMITIVES
@ -854,49 +861,56 @@
// STDCALL is not available on 64bit Linux
#undef STDCALL
#define STDCALL
#elif (defined(__ARMEL__) || defined(__arm__)) && !(defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__))
#define AS_ARM
#elif defined(__ARMEL__) || defined(__arm__) || defined(__aarch64__) || defined(__AARCH64EL__)
// arm
// TODO: The stack unwind on exceptions currently fails due to the assembler code in as_callfunc_arm_gcc.S
#define AS_NO_EXCEPTIONS
// The assembler code currently doesn't support arm v4, nor 64bit (v8)
#if !defined(__ARM_ARCH_4__) && !defined(__ARM_ARCH_4T__) && !defined(__LP64__)
#define AS_ARM
#undef STDCALL
#define STDCALL
// TODO: The stack unwind on exceptions currently fails due to the assembler code in as_callfunc_arm_gcc.S
#define AS_NO_EXCEPTIONS
#define CDECL_RETURN_SIMPLE_IN_MEMORY
#define STDCALL_RETURN_SIMPLE_IN_MEMORY
#define THISCALL_RETURN_SIMPLE_IN_MEMORY
#undef STDCALL
#define STDCALL
#undef THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
#undef CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
#undef STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
#define CDECL_RETURN_SIMPLE_IN_MEMORY
#define STDCALL_RETURN_SIMPLE_IN_MEMORY
#define THISCALL_RETURN_SIMPLE_IN_MEMORY
#define THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
#define CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
#define STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
#undef THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
#undef CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
#undef STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
#ifndef AS_MAX_PORTABILITY
// Make a few checks against incompatible ABI combinations
#if defined(__FAST_MATH__) && __FAST_MATH__ == 1
#error -ffast-math is not supported with native calling conventions
#define THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
#define CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
#define STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
#ifndef AS_MAX_PORTABILITY
// Make a few checks against incompatible ABI combinations
#if defined(__FAST_MATH__) && __FAST_MATH__ == 1
#error -ffast-math is not supported with native calling conventions
#endif
#endif
// Verify if soft-float or hard-float ABI is used
#if defined(__SOFTFP__) && __SOFTFP__ == 1
// -ffloat-abi=softfp or -ffloat-abi=soft
#define AS_SOFTFP
#endif
// Tested with both hard float and soft float abi
#undef AS_NO_THISCALL_FUNCTOR_METHOD
#endif
#endif
// Verify if soft-float or hard-float ABI is used
#if defined(__SOFTFP__) && __SOFTFP__ == 1
// -ffloat-abi=softfp or -ffloat-abi=soft
#define AS_SOFTFP
#endif
// Tested with both hard float and soft float abi
#undef AS_NO_THISCALL_FUNCTOR_METHOD
#elif defined(__mips__)
// mips
#define AS_MIPS
#undef STDCALL
#define STDCALL
#ifdef _ABIO32
// 32bit O32 ABI
#define AS_MIPS
// All structures are returned in memory regardless of size or complexity
@ -911,6 +925,13 @@
// For other ABIs the native calling convention is not available (yet)
#define AS_MAX_PORTABILITY
#endif
#elif defined(__PPC64__)
// PPC 64bit
// The code in as_callfunc_ppc_64.cpp was built for PS3 and XBox 360, that
// although use 64bit PPC only uses 32bit pointers.
// TODO: Add support for native calling conventions on Linux with PPC 64bit
#define AS_MAX_PORTABILITY
#else
#define AS_MAX_PORTABILITY
#endif
@ -923,7 +944,7 @@
#endif
// Free BSD
#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) || defined(__NetBSD__)
#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)
#define AS_BSD
#if (defined(i386) || defined(__i386) || defined(__i386__)) && !defined(__LP64__)
#undef COMPLEX_MASK
@ -1153,23 +1174,20 @@
// Detect target hardware
//------------------------------------------------
// X86, Intel, AMD, etc, i.e. most PCs
#if defined(__i386__) || defined(_M_IX86)
// Nothing special here
// Big endian CPU target?
// see: http://sourceforge.net/p/predef/wiki/Endianness/
#if !defined(AS_BIG_ENDIAN) && \
defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN || \
defined(__BIG_ENDIAN__) || \
defined(__ARMEB__) || \
defined(__THUMBEB__) || \
defined(__AARCH64EB__) || \
defined(_MIBSEB) || defined(__MIBSEB) || defined(__MIBSEB__)
#define AS_BIG_ENDIAN
#endif
// PowerPC, e.g. Mac, GameCube, PS3, XBox 360, Wii
#if defined(__PPC__) || defined(__ppc__) || defined(_PPC_) || defined(EPPC)
#define AS_BIG_ENDIAN
// Gamecube
#if defined(_GC)
#define AS_USE_DOUBLE_AS_FLOAT
#endif
#endif
// Dreamcast console
#ifdef __SH4_SINGLE_ONLY__
// Dreamcast and Gamecube use only 32bit floats, so treat doubles as floats
#if defined(__SH4_SINGLE_ONLY__) || defined(_GC)
#define AS_USE_DOUBLE_AS_FLOAT // use 32bit floats instead of doubles
#endif

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2014 Andreas Jonsson
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
@ -66,11 +66,11 @@ int asCConfigGroup::Release()
return refCount;
}
asCObjectType *asCConfigGroup::FindType(const char *obj)
asCTypeInfo *asCConfigGroup::FindType(const char *obj)
{
for( asUINT n = 0; n < objTypes.GetLength(); n++ )
if( objTypes[n]->name == obj )
return objTypes[n];
for( asUINT n = 0; n < types.GetLength(); n++ )
if( types[n]->name == obj )
return types[n];
return 0;
}
@ -90,27 +90,27 @@ void asCConfigGroup::RefConfigGroup(asCConfigGroup *group)
void asCConfigGroup::AddReferencesForFunc(asCScriptEngine *engine, asCScriptFunction *func)
{
AddReferencesForType(engine, func->returnType.GetObjectType());
AddReferencesForType(engine, func->returnType.GetTypeInfo());
for( asUINT n = 0; n < func->parameterTypes.GetLength(); n++ )
AddReferencesForType(engine, func->parameterTypes[n].GetObjectType());
AddReferencesForType(engine, func->parameterTypes[n].GetTypeInfo());
}
void asCConfigGroup::AddReferencesForType(asCScriptEngine *engine, asCObjectType *type)
void asCConfigGroup::AddReferencesForType(asCScriptEngine *engine, asCTypeInfo *type)
{
if( type == 0 ) return;
// Keep reference to other groups
RefConfigGroup(engine->FindConfigGroupForObjectType(type));
RefConfigGroup(engine->FindConfigGroupForTypeInfo(type));
// Keep track of which generated template instances the config group uses
if( type->flags & asOBJ_TEMPLATE && engine->generatedTemplateTypes.Exists(type) && !generatedTemplateInstances.Exists(type) )
generatedTemplateInstances.PushLast(type);
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 < objTypes.GetLength(); n++ )
if( objTypes[n]->externalRefCount.get() != 0 )
for( asUINT n = 0; n < types.GetLength(); n++ )
if( types[n]->externalRefCount.get() != 0 )
return true;
return false;
@ -143,36 +143,24 @@ void asCConfigGroup::RemoveConfiguration(asCScriptEngine *engine, bool notUsed)
if( index >= 0 )
engine->registeredGlobalFuncs.Erase(index);
scriptFunctions[n]->ReleaseInternal();
if( engine->stringFactory == scriptFunctions[n] )
engine->stringFactory = 0;
}
scriptFunctions.SetLength(0);
// Remove behaviours and members of object types
for( n = 0; n < objTypes.GetLength(); n++ )
for( n = 0; n < types.GetLength(); n++ )
{
asCObjectType *obj = objTypes[n];
obj->ReleaseAllFunctions();
asCObjectType *obj = CastToObjectType(types[n]);
if( obj )
obj->ReleaseAllFunctions();
}
// Remove function definitions
for( n = 0; n < funcDefs.GetLength(); n++ )
{
engine->registeredFuncDefs.RemoveValue(funcDefs[n]);
funcDefs[n]->ReleaseInternal();
engine->RemoveFuncdef(funcDefs[n]);
funcDefs[n]->ReleaseInternal();
}
funcDefs.SetLength(0);
// Remove object types (skip this if it is possible other groups are still using the types)
if( !notUsed )
{
for( n = asUINT(objTypes.GetLength()); n-- > 0; )
for( n = asUINT(types.GetLength()); n-- > 0; )
{
asCObjectType *t = objTypes[n];
asSMapNode<asSNameSpaceNamePair, asCObjectType*> *cursor;
asCTypeInfo *t = types[n];
asSMapNode<asSNameSpaceNamePair, asCTypeInfo*> *cursor;
if( engine->allRegisteredTypes.MoveTo(&cursor, asSNameSpaceNamePair(t->nameSpace, t->name)) &&
cursor->value == t )
{
@ -182,29 +170,35 @@ void asCConfigGroup::RemoveConfiguration(asCScriptEngine *engine, bool notUsed)
engine->defaultArrayObjectType = 0;
if( t->flags & asOBJ_TYPEDEF )
engine->registeredTypeDefs.RemoveValue(t);
engine->registeredTypeDefs.RemoveValue(CastToTypedefType(t));
else if( t->flags & asOBJ_ENUM )
engine->registeredEnums.RemoveValue(t);
else if( t->flags & asOBJ_TEMPLATE )
engine->registeredTemplateTypes.RemoveValue(t);
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(t);
engine->registeredObjTypes.RemoveValue(CastToObjectType(t));
t->DestroyInternal();
t->ReleaseInternal();
}
else
{
int idx = engine->templateInstanceTypes.IndexOf(t);
int idx = engine->templateInstanceTypes.IndexOf(CastToObjectType(t));
if( idx >= 0 )
{
engine->templateInstanceTypes.RemoveIndexUnordered(idx);
t->DestroyInternal();
t->ReleaseInternal();
asCObjectType *ot = CastToObjectType(t);
ot->DestroyInternal();
ot->ReleaseInternal();
}
}
}
objTypes.SetLength(0);
types.SetLength(0);
}
// Release other config groups

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2014 Andreas Jonsson
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
@ -57,23 +57,22 @@ public:
int AddRef();
int Release();
asCObjectType *FindType(const char *obj);
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, asCObjectType *type);
void AddReferencesForType(asCScriptEngine *engine, asCTypeInfo *type);
asCString groupName;
int refCount;
asCArray<asCObjectType*> objTypes;
asCArray<asCTypeInfo*> types;
asCArray<asCScriptFunction*> scriptFunctions;
asCArray<asCGlobalProperty*> globalProps;
asCArray<asCConfigGroup*> referencedConfigGroups;
asCArray<asCScriptFunction*> funcDefs;
// This array holds the generated template instances that are used
// by the config group as part of function signature or property

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
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
@ -153,7 +153,6 @@ AS_API asIScriptContext *asGetActiveContext()
}
// internal
// Note: There is no asPopActiveContext(), just call tld->activeContexts.PopLast() instead
asCThreadLocalData *asPushActiveContext(asIScriptContext *ctx)
{
asCThreadLocalData *tld = asCThreadManager::GetLocalData();
@ -164,6 +163,15 @@ asCThreadLocalData *asPushActiveContext(asIScriptContext *ctx)
return tld;
}
// internal
void asPopActiveContext(asCThreadLocalData *tld, asIScriptContext *ctx)
{
UNUSED_VAR(ctx);
asASSERT(tld && tld->activeContexts[tld->activeContexts.GetLength() - 1] == ctx);
if (tld)
tld->activeContexts.PopLast();
}
asCContext::asCContext(asCScriptEngine *engine, bool holdRef)
{
m_refCount.set(1);
@ -501,6 +509,11 @@ int asCContext::Unprepare()
if( m_status == asEXECUTION_ACTIVE || m_status == asEXECUTION_SUSPENDED )
return asCONTEXT_ACTIVE;
// Set the context as active so that any clean up code can use access it if desired
asCThreadLocalData *tld = asPushActiveContext((asIScriptContext *)this);
asDWORD count = m_refCount.get();
UNUSED_VAR(count);
// Only clean the stack if the context was prepared but not executed until the end
if( m_status != asEXECUTION_UNINITIALIZED &&
m_status != asEXECUTION_FINISHED )
@ -511,6 +524,11 @@ int asCContext::Unprepare()
// Release the returned object (if any)
CleanReturnObject();
// TODO: Unprepare is called during destruction, so nobody
// must be allowed to keep an extra reference
asASSERT(m_refCount.get() == count);
asPopActiveContext(tld, this);
// Release the object if it is a script object
if( m_initialFunction && m_initialFunction->objectType && (m_initialFunction->objectType->flags & asOBJ_SCRIPT_OBJECT) )
{
@ -552,7 +570,7 @@ asBYTE asCContext::GetReturnByte()
asCDataType *dt = &m_initialFunction->returnType;
if( dt->IsObject() || dt->IsReference() ) return 0;
if( dt->IsObject() || dt->IsFuncdef() || dt->IsReference() ) return 0;
return *(asBYTE*)&m_regs.valueRegister;
}
@ -563,7 +581,7 @@ asWORD asCContext::GetReturnWord()
asCDataType *dt = &m_initialFunction->returnType;
if( dt->IsObject() || dt->IsReference() ) return 0;
if( dt->IsObject() || dt->IsFuncdef() || dt->IsReference() ) return 0;
return *(asWORD*)&m_regs.valueRegister;
}
@ -574,7 +592,7 @@ asDWORD asCContext::GetReturnDWord()
asCDataType *dt = &m_initialFunction->returnType;
if( dt->IsObject() || dt->IsReference() ) return 0;
if( dt->IsObject() || dt->IsFuncdef() || dt->IsReference() ) return 0;
return *(asDWORD*)&m_regs.valueRegister;
}
@ -585,7 +603,7 @@ asQWORD asCContext::GetReturnQWord()
asCDataType *dt = &m_initialFunction->returnType;
if( dt->IsObject() || dt->IsReference() ) return 0;
if( dt->IsObject() || dt->IsFuncdef() || dt->IsReference() ) return 0;
return m_regs.valueRegister;
}
@ -596,7 +614,7 @@ float asCContext::GetReturnFloat()
asCDataType *dt = &m_initialFunction->returnType;
if( dt->IsObject() || dt->IsReference() ) return 0;
if( dt->IsObject() || dt->IsFuncdef() || dt->IsReference() ) return 0;
return *(float*)&m_regs.valueRegister;
}
@ -607,7 +625,7 @@ double asCContext::GetReturnDouble()
asCDataType *dt = &m_initialFunction->returnType;
if( dt->IsObject() || dt->IsReference() ) return 0;
if( dt->IsObject() || dt->IsFuncdef() || dt->IsReference() ) return 0;
return *(double*)&m_regs.valueRegister;
}
@ -620,7 +638,7 @@ void *asCContext::GetReturnAddress()
if( dt->IsReference() )
return *(void**)&m_regs.valueRegister;
else if( dt->IsObject() )
else if( dt->IsObject() || dt->IsFuncdef() )
{
if( m_initialFunction->DoesReturnOnStack() )
{
@ -644,7 +662,7 @@ void *asCContext::GetReturnObject()
asCDataType *dt = &m_initialFunction->returnType;
if( !dt->IsObject() ) return 0;
if( !dt->IsObject() && !dt->IsFuncdef() ) return 0;
if( dt->IsReference() )
return *(void**)(asPWORD)m_regs.valueRegister;
@ -671,7 +689,7 @@ void *asCContext::GetAddressOfReturnValue()
asCDataType *dt = &m_initialFunction->returnType;
// An object is stored in the objectRegister
if( !dt->IsReference() && dt->IsObject() )
if( !dt->IsReference() && (dt->IsObject() || dt->IsFuncdef()) )
{
// Need to dereference objects
if( !dt->IsObjectHandle() )
@ -731,7 +749,7 @@ int asCContext::SetArgByte(asUINT arg, asBYTE value)
// Verify the type of the argument
asCDataType *dt = &m_initialFunction->parameterTypes[arg];
if( dt->IsObject() || dt->IsReference() )
if( dt->IsObject() || dt->IsFuncdef() || dt->IsReference() )
{
m_status = asEXECUTION_ERROR;
return asINVALID_TYPE;
@ -774,7 +792,7 @@ int asCContext::SetArgWord(asUINT arg, asWORD value)
// Verify the type of the argument
asCDataType *dt = &m_initialFunction->parameterTypes[arg];
if( dt->IsObject() || dt->IsReference() )
if( dt->IsObject() || dt->IsFuncdef() || dt->IsReference() )
{
m_status = asEXECUTION_ERROR;
return asINVALID_TYPE;
@ -817,7 +835,7 @@ int asCContext::SetArgDWord(asUINT arg, asDWORD value)
// Verify the type of the argument
asCDataType *dt = &m_initialFunction->parameterTypes[arg];
if( dt->IsObject() || dt->IsReference() )
if( dt->IsObject() || dt->IsFuncdef() || dt->IsReference() )
{
m_status = asEXECUTION_ERROR;
return asINVALID_TYPE;
@ -860,7 +878,7 @@ int asCContext::SetArgQWord(asUINT arg, asQWORD value)
// Verify the type of the argument
asCDataType *dt = &m_initialFunction->parameterTypes[arg];
if( dt->IsObject() || dt->IsReference() )
if( dt->IsObject() || dt->IsFuncdef() || dt->IsReference() )
{
m_status = asEXECUTION_ERROR;
return asINVALID_TYPE;
@ -903,7 +921,7 @@ int asCContext::SetArgFloat(asUINT arg, float value)
// Verify the type of the argument
asCDataType *dt = &m_initialFunction->parameterTypes[arg];
if( dt->IsObject() || dt->IsReference() )
if( dt->IsObject() || dt->IsFuncdef() || dt->IsReference() )
{
m_status = asEXECUTION_ERROR;
return asINVALID_TYPE;
@ -946,7 +964,7 @@ int asCContext::SetArgDouble(asUINT arg, double value)
// Verify the type of the argument
asCDataType *dt = &m_initialFunction->parameterTypes[arg];
if( dt->IsObject() || dt->IsReference() )
if( dt->IsObject() || dt->IsFuncdef() || dt->IsReference() )
{
m_status = asEXECUTION_ERROR;
return asINVALID_TYPE;
@ -1026,7 +1044,7 @@ int asCContext::SetArgObject(asUINT arg, void *obj)
// Verify the type of the argument
asCDataType *dt = &m_initialFunction->parameterTypes[arg];
if( !dt->IsObject() )
if( !dt->IsObject() && !dt->IsFuncdef() )
{
m_status = asEXECUTION_ERROR;
return asINVALID_TYPE;
@ -1038,13 +1056,18 @@ int asCContext::SetArgObject(asUINT arg, void *obj)
if( dt->IsObjectHandle() )
{
// Increase the reference counter
asSTypeBehaviour *beh = &dt->GetObjectType()->beh;
if( obj && beh->addref )
m_engine->CallObjectMethod(obj, beh->addref);
if (obj && dt->IsFuncdef())
((asIScriptFunction*)obj)->AddRef();
else
{
asSTypeBehaviour *beh = &CastToObjectType(dt->GetTypeInfo())->beh;
if (obj && beh->addref)
m_engine->CallObjectMethod(obj, beh->addref);
}
}
else
{
obj = m_engine->CreateScriptObjectCopy(obj, dt->GetObjectType());
obj = m_engine->CreateScriptObjectCopy(obj, dt->GetTypeInfo());
}
}
@ -1186,7 +1209,11 @@ int asCContext::Execute()
asCThreadLocalData *tld = asPushActiveContext((asIScriptContext *)this);
if( m_regs.programPointer == 0 )
// Make sure there are not too many nested calls, as it could crash the application
// by filling up the thread call stack
if (tld->activeContexts.GetLength() > m_engine->ep.maxNestedCalls)
SetInternalException(TXT_TOO_MANY_NESTED_CALLS);
else if( m_regs.programPointer == 0 )
{
if( m_currentFunction->funcType == asFUNC_DELEGATE )
{
@ -1319,13 +1346,11 @@ int asCContext::Execute()
}
// Pop the active context
asASSERT(tld && tld->activeContexts[tld->activeContexts.GetLength()-1] == this);
if( tld )
tld->activeContexts.PopLast();
asPopActiveContext(tld, this);
if( m_status == asEXECUTION_FINISHED )
{
m_regs.objectType = m_initialFunction->returnType.GetObjectType();
m_regs.objectType = m_initialFunction->returnType.GetTypeInfo();
return asEXECUTION_FINISHED;
}
@ -1426,7 +1451,7 @@ int asCContext::PopState()
m_regs.valueRegister = asQWORD(asDWORD(tmp[5]));
m_regs.valueRegister |= asQWORD(tmp[6])<<32;
m_regs.objectRegister = (void*)tmp[7];
m_regs.objectType = (asIObjectType*)tmp[8];
m_regs.objectType = (asITypeInfo*)tmp[8];
// Calculate the returnValueSize
if( m_initialFunction->DoesReturnOnStack() )
@ -2481,18 +2506,9 @@ void asCContext::ExecuteNext()
break;
case asBC_STR:
{
// Get the string id from the argument
asWORD w = asBC_WORDARG0(l_bc);
// Push the string pointer on the stack
const asCString &b = m_engine->GetConstantString(w);
l_sp -= AS_PTR_SIZE;
*(asPWORD*)l_sp = (asPWORD)b.AddressOf();
// Push the string length on the stack
--l_sp;
*l_sp = (asDWORD)b.GetLength();
l_bc++;
}
// TODO: NEWSTRING: Deprecate this instruction
asASSERT(false);
l_bc++;
break;
case asBC_CALLSYS:
@ -2803,7 +2819,7 @@ void asCContext::ExecuteNext()
{
// Read variable index from location on stack
asPWORD *a = (asPWORD*)(l_sp + asBC_WORDARG0(l_bc));
asDWORD offset = *(asDWORD*)a;
asPWORD offset = *a;
// Move pointer from variable to the same location on the stack
asPWORD *v = (asPWORD*)(l_fp - offset);
*a = *v;
@ -4339,17 +4355,24 @@ void asCContext::ExecuteNext()
// Pop the thispointer from the stack
void *obj = *(void**)l_sp;
l_sp += AS_PTR_SIZE;
if (obj == 0)
SetInternalException(TXT_NULL_POINTER_ACCESS);
else
{
// Only update the stack pointer if all is OK so the
// exception handler can properly clean up the stack
l_sp += AS_PTR_SIZE;
// Pop the int arg from the stack
int arg = *(int*)l_sp;
l_sp++;
// Pop the int arg from the stack
int arg = *(int*)l_sp;
l_sp++;
// Call the method
m_callingSystemFunction = m_engine->scriptFunctions[i];
void *ptr = m_engine->CallObjectMethodRetPtr(obj, arg, m_callingSystemFunction);
m_callingSystemFunction = 0;
*(asPWORD*)&m_regs.valueRegister = (asPWORD)ptr;
// Call the method
m_callingSystemFunction = m_engine->scriptFunctions[i];
void *ptr = m_engine->CallObjectMethodRetPtr(obj, arg, m_callingSystemFunction);
m_callingSystemFunction = 0;
*(asPWORD*)&m_regs.valueRegister = (asPWORD)ptr;
}
// Update the program position after the call so that line number is correct
l_bc += 2;
@ -4510,8 +4533,8 @@ void asCContext::CleanReturnObject()
if( m_initialFunction && m_initialFunction->DoesReturnOnStack() && m_status == asEXECUTION_FINISHED )
{
// If function returns on stack we need to call the destructor on the returned object
if( m_initialFunction->returnType.GetObjectType()->beh.destruct )
m_engine->CallObjectMethod(GetReturnObject(), m_initialFunction->returnType.GetObjectType()->beh.destruct);
if(CastToObjectType(m_initialFunction->returnType.GetTypeInfo())->beh.destruct )
m_engine->CallObjectMethod(GetReturnObject(), CastToObjectType(m_initialFunction->returnType.GetTypeInfo())->beh.destruct);
return;
}
@ -4522,25 +4545,34 @@ void asCContext::CleanReturnObject()
if( m_regs.objectType )
{
// Call the destructor on the object
asSTypeBehaviour *beh = &((asCObjectType*)m_regs.objectType)->beh;
if( m_regs.objectType->GetFlags() & asOBJ_REF )
if (m_regs.objectType->GetFlags() & asOBJ_FUNCDEF)
{
asASSERT( beh->release || (m_regs.objectType->GetFlags() & asOBJ_NOCOUNT) );
if( beh->release )
m_engine->CallObjectMethod(m_regs.objectRegister, beh->release);
// Release the function pointer
reinterpret_cast<asIScriptFunction*>(m_regs.objectRegister)->Release();
m_regs.objectRegister = 0;
}
else
{
if( beh->destruct )
m_engine->CallObjectMethod(m_regs.objectRegister, beh->destruct);
// Call the destructor on the object
asSTypeBehaviour *beh = &(CastToObjectType(reinterpret_cast<asCTypeInfo*>(m_regs.objectType))->beh);
if (m_regs.objectType->GetFlags() & asOBJ_REF)
{
asASSERT(beh->release || (m_regs.objectType->GetFlags() & asOBJ_NOCOUNT));
// Free the memory
m_engine->CallFree(m_regs.objectRegister);
m_regs.objectRegister = 0;
if (beh->release)
m_engine->CallObjectMethod(m_regs.objectRegister, beh->release);
m_regs.objectRegister = 0;
}
else
{
if (beh->destruct)
m_engine->CallObjectMethod(m_regs.objectRegister, beh->destruct);
// Free the memory
m_engine->CallFree(m_regs.objectRegister);
m_regs.objectRegister = 0;
}
}
}
}
@ -4779,7 +4811,7 @@ void asCContext::CleanArgsOnStack()
for( v = 0; v < m_currentFunction->scriptData->objVariablePos.GetLength(); v++ )
if( m_currentFunction->scriptData->objVariablePos[v] == var )
{
func = m_currentFunction->scriptData->funcVariableTypes[v];
func = CastToFuncdefType(m_currentFunction->scriptData->objVariableTypes[v])->funcdef;
break;
}
@ -4795,7 +4827,8 @@ void asCContext::CleanArgsOnStack()
{
if( var == paramPos )
{
func = m_currentFunction->parameterTypes[v].GetFuncDef();
if (m_currentFunction->parameterTypes[v].IsFuncdef())
func = CastToFuncdefType(m_currentFunction->parameterTypes[v].GetTypeInfo())->funcdef;
break;
}
paramPos -= m_currentFunction->parameterTypes[v].GetSizeOnStackDWords();
@ -4815,19 +4848,23 @@ void asCContext::CleanArgsOnStack()
offset += AS_PTR_SIZE;
for( asUINT n = 0; n < func->parameterTypes.GetLength(); n++ )
{
if( func->parameterTypes[n].IsObject() && !func->parameterTypes[n].IsReference() )
if( (func->parameterTypes[n].IsObject() || func->parameterTypes[n].IsFuncdef()) && !func->parameterTypes[n].IsReference() )
{
// TODO: cleanup: This logic is repeated twice in CleanStackFrame too. Should create a common function to share the code
if( *(asPWORD*)&m_regs.stackPointer[offset] )
{
// Call the object's destructor
asSTypeBehaviour *beh = func->parameterTypes[n].GetBehaviour();
if( func->parameterTypes[n].GetObjectType()->flags & asOBJ_REF )
if (func->parameterTypes[n].GetTypeInfo()->flags & asOBJ_FUNCDEF)
{
asASSERT( (func->parameterTypes[n].GetObjectType()->flags & asOBJ_NOCOUNT) || beh->release );
(*(asCScriptFunction**)&m_regs.stackPointer[offset])->Release();
}
else if( func->parameterTypes[n].GetTypeInfo()->flags & asOBJ_REF )
{
asASSERT( (func->parameterTypes[n].GetTypeInfo()->flags & asOBJ_NOCOUNT) || beh->release );
if( beh->release )
m_engine->CallObjectMethod((void*)*(asPWORD*)&m_regs.stackPointer[offset], beh->release);
*(asPWORD*)&m_regs.stackPointer[offset] = 0;
}
else
{
@ -4836,8 +4873,8 @@ void asCContext::CleanArgsOnStack()
// Free the memory
m_engine->CallFree((void*)*(asPWORD*)&m_regs.stackPointer[offset]);
*(asPWORD*)&m_regs.stackPointer[offset] = 0;
}
*(asPWORD*)&m_regs.stackPointer[offset] = 0;
}
}
@ -4875,25 +4912,29 @@ void asCContext::CleanStackFrame()
if( *(asPWORD*)&m_regs.stackFramePointer[-pos] )
{
// Call the object's destructor
asSTypeBehaviour *beh = &m_currentFunction->scriptData->objVariableTypes[n]->beh;
if( m_currentFunction->scriptData->objVariableTypes[n]->flags & asOBJ_REF )
if (m_currentFunction->scriptData->objVariableTypes[n]->flags & asOBJ_FUNCDEF)
{
(*(asCScriptFunction**)&m_regs.stackFramePointer[-pos])->Release();
}
else if( m_currentFunction->scriptData->objVariableTypes[n]->flags & asOBJ_REF )
{
asSTypeBehaviour *beh = &CastToObjectType(m_currentFunction->scriptData->objVariableTypes[n])->beh;
asASSERT( (m_currentFunction->scriptData->objVariableTypes[n]->flags & asOBJ_NOCOUNT) || beh->release );
if( beh->release )
m_engine->CallObjectMethod((void*)*(asPWORD*)&m_regs.stackFramePointer[-pos], beh->release);
*(asPWORD*)&m_regs.stackFramePointer[-pos] = 0;
}
else
{
asSTypeBehaviour *beh = &CastToObjectType(m_currentFunction->scriptData->objVariableTypes[n])->beh;
if( beh->destruct )
m_engine->CallObjectMethod((void*)*(asPWORD*)&m_regs.stackFramePointer[-pos], beh->destruct);
else if( m_currentFunction->scriptData->objVariableTypes[n]->flags & asOBJ_LIST_PATTERN )
m_engine->DestroyList((asBYTE*)*(asPWORD*)&m_regs.stackFramePointer[-pos], m_currentFunction->scriptData->objVariableTypes[n]);
m_engine->DestroyList((asBYTE*)*(asPWORD*)&m_regs.stackFramePointer[-pos], CastToObjectType(m_currentFunction->scriptData->objVariableTypes[n]));
// Free the memory
m_engine->CallFree((void*)*(asPWORD*)&m_regs.stackFramePointer[-pos]);
*(asPWORD*)&m_regs.stackFramePointer[-pos] = 0;
}
*(asPWORD*)&m_regs.stackFramePointer[-pos] = 0;
}
}
else
@ -4903,7 +4944,7 @@ void asCContext::CleanStackFrame()
// Only destroy the object if it is truly alive
if( liveObjects[n] > 0 )
{
asSTypeBehaviour *beh = &m_currentFunction->scriptData->objVariableTypes[n]->beh;
asSTypeBehaviour *beh = &CastToObjectType(m_currentFunction->scriptData->objVariableTypes[n])->beh;
if( beh->destruct )
m_engine->CallObjectMethod((void*)(asPWORD*)&m_regs.stackFramePointer[-pos], beh->destruct);
}
@ -4925,19 +4966,22 @@ void asCContext::CleanStackFrame()
offset += AS_PTR_SIZE;
for( asUINT n = 0; n < m_currentFunction->parameterTypes.GetLength(); n++ )
{
if( m_currentFunction->parameterTypes[n].IsObject() && !m_currentFunction->parameterTypes[n].IsReference() )
if( (m_currentFunction->parameterTypes[n].IsObject() ||m_currentFunction->parameterTypes[n].IsFuncdef()) && !m_currentFunction->parameterTypes[n].IsReference() )
{
if( *(asPWORD*)&m_regs.stackFramePointer[offset] )
{
// Call the object's destructor
asSTypeBehaviour *beh = m_currentFunction->parameterTypes[n].GetBehaviour();
if( m_currentFunction->parameterTypes[n].GetObjectType()->flags & asOBJ_REF )
if (m_currentFunction->parameterTypes[n].GetTypeInfo()->flags & asOBJ_FUNCDEF)
{
asASSERT( (m_currentFunction->parameterTypes[n].GetObjectType()->flags & asOBJ_NOCOUNT) || beh->release );
(*(asCScriptFunction**)&m_regs.stackFramePointer[offset])->Release();
}
else if( m_currentFunction->parameterTypes[n].GetTypeInfo()->flags & asOBJ_REF )
{
asASSERT( (m_currentFunction->parameterTypes[n].GetTypeInfo()->flags & asOBJ_NOCOUNT) || beh->release );
if( beh->release )
m_engine->CallObjectMethod((void*)*(asPWORD*)&m_regs.stackFramePointer[offset], beh->release);
*(asPWORD*)&m_regs.stackFramePointer[offset] = 0;
}
else
{
@ -4946,8 +4990,8 @@ void asCContext::CleanStackFrame()
// Free the memory
m_engine->CallFree((void*)*(asPWORD*)&m_regs.stackFramePointer[offset]);
*(asPWORD*)&m_regs.stackFramePointer[offset] = 0;
}
*(asPWORD*)&m_regs.stackFramePointer[offset] = 0;
}
}
@ -5122,12 +5166,27 @@ int asCContext::CallGeneric(asCScriptFunction *descr)
asCGeneric gen(m_engine, descr, currentObject, args);
m_callingSystemFunction = descr;
#ifdef AS_NO_EXCEPTIONS
func(&gen);
#else
// This try/catch block is to catch potential exception that may
// be thrown by the registered function.
try
{
func(&gen);
}
catch (...)
{
// Convert the exception to a script exception so the VM can
// properly report the error to the application and then clean up
SetException(TXT_EXCEPTION_CAUGHT);
}
#endif
m_callingSystemFunction = 0;
m_regs.valueRegister = gen.returnVal;
m_regs.objectRegister = gen.objectRegister;
m_regs.objectType = descr->returnType.GetObjectType();
m_regs.objectType = descr->returnType.GetTypeInfo();
// Clean up arguments
const asUINT cleanCount = sysFunc->cleanArgs.GetLength();
@ -5244,7 +5303,7 @@ void *asCContext::GetAddressOfVar(asUINT varIndex, asUINT stackLevel)
!func->scriptData->variables[varIndex]->type.IsObjectHandle() )
{
onHeap = true;
if( func->scriptData->variables[varIndex]->type.GetObjectType()->GetFlags() & asOBJ_VALUE )
if( func->scriptData->variables[varIndex]->type.GetTypeInfo()->GetFlags() & asOBJ_VALUE )
{
for( asUINT n = 0; n < func->scriptData->objVariablePos.GetLength(); n++ )
{
@ -5312,7 +5371,7 @@ int asCContext::GetThisTypeId(asUINT stackLevel)
return 0; // not in a method
// create a datatype
asCDataType dt = asCDataType::CreateObject((asCObjectType*)func->GetObjectType(), false);
asCDataType dt = asCDataType::CreateType((asCObjectType*)func->GetObjectType(), false);
// return a typeId from the data type
return m_engine->GetTypeIdFromDataType(dt);

View File

@ -1,24 +1,24 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2014 Andreas Jonsson
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
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
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
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
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
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
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
@ -45,18 +45,18 @@ BEGIN_AS_NAMESPACE
#ifdef AS_NO_THREADS
#define DECLARECRITICALSECTION(x)
#define ENTERCRITICALSECTION(x)
#define LEAVECRITICALSECTION(x)
#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)
#define DECLAREREADWRITELOCK(x)
#define ACQUIREEXCLUSIVE(x)
#define RELEASEEXCLUSIVE(x)
#define ACQUIRESHARED(x)
#define RELEASESHARED(x)
#else
@ -115,7 +115,9 @@ END_AS_NAMESPACE
#ifdef AS_XBOX360
#include <xtl.h>
#else
#define WIN32_LEAN_AND_MEAN
#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
@ -154,11 +156,11 @@ public:
void ReleaseShared();
protected:
// The Slim Read Write Lock object, SRWLOCK, is more efficient
// 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.
// 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

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
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
@ -38,6 +38,7 @@
#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"
@ -47,27 +48,27 @@ BEGIN_AS_NAMESPACE
asCDataType::asCDataType()
{
tokenType = ttUnrecognizedToken;
objectType = 0;
typeInfo = 0;
isReference = false;
isReadOnly = false;
isAuto = false;
isObjectHandle = false;
isConstHandle = false;
funcDef = 0;
isHandleToAsHandleType = false;
ifHandleThenConst = false;
}
asCDataType::asCDataType(const asCDataType &dt)
{
tokenType = dt.tokenType;
objectType = dt.objectType;
typeInfo = dt.typeInfo;
isReference = dt.isReference;
isReadOnly = dt.isReadOnly;
isAuto = dt.isAuto;
isObjectHandle = dt.isObjectHandle;
isConstHandle = dt.isConstHandle;
funcDef = dt.funcDef;
isHandleToAsHandleType = dt.isHandleToAsHandleType;
ifHandleThenConst = dt.ifHandleThenConst;
}
asCDataType::~asCDataType()
@ -83,12 +84,12 @@ bool asCDataType::IsValid() const
return true;
}
asCDataType asCDataType::CreateObject(asCObjectType *ot, bool isConst)
asCDataType asCDataType::CreateType(asCTypeInfo *ti, bool isConst)
{
asCDataType dt;
dt.tokenType = ttIdentifier;
dt.objectType = ot;
dt.typeInfo = ti;
dt.isReadOnly = isConst;
return dt;
@ -105,28 +106,20 @@ asCDataType asCDataType::CreateAuto(bool isConst)
return dt;
}
asCDataType asCDataType::CreateObjectHandle(asCObjectType *ot, bool isConst)
asCDataType asCDataType::CreateObjectHandle(asCTypeInfo *ot, bool isConst)
{
asCDataType dt;
asASSERT(CastToObjectType(ot));
dt.tokenType = ttIdentifier;
dt.objectType = ot;
dt.typeInfo = ot;
dt.isObjectHandle = true;
dt.isConstHandle = isConst;
return dt;
}
asCDataType asCDataType::CreateFuncDef(asCScriptFunction *func)
{
asCDataType dt;
dt.tokenType = ttIdentifier;
dt.funcDef = func;
dt.objectType = &func->engine->functionBehaviours;
return dt;
}
asCDataType asCDataType::CreatePrimitive(eTokenType tt, bool isConst)
{
asCDataType dt;
@ -152,7 +145,7 @@ asCDataType asCDataType::CreateNullHandle()
bool asCDataType::IsNullHandle() const
{
if( tokenType == ttUnrecognizedToken &&
objectType == 0 &&
typeInfo == 0 &&
isObjectHandle )
return true;
@ -171,38 +164,40 @@ asCString asCDataType::Format(asSNameSpace *currNs, bool includeNamespace) 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 || (objectType && objectType->nameSpace != currNs) || (funcDef && funcDef->nameSpace != currNs) )
if (includeNamespace || (typeInfo && typeInfo->nameSpace != currNs))
{
if( objectType && objectType->nameSpace->name != "" )
str += objectType->nameSpace->name + "::";
else if( funcDef && funcDef->nameSpace->name != "" )
str += funcDef->nameSpace->name + "::";
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() && objectType && !objectType->engine->ep.expandDefaultArrayToTemplate )
else if( IsArrayType() && typeInfo && !typeInfo->engine->ep.expandDefaultArrayToTemplate )
{
asASSERT( objectType->templateSubTypes.GetLength() == 1 );
str += objectType->templateSubTypes[0].Format(currNs, includeNamespace);
asCObjectType *ot = CastToObjectType(typeInfo);
asASSERT( ot && ot->templateSubTypes.GetLength() == 1 );
str += ot->templateSubTypes[0].Format(currNs, includeNamespace);
str += "[]";
}
else if( funcDef )
else if(typeInfo)
{
str += funcDef->name;
}
else if( objectType )
{
str += objectType->name;
if( objectType->templateSubTypes.GetLength() > 0 )
str += typeInfo->name;
asCObjectType *ot = CastToObjectType(typeInfo);
if( ot && ot->templateSubTypes.GetLength() > 0 )
{
str += "<";
for( asUINT subtypeIndex = 0; subtypeIndex < objectType->templateSubTypes.GetLength(); subtypeIndex++ )
for( asUINT subtypeIndex = 0; subtypeIndex < ot->templateSubTypes.GetLength(); subtypeIndex++ )
{
str += objectType->templateSubTypes[subtypeIndex].Format(currNs, includeNamespace);
if( subtypeIndex != objectType->templateSubTypes.GetLength()-1 )
str += ot->templateSubTypes[subtypeIndex].Format(currNs, includeNamespace);
if( subtypeIndex != ot->templateSubTypes.GetLength()-1 )
str += ",";
}
str += ">";
@ -210,10 +205,7 @@ asCString asCDataType::Format(asSNameSpace *currNs, bool includeNamespace) const
}
else if( isAuto )
{
if( isObjectHandle )
str += "<auto@>";
else
str += "<auto>";
str += "<auto>";
}
else
{
@ -237,13 +229,13 @@ asCDataType &asCDataType::operator =(const asCDataType &dt)
{
tokenType = dt.tokenType;
isReference = dt.isReference;
objectType = dt.objectType;
typeInfo = dt.typeInfo;
isReadOnly = dt.isReadOnly;
isObjectHandle = dt.isObjectHandle;
isConstHandle = dt.isConstHandle;
isAuto = dt.isAuto;
funcDef = dt.funcDef;
isHandleToAsHandleType = dt.isHandleToAsHandleType;
ifHandleThenConst = dt.ifHandleThenConst;
return (asCDataType &)*this;
}
@ -269,18 +261,17 @@ int asCDataType::MakeHandle(bool b, bool acceptHandleForScope)
// (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( !funcDef &&
(!objectType ||
!((objectType->flags & asOBJ_REF) || (objectType->flags & asOBJ_TEMPLATE_SUBTYPE) || (objectType->flags & asOBJ_ASHANDLE)) ||
(objectType->flags & asOBJ_NOHANDLE) ||
((objectType->flags & asOBJ_SCOPED) && !acceptHandleForScope)) )
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( (objectType->flags & asOBJ_ASHANDLE) )
if( (typeInfo->flags & asOBJ_ASHANDLE) )
{
isObjectHandle = false;
isHandleToAsHandleType = true;
@ -306,7 +297,7 @@ int asCDataType::MakeArray(asCScriptEngine *engine, asCModule *module)
isObjectHandle = false;
isConstHandle = false;
objectType = at;
typeInfo = at;
tokenType = ttIdentifier;
return 0;
@ -341,9 +332,9 @@ int asCDataType::MakeHandleToConst(bool b)
bool asCDataType::SupportHandles() const
{
if( objectType &&
(objectType->flags & (asOBJ_REF | asOBJ_ASHANDLE)) &&
!(objectType->flags & asOBJ_NOHANDLE) &&
if( typeInfo &&
(typeInfo->flags & (asOBJ_REF | asOBJ_ASHANDLE | asOBJ_FUNCDEF)) &&
!(typeInfo->flags & asOBJ_NOHANDLE) &&
!isObjectHandle )
return true;
@ -355,19 +346,25 @@ bool asCDataType::CanBeInstantiated() const
if( GetSizeOnStackDWords() == 0 ) // Void
return false;
if( !IsObject() ) // Primitives
if( !IsObject() && !IsFuncdef() ) // Primitives
return true;
if( IsObjectHandle() && !(objectType->flags & asOBJ_NOHANDLE) ) // Handles
return true;
if( funcDef ) // Funcdefs can be instantiated as delegates
return true;
if( (objectType->flags & asOBJ_REF) && objectType->beh.factories.GetLength() == 0 ) // ref types without factories
if (IsNullHandle()) // null
return false;
if( (objectType->flags & asOBJ_ABSTRACT) && !IsObjectHandle() ) // Can't instantiate abstract classes
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;
@ -375,12 +372,16 @@ bool asCDataType::CanBeInstantiated() const
bool asCDataType::IsAbstractClass() const
{
return objectType && (objectType->flags & asOBJ_ABSTRACT) ? true : false;
return typeInfo && (typeInfo->flags & asOBJ_ABSTRACT) ? true : false;
}
bool asCDataType::IsInterface() const
{
return objectType && objectType->IsInterface();
if (typeInfo == 0)
return false;
asCObjectType *ot = CastToObjectType(typeInfo);
return ot && ot->IsInterface();
}
bool asCDataType::CanBeCopied() const
@ -389,19 +390,19 @@ bool asCDataType::CanBeCopied() const
if( IsPrimitive() ) return true;
// Plain-old-data structures can always be copied
if( objectType->flags & asOBJ_POD ) return true;
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
if( objectType->beh.construct == 0 &&
objectType->beh.factory == 0 ) 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;
// It must be possible to copy the type
if( objectType->beh.copy == 0 ) return false;
return true;
return false;
}
bool asCDataType::IsReadOnly() const
@ -430,15 +431,15 @@ bool asCDataType::IsObjectConst() const
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( objectType && objectType->engine->defaultArrayObjectType )
return objectType->name == objectType->engine->defaultArrayObjectType->name;
if( typeInfo && typeInfo->engine->defaultArrayObjectType )
return typeInfo->name == typeInfo->engine->defaultArrayObjectType->name;
return false;
}
bool asCDataType::IsTemplate() const
{
if( objectType && (objectType->flags & asOBJ_TEMPLATE) )
if( typeInfo && (typeInfo->flags & asOBJ_TEMPLATE) )
return true;
return false;
@ -446,7 +447,7 @@ bool asCDataType::IsTemplate() const
bool asCDataType::IsScriptObject() const
{
if( objectType && (objectType->flags & asOBJ_SCRIPT_OBJECT) )
if( typeInfo && (typeInfo->flags & asOBJ_SCRIPT_OBJECT) )
return true;
return false;
@ -454,8 +455,9 @@ bool asCDataType::IsScriptObject() const
asCDataType asCDataType::GetSubType(asUINT subtypeIndex) const
{
asASSERT(objectType);
return objectType->templateSubTypes[subtypeIndex];
asASSERT(typeInfo);
asCObjectType *ot = CastToObjectType(typeInfo);
return ot->templateSubTypes[subtypeIndex];
}
@ -487,11 +489,10 @@ bool asCDataType::IsEqualExceptRefAndConst(const asCDataType &dt) const
{
// Check base type
if( tokenType != dt.tokenType ) return false;
if( objectType != dt.objectType ) return false;
if( typeInfo != dt.typeInfo ) return false;
if( isObjectHandle != dt.isObjectHandle ) return false;
if( isObjectHandle )
if( isReadOnly != dt.isReadOnly ) return false;
if( funcDef != dt.funcDef ) return false;
return true;
}
@ -510,11 +511,11 @@ bool asCDataType::IsPrimitive() const
if( IsEnumType() )
return true;
// A registered object is never a primitive neither is a pointer, nor an array
if( objectType || funcDef )
// A registered object is never a primitive neither is a pointer nor an array
if( typeInfo )
return false;
// Null handle doesn't have an objectType, but it is not a primitive
// Null handle doesn't have a typeInfo, but it is not a primitive
if( tokenType == ttUnrecognizedToken )
return false;
@ -584,16 +585,25 @@ bool asCDataType::IsObject() const
return false;
// Null handle doesn't have an object type but should still be considered an object
if( objectType == 0 )
if( typeInfo == 0 )
return IsNullHandle();
return true;
// 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( objectType != 0 )
return objectType->size;
if( typeInfo != 0 )
return typeInfo->size;
if( tokenType == ttVoid )
return 0;
@ -640,7 +650,7 @@ int asCDataType::GetSizeOnStackDWords() const
int size = tokenType == ttQuestion ? 1 : 0;
if( isReference ) return AS_PTR_SIZE + size;
if( objectType && !IsEnumType() ) return AS_PTR_SIZE + size;
if( typeInfo && !IsEnumType() ) return AS_PTR_SIZE + size;
return GetSizeInMemoryDWords() + size;
}
@ -648,27 +658,29 @@ int asCDataType::GetSizeOnStackDWords() const
#ifdef WIP_16BYTE_ALIGN
int asCDataType::GetAlignment() const
{
if( objectType == NULL )
if( typeInfo == NULL )
{
// TODO: Small primitives should not be aligned to 4 byte boundaries
return 4; //Default alignment
}
return objectType->alignment;
return typeInfo->alignment;
}
#endif
asSTypeBehaviour *asCDataType::GetBehaviour() const
{
return objectType ? &objectType->beh : 0;
{
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( objectType == 0 || objectType->name.GetLength() < 100 );
asASSERT(typeInfo == 0 || typeInfo->name.GetLength() < 100);
if( objectType && (objectType->flags & asOBJ_ENUM) )
if (typeInfo && (typeInfo->flags & asOBJ_ENUM))
return true;
return false;

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
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
@ -47,12 +47,14 @@ BEGIN_AS_NAMESPACE
struct asSTypeBehaviour;
class asCScriptEngine;
class asCObjectType;
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 asCTypeInfo
// 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
@ -67,10 +69,9 @@ public:
asCString Format(asSNameSpace *currNs, bool includeNamespace = false) const;
static asCDataType CreatePrimitive(eTokenType tt, bool isConst);
static asCDataType CreateObject(asCObjectType *ot, bool isConst);
static asCDataType CreateType(asCTypeInfo *ti, bool isConst);
static asCDataType CreateAuto(bool isConst);
static asCDataType CreateObjectHandle(asCObjectType *ot, bool isConst);
static asCDataType CreateFuncDef(asCScriptFunction *ot);
static asCDataType CreateObjectHandle(asCTypeInfo *ot, bool isConst);
static asCDataType CreateNullHandle();
int MakeHandle(bool b, bool acceptHandleForScope = false);
@ -78,6 +79,8 @@ public:
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;
@ -101,6 +104,7 @@ public:
bool IsHandleToAsHandleType() const {return isHandleToAsHandleType;}
bool IsAbstractClass() const;
bool IsInterface() const;
bool IsFuncdef() const;
bool IsObjectConst() const;
@ -118,8 +122,7 @@ public:
asCDataType GetSubType(asUINT subtypeIndex = 0) const;
eTokenType GetTokenType() const {return tokenType;}
asCObjectType *GetObjectType() const {return objectType;}
asCScriptFunction *GetFuncDef() const {return funcDef;}
asCTypeInfo *GetTypeInfo() const { return typeInfo; }
int GetSizeOnStackDWords() const;
int GetSizeInMemoryBytes() const;
@ -129,8 +132,7 @@ public:
#endif
void SetTokenType(eTokenType tt) {tokenType = tt;}
void SetObjectType(asCObjectType *obj) {objectType = obj;}
void SetFuncDef(asCScriptFunction *func) {asASSERT(funcDef); funcDef = func; }
void SetTypeInfo(asCTypeInfo *ti) {typeInfo = ti;}
asCDataType &operator =(const asCDataType &);
@ -141,8 +143,7 @@ protected:
eTokenType tokenType;
// Behaviour type
asCObjectType *objectType;
asCScriptFunction *funcDef;
asCTypeInfo *typeInfo;
// Top level
bool isReference:1;
@ -151,7 +152,8 @@ protected:
bool isConstHandle:1;
bool isAuto:1;
bool isHandleToAsHandleType:1; // Used by the compiler to know how to initialize the object
char dummy:2;
bool ifHandleThenConst:1; // Used when creating template instances to determine if a handle should be const or not
char dummy:1;
};
END_AS_NAMESPACE

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
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
@ -49,7 +49,7 @@
#ifndef AS_PSVITA
// Possible on PSVita, but requires SDK access
#if defined(__GNUC__) || defined( AS_MARMALADE )
#if !defined(_MSC_VER) && (defined(__GNUC__) || defined(AS_MARMALADE))
#ifdef __ghs__
// WIIU defines __GNUC__ but types are not defined here in 'conventional' way

View File

@ -130,7 +130,7 @@ int asCGarbageCollector::AddScriptObjectToGC(void *obj, asCObjectType *objType)
return ot.seqNbr;
}
int asCGarbageCollector::GetObjectInGC(asUINT idx, asUINT *seqNbr, void **obj, asIObjectType **type)
int asCGarbageCollector::GetObjectInGC(asUINT idx, asUINT *seqNbr, void **obj, asITypeInfo **type)
{
if( seqNbr ) *seqNbr = 0;
if( obj ) *obj = 0;

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2014 Andreas Jonsson
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
@ -60,7 +60,7 @@ public:
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, asIObjectType **type);
int GetObjectInGC(asUINT idx, asUINT *seqNbr, void **obj, asITypeInfo **type);
int ReportAndReleaseUndestroyedObjects();

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2013 Andreas Jonsson
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
@ -62,6 +62,12 @@ asCGeneric::~asCGeneric()
{
}
// interface
void *asCGeneric::GetAuxiliary() const
{
return sysFunction->GetAuxiliary();
}
// interface
asIScriptEngine *asCGeneric::GetEngine() const
{
@ -83,7 +89,7 @@ void *asCGeneric::GetObject()
// interface
int asCGeneric::GetObjectTypeId() const
{
asCDataType dt = asCDataType::CreateObject(sysFunction->objectType, false);
asCDataType dt = asCDataType::CreateType(sysFunction->objectType, false);
return engine->GetTypeIdFromDataType(dt);
}
@ -101,7 +107,7 @@ asBYTE asCGeneric::GetArgByte(asUINT arg)
// Verify that the type is correct
asCDataType *dt = &sysFunction->parameterTypes[arg];
if( dt->IsObject() || dt->IsReference() )
if( (dt->IsObject() || dt->IsFuncdef()) || dt->IsReference() )
return 0;
if( dt->GetSizeInMemoryBytes() != 1 )
@ -124,7 +130,7 @@ asWORD asCGeneric::GetArgWord(asUINT arg)
// Verify that the type is correct
asCDataType *dt = &sysFunction->parameterTypes[arg];
if( dt->IsObject() || dt->IsReference() )
if( (dt->IsObject() || dt->IsFuncdef()) || dt->IsReference() )
return 0;
if( dt->GetSizeInMemoryBytes() != 2 )
@ -147,7 +153,7 @@ asDWORD asCGeneric::GetArgDWord(asUINT arg)
// Verify that the type is correct
asCDataType *dt = &sysFunction->parameterTypes[arg];
if( dt->IsObject() || dt->IsReference() )
if( (dt->IsObject() || dt->IsFuncdef()) || dt->IsReference() )
return 0;
if( dt->GetSizeInMemoryBytes() != 4 )
@ -170,7 +176,7 @@ asQWORD asCGeneric::GetArgQWord(asUINT arg)
// Verify that the type is correct
asCDataType *dt = &sysFunction->parameterTypes[arg];
if( dt->IsObject() || dt->IsReference() )
if( (dt->IsObject() || dt->IsFuncdef()) || dt->IsReference() )
return 0;
if( dt->GetSizeInMemoryBytes() != 8 )
@ -193,7 +199,7 @@ float asCGeneric::GetArgFloat(asUINT arg)
// Verify that the type is correct
asCDataType *dt = &sysFunction->parameterTypes[arg];
if( dt->IsObject() || dt->IsReference() )
if( (dt->IsObject() || dt->IsFuncdef()) || dt->IsReference() )
return 0;
if( dt->GetSizeInMemoryBytes() != 4 )
@ -216,7 +222,7 @@ double asCGeneric::GetArgDouble(asUINT arg)
// Verify that the type is correct
asCDataType *dt = &sysFunction->parameterTypes[arg];
if( dt->IsObject() || dt->IsReference() )
if( (dt->IsObject() || dt->IsFuncdef()) || dt->IsReference() )
return 0;
if( dt->GetSizeInMemoryBytes() != 8 )
@ -259,7 +265,7 @@ void *asCGeneric::GetArgObject(asUINT arg)
// Verify that the type is correct
asCDataType *dt = &sysFunction->parameterTypes[arg];
if( !dt->IsObject() )
if( !dt->IsObject() && !dt->IsFuncdef() )
return 0;
// Determine the position of the argument
@ -325,14 +331,14 @@ int asCGeneric::GetArgTypeId(asUINT arg, asDWORD *flags) const
int asCGeneric::SetReturnByte(asBYTE val)
{
// Verify the type of the return value
if( sysFunction->returnType.IsObject() || sysFunction->returnType.IsReference() )
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;
// Store the value
*(asBYTE*)&returnVal = val;
return 0;
}
@ -341,14 +347,14 @@ int asCGeneric::SetReturnByte(asBYTE val)
int asCGeneric::SetReturnWord(asWORD val)
{
// Verify the type of the return value
if( sysFunction->returnType.IsObject() || sysFunction->returnType.IsReference() )
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;
// Store the value
*(asWORD*)&returnVal = val;
return 0;
}
@ -357,14 +363,14 @@ int asCGeneric::SetReturnWord(asWORD val)
int asCGeneric::SetReturnDWord(asDWORD val)
{
// Verify the type of the return value
if( sysFunction->returnType.IsObject() || sysFunction->returnType.IsReference() )
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;
// Store the value
*(asDWORD*)&returnVal = val;
return 0;
}
@ -373,7 +379,7 @@ int asCGeneric::SetReturnDWord(asDWORD val)
int asCGeneric::SetReturnQWord(asQWORD val)
{
// Verify the type of the return value
if( sysFunction->returnType.IsObject() || sysFunction->returnType.IsReference() )
if( (sysFunction->returnType.IsObject() || sysFunction->returnType.IsFuncdef()) || sysFunction->returnType.IsReference() )
return asINVALID_TYPE;
if( sysFunction->returnType.GetSizeOnStackDWords() != 2 )
@ -389,7 +395,7 @@ int asCGeneric::SetReturnQWord(asQWORD val)
int asCGeneric::SetReturnFloat(float val)
{
// Verify the type of the return value
if( sysFunction->returnType.IsObject() || sysFunction->returnType.IsReference() )
if( (sysFunction->returnType.IsObject() || sysFunction->returnType.IsFuncdef()) || sysFunction->returnType.IsReference() )
return asINVALID_TYPE;
if( sysFunction->returnType.GetSizeOnStackDWords() != 1 )
@ -405,7 +411,7 @@ int asCGeneric::SetReturnFloat(float val)
int asCGeneric::SetReturnDouble(double val)
{
// Verify the type of the return value
if( sysFunction->returnType.IsObject() || sysFunction->returnType.IsReference() )
if( (sysFunction->returnType.IsObject() || sysFunction->returnType.IsFuncdef()) || sysFunction->returnType.IsReference() )
return asINVALID_TYPE;
if( sysFunction->returnType.GetSizeOnStackDWords() != 2 )
@ -441,7 +447,7 @@ int asCGeneric::SetReturnAddress(void *val)
int asCGeneric::SetReturnObject(void *obj)
{
asCDataType *dt = &sysFunction->returnType;
if( !dt->IsObject() )
if( !dt->IsObject() && !dt->IsFuncdef() )
return asINVALID_TYPE;
if( dt->IsReference() )
@ -453,9 +459,17 @@ int asCGeneric::SetReturnObject(void *obj)
if( dt->IsObjectHandle() )
{
// Increase the reference counter
asSTypeBehaviour *beh = &dt->GetObjectType()->beh;
if( obj && beh->addref )
engine->CallObjectMethod(obj, beh->addref);
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
{
@ -463,7 +477,7 @@ int asCGeneric::SetReturnObject(void *obj)
// 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, dt->GetObjectType());
engine->ConstructScriptObjectCopy(mem, obj, CastToObjectType(dt->GetTypeInfo()));
return 0;
}
@ -477,7 +491,7 @@ void *asCGeneric::GetReturnPointer()
{
asCDataType &dt = sysFunction->returnType;
if( dt.IsObject() && !dt.IsReference() )
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.
@ -494,7 +508,7 @@ void *asCGeneric::GetAddressOfReturnLocation()
{
asCDataType &dt = sysFunction->returnType;
if( dt.IsObject() && !dt.IsReference() )
if( (dt.IsObject() || dt.IsFuncdef()) && !dt.IsReference() )
{
if( sysFunction->DoesReturnOnStack() )
{

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2013 Andreas Jonsson
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
@ -55,6 +55,7 @@ public:
// Miscellaneous
asIScriptEngine *GetEngine() const;
asIScriptFunction *GetFunction() const;
void *GetAuxiliary() const;
// Object
void *GetObject();

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2014 Andreas Jonsson
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
@ -120,13 +120,13 @@ void *asCGlobalProperty::GetRegisteredAddress() const
return realAddress;
}
void asCGlobalProperty::SetInitFunc(asCScriptFunction *initFunc)
void asCGlobalProperty::SetInitFunc(asCScriptFunction *in_initFunc)
{
// This should only be done once
asASSERT( this->initFunc == 0 );
asASSERT( initFunc == 0 );
this->initFunc = initFunc;
this->initFunc->AddRefInternal();
initFunc = in_initFunc;
initFunc->AddRefInternal();
}
asCScriptFunction *asCGlobalProperty::GetInitFunc()

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
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
@ -38,8 +38,7 @@
#include <stdlib.h>
#if !defined(__APPLE__) && !defined( __SNC__ ) && !defined( __ghs__ ) \
&& !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
#if !defined(__APPLE__) && !defined(__SNC__) && !defined(__ghs__) && !defined(__FreeBSD__) && !defined(__OpenBSD__)
#include <malloc.h>
#endif

View File

@ -1,24 +1,24 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
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
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
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
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
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
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
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
@ -67,7 +67,7 @@ asCModule::~asCModule()
{
InternalReset();
// The builder is not removed by InternalReset because it holds the script
// The builder is not removed by InternalReset because it holds the script
// sections that will be built, so we need to explictly remove it now if it exists
if( builder )
{
@ -111,7 +111,7 @@ void asCModule::Discard()
asCScriptEngine *lEngine = engine;
// Instead of deleting the module immediately, move it to the discarded pile
// This will turn it invisible to the application, yet keep it alive until all
// This will turn it invisible to the application, yet keep it alive until all
// external references to its entities have been released.
ACQUIREEXCLUSIVE(engine->engineRWLock);
if( lEngine->lastModule == this )
@ -195,9 +195,9 @@ asIScriptEngine *asCModule::GetEngine() const
}
// interface
void asCModule::SetName(const char *name)
void asCModule::SetName(const char *in_name)
{
this->name = name;
name = in_name;
}
// interface
@ -248,13 +248,13 @@ int asCModule::SetDefaultNamespace(const char *nameSpace)
}
// interface
int asCModule::AddScriptSection(const char *name, const char *code, size_t codeLength, int lineOffset)
int asCModule::AddScriptSection(const char *in_name, const char *in_code, size_t in_codeLength, int in_lineOffset)
{
#ifdef AS_NO_COMPILER
UNUSED_VAR(name);
UNUSED_VAR(code);
UNUSED_VAR(codeLength);
UNUSED_VAR(lineOffset);
UNUSED_VAR(in_name);
UNUSED_VAR(in_code);
UNUSED_VAR(in_codeLength);
UNUSED_VAR(in_lineOffset);
return asNOT_SUPPORTED;
#else
if( !builder )
@ -264,7 +264,7 @@ int asCModule::AddScriptSection(const char *name, const char *code, size_t codeL
return asOUT_OF_MEMORY;
}
return builder->AddCode(name, code, (int)codeLength, lineOffset, (int)engine->GetScriptSectionNameIndex(name ? name : ""), engine->ep.copyScriptSections);
return builder->AddCode(in_name, in_code, (int)in_codeLength, in_lineOffset, (int)engine->GetScriptSectionNameIndex(in_name ? in_name : ""), engine->ep.copyScriptSections);
#endif
}
@ -287,7 +287,7 @@ int asCModule::Build()
#else
TimeIt("asCModule::Build");
// Don't allow the module to be rebuilt if there are still
// Don't allow the module to be rebuilt if there are still
// external references that will need the previous code
// TODO: interface: The asIScriptModule must have a method for querying if the module is used
if( HasExternalReferences(false) )
@ -322,7 +322,7 @@ int asCModule::Build()
r = builder->Build();
asDELETE(builder,asCBuilder);
builder = 0;
if( r < 0 )
{
// Reset module again
@ -359,7 +359,7 @@ int asCModule::Build()
// interface
int asCModule::ResetGlobalVars(asIScriptContext *ctx)
{
if( isGlobalVarInitialized )
if( isGlobalVarInitialized )
CallExit();
return CallInit(ctx);
@ -374,7 +374,7 @@ asIScriptFunction *asCModule::GetFunctionByIndex(asUINT index) const
// internal
int asCModule::CallInit(asIScriptContext *myCtx)
{
if( isGlobalVarInitialized )
if( isGlobalVarInitialized )
return asERROR;
// Each global variable needs to be cleared individually
@ -414,19 +414,19 @@ int asCModule::CallInit(asIScriptContext *myCtx)
asCScriptFunction *func = desc->GetInitFunc();
engine->WriteMessage(func->scriptData->scriptSectionIdx >= 0 ? engine->scriptSectionNames[func->scriptData->scriptSectionIdx]->AddressOf() : "",
func->GetLineNumber(0, 0) & 0xFFFFF,
func->GetLineNumber(0, 0) & 0xFFFFF,
func->GetLineNumber(0, 0) >> 20,
asMSGTYPE_ERROR,
msg.AddressOf());
if( r == asEXECUTION_EXCEPTION )
{
const asIScriptFunction *function = ctx->GetExceptionFunction();
msg.Format(TXT_EXCEPTION_s_IN_s, ctx->GetExceptionString(), function->GetDeclaration());
engine->WriteMessage(function->GetScriptSectionName(),
ctx->GetExceptionLineNumber(),
engine->WriteMessage(function->GetScriptSectionName(),
ctx->GetExceptionLineNumber(),
0,
asMSGTYPE_INFORMATION,
msg.AddressOf());
@ -442,9 +442,9 @@ int asCModule::CallInit(asIScriptContext *myCtx)
ctx = 0;
}
// Even if the initialization failed we need to set the
// Even if the initialization failed we need to set the
// flag that the variables have been initialized, otherwise
// the module won't free those variables that really were
// the module won't free those variables that really were
// initialized.
isGlobalVarInitialized = true;
@ -454,6 +454,48 @@ int asCModule::CallInit(asIScriptContext *myCtx)
return asSUCCESS;
}
// internal
void asCModule::UninitializeGlobalProp(asCGlobalProperty *prop)
{
if (prop == 0)
return;
if (prop->type.IsObject())
{
void **obj = (void**)prop->GetAddressOfValue();
if (*obj)
{
asCObjectType *ot = CastToObjectType(prop->type.GetTypeInfo());
if (ot->flags & asOBJ_REF)
{
asASSERT((ot->flags & asOBJ_NOCOUNT) || ot->beh.release);
if (ot->beh.release)
engine->CallObjectMethod(*obj, ot->beh.release);
}
else
{
if (ot->beh.destruct)
engine->CallObjectMethod(*obj, ot->beh.destruct);
engine->CallFree(*obj);
}
// Set the address to 0 as someone might try to access the variable afterwards
*obj = 0;
}
}
else if (prop->type.IsFuncdef())
{
asCScriptFunction **func = (asCScriptFunction**)prop->GetAddressOfValue();
if (*func)
{
(*func)->Release();
*func = 0;
}
}
}
// internal
void asCModule::CallExit()
{
@ -462,31 +504,7 @@ void asCModule::CallExit()
asCSymbolTableIterator<asCGlobalProperty> it = scriptGlobals.List();
while( it )
{
if( (*it)->type.IsObject() )
{
void **obj = (void**)(*it)->GetAddressOfValue();
if( *obj )
{
asCObjectType *ot = (*it)->type.GetObjectType();
if( ot->flags & asOBJ_REF )
{
asASSERT( (ot->flags & asOBJ_NOCOUNT) || ot->beh.release );
if( ot->beh.release )
engine->CallObjectMethod(*obj, ot->beh.release);
}
else
{
if( ot->beh.destruct )
engine->CallObjectMethod(*obj, ot->beh.destruct);
engine->CallFree(*obj);
}
// Set the address to 0 as someone might try to access the variable afterwards
*obj = 0;
}
}
UninitializeGlobalProp(*it);
it++;
}
@ -498,7 +516,30 @@ bool asCModule::HasExternalReferences(bool shuttingDown)
{
// Check all entiteis in the module for any external references.
// If there are any external references the module cannot be deleted yet.
asCSymbolTableIterator<asCGlobalProperty> it = scriptGlobals.List();
while (it)
{
asCGlobalProperty *desc = *it;
if (desc->GetInitFunc() && desc->GetInitFunc()->externalRefCount.get())
{
if( !shuttingDown )
return true;
else
{
asCString msg;
msg.Format(TXT_EXTRNL_REF_TO_MODULE_s, name.AddressOf());
engine->WriteMessage("", 0, 0, asMSGTYPE_WARNING, msg.AddressOf());
// TODO: Use a better error message
asCString tmpName = "init " + desc->name;
msg.Format(TXT_PREV_FUNC_IS_NAMED_s_TYPE_IS_d, tmpName.AddressOf(), desc->GetInitFunc()->GetFuncType());
engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, msg.AddressOf());
}
}
it++;
}
for( asUINT n = 0; n < scriptFunctions.GetLength(); n++ )
if( scriptFunctions[n] && scriptFunctions[n]->externalRefCount.get() )
{
@ -542,7 +583,7 @@ bool asCModule::HasExternalReferences(bool shuttingDown)
msg.Format(TXT_EXTRNL_REF_TO_MODULE_s, name.AddressOf());
engine->WriteMessage("", 0, 0, asMSGTYPE_WARNING, msg.AddressOf());
msg.Format(TXT_PREV_FUNC_IS_NAMED_s_TYPE_IS_d, funcDefs[n]->GetName(), funcDefs[n]->GetFuncType());
msg.Format(TXT_PREV_FUNC_IS_NAMED_s_TYPE_IS_d, funcDefs[n]->GetName(), funcDefs[n]->funcdef->GetFuncType());
engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, msg.AddressOf());
}
}
@ -576,7 +617,7 @@ void asCModule::InternalReset()
// Remove all global functions
globalFunctions.Clear();
// Destroy the internals of the global properties here, but do not yet remove them from the
// Destroy the internals of the global properties here, but do not yet remove them from the
// engine, because functions need the engine's varAddressMap to get to the property. If the
// property is removed already, it may leak as the refCount doesn't reach 0.
asCSymbolTableIterator<asCGlobalProperty> globIt = scriptGlobals.List();
@ -650,7 +691,7 @@ void asCModule::InternalReset()
classTypes.SetLength(0);
for( n = 0; n < enumTypes.GetLength(); n++ )
{
asCObjectType *type = enumTypes[n];
asCEnumType *type = enumTypes[n];
if( type->IsShared() )
{
// The type is shared, so transfer ownership to another module that also uses it
@ -662,9 +703,6 @@ void asCModule::InternalReset()
}
}
// The type should be destroyed now
type->DestroyInternal();
// Remove the type from the engine
if( type->IsShared() )
{
@ -679,7 +717,7 @@ void asCModule::InternalReset()
enumTypes.SetLength(0);
for( n = 0; n < typeDefs.GetLength(); n++ )
{
asCObjectType *type = typeDefs[n];
asCTypedefType *type = typeDefs[n];
// The type should be destroyed now
type->DestroyInternal();
@ -693,13 +731,14 @@ void asCModule::InternalReset()
// Free funcdefs
for( n = 0; n < funcDefs.GetLength(); n++ )
{
asCScriptFunction *func = funcDefs[n];
if( func->IsShared() )
asCFuncdefType *func = funcDefs[n];
asASSERT(func);
if( func->funcdef && func->funcdef->IsShared() )
{
// The func is shared, so transfer ownership to another module that also uses it
if( engine->FindNewOwnerForSharedFunc(func, this) != this )
// The funcdef is shared, so transfer ownership to another module that also uses it
if( engine->FindNewOwnerForSharedType(func, this) != this )
{
// The func is owned by another module, just release our reference
// The funcdef is owned by another module, just release our reference
func->ReleaseInternal();
continue;
}
@ -748,12 +787,12 @@ void asCModule::InternalReset()
}
// interface
asIScriptFunction *asCModule::GetFunctionByName(const char *name) const
asIScriptFunction *asCModule::GetFunctionByName(const char *in_name) const
{
asSNameSpace *ns = defaultNamespace;
while( ns )
{
const asCArray<unsigned int> &idxs = globalFunctions.GetIndexes(ns, name);
const asCArray<unsigned int> &idxs = globalFunctions.GetIndexes(ns, in_name);
if( idxs.GetLength() != 1 )
return 0;
@ -790,7 +829,7 @@ int asCModule::GetImportedFunctionIndexByDecl(const char *decl) const
int id = -1;
for( asUINT n = 0; n < bindInformations.GetLength(); ++n )
{
if( func.name == bindInformations[n]->importedFunctionSignature->name &&
if( func.name == bindInformations[n]->importedFunctionSignature->name &&
func.returnType == bindInformations[n]->importedFunctionSignature->returnType &&
func.parameterTypes.GetLength() == bindInformations[n]->importedFunctionSignature->parameterTypes.GetLength() )
{
@ -898,14 +937,14 @@ asUINT asCModule::GetGlobalVarCount() const
}
// interface
int asCModule::GetGlobalVarIndexByName(const char *name) const
int asCModule::GetGlobalVarIndexByName(const char *in_name) const
{
asSNameSpace *ns = defaultNamespace;
// Find the global var id
while( ns )
{
int id = scriptGlobals.GetFirstIndex(ns, name);
int id = scriptGlobals.GetFirstIndex(ns, in_name);
if( id >= 0 ) return id;
// Recursively search parent namespaces
@ -922,17 +961,22 @@ int asCModule::RemoveGlobalVar(asUINT index)
if( !prop )
return asINVALID_ARG;
// If the global variables have already been initialized
// then uninitialize the variable before it is removed
if (isGlobalVarInitialized)
UninitializeGlobalProp(prop);
// Destroy the internal of the global variable (removes the initialization function)
prop->DestroyInternal();
// Check if the module is the only one referring to the module, if so remove it from the engine too
// Check if the module is the only one referring to the property, if so remove it from the engine too
// If the property is not removed now, it will be removed later when the module is discarded
if( prop->refCount.get() == 2 )
engine->RemoveGlobalProperty(prop);
// Remove the global variable from the module
prop->Release();
scriptGlobals.Erase(index);
prop->Release();
return 0;
}
@ -945,17 +989,17 @@ int asCModule::GetGlobalVarIndexByDecl(const char *decl) const
// Don't write parser errors to the message callback
bld.silent = true;
asCString name;
asCString declName;
asSNameSpace *nameSpace;
asCDataType dt;
int r = bld.ParseVariableDeclaration(decl, defaultNamespace, name, nameSpace, dt);
int r = bld.ParseVariableDeclaration(decl, defaultNamespace, declName, nameSpace, dt);
if( r < 0 )
return r;
// Search global variables for a match
while( nameSpace )
{
int id = scriptGlobals.GetFirstIndex(nameSpace, name, asCCompGlobPropType(dt));
int id = scriptGlobals.GetFirstIndex(nameSpace, declName, asCCompGlobPropType(dt));
if( id != -1 )
return id;
@ -970,7 +1014,7 @@ int asCModule::GetGlobalVarIndexByDecl(const char *decl) const
void *asCModule::GetAddressOfGlobalVar(asUINT index)
{
asCGlobalProperty *prop = scriptGlobals.Get(index);
if( !prop )
if( !prop )
return 0;
// For object variables it's necessary to dereference the pointer to get the address of the value
@ -998,19 +1042,19 @@ const char *asCModule::GetGlobalVarDeclaration(asUINT index, bool includeNamespa
}
// interface
int asCModule::GetGlobalVar(asUINT index, const char **name, const char **nameSpace, int *typeId, bool *isConst) const
int asCModule::GetGlobalVar(asUINT index, const char **out_name, const char **out_nameSpace, int *out_typeId, bool *out_isConst) const
{
const asCGlobalProperty *prop = scriptGlobals.Get(index);
if (!prop) return 0;
if( name )
*name = prop->name.AddressOf();
if( nameSpace )
*nameSpace = prop->nameSpace->name.AddressOf();
if( typeId )
*typeId = engine->GetTypeIdFromDataType(prop->type);
if( isConst )
*isConst = prop->type.IsReadOnly();
if( out_name )
*out_name = prop->name.AddressOf();
if( out_nameSpace )
*out_nameSpace = prop->nameSpace->name.AddressOf();
if( out_typeId )
*out_typeId = engine->GetTypeIdFromDataType(prop->type);
if( out_isConst )
*out_isConst = prop->type.IsReadOnly();
return asSUCCESS;
}
@ -1021,29 +1065,45 @@ asUINT asCModule::GetObjectTypeCount() const
return (asUINT)classTypes.GetLength();
}
// interface
asIObjectType *asCModule::GetObjectTypeByIndex(asUINT index) const
// interface
asITypeInfo *asCModule::GetObjectTypeByIndex(asUINT index) const
{
if( index >= classTypes.GetLength() )
if( index >= classTypes.GetLength() )
return 0;
return classTypes[index];
}
// interface
asIObjectType *asCModule::GetObjectTypeByName(const char *name) const
asITypeInfo *asCModule::GetTypeInfoByName(const char *in_name) const
{
asSNameSpace *ns = defaultNamespace;
while( ns )
while (ns)
{
for( asUINT n = 0; n < classTypes.GetLength(); n++ )
for (asUINT n = 0; n < classTypes.GetLength(); n++)
{
if( classTypes[n] &&
classTypes[n]->name == name &&
classTypes[n]->nameSpace == ns )
if (classTypes[n] &&
classTypes[n]->name == in_name &&
classTypes[n]->nameSpace == ns)
return classTypes[n];
}
for (asUINT n = 0; n < enumTypes.GetLength(); n++)
{
if (enumTypes[n] &&
enumTypes[n]->name == in_name &&
enumTypes[n]->nameSpace == ns)
return enumTypes[n];
}
for (asUINT n = 0; n < typeDefs.GetLength(); n++)
{
if (typeDefs[n] &&
typeDefs[n]->name == in_name &&
typeDefs[n]->nameSpace == ns)
return typeDefs[n];
}
// Recursively search parent namespace
ns = engine->GetParentNameSpace(ns);
}
@ -1070,7 +1130,7 @@ int asCModule::GetTypeIdByDecl(const char *decl) const
}
// interface
asIObjectType *asCModule::GetObjectTypeByDecl(const char *decl) const
asITypeInfo *asCModule::GetTypeInfoByDecl(const char *decl) const
{
asCDataType dt;
@ -1081,59 +1141,25 @@ asIObjectType *asCModule::GetObjectTypeByDecl(const char *decl) const
bld.silent = true;
int r = bld.ParseDataType(decl, &dt, defaultNamespace);
if( r < 0 )
if (r < 0)
return 0;
return dt.GetObjectType();
return dt.GetTypeInfo();
}
// interface
asUINT asCModule::GetEnumCount() const
{
return (asUINT)enumTypes.GetLength();
return enumTypes.GetLength();
}
// interface
const char *asCModule::GetEnumByIndex(asUINT index, int *enumTypeId, const char **nameSpace) const
asITypeInfo *asCModule::GetEnumByIndex(asUINT index) const
{
if( index >= enumTypes.GetLength() )
return 0;
if( enumTypeId )
*enumTypeId = engine->GetTypeIdFromDataType(asCDataType::CreateObject(enumTypes[index], false));
if( nameSpace )
*nameSpace = enumTypes[index]->nameSpace->name.AddressOf();
return enumTypes[index]->name.AddressOf();
}
// interface
int asCModule::GetEnumValueCount(int enumTypeId) const
{
asCDataType dt = engine->GetDataTypeFromTypeId(enumTypeId);
asCObjectType *t = dt.GetObjectType();
if( t == 0 || !(t->GetFlags() & asOBJ_ENUM) )
return asINVALID_TYPE;
return (int)t->enumValues.GetLength();
}
// interface
const char *asCModule::GetEnumValueByIndex(int enumTypeId, asUINT index, int *outValue) const
{
asCDataType dt = engine->GetDataTypeFromTypeId(enumTypeId);
asCObjectType *t = dt.GetObjectType();
if( t == 0 || !(t->GetFlags() & asOBJ_ENUM) )
return 0;
if( index >= t->enumValues.GetLength() )
return 0;
if( outValue )
*outValue = t->enumValues[index]->value;
return t->enumValues[index]->name.AddressOf();
return enumTypes[index];
}
// interface
@ -1143,21 +1169,14 @@ asUINT asCModule::GetTypedefCount() const
}
// interface
const char *asCModule::GetTypedefByIndex(asUINT index, int *typeId, const char **nameSpace) const
asITypeInfo *asCModule::GetTypedefByIndex(asUINT index) const
{
if( index >= typeDefs.GetLength() )
return 0;
if( typeId )
*typeId = engine->GetTypeIdFromDataType(typeDefs[index]->templateSubTypes[0]);
if( nameSpace )
*nameSpace = typeDefs[index]->nameSpace->name.AddressOf();
return typeDefs[index]->name.AddressOf();
return typeDefs[index];
}
// internal
int asCModule::GetNextImportedFunctionId()
{
@ -1170,7 +1189,7 @@ int asCModule::GetNextImportedFunctionId()
#ifndef AS_NO_COMPILER
// internal
int asCModule::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, bool isConstMethod, bool isGlobalFunction, bool isPrivate, bool isProtected, bool isFinal, bool isOverride, bool isShared, asSNameSpace *ns)
int asCModule::AddScriptFunction(int sectionIdx, int declaredAt, int id, const asCString &funcName, const asCDataType &returnType, const asCArray<asCDataType> &params, const asCArray<asCString> &paramNames, const asCArray<asETypeModifiers> &inOutFlags, const asCArray<asCString *> &defaultArgs, bool isInterface, asCObjectType *objType, bool isGlobalFunction, asSFunctionTraits funcTraits, asSNameSpace *ns)
{
asASSERT(id >= 0);
@ -1191,9 +1210,9 @@ int asCModule::AddScriptFunction(int sectionIdx, int declaredAt, int id, const a
// All methods of shared objects are also shared
if( objType && objType->IsShared() )
isShared = true;
funcTraits.SetTrait(asTRAIT_SHARED, true);
func->name = name;
func->name = funcName;
func->nameSpace = ns;
func->id = id;
func->returnType = returnType;
@ -1209,18 +1228,13 @@ int asCModule::AddScriptFunction(int sectionIdx, int declaredAt, int id, const a
func->objectType = objType;
if( objType )
objType->AddRefInternal();
func->isReadOnly = isConstMethod;
func->isPrivate = isPrivate;
func->isProtected = isProtected;
func->isFinal = isFinal;
func->isOverride = isOverride;
func->isShared = isShared;
func->traits = funcTraits;
asASSERT( params.GetLength() == inOutFlags.GetLength() && params.GetLength() == defaultArgs.GetLength() );
// Verify that we are not assigning either the final or override specifier(s) if we are registering a non-member function
asASSERT( !(!objType && isFinal) );
asASSERT( !(!objType && isOverride) );
asASSERT( !(!objType && funcTraits.GetTrait(asTRAIT_FINAL)) );
asASSERT( !(!objType && funcTraits.GetTrait(asTRAIT_OVERRIDE)) );
// The internal ref count was already set by the constructor
scriptFunctions.PushLast(func);
@ -1237,7 +1251,7 @@ int asCModule::AddScriptFunction(int sectionIdx, int declaredAt, int id, const a
return 0;
}
// internal
// internal
int asCModule::AddScriptFunction(asCScriptFunction *func)
{
scriptFunctions.PushLast(func);
@ -1247,9 +1261,9 @@ int asCModule::AddScriptFunction(asCScriptFunction *func)
// If the function that is being added is an already compiled shared function
// then it is necessary to look for anonymous functions that may be declared
// within it and add those as well
if( func->isShared && func->funcType == asFUNC_SCRIPT )
if( func->IsShared() && func->funcType == asFUNC_SCRIPT )
{
// Loop through the byte code and check all the
// Loop through the byte code and check all the
// asBC_FuncPtr instructions for anonymous functions
asDWORD *bc = func->scriptData->byteCode.AddressOf();
asUINT bcLength = (asUINT)func->scriptData->byteCode.GetLength();
@ -1275,7 +1289,7 @@ int asCModule::AddScriptFunction(asCScriptFunction *func)
}
// internal
int asCModule::AddImportedFunction(int id, const asCString &name, const asCDataType &returnType, const asCArray<asCDataType> &params, const asCArray<asETypeModifiers> &inOutFlags, const asCArray<asCString *> &defaultArgs, asSNameSpace *ns, const asCString &moduleName)
int asCModule::AddImportedFunction(int id, const asCString &funcName, const asCDataType &returnType, const asCArray<asCDataType> &params, const asCArray<asETypeModifiers> &inOutFlags, const asCArray<asCString *> &defaultArgs, asSNameSpace *ns, const asCString &moduleName)
{
asASSERT(id >= 0);
@ -1291,7 +1305,7 @@ int asCModule::AddImportedFunction(int id, const asCString &name, const asCDataT
return asOUT_OF_MEMORY;
}
func->name = name;
func->name = funcName;
func->id = id;
func->returnType = returnType;
func->nameSpace = ns;
@ -1343,7 +1357,7 @@ int asCModule::BindImportedFunction(asUINT index, asIScriptFunction *func)
return asINVALID_ARG;
asCScriptFunction *src = engine->GetScriptFunction(func->GetId());
if( src == 0 )
if( src == 0 )
return asNO_FUNCTION;
// Verify return type
@ -1454,6 +1468,35 @@ int asCModule::UnbindAllImportedFunctions()
return asSUCCESS;
}
// internal
asCTypeInfo *asCModule::GetType(const char *type, asSNameSpace *ns)
{
asUINT n;
// TODO: optimize: Improve linear search
for (n = 0; n < classTypes.GetLength(); n++)
if (classTypes[n]->name == type &&
classTypes[n]->nameSpace == ns)
return classTypes[n];
for (n = 0; n < enumTypes.GetLength(); n++)
if (enumTypes[n]->name == type &&
enumTypes[n]->nameSpace == ns)
return enumTypes[n];
for (n = 0; n < typeDefs.GetLength(); n++)
if (typeDefs[n]->name == type &&
typeDefs[n]->nameSpace == ns)
return typeDefs[n];
for (n = 0; n < funcDefs.GetLength(); n++)
if (funcDefs[n]->name == type &&
funcDefs[n]->nameSpace == ns)
return funcDefs[n];
return 0;
}
// internal
asCObjectType *asCModule::GetObjectType(const char *type, asSNameSpace *ns)
{
@ -1465,24 +1508,14 @@ asCObjectType *asCModule::GetObjectType(const char *type, asSNameSpace *ns)
classTypes[n]->nameSpace == ns )
return classTypes[n];
for( n = 0; n < enumTypes.GetLength(); n++ )
if( enumTypes[n]->name == type &&
enumTypes[n]->nameSpace == ns )
return enumTypes[n];
for( n = 0; n < typeDefs.GetLength(); n++ )
if( typeDefs[n]->name == type &&
typeDefs[n]->nameSpace == ns )
return typeDefs[n];
return 0;
}
// internal
asCGlobalProperty *asCModule::AllocateGlobalProperty(const char *name, const asCDataType &dt, asSNameSpace *ns)
asCGlobalProperty *asCModule::AllocateGlobalProperty(const char *propName, const asCDataType &dt, asSNameSpace *ns)
{
asCGlobalProperty *prop = engine->AllocateGlobalProperty();
prop->name = name;
prop->name = propName;
prop->nameSpace = ns;
// Allocate the memory for this property based on its type
@ -1538,7 +1571,7 @@ int asCModule::LoadByteCode(asIBinaryStream *in, bool *wasDebugInfoStripped)
{
if( in == 0 ) return asINVALID_ARG;
// Don't allow the module to be rebuilt if there are still
// Don't allow the module to be rebuilt if there are still
// external references that will need the previous code
if( HasExternalReferences(false) )
{
@ -1554,6 +1587,11 @@ int asCModule::LoadByteCode(asIBinaryStream *in, bool *wasDebugInfoStripped)
asCReader read(this, in, engine);
r = read.Read(wasDebugInfoStripped);
if (r < 0)
{
engine->BuildCompleted();
return r;
}
JITCompile();
@ -1601,33 +1639,33 @@ int asCModule::CompileGlobalVar(const char *sectionName, const char *code, int l
}
// Compile the global variable and add it to the module scope
asCBuilder builder(engine, this);
asCBuilder varBuilder(engine, this);
asCString str = code;
r = builder.CompileGlobalVar(sectionName, str.AddressOf(), lineOffset);
r = varBuilder.CompileGlobalVar(sectionName, str.AddressOf(), lineOffset);
engine->BuildCompleted();
// Initialize the variable
if( r >= 0 && engine->ep.initGlobalVarsAfterBuild )
{
// Clear the memory
// Clear the memory
asCGlobalProperty *prop = scriptGlobals.GetLast();
if( prop )
{
memset(prop->GetAddressOfValue(), 0, sizeof(asDWORD)*prop->type.GetSizeOnStackDWords());
if( prop->GetInitFunc() )
{
// Call the init function for the global variable
asIScriptContext *ctx = 0;
int r = engine->CreateContext(&ctx, true);
r = engine->CreateContext(&ctx, true);
if( r < 0 )
return r;
r = ctx->Prepare(prop->GetInitFunc());
if( r >= 0 )
r = ctx->Execute();
ctx->Release();
}
}
@ -1640,7 +1678,7 @@ int asCModule::CompileGlobalVar(const char *sectionName, const char *code, int l
// interface
int asCModule::CompileFunction(const char *sectionName, const char *code, int lineOffset, asDWORD compileFlags, asIScriptFunction **outFunc)
{
// Make sure the outFunc is null if the function fails, so the
// Make sure the outFunc is null if the function fails, so the
// application doesn't attempt to release a non-existent function
if( outFunc )
*outFunc = 0;
@ -1653,7 +1691,7 @@ int asCModule::CompileFunction(const char *sectionName, const char *code, int li
return asNOT_SUPPORTED;
#else
// Validate arguments
if( code == 0 ||
if( code == 0 ||
(compileFlags != 0 && compileFlags != asCOMP_ADD_TO_MODULE) )
return asINVALID_ARG;
@ -1673,10 +1711,10 @@ int asCModule::CompileFunction(const char *sectionName, const char *code, int li
}
// Compile the single function
asCBuilder builder(engine, this);
asCBuilder funcBuilder(engine, this);
asCString str = code;
asCScriptFunction *func = 0;
r = builder.CompileFunction(sectionName, str.AddressOf(), lineOffset, compileFlags, &func);
r = funcBuilder.CompileFunction(sectionName, str.AddressOf(), lineOffset, compileFlags, &func);
engine->BuildCompleted();
@ -1714,22 +1752,32 @@ int asCModule::RemoveFunction(asIScriptFunction *func)
#ifndef AS_NO_COMPILER
// internal
int asCModule::AddFuncDef(const asCString &name, asSNameSpace *ns)
int asCModule::AddFuncDef(const asCString &funcName, asSNameSpace *ns, asCObjectType *parent)
{
// namespace and parent are mutually exclusive
asASSERT((ns == 0 && parent) || (ns && parent == 0));
asCScriptFunction *func = asNEW(asCScriptFunction)(engine, 0, asFUNC_FUNCDEF);
if( func == 0 )
if (func == 0)
return asOUT_OF_MEMORY;
func->name = name;
func->name = funcName;
func->nameSpace = ns;
func->module = this;
funcDefs.PushLast(func);
asCFuncdefType *fdt = asNEW(asCFuncdefType)(engine, func);
funcDefs.PushLast(fdt); // The constructor set the refcount to 1
engine->funcDefs.PushLast(func);
engine->funcDefs.PushLast(fdt); // doesn't increase refcount
func->id = engine->GetNextScriptFunctionId();
engine->AddScriptFunction(func);
if (parent)
{
parent->childFuncDefs.PushLast(fdt);
fdt->parentClass = parent;
}
return (int)funcDefs.GetLength()-1;
}
#endif

View File

@ -1,24 +1,24 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2014 Andreas Jonsson
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
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
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
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
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
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
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
@ -58,12 +58,14 @@ class asCCompiler;
class asCBuilder;
class asCContext;
class asCConfigGroup;
class asCTypedefType;
class asCFuncdefType;
struct asSNameSpace;
struct sBindInfo
{
asCScriptFunction *importedFunctionSignature;
asCString importFromModule;
asCString importFromModule;
int boundFunctionId;
};
@ -74,17 +76,17 @@ struct sObjectTypePair
};
// TODO: import: Remove function imports. When I have implemented function
// 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 an special compile option that will let the application
// 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
@ -130,20 +132,18 @@ public:
// Type identification
virtual asUINT GetObjectTypeCount() const;
virtual asIObjectType *GetObjectTypeByIndex(asUINT index) const;
virtual asIObjectType *GetObjectTypeByName(const char *name) const;
virtual asIObjectType *GetObjectTypeByDecl(const char *decl) 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 const char *GetEnumByIndex(asUINT index, int *enumTypeId, const char **nameSpace) const;
virtual int GetEnumValueCount(int enumTypeId) const;
virtual const char *GetEnumValueByIndex(int enumTypeId, asUINT index, int *outValue) const;
virtual asUINT GetEnumCount() const;
virtual asITypeInfo *GetEnumByIndex(asUINT index) const;
// Typedefs
virtual asUINT GetTypedefCount() const;
virtual const char *GetTypedefByIndex(asUINT index, int *typeId, const char **nameSpace) const;
virtual asUINT GetTypedefCount() const;
virtual asITypeInfo *GetTypedefByIndex(asUINT index) const;
// Dynamic binding between modules
virtual asUINT GetImportedFunctionCount() const;
@ -186,16 +186,18 @@ public:
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 isConstMethod = false, bool isGlobalFunction = false, bool isPrivate = false, bool isProtected = false, bool isFinal = false, bool isOverride = false, bool isShared = false, asSNameSpace *ns = 0);
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, asSNameSpace *ns, const asCString &moduleName);
int AddFuncDef(const asCString &name, asSNameSpace *ns);
int AddFuncDef(const asCString &name, asSNameSpace *ns, asCObjectType *parent);
#endif
int GetNextImportedFunctionId();
asCScriptFunction *GetImportedFunction(int funcId) const;
asCTypeInfo *GetType(const char *type, asSNameSpace *ns);
asCObjectType *GetObjectType(const char *type, asSNameSpace *ns);
asCGlobalProperty *AllocateGlobalProperty(const char *name, const asCDataType &dt, asSNameSpace *ns);
void UninitializeGlobalProp(asCGlobalProperty *prop);
asCString name;
@ -208,7 +210,7 @@ public:
// 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 *> scriptFunctions; // increases ref count
// This array holds global functions declared in the module. These references are not counted,
// 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> globalFunctions; // doesn't increase ref count
// This array holds imported functions in the module.
@ -223,11 +225,16 @@ public:
// This array holds class and interface types
asCArray<asCObjectType*> classTypes; // increases ref count
// This array holds enum types
asCArray<asCObjectType*> enumTypes; // increases ref count
asCArray<asCEnumType*> enumTypes; // increases ref count
// This array holds typedefs
asCArray<asCObjectType*> typeDefs; // increases ref count
asCArray<asCTypedefType*> typeDefs; // increases ref count
// This array holds the funcdefs declared in the module
asCArray<asCScriptFunction*> funcDefs; // increases ref count
asCArray<asCFuncdefType*> funcDefs; // increases ref count
// This array holds types that have been explicitly declared with 'external'
asCArray<asCTypeInfo*> externalTypes; // doesn't increase ref count
// This array holds functions that have been explicitly declared with 'external'
asCArray<asCScriptFunction*> externalFunctions; // doesn't increase ref count
};
END_AS_NAMESPACE

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
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
@ -45,155 +45,46 @@
BEGIN_AS_NAMESPACE
asCObjectType::asCObjectType()
asCObjectType::asCObjectType() : asCTypeInfo()
{
externalRefCount.set(0);
internalRefCount.set(1); // start with one internal ref-count
engine = 0;
module = 0;
derivedFrom = 0;
size = 0;
typeId = -1; // start as -1 to signal that it hasn't been defined
acceptValueSubType = true;
acceptRefSubType = true;
scriptSectionIdx = -1;
declaredAt = 0;
accessMask = 0xFFFFFFFF;
nameSpace = 0;
#ifdef WIP_16BYTE_ALIGN
alignment = 4;
#endif
}
asCObjectType::asCObjectType(asCScriptEngine *engine)
asCObjectType::asCObjectType(asCScriptEngine *in_engine) : asCTypeInfo(in_engine)
{
externalRefCount.set(0);
internalRefCount.set(1); // start with one internal ref count
this->engine = engine;
module = 0;
derivedFrom = 0;
typeId = -1; // start as -1 to signal that it hasn't been defined
acceptValueSubType = true;
acceptRefSubType = true;
acceptRefSubType = true;
scriptSectionIdx = -1;
declaredAt = 0;
accessMask = 0xFFFFFFFF;
nameSpace = engine->nameSpaces[0];
#ifdef WIP_16BYTE_ALIGN
alignment = 4;
#endif
}
int asCObjectType::AddRef() const
{
return externalRefCount.atomicInc();
}
int asCObjectType::Release() const
{
int r = externalRefCount.atomicDec();
if( r == 0 )
{
// There are no more external references, if there are also no
// internal references then it is time to delete the object type
if( internalRefCount.get() == 0 )
{
// If the engine is no longer set, then it has already been
// released and we must take care of the deletion ourselves
asDELETE(const_cast<asCObjectType*>(this), asCObjectType);
}
}
return r;
}
int asCObjectType::AddRefInternal()
{
return internalRefCount.atomicInc();
}
int asCObjectType::ReleaseInternal()
{
int r = internalRefCount.atomicDec();
if( r == 0 )
{
// There are no more internal references, if there are also no
// external references then it is time to delete the object type
if( externalRefCount.get() == 0 )
{
// If the engine is no longer set, then it has already been
// released and we must take care of the deletion ourselves
asDELETE(const_cast<asCObjectType*>(this), asCObjectType);
}
}
return r;
}
// interface
asIScriptModule *asCObjectType::GetModule() const
asUINT asCObjectType::GetChildFuncdefCount() const
{
return module;
return childFuncDefs.GetLength();
}
void *asCObjectType::SetUserData(void *data, asPWORD type)
// interface
asITypeInfo *asCObjectType::GetChildFuncdef(asUINT index) const
{
// As a thread might add a new new user data at the same time as another
// it is necessary to protect both read and write access to the userData member
ACQUIREEXCLUSIVE(engine->engineRWLock);
if (index >= childFuncDefs.GetLength())
return 0;
// It is not intended to store a lot of different types of userdata,
// so a more complex structure like a associative map would just have
// more overhead than a simple array.
for( asUINT n = 0; n < userData.GetLength(); n += 2 )
{
if( userData[n] == type )
{
void *oldData = reinterpret_cast<void*>(userData[n+1]);
userData[n+1] = reinterpret_cast<asPWORD>(data);
RELEASEEXCLUSIVE(engine->engineRWLock);
return oldData;
}
}
userData.PushLast(type);
userData.PushLast(reinterpret_cast<asPWORD>(data));
RELEASEEXCLUSIVE(engine->engineRWLock);
return 0;
}
void *asCObjectType::GetUserData(asPWORD type) const
{
// There may be multiple threads reading, but when
// setting the user data nobody must be reading.
ACQUIRESHARED(engine->engineRWLock);
for( asUINT n = 0; n < userData.GetLength(); n += 2 )
{
if( userData[n] == type )
{
RELEASESHARED(engine->engineRWLock);
return reinterpret_cast<void*>(userData[n+1]);
}
}
RELEASESHARED(engine->engineRWLock);
return 0;
return childFuncDefs[index];
}
// internal
void asCObjectType::DestroyInternal()
{
if( engine == 0 ) return;
@ -207,13 +98,38 @@ void asCObjectType::DestroyInternal()
}
// Release the object types held by the templateSubTypes
bool isTemplateInstance = templateSubTypes.GetLength() > 0;
for( asUINT subtypeIndex = 0; subtypeIndex < templateSubTypes.GetLength(); subtypeIndex++ )
{
if( templateSubTypes[subtypeIndex].GetObjectType() )
templateSubTypes[subtypeIndex].GetObjectType()->ReleaseInternal();
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;
@ -222,25 +138,7 @@ void asCObjectType::DestroyInternal()
ReleaseAllFunctions();
asUINT n;
for( n = 0; n < enumValues.GetLength(); n++ )
{
if( enumValues[n] )
asDELETE(enumValues[n],asSEnumValue);
}
enumValues.SetLength(0);
// Clean the user data
for( n = 0; n < userData.GetLength(); n += 2 )
{
if( userData[n+1] )
{
for( asUINT c = 0; c < engine->cleanObjectTypeFuncs.GetLength(); c++ )
if( engine->cleanObjectTypeFuncs[c].type == userData[n] )
engine->cleanObjectTypeFuncs[c].cleanFunc(this);
}
}
userData.SetLength(0);
CleanUserData();
// Remove the type from the engine
if( typeId != -1 )
@ -252,14 +150,11 @@ void asCObjectType::DestroyInternal()
asCObjectType::~asCObjectType()
{
if( engine == 0 )
return;
DestroyInternal();
}
// interface
bool asCObjectType::Implements(const asIObjectType *objType) const
bool asCObjectType::Implements(const asITypeInfo *objType) const
{
if( this == objType )
return true;
@ -271,7 +166,7 @@ bool asCObjectType::Implements(const asIObjectType *objType) const
}
// interface
bool asCObjectType::DerivesFrom(const asIObjectType *objType) const
bool asCObjectType::DerivesFrom(const asITypeInfo *objType) const
{
if( this == objType )
return true;
@ -288,56 +183,6 @@ bool asCObjectType::DerivesFrom(const asIObjectType *objType) const
return false;
}
bool asCObjectType::IsShared() const
{
// Objects that can be declared by scripts need to have the explicit flag asOBJ_SHARED
if( flags & (asOBJ_SCRIPT_OBJECT|asOBJ_ENUM) ) return flags & asOBJ_SHARED ? true : false;
// Otherwise we assume the object to be shared
return true;
}
// interface
const char *asCObjectType::GetName() const
{
return name.AddressOf();
}
// interface
const char *asCObjectType::GetNamespace() const
{
return nameSpace->name.AddressOf();
}
// interface
asDWORD asCObjectType::GetFlags() const
{
return flags;
}
// interface
asUINT asCObjectType::GetSize() const
{
return size;
}
// interface
int asCObjectType::GetTypeId() const
{
if( typeId == -1 )
{
// We need a non const pointer to create the asCDataType object.
// We're not breaking anything here because this function is not
// modifying the object, so this const cast is safe.
asCObjectType *ot = const_cast<asCObjectType*>(this);
// The engine will define the typeId for this object type
engine->GetTypeIdFromDataType(asCDataType::CreateObject(ot, false));
}
return typeId;
}
// interface
int asCObjectType::GetSubTypeId(asUINT subtypeIndex) const
{
@ -352,12 +197,12 @@ int asCObjectType::GetSubTypeId(asUINT subtypeIndex) const
}
// interface
asIObjectType *asCObjectType::GetSubType(asUINT subtypeIndex) const
asITypeInfo *asCObjectType::GetSubType(asUINT subtypeIndex) const
{
if( subtypeIndex >= templateSubTypes.GetLength() )
return 0;
return templateSubTypes[subtypeIndex].GetObjectType();
return templateSubTypes[subtypeIndex].GetTypeInfo();
}
asUINT asCObjectType::GetSubTypeCount() const
@ -370,7 +215,7 @@ asUINT asCObjectType::GetInterfaceCount() const
return asUINT(interfaces.GetLength());
}
asIObjectType *asCObjectType::GetInterface(asUINT index) const
asITypeInfo *asCObjectType::GetInterface(asUINT index) const
{
return interfaces[index];
}
@ -384,11 +229,6 @@ bool asCObjectType::IsInterface() const
return false;
}
asIScriptEngine *asCObjectType::GetEngine() const
{
return engine;
}
// interface
asUINT asCObjectType::GetFactoryCount() const
{
@ -437,12 +277,12 @@ asIScriptFunction *asCObjectType::GetMethodByIndex(asUINT index, bool getVirtual
}
// interface
asIScriptFunction *asCObjectType::GetMethodByName(const char *name, bool getVirtual) const
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 == name )
if( engine->scriptFunctions[methods[n]]->name == in_name )
{
if( id == -1 )
id = methods[n];
@ -454,7 +294,7 @@ asIScriptFunction *asCObjectType::GetMethodByName(const char *name, bool getVirt
if( id == -1 ) return 0;
asCScriptFunction *func = engine->scriptFunctions[id];
if( !getVirtual )
if( !in_getVirtual )
{
if( func && func->funcType == asFUNC_VIRTUAL )
return virtualFunctionTable[func->vfTableIdx];
@ -497,26 +337,30 @@ asUINT asCObjectType::GetPropertyCount() const
}
// interface
int asCObjectType::GetProperty(asUINT index, const char **name, int *typeId, bool *isPrivate, bool *isProtected, int *offset, bool *isReference, asDWORD *accessMask) const
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( name )
*name = prop->name.AddressOf();
if( typeId )
*typeId = engine->GetTypeIdFromDataType(prop->type);
if( isPrivate )
*isPrivate = prop->isPrivate;
if( isProtected )
*isProtected = prop->isProtected;
if( offset )
*offset = prop->byteOffset;
if( isReference )
*isReference = prop->type.IsReference();
if( accessMask )
*accessMask = prop->accessMask;
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;
}
@ -541,7 +385,7 @@ const char *asCObjectType::GetPropertyDeclaration(asUINT index, bool includeName
return tempString->AddressOf();
}
asIObjectType *asCObjectType::GetBaseType() const
asITypeInfo *asCObjectType::GetBaseType() const
{
return derivedFrom;
}
@ -661,24 +505,8 @@ asIScriptFunction *asCObjectType::GetBehaviourByIndex(asUINT index, asEBehaviour
return 0;
}
// interface
const char *asCObjectType::GetConfigGroup() const
{
asCConfigGroup *group = engine->FindConfigGroupForObjectType(this);
if( group == 0 )
return 0;
return group->groupName.AddressOf();
}
// interface
asDWORD asCObjectType::GetAccessMask() const
{
return accessMask;
}
// internal
asCObjectProperty *asCObjectType::AddPropertyToClass(const asCString &name, const asCDataType &dt, bool isPrivate, bool isProtected, bool isInherited)
asCObjectProperty *asCObjectType::AddPropertyToClass(const asCString &propName, const asCDataType &dt, bool isPrivate, bool isProtected, bool isInherited)
{
asASSERT( flags & asOBJ_SCRIPT_OBJECT );
asASSERT( dt.CanBeInstantiated() );
@ -692,7 +520,7 @@ asCObjectProperty *asCObjectType::AddPropertyToClass(const asCString &name, cons
return 0;
}
prop->name = name;
prop->name = propName;
prop->type = dt;
prop->isPrivate = isPrivate;
prop->isProtected = isProtected;
@ -705,7 +533,7 @@ asCObjectProperty *asCObjectType::AddPropertyToClass(const asCString &name, cons
// 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.GetObjectType()->flags & asOBJ_POD )
if( dt.GetTypeInfo()->flags & asOBJ_POD )
propSize = dt.GetSizeInMemoryBytes();
else
{
@ -714,6 +542,12 @@ asCObjectProperty *asCObjectType::AddPropertyToClass(const asCString &name, cons
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();
@ -738,11 +572,11 @@ asCObjectProperty *asCObjectType::AddPropertyToClass(const asCString &name, cons
properties.PushLast(prop);
// Make sure the struct holds a reference to the config group where the object is registered
asCConfigGroup *group = engine->FindConfigGroupForObjectType(prop->type.GetObjectType());
asCConfigGroup *group = engine->FindConfigGroupForTypeInfo(prop->type.GetTypeInfo());
if( group != 0 ) group->AddRef();
// Add reference to object types
asCObjectType *type = prop->type.GetObjectType();
asCTypeInfo *type = prop->type.GetTypeInfo();
if( type )
type->AddRefInternal();
@ -759,18 +593,18 @@ void asCObjectType::ReleaseAllProperties()
if( flags & asOBJ_SCRIPT_OBJECT )
{
// Release the config group for script classes that are being destroyed
asCConfigGroup *group = engine->FindConfigGroupForObjectType(properties[n]->type.GetObjectType());
asCConfigGroup *group = engine->FindConfigGroupForTypeInfo(properties[n]->type.GetTypeInfo());
if( group != 0 ) group->Release();
// Release references to objects types
asCObjectType *type = properties[n]->type.GetObjectType();
asCTypeInfo *type = properties[n]->type.GetTypeInfo();
if( type )
type->ReleaseInternal();
}
else
{
// Release template instance types (ref increased by RegisterObjectProperty)
asCObjectType *type = properties[n]->type.GetObjectType();
asCTypeInfo *type = properties[n]->type.GetTypeInfo();
if( type )
type->ReleaseInternal();
}

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
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
@ -41,17 +41,13 @@
#ifndef AS_OBJECTTYPE_H
#define AS_OBJECTTYPE_H
#include "as_atomic.h"
#include "as_string.h"
#include "as_property.h"
#include "as_array.h"
#include "as_scriptfunction.h"
#include "as_typeinfo.h"
BEGIN_AS_NAMESPACE
// TODO: memory: Need to minimize used memory here, because not all types use all properties of the class
struct asSTypeBehaviour
{
asSTypeBehaviour()
@ -99,134 +95,75 @@ struct asSTypeBehaviour
asCArray<int> constructors;
};
struct asSEnumValue
{
asCString name;
int value;
};
class asCScriptEngine;
struct asSNameSpace;
class asCObjectType : public asIObjectType
class asCObjectType : public asCTypeInfo
{
public:
//=====================================
// From asIObjectType
//=====================================
asIScriptEngine *GetEngine() const;
const char *GetConfigGroup() const;
asDWORD GetAccessMask() const;
asIScriptModule *GetModule() const;
// Memory management
int AddRef() const;
int Release() const;
// Type info
const char *GetName() const;
const char *GetNamespace() const;
asIObjectType *GetBaseType() const;
bool DerivesFrom(const asIObjectType *objType) const;
asDWORD GetFlags() const;
asUINT GetSize() const;
int GetTypeId() const;
int GetSubTypeId(asUINT subtypeIndex = 0) const;
asIObjectType *GetSubType(asUINT subtypeIndex = 0) const;
asUINT GetSubTypeCount() const;
// Interfaces
asUINT GetInterfaceCount() const;
asIObjectType *GetInterface(asUINT index) const;
bool Implements(const asIObjectType *objType) const;
// Factories
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;
// Methods
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;
// Properties
asUINT GetPropertyCount() const;
int GetProperty(asUINT index, const char **name, int *typeId, bool *isPrivate, bool *isProtected, int *offset, bool *isReference, asDWORD *accessMask) const;
const char *GetPropertyDeclaration(asUINT index, bool includeNamespace = false) const;
// Behaviours
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;
// User data
void *SetUserData(void *data, asPWORD type);
void *GetUserData(asPWORD type) const;
//===========================================
// Internal
//===========================================
public:
asCObjectType(asCScriptEngine *engine);
~asCObjectType();
void DestroyInternal();
// Keep an internal reference counter to separate references coming from
// application or script objects and references coming from the script code
int AddRefInternal();
int ReleaseInternal();
void ReleaseAllFunctions();
bool IsInterface() const;
bool IsShared() const;
asCObjectProperty *AddPropertyToClass(const asCString &name, const asCDataType &dt, bool isPrivate, bool isProtected, bool isInherited);
void ReleaseAllProperties();
asCString name;
asSNameSpace *nameSpace;
int size;
#ifdef WIP_16BYTE_ALIGN
int alignment;
#endif
mutable int typeId;
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;
asCArray<asSEnumValue*> enumValues;
asCObjectType * derivedFrom;
asCArray<asCScriptFunction*> virtualFunctionTable;
asDWORD flags;
asDWORD accessMask;
// 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;
asCArray<asCDataType> templateSubTypes; // increases refCount for typeinfo held in datatype
bool acceptValueSubType;
bool acceptRefSubType;
// Store the script section where the code was declared
int scriptSectionIdx;
// Store the location where the function was declared (row in the lower 20 bits, and column in the upper 12)
int declaredAt;
asCScriptEngine *engine;
asCModule *module;
asCArray<asPWORD> userData;
protected:
friend class asCScriptEngine;
friend class asCConfigGroup;
friend class asCModule;
asCObjectType();
mutable asCAtomic externalRefCount;
asCAtomic internalRefCount;
};
END_AS_NAMESPACE

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +1,24 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
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
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
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
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
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
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
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
@ -66,7 +66,7 @@ public:
int ParseVarInit(asCScriptCode *script, asCScriptNode *init);
int ParseExpression(asCScriptCode *script);
#endif
asCScriptNode *GetScriptNode();
protected:
@ -90,6 +90,7 @@ protected:
asCScriptNode *ParseRealType();
asCScriptNode *ParseDataType(bool allowVariableType = false, bool allowAuto = false);
asCScriptNode *ParseIdentifier();
bool ParseTemplTypeList(asCScriptNode *node, bool required = true);
asCScriptNode *ParseListPattern();
@ -161,7 +162,7 @@ protected:
bool IsPostOperator(int tokenType);
bool IsAssignOperator(int tokenType);
bool CheckTemplateType(sToken &t);
bool CheckTemplateType(const sToken &t);
#endif
asCScriptNode *ParseToken(int token);

View File

@ -1,24 +1,24 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
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
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
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
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
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
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
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
@ -53,12 +53,14 @@ struct asSNameSpace;
class asCObjectProperty
{
public:
asCObjectProperty() {accessMask = 0xFFFFFFFF;}
asCObjectProperty(const asCObjectProperty &o) : name(o.name), type(o.type), byteOffset(o.byteOffset), accessMask(o.accessMask), isPrivate(o.isPrivate), isProtected(o.isProtected), isInherited(o.isInherited) {}
asCObjectProperty() : byteOffset(0), accessMask(0xFFFFFFFF), compositeOffset(0), isCompositeIndirect(false), isPrivate(false), isProtected(false), isInherited(false) {}
asCObjectProperty(const asCObjectProperty &o) : name(o.name), type(o.type), byteOffset(o.byteOffset), accessMask(o.accessMask), compositeOffset(o.compositeOffset), isCompositeIndirect(o.isCompositeIndirect), isPrivate(o.isPrivate), isProtected(o.isProtected), isInherited(o.isInherited) {}
asCString name;
asCDataType type;
int byteOffset;
asDWORD accessMask;
int compositeOffset;
bool isCompositeIndirect;
bool isPrivate;
bool isProtected;
bool isInherited;

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2014 Andreas Jonsson
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
@ -64,15 +64,15 @@ protected:
int ReadInner();
void ReadData(void *data, asUINT size);
int ReadData(void *data, asUINT size);
void ReadString(asCString *str);
asCScriptFunction *ReadFunction(bool &isNew, bool addToModule = true, bool addToEngine = true, bool addToGC = true);
void ReadFunctionSignature(asCScriptFunction *func);
asCScriptFunction *ReadFunction(bool &isNew, bool addToModule = true, bool addToEngine = true, bool addToGC = true, bool *isExternal = 0);
void ReadFunctionSignature(asCScriptFunction *func, asCObjectType **parentClass = 0);
void ReadGlobalProperty();
void ReadObjectProperty(asCObjectType *ot);
void ReadDataType(asCDataType *dt);
asCObjectType * ReadObjectType();
void ReadObjectTypeDeclaration(asCObjectType *ot, int phase);
asCTypeInfo *ReadTypeInfo();
void ReadTypeDeclaration(asCTypeInfo *ot, int phase, bool *isExternal = 0);
void ReadByteCode(asCScriptFunction *func);
asWORD ReadEncodedUInt16();
asUINT ReadEncodedUInt();
@ -84,7 +84,7 @@ protected:
void ReadUsedStringConstants();
void ReadUsedObjectProps();
asCObjectType * FindObjectType(int idx);
asCTypeInfo * FindType(int idx);
int FindTypeId(int idx);
short FindObjectPropOffset(asWORD index);
asCScriptFunction *FindFunction(int idx);
@ -99,10 +99,10 @@ protected:
// Temporary storage for persisting variable data
asCArray<int> usedTypeIds;
asCArray<asCObjectType*> usedTypes;
asCArray<asCTypeInfo*> usedTypes;
asCArray<asCScriptFunction*> usedFunctions;
asCArray<void*> usedGlobalProperties;
asCArray<int> usedStringConstants;
asCArray<void*> usedStringConstants;
asCArray<asCScriptFunction*> savedFunctions;
asCArray<asCDataType> savedDataTypes;
@ -113,8 +113,8 @@ protected:
struct SObjProp
{
asCObjectType *objType;
int offset;
asCObjectType *objType;
asCObjectProperty *prop;
};
asCArray<SObjProp> usedObjectProperties;
@ -165,8 +165,12 @@ protected:
asIBinaryStream *stream;
asCScriptEngine *engine;
bool stripDebugInfo;
bool error;
asUINT bytesWritten;
void WriteData(const void *data, asUINT size);
int Error(const char *msg);
int WriteData(const void *data, asUINT size);
void WriteString(asCString *str);
void WriteFunction(asCScriptFunction *func);
@ -174,18 +178,18 @@ protected:
void WriteGlobalProperty(asCGlobalProperty *prop);
void WriteObjectProperty(asCObjectProperty *prop);
void WriteDataType(const asCDataType *dt);
void WriteObjectType(asCObjectType *ot);
void WriteObjectTypeDeclaration(asCObjectType *ot, int phase);
void WriteTypeInfo(asCTypeInfo *ot);
void WriteTypeDeclaration(asCTypeInfo *ot, int phase);
void WriteByteCode(asCScriptFunction *func);
void WriteEncodedInt64(asINT64 i);
// Helper functions for storing variable data
int FindObjectTypeIdx(asCObjectType*);
int FindTypeInfoIdx(asCTypeInfo *ti);
int FindTypeIdIdx(int typeId);
int FindFunctionIndex(asCScriptFunction *func);
int FindGlobalPropPtrIndex(void *);
int FindStringConstantIndex(int id);
int FindObjectPropIndex(short offset, int typeId);
int FindStringConstantIndex(void *str);
int FindObjectPropIndex(short offset, int typeId, asDWORD *bc);
void CalculateAdjustmentByPos(asCScriptFunction *func);
int AdjustStackPosition(int pos);
@ -201,24 +205,24 @@ protected:
// Temporary storage for persisting variable data
asCArray<int> usedTypeIds;
asCArray<asCObjectType*> usedTypes;
asCArray<asCTypeInfo*> usedTypes;
asCArray<asCScriptFunction*> usedFunctions;
asCArray<void*> usedGlobalProperties;
asCArray<int> usedStringConstants;
asCMap<int, int> stringIdToIndexMap;
asCArray<void*> usedStringConstants;
asCMap<void*, int> stringToIndexMap;
asCArray<asCScriptFunction*> savedFunctions;
asCArray<asCDataType> savedDataTypes;
asCArray<asCString> savedStrings;
asCMap<asCStringPointer, int> stringToIdMap;
asCMap<asCString, int> stringToIdMap;
asCArray<int> adjustStackByPos;
asCArray<int> adjustNegativeStackByPos;
asCArray<int> bytecodeNbrByPos;
struct SObjProp
{
asCObjectType *objType;
int offset;
asCObjectType *objType;
asCObjectProperty *prop;
};
asCArray<SObjProp> usedObjectProperties;

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2013 Andreas Jonsson
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
@ -58,41 +58,41 @@ asCScriptCode::~asCScriptCode()
}
}
int asCScriptCode::SetCode(const char *name, const char *code, bool makeCopy)
int asCScriptCode::SetCode(const char *in_name, const char *in_code, bool in_makeCopy)
{
return SetCode(name, code, 0, makeCopy);
return SetCode(in_name, in_code, 0, in_makeCopy);
}
int asCScriptCode::SetCode(const char *name, const char *code, size_t length, bool makeCopy)
int asCScriptCode::SetCode(const char *in_name, const char *in_code, size_t in_length, bool in_makeCopy)
{
if( !code ) return asINVALID_ARG;
this->name = name ? name : "";
if( !sharedCode && this->code )
asDELETEARRAY(this->code);
if( !in_code) return asINVALID_ARG;
this->name = in_name ? in_name : "";
if( !sharedCode && code )
asDELETEARRAY(code);
if( length == 0 )
length = strlen(code);
if( makeCopy )
if( in_length == 0 )
in_length = strlen(in_code);
if( in_makeCopy )
{
codeLength = length;
codeLength = in_length;
sharedCode = false;
this->code = asNEWARRAY(char,length);
if( this->code == 0 )
code = asNEWARRAY(char, in_length);
if( code == 0 )
return asOUT_OF_MEMORY;
memcpy((char*)this->code, code, length);
memcpy(code, in_code, in_length);
}
else
{
codeLength = length;
this->code = const_cast<char*>(code);
codeLength = in_length;
code = const_cast<char*>(in_code);
sharedCode = true;
}
// Find the positions of each line
linePositions.PushLast(0);
for( size_t n = 0; n < length; n++ )
if( code[n] == '\n' ) linePositions.PushLast(n+1);
linePositions.PushLast(length);
for( size_t n = 0; n < in_length; n++ )
if( in_code[n] == '\n' ) linePositions.PushLast(n+1);
linePositions.PushLast(in_length);
return asSUCCESS;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +1,24 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
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
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
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
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
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
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
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
@ -86,7 +86,7 @@ public:
virtual asIJITCompiler *GetJITCompiler() const;
// Global functions
virtual int RegisterGlobalFunction(const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv, void *objForThiscall = 0);
virtual int RegisterGlobalFunction(const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv, void *auxiliary = 0);
virtual asUINT GetGlobalFunctionCount() const;
virtual asIScriptFunction *GetGlobalFunctionByIndex(asUINT index) const;
virtual asIScriptFunction *GetGlobalFunctionByDecl(const char *declaration) const;
@ -100,18 +100,16 @@ public:
// Type registration
virtual int RegisterObjectType(const char *obj, int byteSize, asDWORD flags);
virtual int RegisterObjectProperty(const char *obj, const char *declaration, int byteOffset);
virtual int RegisterObjectMethod(const char *obj, const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv, void *objForThiscall = 0);
virtual int RegisterObjectBehaviour(const char *obj, asEBehaviours behaviour, const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv, void *objForThiscall = 0);
virtual int RegisterObjectProperty(const char *obj, const char *declaration, int byteOffset, int compositeOffset = 0, bool isCompositeIndirect = false);
virtual int RegisterObjectMethod(const char *obj, const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv, void *auxiliary = 0, int compositeOffset = 0, bool isCompositeIndirect = false);
virtual int RegisterObjectBehaviour(const char *obj, asEBehaviours behaviour, const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv, void *auxiliary = 0, int compositeOffset = 0, bool isCompositeIndirect = false);
virtual int RegisterInterface(const char *name);
virtual int RegisterInterfaceMethod(const char *intf, const char *declaration);
virtual asUINT GetObjectTypeCount() const;
virtual asIObjectType *GetObjectTypeByIndex(asUINT index) const;
virtual asIObjectType *GetObjectTypeByName(const char *name) const;
virtual asIObjectType *GetObjectTypeByDecl(const char *decl) const;
virtual asITypeInfo *GetObjectTypeByIndex(asUINT index) const;
// String factory
virtual int RegisterStringFactory(const char *datatype, const asSFuncPtr &factoryFunc, asDWORD callConv, void *objForThiscall = 0);
virtual int RegisterStringFactory(const char *datatype, asIStringFactory *factory);
virtual int GetStringFactoryReturnTypeId(asDWORD *flags) const;
// Default array type
@ -119,23 +117,21 @@ public:
virtual int GetDefaultArrayTypeId() const;
// Enums
virtual int RegisterEnum(const char *type);
virtual int RegisterEnumValue(const char *type, const char *name, int value);
virtual asUINT GetEnumCount() const;
virtual const char *GetEnumByIndex(asUINT index, int *enumTypeId, const char **nameSpace, const char **configGroup = 0, asDWORD *accessMask = 0) const;
virtual int GetEnumValueCount(int enumTypeId) const;
virtual const char *GetEnumValueByIndex(int enumTypeId, asUINT index, int *outValue) const;
virtual int RegisterEnum(const char *type);
virtual int RegisterEnumValue(const char *type, const char *name, int value);
virtual asUINT GetEnumCount() const;
virtual asITypeInfo *GetEnumByIndex(asUINT index) const;
// Funcdefs
virtual int RegisterFuncdef(const char *decl);
virtual asUINT GetFuncdefCount() const;
virtual asIScriptFunction *GetFuncdefByIndex(asUINT index) const;
virtual int RegisterFuncdef(const char *decl);
virtual asUINT GetFuncdefCount() const;
virtual asITypeInfo *GetFuncdefByIndex(asUINT index) const;
// Typedefs
// TODO: interface: Should perhaps rename this to Alias, since it doesn't really create a new type
virtual int RegisterTypedef(const char *type, const char *decl);
virtual asUINT GetTypedefCount() const;
virtual const char *GetTypedefByIndex(asUINT index, int *typeId, const char **nameSpace, const char **configGroup = 0, asDWORD *accessMask = 0) const;
virtual int RegisterTypedef(const char *type, const char *decl);
virtual asUINT GetTypedefCount() const;
virtual asITypeInfo *GetTypedefByIndex(asUINT index) const;
// Configuration groups
virtual int BeginConfigGroup(const char *groupName);
@ -153,29 +149,26 @@ public:
// Script functions
virtual asIScriptFunction *GetFunctionById(int funcId) const;
virtual asIScriptFunction *GetFuncDefFromTypeId(int typeId) const;
// Type identification
virtual asIObjectType *GetObjectTypeById(int typeId) const;
virtual int GetTypeIdByDecl(const char *decl) const;
virtual const char *GetTypeDeclaration(int typeId, bool includeNamespace = false) const;
virtual int GetSizeOfPrimitiveType(int typeId) const;
virtual asITypeInfo *GetTypeInfoById(int typeId) const;
virtual asITypeInfo *GetTypeInfoByName(const char *name) const;
virtual asITypeInfo *GetTypeInfoByDecl(const char *decl) const;
// Script execution
virtual asIScriptContext *CreateContext();
virtual void *CreateScriptObject(const asIObjectType *type);
virtual void *CreateScriptObjectCopy(void *obj, const asIObjectType *type);
virtual void *CreateUninitializedScriptObject(const asIObjectType *type);
virtual void *CreateScriptObject(const asITypeInfo *type);
virtual void *CreateScriptObjectCopy(void *obj, const asITypeInfo *type);
virtual void *CreateUninitializedScriptObject(const asITypeInfo *type);
virtual asIScriptFunction *CreateDelegate(asIScriptFunction *func, void *obj);
virtual int AssignScriptObject(void *dstObj, void *srcObj, const asIObjectType *type);
virtual void ReleaseScriptObject(void *obj, const asIObjectType *type);
virtual void AddRefScriptObject(void *obj, const asIObjectType *type);
virtual int RefCastObject(void *obj, asIObjectType *fromType, asIObjectType *toType, void **newPtr, bool useOnlyImplicitCast = false);
#ifdef AS_DEPRECATED
// Deprecated since 2.30.0, 2014-11-04
virtual bool IsHandleCompatibleWithObject(void *obj, int objTypeId, int handleTypeId) const;
#endif
virtual asILockableSharedBool *GetWeakRefFlagOfScriptObject(void *obj, const asIObjectType *type) const;
virtual int AssignScriptObject(void *dstObj, void *srcObj, const asITypeInfo *type);
virtual void ReleaseScriptObject(void *obj, const asITypeInfo *type);
virtual void AddRefScriptObject(void *obj, const asITypeInfo *type);
virtual int RefCastObject(void *obj, asITypeInfo *fromType, asITypeInfo *toType, void **newPtr, bool useOnlyImplicitCast = false);
virtual asILockableSharedBool *GetWeakRefFlagOfScriptObject(void *obj, const asITypeInfo *type) const;
// Context pooling
virtual asIScriptContext *RequestContext();
@ -188,8 +181,8 @@ public:
// Garbage collection
virtual int GarbageCollect(asDWORD flags = asGC_FULL_CYCLE, asUINT numIterations = 1);
virtual void GetGCStatistics(asUINT *currentSize, asUINT *totalDestroyed, asUINT *totalDetected, asUINT *newObjects, asUINT *totalNewDestroyed) const;
virtual int NotifyGarbageCollectorOfNewObject(void *obj, asIObjectType *type);
virtual int GetObjectInGC(asUINT idx, asUINT *seqNbr, void **obj = 0, asIObjectType **type = 0);
virtual int NotifyGarbageCollectorOfNewObject(void *obj, asITypeInfo *type);
virtual int GetObjectInGC(asUINT idx, asUINT *seqNbr, void **obj = 0, asITypeInfo **type = 0);
virtual void GCEnumCallback(void *reference);
// User data
@ -199,7 +192,7 @@ public:
virtual void SetModuleUserDataCleanupCallback(asCLEANMODULEFUNC_t callback, asPWORD type);
virtual void SetContextUserDataCleanupCallback(asCLEANCONTEXTFUNC_t callback, asPWORD type);
virtual void SetFunctionUserDataCleanupCallback(asCLEANFUNCTIONFUNC_t callback, asPWORD type);
virtual void SetObjectTypeUserDataCleanupCallback(asCLEANOBJECTTYPEFUNC_t callback, asPWORD type);
virtual void SetTypeInfoUserDataCleanupCallback(asCLEANTYPEINFOFUNC_t callback, asPWORD type);
virtual void SetScriptObjectUserDataCleanupCallback(asCLEANSCRIPTOBJECTFUNC_t callback, asPWORD type);
//===========================================================
@ -219,8 +212,8 @@ public:
friend class asCByteCode;
friend int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *internal, asCScriptEngine *engine);
int RegisterMethodToObjectType(asCObjectType *objectType, const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv, void *objForThiscall = 0);
int RegisterBehaviourToObjectType(asCObjectType *objectType, asEBehaviours behaviour, const char *decl, const asSFuncPtr &funcPointer, asDWORD callConv, void *objForThiscall);
int RegisterMethodToObjectType(asCObjectType *objectType, const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv, void *auxiliary = 0, int compositeOffset = 0, bool isCompositeIndirect = false);
int RegisterBehaviourToObjectType(asCObjectType *objectType, asEBehaviours behaviour, const char *decl, const asSFuncPtr &funcPointer, asDWORD callConv, void *auxiliary = 0, int compositeOffset = 0, bool isCompositeIndirect = false);
int VerifyVarTypeNotInFunction(asCScriptFunction *func);
@ -241,18 +234,18 @@ public:
void *CallObjectMethodRetPtr(void *obj, int param1, asCScriptFunction *func) const;
void CallGlobalFunction(void *param1, void *param2, asSSystemFunctionInterface *func, asCScriptFunction *desc) const;
bool CallGlobalFunctionRetBool(void *param1, void *param2, asSSystemFunctionInterface *func, asCScriptFunction *desc) const;
int CallScriptObjectMethod(void *obj, int func);
void ConstructScriptObjectCopy(void *mem, void *obj, asCObjectType *type);
void DeleteDiscardedModules();
void RemoveTemplateInstanceType(asCObjectType *t);
void RemoveTypeAndRelatedFromList(asCMap<asCObjectType*,char> &types, asCObjectType *ot);
asCConfigGroup *FindConfigGroupForFunction(int funcId) const;
asCConfigGroup *FindConfigGroupForGlobalVar(int gvarId) const;
asCConfigGroup *FindConfigGroupForObjectType(const asCObjectType *type) const;
asCConfigGroup *FindConfigGroupForFuncDef(const asCScriptFunction *funcDef) const;
asCConfigGroup *FindConfigGroupForTypeInfo(const asCTypeInfo *type) const;
asCConfigGroup *FindConfigGroupForFuncDef(const asCFuncdefType *funcDef) const;
int RequestBuild();
void BuildCompleted();
@ -262,7 +255,7 @@ public:
int CreateContext(asIScriptContext **context, bool isInternal);
asCObjectType *GetRegisteredObjectType(const asCString &name, asSNameSpace *ns) const;
asCTypeInfo *GetRegisteredType(const asCString &name, asSNameSpace *ns) const;
asCObjectType *GetListPatternType(int listPatternFuncId);
void DestroyList(asBYTE *buffer, const asCObjectType *listPatternType);
@ -283,29 +276,28 @@ public:
int GetNextScriptFunctionId();
void AddScriptFunction(asCScriptFunction *func);
void RemoveScriptFunction(asCScriptFunction *func);
void RemoveFuncdef(asCScriptFunction *func);
void RemoveFuncdef(asCFuncdefType *func);
int ConfigError(int err, const char *funcName, const char *arg1, const char *arg2);
int GetTypeIdFromDataType(const asCDataType &dt) const;
asCDataType GetDataTypeFromTypeId(int typeId) const;
asCObjectType *GetObjectTypeFromTypeId(int typeId) const;
void RemoveFromTypeIdMap(asCObjectType *type);
void RemoveFromTypeIdMap(asCTypeInfo *type);
bool IsTemplateType(const char *name) const;
int SetTemplateRestrictions(asCObjectType *templateType, asCScriptFunction *func, const char *caller, const char *decl);
asCObjectType *GetTemplateInstanceType(asCObjectType *templateType, asCArray<asCDataType> &subTypes, asCModule *requestingModule);
asCScriptFunction *GenerateTemplateFactoryStub(asCObjectType *templateType, asCObjectType *templateInstanceType, int origFactoryId);
bool GenerateNewTemplateFunction(asCObjectType *templateType, asCObjectType *templateInstanceType, asCScriptFunction *templateFunc, asCScriptFunction **newFunc);
asCFuncdefType *GenerateNewTemplateFuncdef(asCObjectType *templateType, asCObjectType *templateInstanceType, asCFuncdefType *templateFuncdef);
asCDataType DetermineTypeForTemplate(const asCDataType &orig, asCObjectType *tmpl, asCObjectType *ot);
bool RequireTypeReplacement(asCDataType &type, asCObjectType *templateType);
asCModule *FindNewOwnerForSharedType(asCObjectType *type, asCModule *mod);
asCModule *FindNewOwnerForSharedType(asCTypeInfo *type, asCModule *mod);
asCModule *FindNewOwnerForSharedFunc(asCScriptFunction *func, asCModule *mod);
// String constants
// TODO: Must free unused string constants, thus the ref count for each must be tracked
int AddConstantString(const char *str, size_t length);
const asCString &GetConstantString(int id);
asCFuncdefType *FindMatchingFuncdef(asCScriptFunction *func, asCModule *mod);
// Global property management
asCGlobalProperty *AllocateGlobalProperty();
@ -330,24 +322,26 @@ public:
asCObjectType functionBehaviours;
// Registered interface
asCArray<asCObjectType *> registeredObjTypes;
asCArray<asCObjectType *> registeredTypeDefs;
asCArray<asCObjectType *> registeredEnums;
asCSymbolTable<asCGlobalProperty> registeredGlobalProps; // increases ref count // TODO: memory savings: Since there can be only one property with the same name a simpler symbol table should be used
asCArray<asCObjectType *> registeredObjTypes; // doesn't increase ref count
asCArray<asCTypedefType *> registeredTypeDefs; // doesn't increase ref count
asCArray<asCEnumType *> registeredEnums; // doesn't increase ref count
// TODO: memory savings: Since there can be only one property with the same name a simpler symbol table should be used for global props
asCSymbolTable<asCGlobalProperty> registeredGlobalProps; // increases ref count
asCSymbolTable<asCScriptFunction> registeredGlobalFuncs;
asCArray<asCScriptFunction *> registeredFuncDefs;
asCArray<asCObjectType *> registeredTemplateTypes;
asCScriptFunction *stringFactory;
asCArray<asCFuncdefType *> registeredFuncDefs; // doesn't increase ref count
asCArray<asCObjectType *> registeredTemplateTypes; // doesn't increase ref count
asIStringFactory *stringFactory;
asCDataType stringType;
bool configFailed;
// Stores all registered types except funcdefs
asCMap<asSNameSpaceNamePair, asCObjectType*> allRegisteredTypes; // increases ref count
// Stores all registered types
asCMap<asSNameSpaceNamePair, asCTypeInfo*> allRegisteredTypes; // increases ref count
// Dummy types used to name the subtypes in the template objects
asCArray<asCObjectType *> templateSubTypes;
// Dummy types used to name the subtypes in the template objects
asCArray<asCTypeInfo *> templateSubTypes;
// Store information about template types
// This list will contain all instances of templates, both registered specialized
// This list will contain all instances of templates, both registered specialized
// types and those automacially instantiated from scripts
asCArray<asCObjectType *> templateInstanceTypes; // increases ref count
@ -378,7 +372,7 @@ public:
// This array holds all live script modules
asCArray<asCModule *> scriptModules;
// Synchronized with engineRWLock
// This is a pointer to the last module that was requested. It is used for performance
// This is a pointer to the last module that was requested. It is used for performance
// improvement, since it is common that the same module is accessed many times in a row
asCModule *lastModule;
// Synchronized with engineRWLock
@ -389,29 +383,28 @@ public:
// This array holds modules that have been discard (thus are no longer visible to the application)
// but cannot yet be deleted due to having external references to some of the entities in them
asCArray<asCModule *> discardedModules;
// This flag is set to true during compilations of scripts (or loading pre-compiled scripts)
// to delay the validation of template types until the subtypes have been fully declared
// This flag is set to true during compilations of scripts (or loading pre-compiled scripts)
// to delay the validation of template types until the subtypes have been fully declared
bool deferValidationOfTemplateTypes;
// Tokenizer is instantiated once to share resources
asCTokenizer tok;
// Stores shared script declared types (classes, interfaces, enums)
asCArray<asCObjectType *> sharedScriptTypes; // increases ref count
asCArray<asCTypeInfo *> sharedScriptTypes; // increases ref count
// This array stores the template instances types that have been automatically generated from template types
asCArray<asCObjectType *> generatedTemplateTypes;
// Stores the funcdefs
// TODO: redesign: Only shared funcdefs should be stored here
// a funcdef becomes shared if all arguments and the return type are shared (or application registered)
asCArray<asCScriptFunction *> funcDefs; // doesn't increase ref count
asCArray<asCFuncdefType *> funcDefs; // doesn't increases ref count
// Stores the names of the script sections for debugging purposes
asCArray<asCString *> scriptSectionNames;
// Type identifiers
mutable int typeIdSeqNbr;
mutable asCMap<int, asCObjectType*> mapTypeIdToObjectType;
mutable asCMap<int, asCScriptFunction*> mapTypeIdToFunction;
mutable asCMap<int, asCTypeInfo*> mapTypeIdToTypeInfo;
// Garbage collector
asCGarbageCollector gc;
@ -441,16 +434,10 @@ public:
asIJITCompiler *jitCompiler;
// Namespaces
// These are shared between all entities and are
// These are shared between all entities and are
// only deleted once the engine is destroyed
asCArray<asSNameSpace*> nameSpaces;
// String constants
// These are shared between all scripts and are
// only deleted once the engine is destroyed
asCArray<asCString*> stringConstants;
asCMap<asCStringPointer, int> stringToIdMap;
// Callbacks for context pooling
asREQUESTCONTEXTFUNC_t requestCtxFunc;
asRETURNCONTEXTFUNC_t returnCtxFunc;
@ -459,16 +446,16 @@ public:
// User data
asCArray<asPWORD> userData;
struct SEngineClean { asPWORD type; asCLEANENGINEFUNC_t cleanFunc; };
struct SEngineClean { asPWORD type; asCLEANENGINEFUNC_t cleanFunc; };
asCArray<SEngineClean> cleanEngineFuncs;
struct SModuleClean { asPWORD type; asCLEANMODULEFUNC_t cleanFunc; };
struct SModuleClean { asPWORD type; asCLEANMODULEFUNC_t cleanFunc; };
asCArray<SModuleClean> cleanModuleFuncs;
struct SContextClean { asPWORD type; asCLEANCONTEXTFUNC_t cleanFunc; };
struct SContextClean { asPWORD type; asCLEANCONTEXTFUNC_t cleanFunc; };
asCArray<SContextClean> cleanContextFuncs;
struct SFunctionClean { asPWORD type; asCLEANFUNCTIONFUNC_t cleanFunc; };
struct SFunctionClean { asPWORD type; asCLEANFUNCTIONFUNC_t cleanFunc; };
asCArray<SFunctionClean> cleanFunctionFuncs;
struct SObjTypeClean { asPWORD type; asCLEANOBJECTTYPEFUNC_t cleanFunc; };
asCArray<SObjTypeClean> cleanObjectTypeFuncs;
struct STypeInfoClean { asPWORD type; asCLEANTYPEINFOFUNC_t cleanFunc; };
asCArray<STypeInfoClean> cleanTypeInfoFuncs;
struct SScriptObjClean { asPWORD type; asCLEANSCRIPTOBJECTFUNC_t cleanFunc; };
asCArray<SScriptObjClean> cleanScriptObjectFuncs;
@ -504,12 +491,15 @@ public:
bool disallowEmptyListElements;
// TODO: 3.0.0: Remove the privatePropAsProtected
bool privatePropAsProtected;
bool allowUnicodeIdentifiers;
int heredocTrimMode;
asUINT maxNestedCalls;
} ep;
// This flag is to allow a quicker shutdown when releasing the engine
bool shuttingDown;
// This flag is set when the engine's destructor is called, this is to
// This flag is set when the engine's destructor is called, this is to
// avoid recursive calls if an object happens to increment/decrement
// the ref counter during shutdown
bool inDestructor;

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
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
@ -123,7 +123,7 @@ void RegisterScriptFunction(asCScriptEngine *engine)
int r = 0;
UNUSED_VAR(r); // It is only used in debug mode
engine->functionBehaviours.engine = engine;
engine->functionBehaviours.flags = asOBJ_REF | asOBJ_GC | asOBJ_SCRIPT_FUNCTION;
engine->functionBehaviours.flags = asOBJ_REF | asOBJ_GC;
engine->functionBehaviours.name = "$func";
#ifndef AS_MAX_PORTABILITY
r = engine->RegisterBehaviourToObjectType(&engine->functionBehaviours, asBEHAVE_ADDREF, "void f()", asMETHOD(asCScriptFunction,AddRef), asCALL_THISCALL, 0); asASSERT( r >= 0 );
@ -163,7 +163,7 @@ void RegisterScriptFunction(asCScriptEngine *engine)
engine->registeredGlobalFuncs.Put(engine->scriptFunctions[r]);
// Change the return type so the VM will know the function really returns a handle
engine->scriptFunctions[r]->returnType = asCDataType::CreateObject(&engine->functionBehaviours, false);
engine->scriptFunctions[r]->returnType = asCDataType::CreateType(&engine->functionBehaviours, false);
engine->scriptFunctions[r]->returnType.MakeHandle(true);
}
@ -205,6 +205,15 @@ void asCScriptFunction::MakeDelegate(asCScriptFunction *func, void *obj)
dontCleanUpOnException = true;
}
// interface
void *asCScriptFunction::GetAuxiliary() const
{
if (sysFuncIntf)
return sysFuncIntf->auxiliary;
return 0;
}
// interface
void *asCScriptFunction::GetDelegateObject() const
{
@ -212,7 +221,7 @@ void *asCScriptFunction::GetDelegateObject() const
}
// interface
asIObjectType *asCScriptFunction::GetDelegateObjectType() const
asITypeInfo *asCScriptFunction::GetDelegateObjectType() const
{
if( objForDelegate == 0 || funcForDelegate == 0 )
return 0;
@ -297,7 +306,7 @@ int asCScriptFunction::ParseListPattern(asSListPatternNode *&target, const char
asCBuilder builder(engine, 0);
asCScriptCode code;
code.SetCode("", decl, 0, false);
dt = builder.CreateDataTypeFromNode(listNodes, &code, engine->defaultNamespace, false, returnType.GetObjectType());
dt = builder.CreateDataTypeFromNode(listNodes, &code, engine->defaultNamespace, false, CastToObjectType(returnType.GetTypeInfo()));
node->next = asNEW(asSListPatternDataTypeNode)(dt);
node = node->next;
@ -350,11 +359,6 @@ asCScriptFunction::asCScriptFunction(asCScriptEngine *engine, asCModule *mod, as
module = mod;
objectType = 0;
name = "";
isReadOnly = false;
isPrivate = false;
isProtected = false;
isFinal = false;
isOverride = false;
sysFuncIntf = 0;
signatureId = 0;
dontCleanUpOnException = false;
@ -363,11 +367,11 @@ asCScriptFunction::asCScriptFunction(asCScriptEngine *engine, asCModule *mod, as
userData = 0;
id = 0;
accessMask = 0xFFFFFFFF;
isShared = false;
nameSpace = engine->nameSpaces[0];
objForDelegate = 0;
funcForDelegate = 0;
listPattern = 0;
funcdefType = 0;
if( funcType == asFUNC_SCRIPT )
AllocateScriptFunctionData();
@ -552,7 +556,7 @@ int asCScriptFunction::ReleaseInternal()
int asCScriptFunction::GetTypeId() const
{
// This const cast is ok, the object won't be modified
asCDataType dt = asCDataType::CreateFuncDef(const_cast<asCScriptFunction*>(this));
asCDataType dt = asCDataType::CreateType(engine->FindMatchingFuncdef(const_cast<asCScriptFunction*>(this), 0), false);
return engine->GetTypeIdFromDataType(dt);
}
@ -562,10 +566,10 @@ bool asCScriptFunction::IsCompatibleWithTypeId(int typeId) const
asCDataType dt = engine->GetDataTypeFromTypeId(typeId);
// Make sure the type is a function
asCScriptFunction *func = dt.GetFuncDef();
if( func == 0 )
if (!dt.IsFuncdef())
return false;
asCScriptFunction *func = CastToFuncdefType(dt.GetTypeInfo())->funcdef;
if( !IsSignatureExceptNameEqual(func) )
return false;
@ -594,7 +598,7 @@ asIScriptModule *asCScriptFunction::GetModule() const
}
// interface
asIObjectType *asCScriptFunction::GetObjectType() const
asITypeInfo *asCScriptFunction::GetObjectType() const
{
return objectType;
}
@ -617,25 +621,28 @@ const char *asCScriptFunction::GetName() const
// interface
const char *asCScriptFunction::GetNamespace() const
{
return nameSpace->name.AddressOf();
if (nameSpace)
return nameSpace->name.AddressOf();
return 0;
}
// interface
bool asCScriptFunction::IsReadOnly() const
{
return isReadOnly;
return traits.GetTrait(asTRAIT_CONST);
}
// interface
bool asCScriptFunction::IsPrivate() const
{
return isPrivate;
return traits.GetTrait(asTRAIT_PRIVATE);
}
// interface
bool asCScriptFunction::IsProtected() const
{
return isProtected;
return traits.GetTrait(asTRAIT_PROTECTED);
}
// internal
@ -658,8 +665,8 @@ int asCScriptFunction::GetSpaceNeededForReturnValue()
// internal
bool asCScriptFunction::DoesReturnOnStack() const
{
if( returnType.GetObjectType() &&
(returnType.GetObjectType()->flags & asOBJ_VALUE) &&
if( returnType.GetTypeInfo() &&
(returnType.GetTypeInfo()->flags & asOBJ_VALUE) &&
!returnType.IsReference() )
return true;
@ -692,6 +699,16 @@ asCString asCScriptFunction::GetDeclarationStr(bool includeObjectName, bool incl
else
str += "_unnamed_type_::";
}
else if (funcdefType && funcdefType->parentClass && includeObjectName)
{
if (includeNamespace && funcdefType->parentClass->nameSpace->name != "")
str += funcdefType->parentClass->nameSpace->name + "::";
if (funcdefType->parentClass->name != "")
str += funcdefType->parentClass->name + "::";
else
str += "_unnamed_type_::";
}
else if( includeNamespace && nameSpace->name != "" )
{
str += nameSpace->name + "::";
@ -703,7 +720,7 @@ asCString asCScriptFunction::GetDeclarationStr(bool includeObjectName, bool incl
if( name[4] == '0' + asBEHAVE_CONSTRUCT )
str += objectType->name + "(";
else if( name[4] == '0' + asBEHAVE_FACTORY )
str += returnType.GetObjectType()->name + "(";
str += returnType.GetTypeInfo()->name + "(";
else if( name[4] == '0' + asBEHAVE_DESTRUCT )
str += "~" + objectType->name + "(";
else
@ -766,7 +783,7 @@ asCString asCScriptFunction::GetDeclarationStr(bool includeObjectName, bool incl
str += ")";
if( isReadOnly )
if( IsReadOnly() )
str += " const";
// Add the declaration of the list pattern
@ -923,17 +940,17 @@ asUINT asCScriptFunction::GetVarCount() const
}
// interface
int asCScriptFunction::GetVar(asUINT index, const char **name, int *typeId) const
int asCScriptFunction::GetVar(asUINT index, const char **out_name, int *out_typeId) const
{
if( scriptData == 0 )
return asNOT_SUPPORTED;
if( index >= scriptData->variables.GetLength() )
return asINVALID_ARG;
if( name )
*name = scriptData->variables[index]->name.AddressOf();
if( typeId )
*typeId = engine->GetTypeIdFromDataType(scriptData->variables[index]->type);
if( out_name )
*out_name = scriptData->variables[index]->name.AddressOf();
if( out_typeId )
*out_typeId = engine->GetTypeIdFromDataType(scriptData->variables[index]->type);
return asSUCCESS;
}
@ -952,7 +969,7 @@ const char *asCScriptFunction::GetVarDecl(asUINT index, bool includeNamespace) c
}
// internal
void asCScriptFunction::AddVariable(asCString &name, asCDataType &type, int stackOffset)
void asCScriptFunction::AddVariable(asCString &in_name, asCDataType &in_type, int in_stackOffset)
{
asASSERT( scriptData );
asSScriptVariable *var = asNEW(asSScriptVariable);
@ -961,15 +978,15 @@ void asCScriptFunction::AddVariable(asCString &name, asCDataType &type, int stac
// Out of memory
return;
}
var->name = name;
var->type = type;
var->stackOffset = stackOffset;
var->name = in_name;
var->type = in_type;
var->stackOffset = in_stackOffset;
var->declaredAtProgramPos = 0;
scriptData->variables.PushLast(var);
}
// internal
asCObjectType *asCScriptFunction::GetObjectTypeOfLocalVar(short varOffset)
asCTypeInfo *asCScriptFunction::GetTypeInfoOfLocalVar(short varOffset)
{
asASSERT( scriptData );
@ -1015,7 +1032,7 @@ bool asCScriptFunction::IsSignatureEqual(const asCScriptFunction *func) const
// internal
bool asCScriptFunction::IsSignatureExceptNameEqual(const asCScriptFunction *func) const
{
return IsSignatureExceptNameEqual(func->returnType, func->parameterTypes, func->inOutFlags, func->objectType, func->isReadOnly);
return IsSignatureExceptNameEqual(func->returnType, func->parameterTypes, func->inOutFlags, func->objectType, func->IsReadOnly());
}
// internal
@ -1029,19 +1046,19 @@ bool asCScriptFunction::IsSignatureExceptNameEqual(const asCDataType &retType, c
// internal
bool asCScriptFunction::IsSignatureExceptNameAndObjectTypeEqual(const asCScriptFunction *func) const
{
return IsSignatureExceptNameEqual(func->returnType, func->parameterTypes, func->inOutFlags, objectType, isReadOnly);
return IsSignatureExceptNameEqual(func->returnType, func->parameterTypes, func->inOutFlags, objectType, IsReadOnly());
}
// internal
bool asCScriptFunction::IsSignatureExceptNameAndReturnTypeEqual(const asCScriptFunction *func) const
{
return IsSignatureExceptNameAndReturnTypeEqual(func->parameterTypes, func->inOutFlags, func->objectType, func->isReadOnly);
return IsSignatureExceptNameAndReturnTypeEqual(func->parameterTypes, func->inOutFlags, func->objectType, func->IsReadOnly());
}
// internal
bool asCScriptFunction::IsSignatureExceptNameAndReturnTypeEqual(const asCArray<asCDataType> &paramTypes, const asCArray<asETypeModifiers> &paramInOut, const asCObjectType *objType, bool readOnly) const
{
if( this->isReadOnly != readOnly ) return false;
if( this->IsReadOnly() != readOnly ) return false;
if( (this->objectType != 0) != (objType != 0) ) return false;
if( this->inOutFlags != paramInOut ) return false;
if( this->parameterTypes != paramTypes ) return false;
@ -1062,20 +1079,20 @@ void asCScriptFunction::AddReferences()
// Only count references if there is any bytecode
if( scriptData && scriptData->byteCode.GetLength() )
{
if( returnType.GetObjectType() )
if( returnType.GetTypeInfo() )
{
returnType.GetObjectType()->AddRefInternal();
returnType.GetTypeInfo()->AddRefInternal();
asCConfigGroup *group = engine->FindConfigGroupForObjectType(returnType.GetObjectType());
asCConfigGroup *group = engine->FindConfigGroupForTypeInfo(returnType.GetTypeInfo());
if( group != 0 ) group->AddRef();
}
for( asUINT p = 0; p < parameterTypes.GetLength(); p++ )
if( parameterTypes[p].GetObjectType() )
if( parameterTypes[p].GetTypeInfo() )
{
parameterTypes[p].GetObjectType()->AddRefInternal();
parameterTypes[p].GetTypeInfo()->AddRefInternal();
asCConfigGroup *group = engine->FindConfigGroupForObjectType(parameterTypes[p].GetObjectType());
asCConfigGroup *group = engine->FindConfigGroupForTypeInfo(parameterTypes[p].GetTypeInfo());
if( group != 0 ) group->AddRef();
}
@ -1084,7 +1101,7 @@ void asCScriptFunction::AddReferences()
{
scriptData->objVariableTypes[v]->AddRefInternal();
asCConfigGroup *group = engine->FindConfigGroupForObjectType(scriptData->objVariableTypes[v]);
asCConfigGroup *group = engine->FindConfigGroupForTypeInfo(scriptData->objVariableTypes[v]);
if( group != 0 ) group->AddRef();
}
@ -1135,7 +1152,31 @@ void asCScriptFunction::AddReferences()
void *gvarPtr = (void*)asBC_PTRARG(&bc[n]);
if( !gvarPtr ) break;
asCGlobalProperty *prop = GetPropertyByGlobalVarPtr(gvarPtr);
if( !prop ) break;
if (!prop)
{
// The pointer is a string constant. In order to make sure the correct resource
// management is maintained we request a new string constant here, so the compiler
// or bytecode loader can release its copy afterwards.
asCString str;
asUINT length;
int r = engine->stringFactory->GetRawStringData(gvarPtr, 0, &length);
if (r >= 0)
{
str.SetLength(length);
engine->stringFactory->GetRawStringData(gvarPtr, str.AddressOf(), &length);
// Get a new pointer (depending on the string factory implementation it may actually be the same)
gvarPtr = const_cast<void*>(engine->stringFactory->GetStringConstant(str.AddressOf(), length));
asBC_PTRARG(&bc[n]) = (asPWORD)gvarPtr;
}
// If we get an error from the string factory there is not
// anything we can do about it, except report a message.
// TODO: NEWSTRING: Write a message and then exit gracefully
asASSERT(r >= 0);
break;
}
// Only addref the properties once
if( !ptrs.Exists(gvarPtr) )
@ -1195,20 +1236,20 @@ void asCScriptFunction::ReleaseReferences()
// Only count references if there is any bytecode
if( scriptData && scriptData->byteCode.GetLength() )
{
if( returnType.GetObjectType() )
if( returnType.GetTypeInfo() )
{
returnType.GetObjectType()->ReleaseInternal();
returnType.GetTypeInfo()->ReleaseInternal();
asCConfigGroup *group = engine->FindConfigGroupForObjectType(returnType.GetObjectType());
asCConfigGroup *group = engine->FindConfigGroupForTypeInfo(returnType.GetTypeInfo());
if( group != 0 ) group->Release();
}
for( asUINT p = 0; p < parameterTypes.GetLength(); p++ )
if( parameterTypes[p].GetObjectType() )
if( parameterTypes[p].GetTypeInfo() )
{
parameterTypes[p].GetObjectType()->ReleaseInternal();
parameterTypes[p].GetTypeInfo()->ReleaseInternal();
asCConfigGroup *group = engine->FindConfigGroupForObjectType(parameterTypes[p].GetObjectType());
asCConfigGroup *group = engine->FindConfigGroupForTypeInfo(parameterTypes[p].GetTypeInfo());
if( group != 0 ) group->Release();
}
@ -1217,7 +1258,7 @@ void asCScriptFunction::ReleaseReferences()
{
scriptData->objVariableTypes[v]->ReleaseInternal();
asCConfigGroup *group = engine->FindConfigGroupForObjectType(scriptData->objVariableTypes[v]);
asCConfigGroup *group = engine->FindConfigGroupForTypeInfo(scriptData->objVariableTypes[v]);
if( group != 0 ) group->Release();
}
@ -1276,7 +1317,21 @@ void asCScriptFunction::ReleaseReferences()
void *gvarPtr = (void*)asBC_PTRARG(&bc[n]);
if( !gvarPtr ) break;
asCGlobalProperty *prop = GetPropertyByGlobalVarPtr(gvarPtr);
if( !prop ) break;
if (!prop)
{
// The pointer is a string constant, so it needs to be released by the string factory
int r = engine->stringFactory->ReleaseStringConstant(gvarPtr);
UNUSED_VAR(r);
// If we get an error from the string factory there is not
// anything we can do about it, except report a message.
// TODO: Write a message showing that the string couldn't be
// released. Include the first 10 characters and the length
// to make it easier to identify which string it was
asASSERT(r >= 0);
break;
}
// Only release the properties once
if( !ptrs.Exists(gvarPtr) )
@ -1376,57 +1431,40 @@ asUINT asCScriptFunction::GetParamCount() const
}
// interface
int asCScriptFunction::GetParam(asUINT index, int *typeId, asDWORD *flags, const char **name, const char **defaultArg) const
int asCScriptFunction::GetParam(asUINT index, int *out_typeId, asDWORD *out_flags, const char **out_name, const char **out_defaultArg) const
{
if( index >= parameterTypes.GetLength() )
return asINVALID_ARG;
if( typeId )
*typeId = engine->GetTypeIdFromDataType(parameterTypes[index]);
if( out_typeId )
*out_typeId = engine->GetTypeIdFromDataType(parameterTypes[index]);
if( flags )
if( out_flags )
{
*flags = inOutFlags[index];
*flags |= parameterTypes[index].IsReadOnly() ? asTM_CONST : 0;
*out_flags = inOutFlags[index];
*out_flags |= parameterTypes[index].IsReadOnly() ? asTM_CONST : 0;
}
if( name )
if( out_name )
{
// The parameter names are not stored if loading from bytecode without debug information
if( index < parameterNames.GetLength() )
*name = parameterNames[index].AddressOf();
*out_name = parameterNames[index].AddressOf();
else
*name = 0;
*out_name = 0;
}
if( defaultArg )
if( out_defaultArg )
{
if( index < defaultArgs.GetLength() && defaultArgs[index] )
*defaultArg = defaultArgs[index]->AddressOf();
*out_defaultArg = defaultArgs[index]->AddressOf();
else
*defaultArg = 0;
*out_defaultArg = 0;
}
return asSUCCESS;
}
#ifdef AS_DEPRECATED
// Deprecated since 2014-04-06, 2.29.0
int asCScriptFunction::GetParamTypeId(asUINT index, asDWORD *flags) const
{
if( index >= parameterTypes.GetLength() )
return asINVALID_ARG;
if( flags )
{
*flags = inOutFlags[index];
*flags |= parameterTypes[index].IsReadOnly() ? asTM_CONST : 0;
}
return engine->GetTypeIdFromDataType(parameterTypes[index]);
}
#endif
// interface
asIScriptEngine *asCScriptFunction::GetEngine() const
{
@ -1457,7 +1495,7 @@ const char *asCScriptFunction::GetConfigGroup() const
if( funcType != asFUNC_FUNCDEF )
group = engine->FindConfigGroupForFunction(id);
else
group = engine->FindConfigGroupForFuncDef(this);
group = engine->FindConfigGroupForFuncDef(this->funcdefType);
if( group == 0 )
return 0;
@ -1655,20 +1693,23 @@ bool asCScriptFunction::IsShared() const
asASSERT( objectType == 0 || objectType->engine == engine || objectType->engine == 0 );
if( objectType && (objectType->flags & asOBJ_SHARED) ) return true;
// funcdefs that are registered by the application are shared
if (funcType == asFUNC_FUNCDEF && module == 0) return true;
// Functions that have been specifically marked as shared are shared
return isShared;
return traits.GetTrait(asTRAIT_SHARED);
}
// internal
bool asCScriptFunction::IsFinal() const
{
return isFinal;
return traits.GetTrait(asTRAIT_FINAL);
}
// internal
bool asCScriptFunction::IsOverride() const
{
return isOverride;
return traits.GetTrait(asTRAIT_OVERRIDE);
}
END_AS_NAMESPACE

View File

@ -1,24 +1,24 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
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
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
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
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
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
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
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
@ -53,6 +53,7 @@ class asCModule;
class asCConfigGroup;
class asCGlobalProperty;
class asCScriptNode;
class asCFuncdefType;
struct asSNameSpace;
struct asSScriptVariable
@ -96,17 +97,39 @@ enum asEObjVarInfoOption
asBLOCK_END
};
enum asEFuncTrait
{
asTRAIT_CONSTRUCTOR = 1,
asTRAIT_DESTRUCTOR = 2,
asTRAIT_CONST = 4,
asTRAIT_PRIVATE = 8,
asTRAIT_PROTECTED = 16,
asTRAIT_FINAL = 32,
asTRAIT_OVERRIDE = 64,
asTRAIT_SHARED = 128,
asTRAIT_EXTERNAL = 256
};
struct asSFunctionTraits
{
asSFunctionTraits() : traits(0) {}
void SetTrait(asEFuncTrait trait, bool set) { if (set) traits |= trait; else traits &= ~trait; }
bool GetTrait(asEFuncTrait trait) const { return (traits & trait) ? true : false; }
protected:
asDWORD traits;
};
struct asSObjectVariableInfo
{
asUINT programPos;
int variableOffset;
asUINT option;
asUINT programPos;
int variableOffset;
asEObjVarInfoOption option;
};
struct asSSystemFunctionInterface;
// TODO: Might be interesting to allow enumeration of accessed global variables, and
// also functions/methods that are being called. This could be used to build a
// TODO: Might be interesting to allow enumeration of accessed global variables, and
// also functions/methods that are being called. This could be used to build a
// code database with call graphs, etc.
void RegisterScriptFunction(asCScriptEngine *engine);
@ -129,9 +152,10 @@ public:
const char *GetScriptSectionName() const;
const char *GetConfigGroup() const;
asDWORD GetAccessMask() const;
void *GetAuxiliary() const;
// Function signature
asIObjectType *GetObjectType() const;
asITypeInfo *GetObjectType() const;
const char *GetObjectName() const;
const char *GetName() const;
const char *GetNamespace() const;
@ -144,19 +168,15 @@ public:
bool IsShared() const;
asUINT GetParamCount() const;
int GetParam(asUINT index, int *typeId, asDWORD *flags = 0, const char **name = 0, const char **defaultArg = 0) const;
#ifdef AS_DEPRECATED
// Deprecated, since 2.29.0, 2014-04-06
int GetParamTypeId(asUINT index, asDWORD *flags = 0) const;
#endif
int GetReturnTypeId(asDWORD *flags = 0) const;
// Type id for function pointers
// Type id for function pointers
int GetTypeId() const;
bool IsCompatibleWithTypeId(int typeId) const;
// Delegates
void *GetDelegateObject() const;
asIObjectType *GetDelegateObjectType() const;
asITypeInfo *GetDelegateObjectType() const;
asIScriptFunction *GetDelegateFunction() const;
// Debug information
@ -176,10 +196,17 @@ public:
//-----------------------------------
// Internal methods
void SetShared(bool set) {traits.SetTrait(asTRAIT_SHARED, set);}
void SetReadOnly(bool set) { traits.SetTrait(asTRAIT_CONST, set); }
void SetFinal(bool set) { traits.SetTrait(asTRAIT_FINAL, set); }
void SetOverride(bool set) { traits.SetTrait(asTRAIT_OVERRIDE, set); }
void SetProtected(bool set) { traits.SetTrait(asTRAIT_PROTECTED, set); }
void SetPrivate(bool set) { traits.SetTrait(asTRAIT_PRIVATE, set); }
asCScriptFunction(asCScriptEngine *engine, asCModule *mod, asEFuncType funcType);
~asCScriptFunction();
// Keep an internal reference counter to separate references coming from
// Keep an internal reference counter to separate references coming from
// application or script objects and references coming from the script code
int AddRefInternal();
int ReleaseInternal();
@ -210,7 +237,7 @@ public:
bool IsSignatureExceptNameAndReturnTypeEqual(const asCArray<asCDataType> &paramTypes, const asCArray<asETypeModifiers> &inOutFlags, const asCObjectType *type, bool isReadOnly) const;
bool IsSignatureExceptNameAndObjectTypeEqual(const asCScriptFunction *func) const;
asCObjectType *GetObjectTypeOfLocalVar(short varOffset);
asCTypeInfo *GetTypeInfoOfLocalVar(short varOffset);
void MakeDelegate(asCScriptFunction *func, void *obj);
@ -255,11 +282,7 @@ public:
asCArray<asCString> parameterNames;
asCArray<asETypeModifiers> inOutFlags;
asCArray<asCString *> defaultArgs;
bool isReadOnly;
bool isPrivate;
bool isProtected;
bool isFinal;
bool isOverride;
asSFunctionTraits traits;
asCObjectType *objectType;
int signatureId;
@ -267,10 +290,14 @@ public:
asEFuncType funcType;
asDWORD accessMask;
bool isShared;
// Namespace will be null for funcdefs that are declared as child funcdefs
// of a class. In this case the namespace shall be taken from the parentClass
// in the funcdefType
asSNameSpace *nameSpace;
asCFuncdefType *funcdefType; // Doesn't increase refCount
// Used by asFUNC_DELEGATE
void *objForDelegate;
asCScriptFunction *funcForDelegate;
@ -289,8 +316,7 @@ public:
// These hold information on objects and function pointers, including temporary
// variables used by exception handler and when saving bytecode
asCArray<asCObjectType*> objVariableTypes;
asCArray<asCScriptFunction*> funcVariableTypes;
asCArray<asCTypeInfo*> objVariableTypes;
asCArray<int> objVariablePos;
// The first variables in above array are allocated on the heap, the rest on the stack.

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2012 Andreas Jonsson
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
@ -60,13 +60,13 @@ void asCScriptNode::Destroy(asCScriptEngine *engine)
{
// Destroy all children
asCScriptNode *node = firstChild;
asCScriptNode *next;
asCScriptNode *nxt;
while( node )
{
next = node->next;
nxt = node->next;
node->Destroy(engine);
node = next;
node = nxt;
}
// Return the memory to the memory manager

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2014 Andreas Jonsson
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
@ -89,7 +89,8 @@ enum eScriptNode
snNamespace,
snMixin,
snListPattern,
snNamedArgument
snNamedArgument,
snScope
};
struct sToken

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
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
@ -271,13 +271,13 @@ asCScriptObject::asCScriptObject(asCObjectType *ot, bool doInitialize)
asCObjectProperty *prop = objType->properties[n];
if( prop->type.IsObject() && !prop->type.IsObjectHandle() )
{
if( prop->type.IsReference() || prop->type.GetObjectType()->flags & asOBJ_REF )
if( prop->type.IsReference() || prop->type.GetTypeInfo()->flags & asOBJ_REF )
{
asPWORD *ptr = reinterpret_cast<asPWORD*>(reinterpret_cast<asBYTE*>(this) + prop->byteOffset);
if( prop->type.GetObjectType()->flags & asOBJ_SCRIPT_OBJECT )
*ptr = (asPWORD)ScriptObjectFactory(prop->type.GetObjectType(), ot->engine);
if( prop->type.GetTypeInfo()->flags & asOBJ_SCRIPT_OBJECT )
*ptr = (asPWORD)ScriptObjectFactory(prop->type.GetTypeInfo(), ot->engine);
else
*ptr = (asPWORD)AllocateUninitializedObject(prop->type.GetObjectType(), ot->engine);
*ptr = (asPWORD)AllocateUninitializedObject(prop->type.GetTypeInfo(), ot->engine);
}
}
}
@ -292,10 +292,10 @@ asCScriptObject::asCScriptObject(asCObjectType *ot, bool doInitialize)
asCObjectProperty *prop = objType->properties[n];
if( prop->type.IsObject() && !prop->type.IsObjectHandle() )
{
if( prop->type.IsReference() || (prop->type.GetObjectType()->flags & asOBJ_REF) )
if( prop->type.IsReference() || (prop->type.GetTypeInfo()->flags & asOBJ_REF) )
{
asPWORD *ptr = reinterpret_cast<asPWORD*>(reinterpret_cast<asBYTE*>(this) + prop->byteOffset);
*ptr = (asPWORD)AllocateUninitializedObject(prop->type.GetObjectType(), engine);
*ptr = (asPWORD)AllocateUninitializedObject(CastToObjectType(prop->type.GetTypeInfo()), engine);
}
}
}
@ -359,7 +359,7 @@ asCScriptObject::~asCScriptObject()
if( prop->type.IsObject() )
{
// Destroy the object
asCObjectType *propType = prop->type.GetObjectType();
asCObjectType *propType = CastToObjectType(prop->type.GetTypeInfo());
if( prop->type.IsReference() || propType->flags & asOBJ_REF )
{
void **ptr = (void**)(((char*)this) + prop->byteOffset);
@ -381,6 +381,16 @@ asCScriptObject::~asCScriptObject()
engine->CallObjectMethod(ptr, propType->beh.destruct);
}
}
else if( prop->type.IsFuncdef() )
{
// Release the function descriptor
asCScriptFunction **ptr = (asCScriptFunction**)(((char*)this) + prop->byteOffset);
if (*ptr)
{
(*ptr)->Release();
*ptr = 0;
}
}
}
objType->Release();
@ -647,7 +657,7 @@ void asCScriptObject::CallDestructor()
}
}
asIObjectType *asCScriptObject::GetObjectType() const
asITypeInfo *asCScriptObject::GetObjectType() const
{
return objType;
}
@ -670,7 +680,7 @@ bool asCScriptObject::GetFlag()
// interface
int asCScriptObject::GetTypeId() const
{
asCDataType dt = asCDataType::CreateObject(objType, false);
asCDataType dt = asCDataType::CreateType(objType, false);
return objType->engine->GetTypeIdFromDataType(dt);
}
@ -703,7 +713,7 @@ void *asCScriptObject::GetAddressOfProperty(asUINT prop)
// Objects are stored by reference, so this must be dereferenced
asCDataType *dt = &objType->properties[prop]->type;
if( dt->IsObject() && !dt->IsObjectHandle() &&
(dt->IsReference() || dt->GetObjectType()->flags & asOBJ_REF) )
(dt->IsReference() || dt->GetTypeInfo()->flags & asOBJ_REF) )
return *(void**)(((char*)this) + objType->properties[prop]->byteOffset);
return (void*)(((char*)this) + objType->properties[prop]->byteOffset);
@ -715,19 +725,21 @@ void asCScriptObject::EnumReferences(asIScriptEngine *engine)
for( asUINT n = 0; n < objType->properties.GetLength(); n++ )
{
asCObjectProperty *prop = objType->properties[n];
void *ptr = 0;
if( prop->type.IsObject() )
{
// TODO: gc: The members of the value type needs to be enumerated
// too, since the value type may be holding a reference.
void *ptr;
if( prop->type.IsReference() || (prop->type.GetObjectType()->flags & asOBJ_REF) )
if( prop->type.IsReference() || (prop->type.GetTypeInfo()->flags & asOBJ_REF) )
ptr = *(void**)(((char*)this) + prop->byteOffset);
else
ptr = (void*)(((char*)this) + prop->byteOffset);
if( ptr )
((asCScriptEngine*)engine)->GCEnumCallback(ptr);
}
else if (prop->type.IsFuncdef())
ptr = *(void**)(((char*)this) + prop->byteOffset);
if (ptr)
((asCScriptEngine*)engine)->GCEnumCallback(ptr);
}
}
@ -745,12 +757,21 @@ void asCScriptObject::ReleaseAllHandles(asIScriptEngine *engine)
void **ptr = (void**)(((char*)this) + prop->byteOffset);
if( *ptr )
{
asASSERT( (prop->type.GetObjectType()->flags & asOBJ_NOCOUNT) || prop->type.GetBehaviour()->release );
asASSERT( (prop->type.GetTypeInfo()->flags & asOBJ_NOCOUNT) || prop->type.GetBehaviour()->release );
if( prop->type.GetBehaviour()->release )
((asCScriptEngine*)engine)->CallObjectMethod(*ptr, prop->type.GetBehaviour()->release);
*ptr = 0;
}
}
else if (prop->type.IsFuncdef())
{
asCScriptFunction **ptr = (asCScriptFunction**)(((char*)this) + prop->byteOffset);
if (*ptr)
{
(*ptr)->Release();
*ptr = 0;
}
}
}
}
@ -787,13 +808,23 @@ asCScriptObject &asCScriptObject::operator=(const asCScriptObject &other)
void **src = (void**)(((char*)&other) + prop->byteOffset);
if( !prop->type.IsObjectHandle() )
{
if( prop->type.IsReference() || (prop->type.GetObjectType()->flags & asOBJ_REF) )
CopyObject(*src, *dst, prop->type.GetObjectType(), engine);
if( prop->type.IsReference() || (prop->type.GetTypeInfo()->flags & asOBJ_REF) )
CopyObject(*src, *dst, CastToObjectType(prop->type.GetTypeInfo()), engine);
else
CopyObject(src, dst, prop->type.GetObjectType(), engine);
CopyObject(src, dst, CastToObjectType(prop->type.GetTypeInfo()), engine);
}
else
CopyHandle((asPWORD*)src, (asPWORD*)dst, prop->type.GetObjectType(), engine);
CopyHandle((asPWORD*)src, (asPWORD*)dst, CastToObjectType(prop->type.GetTypeInfo()), engine);
}
else if (prop->type.IsFuncdef())
{
asCScriptFunction **dst = (asCScriptFunction**)(((char*)this) + prop->byteOffset);
asCScriptFunction **src = (asCScriptFunction**)(((char*)&other) + prop->byteOffset);
if (*dst)
(*dst)->Release();
*dst = *src;
if (*dst)
(*dst)->AddRef();
}
else
{
@ -905,29 +936,29 @@ int asCScriptObject::CopyFrom(asIScriptObject *other)
return 0;
}
void *asCScriptObject::AllocateUninitializedObject(asCObjectType *objType, asCScriptEngine *engine)
void *asCScriptObject::AllocateUninitializedObject(asCObjectType *in_objType, asCScriptEngine *engine)
{
void *ptr = 0;
if( objType->flags & asOBJ_SCRIPT_OBJECT )
if( in_objType->flags & asOBJ_SCRIPT_OBJECT )
{
ptr = engine->CallAlloc(objType);
ScriptObject_ConstructUnitialized(objType, reinterpret_cast<asCScriptObject*>(ptr));
ptr = engine->CallAlloc(in_objType);
ScriptObject_ConstructUnitialized(in_objType, reinterpret_cast<asCScriptObject*>(ptr));
}
else if( objType->flags & asOBJ_TEMPLATE )
else if( in_objType->flags & asOBJ_TEMPLATE )
{
// Templates store the original factory that takes the object
// type as a hidden parameter in the construct behaviour
ptr = engine->CallGlobalFunctionRetPtr(objType->beh.construct, objType);
ptr = engine->CallGlobalFunctionRetPtr(in_objType->beh.construct, in_objType);
}
else if( objType->flags & asOBJ_REF )
else if( in_objType->flags & asOBJ_REF )
{
ptr = engine->CallGlobalFunctionRetPtr(objType->beh.factory);
ptr = engine->CallGlobalFunctionRetPtr(in_objType->beh.factory);
}
else
{
ptr = engine->CallAlloc(objType);
int funcIndex = objType->beh.construct;
ptr = engine->CallAlloc(in_objType);
int funcIndex = in_objType->beh.construct;
if( funcIndex )
engine->CallObjectMethod(ptr, funcIndex);
}
@ -935,52 +966,52 @@ void *asCScriptObject::AllocateUninitializedObject(asCObjectType *objType, asCSc
return ptr;
}
void asCScriptObject::FreeObject(void *ptr, asCObjectType *objType, asCScriptEngine *engine)
void asCScriptObject::FreeObject(void *ptr, asCObjectType *in_objType, asCScriptEngine *engine)
{
if( objType->flags & asOBJ_REF )
if( in_objType->flags & asOBJ_REF )
{
asASSERT( (objType->flags & asOBJ_NOCOUNT) || objType->beh.release );
if( objType->beh.release )
engine->CallObjectMethod(ptr, objType->beh.release);
asASSERT( (in_objType->flags & asOBJ_NOCOUNT) || in_objType->beh.release );
if(in_objType->beh.release )
engine->CallObjectMethod(ptr, in_objType->beh.release);
}
else
{
if( objType->beh.destruct )
engine->CallObjectMethod(ptr, objType->beh.destruct);
if( in_objType->beh.destruct )
engine->CallObjectMethod(ptr, in_objType->beh.destruct);
engine->CallFree(ptr);
}
}
void asCScriptObject::CopyObject(void *src, void *dst, asCObjectType *objType, asCScriptEngine *engine)
void asCScriptObject::CopyObject(void *src, void *dst, asCObjectType *in_objType, asCScriptEngine *engine)
{
int funcIndex = objType->beh.copy;
int funcIndex = in_objType->beh.copy;
if( funcIndex )
{
asCScriptFunction *func = engine->scriptFunctions[objType->beh.copy];
asCScriptFunction *func = engine->scriptFunctions[in_objType->beh.copy];
if( func->funcType == asFUNC_SYSTEM )
engine->CallObjectMethod(dst, src, funcIndex);
else
{
// Call the script class' opAssign method
asASSERT( objType->flags & asOBJ_SCRIPT_OBJECT );
asASSERT(in_objType->flags & asOBJ_SCRIPT_OBJECT );
reinterpret_cast<asCScriptObject*>(dst)->CopyFrom(reinterpret_cast<asCScriptObject*>(src));
}
}
else if( objType->size && (objType->flags & asOBJ_POD) )
memcpy(dst, src, objType->size);
else if( in_objType->size && (in_objType->flags & asOBJ_POD) )
memcpy(dst, src, in_objType->size);
}
void asCScriptObject::CopyHandle(asPWORD *src, asPWORD *dst, asCObjectType *objType, asCScriptEngine *engine)
void asCScriptObject::CopyHandle(asPWORD *src, asPWORD *dst, asCObjectType *in_objType, asCScriptEngine *engine)
{
// asOBJ_NOCOUNT doesn't have addref or release behaviours
asASSERT( (objType->flags & asOBJ_NOCOUNT) || (objType->beh.release && objType->beh.addref) );
asASSERT( (in_objType->flags & asOBJ_NOCOUNT) || (in_objType->beh.release && in_objType->beh.addref) );
if( *dst && objType->beh.release )
engine->CallObjectMethod(*(void**)dst, objType->beh.release);
if( *dst && in_objType->beh.release )
engine->CallObjectMethod(*(void**)dst, in_objType->beh.release);
*dst = *src;
if( *dst && objType->beh.addref )
engine->CallObjectMethod(*(void**)dst, objType->beh.addref);
if( *dst && in_objType->beh.addref )
engine->CallObjectMethod(*(void**)dst, in_objType->beh.addref);
}
// TODO: weak: Should move to its own file

View File

@ -1,24 +1,24 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2015 Andreas Jonsson
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
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
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
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
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
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
3. This notice may not be removed or altered from any source
distribution.
The original version of this library can be located at:
@ -60,14 +60,14 @@ public:
bool Get() const;
void Set(bool);
void Lock() const;
void Unlock() const;
protected:
mutable asCAtomic refCount;
bool value;
DECLARECRITICALSECTION(mutable lock);
DECLARECRITICALSECTION(mutable lock)
};
class asCScriptObject : public asIScriptObject
@ -84,7 +84,7 @@ public:
// Type info
int GetTypeId() const;
asIObjectType *GetObjectType() const;
asITypeInfo *GetObjectType() const;
// Class properties
asUINT GetPropertyCount() const;
@ -137,7 +137,7 @@ protected:
bool isDestructCalled;
// Most script classes instances won't have neither the weakRefFlags nor
// userData so we only allocate this if requested. Even when used it is
// userData so we only allocate this if requested. Even when used it is
// not something that will be accessed all the time so having the extra
// indirection will not affect the performance significantly.
struct SExtra

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2014 Andreas Jonsson
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
@ -283,20 +283,24 @@ size_t asCString::Format(const char *format, ...)
va_list args;
va_start(args, format);
char tmp[256];
int r = asVSNPRINTF(tmp, 255, format, args);
const size_t startSize = 1024;
char tmp[startSize];
int r = asVSNPRINTF(tmp, startSize-1, format, args);
if( r > 0 )
if( r > 0 && r < int(startSize) )
{
Assign(tmp, r);
}
else
{
size_t n = 512;
// TODO: For some reason this doesn't work properly on Linux. Perhaps the
// problem is related to vsnprintf not keeping the state of va_arg.
// Perhaps I need to rewrite this in some way to keep the state
size_t n = startSize*2;
asCString str; // Use temporary string in case the current buffer is a parameter
str.Allocate(n, false);
while( (r = asVSNPRINTF(str.AddressOf(), n, format, args)) < 0 )
while( (r = asVSNPRINTF(str.AddressOf(), n, format, args)) < 0 || r >= int(n) )
{
n *= 2;
str.Allocate(n, false);
@ -324,15 +328,15 @@ const char &asCString::operator [](size_t index) const
return AddressOf()[index];
}
asCString asCString::SubString(size_t start, size_t length) const
asCString asCString::SubString(size_t in_start, size_t in_length) const
{
if( start >= GetLength() || length == 0 )
if( in_start >= GetLength() || in_length == 0 )
return asCString("");
if( length == (size_t)(-1) ) length = GetLength() - start;
if( in_length == (size_t)(-1) ) in_length = GetLength() - in_start;
asCString tmp;
tmp.Assign(AddressOf() + start, length);
tmp.Assign(AddressOf() + in_start, in_length);
return tmp;
}

View File

@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2013 Andreas Jonsson
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
@ -171,17 +171,24 @@ static int asCharToNbr(char ch, int radix)
}
// If base is 0 the string should be prefixed by 0x, 0d, 0o, or 0b to allow the function to automatically determine the radix
asQWORD asStringScanUInt64(const char *string, int base, size_t *numScanned)
asQWORD asStringScanUInt64(const char *string, int base, size_t *numScanned, bool *overflow)
{
asASSERT(base == 10 || base == 16 || base == 0);
if (overflow)
*overflow = false;
const char *end = string;
static const asQWORD QWORD_MAX = (~asQWORD(0));
asQWORD res = 0;
if( base == 10 )
{
while( *end >= '0' && *end <= '9' )
{
if( overflow && ((res > QWORD_MAX / 10) || ((asUINT(*end - '0') > (QWORD_MAX - (QWORD_MAX / 10) * 10)) && res == QWORD_MAX / 10)) )
*overflow = true;
res *= 10;
res += *end++ - '0';
}
@ -205,8 +212,13 @@ asQWORD asStringScanUInt64(const char *string, int base, size_t *numScanned)
if( base )
{
for( int nbr; (nbr = asCharToNbr(*end, base)) >= 0; end++ )
for (int nbr; (nbr = asCharToNbr(*end, base)) >= 0; end++)
{
if (overflow && ((res > QWORD_MAX / base) || ((asUINT(nbr) > (QWORD_MAX - (QWORD_MAX / base) * base)) && res == QWORD_MAX / base)) )
*overflow = true;
res = res * base + nbr;
}
}
}

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