Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ef1b65eba | ||
|
|
4d10a680c1 | ||
|
|
b8e4aa589d | ||
|
|
4070933364 | ||
|
|
be81a7fd11 | ||
|
|
64adbb4238 | ||
|
|
74f19f0cbc | ||
|
|
0fdc7a2d98 | ||
|
|
ae18901bb2 | ||
|
|
b73469caf1 | ||
|
|
9119f5f291 | ||
|
|
90cf3176d1 | ||
|
|
789384a7bf | ||
|
|
8119b59af0 | ||
|
|
403d61e754 | ||
|
|
b3cc5f9f0d | ||
|
|
01b9ee2a63 | ||
|
|
fa027c11da | ||
|
|
db55c35ed1 | ||
|
|
97100db507 | ||
|
|
f651321ceb | ||
|
|
edbb6892e0 | ||
|
|
e35d5a07b4 | ||
|
|
da6133d72e | ||
|
|
b32fff8dad | ||
|
|
d95bdc2ea9 | ||
|
|
09227fa19d | ||
|
|
860135376d | ||
|
|
0162407ff3 | ||
|
|
32edaa25fe | ||
|
|
cb510840ae | ||
|
|
41002fc262 | ||
|
|
238578c921 | ||
|
|
9531f0b3a4 | ||
|
|
bd006c875e | ||
|
|
9a1cba3ac8 | ||
|
|
9094cbd31a | ||
|
|
f59d277f3e | ||
|
|
d4f3fc88d6 | ||
|
|
2cf4341916 | ||
|
|
1dabb39ed4 | ||
|
|
8fd0b9186a | ||
|
|
0f5a44ea1f | ||
|
|
cfbec1f470 | ||
|
|
a51d56a6e5 | ||
|
|
b3d97241d7 | ||
|
|
501dd14bb6 | ||
|
|
9b2994c975 | ||
|
|
2f287fbee6 | ||
|
|
8ef16c146e | ||
|
|
51fb693455 | ||
|
|
642216da83 | ||
|
|
e5a7f27f19 | ||
|
|
48235a5d77 | ||
|
|
40ea7f94f0 | ||
|
|
1ada542fa5 | ||
|
|
4c02204eff | ||
|
|
855c59db09 | ||
|
|
0b2c44ed71 | ||
|
|
5ba3dee122 | ||
|
|
ced9e55639 | ||
|
|
cbd5670764 | ||
|
|
0a3daf9484 | ||
|
|
17cfc130d0 | ||
|
|
e4f29d4dea | ||
|
|
30fa3345e4 | ||
|
|
0f8d36889f | ||
|
|
813d80a792 | ||
|
|
c21f6abeb7 | ||
|
|
8577f0d185 | ||
|
|
9048b6ffcd | ||
|
|
cc9163ca77 | ||
|
|
722cd0e181 | ||
|
|
3a64d2c70e | ||
|
|
d2a7e21632 | ||
|
|
18179bd18d | ||
|
|
2c68bd194c | ||
|
|
6f84a4dca1 | ||
|
|
959d17ccb5 | ||
|
|
abbd54ffa0 | ||
|
|
4d6a9726b6 | ||
|
|
dc8361b941 | ||
|
|
8113ea128b | ||
|
|
101fcf5df7 | ||
|
|
e9c2f0ecf1 | ||
|
|
d437ffa3bf | ||
|
|
8e6d9d2f41 | ||
|
|
dec62d63ea | ||
|
|
063fb6b65f | ||
|
|
4ef85d692c | ||
|
|
e241f167a7 | ||
|
|
d64428db34 | ||
|
|
e0b1e876f0 | ||
|
|
ab4f77e80e | ||
|
|
0c2e6c1640 | ||
|
|
553a0a8b58 | ||
|
|
52017e31ea | ||
|
|
a401096487 | ||
|
|
e94c3e5d3f | ||
|
|
6d8d78be73 | ||
|
|
2224f4ebfa | ||
|
|
283a7c58b9 | ||
|
|
b40f84e89d | ||
|
|
7005f3b069 | ||
|
|
65c25065ee | ||
|
|
8e4ee298e0 | ||
|
|
2b36759ba3 | ||
|
|
6def0c752c | ||
|
|
90d7fac6c4 | ||
|
|
e290e9003d | ||
|
|
db4c6f4799 | ||
|
|
080936f144 | ||
|
|
78220d5ed7 | ||
|
|
3cb0c6f4c2 | ||
|
|
37d787ff38 | ||
|
|
a50d11df36 | ||
|
|
f0f230b042 | ||
|
|
1a09a09dd9 | ||
|
|
e0ef910137 | ||
|
|
329a4ac047 | ||
|
|
e23f854845 | ||
|
|
dc211f2000 | ||
|
|
488f506932 | ||
|
|
f0d0e7e601 | ||
|
|
0ca0b21327 | ||
|
|
dd80daa5d9 | ||
|
|
3b682ff084 | ||
|
|
7d66dfec0e | ||
|
|
56bc14ff31 | ||
|
|
0ea991adee | ||
|
|
ea69eb3178 | ||
|
|
26d63ce844 | ||
|
|
6106ed3ec6 | ||
|
|
465130a4a2 | ||
|
|
827b9adce2 | ||
|
|
320dd6d1df | ||
|
|
fbad97a4a7 | ||
|
|
6ccebd09b6 | ||
|
|
ee26611759 | ||
|
|
f4cf41e466 | ||
|
|
c48037984d | ||
|
|
ac3984b403 | ||
|
|
e337b72789 | ||
|
|
77bfa84609 | ||
|
|
f269b44208 | ||
|
|
a29fa5c4a3 | ||
|
|
f3f30a8057 | ||
|
|
400f9c612b | ||
|
|
78f9500b1d | ||
|
|
93f24f2a74 | ||
|
|
199cda80b1 | ||
|
|
824b6906c1 | ||
|
|
7453853c6d | ||
|
|
ba957ca0dc | ||
|
|
3607cadf62 | ||
|
|
310a58541d | ||
|
|
a16bbf71a4 | ||
|
|
5070531ad7 | ||
|
|
38a1deeff5 | ||
|
|
b441dba764 | ||
|
|
4338fe6144 | ||
|
|
43add89cc2 | ||
|
|
8b9e5acd1a | ||
|
|
a311281aa7 | ||
|
|
08ea768e16 | ||
|
|
a6b8783d46 | ||
|
|
dfe4f09ed5 | ||
|
|
f019f8622c | ||
|
|
0ace0aeb5b | ||
|
|
6082a4502b | ||
|
|
eea9069265 | ||
|
|
d98c1044e6 | ||
|
|
1559d03ea1 | ||
|
|
585d1c5016 | ||
|
|
85cf5b181e | ||
|
|
d32a76cd16 | ||
|
|
c91f9655d8 | ||
|
|
75b24c96ad | ||
|
|
aaf20dc919 | ||
|
|
0b7c03b34c | ||
|
|
38e4e4e03c | ||
|
|
dfcaf44058 | ||
|
|
eacd599b93 | ||
|
|
b14acf2a67 | ||
|
|
d19112760f | ||
|
|
5462a62c75 | ||
|
|
af88b4a16f | ||
|
|
0b9876c53e | ||
|
|
fae12f3714 | ||
|
|
56aecdb692 | ||
|
|
6e0b96c21f | ||
|
|
e1ef2aa305 | ||
|
|
f97db81ce3 | ||
|
|
e769f995ec | ||
|
|
a4559fc09d | ||
|
|
9f883db6f7 | ||
|
|
fc942433e2 | ||
|
|
30431adc69 | ||
|
|
45d6c863b3 | ||
|
|
118233fb24 | ||
|
|
865760ffa4 | ||
|
|
819156106d | ||
|
|
5d098488e6 | ||
|
|
1cc3a0f0b8 | ||
|
|
bbaf061ae9 | ||
|
|
1a96ed6249 | ||
|
|
1a395efbfd | ||
|
|
76270ce0ec | ||
|
|
adceb35812 | ||
|
|
a51225ec36 | ||
|
|
262fc0c373 | ||
|
|
959c86d816 | ||
|
|
b6a10b7603 | ||
|
|
63406b40f1 | ||
|
|
55079289da | ||
|
|
50ff2e6e35 | ||
|
|
513df96c53 | ||
|
|
543bb8d303 | ||
|
|
52f77f7d43 | ||
|
|
fbac4d791c | ||
|
|
4ea1145af1 | ||
|
|
00782180f7 | ||
|
|
418ccf284e | ||
|
|
4b956ebfce | ||
|
|
ad2ca0f394 | ||
|
|
d4c33b294d | ||
|
|
50acbea315 | ||
|
|
e8b8bbdd3b | ||
|
|
8f090525fb | ||
|
|
fb9d422f9b | ||
|
|
ecdf32c01e | ||
|
|
0627bd85f3 | ||
|
|
2c44bd1201 | ||
|
|
a4264cc063 | ||
|
|
cdde932908 | ||
|
|
9a905cb579 | ||
|
|
effe131e4a | ||
|
|
66dd089902 | ||
|
|
dffd431f3c | ||
|
|
a4536d7752 | ||
|
|
66db970564 | ||
|
|
d746ea8aa1 | ||
|
|
67d5e41d2c | ||
|
|
ddcd6f9ca3 | ||
|
|
fb58e4b3b3 | ||
|
|
4135ed4be2 | ||
|
|
3f76b0c68d | ||
|
|
6af71fe582 | ||
|
|
d8a918758d | ||
|
|
cbd45c26a2 | ||
|
|
4b735861cd | ||
|
|
09a70b8aac | ||
|
|
414522e823 | ||
|
|
5e56f8904a | ||
|
|
c7e785b59c | ||
|
|
cd67daf4a3 | ||
|
|
9cb862f708 | ||
|
|
8d07d26c25 | ||
|
|
bcd9654a86 | ||
|
|
2d2624f71c | ||
|
|
3a6fd75f10 | ||
|
|
c579eba6db | ||
|
|
1971254a7f | ||
|
|
c08b898742 | ||
|
|
e1eec44d1a | ||
|
|
dda3bb0f31 | ||
|
|
cedb7e7123 |
+12
-5
@@ -1,6 +1,6 @@
|
||||
# root CMakeLists for the SuperTuxKart project
|
||||
project(SuperTuxKart)
|
||||
set(PROJECT_VERSION "0.9")
|
||||
set(PROJECT_VERSION "0.8.1")
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.4)
|
||||
if(NOT (CMAKE_MAJOR_VERSION VERSION_LESS 3))
|
||||
@@ -18,6 +18,7 @@ endif()
|
||||
option(USE_WIIUSE "Support for wiimote input devices" ON)
|
||||
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)
|
||||
|
||||
if(MSVC)
|
||||
# Normally hide the option to build wiiuse on VS, since it depends
|
||||
@@ -121,9 +122,15 @@ elseif(MSVC)
|
||||
endif()
|
||||
|
||||
|
||||
# Build the angelscript library
|
||||
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/angelscript/projects/cmake")
|
||||
include_directories("${PROJECT_SOURCE_DIR}/lib/angelscript/include")
|
||||
# Build the angelscript library if not in system
|
||||
find_package(Angelscript)
|
||||
if(USE_SYSTEM_ANGELSCRIPT AND ANGELSCRIPT_FOUND)
|
||||
include_directories(${Angelscript_INCLUDE_DIRS})
|
||||
else()
|
||||
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/angelscript/projects/cmake")
|
||||
include_directories("${PROJECT_SOURCE_DIR}/lib/angelscript/include")
|
||||
set(Angelscript_LIBRARIES angelscript)
|
||||
endif()
|
||||
|
||||
# OpenAL
|
||||
if(APPLE)
|
||||
@@ -310,7 +317,7 @@ target_link_libraries(supertuxkart
|
||||
enet
|
||||
glew
|
||||
stkirrlicht
|
||||
angelscript
|
||||
${Angelscript_LIBRARIES}
|
||||
${CURL_LIBRARIES}
|
||||
${OGGVORBIS_LIBRARIES}
|
||||
${OPENAL_LIBRARY}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
# - Try to find angelscript
|
||||
# Once done this will define
|
||||
#
|
||||
# ANGELSCRIPT_FOUND - system has angelscript
|
||||
# Angelscript_INCLUDE_DIRS - the angelscript include directory
|
||||
# Angelscript_LIBRARIES - the libraries needed to use angelscript
|
||||
#
|
||||
|
||||
FIND_PATH(Angelscript_INCLUDE_DIRS angelscript.h
|
||||
PATHS
|
||||
/usr/local
|
||||
/usr
|
||||
PATH_SUFFIXES include
|
||||
)
|
||||
|
||||
FIND_LIBRARY(Angelscript_LIBRARY
|
||||
NAMES angelscript
|
||||
PATHS
|
||||
/usr/local
|
||||
/usr
|
||||
PATH_SUFFIXES lib
|
||||
)
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set ANGELSCRIPT_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Angelscript DEFAULT_MSG Angelscript_LIBRARY Angelscript_INCLUDE_DIRS)
|
||||
|
||||
IF (ANGELSCRIPT_FOUND)
|
||||
SET(Angelscript_LIBRARIES ${Angelscript_LIBRARY})
|
||||
ENDIF (ANGELSCRIPT_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(Angelscript_LIBRARY Angelscript_LIBRARIES Angelscript_INCLUDE_DIRS)
|
||||
Binary file not shown.
@@ -17,11 +17,11 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.9</string>
|
||||
<string>0.8.1</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>SPTK</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.9</string>
|
||||
<string>0.8.1</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
<skidding goal="5"/>
|
||||
</achievement>
|
||||
<achievement id="6" check-type="all-at-least" reset-type="never"
|
||||
name="Gold driver" description="Win in all single player modes, against at least 3 opponents.">
|
||||
name="Gold driver" description="Win against at least 3 opponents in all single player modes.">
|
||||
<standard goal="1"/>
|
||||
<std_timetrial goal="1"/>
|
||||
<follow_leader goal="1"/>
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
</hard>
|
||||
<medium>
|
||||
<karts number="4"/>
|
||||
<requirements time="175"/>
|
||||
<requirements time="185"/>
|
||||
</medium>
|
||||
<easy>
|
||||
<karts number="4"/>
|
||||
<requirements time="225"/>
|
||||
<requirements time="270"/>
|
||||
</easy>
|
||||
</challenge>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 161 KiB After Width: | Height: | Size: 154 KiB |
@@ -17,6 +17,9 @@
|
||||
<card contains="Gallium" os="linux" version="<10.3" disable="DriverRecentEnough"/>
|
||||
<card contains="Gallium" os="linux" version="<10.6" disable="GeometryShader4"/>
|
||||
<card contains="Gallium" os="linux" disable="TextureCompressionS3TC"/>
|
||||
<card contains="Radeon" version="<14.300" disable="DriverRecentEnough"/>
|
||||
<!-- On osx radeon appears to have different version numbers, e.g.
|
||||
1.32.20 -->
|
||||
<card contains="Radeon" os="linux" version="<14.300" disable="DriverRecentEnough"/>
|
||||
<card contains="Radeon" os="windows" version="<14.300" disable="DriverRecentEnough"/>
|
||||
</graphical-restrictions>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
<div x="5%" y="2%" width="90%" height="96%" layout="vertical-row" >
|
||||
|
||||
<header I18N="Title for challenges screen" text="Challenges : Trophy Room" text_align="center" align="center" width="80%" />
|
||||
<header I18N="Title for challenges screen" text="Challenges - Trophy Room" text_align="center" align="center" width="80%" />
|
||||
|
||||
<spacer height="5" width="100%"/>
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -7,7 +7,7 @@
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<box id="info" proportion="2" height="100%" layout="vertical-row">
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" text_align="left" I18N="In the networking lobby" text="Server name :"/>
|
||||
<label proportion="1" text_align="left" I18N="In the networking lobby" text="Server name:"/>
|
||||
<label proportion="2" text_align="left" id="server_name" text=""/>
|
||||
</div>
|
||||
</box>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<box proportion="1" width="100%" layout="vertical-row">
|
||||
<div x="1%" y="2%" width="98%" height="96%" layout="vertical-row" >
|
||||
<div width="fit" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" height="fit" text_align="left" I18N="In the online account settings screen" text="Password :"/>
|
||||
<label proportion="1" height="fit" text_align="left" I18N="In the online account settings screen" text="Password:"/>
|
||||
<spacer width="20" height="1"/>
|
||||
<button id="change_password_button" height="100%" width="fit" text="Change" />
|
||||
</div>
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
<button id="add_device" I18N="In the input configuration screen" text="Add a device" align="center"/>
|
||||
|
||||
<label text="* Which config to use will be inferred from which 'Select' key is pressed to join the game."
|
||||
<label I18N="In the input configuration screen" text="* Which config to use will be inferred from which 'Select' key is pressed to join the game."
|
||||
proportion="2" word_wrap="true"/>
|
||||
</box>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="2%" y="10%" width="96%" height="80%" layout="vertical-row" >
|
||||
|
||||
<label raw_text="Run script"/>
|
||||
|
||||
<textbox id="textfield" width="75%" I18N="In the 'add new grand prix' dialog" align="center"/>
|
||||
|
||||
<spacer height="20" width="20" />
|
||||
|
||||
<div align="center" height="fit" width="100%" layout="horizontal-row">
|
||||
<button id="run" raw_text="Run" align="center" proportion="1"/>
|
||||
<spacer height="20" width="20" />
|
||||
<button id="close" raw_text="Close" align="center" proportion="1"/>
|
||||
</div>
|
||||
</div>
|
||||
</stkgui>
|
||||
@@ -7,7 +7,7 @@
|
||||
<spacer height="2%" width="1"/>
|
||||
|
||||
<div width="100%" layout="horizontal-row" height="fit">
|
||||
<label id="race_type" text="Type :" I18N="Type of race, in a challenge"/>
|
||||
<label id="race_type" text="Type:" I18N="Type of race, in a challenge"/>
|
||||
<spacer width="5" height="1"/>
|
||||
<label id="race_type_val" proportion="1"/>
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
<div x="5%" y="2%" width="90%" height="96%" layout="vertical-row" >
|
||||
|
||||
<header I18N="Title for tutorials screen" text="Tutorial : Selection Room" text_align="center" width="100%" />
|
||||
<header I18N="Title for tutorials screen" text="Tutorial - Selection Room" text_align="center" width="100%" />
|
||||
|
||||
<spacer proportion="1" width="100%"/>
|
||||
|
||||
|
||||
+27
-5
@@ -20,8 +20,9 @@ jpegtran=true
|
||||
advdef=true
|
||||
advzip=true
|
||||
optipng=true
|
||||
convert=true
|
||||
|
||||
#WARNING! SETTING TO TRUE MAY POSSIBLY INCREASE LOAD TIMES ON A SLOW CPU (UNTESTED) OR LEAD TO FILE NOT FOUND ERRORS WHEN RUNNING SUPERTUXKART!
|
||||
#WARNING! SETTING TO TRUE MAY POSSIBLY INCREASE LOAD TIMES ON A SLOW CPU (UNTESTED) OR LEAD TO FILE NOT FOUND ERRORS WHEN RUNNING SUPERTUXKART!
|
||||
compress_b3d=false
|
||||
|
||||
|
||||
@@ -58,10 +59,17 @@ then
|
||||
sleep 2
|
||||
fi
|
||||
|
||||
#check for convert
|
||||
if [ ! $(which convert) ]
|
||||
then
|
||||
echo "convert is not installed, therefore it will not be used."; convert=false
|
||||
sleep 2
|
||||
fi
|
||||
|
||||
#check for optipng
|
||||
if [ ! $(which optipng) ]
|
||||
then
|
||||
echo "optipng is not installed, therefore it will not be used."; optipng=false
|
||||
echo "optipng is not installed, therefore it will not be used."; optipng=false
|
||||
sleep 2
|
||||
fi
|
||||
|
||||
@@ -83,10 +91,18 @@ BEFORE=`du -sk | awk '{print $1}'`
|
||||
#functions for xargs multithreading, used instead of GNU parallel for cross-compatibility
|
||||
#TODO: let next set of optimization scripts run if one set is stuck on a single file at the end to decrease total runtime
|
||||
|
||||
#strip ICC information off PNG's
|
||||
strippng () {
|
||||
for arg; do
|
||||
convert "$arg" -strip "$arg"
|
||||
done
|
||||
}
|
||||
export -f strippng
|
||||
|
||||
#optimize PNG's
|
||||
optimpng () {
|
||||
for arg; do
|
||||
optipng -quiet -o3 "$arg"
|
||||
optipng -quiet -o3 "$arg"
|
||||
#level 3 = 16 trials, which according to http://optipng.sourceforge.net/pngtech/optipng.html (retrieved October 2014) should be satisfactory for all users
|
||||
done
|
||||
}
|
||||
@@ -96,7 +112,7 @@ export -f optimpng
|
||||
#compress PNG in-stream data
|
||||
comprpng () {
|
||||
for arg; do
|
||||
advdef -z4 "$arg"
|
||||
advdef -z4 "$arg"
|
||||
done
|
||||
}
|
||||
export -f comprpng
|
||||
@@ -121,6 +137,12 @@ done
|
||||
export -f recomprb3dz
|
||||
#END MULTITHREADING FUNCTIONS
|
||||
|
||||
#strip png icc information
|
||||
if [ "$convert" = true ]; then
|
||||
find . -path .svn -prune -o -name "*.png" -print0 | xargs -0 -n 1 -P "$threads" bash -c 'strippng "$@"' -- #multithread the png stripping
|
||||
else echo "convert not installed. Ignoring commands using convert..."; sleep 1
|
||||
fi
|
||||
|
||||
#lossless png image optimization
|
||||
if [ "$optipng" = true ]; then
|
||||
find . -path .svn -prune -o -name "*.png" -print0 | xargs -0 -n 1 -P "$threads" bash -c 'optimpng "$@"' -- #multithread the png optimization
|
||||
@@ -142,7 +164,7 @@ else echo "jpegtran not installed. Ignoring commands using jpegtran..."; sleep 1
|
||||
fi
|
||||
|
||||
|
||||
#b3dz to b3dz compression
|
||||
#b3dz to b3dz compression
|
||||
#WARNING: BETA, MAY CAUSE MISSING FILE WARNINGS!
|
||||
if [ "$compress_b3d" = true ]; then
|
||||
for xmls in $(find . -name "*.xml"); do
|
||||
|
||||
+3370
File diff suppressed because it is too large
Load Diff
+3370
File diff suppressed because it is too large
Load Diff
+3373
File diff suppressed because it is too large
Load Diff
+3369
File diff suppressed because it is too large
Load Diff
+3370
File diff suppressed because it is too large
Load Diff
+3370
File diff suppressed because it is too large
Load Diff
+3370
File diff suppressed because it is too large
Load Diff
+3367
File diff suppressed because it is too large
Load Diff
+3369
File diff suppressed because it is too large
Load Diff
+3378
File diff suppressed because it is too large
Load Diff
+419
-415
@@ -1,70 +1,4 @@
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Christoffel Columbus")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Play every official track at least once.")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Strike!")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Hit 10 karts with a bowling-ball.")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Arch Enemy")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Hit the same kart at least 5 times in one race.")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Marathoner")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Make a race with 5 laps or more.")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Skid-row")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Make 5 skidding in a single lap.")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Gold driver")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Win in all single player modes, against at least 3 opponents.")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Powerup Love")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Use 10 or more powerups in a race.")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Unstoppable")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Win 5 single races in a row.")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Banana Lover")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Collect at least 5 bananas in one race.")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("It's secret")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Really ... a secret.")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Mosquito Hunter")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Take your opponents for mosquitos! With the swatter, squash at least 5 of them in a race.")
|
||||
|
||||
//I18N: ./data/grandprix/1_penguinplayground.grandprix
|
||||
//I18N: ./data/grandprix/1_penguinplayground.grandprix
|
||||
_("Penguin Playground")
|
||||
|
||||
//I18N: ./data/grandprix/2_offthebeatentrack.grandprix
|
||||
@@ -127,10 +61,6 @@ _("Add-Ons");
|
||||
//I18N: track group
|
||||
_("All");
|
||||
|
||||
//I18N: ./data/gui/challenges.stkgui
|
||||
//I18N: Title for challenges screen
|
||||
_("Challenges : Trophy Room");
|
||||
|
||||
//I18N: ./data/gui/confirm_dialog.stkgui
|
||||
//I18N: In a 'are you sure?' dialog
|
||||
_("Yes");
|
||||
@@ -286,6 +216,30 @@ _("Cancel");
|
||||
//I18N: ./data/gui/feature_unlocked.stkgui
|
||||
_("Continue")
|
||||
|
||||
//I18N: ./data/gui/gp_info.stkgui
|
||||
//I18N: In the grand prix info screen
|
||||
_("AI karts");
|
||||
|
||||
//I18N: ./data/gui/gp_info.stkgui
|
||||
//I18N: In the grand prix info screen
|
||||
_("Reverse");
|
||||
|
||||
//I18N: ./data/gui/gp_info.stkgui
|
||||
//I18N: In the grand prix info screen
|
||||
_("Tracks");
|
||||
|
||||
//I18N: ./data/gui/gp_info.stkgui
|
||||
//I18N: In the grand prix info screen
|
||||
_("Track group");
|
||||
|
||||
//I18N: ./data/gui/gp_info.stkgui
|
||||
//I18N: In the grand prix info screen
|
||||
_("Start Race");
|
||||
|
||||
//I18N: ./data/gui/gp_info.stkgui
|
||||
//I18N: In the grand prix info screen
|
||||
_("Continue saved GP");
|
||||
|
||||
//I18N: ./data/gui/gpedit.stkgui
|
||||
//I18N: Title in edit grand prix screen
|
||||
_("Edit Grand Prix");
|
||||
@@ -338,30 +292,6 @@ _("Remove");
|
||||
//I18N: Menu item
|
||||
_("Rename");
|
||||
|
||||
//I18N: ./data/gui/gp_info.stkgui
|
||||
//I18N: In the grand prix info screen
|
||||
_("AI karts");
|
||||
|
||||
//I18N: ./data/gui/gp_info.stkgui
|
||||
//I18N: In the grand prix info screen
|
||||
_("Reverse");
|
||||
|
||||
//I18N: ./data/gui/gp_info.stkgui
|
||||
//I18N: In the grand prix info screen
|
||||
_("Tracks");
|
||||
|
||||
//I18N: ./data/gui/gp_info.stkgui
|
||||
//I18N: In the grand prix info screen
|
||||
_("Track group");
|
||||
|
||||
//I18N: ./data/gui/gp_info.stkgui
|
||||
//I18N: In the grand prix info screen
|
||||
_("Start Race");
|
||||
|
||||
//I18N: ./data/gui/gp_info.stkgui
|
||||
//I18N: In the grand prix info screen
|
||||
_("Continue saved GP");
|
||||
|
||||
//I18N: ./data/gui/grand_prix_lose.stkgui
|
||||
_("Continue")
|
||||
|
||||
@@ -374,152 +304,6 @@ _("Continue")
|
||||
//I18N: ./data/gui/grand_prix_win.stkgui
|
||||
_("Save Grand Prix")
|
||||
|
||||
//I18N: ./data/gui/help1.stkgui
|
||||
_("SuperTuxKart Help")
|
||||
|
||||
//I18N: ./data/gui/help1.stkgui
|
||||
//I18N: Tab in help menu
|
||||
_("General");
|
||||
|
||||
//I18N: ./data/gui/help1.stkgui
|
||||
//I18N: Tab in help menu
|
||||
_("Weapons");
|
||||
|
||||
//I18N: ./data/gui/help1.stkgui
|
||||
//I18N: Tab in help menu
|
||||
_("Game Modes");
|
||||
|
||||
//I18N: ./data/gui/help1.stkgui
|
||||
//I18N: Tab in help menu
|
||||
_("Multiplayer");
|
||||
|
||||
//I18N: ./data/gui/help1.stkgui
|
||||
_("Click here to play the tutorial")
|
||||
|
||||
//I18N: ./data/gui/help1.stkgui
|
||||
//I18N: In the help menu
|
||||
_("Collect blue boxes : they will give you weapons or other powerups");
|
||||
|
||||
//I18N: ./data/gui/help1.stkgui
|
||||
//I18N: In the help menu
|
||||
_("Avoid bananas!");
|
||||
|
||||
//I18N: ./data/gui/help1.stkgui
|
||||
//I18N: In the help menu
|
||||
_("Collecting nitro allows you to get speed boosts whenever you wish by pressing the appropriate key. You can see your current level of nitro in the bar at the right of the game screen.");
|
||||
|
||||
//I18N: ./data/gui/help1.stkgui
|
||||
//I18N: In the help menu
|
||||
_("If you see a button with a lock like this one, you need to complete a challenge to unlock it.");
|
||||
|
||||
//I18N: ./data/gui/help1.stkgui
|
||||
//I18N: in the help menu
|
||||
_("The 'skidding' key allows you to skid in sharp turns and get a boost.");
|
||||
|
||||
//I18N: ./data/gui/help1.stkgui
|
||||
//I18N: in the help screen
|
||||
_("* Current key bindings can be seen/changed in menu Options");
|
||||
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
_("SuperTuxKart Help")
|
||||
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
//I18N: Tab in help menu
|
||||
_("General");
|
||||
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
//I18N: Tab in help menu
|
||||
_("Weapons");
|
||||
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
//I18N: Tab in help menu
|
||||
_("Game Modes");
|
||||
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
//I18N: Tab in help menu
|
||||
_("Multiplayer");
|
||||
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
//I18N: In the help menu
|
||||
_("To help you win, there are some powerups you can collect :");
|
||||
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
_("BubbleGum - protect yourself with a shield, or use while looking back to leave a sticky pink puddle behind you.")
|
||||
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
_("Cake - thrown at the closest rival, best on short ranges and long straights.")
|
||||
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
_("Plunger - throw straight to pull an opponent back, or throw while looking back to make one lose sight.")
|
||||
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
_("Bowling Ball - bounces off walls. If you are looking back, it will be thrown backwards.")
|
||||
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
_("Parachute - slows down all karts in a better position.")
|
||||
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
_("Anchor - slows down greatly the kart in the first position.")
|
||||
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
_("Swapper - gift boxes are transformed into bananas and vice versa for a short time.")
|
||||
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
_("Basket Ball - bounces after the leader, and might squash and slow down karts down on the way.")
|
||||
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
_("Swatter - will squash karts close by, slowing them down.")
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
_("SuperTuxKart Help")
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
//I18N: Tab in help menu
|
||||
_("General");
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
//I18N: Tab in help menu
|
||||
_("Weapons");
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
//I18N: Tab in help menu
|
||||
_("Game Modes");
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
//I18N: Tab in help menu
|
||||
_("Multiplayer");
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
_("SuperTuxKart features several game modes")
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
//I18N: In the help menu
|
||||
_("Regular Race: All blows allowed, so catch weapons and make clever use of them!");
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
//I18N: In the help menu
|
||||
_("Time Trial: Contains no powerups, so only your driving skills matter!");
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
//I18N: In the help menu
|
||||
_("Follow the leader: Run for second place, as the last kart will be disqualified every time the counter hits zero. Beware : going in front of the leader will get you eliminated too!");
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
//I18N: In the help menu
|
||||
_("3 Strikes Battle: Only in multiplayer games. Hit others with weapons until they lose all their lives.");
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
//I18N: In the help menu
|
||||
_("Soccer: Only in multiplayer games. Use your kart to push the ball into the goal.");
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
//I18N: In the help menu
|
||||
_("Egg hunt: Explore tracks to find all hidden eggs.");
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
//I18N: In the help menu
|
||||
_("* Most of these game modes can also be played in a Grand Prix fashion: instead of playing a single race, you play many in a row. The better you rank, the more points you get. In the end, the player with the most points wins the cup.");
|
||||
|
||||
//I18N: ./data/gui/help4.stkgui
|
||||
_("SuperTuxKart Help")
|
||||
|
||||
@@ -684,22 +468,6 @@ _("Log In");
|
||||
//I18N: In the login dialog
|
||||
_("Close");
|
||||
|
||||
//I18N: ./data/gui/online/lobby.stkgui
|
||||
//I18N: In networking lobby
|
||||
_("Lobby");
|
||||
|
||||
//I18N: ./data/gui/online/lobby.stkgui
|
||||
//I18N: In the networking lobby
|
||||
_("Server name :");
|
||||
|
||||
//I18N: ./data/gui/online/lobby.stkgui
|
||||
//I18N: In networking lobby
|
||||
_("actions");
|
||||
|
||||
//I18N: ./data/gui/online/lobby.stkgui
|
||||
//I18N: In the networking lobby
|
||||
_("Exit");
|
||||
|
||||
//I18N: ./data/gui/online/lobby_settings.stkgui
|
||||
//I18N: In the lobby settings screen
|
||||
_("Lobby Settings");
|
||||
@@ -775,20 +543,6 @@ _("...")
|
||||
//I18N: Section in the profile screen
|
||||
_("Overview");
|
||||
|
||||
//I18N: ./data/gui/online/profile_settings.stkgui
|
||||
_("...")
|
||||
|
||||
//I18N: ./data/gui/online/profile_settings.stkgui
|
||||
//I18N: Section in the profile screen
|
||||
_("Account Settings");
|
||||
|
||||
//I18N: ./data/gui/online/profile_settings.stkgui
|
||||
//I18N: In the online account settings screen
|
||||
_("Password :");
|
||||
|
||||
//I18N: ./data/gui/online/profile_settings.stkgui
|
||||
_("Change")
|
||||
|
||||
//I18N: ./data/gui/online/recovery_info.stkgui
|
||||
//I18N: In the recovery dialog
|
||||
_("Account Recovery");
|
||||
@@ -953,6 +707,36 @@ _("Vote");
|
||||
//I18N: Vote dialog
|
||||
_("Close");
|
||||
|
||||
//I18N: ./data/gui/online/lobby.stkgui
|
||||
//I18N: In networking lobby
|
||||
_("Lobby");
|
||||
|
||||
//I18N: ./data/gui/online/lobby.stkgui
|
||||
//I18N: In the networking lobby
|
||||
_("Server name:");
|
||||
|
||||
//I18N: ./data/gui/online/lobby.stkgui
|
||||
//I18N: In networking lobby
|
||||
_("actions");
|
||||
|
||||
//I18N: ./data/gui/online/lobby.stkgui
|
||||
//I18N: In the networking lobby
|
||||
_("Exit");
|
||||
|
||||
//I18N: ./data/gui/online/profile_settings.stkgui
|
||||
_("...")
|
||||
|
||||
//I18N: ./data/gui/online/profile_settings.stkgui
|
||||
//I18N: Section in the profile screen
|
||||
_("Account Settings");
|
||||
|
||||
//I18N: ./data/gui/online/profile_settings.stkgui
|
||||
//I18N: In the online account settings screen
|
||||
_("Password:");
|
||||
|
||||
//I18N: ./data/gui/online/profile_settings.stkgui
|
||||
_("Change")
|
||||
|
||||
//I18N: ./data/gui/options_audio.stkgui
|
||||
_("SuperTuxKart Options")
|
||||
|
||||
@@ -1015,7 +799,8 @@ _("Press enter or double-click on a device to configure it");
|
||||
_("Add a device");
|
||||
|
||||
//I18N: ./data/gui/options_input.stkgui
|
||||
_("* Which config to use will be inferred from which 'Select' key is pressed to join the game.")
|
||||
//I18N: In the input configuration screen
|
||||
_("* Which config to use will be inferred from which 'Select' key is pressed to join the game.");
|
||||
|
||||
//I18N: ./data/gui/options_players.stkgui
|
||||
_("SuperTuxKart Options")
|
||||
@@ -1139,31 +924,6 @@ _("Assign nothing");
|
||||
//I18N: When configuring input
|
||||
_("Press ESC to cancel");
|
||||
|
||||
//I18N: ./data/gui/racesetup.stkgui
|
||||
_("Race Setup")
|
||||
|
||||
//I18N: ./data/gui/racesetup.stkgui
|
||||
_("Select a difficulty")
|
||||
|
||||
//I18N: ./data/gui/racesetup.stkgui
|
||||
//I18N: Difficulty
|
||||
_("Novice");
|
||||
|
||||
//I18N: ./data/gui/racesetup.stkgui
|
||||
//I18N: Difficulty
|
||||
_("Intermediate");
|
||||
|
||||
//I18N: ./data/gui/racesetup.stkgui
|
||||
//I18N: Difficulty
|
||||
_("Expert");
|
||||
|
||||
//I18N: ./data/gui/racesetup.stkgui
|
||||
//I18N: Difficulty
|
||||
_("SuperTux");
|
||||
|
||||
//I18N: ./data/gui/racesetup.stkgui
|
||||
_("Select a game mode")
|
||||
|
||||
//I18N: ./data/gui/race_paused_dialog.stkgui
|
||||
_("Paused")
|
||||
|
||||
@@ -1195,25 +955,31 @@ _("Help");
|
||||
//I18N: Race paused button
|
||||
_("Exit Race");
|
||||
|
||||
//I18N: ./data/gui/select_challenge.stkgui
|
||||
//I18N: ./data/gui/racesetup.stkgui
|
||||
_("Race Setup")
|
||||
|
||||
//I18N: ./data/gui/select_challenge.stkgui
|
||||
//I18N: Type of race, in a challenge
|
||||
_("Type :");
|
||||
//I18N: ./data/gui/racesetup.stkgui
|
||||
_("Select a difficulty")
|
||||
|
||||
//I18N: ./data/gui/select_challenge.stkgui
|
||||
//I18N: ./data/gui/racesetup.stkgui
|
||||
//I18N: Difficulty
|
||||
_("Novice");
|
||||
|
||||
//I18N: ./data/gui/select_challenge.stkgui
|
||||
//I18N: ./data/gui/racesetup.stkgui
|
||||
//I18N: Difficulty
|
||||
_("Intermediate");
|
||||
|
||||
//I18N: ./data/gui/select_challenge.stkgui
|
||||
//I18N: ./data/gui/racesetup.stkgui
|
||||
//I18N: Difficulty
|
||||
_("Expert");
|
||||
|
||||
//I18N: ./data/gui/racesetup.stkgui
|
||||
//I18N: Difficulty
|
||||
_("SuperTux");
|
||||
|
||||
//I18N: ./data/gui/racesetup.stkgui
|
||||
_("Select a game mode")
|
||||
|
||||
//I18N: ./data/gui/soccer_setup.stkgui
|
||||
_("Race Setup")
|
||||
|
||||
@@ -1240,14 +1006,6 @@ _("VS")
|
||||
//I18N: In soccer setup screen
|
||||
_("Continue");
|
||||
|
||||
//I18N: ./data/gui/tracks.stkgui
|
||||
//I18N: In the track selection screen
|
||||
_("Grand Prix");
|
||||
|
||||
//I18N: ./data/gui/tracks.stkgui
|
||||
//I18N: In the track selection screen
|
||||
_("All Tracks");
|
||||
|
||||
//I18N: ./data/gui/track_info.stkgui
|
||||
_("= Highscores =")
|
||||
|
||||
@@ -1276,12 +1034,13 @@ _("Drive in reverse");
|
||||
//I18N: In the track info screen
|
||||
_("Start Race");
|
||||
|
||||
//I18N: ./data/gui/tutorial.stkgui
|
||||
//I18N: Title for tutorials screen
|
||||
_("Tutorial : Selection Room");
|
||||
//I18N: ./data/gui/tracks.stkgui
|
||||
//I18N: In the track selection screen
|
||||
_("Grand Prix");
|
||||
|
||||
//I18N: ./data/gui/tutorial.stkgui
|
||||
_("Play all")
|
||||
//I18N: ./data/gui/tracks.stkgui
|
||||
//I18N: In the track selection screen
|
||||
_("All Tracks");
|
||||
|
||||
//I18N: ./data/gui/tutorial_message_dialog.stkgui
|
||||
//I18N: Button in tutorial
|
||||
@@ -1369,74 +1128,343 @@ _("Rename");
|
||||
//I18N: In the user screen
|
||||
_("Cancel");
|
||||
|
||||
//I18N: ../stk-assets/tracks/battleisland/track.xml
|
||||
_("Battle Island")
|
||||
//I18N: ./data/gui/challenges.stkgui
|
||||
//I18N: Title for challenges screen
|
||||
_("Challenges - Trophy Room");
|
||||
|
||||
//I18N: ../stk-assets/tracks/cave/track.xml
|
||||
_("Cave X")
|
||||
//I18N: ./data/gui/tutorial.stkgui
|
||||
//I18N: Title for tutorials screen
|
||||
_("Tutorial - Selection Room");
|
||||
|
||||
//I18N: ../stk-assets/tracks/city/track.xml
|
||||
_("Shiny Suburbs")
|
||||
//I18N: ./data/gui/tutorial.stkgui
|
||||
_("Play all")
|
||||
|
||||
//I18N: ../stk-assets/tracks/cocoa_temple/track.xml
|
||||
_("Cocoa Temple")
|
||||
//I18N: ./data/gui/help1.stkgui
|
||||
_("SuperTuxKart Help")
|
||||
|
||||
//I18N: ../stk-assets/tracks/farm/track.xml
|
||||
_("Bovine Barnyard")
|
||||
//I18N: ./data/gui/help1.stkgui
|
||||
//I18N: Tab in help menu
|
||||
_("General");
|
||||
|
||||
//I18N: ../stk-assets/tracks/fortmagma/track.xml
|
||||
_("Fort Magma")
|
||||
//I18N: ./data/gui/help1.stkgui
|
||||
//I18N: Tab in help menu
|
||||
_("Weapons");
|
||||
|
||||
//I18N: ../stk-assets/tracks/gran_paradiso_island/track.xml
|
||||
_("Gran Paradiso Island")
|
||||
//I18N: ./data/gui/help1.stkgui
|
||||
//I18N: Tab in help menu
|
||||
_("Game Modes");
|
||||
|
||||
//I18N: ../stk-assets/tracks/greenvalley/track.xml
|
||||
_("Green Valley")
|
||||
//I18N: ./data/gui/help1.stkgui
|
||||
//I18N: Tab in help menu
|
||||
_("Multiplayer");
|
||||
|
||||
//I18N: ../stk-assets/tracks/hacienda/track.xml
|
||||
_("Hacienda")
|
||||
//I18N: ./data/gui/help1.stkgui
|
||||
_("Click here to play the tutorial")
|
||||
|
||||
//I18N: Cutscene subtitle from ../stk-assets/tracks/introcutscene2/scene.xml
|
||||
_("What's wrong, little hippies? Your great gnu leader is missing?")
|
||||
//I18N: ./data/gui/help1.stkgui
|
||||
//I18N: In the help menu
|
||||
_("Collect blue boxes. They will give you weapons or other powerups.");
|
||||
|
||||
//I18N: ../stk-assets/tracks/introcutscene2/scene.xml
|
||||
_("What's wrong, little hippies? Your great gnu leader is missing?")
|
||||
//I18N: ./data/gui/help1.stkgui
|
||||
//I18N: In the help menu
|
||||
_("Avoid bananas!");
|
||||
|
||||
//I18N: Cutscene subtitle from ../stk-assets/tracks/introcutscene2/scene.xml
|
||||
_("Oh yes, see, he's in my castle now and will be served for supper...")
|
||||
//I18N: ./data/gui/help1.stkgui
|
||||
//I18N: In the help menu
|
||||
_("Collecting nitro allows you to get speed boosts whenever you wish by pressing the appropriate key. You can see your current level of nitro in the bar at the right of the game screen.");
|
||||
|
||||
//I18N: ../stk-assets/tracks/introcutscene2/scene.xml
|
||||
_("Oh yes, see, he's in my castle now and will be served for supper...")
|
||||
//I18N: ./data/gui/help1.stkgui
|
||||
//I18N: In the help menu
|
||||
_("If you see a button with a lock like this one, you need to complete a challenge to unlock it.");
|
||||
|
||||
//I18N: Cutscene subtitle from ../stk-assets/tracks/introcutscene2/scene.xml
|
||||
_("But I'm a fair creature, so I'll make you a deal.")
|
||||
//I18N: ./data/gui/help1.stkgui
|
||||
//I18N: in the help menu
|
||||
_("The 'skidding' key allows you to skid in sharp turns and get a boost.");
|
||||
|
||||
//I18N: ../stk-assets/tracks/introcutscene2/scene.xml
|
||||
_("But I'm a fair creature, so I'll make you a deal.")
|
||||
//I18N: ./data/gui/help1.stkgui
|
||||
//I18N: in the help screen
|
||||
_("* Current key bindings can be seen/changed in menu Options");
|
||||
|
||||
//I18N: Cutscene subtitle from ../stk-assets/tracks/introcutscene2/scene.xml
|
||||
_("If you can beat me at racing, I will free the old codger.")
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
_("SuperTuxKart Help")
|
||||
|
||||
//I18N: ../stk-assets/tracks/introcutscene2/scene.xml
|
||||
_("If you can beat me at racing, I will free the old codger.")
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
//I18N: Tab in help menu
|
||||
_("General");
|
||||
|
||||
//I18N: Cutscene subtitle from ../stk-assets/tracks/introcutscene2/scene.xml
|
||||
_(" But you pathetic little twerps will never be able to beat me - King of the Karts!")
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
//I18N: Tab in help menu
|
||||
_("Weapons");
|
||||
|
||||
//I18N: ../stk-assets/tracks/introcutscene2/scene.xml
|
||||
_(" But you pathetic little twerps will never be able to beat me - King of the Karts!")
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
//I18N: Tab in help menu
|
||||
_("Game Modes");
|
||||
|
||||
//I18N: ../stk-assets/tracks/lighthouse/track.xml
|
||||
_("Around the lighthouse")
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
//I18N: Tab in help menu
|
||||
_("Multiplayer");
|
||||
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
//I18N: In the help menu
|
||||
_("To help you win, there are some powerups you can collect:");
|
||||
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
_("BubbleGum - protect yourself with a shield, or use while looking back to leave a sticky pink puddle behind you.")
|
||||
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
_("Cake - thrown at the closest rival, best on short ranges and long straights.")
|
||||
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
_("Plunger - throw straight to pull an opponent back, or throw while looking back to make one lose sight.")
|
||||
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
_("Bowling Ball - bounces off walls. If you are looking back, it will be thrown backwards.")
|
||||
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
_("Parachute - slows down all karts in a better position.")
|
||||
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
_("Anchor - greatly slows down the kart in the first position.")
|
||||
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
_("Swapper - gift boxes are transformed into bananas and vice versa for a short time.")
|
||||
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
_("Basket Ball - bounces after the leader, and might squash and slow down karts down on the way.")
|
||||
|
||||
//I18N: ./data/gui/help2.stkgui
|
||||
_("Swatter - will squash karts close by, slowing them down.")
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
_("SuperTuxKart Help")
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
//I18N: Tab in help menu
|
||||
_("General");
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
//I18N: Tab in help menu
|
||||
_("Weapons");
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
//I18N: Tab in help menu
|
||||
_("Game Modes");
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
//I18N: Tab in help menu
|
||||
_("Multiplayer");
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
_("SuperTuxKart features several game modes")
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
//I18N: In the help menu
|
||||
_("Regular Race: All blows allowed, so catch weapons and make clever use of them!");
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
//I18N: In the help menu
|
||||
_("Time Trial: Contains no powerups, so only your driving skills matter!");
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
//I18N: In the help menu
|
||||
_("Follow the leader: Run for second place, as the last kart will be disqualified every time the counter hits zero. Beware: going in front of the leader will get you eliminated too!");
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
//I18N: In the help menu
|
||||
_("3 Strikes Battle: Only in multiplayer games. Hit others with weapons until they lose all their lives.");
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
//I18N: In the help menu
|
||||
_("Soccer: Only in multiplayer games. Use your kart to push the ball into the goal.");
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
//I18N: In the help menu
|
||||
_("Egg hunt: Explore tracks to find all hidden eggs.");
|
||||
|
||||
//I18N: ./data/gui/help3.stkgui
|
||||
//I18N: In the help menu
|
||||
_("* Most of these game modes can also be played in a Grand Prix fashion: instead of playing a single race, you play many in a row. The better you rank, the more points you get. In the end, the player with the most points wins the cup.");
|
||||
|
||||
//I18N: ./data/gui/select_challenge.stkgui
|
||||
_("Race Setup")
|
||||
|
||||
//I18N: ./data/gui/select_challenge.stkgui
|
||||
//I18N: Type of race, in a challenge
|
||||
_("Type:");
|
||||
|
||||
//I18N: ./data/gui/select_challenge.stkgui
|
||||
//I18N: Difficulty
|
||||
_("Novice");
|
||||
|
||||
//I18N: ./data/gui/select_challenge.stkgui
|
||||
//I18N: Difficulty
|
||||
_("Intermediate");
|
||||
|
||||
//I18N: ./data/gui/select_challenge.stkgui
|
||||
//I18N: Difficulty
|
||||
_("Expert");
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Christoffel Columbus")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Play every official track at least once.")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Strike!")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Hit 10 karts with a bowling-ball.")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Arch Enemy")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Hit the same kart at least 5 times in one race.")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Marathoner")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Make a race with 5 laps or more.")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Skid-row")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Make 5 skidding in a single lap.")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Gold driver")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Win against at least 3 opponents in all single player modes.")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Powerup Love")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Use 10 or more powerups in a race.")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Unstoppable")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Win 5 single races in a row.")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Banana Lover")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Collect at least 5 bananas in one race.")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("It's secret")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Really ... a secret.")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Mosquito Hunter")
|
||||
|
||||
//I18N: ./data/achievements.xml
|
||||
_("Take your opponents for mosquitos! With the swatter, squash at least 5 of them in a race.")
|
||||
|
||||
//I18N: ../stk-assets/tracks/soccer_field/track.xml
|
||||
_("Soccer field")
|
||||
|
||||
//I18N: ../stk-assets/tracks/subsea/track.xml
|
||||
_("Subsea")
|
||||
|
||||
//I18N: ../stk-assets/tracks/snowmountain/track.xml
|
||||
_("Northern Resort")
|
||||
|
||||
//I18N: ../stk-assets/tracks/minigolf/track.xml
|
||||
_("Minigolf")
|
||||
|
||||
//I18N: ../stk-assets/tracks/mansion/track.xml
|
||||
_("Blackhill Mansion")
|
||||
|
||||
//I18N: ../stk-assets/tracks/stadium/track.xml
|
||||
_("The Stadium")
|
||||
|
||||
//I18N: ../stk-assets/tracks/battleisland/track.xml
|
||||
_("Battle Island")
|
||||
|
||||
//I18N: ../stk-assets/tracks/scotland/track.xml
|
||||
_("Nessie's pond")
|
||||
|
||||
//I18N: ../stk-assets/tracks/city/track.xml
|
||||
_("Shiny Suburbs")
|
||||
|
||||
//I18N: ../stk-assets/tracks/lighthouse/track.xml
|
||||
_("Around the lighthouse")
|
||||
|
||||
//I18N: ../stk-assets/tracks/mines/track.xml
|
||||
_("Old Mine")
|
||||
|
||||
//I18N: ../stk-assets/tracks/minigolf/track.xml
|
||||
_("Minigolf")
|
||||
//I18N: ../stk-assets/tracks/zengarden/track.xml
|
||||
_("Zen Garden")
|
||||
|
||||
//I18N: ../stk-assets/tracks/greenvalley/track.xml
|
||||
_("Green Valley")
|
||||
|
||||
//I18N: ../stk-assets/tracks/fortmagma/track.xml
|
||||
_("Fort Magma")
|
||||
|
||||
//I18N: ../stk-assets/tracks/farm/track.xml
|
||||
_("Bovine Barnyard")
|
||||
|
||||
//I18N: ../stk-assets/tracks/temple/track.xml
|
||||
_("Temple")
|
||||
|
||||
//I18N: ../stk-assets/tracks/snowtuxpeak/track.xml
|
||||
_("Snow Peak")
|
||||
|
||||
//I18N: ../stk-assets/tracks/xr591/track.xml
|
||||
_("XR591")
|
||||
|
||||
//I18N: ../stk-assets/tracks/cocoa_temple/track.xml
|
||||
_("Cocoa Temple")
|
||||
|
||||
//I18N: ../stk-assets/tracks/hacienda/track.xml
|
||||
_("Hacienda")
|
||||
|
||||
//I18N: ../stk-assets/tracks/stk_enterprise/track.xml
|
||||
_("STK Enterprise")
|
||||
|
||||
//I18N: ../stk-assets/tracks/gran_paradiso_island/track.xml
|
||||
_("Gran Paradiso Island")
|
||||
|
||||
//I18N: Cutscene subtitle from ../stk-assets/tracks/introcutscene2/scene.xml
|
||||
_("What's wrong, little hippies? Your great gnu leader is missing?")
|
||||
|
||||
//I18N: ../stk-assets/tracks/introcutscene2/scene.xml
|
||||
_("What's wrong, little hippies? Your great gnu leader is missing?")
|
||||
|
||||
//I18N: Cutscene subtitle from ../stk-assets/tracks/introcutscene2/scene.xml
|
||||
_("Oh yes, see, he's in my castle now and will be served for supper...")
|
||||
|
||||
//I18N: ../stk-assets/tracks/introcutscene2/scene.xml
|
||||
_("Oh yes, see, he's in my castle now and will be served for supper...")
|
||||
|
||||
//I18N: Cutscene subtitle from ../stk-assets/tracks/introcutscene2/scene.xml
|
||||
_("But I'm a fair creature, so I'll make you a deal.")
|
||||
|
||||
//I18N: ../stk-assets/tracks/introcutscene2/scene.xml
|
||||
_("But I'm a fair creature, so I'll make you a deal.")
|
||||
|
||||
//I18N: Cutscene subtitle from ../stk-assets/tracks/introcutscene2/scene.xml
|
||||
_("If you can beat me at racing, I will free the old codger.")
|
||||
|
||||
//I18N: ../stk-assets/tracks/introcutscene2/scene.xml
|
||||
_("If you can beat me at racing, I will free the old codger.")
|
||||
|
||||
//I18N: Cutscene subtitle from ../stk-assets/tracks/introcutscene2/scene.xml
|
||||
_(" But you pathetic little twerps will never be able to beat me - King of the Karts!")
|
||||
|
||||
//I18N: ../stk-assets/tracks/introcutscene2/scene.xml
|
||||
_(" But you pathetic little twerps will never be able to beat me - King of the Karts!")
|
||||
|
||||
//I18N: ../stk-assets/tracks/olivermath/track.xml
|
||||
_("Oliver's Math Class")
|
||||
@@ -1444,56 +1472,17 @@ _("Oliver's Math Class")
|
||||
//I18N: ../stk-assets/tracks/sandtrack/track.xml
|
||||
_("Shifting Sands")
|
||||
|
||||
//I18N: ../stk-assets/tracks/scotland/track.xml
|
||||
_("Nessie's pond")
|
||||
//I18N: ../stk-assets/tracks/cave/track.xml
|
||||
_("Cave X")
|
||||
|
||||
//I18N: ../stk-assets/tracks/snowmountain/track.xml
|
||||
_("Northern Resort")
|
||||
|
||||
//I18N: ../stk-assets/tracks/snowtuxpeak/track.xml
|
||||
_("Snow Peak")
|
||||
|
||||
//I18N: ../stk-assets/tracks/soccer_field/track.xml
|
||||
_("Soccer field")
|
||||
|
||||
//I18N: ../stk-assets/tracks/stadium/track.xml
|
||||
_("The Stadium")
|
||||
|
||||
//I18N: ../stk-assets/tracks/stk_enterprise/track.xml
|
||||
_("STK Enterprise")
|
||||
|
||||
//I18N: ../stk-assets/tracks/subsea/track.xml
|
||||
_("Subsea")
|
||||
|
||||
//I18N: ../stk-assets/tracks/temple/track.xml
|
||||
_("Temple")
|
||||
|
||||
//I18N: ../stk-assets/tracks/xr591/track.xml
|
||||
_("XR591")
|
||||
|
||||
//I18N: ../stk-assets/tracks/zengarden/track.xml
|
||||
_("Zen Garden")
|
||||
|
||||
//I18N: ../stk-assets/karts/adiumy/kart.xml
|
||||
_("Adiumy")
|
||||
|
||||
//I18N: ../stk-assets/karts/amanda/kart.xml
|
||||
_("Amanda")
|
||||
|
||||
//I18N: ../stk-assets/karts/beastie/kart.xml
|
||||
_("Beastie")
|
||||
//I18N: ../stk-assets/karts/tux/kart.xml
|
||||
_("Tux")
|
||||
|
||||
//I18N: ../stk-assets/karts/elephpant/kart.xml
|
||||
_("Elephpant")
|
||||
|
||||
//I18N: ../stk-assets/karts/emule/kart.xml
|
||||
_("Emule")
|
||||
|
||||
//I18N: ../stk-assets/karts/gnu/kart.xml
|
||||
_("Gnu")
|
||||
|
||||
//I18N: ../stk-assets/karts/hexley/kart.xml
|
||||
_("Hexley")
|
||||
//I18N: ../stk-assets/karts/amanda/kart.xml
|
||||
_("Amanda")
|
||||
|
||||
//I18N: ../stk-assets/karts/konqi/kart.xml
|
||||
_("Konqi")
|
||||
@@ -1501,27 +1490,42 @@ _("Konqi")
|
||||
//I18N: ../stk-assets/karts/nolok/kart.xml
|
||||
_("Nolok")
|
||||
|
||||
//I18N: ../stk-assets/karts/pidgin/kart.xml
|
||||
_("Pidgin")
|
||||
//I18N: ../stk-assets/karts/suzanne/kart.xml
|
||||
_("Suzanne")
|
||||
|
||||
//I18N: ../stk-assets/karts/wilber/kart.xml
|
||||
_("Wilber")
|
||||
|
||||
//I18N: ../stk-assets/karts/adiumy/kart.xml
|
||||
_("Adiumy")
|
||||
|
||||
//I18N: ../stk-assets/karts/gnu/kart.xml
|
||||
_("Gnu")
|
||||
|
||||
//I18N: ../stk-assets/karts/puffy/kart.xml
|
||||
_("Puffy")
|
||||
|
||||
//I18N: ../stk-assets/karts/gavroche/kart.xml
|
||||
_("Gavroche")
|
||||
|
||||
//I18N: ../stk-assets/karts/hexley/kart.xml
|
||||
_("Hexley")
|
||||
|
||||
//I18N: ../stk-assets/karts/xue/kart.xml
|
||||
_("Xue")
|
||||
|
||||
//I18N: ../stk-assets/karts/sara_the_racer/kart.xml
|
||||
_("Sara the Racer")
|
||||
|
||||
//I18N: ../stk-assets/karts/sara_the_wizard/kart.xml
|
||||
_("Sara the Wizard")
|
||||
|
||||
//I18N: ../stk-assets/karts/suzanne/kart.xml
|
||||
_("Suzanne")
|
||||
//I18N: ../stk-assets/karts/emule/kart.xml
|
||||
_("Emule")
|
||||
|
||||
//I18N: ../stk-assets/karts/tux/kart.xml
|
||||
_("Tux")
|
||||
//I18N: ../stk-assets/karts/pidgin/kart.xml
|
||||
_("Pidgin")
|
||||
|
||||
//I18N: ../stk-assets/karts/wilber/kart.xml
|
||||
_("Wilber")
|
||||
|
||||
//I18N: ../stk-assets/karts/xue/kart.xml
|
||||
_("Xue")
|
||||
//I18N: ../stk-assets/karts/beastie/kart.xml
|
||||
_("Beastie")
|
||||
|
||||
|
||||
+3370
File diff suppressed because it is too large
Load Diff
+3373
File diff suppressed because it is too large
Load Diff
+3370
File diff suppressed because it is too large
Load Diff
+3370
File diff suppressed because it is too large
Load Diff
+3371
File diff suppressed because it is too large
Load Diff
+3367
File diff suppressed because it is too large
Load Diff
+3372
File diff suppressed because it is too large
Load Diff
+3369
File diff suppressed because it is too large
Load Diff
+3369
File diff suppressed because it is too large
Load Diff
+3370
File diff suppressed because it is too large
Load Diff
+3372
File diff suppressed because it is too large
Load Diff
+3370
File diff suppressed because it is too large
Load Diff
+3373
File diff suppressed because it is too large
Load Diff
+3370
File diff suppressed because it is too large
Load Diff
+2956
-2928
File diff suppressed because it is too large
Load Diff
+3369
File diff suppressed because it is too large
Load Diff
+3367
File diff suppressed because it is too large
Load Diff
@@ -17,11 +17,13 @@ XML_FILE_LIST="`find ./data ../stk-assets/tracks ../stk-assets/karts \
|
||||
-name '*.grandprix' -or \
|
||||
-name '*.stkgui' \
|
||||
`"
|
||||
ANGELSCRIPT_FILE_LIST="`find ./data ../stk-assets/tracks -name '*.as'`"
|
||||
|
||||
echo "--------------------"
|
||||
echo " Source Files :"
|
||||
echo "--------------------"
|
||||
echo $CPP_FILE_LIST
|
||||
echo $ANGELSCRIPT_FILE_LIST
|
||||
|
||||
echo "--------------------"
|
||||
echo " XML Files :"
|
||||
@@ -37,18 +39,22 @@ echo "---------------------------"
|
||||
echo " Generating .pot file..."
|
||||
|
||||
# XML Files
|
||||
xgettext -d supertuxkart -s --keyword=_ --add-comments="I18N:" \
|
||||
xgettext -d supertuxkart --keyword=_ --add-comments="I18N:" \
|
||||
-p ./data/po -o supertuxkart.pot \
|
||||
--no-location --from-code=UTF-8 ./data/po/gui_strings.h \
|
||||
--package-name=supertuxkart
|
||||
|
||||
# C++ Files
|
||||
xgettext -j -d supertuxkart -s --keyword=_ --keyword=N_ --keyword=_LTR \
|
||||
xgettext -j -d supertuxkart --keyword=_ --keyword=N_ --keyword=_LTR \
|
||||
--keyword=_C:1c,2 --keyword=_P:1,2 \
|
||||
--keyword=_CP:1c,2,3 --add-comments="I18N:" \
|
||||
-p ./data/po -o supertuxkart.pot $CPP_FILE_LIST \
|
||||
--package-name=supertuxkart
|
||||
|
||||
# Angelscript files (xgettext doesn't support AS so pretend it's c++)
|
||||
xgettext -j -d supertuxkart -s --keyword="translate" --add-comments="I18N:" \
|
||||
-p ./data/po -o supertuxkart.pot $ANGELSCRIPT_FILE_LIST \
|
||||
--package-name=supertuxkart --language=c++
|
||||
|
||||
|
||||
echo " Done"
|
||||
|
||||
+3367
File diff suppressed because it is too large
Load Diff
@@ -1,55 +0,0 @@
|
||||
uniform sampler2D depth;
|
||||
|
||||
layout (local_size_x = 32, local_size_y = 32) in;
|
||||
|
||||
layout (std430) buffer Histogram
|
||||
{
|
||||
int bin[1024];
|
||||
int mindepth;
|
||||
int maxdepth;
|
||||
int count;
|
||||
};
|
||||
|
||||
vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
|
||||
|
||||
shared int sbin[1024];
|
||||
shared int smindepth;
|
||||
shared int smaxdepth;
|
||||
shared int scount;
|
||||
|
||||
void main()
|
||||
{
|
||||
int x = int(gl_GlobalInvocationID.x), y = int(gl_GlobalInvocationID.y);
|
||||
vec2 uv = vec2(x, y) / screen;
|
||||
float z = texture(depth, uv).x;
|
||||
vec4 xpos = getPosFromUVDepth(vec3(uv, z), InverseProjectionMatrix);
|
||||
|
||||
int lineardepth = int(xpos.z * 4);
|
||||
|
||||
|
||||
sbin[gl_LocalInvocationIndex] = 0;
|
||||
if (gl_LocalInvocationIndex == 0) {
|
||||
smindepth = 1000;
|
||||
smaxdepth = 0;
|
||||
scount = 0;
|
||||
}
|
||||
|
||||
barrier();
|
||||
|
||||
if (lineardepth < 1000) {
|
||||
atomicAdd(sbin[lineardepth], 1);
|
||||
atomicAdd(scount, 1);
|
||||
atomicMin(smindepth, lineardepth);
|
||||
atomicMax(smaxdepth, lineardepth);
|
||||
}
|
||||
|
||||
barrier();
|
||||
|
||||
atomicAdd(bin[gl_LocalInvocationIndex], sbin[gl_LocalInvocationIndex]);
|
||||
if (gl_LocalInvocationIndex == 0) {
|
||||
atomicAdd(count, scount);
|
||||
atomicMin(mindepth, smindepth);
|
||||
atomicMax(maxdepth, smaxdepth);
|
||||
}
|
||||
}
|
||||
|
||||
+1361
-1241
File diff suppressed because it is too large
Load Diff
@@ -1,116 +1,155 @@
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS TRUE)
|
||||
cmake_policy(SET CMP0003 NEW)
|
||||
|
||||
project(angelscript)
|
||||
|
||||
option(BUILD_SHARED_LIBS "Build shared library" OFF)
|
||||
|
||||
if(APPLE)
|
||||
option(BUILD_FRAMEWORK "Build Framework bundle for OSX" OFF)
|
||||
endif()
|
||||
|
||||
set(ANGELSCRIPT_VERSION_MAJOR 2)
|
||||
set(ANGELSCRIPT_VERSION_MINOR 30)
|
||||
set(ANGELSCRIPT_VERSION_PATCH 0)
|
||||
set(PROJECT_VERSION ${ANGELSCRIPT_VERSION_MAJOR}.${ANGELSCRIPT_VERSION_MINOR}.${ANGELSCRIPT_VERSION_PATCH})
|
||||
|
||||
find_package(Threads)
|
||||
|
||||
set(ANGELSCRIPT_HEADERS
|
||||
../../include/angelscript.h
|
||||
../../source/as_array.h
|
||||
../../source/as_builder.h
|
||||
../../source/as_bytecode.h
|
||||
../../source/as_callfunc.h
|
||||
../../source/as_compiler.h
|
||||
../../source/as_config.h
|
||||
../../source/as_configgroup.h
|
||||
../../source/as_context.h
|
||||
../../source/as_criticalsection.h
|
||||
../../source/as_datatype.h
|
||||
../../source/as_debug.h
|
||||
../../source/as_generic.h
|
||||
../../source/as_map.h
|
||||
../../source/as_memory.h
|
||||
../../source/as_module.h
|
||||
../../source/as_objecttype.h
|
||||
../../source/as_outputbuffer.h
|
||||
../../source/as_parser.h
|
||||
../../source/as_property.h
|
||||
../../source/as_restore.h
|
||||
../../source/as_scriptcode.h
|
||||
../../source/as_scriptengine.h
|
||||
../../source/as_scriptfunction.h
|
||||
../../source/as_scriptnode.h
|
||||
../../source/as_scriptobject.h
|
||||
../../source/as_string.h
|
||||
../../source/as_string_util.h
|
||||
../../source/as_texts.h
|
||||
../../source/as_thread.h
|
||||
../../source/as_tokendef.h
|
||||
../../source/as_tokenizer.h
|
||||
../../source/as_typeinfo.h
|
||||
../../source/as_variablescope.h
|
||||
)
|
||||
|
||||
set(ANGELSCRIPT_SOURCE
|
||||
../../source/as_atomic.cpp
|
||||
../../source/as_builder.cpp
|
||||
../../source/as_bytecode.cpp
|
||||
../../source/as_callfunc.cpp
|
||||
../../source/as_callfunc_x86.cpp
|
||||
../../source/as_callfunc_x64_gcc.cpp
|
||||
../../source/as_callfunc_x64_msvc.cpp
|
||||
../../source/as_callfunc_x64_mingw.cpp
|
||||
../../source/as_compiler.cpp
|
||||
../../source/as_configgroup.cpp
|
||||
../../source/as_context.cpp
|
||||
../../source/as_datatype.cpp
|
||||
../../source/as_gc.cpp
|
||||
../../source/as_generic.cpp
|
||||
../../source/as_globalproperty.cpp
|
||||
../../source/as_memory.cpp
|
||||
../../source/as_module.cpp
|
||||
../../source/as_objecttype.cpp
|
||||
../../source/as_outputbuffer.cpp
|
||||
../../source/as_parser.cpp
|
||||
../../source/as_restore.cpp
|
||||
../../source/as_scriptcode.cpp
|
||||
../../source/as_scriptengine.cpp
|
||||
../../source/as_scriptfunction.cpp
|
||||
../../source/as_scriptnode.cpp
|
||||
../../source/as_scriptobject.cpp
|
||||
../../source/as_string.cpp
|
||||
../../source/as_string_util.cpp
|
||||
../../source/as_thread.cpp
|
||||
../../source/as_tokenizer.cpp
|
||||
../../source/as_typeinfo.cpp
|
||||
../../source/as_variablescope.cpp
|
||||
../../source/as_atomic.cpp
|
||||
../../source/as_builder.cpp
|
||||
../../source/as_bytecode.cpp
|
||||
../../source/as_callfunc.cpp
|
||||
../../source/as_callfunc_x86.cpp
|
||||
../../source/as_callfunc_x64_gcc.cpp
|
||||
../../source/as_callfunc_x64_msvc.cpp
|
||||
../../source/as_callfunc_x64_mingw.cpp
|
||||
../../source/as_compiler.cpp
|
||||
../../source/as_configgroup.cpp
|
||||
../../source/as_context.cpp
|
||||
../../source/as_datatype.cpp
|
||||
../../source/as_gc.cpp
|
||||
../../source/as_generic.cpp
|
||||
../../source/as_globalproperty.cpp
|
||||
../../source/as_memory.cpp
|
||||
../../source/as_module.cpp
|
||||
../../source/as_objecttype.cpp
|
||||
../../source/as_outputbuffer.cpp
|
||||
../../source/as_parser.cpp
|
||||
../../source/as_restore.cpp
|
||||
../../source/as_scriptcode.cpp
|
||||
../../source/as_scriptengine.cpp
|
||||
../../source/as_scriptfunction.cpp
|
||||
../../source/as_scriptnode.cpp
|
||||
../../source/as_scriptobject.cpp
|
||||
../../source/as_string.cpp
|
||||
../../source/as_string_util.cpp
|
||||
../../source/as_thread.cpp
|
||||
../../source/as_tokenizer.cpp
|
||||
../../source/as_typeinfo.cpp
|
||||
../../source/as_variablescope.cpp
|
||||
)
|
||||
|
||||
if(MSVC AND CMAKE_CL_64)
|
||||
enable_language(ASM_MASM)
|
||||
if(CMAKE_ASM_MASM_COMPILER_WORKS)
|
||||
set(ANGELSCRIPT_SOURCE ${ANGELSCRIPT_SOURCE} ../../source/as_callfunc_x64_msvc_asm.asm)
|
||||
else()
|
||||
message(FATAL ERROR "MSVC x86_64 target requires a working assembler")
|
||||
endif()
|
||||
enable_language(ASM_MASM)
|
||||
if(CMAKE_ASM_MASM_COMPILER_WORKS)
|
||||
set(ANGELSCRIPT_SOURCE ${ANGELSCRIPT_SOURCE} ../../source/as_callfunc_x64_msvc_asm.asm)
|
||||
else()
|
||||
message(FATAL ERROR "MSVC x86_64 target requires a working assembler")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ANDROID)
|
||||
enable_language(ASM)
|
||||
if(CMAKE_ASM_COMPILER_WORKS)
|
||||
set(ANGELSCRIPT_SOURCE ${ANGELSCRIPT_SOURCE} ../../source/as_callfunc_arm.cpp ../../source/as_callfunc_arm_gcc.S)
|
||||
else()
|
||||
message(FATAL ERROR "Android target requires a working assembler")
|
||||
endif(CMAKE_ASM_COMPILER_WORKS)
|
||||
enable_language(ASM)
|
||||
if(CMAKE_ASM_COMPILER_WORKS)
|
||||
set(ANGELSCRIPT_SOURCE ${ANGELSCRIPT_SOURCE} ../../source/as_callfunc_arm.cpp ../../source/as_callfunc_arm_gcc.S)
|
||||
else()
|
||||
message(FATAL ERROR "Android target requires a working assembler")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(ANGELSCRIPT_HEADERS
|
||||
../../include/angelscript.h
|
||||
../../source/as_array.h
|
||||
../../source/as_builder.h
|
||||
../../source/as_bytecode.h
|
||||
../../source/as_callfunc.h
|
||||
../../source/as_compiler.h
|
||||
../../source/as_config.h
|
||||
../../source/as_configgroup.h
|
||||
../../source/as_context.h
|
||||
../../source/as_criticalsection.h
|
||||
../../source/as_datatype.h
|
||||
../../source/as_debug.h
|
||||
../../source/as_generic.h
|
||||
../../source/as_map.h
|
||||
../../source/as_memory.h
|
||||
../../source/as_module.h
|
||||
../../source/as_objecttype.h
|
||||
../../source/as_outputbuffer.h
|
||||
../../source/as_parser.h
|
||||
../../source/as_property.h
|
||||
../../source/as_restore.h
|
||||
../../source/as_scriptcode.h
|
||||
../../source/as_scriptengine.h
|
||||
../../source/as_scriptfunction.h
|
||||
../../source/as_scriptnode.h
|
||||
../../source/as_scriptobject.h
|
||||
../../source/as_string.h
|
||||
../../source/as_string_util.h
|
||||
../../source/as_texts.h
|
||||
../../source/as_thread.h
|
||||
../../source/as_tokendef.h
|
||||
../../source/as_tokenizer.h
|
||||
../../source/as_typeinfo.h
|
||||
../../source/as_variablescope.h
|
||||
)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../include)
|
||||
|
||||
add_definitions("-D_CRT_SECURE_NO_WARNINGS -DANGELSCRIPT_EXPORT -D_LIB")
|
||||
if(MSVC)
|
||||
set(CMAKE_DEBUG_POSTFIX "d")
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
||||
add_definitions(-DANGELSCRIPT_EXPORT -D_LIB)
|
||||
|
||||
# Fix x64 issues on Linux
|
||||
if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64" AND NOT APPLE)
|
||||
add_definitions(-fPIC)
|
||||
add_definitions(-fPIC)
|
||||
endif()
|
||||
|
||||
add_library(angelscript STATIC ${ANGELSCRIPT_SOURCE} ${ANGELSCRIPT_HEADERS})
|
||||
if(NOT BUILD_FRAMEWORK)
|
||||
set(ANGELSCRIPT_LIBRARY_NAME angelscript)
|
||||
else()
|
||||
set(ANGELSCRIPT_LIBRARY_NAME Angelscript) # OS X frameworks should have capitalized name
|
||||
set(BUILD_SHARED_LIBS TRUE)
|
||||
endif()
|
||||
|
||||
#set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/../../lib)
|
||||
add_library(${ANGELSCRIPT_LIBRARY_NAME} ${ANGELSCRIPT_SOURCE} ${ANGELSCRIPT_HEADERS})
|
||||
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/../../lib)
|
||||
target_link_libraries(${ANGELSCRIPT_LIBRARY_NAME} ${CMAKE_THREAD_LIBS_INIT})
|
||||
|
||||
#find_package(Threads)
|
||||
#target_link_libraries(Angelscript ${CMAKE_THREAD_LIBS_INIT})
|
||||
set_target_properties(${ANGELSCRIPT_LIBRARY_NAME} PROPERTIES VERSION ${PROJECT_VERSION})
|
||||
|
||||
#if(MSVC)
|
||||
# set_target_properties(Angelscript PROPERTIES COMPILE_FLAGS "/MP")
|
||||
#endif(MSVC)
|
||||
if(BUILD_FRAMEWORK)
|
||||
set_target_properties(${ANGELSCRIPT_LIBRARY_NAME} PROPERTIES
|
||||
FRAMEWORK TRUE
|
||||
FRAMEWORK_VERSION ${PROJECT_VERSION}
|
||||
MACOSX_FRAMEWORK_IDENTIFIER com.angelcode.Angelscript
|
||||
MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${PROJECT_VERSION}
|
||||
MACOSX_FRAMEWORK_BUNDLE_VERSION ${PROJECT_VERSION}
|
||||
XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
|
||||
PUBLIC_HEADER ../../include/angelscript.h
|
||||
)
|
||||
endif()
|
||||
|
||||
#set(RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../../bin)
|
||||
if(MSVC)
|
||||
set_target_properties(${ANGELSCRIPT_LIBRARY_NAME} PROPERTIES COMPILE_FLAGS "/MP")
|
||||
endif()
|
||||
|
||||
set(RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../../bin)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2012 Andreas Jonsson
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -47,46 +47,46 @@ template <class T> class asCArray
|
||||
public:
|
||||
asCArray();
|
||||
asCArray(const asCArray<T> &);
|
||||
asCArray(size_t reserve);
|
||||
asCArray(asUINT reserve);
|
||||
~asCArray();
|
||||
|
||||
void Allocate(size_t numElements, bool keepData);
|
||||
void AllocateNoConstruct(size_t numElements, bool keepData);
|
||||
size_t GetCapacity() const;
|
||||
void Allocate(asUINT numElements, bool keepData);
|
||||
void AllocateNoConstruct(asUINT numElements, bool keepData);
|
||||
asUINT GetCapacity() const;
|
||||
|
||||
void PushLast(const T &element);
|
||||
T PopLast();
|
||||
|
||||
bool SetLength(size_t numElements);
|
||||
bool SetLengthNoConstruct(size_t numElements);
|
||||
size_t GetLength() const;
|
||||
bool SetLength(asUINT numElements);
|
||||
bool SetLengthNoConstruct(asUINT numElements);
|
||||
asUINT GetLength() const;
|
||||
|
||||
void Copy(const T*, size_t count);
|
||||
void Copy(const T*, asUINT count);
|
||||
asCArray<T> &operator =(const asCArray<T> &);
|
||||
void SwapWith(asCArray<T> &other);
|
||||
|
||||
const T &operator [](size_t index) const;
|
||||
T &operator [](size_t index);
|
||||
const T &operator [](asUINT index) const;
|
||||
T &operator [](asUINT index);
|
||||
T *AddressOf();
|
||||
const T *AddressOf() const;
|
||||
|
||||
void Concatenate(const asCArray<T> &);
|
||||
bool Concatenate(const asCArray<T> &);
|
||||
void Concatenate(T*, unsigned int count);
|
||||
|
||||
bool Exists(const T &element) const;
|
||||
int IndexOf(const T &element) const;
|
||||
void RemoveIndex(size_t index); // Removes the entry without reordering the array
|
||||
void RemoveIndex(asUINT index); // Removes the entry without reordering the array
|
||||
void RemoveValue(const T &element); // Removes the value without reordering the array
|
||||
void RemoveIndexUnordered(size_t index); // Removes the entry without keeping the order
|
||||
void RemoveIndexUnordered(asUINT index); // Removes the entry without keeping the order
|
||||
|
||||
bool operator==(const asCArray<T> &) const;
|
||||
bool operator!=(const asCArray<T> &) const;
|
||||
|
||||
protected:
|
||||
T *array;
|
||||
size_t length;
|
||||
size_t maxLength;
|
||||
char buf[8];
|
||||
asUINT length; // 32bits is enough for all uses of this array
|
||||
asUINT maxLength;
|
||||
char buf[2*4*AS_PTR_SIZE]; // Avoid dynamically allocated memory for tiny arrays
|
||||
};
|
||||
|
||||
// Implementation
|
||||
@@ -122,7 +122,7 @@ asCArray<T>::asCArray(const asCArray<T> ©)
|
||||
}
|
||||
|
||||
template <class T>
|
||||
asCArray<T>::asCArray(size_t reserve)
|
||||
asCArray<T>::asCArray(asUINT reserve)
|
||||
{
|
||||
array = 0;
|
||||
length = 0;
|
||||
@@ -139,13 +139,13 @@ asCArray<T>::~asCArray(void)
|
||||
}
|
||||
|
||||
template <class T>
|
||||
size_t asCArray<T>::GetLength() const
|
||||
asUINT asCArray<T>::GetLength() const
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const T &asCArray<T>::operator [](size_t index) const
|
||||
const T &asCArray<T>::operator [](asUINT index) const
|
||||
{
|
||||
asASSERT(index < length);
|
||||
|
||||
@@ -153,7 +153,7 @@ const T &asCArray<T>::operator [](size_t index) const
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T &asCArray<T>::operator [](size_t index)
|
||||
T &asCArray<T>::operator [](asUINT index)
|
||||
{
|
||||
asASSERT(index < length);
|
||||
|
||||
@@ -189,7 +189,7 @@ T asCArray<T>::PopLast()
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void asCArray<T>::Allocate(size_t numElements, bool keepData)
|
||||
void asCArray<T>::Allocate(asUINT numElements, bool keepData)
|
||||
{
|
||||
// We have 4 situations
|
||||
// 1. The previous array is 8 bytes or smaller and the new array is also 8 bytes or smaller
|
||||
@@ -200,7 +200,7 @@ void asCArray<T>::Allocate(size_t numElements, bool keepData)
|
||||
T *tmp = 0;
|
||||
if( numElements )
|
||||
{
|
||||
if( sizeof(T)*numElements <= 8 )
|
||||
if( sizeof(T)*numElements <= sizeof(buf) )
|
||||
// Use the internal buffer
|
||||
tmp = reinterpret_cast<T*>(buf);
|
||||
else
|
||||
@@ -217,20 +217,20 @@ void asCArray<T>::Allocate(size_t numElements, bool keepData)
|
||||
if( array == tmp )
|
||||
{
|
||||
// Construct only the newly allocated elements
|
||||
for( size_t n = length; n < numElements; n++ )
|
||||
for( asUINT n = length; n < numElements; n++ )
|
||||
new (&tmp[n]) T();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Construct all elements
|
||||
for( size_t n = 0; n < numElements; n++ )
|
||||
for( asUINT n = 0; n < numElements; n++ )
|
||||
new (&tmp[n]) T();
|
||||
}
|
||||
}
|
||||
|
||||
if( array )
|
||||
{
|
||||
size_t oldLength = length;
|
||||
asUINT oldLength = length;
|
||||
|
||||
if( array == tmp )
|
||||
{
|
||||
@@ -243,7 +243,7 @@ void asCArray<T>::Allocate(size_t numElements, bool keepData)
|
||||
length = 0;
|
||||
|
||||
// Call the destructor for elements that are no longer used
|
||||
for( size_t n = length; n < oldLength; n++ )
|
||||
for( asUINT n = length; n < oldLength; n++ )
|
||||
array[n].~T();
|
||||
}
|
||||
else
|
||||
@@ -253,14 +253,14 @@ void asCArray<T>::Allocate(size_t numElements, bool keepData)
|
||||
if( length > numElements )
|
||||
length = numElements;
|
||||
|
||||
for( size_t n = 0; n < length; n++ )
|
||||
for( asUINT n = 0; n < length; n++ )
|
||||
tmp[n] = array[n];
|
||||
}
|
||||
else
|
||||
length = 0;
|
||||
|
||||
// Call the destructor for all elements
|
||||
for( size_t n = 0; n < oldLength; n++ )
|
||||
for( asUINT n = 0; n < oldLength; n++ )
|
||||
array[n].~T();
|
||||
|
||||
if( array != reinterpret_cast<T*>(buf) )
|
||||
@@ -273,7 +273,7 @@ void asCArray<T>::Allocate(size_t numElements, bool keepData)
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void asCArray<T>::AllocateNoConstruct(size_t numElements, bool keepData)
|
||||
void asCArray<T>::AllocateNoConstruct(asUINT numElements, bool keepData)
|
||||
{
|
||||
// We have 4 situations
|
||||
// 1. The previous array is 8 bytes or smaller and the new array is also 8 bytes or smaller
|
||||
@@ -284,7 +284,7 @@ void asCArray<T>::AllocateNoConstruct(size_t numElements, bool keepData)
|
||||
T *tmp = 0;
|
||||
if( numElements )
|
||||
{
|
||||
if( sizeof(T)*numElements <= 8 )
|
||||
if( sizeof(T)*numElements <= sizeof(buf) )
|
||||
// Use the internal buffer
|
||||
tmp = reinterpret_cast<T*>(buf);
|
||||
else
|
||||
@@ -333,13 +333,13 @@ void asCArray<T>::AllocateNoConstruct(size_t numElements, bool keepData)
|
||||
}
|
||||
|
||||
template <class T>
|
||||
size_t asCArray<T>::GetCapacity() const
|
||||
asUINT asCArray<T>::GetCapacity() const
|
||||
{
|
||||
return maxLength;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool asCArray<T>::SetLength(size_t numElements)
|
||||
bool asCArray<T>::SetLength(asUINT numElements)
|
||||
{
|
||||
if( numElements > maxLength )
|
||||
{
|
||||
@@ -356,7 +356,7 @@ bool asCArray<T>::SetLength(size_t numElements)
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool asCArray<T>::SetLengthNoConstruct(size_t numElements)
|
||||
bool asCArray<T>::SetLengthNoConstruct(asUINT numElements)
|
||||
{
|
||||
if( numElements > maxLength )
|
||||
{
|
||||
@@ -373,7 +373,7 @@ bool asCArray<T>::SetLengthNoConstruct(size_t numElements)
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void asCArray<T>::Copy(const T *data, size_t count)
|
||||
void asCArray<T>::Copy(const T *data, asUINT count)
|
||||
{
|
||||
if( maxLength < count )
|
||||
{
|
||||
@@ -385,7 +385,7 @@ void asCArray<T>::Copy(const T *data, size_t count)
|
||||
}
|
||||
}
|
||||
|
||||
for( size_t n = 0; n < count; n++ )
|
||||
for( asUINT n = 0; n < count; n++ )
|
||||
array[n] = data[n];
|
||||
|
||||
length = count;
|
||||
@@ -403,8 +403,8 @@ template <class T>
|
||||
void asCArray<T>::SwapWith(asCArray<T> &other)
|
||||
{
|
||||
T *tmpArray = array;
|
||||
size_t tmpLength = length;
|
||||
size_t tmpMaxLength = maxLength;
|
||||
asUINT tmpLength = length;
|
||||
asUINT tmpMaxLength = maxLength;
|
||||
char tmpBuf[sizeof(buf)];
|
||||
memcpy(tmpBuf, buf, sizeof(buf));
|
||||
|
||||
@@ -430,7 +430,7 @@ bool asCArray<T>::operator ==(const asCArray<T> &other) const
|
||||
{
|
||||
if( length != other.length ) return false;
|
||||
|
||||
for( size_t n = 0; n < length; n++ )
|
||||
for( asUINT n = 0; n < length; n++ )
|
||||
if( array[n] != other.array[n] )
|
||||
return false;
|
||||
|
||||
@@ -443,16 +443,28 @@ bool asCArray<T>::operator !=(const asCArray<T> &other) const
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
|
||||
// Returns false if the concatenation wasn't successful due to out of memory
|
||||
template <class T>
|
||||
void asCArray<T>::Concatenate(const asCArray<T> &other)
|
||||
bool asCArray<T>::Concatenate(const asCArray<T> &other)
|
||||
{
|
||||
if( maxLength < length + other.length )
|
||||
{
|
||||
Allocate(length + other.length, true);
|
||||
if( maxLength < length + other.length )
|
||||
{
|
||||
// Out of memory
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for( size_t n = 0; n < other.length; n++ )
|
||||
for( asUINT n = 0; n < other.length; n++ )
|
||||
array[length+n] = other.array[n];
|
||||
|
||||
length += other.length;
|
||||
|
||||
// Success
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
@@ -471,18 +483,18 @@ bool asCArray<T>::Exists(const T &e) const
|
||||
template <class T>
|
||||
int asCArray<T>::IndexOf(const T &e) const
|
||||
{
|
||||
for( size_t n = 0; n < length; n++ )
|
||||
for( asUINT n = 0; n < length; n++ )
|
||||
if( array[n] == e ) return static_cast<int>(n);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void asCArray<T>::RemoveIndex(size_t index)
|
||||
void asCArray<T>::RemoveIndex(asUINT index)
|
||||
{
|
||||
if( index < length )
|
||||
{
|
||||
for( size_t n = index; n < length-1; n++ )
|
||||
for( asUINT n = index; n < length-1; n++ )
|
||||
array[n] = array[n+1];
|
||||
|
||||
PopLast();
|
||||
@@ -492,7 +504,7 @@ void asCArray<T>::RemoveIndex(size_t index)
|
||||
template <class T>
|
||||
void asCArray<T>::RemoveValue(const T &e)
|
||||
{
|
||||
for( size_t n = 0; n < length; n++ )
|
||||
for( asUINT n = 0; n < length; n++ )
|
||||
{
|
||||
if( array[n] == e )
|
||||
{
|
||||
@@ -503,7 +515,7 @@ void asCArray<T>::RemoveValue(const T &e)
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void asCArray<T>::RemoveIndexUnordered(size_t index)
|
||||
void asCArray<T>::RemoveIndexUnordered(asUINT index)
|
||||
{
|
||||
if( index == length - 1 )
|
||||
PopLast();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2013 Andreas Jonsson
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -45,21 +45,37 @@ asCAtomic::asCAtomic()
|
||||
|
||||
asDWORD asCAtomic::get() const
|
||||
{
|
||||
// A very high ref count is highly unlikely. It most likely a problem with
|
||||
// memory that has been overwritten or is being accessed after it was deleted.
|
||||
asASSERT(value < 1000000);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void asCAtomic::set(asDWORD val)
|
||||
{
|
||||
// A very high ref count is highly unlikely. It most likely a problem with
|
||||
// memory that has been overwritten or is being accessed after it was deleted.
|
||||
asASSERT(value < 1000000);
|
||||
|
||||
value = val;
|
||||
}
|
||||
|
||||
asDWORD asCAtomic::atomicInc()
|
||||
{
|
||||
// A very high ref count is highly unlikely. It most likely a problem with
|
||||
// memory that has been overwritten or is being accessed after it was deleted.
|
||||
asASSERT(value < 1000000);
|
||||
|
||||
return asAtomicInc((int&)value);
|
||||
}
|
||||
|
||||
asDWORD asCAtomic::atomicDec()
|
||||
{
|
||||
// A very high ref count is highly unlikely. It most likely a problem with
|
||||
// memory that has been overwritten or is being accessed after it was deleted.
|
||||
asASSERT(value < 1000000);
|
||||
|
||||
return asAtomicDec((int&)value);
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
@@ -51,6 +51,11 @@
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
#ifdef AS_NO_COMPILER
|
||||
// Forward declare the structure, as it is part of some function signatures used even without the compiler
|
||||
struct sGlobalVariableDescription;
|
||||
#endif
|
||||
|
||||
#ifndef AS_NO_COMPILER
|
||||
|
||||
struct sFunctionDescription
|
||||
@@ -72,6 +77,7 @@ struct sGlobalVariableDescription
|
||||
asCString name;
|
||||
asCGlobalProperty *property;
|
||||
asCDataType datatype;
|
||||
asSNameSpace *ns;
|
||||
int index;
|
||||
bool isCompiled;
|
||||
bool isPureConstant;
|
||||
@@ -160,14 +166,16 @@ protected:
|
||||
void WriteError(const asCString &scriptname, const asCString &msg, int r, int c);
|
||||
void WriteError(const asCString &msg, asCScriptCode *file, asCScriptNode *node);
|
||||
void WriteWarning(const asCString &scriptname, const asCString &msg, int r, int c);
|
||||
void WriteWarning(const asCString &msg, asCScriptCode *file, asCScriptNode *node);
|
||||
|
||||
bool DoesGlobalPropertyExist(const char *prop, asSNameSpace *ns, asCGlobalProperty **outProp = 0, sGlobalVariableDescription **outDesc = 0, bool *isAppProp = 0);
|
||||
asCGlobalProperty *GetGlobalProperty(const char *prop, asSNameSpace *ns, bool *isCompiled, bool *isPureConstant, asQWORD *constantValue, bool *isAppProp);
|
||||
int ValidateDefaultArgs(asCScriptCode *script, asCScriptNode *node, asCScriptFunction *func);
|
||||
asCString GetCleanExpressionString(asCScriptNode *n, asCScriptCode *file);
|
||||
|
||||
asSNameSpace *GetNameSpaceFromNode(asCScriptNode *node, asCScriptCode *script, asSNameSpace *implicitNs, asCScriptNode **next);
|
||||
asSNameSpace *GetNameSpaceByString(const asCString &nsName, asSNameSpace *implicitNs, asCScriptNode *errNode, asCScriptCode *script);
|
||||
asCString GetScopeFromNode(asCScriptNode *n, asCScriptCode *script, asCScriptNode **next = 0);
|
||||
asSNameSpace *GetParentNameSpace(asSNameSpace *ns);
|
||||
|
||||
asCObjectType *GetObjectType(const char *type, asSNameSpace *ns);
|
||||
asCScriptFunction *GetFuncDef(const char *type);
|
||||
@@ -175,15 +183,6 @@ protected:
|
||||
asCDataType CreateDataTypeFromNode(asCScriptNode *node, asCScriptCode *file, asSNameSpace *implicitNamespace, bool acceptHandleForScope = false, asCObjectType *currentType = 0);
|
||||
asCDataType ModifyDataTypeFromNode(const asCDataType &type, asCScriptNode *node, asCScriptCode *file, asETypeModifiers *inOutFlag, bool *autoHandle);
|
||||
|
||||
struct preMessage_t
|
||||
{
|
||||
bool isSet;
|
||||
asCString message;
|
||||
asCString scriptname;
|
||||
int r;
|
||||
int c;
|
||||
} preMessage;
|
||||
|
||||
int numErrors;
|
||||
int numWarnings;
|
||||
bool silent;
|
||||
@@ -195,6 +194,7 @@ protected:
|
||||
protected:
|
||||
friend class asCCompiler;
|
||||
|
||||
int CheckForConflictsDueToDefaultArgs(asCScriptCode *script, asCScriptNode *node, asCScriptFunction *func, asCObjectType *objType);
|
||||
int GetNamespaceAndNameFromNode(asCScriptNode *n, asCScriptCode *script, asSNameSpace *implicitNs, asSNameSpace *&outNs, asCString &outName);
|
||||
int RegisterMixinClass(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
|
||||
sMixinClass *GetMixinClass(const char *name, asSNameSpace *ns);
|
||||
@@ -204,7 +204,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> ¶meterNames, asCArray<asCDataType> ¶meterTypes, asCArray<asETypeModifiers> &inOutFlags, asCArray<asCString *> &defaultArgs, bool isConstMethod, bool isConstructor, bool isDestructor, bool isPrivate, 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> ¶meterNames, asCArray<asCDataType> ¶meterTypes, asCArray<asETypeModifiers> &inOutFlags, asCArray<asCString *> &defaultArgs, bool isConstMethod, bool isConstructor, bool isDestructor, bool isPrivate, bool isProtected, bool isOverride, bool isFinal, bool isShared);
|
||||
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);
|
||||
@@ -215,11 +215,11 @@ protected:
|
||||
int RegisterFuncDef(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
|
||||
void CompleteFuncDef(sFuncDef *funcDef);
|
||||
void CompileInterfaces();
|
||||
void CompileClasses();
|
||||
void GetParsedFunctionDetails(asCScriptNode *node, asCScriptCode *file, asCObjectType *objType, asCString &name, asCDataType &returnType, asCArray<asCString> ¶meterNames, asCArray<asCDataType> ¶meterTypes, asCArray<asETypeModifiers> &inOutFlags, asCArray<asCString *> &defaultArgs, bool &isConstMethod, bool &isConstructor, bool &isDestructor, bool &isPrivate, bool &isOverride, bool &isFinal, bool &isShared, asSNameSpace *implicitNamespace);
|
||||
void CompileClasses(asUINT originalNumTempl);
|
||||
void GetParsedFunctionDetails(asCScriptNode *node, asCScriptCode *file, asCObjectType *objType, asCString &name, asCDataType &returnType, asCArray<asCString> ¶meterNames, asCArray<asCDataType> ¶meterTypes, asCArray<asETypeModifiers> &inOutFlags, asCArray<asCString *> &defaultArgs, bool &isConstMethod, bool &isConstructor, bool &isDestructor, bool &isPrivate, bool &isProtected, bool &isOverride, bool &isFinal, bool &isShared, 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, asCScriptCode *file = 0, asCScriptNode *node = 0);
|
||||
asCObjectProperty *AddPropertyToClass(sClassDeclaration *c, const asCString &name, const asCDataType &type, bool isPrivate, bool isProtected, bool isInherited, asCScriptCode *file = 0, asCScriptNode *node = 0);
|
||||
int CreateVirtualFunction(asCScriptFunction *func, int idx);
|
||||
void ParseScripts();
|
||||
void RegisterTypesFromScript(asCScriptNode *node, asCScriptCode *script, asSNameSpace *ns);
|
||||
@@ -232,7 +232,8 @@ protected:
|
||||
asCObjectProperty *GetObjectProperty(asCDataType &obj, const char *prop);
|
||||
asCScriptFunction *GetFunctionDescription(int funcId);
|
||||
void GetFunctionDescriptions(const char *name, asCArray<int> &funcs, asSNameSpace *ns);
|
||||
void GetObjectMethodDescriptions(const char *name, asCObjectType *objectType, asCArray<int> &methods, bool objIsConst, const asCString &scope = "");
|
||||
void GetObjectMethodDescriptions(const char *name, asCObjectType *objectType, asCArray<int> &methods, bool objIsConst, const asCString &scope = "", asCScriptNode *errNode = 0, asCScriptCode *script = 0);
|
||||
void EvaluateTemplateInstances(asUINT startIdx, bool keepSilent);
|
||||
|
||||
asCArray<asCScriptCode *> scripts;
|
||||
asCArray<sFunctionDescription *> functions;
|
||||
|
||||
@@ -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
|
||||
@@ -864,7 +864,6 @@ void asCByteCode::OptimizeLocally(const asCArray<int> &tempVariableOffsets)
|
||||
|
||||
instr = GoForward(curr);
|
||||
}
|
||||
|
||||
}
|
||||
else if( currOp == asBC_RDSPtr )
|
||||
{
|
||||
@@ -1553,6 +1552,7 @@ int asCByteCode::GetSize()
|
||||
|
||||
void asCByteCode::AddCode(asCByteCode *bc)
|
||||
{
|
||||
if( bc == this ) return;
|
||||
if( bc->first )
|
||||
{
|
||||
if( first == 0 )
|
||||
@@ -2037,7 +2037,14 @@ void asCByteCode::PostProcess()
|
||||
DeleteInstruction(curr);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef AS_DEBUG
|
||||
// If the stackSize is negative, then there is a problem with the bytecode.
|
||||
// If AS_DEBUG is turned on, this same check is done in DebugOutput.
|
||||
asASSERT( instr->stackSize >= 0 || asBCInfo[instr->op].type == asBCTYPE_INFO );
|
||||
#endif
|
||||
instr = instr->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2079,7 +2086,9 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
|
||||
fprintf(file, "Variables: \n");
|
||||
for( n = 0; n < func->scriptData->variables.GetLength(); n++ )
|
||||
{
|
||||
fprintf(file, " %.3d: %s %s\n", func->scriptData->variables[n]->stackOffset, func->scriptData->variables[n]->type.Format().AddressOf(), func->scriptData->variables[n]->name.AddressOf());
|
||||
int idx = func->scriptData->objVariablePos.IndexOf(func->scriptData->variables[n]->stackOffset);
|
||||
bool isOnHeap = asUINT(idx) < func->scriptData->objVariablesOnHeap ? true : false;
|
||||
fprintf(file, " %.3d: %s%s %s\n", func->scriptData->variables[n]->stackOffset, isOnHeap ? "(heap) " : "", func->scriptData->variables[n]->type.Format(func->nameSpace).AddressOf(), func->scriptData->variables[n]->name.AddressOf());
|
||||
}
|
||||
asUINT offset = 0;
|
||||
if( func->objectType )
|
||||
@@ -2099,7 +2108,11 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
|
||||
}
|
||||
}
|
||||
if( !found )
|
||||
fprintf(file, " %.3d: %s {noname param}\n", offset, func->parameterTypes[n].Format().AddressOf());
|
||||
{
|
||||
int idx = func->scriptData->objVariablePos.IndexOf(offset);
|
||||
bool isOnHeap = asUINT(idx) < func->scriptData->objVariablesOnHeap ? true : false;
|
||||
fprintf(file, " %.3d: %s%s {noname param}\n", offset, isOnHeap ? "(heap) " : "", func->parameterTypes[n].Format(func->nameSpace).AddressOf());
|
||||
}
|
||||
|
||||
offset -= func->parameterTypes[n].GetSizeOnStackDWords();
|
||||
}
|
||||
@@ -2115,10 +2128,20 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
|
||||
}
|
||||
}
|
||||
if( !found )
|
||||
fprintf(file, " %.3d: %s {noname}\n", func->scriptData->objVariablePos[n], func->scriptData->objVariableTypes[n]->name.AddressOf());
|
||||
{
|
||||
if( func->scriptData->objVariableTypes[n] )
|
||||
{
|
||||
int idx = func->scriptData->objVariablePos.IndexOf(func->scriptData->objVariablePos[n]);
|
||||
bool isOnHeap = asUINT(idx) < func->scriptData->objVariablesOnHeap ? true : false;
|
||||
fprintf(file, " %.3d: %s%s {noname}\n", func->scriptData->objVariablePos[n], isOnHeap ? "(heap) " : "", func->scriptData->objVariableTypes[n]->name.AddressOf());
|
||||
}
|
||||
else
|
||||
fprintf(file, " %.3d: null handle {noname}\n", func->scriptData->objVariablePos[n]);
|
||||
}
|
||||
}
|
||||
fprintf(file, "\n\n");
|
||||
|
||||
bool invalidStackSize = false;
|
||||
int pos = 0;
|
||||
asUINT lineIndex = 0;
|
||||
asCByteInstruction *instr = first;
|
||||
@@ -2131,10 +2154,19 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
|
||||
lineIndex += 2;
|
||||
}
|
||||
|
||||
fprintf(file, "%5d ", pos);
|
||||
pos += instr->GetSize();
|
||||
if( instr->GetSize() > 0 )
|
||||
{
|
||||
fprintf(file, "%5d ", pos);
|
||||
pos += instr->GetSize();
|
||||
|
||||
fprintf(file, "%3d %c ", int(instr->stackSize + func->scriptData->variableSpace), instr->marked ? '*' : ' ');
|
||||
fprintf(file, "%3d %c ", int(instr->stackSize + func->scriptData->variableSpace), instr->marked ? '*' : ' ');
|
||||
if( instr->stackSize < 0 )
|
||||
invalidStackSize = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(file, " ");
|
||||
}
|
||||
|
||||
switch( asBCInfo[instr->op].type )
|
||||
{
|
||||
@@ -2182,7 +2214,10 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
|
||||
switch( instr->op )
|
||||
{
|
||||
case asBC_OBJTYPE:
|
||||
fprintf(file, " %-8s 0x%x\n", asBCInfo[instr->op].name, (asUINT)*ARG_DW(instr->arg));
|
||||
{
|
||||
asCObjectType *ot = *(asCObjectType**)ARG_DW(instr->arg);
|
||||
fprintf(file, " %-8s 0x%x (type:%s)\n", asBCInfo[instr->op].name, (asUINT)*ARG_DW(instr->arg), ot->GetName());
|
||||
}
|
||||
break;
|
||||
|
||||
case asBC_PshC4:
|
||||
@@ -2229,6 +2264,16 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
|
||||
break;
|
||||
|
||||
case asBCTYPE_QW_ARG:
|
||||
switch( instr->op )
|
||||
{
|
||||
case asBC_OBJTYPE:
|
||||
{
|
||||
asCObjectType *ot = *(asCObjectType**)ARG_DW(instr->arg);
|
||||
fprintf(file, " %-8s 0x%x (type:%s)\n", asBCInfo[instr->op].name, (asUINT)*ARG_QW(instr->arg), ot->GetName());
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
#ifdef __GNUC__
|
||||
#ifdef _LP64
|
||||
fprintf(file, " %-8s 0x%lx (i:%ld, f:%g)\n", asBCInfo[instr->op].name, *ARG_QW(instr->arg), *((asINT64*) ARG_QW(instr->arg)), *((double*) ARG_QW(instr->arg)));
|
||||
@@ -2238,6 +2283,7 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
|
||||
#else
|
||||
fprintf(file, " %-8s 0x%I64x (i:%I64d, f:%g)\n", asBCInfo[instr->op].name, *ARG_QW(instr->arg), *((asINT64*) ARG_QW(instr->arg)), *((double*) ARG_QW(instr->arg)));
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case asBCTYPE_wW_QW_ARG:
|
||||
@@ -2257,7 +2303,8 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
|
||||
if( instr->op == asBC_ALLOC )
|
||||
{
|
||||
asCObjectType *ot = *(asCObjectType**)ARG_DW(instr->arg);
|
||||
fprintf(file, " %-8s 0x%x, %d (type:%s)\n", asBCInfo[instr->op].name, *(int*)ARG_DW(instr->arg), *(int*)(ARG_DW(instr->arg)+1), ot->GetName());
|
||||
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}");
|
||||
}
|
||||
else
|
||||
fprintf(file, " %-8s %u, %d\n", asBCInfo[instr->op].name, *(int*)ARG_DW(instr->arg), *(int*)(ARG_DW(instr->arg)+1));
|
||||
@@ -2271,14 +2318,15 @@ 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__
|
||||
#ifdef AS_64BIT_PTR
|
||||
fprintf(file, " %-8s 0x%lx, %d (type:%s)\n", asBCInfo[instr->op].name, *(asINT64*)ARG_QW(instr->arg), *(int*)(ARG_DW(instr->arg)+2), ot->GetName());
|
||||
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}");
|
||||
#else
|
||||
fprintf(file, " %-8s 0x%llx, %d (type:%s)\n", asBCInfo[instr->op].name, *(asINT64*)ARG_QW(instr->arg), *(int*)(ARG_DW(instr->arg)+2), ot->GetName());
|
||||
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}");
|
||||
#endif
|
||||
#else
|
||||
fprintf(file, " %-8s 0x%I64x, %d (type:%s)\n", asBCInfo[instr->op].name, *(asINT64*)ARG_QW(instr->arg), *(int*)(ARG_DW(instr->arg)+2), ot->GetName());
|
||||
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}");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@@ -2333,6 +2381,11 @@ void asCByteCode::DebugOutput(const char *name, asCScriptEngine *engine, asCScri
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
|
||||
// If the stackSize is negative then there is something wrong with the
|
||||
// bytecode, i.e. there is a bug in the compiler or in the optimizer. We
|
||||
// only check this here to have the bytecode available on file for verification
|
||||
asASSERT( !invalidStackSize );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -45,6 +45,14 @@
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
// ref: Member Function Pointers and the Fastest Possible C++ Delegates
|
||||
// describes the structure of class method pointers for most compilers
|
||||
// http://www.codeproject.com/Articles/7150/Member-Function-Pointers-and-the-Fastest-Possible
|
||||
|
||||
// ref: The code comments for ItaniumCXXABI::EmitLoadOfMemberFunctionPointer in the LLVM compiler
|
||||
// describes the structure for class method pointers on Itanium and arm64 ABI
|
||||
// http://clang.llvm.org/doxygen/CodeGen_2ItaniumCXXABI_8cpp_source.html#l00937
|
||||
|
||||
int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv, void *objForThiscall, asSSystemFunctionInterface *internal)
|
||||
{
|
||||
memset(internal, 0, sizeof(asSSystemFunctionInterface));
|
||||
@@ -57,9 +65,9 @@ int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv,
|
||||
{
|
||||
if( ptr.flag == 1 && callConv != asCALL_GENERIC )
|
||||
return asWRONG_CALLING_CONV;
|
||||
else if( ptr.flag == 2 && (callConv == asCALL_GENERIC || callConv == asCALL_THISCALL || callConv == asCALL_THISCALL_ASGLOBAL) )
|
||||
else if( ptr.flag == 2 && (callConv == asCALL_GENERIC || callConv == asCALL_THISCALL || callConv == asCALL_THISCALL_ASGLOBAL || callConv == asCALL_THISCALL_OBJFIRST || callConv == asCALL_THISCALL_OBJLAST) )
|
||||
return asWRONG_CALLING_CONV;
|
||||
else if( ptr.flag == 3 && !(callConv == asCALL_THISCALL || callConv == asCALL_THISCALL_ASGLOBAL) )
|
||||
else if( ptr.flag == 3 && !(callConv == asCALL_THISCALL || callConv == asCALL_THISCALL_ASGLOBAL || callConv == asCALL_THISCALL_OBJFIRST || callConv == asCALL_THISCALL_OBJLAST) )
|
||||
return asWRONG_CALLING_CONV;
|
||||
}
|
||||
|
||||
@@ -90,20 +98,44 @@ int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv,
|
||||
if( isMethod )
|
||||
{
|
||||
#ifndef AS_NO_CLASS_METHODS
|
||||
if( base == asCALL_THISCALL )
|
||||
if( base == asCALL_THISCALL || base == asCALL_THISCALL_OBJFIRST || base == asCALL_THISCALL_OBJLAST )
|
||||
{
|
||||
internal->callConv = ICC_THISCALL;
|
||||
internalCallConv thisCallConv;
|
||||
if( base == asCALL_THISCALL )
|
||||
{
|
||||
if( callConv != asCALL_THISCALL_ASGLOBAL && objForThiscall )
|
||||
return asINVALID_ARG;
|
||||
|
||||
thisCallConv = ICC_THISCALL;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
return asNOT_SUPPORTED;
|
||||
#else
|
||||
if( objForThiscall == 0 )
|
||||
return asINVALID_ARG;
|
||||
|
||||
internal->objForThiscall = objForThiscall;
|
||||
if( base == asCALL_THISCALL_OBJFIRST )
|
||||
thisCallConv = ICC_THISCALL_OBJFIRST;
|
||||
else //if( base == asCALL_THISCALL_OBJLAST )
|
||||
thisCallConv = ICC_THISCALL_OBJLAST;
|
||||
#endif
|
||||
}
|
||||
|
||||
internal->callConv = thisCallConv;
|
||||
#ifdef GNU_STYLE_VIRTUAL_METHOD
|
||||
if( (size_t(ptr.ptr.f.func) & 1) )
|
||||
internal->callConv = ICC_VIRTUAL_THISCALL;
|
||||
internal->callConv = (internalCallConv)(thisCallConv + 2);
|
||||
#endif
|
||||
internal->baseOffset = ( int )MULTI_BASE_OFFSET(ptr);
|
||||
#if defined(AS_ARM) && defined(__GNUC__)
|
||||
#if defined(AS_ARM) && (defined(__GNUC__) || defined(AS_PSVITA))
|
||||
// As the least significant bit in func is used to switch to THUMB mode
|
||||
// on ARM processors, the LSB in the __delta variable is used instead of
|
||||
// the one in __pfn on ARM processors.
|
||||
if( (size_t(internal->baseOffset) & 1) )
|
||||
internal->callConv = ICC_VIRTUAL_THISCALL;
|
||||
internal->callConv = (internalCallConv)(thisCallConv + 2);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_VIRTUAL_BASE_OFFSET
|
||||
@@ -135,6 +167,49 @@ int PrepareSystemFunctionGeneric(asCScriptFunction *func, asSSystemFunctionInter
|
||||
// Calculate the size needed for the parameters
|
||||
internal->paramSize = func->GetSpaceNeededForArguments();
|
||||
|
||||
// Prepare the clean up instructions for the function arguments
|
||||
internal->cleanArgs.SetLength(0);
|
||||
int offset = 0;
|
||||
for( asUINT n = 0; n < func->parameterTypes.GetLength(); n++ )
|
||||
{
|
||||
asCDataType &dt = func->parameterTypes[n];
|
||||
|
||||
if( dt.IsObject() && !dt.IsReference() )
|
||||
{
|
||||
asSTypeBehaviour *beh = &dt.GetObjectType()->beh;
|
||||
if( dt.GetObjectType()->flags & asOBJ_REF )
|
||||
{
|
||||
asASSERT( (dt.GetObjectType()->flags & asOBJ_NOCOUNT) || beh->release );
|
||||
if( beh->release )
|
||||
{
|
||||
asSSystemFunctionInterface::SClean clean;
|
||||
clean.op = 0; // call release
|
||||
clean.ot = dt.GetObjectType();
|
||||
clean.off = short(offset);
|
||||
internal->cleanArgs.PushLast(clean);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
asSSystemFunctionInterface::SClean clean;
|
||||
clean.op = 1; // call free
|
||||
clean.ot = dt.GetObjectType();
|
||||
clean.off = short(offset);
|
||||
|
||||
// Call the destructor then free the memory
|
||||
if( beh->destruct )
|
||||
clean.op = 2; // call destruct, then free
|
||||
|
||||
internal->cleanArgs.PushLast(clean);
|
||||
}
|
||||
}
|
||||
|
||||
if( dt.IsObject() && !dt.IsObjectHandle() && !dt.IsReference() )
|
||||
offset += AS_PTR_SIZE;
|
||||
else
|
||||
offset += dt.GetSizeOnStackDWords();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -142,11 +217,14 @@ int PrepareSystemFunctionGeneric(asCScriptFunction *func, asSSystemFunctionInter
|
||||
int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *internal, asCScriptEngine *engine)
|
||||
{
|
||||
#ifdef AS_MAX_PORTABILITY
|
||||
UNUSED_VAR(func);
|
||||
UNUSED_VAR(internal);
|
||||
UNUSED_VAR(engine);
|
||||
|
||||
// This should never happen, as when AS_MAX_PORTABILITY is on, all functions
|
||||
// are asCALL_GENERIC, which are prepared by PrepareSystemFunctionGeneric
|
||||
asASSERT(false);
|
||||
#endif
|
||||
|
||||
#else
|
||||
// References are always returned as primitive data
|
||||
if( func->returnType.IsReference() || func->returnType.IsObjectHandle() )
|
||||
{
|
||||
@@ -162,7 +240,7 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
|
||||
// Only value types can be returned by value
|
||||
asASSERT( objType & asOBJ_VALUE );
|
||||
|
||||
if( !(objType & (asOBJ_APP_CLASS | asOBJ_APP_PRIMITIVE | asOBJ_APP_FLOAT)) )
|
||||
if( !(objType & (asOBJ_APP_CLASS | asOBJ_APP_PRIMITIVE | asOBJ_APP_FLOAT | asOBJ_APP_ARRAY)) )
|
||||
{
|
||||
// If the return is by value then we need to know the true type
|
||||
engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, func->GetDeclarationStr().AddressOf());
|
||||
@@ -172,6 +250,13 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
|
||||
engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
|
||||
engine->ConfigError(asINVALID_CONFIGURATION, 0, 0, 0);
|
||||
}
|
||||
else if( objType & asOBJ_APP_ARRAY )
|
||||
{
|
||||
// Array types are always returned in memory
|
||||
internal->hostReturnInMemory = true;
|
||||
internal->hostReturnSize = sizeof(void*)/4;
|
||||
internal->hostReturnFloat = false;
|
||||
}
|
||||
else if( objType & asOBJ_APP_CLASS )
|
||||
{
|
||||
internal->hostReturnFloat = false;
|
||||
@@ -203,7 +288,13 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
|
||||
|
||||
#ifdef THISCALL_RETURN_SIMPLE_IN_MEMORY
|
||||
if((internal->callConv == ICC_THISCALL ||
|
||||
#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
internal->callConv == ICC_VIRTUAL_THISCALL) &&
|
||||
#else
|
||||
internal->callConv == ICC_VIRTUAL_THISCALL ||
|
||||
internal->callConv == ICC_THISCALL_OBJFIRST ||
|
||||
internal->callConv == ICC_THISCALL_OBJLAST) &&
|
||||
#endif
|
||||
func->returnType.GetSizeInMemoryDWords() >= THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE)
|
||||
{
|
||||
internal->hostReturnInMemory = true;
|
||||
@@ -242,7 +333,7 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
|
||||
engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, func->GetDeclarationStr().AddressOf());
|
||||
|
||||
asCString str;
|
||||
str.Format(TXT_DONT_SUPPORT_RET_TYPE_s_BY_VAL, func->returnType.Format().AddressOf());
|
||||
str.Format(TXT_DONT_SUPPORT_RET_TYPE_s_BY_VAL, func->returnType.Format(func->nameSpace).AddressOf());
|
||||
engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
|
||||
engine->ConfigError(asINVALID_CONFIGURATION, 0, 0, 0);
|
||||
}
|
||||
@@ -313,7 +404,7 @@ 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)) )
|
||||
if( !(func->parameterTypes[n].GetObjectType()->flags & (asOBJ_APP_CLASS | asOBJ_APP_PRIMITIVE | asOBJ_APP_FLOAT | asOBJ_APP_ARRAY)) )
|
||||
{
|
||||
engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, func->GetDeclarationStr().AddressOf());
|
||||
|
||||
@@ -350,29 +441,70 @@ int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *i
|
||||
}
|
||||
}
|
||||
|
||||
// Verify if the function has any registered autohandles
|
||||
internal->hasAutoHandles = false;
|
||||
for( n = 0; n < internal->paramAutoHandles.GetLength(); n++ )
|
||||
// Prepare the clean up instructions for the function arguments
|
||||
internal->cleanArgs.SetLength(0);
|
||||
int offset = 0;
|
||||
for( n = 0; n < func->parameterTypes.GetLength(); n++ )
|
||||
{
|
||||
if( internal->paramAutoHandles[n] )
|
||||
{
|
||||
internal->hasAutoHandles = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
asCDataType &dt = func->parameterTypes[n];
|
||||
|
||||
#if defined(COMPLEX_OBJS_PASSED_BY_REF) || defined(AS_LARGE_OBJS_PASSED_BY_REF)
|
||||
bool needFree = false;
|
||||
#ifdef COMPLEX_OBJS_PASSED_BY_REF
|
||||
if( dt.GetObjectType() && dt.GetObjectType()->flags & COMPLEX_MASK ) needFree = true;
|
||||
#endif
|
||||
#ifdef AS_LARGE_OBJS_PASSED_BY_REF
|
||||
if( dt.GetSizeInMemoryDWords() >= AS_LARGE_OBJ_MIN_SIZE ) needFree = true;
|
||||
#endif
|
||||
if( needFree &&
|
||||
dt.IsObject() &&
|
||||
!dt.IsObjectHandle() &&
|
||||
!dt.IsReference() )
|
||||
{
|
||||
asSSystemFunctionInterface::SClean clean;
|
||||
clean.op = 1; // call free
|
||||
clean.ot = dt.GetObjectType();
|
||||
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;
|
||||
if( beh->destruct )
|
||||
clean.op = 2; // call destruct, then free
|
||||
#endif
|
||||
|
||||
internal->cleanArgs.PushLast(clean);
|
||||
}
|
||||
#endif
|
||||
|
||||
if( n < internal->paramAutoHandles.GetLength() && internal->paramAutoHandles[n] )
|
||||
{
|
||||
asSSystemFunctionInterface::SClean clean;
|
||||
clean.op = 0; // call release
|
||||
clean.ot = dt.GetObjectType();
|
||||
clean.off = short(offset);
|
||||
internal->cleanArgs.PushLast(clean);
|
||||
}
|
||||
|
||||
if( dt.IsObject() && !dt.IsObjectHandle() && !dt.IsReference() )
|
||||
offset += AS_PTR_SIZE;
|
||||
else
|
||||
offset += dt.GetSizeOnStackDWords();
|
||||
}
|
||||
#endif // !defined(AS_MAX_PORTABILITY)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef AS_MAX_PORTABILITY
|
||||
|
||||
int CallSystemFunction(int id, asCContext *context, void *objectPointer)
|
||||
int CallSystemFunction(int id, asCContext *context)
|
||||
{
|
||||
asCScriptEngine *engine = context->m_engine;
|
||||
asSSystemFunctionInterface *sysFunc = engine->scriptFunctions[id]->sysFuncIntf;
|
||||
asCScriptFunction *func = engine->scriptFunctions[id];
|
||||
asSSystemFunctionInterface *sysFunc = func->sysFuncIntf;
|
||||
int callConv = sysFunc->callConv;
|
||||
if( callConv == ICC_GENERIC_FUNC || callConv == ICC_GENERIC_METHOD )
|
||||
return context->CallGeneric(id, objectPointer);
|
||||
return context->CallGeneric(func);
|
||||
|
||||
context->SetInternalException(TXT_INVALID_CALLING_CONVENTION);
|
||||
|
||||
@@ -396,15 +528,15 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
|
||||
// args - This is the function arguments, which are packed as in AngelScript
|
||||
// retPointer - This points to a the memory buffer where the return object is to be placed, if the function returns the value in memory rather than in registers
|
||||
// retQW2 - This output parameter should be used if the function returns a value larger than 64bits in registers
|
||||
// secondObj - This is the object pointer that the proxy method should invoke its method on when the call convention is THISCALL_OBJFIRST/LAST
|
||||
//
|
||||
// Return value:
|
||||
//
|
||||
// The function should return the value that is returned in registers.
|
||||
//
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &retQW2);
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &retQW2, void *secondObj);
|
||||
|
||||
|
||||
int CallSystemFunction(int id, asCContext *context, void *objectPointer)
|
||||
int CallSystemFunction(int id, asCContext *context)
|
||||
{
|
||||
asCScriptEngine *engine = context->m_engine;
|
||||
asCScriptFunction *descr = engine->scriptFunctions[id];
|
||||
@@ -412,26 +544,24 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
|
||||
|
||||
int callConv = sysFunc->callConv;
|
||||
if( callConv == ICC_GENERIC_FUNC || callConv == ICC_GENERIC_METHOD )
|
||||
return context->CallGeneric(id, objectPointer);
|
||||
return context->CallGeneric(descr);
|
||||
|
||||
asQWORD retQW = 0;
|
||||
asQWORD retQW2 = 0;
|
||||
asDWORD *args = context->m_regs.stackPointer;
|
||||
void *retPointer = 0;
|
||||
void *obj = 0;
|
||||
int popSize = sysFunc->paramSize;
|
||||
|
||||
#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
void *obj = 0;
|
||||
void *secondObj = 0;
|
||||
|
||||
if( callConv >= ICC_THISCALL )
|
||||
{
|
||||
if( sysFunc->objForThiscall )
|
||||
{
|
||||
// This class method is being called as if it is a global function
|
||||
obj = sysFunc->objForThiscall;
|
||||
asASSERT( objectPointer == 0 );
|
||||
}
|
||||
else if( objectPointer )
|
||||
{
|
||||
obj = objectPointer;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -447,7 +577,7 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
|
||||
}
|
||||
|
||||
// Add the base offset for multiple inheritance
|
||||
#if defined(__GNUC__) && defined(AS_ARM)
|
||||
#if (defined(__GNUC__) && defined(AS_ARM)) || defined(AS_PSVITA)
|
||||
// On GNUC + ARM the lsb of the offset is used to indicate a virtual function
|
||||
// and the whole offset is thus shifted one bit left to keep the original
|
||||
// offset resolution
|
||||
@@ -460,7 +590,73 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
|
||||
args += AS_PTR_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
#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 )
|
||||
{
|
||||
bool continueCheck = true; // True if need check objectPointer or context stack for object
|
||||
int continueCheckIndex = 0; // Index into objectsPtrs to save the object if continueCheck
|
||||
|
||||
if( callConv >= ICC_THISCALL_OBJLAST )
|
||||
{
|
||||
asASSERT( sysFunc->objForThiscall != 0 );
|
||||
// This class method is being called as object method (sysFunc->objForThiscall must be set).
|
||||
obj = sysFunc->objForThiscall;
|
||||
continueCheckIndex = 1;
|
||||
}
|
||||
else if( sysFunc->objForThiscall )
|
||||
{
|
||||
// This class method is being called as if it is a global function
|
||||
obj = sysFunc->objForThiscall;
|
||||
continueCheck = false;
|
||||
}
|
||||
|
||||
if( continueCheck )
|
||||
{
|
||||
void *tempPtr = 0;
|
||||
|
||||
// The object pointer should be popped from the context stack
|
||||
popSize += AS_PTR_SIZE;
|
||||
|
||||
// Check for null pointer
|
||||
tempPtr = (void*)*(asPWORD*)(args);
|
||||
if( tempPtr == 0 )
|
||||
{
|
||||
context->SetInternalException(TXT_NULL_POINTER_ACCESS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Add the base offset for multiple inheritance
|
||||
#if (defined(__GNUC__) && defined(AS_ARM)) || defined(AS_PSVITA)
|
||||
// On GNUC + ARM the lsb of the offset is used to indicate a virtual function
|
||||
// and the whole offset is thus shifted one bit left to keep the original
|
||||
// offset resolution
|
||||
tempPtr = (void*)(asPWORD(tempPtr) + (sysFunc->baseOffset>>1));
|
||||
#else
|
||||
tempPtr = (void*)(asPWORD(tempPtr) + sysFunc->baseOffset);
|
||||
#endif
|
||||
|
||||
// Skip the object pointer
|
||||
args += AS_PTR_SIZE;
|
||||
|
||||
if( continueCheckIndex )
|
||||
secondObj = tempPtr;
|
||||
else
|
||||
{
|
||||
asASSERT( obj == 0 );
|
||||
obj = tempPtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
|
||||
if( descr->DoesReturnOnStack() )
|
||||
{
|
||||
// Get the address of the location for the return value from the stack
|
||||
@@ -479,8 +675,9 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
|
||||
}
|
||||
|
||||
context->m_callingSystemFunction = descr;
|
||||
bool cppException = false;
|
||||
#ifdef AS_NO_EXCEPTIONS
|
||||
retQW = CallSystemFunctionNative(context, descr, obj, args, sysFunc->hostReturnInMemory ? retPointer : 0, retQW2);
|
||||
retQW = CallSystemFunctionNative(context, descr, obj, args, sysFunc->hostReturnInMemory ? retPointer : 0, retQW2, secondObj);
|
||||
#else
|
||||
// This try/catch block is to catch potential exception that may
|
||||
// be thrown by the registered function. The implementation of the
|
||||
@@ -489,10 +686,12 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
|
||||
// executed in case of an exception.
|
||||
try
|
||||
{
|
||||
retQW = CallSystemFunctionNative(context, descr, obj, args, sysFunc->hostReturnInMemory ? retPointer : 0, retQW2);
|
||||
retQW = CallSystemFunctionNative(context, descr, obj, args, sysFunc->hostReturnInMemory ? retPointer : 0, retQW2, secondObj);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
cppException = true;
|
||||
|
||||
// Convert the exception to a script exception so the VM can
|
||||
// properly report the error to the application and then clean up
|
||||
context->SetException(TXT_EXCEPTION_CAUGHT);
|
||||
@@ -500,51 +699,6 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
|
||||
#endif
|
||||
context->m_callingSystemFunction = 0;
|
||||
|
||||
#if defined(COMPLEX_OBJS_PASSED_BY_REF) || defined(AS_LARGE_OBJS_PASSED_BY_REF)
|
||||
if( sysFunc->takesObjByVal )
|
||||
{
|
||||
// Need to free the complex objects passed by value, but that the
|
||||
// calling convention implicitly passes by reference behind the scene as the
|
||||
// calling function is the owner of that memory.
|
||||
|
||||
// args is pointing to the first real argument as used in CallSystemFunctionNative,
|
||||
// i.e. hidden arguments such as the object pointer and return address have already
|
||||
// been skipped.
|
||||
|
||||
int spos = 0;
|
||||
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
|
||||
{
|
||||
bool needFree = false;
|
||||
asCDataType &dt = descr->parameterTypes[n];
|
||||
#ifdef COMPLEX_OBJS_PASSED_BY_REF
|
||||
if( dt.GetObjectType() && dt.GetObjectType()->flags & COMPLEX_MASK ) needFree = true;
|
||||
#endif
|
||||
#ifdef AS_LARGE_OBJS_PASSED_BY_REF
|
||||
if( dt.GetSizeInMemoryDWords() >= AS_LARGE_OBJ_MIN_SIZE ) needFree = true;
|
||||
#endif
|
||||
if( needFree &&
|
||||
dt.IsObject() &&
|
||||
!dt.IsObjectHandle() &&
|
||||
!dt.IsReference() )
|
||||
{
|
||||
void *obj = (void*)*(asPWORD*)&args[spos];
|
||||
spos += AS_PTR_SIZE;
|
||||
|
||||
#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;
|
||||
if( beh->destruct )
|
||||
engine->CallObjectMethod(obj, beh->destruct);
|
||||
#endif
|
||||
|
||||
engine->CallFree(obj);
|
||||
}
|
||||
else
|
||||
spos += dt.GetSizeOnStackDWords();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Store the returned value in our stack
|
||||
if( descr->returnType.IsObject() && !descr->returnType.IsReference() )
|
||||
{
|
||||
@@ -595,7 +749,7 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
|
||||
}
|
||||
}
|
||||
|
||||
if( context->m_status == asEXECUTION_EXCEPTION )
|
||||
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
|
||||
@@ -663,27 +817,36 @@ int CallSystemFunction(int id, asCContext *context, void *objectPointer)
|
||||
context->m_regs.valueRegister = retQW;
|
||||
}
|
||||
|
||||
// Release autohandles in the arguments
|
||||
if( sysFunc->hasAutoHandles )
|
||||
// Clean up arguments
|
||||
const asUINT cleanCount = sysFunc->cleanArgs.GetLength();
|
||||
if( cleanCount )
|
||||
{
|
||||
args = context->m_regs.stackPointer;
|
||||
if( callConv >= ICC_THISCALL && !objectPointer )
|
||||
if( callConv >= ICC_THISCALL )
|
||||
args += AS_PTR_SIZE;
|
||||
|
||||
int spos = 0;
|
||||
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
|
||||
asSSystemFunctionInterface::SClean *clean = sysFunc->cleanArgs.AddressOf();
|
||||
for( asUINT n = 0; n < cleanCount; n++, clean++ )
|
||||
{
|
||||
if( sysFunc->paramAutoHandles[n] && *(asPWORD*)&args[spos] != 0 )
|
||||
void **addr = (void**)&args[clean->off];
|
||||
if( clean->op == 0 )
|
||||
{
|
||||
// Call the release method on the type
|
||||
engine->CallObjectMethod((void*)*(asPWORD*)&args[spos], descr->parameterTypes[n].GetObjectType()->beh.release);
|
||||
*(asPWORD*)&args[spos] = 0;
|
||||
if( *addr != 0 )
|
||||
{
|
||||
engine->CallObjectMethod(*addr, clean->ot->beh.release);
|
||||
*addr = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
asASSERT( clean->op == 1 || clean->op == 2 );
|
||||
asASSERT( *addr );
|
||||
|
||||
if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
|
||||
spos += AS_PTR_SIZE;
|
||||
else
|
||||
spos += descr->parameterTypes[n].GetSizeOnStackDWords();
|
||||
if( clean->op == 2 )
|
||||
engine->CallObjectMethod(*addr, clean->ot->beh.destruct);
|
||||
|
||||
engine->CallFree(*addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2012 Andreas Jonsson
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -46,6 +46,7 @@ BEGIN_AS_NAMESPACE
|
||||
class asCContext;
|
||||
class asCScriptEngine;
|
||||
class asCScriptFunction;
|
||||
class asCObjectType;
|
||||
struct asSSystemFunctionInterface;
|
||||
|
||||
int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv, void *objForThiscall, asSSystemFunctionInterface *internal);
|
||||
@@ -54,7 +55,7 @@ int PrepareSystemFunctionGeneric(asCScriptFunction *func, asSSystemFunctionInter
|
||||
|
||||
int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *internal, asCScriptEngine *engine);
|
||||
|
||||
int CallSystemFunction(int id, asCContext *context, void *objectPointer);
|
||||
int CallSystemFunction(int id, asCContext *context);
|
||||
|
||||
inline asPWORD FuncPtrToUInt(asFUNCTION_t func)
|
||||
{
|
||||
@@ -83,7 +84,15 @@ enum internalCallConv
|
||||
ICC_CDECL_OBJFIRST,
|
||||
ICC_CDECL_OBJFIRST_RETURNINMEM,
|
||||
ICC_GENERIC_METHOD,
|
||||
ICC_GENERIC_METHOD_RETURNINMEM // never used
|
||||
ICC_GENERIC_METHOD_RETURNINMEM, // never used
|
||||
ICC_THISCALL_OBJLAST,
|
||||
ICC_THISCALL_OBJLAST_RETURNINMEM,
|
||||
ICC_VIRTUAL_THISCALL_OBJLAST,
|
||||
ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM,
|
||||
ICC_THISCALL_OBJFIRST,
|
||||
ICC_THISCALL_OBJFIRST_RETURNINMEM,
|
||||
ICC_VIRTUAL_THISCALL_OBJFIRST,
|
||||
ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM
|
||||
};
|
||||
|
||||
struct asSSystemFunctionInterface
|
||||
@@ -97,11 +106,18 @@ struct asSSystemFunctionInterface
|
||||
int hostReturnSize;
|
||||
int paramSize;
|
||||
bool takesObjByVal;
|
||||
asCArray<bool> paramAutoHandles;
|
||||
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;
|
||||
bool hasAutoHandles;
|
||||
void *objForThiscall;
|
||||
|
||||
struct SClean
|
||||
{
|
||||
asCObjectType *ot; // argument type for clean up
|
||||
short op; // clean up operation: 0 = release, 1 = free, 2 = destruct then free
|
||||
short off; // argument offset on the stack
|
||||
};
|
||||
asCArray<SClean> cleanArgs;
|
||||
|
||||
asSSystemFunctionInterface() {}
|
||||
|
||||
asSSystemFunctionInterface(const asSSystemFunctionInterface &in)
|
||||
@@ -122,8 +138,8 @@ struct asSSystemFunctionInterface
|
||||
takesObjByVal = in.takesObjByVal;
|
||||
paramAutoHandles = in.paramAutoHandles;
|
||||
returnAutoHandle = in.returnAutoHandle;
|
||||
hasAutoHandles = in.hasAutoHandles;
|
||||
objForThiscall = in.objForThiscall;
|
||||
cleanArgs = in.cleanArgs;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2013 Andreas Jonsson
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -37,6 +37,8 @@
|
||||
// Written by Fredrik Ehnbom in June 2009, based on as_callfunc_x86.cpp
|
||||
//
|
||||
// The code was complemented to support Linux with ARM by Carlos Luna in December, 2012.
|
||||
//
|
||||
// Added support for functor methods by Jordi Oliveras Rovira in April, 2014.
|
||||
|
||||
|
||||
// This code has to conform to both AAPCS and the modified ABI for iOS
|
||||
@@ -71,7 +73,7 @@ extern "C" asQWORD armFuncR0R1 (const asDWORD *, int, asFUNCTION_t, asDWORD
|
||||
extern "C" asQWORD armFuncObjLast (const asDWORD *, int, asFUNCTION_t, asDWORD obj);
|
||||
extern "C" asQWORD armFuncR0ObjLast (const asDWORD *, int, asFUNCTION_t, asDWORD r0, asDWORD obj);
|
||||
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void *secondObject)
|
||||
{
|
||||
asCScriptEngine *engine = context->m_engine;
|
||||
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
|
||||
@@ -87,33 +89,45 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
// The return is made in memory
|
||||
callConv++;
|
||||
}
|
||||
bool isThisCallMethod = callConv >= ICC_THISCALL_OBJLAST;
|
||||
|
||||
|
||||
asDWORD paramBuffer[64+2];
|
||||
// Android & Linux needs to align 64bit types on even registers, but this isn't done on iOS or Windows Phone
|
||||
// TODO: optimize runtime: There should be a check for this in PrepareSystemFunction() so this
|
||||
// doesn't have to be done for functions that don't have any 64bit types
|
||||
#if !defined(AS_ANDROID) && !defined(AS_LINUX)
|
||||
if( sysFunc->takesObjByVal )
|
||||
// In cases of thiscall methods, the callstack is configured as a standard thiscall
|
||||
// adding the secondObject as first or last element in callstack
|
||||
if( sysFunc->takesObjByVal || isThisCallMethod )
|
||||
#endif
|
||||
{
|
||||
#if defined(AS_ANDROID) || defined(AS_LINUX)
|
||||
// mask is used as a toggler to skip uneven registers.
|
||||
int mask = 1;
|
||||
|
||||
// Check for object pointer as first argument
|
||||
switch( callConv )
|
||||
if( isThisCallMethod )
|
||||
{
|
||||
case ICC_THISCALL:
|
||||
case ICC_CDECL_OBJFIRST:
|
||||
case ICC_VIRTUAL_THISCALL:
|
||||
case ICC_THISCALL_RETURNINMEM:
|
||||
case ICC_CDECL_OBJFIRST_RETURNINMEM:
|
||||
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
|
||||
mask = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
mask = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check for object pointer as first argument
|
||||
switch( callConv )
|
||||
{
|
||||
case ICC_THISCALL:
|
||||
case ICC_CDECL_OBJFIRST:
|
||||
case ICC_VIRTUAL_THISCALL:
|
||||
case ICC_THISCALL_RETURNINMEM:
|
||||
case ICC_CDECL_OBJFIRST_RETURNINMEM:
|
||||
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
|
||||
mask = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for hidden address in case of return by value
|
||||
if( sysFunc->hostReturnInMemory )
|
||||
mask = !mask;
|
||||
@@ -122,6 +136,14 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
int spos = 0;
|
||||
int dpos = 2;
|
||||
|
||||
if( isThisCallMethod && (callConv >= ICC_THISCALL_OBJFIRST &&
|
||||
callConv <= ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM) )
|
||||
{
|
||||
// Add the object pointer as the first parameter
|
||||
paramBuffer[dpos++] = (asDWORD)secondObject;
|
||||
paramSize++;
|
||||
}
|
||||
|
||||
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
|
||||
{
|
||||
// TODO: runtime optimize: Declare a reference to descr->parameterTypes[n] so the array doesn't have to be access all the time
|
||||
@@ -177,6 +199,15 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
paramSize += descr->parameterTypes[n].GetSizeOnStackDWords();
|
||||
}
|
||||
}
|
||||
|
||||
if( isThisCallMethod && (callConv >= ICC_THISCALL_OBJLAST &&
|
||||
callConv <= ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM) )
|
||||
{
|
||||
// Add the object pointer as the last parameter
|
||||
paramBuffer[dpos++] = (asDWORD)secondObject;
|
||||
paramSize++;
|
||||
}
|
||||
|
||||
// Keep a free location at the beginning
|
||||
args = ¶mBuffer[2];
|
||||
}
|
||||
@@ -193,9 +224,13 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
break;
|
||||
case ICC_THISCALL: // fall through
|
||||
case ICC_CDECL_OBJFIRST:
|
||||
case ICC_THISCALL_OBJFIRST:
|
||||
case ICC_THISCALL_OBJLAST:
|
||||
retQW = armFuncR0(args, paramSize<<2, func, (asDWORD)obj);
|
||||
break;
|
||||
case ICC_THISCALL_RETURNINMEM:
|
||||
case ICC_THISCALL_OBJFIRST_RETURNINMEM:
|
||||
case ICC_THISCALL_OBJLAST_RETURNINMEM:
|
||||
#ifdef __GNUC__
|
||||
// On GNUC the address where the return value will be placed should be put in R0
|
||||
retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
|
||||
@@ -208,11 +243,15 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
|
||||
break;
|
||||
case ICC_VIRTUAL_THISCALL:
|
||||
case ICC_VIRTUAL_THISCALL_OBJFIRST:
|
||||
case ICC_VIRTUAL_THISCALL_OBJLAST:
|
||||
// Get virtual function table from the object pointer
|
||||
vftable = *(asFUNCTION_t**)obj;
|
||||
retQW = armFuncR0(args, paramSize<<2, vftable[FuncPtrToUInt(func)>>2], (asDWORD)obj);
|
||||
break;
|
||||
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
|
||||
case ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM:
|
||||
case ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM:
|
||||
// Get virtual function table from the object pointer
|
||||
vftable = *(asFUNCTION_t**)obj;
|
||||
#ifdef __GNUC__
|
||||
@@ -255,7 +294,7 @@ extern "C" asQWORD armFuncR0R1 (const asDWORD *, int, asFUNCTION_t, asDWORD
|
||||
extern "C" asQWORD armFuncObjLast (const asDWORD *, int, asFUNCTION_t, asDWORD obj);
|
||||
extern "C" asQWORD armFuncR0ObjLast (const asDWORD *, int, asFUNCTION_t, asDWORD r0, asDWORD obj);
|
||||
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void *secondObject)
|
||||
{
|
||||
asCScriptEngine *engine = context->m_engine;
|
||||
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
|
||||
@@ -307,6 +346,8 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
callConv++;
|
||||
}
|
||||
|
||||
bool isThisCallMethod = callConv >= ICC_THISCALL_OBJLAST;
|
||||
|
||||
// Linux needs to align 64bit types on even registers, but this isn't done on iOS or Windows Phone
|
||||
// TODO: optimize runtime: There should be a check for this in PrepareSystemFunction() so this
|
||||
// doesn't have to be done for functions that don't have any 64bit types
|
||||
@@ -314,19 +355,26 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
// mask is used as a toggler to skip uneven registers.
|
||||
int mask = 1;
|
||||
|
||||
// Check for object pointer as first argument
|
||||
switch( callConv )
|
||||
if( isThisCallMethod )
|
||||
{
|
||||
case ICC_THISCALL:
|
||||
case ICC_CDECL_OBJFIRST:
|
||||
case ICC_VIRTUAL_THISCALL:
|
||||
case ICC_THISCALL_RETURNINMEM:
|
||||
case ICC_CDECL_OBJFIRST_RETURNINMEM:
|
||||
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
|
||||
mask = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
mask = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check for object pointer as first argument
|
||||
switch( callConv )
|
||||
{
|
||||
case ICC_THISCALL:
|
||||
case ICC_CDECL_OBJFIRST:
|
||||
case ICC_VIRTUAL_THISCALL:
|
||||
case ICC_THISCALL_RETURNINMEM:
|
||||
case ICC_CDECL_OBJFIRST_RETURNINMEM:
|
||||
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
|
||||
mask = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Check for hidden address in case of return by value
|
||||
if( sysFunc->hostReturnInMemory )
|
||||
@@ -336,10 +384,19 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
int spos = 0;
|
||||
int dpos = 2;
|
||||
|
||||
if( isThisCallMethod && (callConv >= ICC_THISCALL_OBJFIRST &&
|
||||
callConv <= ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM) )
|
||||
{
|
||||
// Add the object pointer as the first parameter
|
||||
paramBuffer[dpos++] = (asDWORD)secondObject;
|
||||
paramSize++;
|
||||
}
|
||||
|
||||
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
|
||||
{
|
||||
// TODO: runtime optimize: Declare a reference to descr->parameterTypes[n] so the array doesn't have to be access all the time
|
||||
if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
|
||||
if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() &&
|
||||
!(descr->parameterTypes[n].GetObjectType()->flags & asOBJ_APP_ARRAY) )
|
||||
{
|
||||
#ifdef COMPLEX_OBJS_PASSED_BY_REF
|
||||
if( descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK )
|
||||
@@ -501,6 +558,21 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
}// else...
|
||||
}// Loop
|
||||
|
||||
if( isThisCallMethod && (callConv >= ICC_THISCALL_OBJLAST &&
|
||||
callConv <= ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM) )
|
||||
{
|
||||
if (paramSize < 4)
|
||||
{
|
||||
paramBuffer[dpos++] = (asDWORD)secondObject;
|
||||
paramSize++;
|
||||
}
|
||||
else
|
||||
{
|
||||
paramBuffer[stackPos++] = (asDWORD)secondObject;
|
||||
stackSize++;
|
||||
}
|
||||
}
|
||||
|
||||
// Keep a free location at the beginning
|
||||
args = ¶mBuffer[2];
|
||||
}
|
||||
@@ -519,9 +591,13 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
break;
|
||||
case ICC_THISCALL: // fall through
|
||||
case ICC_CDECL_OBJFIRST:
|
||||
case ICC_THISCALL_OBJFIRST:
|
||||
case ICC_THISCALL_OBJLAST:
|
||||
retQW = armFuncR0(args, paramSize<<2, func, (asDWORD)obj);
|
||||
break;
|
||||
case ICC_THISCALL_RETURNINMEM:
|
||||
case ICC_THISCALL_OBJFIRST_RETURNINMEM:
|
||||
case ICC_THISCALL_OBJLAST_RETURNINMEM:
|
||||
// On GNUC the address where the return value will be placed should be put in R0
|
||||
retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
|
||||
break;
|
||||
@@ -529,11 +605,15 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
|
||||
break;
|
||||
case ICC_VIRTUAL_THISCALL:
|
||||
case ICC_VIRTUAL_THISCALL_OBJFIRST:
|
||||
case ICC_VIRTUAL_THISCALL_OBJLAST:
|
||||
// Get virtual function table from the object pointer
|
||||
vftable = *(asFUNCTION_t**)obj;
|
||||
retQW = armFuncR0(args, paramSize<<2, vftable[FuncPtrToUInt(func)>>2], (asDWORD)obj);
|
||||
break;
|
||||
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
|
||||
case ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM:
|
||||
case ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM:
|
||||
// Get virtual function table from the object pointer
|
||||
vftable = *(asFUNCTION_t**)obj;
|
||||
// On GNUC the address where the return value will be placed should be put in R0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2013 Andreas Jonsson
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -488,6 +488,7 @@ armFuncR0ObjLast:
|
||||
strge r7, [r6, #8]
|
||||
|
||||
str r5, [r6, #12] /* Put objlast in r6 + 12 */
|
||||
mov r5, #0
|
||||
|
||||
movge r5, #4 /* Set r5 with an offset of #4 if there´s one last arg that couldn´t be placed in r registers */
|
||||
add r5, r5, #4 /* Set r5 with an offset of + #4, so objlast can be loaded into the stack */
|
||||
@@ -687,6 +688,12 @@ nomoreargsarmFuncR0R1:
|
||||
|
||||
pop {r4-r8, r10, r11, pc}
|
||||
|
||||
#endif /* hard float abi */
|
||||
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
/* ref: http://hardened.gentoo.org/gnu-stack.xml */
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* arm */
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
;
|
||||
; AngelCode Scripting Library
|
||||
; Copyright (c) 2003-2013 Andreas Jonsson
|
||||
; Copyright (c) 2003-2014 Andreas Jonsson
|
||||
;
|
||||
; This software is provided 'as-is', without any express or implied
|
||||
; warranty. In no event will the authors be held liable for any
|
||||
@@ -29,7 +29,7 @@
|
||||
;
|
||||
|
||||
|
||||
; Assembly routines for the ARM call convention
|
||||
; Assembly routines for the ARM call convention used for Windows CE
|
||||
; Written by Fredrik Ehnbom in June 2009
|
||||
|
||||
; MSVC currently doesn't support inline assembly for the ARM platform
|
||||
|
||||
@@ -0,0 +1,480 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2013 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
The original version of this library can be located at:
|
||||
http://www.angelcode.com/angelscript/
|
||||
|
||||
Andreas Jonsson
|
||||
andreas@angelcode.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Assembly routines for the Playstation Vita SNC call convention.
|
||||
|
||||
This code was adapted from as_callfunc_arm_gcc (ARM, Linux hard float) by Brandon Bare on October 2014.
|
||||
*/
|
||||
|
||||
#ifdef __psp2__
|
||||
|
||||
.syntax unified
|
||||
.cpu cortex-a9
|
||||
.fpu neon
|
||||
|
||||
.section .text.armCallFunc
|
||||
.balign 2
|
||||
.thumb
|
||||
.thumb_func
|
||||
|
||||
.align 2
|
||||
|
||||
.global armFunc
|
||||
.global armFuncR0
|
||||
.global armFuncR0R1
|
||||
.global armFuncObjLast
|
||||
.global armFuncR0ObjLast
|
||||
|
||||
.type armFunc, %function
|
||||
.type armFuncR0, %function
|
||||
.type armFuncR0R1, %function
|
||||
.type armFuncObjLast, %function
|
||||
.type armFuncR0ObjLast, %function
|
||||
|
||||
/* --------------------------------------------------------------------------------------------*/
|
||||
armFunc:
|
||||
.fnstart
|
||||
|
||||
push {r4-r8, r10, r11, lr} /* sp must be 8-byte alignment for ABI compliance, so the pushed registers must be even */
|
||||
|
||||
mov r6, r0 /* arg table */
|
||||
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
|
||||
mov r4, r2 /* function address */
|
||||
|
||||
/* Load float and double args into d0-d7 and s0-s15 */
|
||||
add r10, r6, #272 /* r10 (r6 + 272) points to the first value for the VFP registers */
|
||||
mov r8, #0
|
||||
vldmia.64 r10, {d0-d7} /* Load contents starting at r10 into registers d0-d7 */
|
||||
|
||||
/* If there are no arguments to set into r0-r3 */
|
||||
/* go check if there are arguments for the stack */
|
||||
beq stackargs
|
||||
|
||||
/* Load the first 4 arguments into r0-r3 */
|
||||
cmp r7, #4
|
||||
|
||||
it ge
|
||||
ldrge r0, [r6]
|
||||
cmp r7, #8
|
||||
|
||||
it ge
|
||||
ldrge r1, [r6, #4]
|
||||
cmp r7, #12
|
||||
|
||||
it ge
|
||||
ldrge r2, [r6, #8]
|
||||
cmp r7, #16
|
||||
|
||||
it ge
|
||||
ldrge r3, [r6, #12]
|
||||
|
||||
stackargs:
|
||||
ldr r5, [r6, #268] /* Load stack size into r5 */
|
||||
movs r7, r5 /* Load stack size into r7, checking for 0 args */
|
||||
|
||||
/* If there are no args for the stack, branch */
|
||||
beq nomoreargs
|
||||
|
||||
/* Load the rest of the arguments onto the stack */
|
||||
/* Ensure 8-byte stack alignment */
|
||||
mov r8, sp
|
||||
sub sp, sp, r7
|
||||
add r6, r6, #16 /* Set r6 to point to the first arg to be placed on the stack */
|
||||
|
||||
sub r12, sp, #8
|
||||
bic r12, r12, #7 /* thumb mode couldn't support "bic sp, sp, #7" instruction */
|
||||
sub r8, r8, r12
|
||||
mov sp, r12 /* copy size != frame size, so store frame start sp, r12(ip) is not callee saved register */
|
||||
|
||||
stackargsloop:
|
||||
ldr r5, [r6], #4
|
||||
subs r7, r7, #4
|
||||
str r5, [sp], #4
|
||||
bne stackargsloop
|
||||
mov sp, r12
|
||||
|
||||
nomoreargs:
|
||||
blx r4
|
||||
add sp, sp, r8
|
||||
vstmia.64 r10, {d0-d7} /* Copy contents of registers d0-d7 to the address stored in r10 */
|
||||
|
||||
pop {r4-r8, r10, r11, pc}
|
||||
|
||||
.fnend
|
||||
|
||||
/* --------------------------------------------------------------------------------------------*/
|
||||
armFuncObjLast:
|
||||
.fnstart
|
||||
|
||||
push {r4-r8, r10, r11, lr} /* We´re storing r11 just to keep the stack aligned to an 8 byte boundary */
|
||||
|
||||
mov r6, r0 /* arg table */
|
||||
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
|
||||
mov r4, r2 /* function address */
|
||||
|
||||
mov r0, r3 /* objlast. might get overwritten */
|
||||
mov r5, #0 /* This will hold an offset of #4 only if objlast couldn´t be placed into an "r" register */
|
||||
|
||||
/* Load float and double args into d0-d7 and s0-s15 (r10 holds pointer to first float value) */
|
||||
add r10, r6, #272 /* r10 (r6 + 272) points to the first value for the VFP registers */
|
||||
mov r8, #0
|
||||
vldmia.64 r10, {d0-d7} /* Load contents starting at r10 into registers d0-d7 */
|
||||
|
||||
/* If there are no arguments to set into r0-r3 */
|
||||
/* go check if there are arguments for the stack */
|
||||
beq stackargsFuncObjLast
|
||||
|
||||
mov r5, r3 /* store objlast in r5 temporarily */
|
||||
|
||||
/* Load the first 4 arguments into r0-r3 */
|
||||
cmp r7, #4
|
||||
|
||||
it ge
|
||||
ldrge r0, [r6]
|
||||
cmp r7, #8
|
||||
|
||||
it ge
|
||||
ldrge r1, [r6,#4]
|
||||
|
||||
it lt
|
||||
movlt r1, r5
|
||||
cmp r7, #12
|
||||
|
||||
it ge
|
||||
ldrge r2, [r6,#8]
|
||||
|
||||
it lt
|
||||
movlt r2, r5
|
||||
cmp r7, #16
|
||||
|
||||
it ge
|
||||
ldrge r3, [r6,#12]
|
||||
|
||||
ittt lt
|
||||
movlt r3, r5
|
||||
movlt r5, #0 /* If objlast got placed into a register, r5 = 0 */
|
||||
blt stackargsFuncObjLast /* If objlast got placed into a register, go to stackargsFuncObjLast */
|
||||
|
||||
str r5, [r6, #12] /* Put objlast in r6 + 12 */
|
||||
mov r5, #4 /* Set r5 with an offset of #4, so objlast can be loaded into the stack */
|
||||
|
||||
stackargsFuncObjLast:
|
||||
ldr r7, [r6, #268] /* Load stack size into r7 */
|
||||
add r7, r7, r5 /* Add the offset placed in r5 (could be #0 or #4) */
|
||||
cmp r7, #0 /* Check for 0 args */
|
||||
|
||||
/* If there are no args for the stack, branch */
|
||||
beq nomoreargsarmFuncObjLast
|
||||
|
||||
/* Load the rest of the arguments onto the stack */
|
||||
/* Ensure 8-byte stack alignment */
|
||||
mov r8, sp
|
||||
sub sp, sp, r7
|
||||
add r6, r6, #16 /* Set r6 to point to the first arg to be placed on the stack */
|
||||
|
||||
sub r12, sp, #8
|
||||
sub r6, r6, r5 /* r6 = r6 - r5 (r5 can be #0 or #4) */
|
||||
bic r12, r12, #7 /* thumb mode couldn't support "bic sp, sp, #7" instruction */
|
||||
sub r8, r8, r12
|
||||
mov sp, r12 /* copy size != frame size, so store frame start sp, r12(ip) is not callee saved register */
|
||||
|
||||
stackargslooparmFuncObjLast:
|
||||
ldr r5, [r6], #4
|
||||
subs r7, r7, #4
|
||||
str r5, [sp], #4
|
||||
bne stackargslooparmFuncObjLast
|
||||
mov sp, r12
|
||||
|
||||
nomoreargsarmFuncObjLast:
|
||||
blx r4
|
||||
add sp, sp, r8
|
||||
vstmia.64 r10, {d0-d7} /* Copy contents of registers d0-d10 to the address stored in r10 */
|
||||
|
||||
pop {r4-r8, r10,r11, pc}
|
||||
|
||||
.fnend
|
||||
|
||||
/* --------------------------------------------------------------------------------------------*/
|
||||
armFuncR0ObjLast:
|
||||
.fnstart
|
||||
|
||||
push {r4-r8, r10, r11, lr}
|
||||
|
||||
ldr r5, [sp,#32] /* objlast to temp reg */
|
||||
|
||||
mov r6, r0 /* arg table */
|
||||
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
|
||||
mov r4, r2 /* function address */
|
||||
|
||||
mov r0, r3 /* r0 explicitly set */
|
||||
mov r1, r5 /* objlast. might get overwritten */
|
||||
mov r5, #0 /* This will hold an offset of #4 or #8 if objlast or one arg couldn´t be placed into an "r" register */
|
||||
|
||||
/* Load float and double args into d0-d7 and s0-s15 (r10 holds pointer to first float value) */
|
||||
add r10, r6, #272 /* r10 (r6 + 272) points to the first value for the VFP registers */
|
||||
mov r8, #0
|
||||
vldmia.64 r10, {d0-d7} /* Load contents starting at r10 into registers d0-d7 */
|
||||
|
||||
/* If there are no arguments to set into r0-r3 */
|
||||
/* go check if there are arguments for the stack */
|
||||
beq stackargsFuncR0ObjLast
|
||||
|
||||
mov r5, r1 /* store objlast in r5 temporarily */
|
||||
|
||||
/* Load the first 3 arguments into r1-r3 */
|
||||
cmp r7, #4
|
||||
|
||||
it ge
|
||||
ldrge r1, [r6]
|
||||
cmp r7, #8
|
||||
|
||||
it ge
|
||||
ldrge r2, [r6,#4]
|
||||
|
||||
it lt
|
||||
movlt r2, r5
|
||||
cmp r7, #12
|
||||
|
||||
it ge
|
||||
ldrge r3, [r6,#8]
|
||||
|
||||
ittt lt
|
||||
movlt r3, r5
|
||||
movlt r5, #0 /* If objlast got placed into a register, r5 = 0 */
|
||||
blt stackargsFuncR0ObjLast /* If objlast got placed into a register, go to stackargsFuncR0ObjLast */
|
||||
|
||||
cmp r7, #16 /* Else if we have one last arg set the offset accordingly and store the arg in the array */
|
||||
|
||||
itt ge
|
||||
ldrge r7, [r6, #12]
|
||||
strge r7, [r6, #8]
|
||||
|
||||
str r5, [r6, #12] /* Put objlast in r6 + 12 */
|
||||
mov r5, #0
|
||||
|
||||
it ge
|
||||
movge r5, #4 /* Set r5 with an offset of #4 if there´s one last arg that couldn´t be placed in r registers */
|
||||
add r5, r5, #4 /* Set r5 with an offset of + #4, so objlast can be loaded into the stack */
|
||||
|
||||
stackargsFuncR0ObjLast:
|
||||
ldr r7, [r6, #268] /* Load stack size into r7 */
|
||||
add r7, r7, r5 /* Add the offset placed in r5 (could be #0 or #4) */
|
||||
cmp r7, #0 /* Check for 0 args */
|
||||
|
||||
/* If there are no args for the stack, branch */
|
||||
beq nomoreargsarmFuncR0ObjLast
|
||||
|
||||
/* Load the rest of the arguments onto the stack */
|
||||
/* Ensure 8-byte stack alignment */
|
||||
mov r8, sp
|
||||
sub sp, sp, r7
|
||||
add r6, r6, #16 /* Set r6 to point to the first arg to be placed on the stack */
|
||||
|
||||
sub r12, sp, #8
|
||||
sub r6, r6, r5 /* r6 = r6 - r5 (r5 can be #0 or #4) */
|
||||
bic r12, r12, #7 /* thumb mode couldn't support "bic sp, sp, #7" instruction */
|
||||
sub r8, r8, r12
|
||||
mov sp, r12 /* copy size != frame size, so store frame start sp, r12(ip) is not callee saved register */
|
||||
|
||||
stackargslooparmFuncR0ObjLast:
|
||||
ldr r5, [r6], #4
|
||||
subs r7, r7, #4
|
||||
str r5, [sp], #4
|
||||
bne stackargslooparmFuncR0ObjLast
|
||||
mov sp, r12
|
||||
|
||||
nomoreargsarmFuncR0ObjLast:
|
||||
blx r4
|
||||
add sp, sp, r8
|
||||
vstmia.64 r10, {d0-d7} /* Copy contents of registers d0-d10 to the address stored in r10 */
|
||||
|
||||
pop {r4-r8, r10, r11, pc}
|
||||
|
||||
.fnend
|
||||
|
||||
/* --------------------------------------------------------------------------------------------*/
|
||||
armFuncR0:
|
||||
.fnstart
|
||||
|
||||
push {r4-r8, r10, r11, lr}
|
||||
|
||||
mov r6, r0 /* arg table */
|
||||
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
|
||||
mov r4, r2 /* function address */
|
||||
mov r11, #0 /* This will hold an offset of #4 only if the last arg that should have been placed into an "r" reg needs to go to the stack */
|
||||
mov r0, r3 /* r0 explicitly set */
|
||||
|
||||
/* Load float and double args into d0-d7 and s0-s15 (r10 holds pointer to first float value) */
|
||||
add r10, r6, #272 /* r10 (r6 + 272) points to the first value for the VFP registers */
|
||||
mov r8, #0
|
||||
vldmia.64 r10, {d0-d7} /* Load contents starting at r10 into registers d0-d7 */
|
||||
|
||||
/* If there are no arguments to set into r0-r3 */
|
||||
/* go check if there are arguments for the stack */
|
||||
beq stackargsarmFuncR0
|
||||
|
||||
/* Load the first 3 arguments into r1-r3 */
|
||||
cmp r7, #4
|
||||
|
||||
it ge
|
||||
ldrge r1, [r6]
|
||||
cmp r7, #8
|
||||
|
||||
it ge
|
||||
ldrge r2, [r6, #4]
|
||||
cmp r7, #12
|
||||
|
||||
it ge
|
||||
ldrge r3, [r6, #8]
|
||||
cmp r7, #16
|
||||
|
||||
it ge
|
||||
movge r11, #4 /* If there is still one arg to be placed, set the offset in r11 to #4 */
|
||||
|
||||
stackargsarmFuncR0:
|
||||
ldr r5, [r6, #268] /* Load stack size into r5 */
|
||||
add r5, r11 /* Add the offset placed in r11 (could be #0 or #4) */
|
||||
movs r7, r5 /* Load stack size into r7, checking for 0 args */
|
||||
|
||||
/* If there are no args for the stack, branch */
|
||||
beq nomoreargsarmFuncR0
|
||||
|
||||
/* Load the rest of the arguments onto the stack */
|
||||
/* Ensure 8-byte stack alignment */
|
||||
mov r8, sp
|
||||
sub sp, sp, r7
|
||||
add r6, r6, #16 /* Set r6 to point to the first arg to be placed on the stack */
|
||||
|
||||
sub r12, sp, #8
|
||||
sub r6, r6, r11 /* r6 = r6 - r11 (r11 can be #0 or #4) */
|
||||
bic r12, r12, #7 /* thumb mode couldn't support "bic sp, sp, #7" instruction */
|
||||
sub r8, r8, r12
|
||||
mov sp, r12 /* copy size != frame size, so store frame start sp, r12(ip) is not callee saved register */
|
||||
|
||||
stackargslooparmFuncR0:
|
||||
ldr r5, [r6], #4
|
||||
subs r7, r7, #4
|
||||
str r5, [sp], #4
|
||||
bne stackargslooparmFuncR0
|
||||
mov sp, r12
|
||||
|
||||
nomoreargsarmFuncR0:
|
||||
blx r4
|
||||
add sp, sp, r8
|
||||
vstmia.64 r10, {d0-d7} /* Copy contents of registers d0-d10 to the address stored in r10 */
|
||||
|
||||
pop {r4-r8, r10, r11, pc}
|
||||
|
||||
.fnend
|
||||
|
||||
/* --------------------------------------------------------------------------------------------*/
|
||||
armFuncR0R1:
|
||||
.fnstart
|
||||
|
||||
push {r4-r8, r10, r11, lr}
|
||||
|
||||
mov r6, r0 /* arg table */
|
||||
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
|
||||
mov r4, r2 /* function address */
|
||||
mov r11, #0 /* This will hold an offset of #4 or #8 only if the last arg (or last 2 args) that should have been placed into "r" regs need to go to the stack */
|
||||
|
||||
mov r0, r3 /* r0 explicitly set */
|
||||
ldr r1, [sp, #32] /* r1 explicitly set too */
|
||||
|
||||
/* Load float and double args into d0-d7 and s0-s15 (r10 holds pointer to first float value) */
|
||||
add r10, r6, #272 /* r10 (r6 + 272) points to the first value for the VFP registers */
|
||||
mov r8, #0
|
||||
vldmia.64 r10, {d0-d7} /* Load contents starting at r10 into registers d0-d7 */
|
||||
|
||||
/* If there are no arguments to set into r2-r3 */
|
||||
/* go check if there are arguments for the stack */
|
||||
beq stackargsarmFuncR0R1
|
||||
|
||||
/* Load the first 2 arguments into r2-r3 */
|
||||
cmp r7, #4
|
||||
|
||||
it ge
|
||||
ldrge r2, [r6]
|
||||
cmp r7, #8
|
||||
|
||||
it ge
|
||||
ldrge r3, [r6, #4]
|
||||
cmp r7, #12
|
||||
|
||||
it ge
|
||||
movge r11, #4 /* If there is a third arg to be placed, set the offset in r11 to #4 */
|
||||
|
||||
cmp r7, #16
|
||||
|
||||
it ge
|
||||
movge r11, #8 /* If there is a fourth arg to be placed, set the offset in r11 to #8 */
|
||||
|
||||
itt lt
|
||||
ldrlt r7, [r6, #8] /* Else copy the third arg to the correct place in the array */
|
||||
strlt r7, [r6, #12]
|
||||
|
||||
stackargsarmFuncR0R1:
|
||||
ldr r5, [r6, #268] /* Load stack size into r5 */
|
||||
add r5, r11 /* Add the offset placed in r11 (could be #0 or #4 or #8) */
|
||||
movs r7, r5 /* Load stack size into r7, checking for 0 args */
|
||||
|
||||
/* If there are no args for the stack, branch */
|
||||
beq nomoreargsarmFuncR0R1
|
||||
|
||||
/* Load the rest of the arguments onto the stack */
|
||||
/* Ensure 8-byte stack alignment */
|
||||
mov r8, sp
|
||||
sub sp, sp, r7
|
||||
add r6, r6, #16 /* Set r6 to point to the first arg to be placed on the stack */
|
||||
|
||||
sub r12, sp, #8
|
||||
sub r6, r6, r11 /* r6 = r6 - r11 (r11 can be #0 or #4 or #8) */
|
||||
bic r12, r12, #7 /* thumb mode couldn't support "bic sp, sp, #7" instruction */
|
||||
sub r8, r8, r12
|
||||
mov sp, r12 /* copy size != frame size, so store frame start sp, r12(ip) is not callee saved register */
|
||||
|
||||
stackargslooparmFuncR0R1:
|
||||
ldr r5, [r6], #4
|
||||
subs r7, r7, #4
|
||||
str r5, [sp], #4
|
||||
bne stackargslooparmFuncR0R1
|
||||
mov sp, r12
|
||||
|
||||
nomoreargsarmFuncR0R1:
|
||||
blx r4
|
||||
add sp, sp, r8
|
||||
vstmia.64 r10, {d0-d7} /* Copy contents of registers d0-d10 to the address stored in r10 */
|
||||
|
||||
pop {r4-r8, r10, r11, pc}
|
||||
|
||||
.fnend
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2013 Andreas Jonsson
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -221,12 +221,14 @@ asQWORD GetReturnedDouble()
|
||||
return d;
|
||||
}
|
||||
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void */*secondObject*/)
|
||||
{
|
||||
asCScriptEngine *engine = context->m_engine;
|
||||
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
|
||||
int callConv = sysFunc->callConv;
|
||||
|
||||
// TODO: Mips does not yet support THISCALL_OBJFIRST/LAST
|
||||
|
||||
asQWORD retQW = 0;
|
||||
|
||||
void *func = (void*)sysFunc->func;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2013 Andreas Jonsson
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -482,8 +482,10 @@ static asQWORD CallThisCallFunction_objLast(const void *obj, const asDWORD* pArg
|
||||
return ppcFunc( ppcArgs, PPC_STACK_SIZE(numTotalArgs), func );
|
||||
}
|
||||
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void */*secondObject*/)
|
||||
{
|
||||
// TODO: PPC does not yet support THISCALL_OBJFIRST/LAST
|
||||
|
||||
// use a working array of types, we'll configure the final one in stackArgs
|
||||
asBYTE argsType[2*AS_PPC_MAX_ARGS + 1 + 1 + 1];
|
||||
memset( argsType, 0, sizeof(argsType));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2013 Andreas Jonsson
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -547,8 +547,10 @@ inline bool IsVariableArgument( asCDataType type )
|
||||
return (type.GetTokenType() == ttQuestion) ? true : false;
|
||||
}
|
||||
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void */*secondObject*/)
|
||||
{
|
||||
// TODO: PPC 64 does not yet support THISCALL_OBJFIRST/LAST
|
||||
|
||||
// use a working array of types, we'll configure the final one in stackArgs
|
||||
asBYTE argsType[AS_PPC_MAX_ARGS + 1 + 1 + 1];
|
||||
memset( argsType, 0, sizeof(argsType));
|
||||
@@ -663,7 +665,8 @@ 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() )
|
||||
if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() &&
|
||||
!(descr->parameterTypes[n].GetObjectType()->flags & asOBJ_APP_ARRAY) )
|
||||
{
|
||||
#ifdef COMPLEX_OBJS_PASSED_BY_REF
|
||||
if( descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK )
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2013 Andreas Jonsson
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -270,8 +270,10 @@ asQWORD GetReturnedDouble()
|
||||
return d;
|
||||
}
|
||||
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void */*secondObject*/)
|
||||
{
|
||||
// TODO: SH4 does not yet support THISCALL_OBJFIRST/LAST
|
||||
|
||||
asCScriptEngine *engine = context->m_engine;
|
||||
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
|
||||
int callConv = sysFunc->callConv;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2013 Andreas Jonsson
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -34,8 +34,14 @@
|
||||
* Author: Ionut "gargltk" Leonte <ileonte@bitdefender.com>
|
||||
*
|
||||
* Initial author: niteice
|
||||
*
|
||||
* Added support for functor methods by Jordi Oliveras Rovira in April, 2014.
|
||||
*/
|
||||
|
||||
// Useful references for the System V AMD64 ABI:
|
||||
// http://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64/
|
||||
// http://math-atlas.sourceforge.net/devel/assembly/abi_sysV_amd64.pdf
|
||||
|
||||
#include "as_config.h"
|
||||
|
||||
#ifndef AS_MAX_PORTABILITY
|
||||
@@ -73,6 +79,8 @@ static asQWORD __attribute__((noinline)) X64_CallFunction(const asQWORD *args, i
|
||||
|
||||
// Backup stack pointer in R15 that is guaranteed to maintain its value over function calls
|
||||
" movq %%rsp, %%r15 \n"
|
||||
// Make sure the stack unwind logic knows we've backed up the stack pointer in register r15
|
||||
" .cfi_def_cfa_register r15 \n"
|
||||
|
||||
// Skip the first 128 bytes on the stack frame, called "red zone",
|
||||
// that might be used by the compiler to store temporary values
|
||||
@@ -124,6 +132,8 @@ static asQWORD __attribute__((noinline)) X64_CallFunction(const asQWORD *args, i
|
||||
|
||||
// Restore stack pointer
|
||||
" mov %%r15, %%rsp \n"
|
||||
// Inform the stack unwind logic that the stack pointer has been restored
|
||||
" .cfi_def_cfa_register rsp \n"
|
||||
|
||||
// Put return value in retQW1 and retQW2, using either RAX:RDX or XMM0:XMM1 depending on type of return value
|
||||
" movl %5, %%ecx \n"
|
||||
@@ -152,7 +162,7 @@ static inline bool IsVariableArgument( asCDataType type )
|
||||
return ( type.GetTokenType() == ttQuestion ) ? true : false;
|
||||
}
|
||||
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &retQW2)
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &retQW2, void *secondObject)
|
||||
{
|
||||
asCScriptEngine *engine = context->m_engine;
|
||||
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
|
||||
@@ -172,8 +182,17 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
callConv++;
|
||||
}
|
||||
|
||||
#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
// Determine the real function pointer in case of virtual method
|
||||
if ( obj && ( callConv == ICC_VIRTUAL_THISCALL || callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM ) )
|
||||
#else
|
||||
if ( obj && ( callConv == ICC_VIRTUAL_THISCALL ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJLAST ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM) )
|
||||
#endif
|
||||
{
|
||||
vftable = *((funcptr_t**)obj);
|
||||
func = vftable[FuncPtrToUInt(asFUNCTION_t(func)) >> 3];
|
||||
@@ -195,6 +214,11 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
|
||||
break;
|
||||
}
|
||||
#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
case ICC_THISCALL_OBJLAST:
|
||||
case ICC_VIRTUAL_THISCALL_OBJLAST:
|
||||
param_post = 2;
|
||||
#endif
|
||||
case ICC_THISCALL:
|
||||
case ICC_VIRTUAL_THISCALL:
|
||||
case ICC_CDECL_OBJFIRST:
|
||||
@@ -206,6 +230,11 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
|
||||
break;
|
||||
}
|
||||
#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
case ICC_THISCALL_OBJLAST_RETURNINMEM:
|
||||
case ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM:
|
||||
param_post = 2;
|
||||
#endif
|
||||
case ICC_THISCALL_RETURNINMEM:
|
||||
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
|
||||
case ICC_CDECL_OBJFIRST_RETURNINMEM:
|
||||
@@ -219,7 +248,33 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
|
||||
break;
|
||||
}
|
||||
case ICC_CDECL_OBJLAST:
|
||||
#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
case ICC_THISCALL_OBJFIRST:
|
||||
case ICC_VIRTUAL_THISCALL_OBJFIRST:
|
||||
{
|
||||
paramBuffer[0] = (asPWORD)obj;
|
||||
paramBuffer[1] = (asPWORD)secondObject;
|
||||
argsType[0] = x64INTARG;
|
||||
argsType[1] = x64INTARG;
|
||||
|
||||
argIndex = 2;
|
||||
break;
|
||||
}
|
||||
case ICC_THISCALL_OBJFIRST_RETURNINMEM:
|
||||
case ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM:
|
||||
{
|
||||
paramBuffer[0] = (asPWORD)retPointer;
|
||||
paramBuffer[1] = (asPWORD)obj;
|
||||
paramBuffer[2] = (asPWORD)secondObject;
|
||||
argsType[0] = x64INTARG;
|
||||
argsType[1] = x64INTARG;
|
||||
argsType[2] = x64INTARG;
|
||||
|
||||
argIndex = 3;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case ICC_CDECL_OBJLAST:
|
||||
param_post = 1;
|
||||
break;
|
||||
case ICC_CDECL_OBJLAST_RETURNINMEM:
|
||||
@@ -337,7 +392,11 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
// For the CDECL_OBJ_LAST calling convention we need to add the object pointer as the last argument
|
||||
if( param_post )
|
||||
{
|
||||
#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
paramBuffer[argIndex] = (asPWORD)obj;
|
||||
#else
|
||||
paramBuffer[argIndex] = (asPWORD)(param_post > 1 ? secondObject : obj);
|
||||
#endif
|
||||
argsType[argIndex] = x64INTARG;
|
||||
argIndex++;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2013 Andreas Jonsson
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -31,6 +31,8 @@
|
||||
//
|
||||
// This code was adapted from as_callfunc_x64_msvc by _Vicious_ on August 20th, 2011.
|
||||
//
|
||||
// Added support for functor methods by Jordi Oliveras Rovira in April, 2014.
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -165,7 +167,7 @@ static asQWORD GetReturnedDouble()
|
||||
return ret;
|
||||
}
|
||||
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void *secondObject)
|
||||
{
|
||||
asCScriptEngine *engine = context->m_engine;
|
||||
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
|
||||
@@ -189,10 +191,16 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
allArgBuffer[paramSize++] = (asQWORD)retPointer;
|
||||
}
|
||||
|
||||
#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
if( callConv == ICC_THISCALL ||
|
||||
callConv == ICC_THISCALL_RETURNINMEM ||
|
||||
callConv == ICC_VIRTUAL_THISCALL ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM )
|
||||
#else
|
||||
// Optimization to avoid check 12 values (all ICC_ that contains THISCALL)
|
||||
if( (callConv >= ICC_THISCALL && callConv <= ICC_VIRTUAL_THISCALL_RETURNINMEM) ||
|
||||
(callConv >= ICC_THISCALL_OBJLAST && callConv <= ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM) )
|
||||
#endif
|
||||
{
|
||||
// Add the object pointer as the first parameter
|
||||
allArgBuffer[paramSize++] = (asQWORD)obj;
|
||||
@@ -204,8 +212,28 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
// Add the object pointer as the first parameter
|
||||
allArgBuffer[paramSize++] = (asQWORD)obj;
|
||||
}
|
||||
#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
else if( callConv == ICC_THISCALL_OBJFIRST ||
|
||||
callConv == ICC_THISCALL_OBJFIRST_RETURNINMEM ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM )
|
||||
{
|
||||
// Add the object pointer as the first parameter
|
||||
allArgBuffer[paramSize++] = (asQWORD)secondObject;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
if( callConv == ICC_VIRTUAL_THISCALL ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM )
|
||||
#else
|
||||
if( callConv == ICC_VIRTUAL_THISCALL ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJLAST ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM )
|
||||
#endif
|
||||
{
|
||||
// Get the true function pointer from the virtual function table
|
||||
vftable = *(void***)obj;
|
||||
@@ -287,6 +315,16 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
// Add the object pointer as the last parameter
|
||||
allArgBuffer[paramSize++] = (asQWORD)obj;
|
||||
}
|
||||
#ifndef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
else if( callConv == ICC_THISCALL_OBJLAST ||
|
||||
callConv == ICC_THISCALL_OBJLAST_RETURNINMEM ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJLAST ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM )
|
||||
{
|
||||
// Add the object pointer as the last parameter
|
||||
allArgBuffer[paramSize++] = (asQWORD)secondObject;
|
||||
}
|
||||
#endif
|
||||
|
||||
retQW = CallX64(allArgBuffer, floatArgBuffer, paramSize*8, (asPWORD)func);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2013 Andreas Jonsson
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -28,6 +28,9 @@
|
||||
andreas@angelcode.com
|
||||
*/
|
||||
|
||||
//
|
||||
// Added support for thiscall methods by Jordi Oliveras Rovira in April, 2014.
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -48,7 +51,7 @@ extern "C" asQWORD CallX64(const asQWORD *args, const asQWORD *floatArgs, int pa
|
||||
extern "C" asDWORD GetReturnedFloat();
|
||||
extern "C" asQWORD GetReturnedDouble();
|
||||
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void *secondObject)
|
||||
{
|
||||
asCScriptEngine *engine = context->m_engine;
|
||||
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
|
||||
@@ -62,10 +65,10 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
asQWORD floatArgBuffer[4];
|
||||
|
||||
int callConv = sysFunc->callConv;
|
||||
if( callConv == ICC_THISCALL ||
|
||||
callConv == ICC_THISCALL_RETURNINMEM ||
|
||||
callConv == ICC_VIRTUAL_THISCALL ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM )
|
||||
|
||||
// Optimization to avoid check 12 values (all ICC_ that contains THISCALL)
|
||||
if( (callConv >= ICC_THISCALL && callConv <= ICC_VIRTUAL_THISCALL_RETURNINMEM) ||
|
||||
(callConv >= ICC_THISCALL_OBJLAST && callConv <= ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM) )
|
||||
{
|
||||
// Add the object pointer as the first parameter
|
||||
allArgBuffer[paramSize++] = (asQWORD)obj;
|
||||
@@ -86,9 +89,21 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
// Add the object pointer as the first parameter
|
||||
allArgBuffer[paramSize++] = (asQWORD)obj;
|
||||
}
|
||||
else if( callConv == ICC_THISCALL_OBJFIRST ||
|
||||
callConv == ICC_THISCALL_OBJFIRST_RETURNINMEM ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM )
|
||||
{
|
||||
// Add the object pointer as the first parameter
|
||||
allArgBuffer[paramSize++] = (asQWORD)secondObject;
|
||||
}
|
||||
|
||||
if( callConv == ICC_VIRTUAL_THISCALL ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM )
|
||||
callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJLAST ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM )
|
||||
{
|
||||
// Get the true function pointer from the virtual function table
|
||||
vftable = *(void***)obj;
|
||||
@@ -100,10 +115,11 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
asUINT spos = 0;
|
||||
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
|
||||
{
|
||||
if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
|
||||
asCDataType &dt = descr->parameterTypes[n];
|
||||
if( dt.IsObject() && !dt.IsObjectHandle() && !dt.IsReference() )
|
||||
{
|
||||
if( descr->parameterTypes[n].GetSizeInMemoryDWords() >= AS_LARGE_OBJ_MIN_SIZE ||
|
||||
(descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK) )
|
||||
if( dt.GetSizeInMemoryDWords() >= AS_LARGE_OBJ_MIN_SIZE ||
|
||||
(dt.GetObjectType()->flags & COMPLEX_MASK) )
|
||||
{
|
||||
allArgBuffer[dpos++] = *(asQWORD*)&args[spos];
|
||||
spos += AS_PTR_SIZE;
|
||||
@@ -112,18 +128,18 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
else
|
||||
{
|
||||
// Copy the object's memory to the buffer
|
||||
memcpy(&allArgBuffer[dpos], *(void**)(args+spos), descr->parameterTypes[n].GetSizeInMemoryBytes());
|
||||
memcpy(&allArgBuffer[dpos], *(void**)(args+spos), dt.GetSizeInMemoryBytes());
|
||||
|
||||
// Delete the original memory
|
||||
engine->CallFree(*(char**)(args+spos));
|
||||
spos += AS_PTR_SIZE;
|
||||
asUINT dwords = descr->parameterTypes[n].GetSizeInMemoryDWords();
|
||||
asUINT dwords = dt.GetSizeInMemoryDWords();
|
||||
asUINT qwords = (dwords >> 1) + (dwords & 1);
|
||||
dpos += qwords;
|
||||
paramSize += qwords;
|
||||
}
|
||||
}
|
||||
else if( descr->parameterTypes[n].GetTokenType() == ttQuestion )
|
||||
else if( dt.GetTokenType() == ttQuestion )
|
||||
{
|
||||
// Copy the reference and the type id
|
||||
allArgBuffer[dpos++] = *(asQWORD*)&args[spos];
|
||||
@@ -134,14 +150,14 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
else
|
||||
{
|
||||
// Copy the value directly
|
||||
asUINT dwords = descr->parameterTypes[n].GetSizeOnStackDWords();
|
||||
asUINT dwords = dt.GetSizeOnStackDWords();
|
||||
if( dwords > 1 )
|
||||
{
|
||||
allArgBuffer[dpos] = *(asQWORD*)&args[spos];
|
||||
|
||||
// Double arguments are moved to a separate buffer in order to be placed in the XMM registers,
|
||||
// though this is only done for first 4 arguments, the rest are placed on the stack
|
||||
if( paramSize < 4 && descr->parameterTypes[n].IsDoubleType() )
|
||||
if( paramSize < 4 && dt.IsDoubleType() )
|
||||
floatArgBuffer[dpos] = *(asQWORD*)&args[spos];
|
||||
|
||||
dpos++;
|
||||
@@ -153,7 +169,7 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
|
||||
// Float arguments are moved to a separate buffer in order to be placed in the XMM registers,
|
||||
// though this is only done for first 4 arguments, the rest are placed on the stack
|
||||
if( paramSize < 4 && descr->parameterTypes[n].IsFloatType() )
|
||||
if( paramSize < 4 && dt.IsFloatType() )
|
||||
floatArgBuffer[dpos] = args[spos];
|
||||
|
||||
dpos++;
|
||||
@@ -170,6 +186,14 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
// Add the object pointer as the last parameter
|
||||
allArgBuffer[paramSize++] = (asQWORD)obj;
|
||||
}
|
||||
else if( callConv == ICC_THISCALL_OBJLAST ||
|
||||
callConv == ICC_THISCALL_OBJLAST_RETURNINMEM ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJLAST ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM )
|
||||
{
|
||||
// Add the object pointer as the last parameter
|
||||
allArgBuffer[paramSize++] = (asQWORD)secondObject;
|
||||
}
|
||||
|
||||
retQW = CallX64(allArgBuffer, floatArgBuffer, paramSize*8, (asPWORD)func);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2013 Andreas Jonsson
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -34,6 +34,8 @@
|
||||
//
|
||||
// These functions handle the actual calling of system functions
|
||||
//
|
||||
// Added support for functor methods by Jordi Oliveras Rovira in April, 2014.
|
||||
//
|
||||
|
||||
|
||||
|
||||
@@ -87,7 +89,7 @@ asQWORD CallThisCallFunctionRetByRef(const void *, const asDWORD *, int, asFUNCT
|
||||
asDWORD GetReturnedFloat();
|
||||
asQWORD GetReturnedDouble();
|
||||
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void *secondObject)
|
||||
{
|
||||
asCScriptEngine *engine = context->m_engine;
|
||||
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
|
||||
@@ -95,13 +97,30 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
asQWORD retQW = 0;
|
||||
|
||||
// Prepare the parameters
|
||||
int paramSize = sysFunc->paramSize;
|
||||
asDWORD paramBuffer[64];
|
||||
if( sysFunc->takesObjByVal )
|
||||
int callConv = sysFunc->callConv;
|
||||
|
||||
// Changed because need check for ICC_THISCALL_OBJFIRST or
|
||||
// ICC_THISCALL_OBJLAST if sysFunc->takesObjByVal (avoid copy code)
|
||||
// Check if is THISCALL_OBJ* calling convention (in this case needs to add secondObject pointer into stack).
|
||||
bool isThisCallMethod = callConv >= ICC_THISCALL_OBJLAST;
|
||||
int paramSize = isThisCallMethod || sysFunc->takesObjByVal ? 0 : sysFunc->paramSize;
|
||||
|
||||
int dpos = 1;
|
||||
|
||||
if( isThisCallMethod &&
|
||||
(callConv >= ICC_THISCALL_OBJFIRST &&
|
||||
callConv <= ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM) )
|
||||
{
|
||||
// Add the object pointer as the first parameter
|
||||
paramBuffer[dpos++] = (asDWORD)secondObject;
|
||||
paramSize++;
|
||||
}
|
||||
|
||||
if( sysFunc->takesObjByVal || isThisCallMethod )
|
||||
{
|
||||
paramSize = 0;
|
||||
int spos = 0;
|
||||
int dpos = 1;
|
||||
|
||||
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
|
||||
{
|
||||
if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
|
||||
@@ -146,9 +165,17 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
args = ¶mBuffer[1];
|
||||
}
|
||||
|
||||
if( isThisCallMethod &&
|
||||
(callConv >= ICC_THISCALL_OBJLAST &&
|
||||
callConv <= ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM) )
|
||||
{
|
||||
// Add the object pointer as the last parameter
|
||||
paramBuffer[dpos++] = (asDWORD)secondObject;
|
||||
paramSize++;
|
||||
}
|
||||
|
||||
// Make the actual call
|
||||
asFUNCTION_t func = sysFunc->func;
|
||||
int callConv = sysFunc->callConv;
|
||||
if( sysFunc->hostReturnInMemory )
|
||||
callConv++;
|
||||
|
||||
@@ -176,14 +203,20 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
break;
|
||||
|
||||
case ICC_THISCALL:
|
||||
case ICC_THISCALL_OBJFIRST:
|
||||
case ICC_THISCALL_OBJLAST:
|
||||
retQW = CallThisCallFunction(obj, args, paramSize<<2, func);
|
||||
break;
|
||||
|
||||
case ICC_THISCALL_RETURNINMEM:
|
||||
case ICC_THISCALL_OBJFIRST_RETURNINMEM:
|
||||
case ICC_THISCALL_OBJLAST_RETURNINMEM:
|
||||
retQW = CallThisCallFunctionRetByRef(obj, args, paramSize<<2, func, retPointer);
|
||||
break;
|
||||
|
||||
case ICC_VIRTUAL_THISCALL:
|
||||
case ICC_VIRTUAL_THISCALL_OBJFIRST:
|
||||
case ICC_VIRTUAL_THISCALL_OBJLAST:
|
||||
{
|
||||
// Get virtual function table from the object pointer
|
||||
asFUNCTION_t *vftable = *(asFUNCTION_t**)obj;
|
||||
@@ -192,6 +225,8 @@ asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr,
|
||||
break;
|
||||
|
||||
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
|
||||
case ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM:
|
||||
case ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM:
|
||||
{
|
||||
// Get virtual function table from the object pointer
|
||||
asFUNCTION_t *vftable = *(asFUNCTION_t**)obj;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2013 Andreas Jonsson
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -498,8 +498,10 @@ inline bool IsVariableArgument( asCDataType type )
|
||||
return (type.GetTokenType() == ttQuestion) ? true : false;
|
||||
}
|
||||
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/)
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void */*secondObject*/)
|
||||
{
|
||||
// TODO: Xenon does not yet support THISCALL_OBJFIRST/LAST
|
||||
|
||||
asCScriptEngine *engine = context->m_engine;
|
||||
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
|
||||
int callConv = sysFunc->callConv;
|
||||
|
||||
+2466
-1235
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2013 Andreas Jonsson
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -103,6 +103,7 @@ struct asSExprContext
|
||||
property_handle = false;
|
||||
property_ref = false;
|
||||
methodName = "";
|
||||
enumValue = "";
|
||||
}
|
||||
bool IsClassMethod()
|
||||
{
|
||||
@@ -143,6 +144,13 @@ struct asSOverloadCandidate
|
||||
asUINT cost;
|
||||
};
|
||||
|
||||
struct asSNamedArgument
|
||||
{
|
||||
asCString name;
|
||||
asSExprContext *ctx;
|
||||
asUINT match;
|
||||
};
|
||||
|
||||
enum EImplicitConv
|
||||
{
|
||||
asIC_IMPLICIT_CONV,
|
||||
@@ -206,31 +214,34 @@ protected:
|
||||
int CompileFunctionCall(asCScriptNode *node, asSExprContext *out, asCObjectType *objectType, bool objIsConst, const asCString &scope = "");
|
||||
void CompileConstructCall(asCScriptNode *node, asSExprContext *out);
|
||||
void CompileConversion(asCScriptNode *node, asSExprContext *out);
|
||||
int CompileOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out);
|
||||
void CompileOperatorOnHandles(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out);
|
||||
void CompileMathOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out);
|
||||
void CompileBitwiseOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out);
|
||||
void CompileComparisonOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out);
|
||||
void CompileBooleanOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, asSExprContext *out);
|
||||
bool CompileOverloadedDualOperator(asCScriptNode *node, asSExprContext *l, asSExprContext *r, 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));
|
||||
|
||||
void CompileInitList(asCTypeInfo *var, asCScriptNode *node, asCByteCode *bc, int isVarGlobOrMem);
|
||||
int CompileInitListElement(asSListPatternNode *&patternNode, asCScriptNode *&valueNode, int bufferTypeId, short bufferVar, asUINT &bufferSize, asCByteCode &byteCode);
|
||||
int CompileInitListElement(asSListPatternNode *&patternNode, asCScriptNode *&valueNode, int bufferTypeId, short bufferVar, asUINT &bufferSize, asCByteCode &byteCode, int &elementsInSubList);
|
||||
|
||||
int CallDefaultConstructor(asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc, asCScriptNode *node, int isVarGlobOrMem = 0, bool derefDest = false);
|
||||
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);
|
||||
void CallDestructor(asCDataType &type, int offset, bool isObjectOnHeap, asCByteCode *bc);
|
||||
int CompileArgumentList(asCScriptNode *node, asCArray<asSExprContext *> &args);
|
||||
int CompileDefaultArgs(asCScriptNode *node, asCArray<asSExprContext*> &args, asCScriptFunction *func);
|
||||
asUINT MatchFunctions(asCArray<int> &funcs, asCArray<asSExprContext*> &args, asCScriptNode *node, const char *name, asCObjectType *objectType = NULL, bool isConstMethod = false, bool silent = false, bool allowObjectConstruct = true, const asCString &scope = "");
|
||||
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);
|
||||
void CompileMemberInitialization(asCByteCode *bc, bool onlyDefaults);
|
||||
bool CompileInitialization(asCScriptNode *node, asCByteCode *bc, asCDataType &type, asCScriptNode *errNode, int offset, asQWORD *constantValue, int isVarGlobOrMem);
|
||||
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);
|
||||
|
||||
// Helper functions
|
||||
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);
|
||||
@@ -241,16 +252,17 @@ protected:
|
||||
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);
|
||||
void PrepareArgument(asCDataType *paramType, asSExprContext *ctx, asCScriptNode *node, bool isFunction = false, int refType = 0, bool isMakingCopy = false);
|
||||
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, int op, asCScriptNode *opNode);
|
||||
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 FilterConst(asCArray<int> &funcs, bool removeConst = true);
|
||||
@@ -275,6 +287,7 @@ protected:
|
||||
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);
|
||||
|
||||
void LineInstr(asCByteCode *bc, size_t pos);
|
||||
|
||||
@@ -284,7 +297,7 @@ protected:
|
||||
void Error(const asCString &msg, asCScriptNode *node);
|
||||
void Warning(const asCString &msg, asCScriptNode *node);
|
||||
void Information(const asCString &msg, asCScriptNode *node);
|
||||
void PrintMatchingFuncs(asCArray<int> &funcs, asCScriptNode *node);
|
||||
void PrintMatchingFuncs(asCArray<int> &funcs, asCScriptNode *node, asCObjectType *inType = 0);
|
||||
void AddVariableScope(bool isBreakScope = false, bool isContinueScope = false);
|
||||
void RemoveVariableScope();
|
||||
void FinalizeFunction();
|
||||
|
||||
@@ -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
|
||||
@@ -101,6 +101,10 @@
|
||||
// if the new order of the member initialization caused null pointer exceptions in older
|
||||
// scripts (e.g. if a base class accessed members of a derived class through a virtual method).
|
||||
|
||||
// AS_USE_NAMESPACE
|
||||
// Adds the AngelScript namespace on the declarations.
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Library usage
|
||||
@@ -140,12 +144,12 @@
|
||||
// STDCALL
|
||||
// This is used to declare a function to use the stdcall calling convention.
|
||||
|
||||
// AS_USE_NAMESPACE
|
||||
// Adds the AngelScript namespace on the declarations.
|
||||
|
||||
// AS_NO_MEMORY_H
|
||||
// Some compilers don't come with the memory.h header file.
|
||||
|
||||
// AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
// Defined if the support for functor methods hasn't been implemented on the platform.
|
||||
|
||||
|
||||
|
||||
//
|
||||
@@ -166,6 +170,9 @@
|
||||
// Embarcadero C++Builder
|
||||
// __BORLANDC__ is defined
|
||||
|
||||
// Sun CC compiler
|
||||
// __SUNPRO_CC is defined
|
||||
|
||||
|
||||
|
||||
//
|
||||
@@ -213,6 +220,9 @@
|
||||
// AS_BIG_ENDIAN
|
||||
// Define this for CPUs that use big endian memory layout, e.g. PPC
|
||||
|
||||
// AS_SPARC
|
||||
// Define this for SPARC CPU family
|
||||
|
||||
|
||||
|
||||
//
|
||||
@@ -230,6 +240,7 @@
|
||||
// AS_XBOX - Microsoft XBox
|
||||
// AS_XBOX360 - Microsoft XBox 360
|
||||
// AS_PSP - Sony Playstation Portable
|
||||
// AS_PSVITA - Sony Playstation Vita
|
||||
// AS_PS2 - Sony Playstation 2
|
||||
// AS_PS3 - Sony Playstation 3
|
||||
// AS_DC - Sega Dreamcast
|
||||
@@ -241,6 +252,7 @@
|
||||
// AS_HAIKU - Haiku
|
||||
// AS_ILLUMOS - Illumos like (OpenSolaris, OpenIndiana, NCP, etc)
|
||||
// AS_MARMALADE - Marmalade cross platform SDK (a layer on top of the OS)
|
||||
// AS_SUN - Sun UNIX
|
||||
|
||||
|
||||
|
||||
@@ -339,6 +351,9 @@
|
||||
#define THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 0
|
||||
#define THISCALL_CALLEE_POPS_HIDDEN_RETURN_POINTER
|
||||
|
||||
// Not implemented by default. Undefined with tested platforms.
|
||||
#define AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
|
||||
|
||||
// Embarcadero C++Builder
|
||||
#if defined(__BORLANDC__)
|
||||
@@ -437,6 +452,7 @@
|
||||
#define THISCALL_CALLEE_POPS_ARGUMENTS
|
||||
#define STDCALL __stdcall
|
||||
#define AS_SIZEOF_BOOL 1
|
||||
#define COMPLEX_OBJS_PASSED_BY_REF
|
||||
|
||||
#define ASM_INTEL // Intel style for inline assembly on microsoft compilers
|
||||
|
||||
@@ -452,14 +468,18 @@
|
||||
#else
|
||||
#if defined(_XBOX) || (defined(_M_IX86) && !defined(__LP64__))
|
||||
#define AS_X86
|
||||
#ifndef _XBOX
|
||||
// Not tested with xbox (only enabled if is Windows)
|
||||
#undef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
#endif
|
||||
#elif defined(_M_X64)
|
||||
#define AS_X64_MSVC
|
||||
#undef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
#define AS_CALLEE_DESTROY_OBJ_BY_VAL
|
||||
#define AS_LARGE_OBJS_PASSED_BY_REF
|
||||
#define AS_LARGE_OBJ_MIN_SIZE 3
|
||||
#define COMPLEX_OBJS_PASSED_BY_REF
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -468,18 +488,22 @@
|
||||
#define AS_CALLEE_DESTROY_OBJ_BY_VAL
|
||||
#define CDECL_RETURN_SIMPLE_IN_MEMORY
|
||||
#define STDCALL_RETURN_SIMPLE_IN_MEMORY
|
||||
#define COMPLEX_OBJS_PASSED_BY_REF
|
||||
#define COMPLEX_MASK asOBJ_APP_CLASS_ASSIGNMENT
|
||||
#define COMPLEX_RETURN_MASK asOBJ_APP_CLASS_ASSIGNMENT
|
||||
#define AS_SOFTFP
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_ASSIGNMENT | asOBJ_APP_ARRAY)
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_ASSIGNMENT | asOBJ_APP_ARRAY)
|
||||
|
||||
// Windows CE uses softfp calling convention, while Windows RT uses hardfp calling convention
|
||||
// ref: http://stackoverflow.com/questions/16375355/what-is-the-windows-rt-on-arm-native-code-calling-convention
|
||||
#if defined(_WIN32_WCE)
|
||||
#define AS_SOFTFP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef COMPLEX_MASK
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT)
|
||||
#define COMPLEX_MASK (asOBJ_APP_ARRAY)
|
||||
#endif
|
||||
|
||||
#ifndef COMPLEX_RETURN_MASK
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT)
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT | asOBJ_APP_ARRAY)
|
||||
#endif
|
||||
|
||||
#define UNREACHABLE_RETURN
|
||||
@@ -511,13 +535,26 @@
|
||||
|
||||
// SN Systems ProDG
|
||||
#if defined(__SNC__) || defined(SNSYS)
|
||||
#define GNU_STYLE_VIRTUAL_METHOD
|
||||
#define MULTI_BASE_OFFSET(x) (*((asDWORD*)(&x)+1))
|
||||
#define CALLEE_POPS_HIDDEN_RETURN_POINTER
|
||||
#define COMPLEX_OBJS_PASSED_BY_REF
|
||||
#define ASM_AT_N_T // AT&T style inline assembly
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR)
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR)
|
||||
|
||||
#ifdef __psp2__
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
|
||||
#define THISCALL_RETURN_SIMPLE_IN_MEMORY
|
||||
#define CDECL_RETURN_SIMPLE_IN_MEMORY
|
||||
#define STDCALL_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
|
||||
#else
|
||||
#define GNU_STYLE_VIRTUAL_METHOD
|
||||
#define ASM_AT_N_T // AT&T style inline assembly
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR)
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR)
|
||||
#endif
|
||||
|
||||
#define AS_SIZEOF_BOOL 1
|
||||
#define asVSNPRINTF(a, b, c, d) vsnprintf(a, b, c, d)
|
||||
|
||||
@@ -541,11 +578,22 @@
|
||||
// Support native calling conventions on PS3
|
||||
#define AS_PS3
|
||||
#define AS_PPC_64
|
||||
#define AS_NO_MEMORY_H
|
||||
#define AS_NO_EXCEPTIONS
|
||||
#include <stdlib.h>
|
||||
// PSP
|
||||
#elif defined(__psp__)
|
||||
#define AS_NO_MEMORY_H
|
||||
#define AS_MIPS
|
||||
#define AS_PSP
|
||||
// PSVita
|
||||
#elif defined(__psp2__)
|
||||
#define AS_PSVITA
|
||||
#define AS_ARM
|
||||
#define AS_NO_MEMORY_H
|
||||
#define AS_NO_EXCEPTIONS
|
||||
#define AS_CALLEE_DESTROY_OBJ_BY_VAL
|
||||
#undef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
#endif
|
||||
|
||||
#define UNREACHABLE_RETURN
|
||||
@@ -555,16 +603,12 @@
|
||||
// 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
|
||||
#define GNU_STYLE_VIRTUAL_METHOD
|
||||
#if !defined( __amd64__ )
|
||||
#define MULTI_BASE_OFFSET(x) (*((asDWORD*)(&x)+1))
|
||||
#else
|
||||
#define MULTI_BASE_OFFSET(x) (*((asQWORD*)(&x)+1))
|
||||
#endif
|
||||
#define MULTI_BASE_OFFSET(x) (*((asPWORD*)(&x)+1))
|
||||
#define asVSNPRINTF(a, b, c, d) vsnprintf(a, b, c, d)
|
||||
#define CALLEE_POPS_HIDDEN_RETURN_POINTER
|
||||
#define COMPLEX_OBJS_PASSED_BY_REF
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR)
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR)
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_ARRAY)
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_ARRAY)
|
||||
#define AS_NO_MEMORY_H
|
||||
#define AS_SIZEOF_BOOL 1
|
||||
#define STDCALL __attribute__((stdcall))
|
||||
@@ -618,9 +662,9 @@
|
||||
#undef GNU_STYLE_VIRTUAL_METHOD
|
||||
|
||||
#undef COMPLEX_MASK
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||
#undef COMPLEX_RETURN_MASK
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||
|
||||
#define AS_CALLEE_DESTROY_OBJ_BY_VAL
|
||||
#endif
|
||||
@@ -651,6 +695,7 @@
|
||||
#if (defined(_ARM_) || defined(__arm__))
|
||||
// iOS use ARM processor
|
||||
#define AS_ARM
|
||||
#undef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
#define CDECL_RETURN_SIMPLE_IN_MEMORY
|
||||
#define STDCALL_RETURN_SIMPLE_IN_MEMORY
|
||||
#define THISCALL_RETURN_SIMPLE_IN_MEMORY
|
||||
@@ -666,9 +711,9 @@
|
||||
#define STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
|
||||
#define COMPLEX_OBJS_PASSED_BY_REF
|
||||
#undef COMPLEX_MASK
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||
#undef COMPLEX_RETURN_MASK
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||
|
||||
// iOS uses soft-float ABI
|
||||
#define AS_SOFTFP
|
||||
@@ -679,8 +724,8 @@
|
||||
|
||||
#elif (defined(__arm64__))
|
||||
// The IPhone 5S+ uses an ARM64 processor
|
||||
|
||||
// AngelScript currently doesn't support native calling
|
||||
|
||||
// AngelScript currently doesn't support native calling
|
||||
// for 64bit ARM processors so it's necessary to turn on
|
||||
// portability mode
|
||||
#define AS_MAX_PORTABILITY
|
||||
@@ -692,21 +737,23 @@
|
||||
#elif (defined(i386) || defined(__i386) || defined(__i386__)) && !defined(__LP64__)
|
||||
// Support native calling conventions on Mac OS X + Intel 32bit CPU
|
||||
#define AS_X86
|
||||
#undef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
|
||||
#undef COMPLEX_MASK
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||
#undef COMPLEX_RETURN_MASK
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||
|
||||
#elif defined(__LP64__) && !defined(__ppc__) && !defined(__PPC__) && !defined(__arm64__)
|
||||
// http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/LowLevelABI/140-x86-64_Function_Calling_Conventions/x86_64.html#//apple_ref/doc/uid/TP40005035-SW1
|
||||
#define AS_X64_GCC
|
||||
#undef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
#define HAS_128_BIT_PRIMITIVES
|
||||
#define SPLIT_OBJS_BY_MEMBER_TYPES
|
||||
#undef COMPLEX_MASK
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||
#undef COMPLEX_RETURN_MASK
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||
#define AS_LARGE_OBJS_PASSED_BY_REF
|
||||
#define AS_LARGE_OBJ_MIN_SIZE 5
|
||||
// STDCALL is not available on 64bit Mac
|
||||
@@ -720,9 +767,9 @@
|
||||
#define CDECL_RETURN_SIMPLE_IN_MEMORY
|
||||
#define STDCALL_RETURN_SIMPLE_IN_MEMORY
|
||||
#undef COMPLEX_MASK
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||
#undef COMPLEX_RETURN_MASK
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||
|
||||
#elif (defined(__ppc__) || defined(__PPC__)) && defined(__LP64__)
|
||||
#define AS_PPC_64
|
||||
@@ -740,13 +787,14 @@
|
||||
//#define STDCALL_RETURN_SIMPLE_IN_MEMORY
|
||||
|
||||
#undef COMPLEX_MASK
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||
#undef COMPLEX_RETURN_MASK
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
|
||||
#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__)
|
||||
// Support native calling conventions on Intel 32bit CPU
|
||||
#define AS_X86
|
||||
#undef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
|
||||
// As of version 4.7 MinGW changed the ABI, presumably
|
||||
// to be better aligned with how MSVC works
|
||||
@@ -760,6 +808,7 @@
|
||||
|
||||
#elif defined(__x86_64__)
|
||||
#define AS_X64_MINGW
|
||||
#undef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
#define AS_LARGE_OBJS_PASSED_BY_REF
|
||||
#define AS_LARGE_OBJ_MIN_SIZE 3
|
||||
#define COMPLEX_OBJS_PASSED_BY_REF
|
||||
@@ -773,9 +822,9 @@
|
||||
#elif defined(__linux__) && !defined(ANDROID) && !defined(__ANDROID__)
|
||||
|
||||
#undef COMPLEX_MASK
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||
#undef COMPLEX_RETURN_MASK
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
|
||||
#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__)
|
||||
#define THISCALL_RETURN_SIMPLE_IN_MEMORY
|
||||
@@ -785,8 +834,10 @@
|
||||
// Support native calling conventions on Intel 32bit CPU
|
||||
#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
|
||||
#define AS_X86
|
||||
#undef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
#elif defined(__LP64__) && !defined(__arm64__)
|
||||
#define AS_X64_GCC
|
||||
#undef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
#define HAS_128_BIT_PRIMITIVES
|
||||
#define SPLIT_OBJS_BY_MEMBER_TYPES
|
||||
#define AS_LARGE_OBJS_PASSED_BY_REF
|
||||
@@ -797,6 +848,9 @@
|
||||
#elif defined(__ARMEL__) || defined(__arm__)
|
||||
#define AS_ARM
|
||||
|
||||
// TODO: The stack unwind on exceptions currently fails due to the assembler code in as_callfunc_arm_gcc.S
|
||||
#define AS_NO_EXCEPTIONS
|
||||
|
||||
#undef STDCALL
|
||||
#define STDCALL
|
||||
|
||||
@@ -822,9 +876,12 @@
|
||||
// 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
|
||||
#define AS_SOFTFP
|
||||
#endif
|
||||
|
||||
// Tested with both hard float and soft float abi
|
||||
#undef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
|
||||
#elif defined(__mips__)
|
||||
#define AS_MIPS
|
||||
#define AS_BIG_ENDIAN
|
||||
@@ -848,9 +905,9 @@
|
||||
#define AS_BSD
|
||||
#if (defined(i386) || defined(__i386) || defined(__i386__)) && !defined(__LP64__)
|
||||
#undef COMPLEX_MASK
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||
#undef COMPLEX_RETURN_MASK
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||
#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
|
||||
#define AS_X86
|
||||
#elif defined(__LP64__)
|
||||
@@ -858,9 +915,9 @@
|
||||
#define HAS_128_BIT_PRIMITIVES
|
||||
#define SPLIT_OBJS_BY_MEMBER_TYPES
|
||||
#undef COMPLEX_MASK
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||
#undef COMPLEX_RETURN_MASK
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||
#define AS_LARGE_OBJS_PASSED_BY_REF
|
||||
#define AS_LARGE_OBJ_MIN_SIZE 5
|
||||
#undef STDCALL
|
||||
@@ -915,36 +972,47 @@
|
||||
#elif defined(ANDROID) || defined(__ANDROID__)
|
||||
#define AS_ANDROID
|
||||
|
||||
// Android NDK 9+ supports posix threads
|
||||
// Android 2.3+ supports posix threads
|
||||
#define AS_POSIX_THREADS
|
||||
|
||||
// Common configuration with Android arm and x86
|
||||
#define CDECL_RETURN_SIMPLE_IN_MEMORY
|
||||
#define STDCALL_RETURN_SIMPLE_IN_MEMORY
|
||||
#define THISCALL_RETURN_SIMPLE_IN_MEMORY
|
||||
|
||||
#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 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 COMPLEX_MASK
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||
#undef COMPLEX_RETURN_MASK
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||
|
||||
#if (defined(_ARM_) || defined(__arm__))
|
||||
// Android ARM
|
||||
|
||||
#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 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
|
||||
|
||||
// The stdcall calling convention is not used on the arm cpu
|
||||
#undef STDCALL
|
||||
#define STDCALL
|
||||
|
||||
#undef GNU_STYLE_VIRTUAL_METHOD
|
||||
|
||||
#undef COMPLEX_MASK
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
|
||||
#undef COMPLEX_RETURN_MASK
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
|
||||
|
||||
#define AS_ARM
|
||||
#undef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
#define AS_SOFTFP
|
||||
#define AS_CALLEE_DESTROY_OBJ_BY_VAL
|
||||
#elif (defined(i386) || defined(__i386) || defined(__i386__)) && !defined(__LP64__)
|
||||
// Android Intel x86 (same config as Linux x86). Tested with Intel x86 Atom System Image.
|
||||
|
||||
// Support native calling conventions on Intel 32bit CPU
|
||||
#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
|
||||
#define AS_X86
|
||||
#undef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
#endif
|
||||
|
||||
// Haiku OS
|
||||
@@ -1001,6 +1069,39 @@
|
||||
#define UNREACHABLE_RETURN
|
||||
#endif
|
||||
|
||||
// Sun CC
|
||||
// Initial information provided by Andrey Bergman
|
||||
#if defined(__SUNPRO_CC)
|
||||
#if defined(__sparc)
|
||||
#define AS_SPARC
|
||||
#endif
|
||||
|
||||
#if defined(__sun)
|
||||
#define AS_SUN
|
||||
#endif
|
||||
|
||||
// Native calling conventions is not yet supported for Sun CC
|
||||
#if !defined(AS_MAX_PORTABILITY)
|
||||
#define AS_MAX_PORTABILITY
|
||||
#endif
|
||||
|
||||
// I presume Sun CC uses a similar structure of method pointers as gnuc
|
||||
#define MULTI_BASE_OFFSET(x) (*((asPWORD*)(&x)+1))
|
||||
|
||||
#if !defined(AS_SIZEOF_BOOL)
|
||||
#define AS_SIZEOF_BOOL 1 // sizeof(bool) == 1
|
||||
#endif
|
||||
#if !defined(UNREACHABLE_RETURN)
|
||||
#define UNREACHABLE_RETURN
|
||||
#endif
|
||||
#if !defined(STDCALL)
|
||||
#define STDCALL // There is no stdcall on Solaris/SunPro/SPARC
|
||||
#endif
|
||||
#if !defined(asVSNPRINTF)
|
||||
#define asVSNPRINTF(a, b, c, d) vsnprintf(a, b, c, d)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// Detect target hardware
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2013 Andreas Jonsson
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -88,10 +88,29 @@ void asCConfigGroup::RefConfigGroup(asCConfigGroup *group)
|
||||
group->AddRef();
|
||||
}
|
||||
|
||||
void asCConfigGroup::AddReferencesForFunc(asCScriptEngine *engine, asCScriptFunction *func)
|
||||
{
|
||||
AddReferencesForType(engine, func->returnType.GetObjectType());
|
||||
for( asUINT n = 0; n < func->parameterTypes.GetLength(); n++ )
|
||||
AddReferencesForType(engine, func->parameterTypes[n].GetObjectType());
|
||||
}
|
||||
|
||||
void asCConfigGroup::AddReferencesForType(asCScriptEngine *engine, asCObjectType *type)
|
||||
{
|
||||
if( type == 0 ) return;
|
||||
|
||||
// Keep reference to other groups
|
||||
RefConfigGroup(engine->FindConfigGroupForObjectType(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);
|
||||
}
|
||||
|
||||
bool asCConfigGroup::HasLiveObjects()
|
||||
{
|
||||
for( asUINT n = 0; n < objTypes.GetLength(); n++ )
|
||||
if( objTypes[n]->GetRefCount() != 0 )
|
||||
if( objTypes[n]->externalRefCount.get() != 0 )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -123,7 +142,7 @@ void asCConfigGroup::RemoveConfiguration(asCScriptEngine *engine, bool notUsed)
|
||||
int index = engine->registeredGlobalFuncs.GetIndex(scriptFunctions[n]);
|
||||
if( index >= 0 )
|
||||
engine->registeredGlobalFuncs.Erase(index);
|
||||
scriptFunctions[n]->Release();
|
||||
scriptFunctions[n]->ReleaseInternal();
|
||||
if( engine->stringFactory == scriptFunctions[n] )
|
||||
engine->stringFactory = 0;
|
||||
}
|
||||
@@ -141,27 +160,24 @@ void asCConfigGroup::RemoveConfiguration(asCScriptEngine *engine, bool notUsed)
|
||||
for( n = 0; n < funcDefs.GetLength(); n++ )
|
||||
{
|
||||
engine->registeredFuncDefs.RemoveValue(funcDefs[n]);
|
||||
funcDefs[n]->Release();
|
||||
funcDefs[n]->ReleaseInternal();
|
||||
engine->RemoveFuncdef(funcDefs[n]);
|
||||
funcDefs[n]->ReleaseInternal();
|
||||
}
|
||||
funcDefs.SetLength(0);
|
||||
|
||||
engine->ClearUnusedTypes();
|
||||
|
||||
// Remove object types (skip this if it is possible other groups are still using the types)
|
||||
if( !notUsed )
|
||||
{
|
||||
for( n = 0; n < objTypes.GetLength(); n++ )
|
||||
for( n = asUINT(objTypes.GetLength()); n-- > 0; )
|
||||
{
|
||||
asCObjectType *t = objTypes[n];
|
||||
asSMapNode<asSNameSpaceNamePair, asCObjectType*> *cursor;
|
||||
if( engine->allRegisteredTypes.MoveTo(&cursor, asSNameSpaceNamePair(t->nameSpace, t->name)) &&
|
||||
cursor->value == t )
|
||||
{
|
||||
#ifdef AS_DEBUG
|
||||
ValidateNoUsage(engine, t);
|
||||
#endif
|
||||
|
||||
engine->allRegisteredTypes.Erase(cursor);
|
||||
|
||||
if( engine->defaultArrayObjectType == t )
|
||||
engine->defaultArrayObjectType = 0;
|
||||
|
||||
@@ -174,21 +190,17 @@ void asCConfigGroup::RemoveConfiguration(asCScriptEngine *engine, bool notUsed)
|
||||
else
|
||||
engine->registeredObjTypes.RemoveValue(t);
|
||||
|
||||
asDELETE(t, asCObjectType);
|
||||
t->DestroyInternal();
|
||||
t->ReleaseInternal();
|
||||
}
|
||||
else
|
||||
{
|
||||
int idx = engine->templateInstanceTypes.IndexOf(t);
|
||||
if( idx >= 0 )
|
||||
{
|
||||
#ifdef AS_DEBUG
|
||||
ValidateNoUsage(engine, t);
|
||||
#endif
|
||||
|
||||
engine->templateInstanceTypes.RemoveIndexUnordered(idx);
|
||||
t->templateSubTypes.SetLength(0);
|
||||
|
||||
asDELETE(t, asCObjectType);
|
||||
t->DestroyInternal();
|
||||
t->ReleaseInternal();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -201,57 +213,4 @@ void asCConfigGroup::RemoveConfiguration(asCScriptEngine *engine, bool notUsed)
|
||||
referencedConfigGroups.SetLength(0);
|
||||
}
|
||||
|
||||
#ifdef AS_DEBUG
|
||||
void asCConfigGroup::ValidateNoUsage(asCScriptEngine *engine, asCObjectType *type)
|
||||
{
|
||||
for( asUINT n = 0; n < engine->scriptFunctions.GetLength(); n++ )
|
||||
{
|
||||
asCScriptFunction *func = engine->scriptFunctions[n];
|
||||
if( func == 0 ) continue;
|
||||
|
||||
// Ignore factory, list factory, and members
|
||||
if( func->name == "_beh_3_" || func->name == "_beh_4_" || func->objectType == type )
|
||||
continue;
|
||||
|
||||
// Ignore function definitions too, as they aren't released until the engine is destroyed
|
||||
if( func->funcType == asFUNC_FUNCDEF )
|
||||
continue;
|
||||
|
||||
// Ignore functions whose object type has already reached refCount 0 as they are to be removed
|
||||
if( func->objectType && func->objectType->GetRefCount() == 0 )
|
||||
continue;
|
||||
|
||||
if( func->returnType.GetObjectType() == type )
|
||||
{
|
||||
asCString msg;
|
||||
// We can only use the function name here, because the types used by the function may have been deleted already
|
||||
msg.Format(TXT_TYPE_s_IS_STILL_USED_BY_FUNC_s, type->name.AddressOf(), func->GetDeclaration());
|
||||
engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, msg.AddressOf());
|
||||
}
|
||||
else
|
||||
{
|
||||
for( asUINT p = 0; p < func->parameterTypes.GetLength(); p++ )
|
||||
{
|
||||
if( func->parameterTypes[p].GetObjectType() == type )
|
||||
{
|
||||
asCString msg;
|
||||
// We can only use the function name here, because the types used by the function may have been deleted already
|
||||
msg.Format(TXT_TYPE_s_IS_STILL_USED_BY_FUNC_s, type->name.AddressOf(), func->GetDeclaration());
|
||||
engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, msg.AddressOf());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Check also usage of the type in global variables
|
||||
|
||||
// TODO: Check also usage of the type in local variables in script functions
|
||||
|
||||
// TODO: Check also usage of the type as members of classes
|
||||
|
||||
// TODO: Check also usage of the type as sub types in other types
|
||||
}
|
||||
#endif
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2012 Andreas Jonsson
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -63,9 +63,8 @@ public:
|
||||
bool HasLiveObjects();
|
||||
void RemoveConfiguration(asCScriptEngine *engine, bool notUsed = false);
|
||||
|
||||
#ifdef AS_DEBUG
|
||||
void ValidateNoUsage(asCScriptEngine *engine, asCObjectType *type);
|
||||
#endif
|
||||
void AddReferencesForFunc(asCScriptEngine *engine, asCScriptFunction *func);
|
||||
void AddReferencesForType(asCScriptEngine *engine, asCObjectType *type);
|
||||
|
||||
asCString groupName;
|
||||
int refCount;
|
||||
@@ -75,6 +74,10 @@ public:
|
||||
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
|
||||
asCArray<asCObjectType*> generatedTemplateInstances;
|
||||
};
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
@@ -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
|
||||
@@ -61,7 +61,6 @@ const int RESERVE_STACK = 2*AS_PTR_SIZE;
|
||||
// For each script function call we push 9 PTRs on the call stack
|
||||
const int CALLSTACK_FRAME_SIZE = 9;
|
||||
|
||||
|
||||
#if defined(AS_DEBUG)
|
||||
|
||||
class asCDebugStats
|
||||
@@ -254,15 +253,27 @@ void asCContext::DetachEngine()
|
||||
{
|
||||
if( m_stackBlocks[n] )
|
||||
{
|
||||
#ifndef WIP_16BYTE_ALIGN
|
||||
asDELETEARRAY(m_stackBlocks[n]);
|
||||
#else
|
||||
asDELETEARRAYALIGNED(m_stackBlocks[n]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
m_stackBlocks.SetLength(0);
|
||||
m_stackBlockSize = 0;
|
||||
|
||||
// Clean the user data
|
||||
if( m_userData && m_engine->cleanContextFunc )
|
||||
m_engine->cleanContextFunc(this);
|
||||
for( asUINT n = 0; n < m_userData.GetLength(); n += 2 )
|
||||
{
|
||||
if( m_userData[n+1] )
|
||||
{
|
||||
for( asUINT c = 0; c < m_engine->cleanContextFuncs.GetLength(); c++ )
|
||||
if( m_engine->cleanContextFuncs[c].type == m_userData[n] )
|
||||
m_engine->cleanContextFuncs[c].cleanFunc(this);
|
||||
}
|
||||
}
|
||||
m_userData.SetLength(0);
|
||||
|
||||
// Clear engine pointer
|
||||
if( m_holdEngineRef )
|
||||
@@ -277,17 +288,55 @@ asIScriptEngine *asCContext::GetEngine() const
|
||||
}
|
||||
|
||||
// interface
|
||||
void *asCContext::SetUserData(void *data)
|
||||
void *asCContext::SetUserData(void *data, asPWORD type)
|
||||
{
|
||||
void *oldData = m_userData;
|
||||
m_userData = data;
|
||||
return oldData;
|
||||
// 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(m_engine->engineRWLock);
|
||||
|
||||
// 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 < m_userData.GetLength(); n += 2 )
|
||||
{
|
||||
if( m_userData[n] == type )
|
||||
{
|
||||
void *oldData = reinterpret_cast<void*>(m_userData[n+1]);
|
||||
m_userData[n+1] = reinterpret_cast<asPWORD>(data);
|
||||
|
||||
RELEASEEXCLUSIVE(m_engine->engineRWLock);
|
||||
|
||||
return oldData;
|
||||
}
|
||||
}
|
||||
|
||||
m_userData.PushLast(type);
|
||||
m_userData.PushLast(reinterpret_cast<asPWORD>(data));
|
||||
|
||||
RELEASEEXCLUSIVE(m_engine->engineRWLock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// interface
|
||||
void *asCContext::GetUserData() const
|
||||
void *asCContext::GetUserData(asPWORD type) const
|
||||
{
|
||||
return m_userData;
|
||||
// There may be multiple threads reading, but when
|
||||
// setting the user data nobody must be reading.
|
||||
ACQUIRESHARED(m_engine->engineRWLock);
|
||||
|
||||
for( asUINT n = 0; n < m_userData.GetLength(); n += 2 )
|
||||
{
|
||||
if( m_userData[n] == type )
|
||||
{
|
||||
RELEASESHARED(m_engine->engineRWLock);
|
||||
return reinterpret_cast<void*>(m_userData[n+1]);
|
||||
}
|
||||
}
|
||||
|
||||
RELEASESHARED(m_engine->engineRWLock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// interface
|
||||
@@ -322,6 +371,16 @@ int asCContext::Prepare(asIScriptFunction *func)
|
||||
// Release the returned object (if any)
|
||||
CleanReturnObject();
|
||||
|
||||
// Release the object if it is a script object
|
||||
if( m_initialFunction && m_initialFunction->objectType && (m_initialFunction->objectType->flags & asOBJ_SCRIPT_OBJECT) )
|
||||
{
|
||||
asCScriptObject *obj = *(asCScriptObject**)&m_regs.stackFramePointer[0];
|
||||
if( obj )
|
||||
obj->Release();
|
||||
|
||||
*(asPWORD*)&m_regs.stackFramePointer[0] = 0;
|
||||
}
|
||||
|
||||
if( m_initialFunction && m_initialFunction == func )
|
||||
{
|
||||
// If the same function is executed again, we can skip a lot of the setup
|
||||
@@ -437,6 +496,14 @@ int asCContext::Unprepare()
|
||||
// Release the returned object (if any)
|
||||
CleanReturnObject();
|
||||
|
||||
// Release the object if it is a script object
|
||||
if( m_initialFunction && m_initialFunction->objectType && (m_initialFunction->objectType->flags & asOBJ_SCRIPT_OBJECT) )
|
||||
{
|
||||
asCScriptObject *obj = *(asCScriptObject**)&m_regs.stackFramePointer[0];
|
||||
if( obj )
|
||||
obj->Release();
|
||||
}
|
||||
|
||||
// Release the initial function
|
||||
if( m_initialFunction )
|
||||
{
|
||||
@@ -624,8 +691,15 @@ int asCContext::SetObject(void *obj)
|
||||
return asERROR;
|
||||
}
|
||||
|
||||
asASSERT( *(asPWORD*)&m_regs.stackFramePointer[0] == 0 );
|
||||
|
||||
*(asPWORD*)&m_regs.stackFramePointer[0] = (asPWORD)obj;
|
||||
|
||||
// TODO: This should be optional by having a flag where the application can chose whether it should be done or not
|
||||
// The flag could be named something like takeOwnership and have default value of true
|
||||
if( obj && (m_initialFunction->objectType->flags & asOBJ_SCRIPT_OBJECT) )
|
||||
reinterpret_cast<asCScriptObject*>(obj)->AddRef();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -977,6 +1051,44 @@ int asCContext::SetArgObject(asUINT arg, void *obj)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int asCContext::SetArgVarType(asUINT arg, void *ptr, int typeId)
|
||||
{
|
||||
if( m_status != asEXECUTION_PREPARED )
|
||||
return asCONTEXT_NOT_PREPARED;
|
||||
|
||||
if( arg >= (unsigned)m_initialFunction->parameterTypes.GetLength() )
|
||||
{
|
||||
m_status = asEXECUTION_ERROR;
|
||||
return asINVALID_ARG;
|
||||
}
|
||||
|
||||
// Verify the type of the argument
|
||||
asCDataType *dt = &m_initialFunction->parameterTypes[arg];
|
||||
if( dt->GetTokenType() != ttQuestion )
|
||||
{
|
||||
m_status = asEXECUTION_ERROR;
|
||||
return asINVALID_TYPE;
|
||||
}
|
||||
|
||||
// Determine the position of the argument
|
||||
int offset = 0;
|
||||
if( m_initialFunction->objectType )
|
||||
offset += AS_PTR_SIZE;
|
||||
|
||||
// If function returns object by value an extra pointer is pushed on the stack
|
||||
if( m_returnValueSize )
|
||||
offset += AS_PTR_SIZE;
|
||||
|
||||
for( asUINT n = 0; n < arg; n++ )
|
||||
offset += m_initialFunction->parameterTypes[n].GetSizeOnStackDWords();
|
||||
|
||||
// Set the typeId and pointer
|
||||
*(asPWORD*)(&m_regs.stackFramePointer[offset]) = (asPWORD)ptr;
|
||||
offset += AS_PTR_SIZE;
|
||||
*(int*)(&m_regs.stackFramePointer[offset]) = typeId;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO: Instead of GetAddressOfArg, maybe we need a SetArgValue(int arg, void *value, bool takeOwnership) instead.
|
||||
|
||||
@@ -1119,6 +1231,14 @@ int asCContext::Execute()
|
||||
SetInternalException(TXT_NULL_POINTER_ACCESS);
|
||||
}
|
||||
}
|
||||
else if( m_currentFunction->funcType == asFUNC_IMPORTED )
|
||||
{
|
||||
int funcId = m_engine->importedFunctions[m_currentFunction->id & ~FUNC_IMPORTED]->boundFunctionId;
|
||||
if( funcId > 0 )
|
||||
m_currentFunction = m_engine->scriptFunctions[funcId];
|
||||
else
|
||||
SetInternalException(TXT_UNBOUND_FUNCTION);
|
||||
}
|
||||
|
||||
if( m_currentFunction->funcType == asFUNC_SCRIPT )
|
||||
{
|
||||
@@ -1132,7 +1252,7 @@ int asCContext::Execute()
|
||||
// The current function is an application registered function
|
||||
|
||||
// Call the function directly
|
||||
CallSystemFunction(m_currentFunction->id, this, 0);
|
||||
CallSystemFunction(m_currentFunction->id, this);
|
||||
|
||||
// Was the call successful?
|
||||
if( m_status == asEXECUTION_ACTIVE )
|
||||
@@ -1174,13 +1294,12 @@ int asCContext::Execute()
|
||||
if( gcPosObjects > gcPreObjects )
|
||||
{
|
||||
// Execute as many steps as there were new objects created
|
||||
while( gcPosObjects-- > gcPreObjects )
|
||||
m_engine->GarbageCollect(asGC_ONE_STEP | asGC_DESTROY_GARBAGE | asGC_DETECT_GARBAGE);
|
||||
m_engine->GarbageCollect(asGC_ONE_STEP | asGC_DESTROY_GARBAGE | asGC_DETECT_GARBAGE, gcPosObjects - gcPreObjects);
|
||||
}
|
||||
else if( gcPosObjects > 0 )
|
||||
{
|
||||
// Execute at least one step, even if no new objects were created
|
||||
m_engine->GarbageCollect(asGC_ONE_STEP | asGC_DESTROY_GARBAGE | asGC_DETECT_GARBAGE);
|
||||
m_engine->GarbageCollect(asGC_ONE_STEP | asGC_DESTROY_GARBAGE | asGC_DETECT_GARBAGE, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1430,22 +1549,46 @@ int asCContext::GetLineNumber(asUINT stackLevel, int *column, const char **secti
|
||||
// internal
|
||||
bool asCContext::ReserveStackSpace(asUINT size)
|
||||
{
|
||||
#ifdef WIP_16BYTE_ALIGN
|
||||
// Pad size to a multiple of MAX_TYPE_ALIGNMENT.
|
||||
const asUINT remainder = size % MAX_TYPE_ALIGNMENT;
|
||||
if(remainder != 0)
|
||||
{
|
||||
size = size + (MAX_TYPE_ALIGNMENT - (size % MAX_TYPE_ALIGNMENT));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Make sure the first stack block is allocated
|
||||
if( m_stackBlocks.GetLength() == 0 )
|
||||
{
|
||||
m_stackBlockSize = m_engine->initialContextStackSize;
|
||||
asASSERT( m_stackBlockSize > 0 );
|
||||
|
||||
#ifndef WIP_16BYTE_ALIGN
|
||||
asDWORD *stack = asNEWARRAY(asDWORD,m_stackBlockSize);
|
||||
#else
|
||||
asDWORD *stack = asNEWARRAYALIGNED(asDWORD, m_stackBlockSize, MAX_TYPE_ALIGNMENT);
|
||||
#endif
|
||||
if( stack == 0 )
|
||||
{
|
||||
// Out of memory
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef WIP_16BYTE_ALIGN
|
||||
asASSERT( isAligned(stack, MAX_TYPE_ALIGNMENT) );
|
||||
#endif
|
||||
|
||||
m_stackBlocks.PushLast(stack);
|
||||
m_stackIndex = 0;
|
||||
m_regs.stackPointer = m_stackBlocks[0] + m_stackBlockSize;
|
||||
|
||||
#ifdef WIP_16BYTE_ALIGN
|
||||
// Align the stack pointer. This is necessary as the m_stackBlockSize is not necessarily evenly divisable with the max alignment
|
||||
((asPWORD&)m_regs.stackPointer) &= ~(MAX_TYPE_ALIGNMENT-1);
|
||||
|
||||
asASSERT( isAligned(m_regs.stackPointer, MAX_TYPE_ALIGNMENT) );
|
||||
#endif
|
||||
}
|
||||
|
||||
// Check if there is enough space on the current stack block, otherwise move
|
||||
@@ -1472,7 +1615,11 @@ bool asCContext::ReserveStackSpace(asUINT size)
|
||||
if( m_stackBlocks.GetLength() == m_stackIndex )
|
||||
{
|
||||
// Allocate the new stack block, with twice the size of the previous
|
||||
asDWORD *stack = asNEWARRAY(asDWORD,(m_stackBlockSize << m_stackIndex));
|
||||
#ifndef WIP_16BYTE_ALIGN
|
||||
asDWORD *stack = asNEWARRAY(asDWORD, (m_stackBlockSize << m_stackIndex));
|
||||
#else
|
||||
asDWORD *stack = asNEWARRAYALIGNED(asDWORD, (m_stackBlockSize << m_stackIndex), MAX_TYPE_ALIGNMENT);
|
||||
#endif
|
||||
if( stack == 0 )
|
||||
{
|
||||
// Out of memory
|
||||
@@ -1484,6 +1631,11 @@ bool asCContext::ReserveStackSpace(asUINT size)
|
||||
SetInternalException(TXT_STACK_OVERFLOW);
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef WIP_16BYTE_ALIGN
|
||||
asASSERT( isAligned(stack, MAX_TYPE_ALIGNMENT) );
|
||||
#endif
|
||||
|
||||
m_stackBlocks.PushLast(stack);
|
||||
}
|
||||
|
||||
@@ -1494,6 +1646,13 @@ bool asCContext::ReserveStackSpace(asUINT size)
|
||||
m_currentFunction->GetSpaceNeededForArguments() -
|
||||
(m_currentFunction->objectType ? AS_PTR_SIZE : 0) -
|
||||
(m_currentFunction->DoesReturnOnStack() ? AS_PTR_SIZE : 0);
|
||||
|
||||
#ifdef WIP_16BYTE_ALIGN
|
||||
// Align the stack pointer
|
||||
(asPWORD&)m_regs.stackPointer &= ~(MAX_TYPE_ALIGNMENT-1);
|
||||
|
||||
asASSERT( isAligned(m_regs.stackPointer, MAX_TYPE_ALIGNMENT) );
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1512,19 +1671,6 @@ void asCContext::CallScriptFunction(asCScriptFunction *func)
|
||||
m_currentFunction = func;
|
||||
m_regs.programPointer = m_currentFunction->scriptData->byteCode.AddressOf();
|
||||
|
||||
// Make sure there is space on the stack to execute the function
|
||||
asDWORD *oldStackPointer = m_regs.stackPointer;
|
||||
if( !ReserveStackSpace(func->scriptData->stackNeeded) )
|
||||
return;
|
||||
|
||||
// If a new stack block was allocated then we'll need to move
|
||||
// over the function arguments to the new block
|
||||
if( m_regs.stackPointer != oldStackPointer )
|
||||
{
|
||||
int numDwords = func->GetSpaceNeededForArguments() + (func->objectType ? AS_PTR_SIZE : 0) + (func->DoesReturnOnStack() ? AS_PTR_SIZE : 0);
|
||||
memcpy(m_regs.stackPointer, oldStackPointer, sizeof(asDWORD)*numDwords);
|
||||
}
|
||||
|
||||
PrepareScriptFunction();
|
||||
}
|
||||
|
||||
@@ -1532,6 +1678,21 @@ void asCContext::PrepareScriptFunction()
|
||||
{
|
||||
asASSERT( m_currentFunction->scriptData );
|
||||
|
||||
// Make sure there is space on the stack to execute the function
|
||||
asDWORD *oldStackPointer = m_regs.stackPointer;
|
||||
if( !ReserveStackSpace(m_currentFunction->scriptData->stackNeeded) )
|
||||
return;
|
||||
|
||||
// If a new stack block was allocated then we'll need to move
|
||||
// over the function arguments to the new block.
|
||||
if( m_regs.stackPointer != oldStackPointer )
|
||||
{
|
||||
int numDwords = m_currentFunction->GetSpaceNeededForArguments() +
|
||||
(m_currentFunction->objectType ? AS_PTR_SIZE : 0) +
|
||||
(m_currentFunction->DoesReturnOnStack() ? AS_PTR_SIZE : 0);
|
||||
memcpy(m_regs.stackPointer, oldStackPointer, sizeof(asDWORD)*numDwords);
|
||||
}
|
||||
|
||||
// Update framepointer
|
||||
m_regs.stackFramePointer = m_regs.stackPointer;
|
||||
|
||||
@@ -2329,7 +2490,7 @@ void asCContext::ExecuteNext()
|
||||
m_regs.stackPointer = l_sp;
|
||||
m_regs.stackFramePointer = l_fp;
|
||||
|
||||
l_sp += CallSystemFunction(i, this, 0);
|
||||
l_sp += CallSystemFunction(i, this);
|
||||
|
||||
// Update the program position after the call so that line number is correct
|
||||
l_bc += 2;
|
||||
@@ -2361,9 +2522,9 @@ void asCContext::ExecuteNext()
|
||||
|
||||
case asBC_CALLBND:
|
||||
{
|
||||
// TODO: Clean-up: This code is very similar to asBC_CallPtr. Create a shared method for them
|
||||
// Get the function ID from the stack
|
||||
int i = asBC_INTARG(l_bc);
|
||||
l_bc += 2;
|
||||
|
||||
asASSERT( i >= 0 );
|
||||
asASSERT( i & FUNC_IMPORTED );
|
||||
@@ -2376,6 +2537,9 @@ void asCContext::ExecuteNext()
|
||||
int funcId = m_engine->importedFunctions[i & ~FUNC_IMPORTED]->boundFunctionId;
|
||||
if( funcId == -1 )
|
||||
{
|
||||
// Need to update the program pointer for the exception handler
|
||||
m_regs.programPointer += 2;
|
||||
|
||||
// Tell the exception handler to clean up the arguments to this function
|
||||
m_needToCleanupArgs = true;
|
||||
SetInternalException(TXT_UNBOUND_FUNCTION);
|
||||
@@ -2384,8 +2548,46 @@ void asCContext::ExecuteNext()
|
||||
else
|
||||
{
|
||||
asCScriptFunction *func = m_engine->GetScriptFunction(funcId);
|
||||
if( func->funcType == asFUNC_SCRIPT )
|
||||
{
|
||||
m_regs.programPointer += 2;
|
||||
CallScriptFunction(func);
|
||||
}
|
||||
else if( func->funcType == asFUNC_DELEGATE )
|
||||
{
|
||||
// Push the object pointer on the stack. There is always a reserved space for this so
|
||||
// we don't don't need to worry about overflowing the allocated memory buffer
|
||||
asASSERT( m_regs.stackPointer - AS_PTR_SIZE >= m_stackBlocks[m_stackIndex] );
|
||||
m_regs.stackPointer -= AS_PTR_SIZE;
|
||||
*(asPWORD*)m_regs.stackPointer = asPWORD(func->objForDelegate);
|
||||
|
||||
CallScriptFunction(func);
|
||||
// Call the delegated method
|
||||
if( func->funcForDelegate->funcType == asFUNC_SYSTEM )
|
||||
{
|
||||
m_regs.stackPointer += CallSystemFunction(func->funcForDelegate->id, this);
|
||||
|
||||
// Update program position after the call so the line number
|
||||
// is correct in case the system function queries it
|
||||
m_regs.programPointer += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_regs.programPointer += 2;
|
||||
|
||||
// TODO: run-time optimize: The true method could be figured out when creating the delegate
|
||||
CallInterfaceMethod(func->funcForDelegate);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
asASSERT( func->funcType == asFUNC_SYSTEM );
|
||||
|
||||
m_regs.stackPointer += CallSystemFunction(func->id, this);
|
||||
|
||||
// Update program position after the call so the line number
|
||||
// is correct in case the system function queries it
|
||||
m_regs.programPointer += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Extract the values from the context again
|
||||
@@ -2476,13 +2678,17 @@ void asCContext::ExecuteNext()
|
||||
|
||||
if( func )
|
||||
{
|
||||
// Push the object pointer on the stack (it will be popped by the function)
|
||||
l_sp -= AS_PTR_SIZE;
|
||||
*(asPWORD*)l_sp = (asPWORD)mem;
|
||||
|
||||
// Need to move the values back to the context as the called functions
|
||||
// may use the debug interface to inspect the registers
|
||||
m_regs.programPointer = l_bc;
|
||||
m_regs.stackPointer = l_sp;
|
||||
m_regs.stackFramePointer = l_fp;
|
||||
|
||||
l_sp += CallSystemFunction(func, this, mem);
|
||||
l_sp += CallSystemFunction(func, this);
|
||||
}
|
||||
|
||||
// Pop the variable address from the stack
|
||||
@@ -3352,7 +3558,7 @@ void asCContext::ExecuteNext()
|
||||
break;
|
||||
|
||||
case asBC_u64TOf:
|
||||
#if _MSC_VER <= 1200 // MSVC6
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1200 // MSVC6
|
||||
{
|
||||
// MSVC6 doesn't permit UINT64 to double
|
||||
asINT64 v = *(asINT64*)(l_fp - asBC_SWORDARG1(l_bc));
|
||||
@@ -3373,7 +3579,7 @@ void asCContext::ExecuteNext()
|
||||
break;
|
||||
|
||||
case asBC_u64TOd:
|
||||
#if _MSC_VER <= 1200 // MSVC6
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1200 // MSVC6
|
||||
{
|
||||
// MSVC6 doesn't permit UINT64 to double
|
||||
asINT64 v = *(asINT64*)(l_fp - asBC_SWORDARG0(l_bc));
|
||||
@@ -3655,7 +3861,7 @@ void asCContext::ExecuteNext()
|
||||
// Call the delegated method
|
||||
if( func->funcForDelegate->funcType == asFUNC_SYSTEM )
|
||||
{
|
||||
m_regs.stackPointer += CallSystemFunction(func->funcForDelegate->id, this, 0);
|
||||
m_regs.stackPointer += CallSystemFunction(func->funcForDelegate->id, this);
|
||||
|
||||
// Update program position after the call so the line number
|
||||
// is correct in case the system function queries it
|
||||
@@ -3673,7 +3879,7 @@ void asCContext::ExecuteNext()
|
||||
{
|
||||
asASSERT( func->funcType == asFUNC_SYSTEM );
|
||||
|
||||
m_regs.stackPointer += CallSystemFunction(func->id, this, 0);
|
||||
m_regs.stackPointer += CallSystemFunction(func->id, this);
|
||||
|
||||
// Update program position after the call so the line number
|
||||
// is correct in case the system function queries it
|
||||
@@ -3906,7 +4112,11 @@ void asCContext::ExecuteNext()
|
||||
|
||||
asUINT size = asBC_DWORDARG(l_bc);
|
||||
asBYTE **var = (asBYTE**)(l_fp - asBC_SWORDARG0(l_bc));
|
||||
#ifndef WIP_16BYTE_ALIGN
|
||||
*var = asNEWARRAY(asBYTE, size);
|
||||
#else
|
||||
*var = asNEWARRAYALIGNED(asBYTE, size, MAX_TYPE_ALIGNMENT);
|
||||
#endif
|
||||
|
||||
// Clear the buffer for the pointers that will be placed in it
|
||||
memset(*var, 0, size);
|
||||
@@ -4622,23 +4832,6 @@ void asCContext::CleanStackFrame()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the object is a script declared object, then we must release it
|
||||
// as the compiler adds a reference at the entry of the function. Make sure
|
||||
// the function has actually been entered
|
||||
if( m_currentFunction->objectType && m_regs.programPointer != m_currentFunction->scriptData->byteCode.AddressOf() )
|
||||
{
|
||||
// Methods returning a reference or constructors don't add a reference
|
||||
if( !m_currentFunction->returnType.IsReference() && m_currentFunction->name != m_currentFunction->objectType->name )
|
||||
{
|
||||
asSTypeBehaviour *beh = &m_currentFunction->objectType->beh;
|
||||
if( beh->release && *(asPWORD*)&m_regs.stackFramePointer[0] != 0 )
|
||||
{
|
||||
m_engine->CallObjectMethod((void*)*(asPWORD*)&m_regs.stackFramePointer[0], beh->release);
|
||||
*(asPWORD*)&m_regs.stackFramePointer[0] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
m_isStackMemoryNotAllocated = false;
|
||||
@@ -4729,13 +4922,14 @@ asEContextState asCContext::GetState() const
|
||||
// interface
|
||||
int asCContext::SetLineCallback(asSFuncPtr callback, void *obj, int callConv)
|
||||
{
|
||||
m_lineCallback = true;
|
||||
m_regs.doProcessSuspend = true;
|
||||
// First turn off the line callback to avoid a second thread
|
||||
// attempting to call it while the new one is still being set
|
||||
m_lineCallback = false;
|
||||
|
||||
m_lineCallbackObj = obj;
|
||||
bool isObj = false;
|
||||
if( (unsigned)callConv == asCALL_GENERIC )
|
||||
if( (unsigned)callConv == asCALL_GENERIC || (unsigned)callConv == asCALL_THISCALL_OBJFIRST || (unsigned)callConv == asCALL_THISCALL_OBJLAST )
|
||||
{
|
||||
m_lineCallback = false;
|
||||
m_regs.doProcessSuspend = m_doSuspend;
|
||||
return asNOT_SUPPORTED;
|
||||
}
|
||||
@@ -4744,15 +4938,18 @@ int asCContext::SetLineCallback(asSFuncPtr callback, void *obj, int callConv)
|
||||
isObj = true;
|
||||
if( obj == 0 )
|
||||
{
|
||||
m_lineCallback = false;
|
||||
m_regs.doProcessSuspend = m_doSuspend;
|
||||
return asINVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
int r = DetectCallingConvention(isObj, callback, callConv, 0, &m_lineCallbackFunc);
|
||||
if( r < 0 ) m_lineCallback = false;
|
||||
|
||||
// Turn on the line callback after setting both the function pointer and object pointer
|
||||
if( r >= 0 ) m_lineCallback = true;
|
||||
|
||||
// The BC_SUSPEND instruction should be processed if either line
|
||||
// callback is set or if the application has requested a suspension
|
||||
m_regs.doProcessSuspend = m_doSuspend || m_lineCallback;
|
||||
|
||||
return r;
|
||||
@@ -4772,7 +4969,7 @@ int asCContext::SetExceptionCallback(asSFuncPtr callback, void *obj, int callCon
|
||||
m_exceptionCallback = true;
|
||||
m_exceptionCallbackObj = obj;
|
||||
bool isObj = false;
|
||||
if( (unsigned)callConv == asCALL_GENERIC )
|
||||
if( (unsigned)callConv == asCALL_GENERIC || (unsigned)callConv == asCALL_THISCALL_OBJFIRST || (unsigned)callConv == asCALL_THISCALL_OBJLAST )
|
||||
return asNOT_SUPPORTED;
|
||||
if( (unsigned)callConv >= asCALL_THISCALL )
|
||||
{
|
||||
@@ -4809,91 +5006,79 @@ void asCContext::ClearExceptionCallback()
|
||||
m_exceptionCallback = false;
|
||||
}
|
||||
|
||||
int asCContext::CallGeneric(int id, void *objectPointer)
|
||||
int asCContext::CallGeneric(asCScriptFunction *descr)
|
||||
{
|
||||
asCScriptFunction *sysFunction = m_engine->scriptFunctions[id];
|
||||
asSSystemFunctionInterface *sysFunc = sysFunction->sysFuncIntf;
|
||||
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
|
||||
void (*func)(asIScriptGeneric*) = (void (*)(asIScriptGeneric*))sysFunc->func;
|
||||
int popSize = sysFunc->paramSize;
|
||||
asDWORD *args = m_regs.stackPointer;
|
||||
|
||||
// Verify the object pointer if it is a class method
|
||||
void *currentObject = 0;
|
||||
asASSERT( sysFunc->callConv == ICC_GENERIC_FUNC || sysFunc->callConv == ICC_GENERIC_METHOD );
|
||||
if( sysFunc->callConv == ICC_GENERIC_METHOD )
|
||||
{
|
||||
if( objectPointer )
|
||||
// The object pointer should be popped from the context stack
|
||||
popSize += AS_PTR_SIZE;
|
||||
|
||||
// Check for null pointer
|
||||
currentObject = (void*)*(asPWORD*)(args);
|
||||
if( currentObject == 0 )
|
||||
{
|
||||
currentObject = objectPointer;
|
||||
|
||||
// Don't increase the reference of this pointer
|
||||
// since it will not have been constructed yet
|
||||
SetInternalException(TXT_NULL_POINTER_ACCESS);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The object pointer should be popped from the context stack
|
||||
popSize += AS_PTR_SIZE;
|
||||
|
||||
// Check for null pointer
|
||||
currentObject = (void*)*(asPWORD*)(args);
|
||||
if( currentObject == 0 )
|
||||
{
|
||||
SetInternalException(TXT_NULL_POINTER_ACCESS);
|
||||
return 0;
|
||||
}
|
||||
asASSERT( sysFunc->baseOffset == 0 );
|
||||
|
||||
// Add the base offset for multiple inheritance
|
||||
currentObject = (void*)(asPWORD(currentObject) + sysFunc->baseOffset);
|
||||
|
||||
// Skip object pointer
|
||||
args += AS_PTR_SIZE;
|
||||
}
|
||||
// Skip object pointer
|
||||
args += AS_PTR_SIZE;
|
||||
}
|
||||
|
||||
if( sysFunction->DoesReturnOnStack() )
|
||||
if( descr->DoesReturnOnStack() )
|
||||
{
|
||||
// Skip the address where the return value will be stored
|
||||
args += AS_PTR_SIZE;
|
||||
popSize += AS_PTR_SIZE;
|
||||
}
|
||||
|
||||
asCGeneric gen(m_engine, sysFunction, currentObject, args);
|
||||
asCGeneric gen(m_engine, descr, currentObject, args);
|
||||
|
||||
m_callingSystemFunction = sysFunction;
|
||||
m_callingSystemFunction = descr;
|
||||
func(&gen);
|
||||
m_callingSystemFunction = 0;
|
||||
|
||||
m_regs.valueRegister = gen.returnVal;
|
||||
m_regs.objectRegister = gen.objectRegister;
|
||||
m_regs.objectType = sysFunction->returnType.GetObjectType();
|
||||
m_regs.objectType = descr->returnType.GetObjectType();
|
||||
|
||||
// Clean up function parameters
|
||||
int offset = 0;
|
||||
for( asUINT n = 0; n < sysFunction->parameterTypes.GetLength(); n++ )
|
||||
// Clean up arguments
|
||||
const asUINT cleanCount = sysFunc->cleanArgs.GetLength();
|
||||
if( cleanCount )
|
||||
{
|
||||
if( sysFunction->parameterTypes[n].IsObject() && !sysFunction->parameterTypes[n].IsReference() )
|
||||
asSSystemFunctionInterface::SClean *clean = sysFunc->cleanArgs.AddressOf();
|
||||
for( asUINT n = 0; n < cleanCount; n++, clean++ )
|
||||
{
|
||||
void *obj = *(void**)&args[offset];
|
||||
if( obj )
|
||||
void **addr = (void**)&args[clean->off];
|
||||
if( clean->op == 0 )
|
||||
{
|
||||
// Release the object
|
||||
asSTypeBehaviour *beh = &sysFunction->parameterTypes[n].GetObjectType()->beh;
|
||||
if( sysFunction->parameterTypes[n].GetObjectType()->flags & asOBJ_REF )
|
||||
if( *addr != 0 )
|
||||
{
|
||||
asASSERT( (sysFunction->parameterTypes[n].GetObjectType()->flags & asOBJ_NOCOUNT) || beh->release );
|
||||
if( beh->release )
|
||||
m_engine->CallObjectMethod(obj, beh->release);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Call the destructor then free the memory
|
||||
if( beh->destruct )
|
||||
m_engine->CallObjectMethod(obj, beh->destruct);
|
||||
|
||||
m_engine->CallFree(obj);
|
||||
m_engine->CallObjectMethod(*addr, clean->ot->beh.release);
|
||||
*addr = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
asASSERT( clean->op == 1 || clean->op == 2 );
|
||||
asASSERT( *addr );
|
||||
|
||||
if( clean->op == 2 )
|
||||
m_engine->CallObjectMethod(*addr, clean->ot->beh.destruct);
|
||||
|
||||
m_engine->CallFree(*addr);
|
||||
}
|
||||
}
|
||||
offset += sysFunction->parameterTypes[n].GetSizeOnStackDWords();
|
||||
}
|
||||
|
||||
// Return how much should be popped from the stack
|
||||
|
||||
@@ -76,14 +76,15 @@ public:
|
||||
int SetObject(void *obj);
|
||||
|
||||
// Arguments
|
||||
int SetArgByte(asUINT arg, asBYTE value);
|
||||
int SetArgWord(asUINT arg, asWORD value);
|
||||
int SetArgDWord(asUINT arg, asDWORD value);
|
||||
int SetArgQWord(asUINT arg, asQWORD value);
|
||||
int SetArgFloat(asUINT arg, float value);
|
||||
int SetArgDouble(asUINT arg, double value);
|
||||
int SetArgAddress(asUINT arg, void *addr);
|
||||
int SetArgObject(asUINT arg, void *obj);
|
||||
int SetArgByte(asUINT arg, asBYTE value);
|
||||
int SetArgWord(asUINT arg, asWORD value);
|
||||
int SetArgDWord(asUINT arg, asDWORD value);
|
||||
int SetArgQWord(asUINT arg, asQWORD value);
|
||||
int SetArgFloat(asUINT arg, float value);
|
||||
int SetArgDouble(asUINT arg, double value);
|
||||
int SetArgAddress(asUINT arg, void *addr);
|
||||
int SetArgObject(asUINT arg, void *obj);
|
||||
int SetArgVarType(asUINT arg, void *ptr, int typeId);
|
||||
void *GetAddressOfArg(asUINT arg);
|
||||
|
||||
// Return value
|
||||
@@ -122,8 +123,8 @@ public:
|
||||
asIScriptFunction *GetSystemFunction();
|
||||
|
||||
// User data
|
||||
void *SetUserData(void *data);
|
||||
void *GetUserData() const;
|
||||
void *SetUserData(void *data, asPWORD type);
|
||||
void *GetUserData(asPWORD type) const;
|
||||
|
||||
public:
|
||||
// Internal public functions
|
||||
@@ -136,7 +137,7 @@ public:
|
||||
void CallLineCallback();
|
||||
void CallExceptionCallback();
|
||||
|
||||
int CallGeneric(int funcID, void *objectPointer);
|
||||
int CallGeneric(asCScriptFunction *func);
|
||||
|
||||
void DetachEngine();
|
||||
|
||||
@@ -204,7 +205,7 @@ public:
|
||||
asSSystemFunctionInterface m_exceptionCallbackFunc;
|
||||
void * m_exceptionCallbackObj;
|
||||
|
||||
void *m_userData;
|
||||
asCArray<asPWORD> m_userData;
|
||||
|
||||
// Registers available to JIT compiler functions
|
||||
asSVMRegisters m_regs;
|
||||
|
||||
@@ -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
|
||||
@@ -46,24 +46,28 @@ BEGIN_AS_NAMESPACE
|
||||
|
||||
asCDataType::asCDataType()
|
||||
{
|
||||
tokenType = ttUnrecognizedToken;
|
||||
objectType = 0;
|
||||
isReference = false;
|
||||
isReadOnly = false;
|
||||
isObjectHandle = false;
|
||||
isConstHandle = false;
|
||||
funcDef = 0;
|
||||
tokenType = ttUnrecognizedToken;
|
||||
objectType = 0;
|
||||
isReference = false;
|
||||
isReadOnly = false;
|
||||
isAuto = false;
|
||||
isObjectHandle = false;
|
||||
isConstHandle = false;
|
||||
funcDef = 0;
|
||||
isHandleToAsHandleType = false;
|
||||
}
|
||||
|
||||
asCDataType::asCDataType(const asCDataType &dt)
|
||||
{
|
||||
tokenType = dt.tokenType;
|
||||
objectType = dt.objectType;
|
||||
isReference = dt.isReference;
|
||||
isReadOnly = dt.isReadOnly;
|
||||
isObjectHandle = dt.isObjectHandle;
|
||||
isConstHandle = dt.isConstHandle;
|
||||
funcDef = dt.funcDef;
|
||||
tokenType = dt.tokenType;
|
||||
objectType = dt.objectType;
|
||||
isReference = dt.isReference;
|
||||
isReadOnly = dt.isReadOnly;
|
||||
isAuto = dt.isAuto;
|
||||
isObjectHandle = dt.isObjectHandle;
|
||||
isConstHandle = dt.isConstHandle;
|
||||
funcDef = dt.funcDef;
|
||||
isHandleToAsHandleType = dt.isHandleToAsHandleType;
|
||||
}
|
||||
|
||||
asCDataType::~asCDataType()
|
||||
@@ -90,6 +94,17 @@ asCDataType asCDataType::CreateObject(asCObjectType *ot, bool isConst)
|
||||
return dt;
|
||||
}
|
||||
|
||||
asCDataType asCDataType::CreateAuto(bool isConst)
|
||||
{
|
||||
asCDataType dt;
|
||||
|
||||
dt.tokenType = ttIdentifier;
|
||||
dt.isReadOnly = isConst;
|
||||
dt.isAuto = true;
|
||||
|
||||
return dt;
|
||||
}
|
||||
|
||||
asCDataType asCDataType::CreateObjectHandle(asCObjectType *ot, bool isConst)
|
||||
{
|
||||
asCDataType dt;
|
||||
@@ -144,7 +159,7 @@ bool asCDataType::IsNullHandle() const
|
||||
return false;
|
||||
}
|
||||
|
||||
asCString asCDataType::Format(bool includeNamespace) const
|
||||
asCString asCDataType::Format(asSNameSpace *currNs, bool includeNamespace) const
|
||||
{
|
||||
if( IsNullHandle() )
|
||||
return "<null handle>";
|
||||
@@ -154,11 +169,13 @@ asCString asCDataType::Format(bool includeNamespace) const
|
||||
if( isReadOnly )
|
||||
str = "const ";
|
||||
|
||||
if( includeNamespace )
|
||||
// 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( objectType )
|
||||
if( objectType && objectType->nameSpace->name != "" )
|
||||
str += objectType->nameSpace->name + "::";
|
||||
else if( funcDef )
|
||||
else if( funcDef && funcDef->nameSpace->name != "" )
|
||||
str += funcDef->nameSpace->name + "::";
|
||||
}
|
||||
|
||||
@@ -169,7 +186,7 @@ asCString asCDataType::Format(bool includeNamespace) const
|
||||
else if( IsArrayType() && objectType && !objectType->engine->ep.expandDefaultArrayToTemplate )
|
||||
{
|
||||
asASSERT( objectType->templateSubTypes.GetLength() == 1 );
|
||||
str += objectType->templateSubTypes[0].Format(includeNamespace);
|
||||
str += objectType->templateSubTypes[0].Format(currNs, includeNamespace);
|
||||
str += "[]";
|
||||
}
|
||||
else if( funcDef )
|
||||
@@ -184,13 +201,20 @@ asCString asCDataType::Format(bool includeNamespace) const
|
||||
str += "<";
|
||||
for( asUINT subtypeIndex = 0; subtypeIndex < objectType->templateSubTypes.GetLength(); subtypeIndex++ )
|
||||
{
|
||||
str += objectType->templateSubTypes[subtypeIndex].Format(includeNamespace);
|
||||
str += objectType->templateSubTypes[subtypeIndex].Format(currNs, includeNamespace);
|
||||
if( subtypeIndex != objectType->templateSubTypes.GetLength()-1 )
|
||||
str += ",";
|
||||
}
|
||||
str += ">";
|
||||
}
|
||||
}
|
||||
else if( isAuto )
|
||||
{
|
||||
if( isObjectHandle )
|
||||
str += "<auto@>";
|
||||
else
|
||||
str += "<auto>";
|
||||
}
|
||||
else
|
||||
{
|
||||
str = "<unknown>";
|
||||
@@ -211,13 +235,15 @@ asCString asCDataType::Format(bool includeNamespace) const
|
||||
|
||||
asCDataType &asCDataType::operator =(const asCDataType &dt)
|
||||
{
|
||||
tokenType = dt.tokenType;
|
||||
isReference = dt.isReference;
|
||||
objectType = dt.objectType;
|
||||
isReadOnly = dt.isReadOnly;
|
||||
isObjectHandle = dt.isObjectHandle;
|
||||
isConstHandle = dt.isConstHandle;
|
||||
funcDef = dt.funcDef;
|
||||
tokenType = dt.tokenType;
|
||||
isReference = dt.isReference;
|
||||
objectType = dt.objectType;
|
||||
isReadOnly = dt.isReadOnly;
|
||||
isObjectHandle = dt.isObjectHandle;
|
||||
isConstHandle = dt.isConstHandle;
|
||||
isAuto = dt.isAuto;
|
||||
funcDef = dt.funcDef;
|
||||
isHandleToAsHandleType = dt.isHandleToAsHandleType;
|
||||
|
||||
return (asCDataType &)*this;
|
||||
}
|
||||
@@ -226,35 +252,46 @@ int asCDataType::MakeHandle(bool b, bool acceptHandleForScope)
|
||||
{
|
||||
if( !b )
|
||||
{
|
||||
isObjectHandle = b;
|
||||
isObjectHandle = false;
|
||||
isConstHandle = false;
|
||||
isHandleToAsHandleType = false;
|
||||
}
|
||||
else if( b && !isObjectHandle )
|
||||
else
|
||||
{
|
||||
// Only reference types are allowed to be handles,
|
||||
// but not nohandle reference types, and not scoped references
|
||||
// (except when returned from registered function)
|
||||
// funcdefs are special reference types and support handles
|
||||
// value types with asOBJ_ASHANDLE are treated as a handle
|
||||
if( !funcDef &&
|
||||
(!objectType ||
|
||||
!((objectType->flags & asOBJ_REF) || (objectType->flags & asOBJ_TEMPLATE_SUBTYPE) || (objectType->flags & asOBJ_ASHANDLE)) ||
|
||||
(objectType->flags & asOBJ_NOHANDLE) ||
|
||||
((objectType->flags & asOBJ_SCOPED) && !acceptHandleForScope)) )
|
||||
return -1;
|
||||
if( isAuto )
|
||||
{
|
||||
isObjectHandle = true;
|
||||
}
|
||||
else if( !isObjectHandle )
|
||||
{
|
||||
// Only reference types are allowed to be handles,
|
||||
// but not nohandle reference types, and not scoped references
|
||||
// (except when returned from registered function)
|
||||
// funcdefs are special reference types and support handles
|
||||
// value types with asOBJ_ASHANDLE are treated as a handle
|
||||
if( !funcDef &&
|
||||
(!objectType ||
|
||||
!((objectType->flags & asOBJ_REF) || (objectType->flags & asOBJ_TEMPLATE_SUBTYPE) || (objectType->flags & asOBJ_ASHANDLE)) ||
|
||||
(objectType->flags & asOBJ_NOHANDLE) ||
|
||||
((objectType->flags & asOBJ_SCOPED) && !acceptHandleForScope)) )
|
||||
return -1;
|
||||
|
||||
isObjectHandle = b;
|
||||
isConstHandle = false;
|
||||
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) )
|
||||
isObjectHandle = 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) )
|
||||
{
|
||||
isObjectHandle = false;
|
||||
isHandleToAsHandleType = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int asCDataType::MakeArray(asCScriptEngine *engine)
|
||||
int asCDataType::MakeArray(asCScriptEngine *engine, asCModule *module)
|
||||
{
|
||||
if( engine->defaultArrayObjectType == 0 )
|
||||
return asINVALID_TYPE;
|
||||
@@ -263,7 +300,7 @@ int asCDataType::MakeArray(asCScriptEngine *engine)
|
||||
isReadOnly = false;
|
||||
asCArray<asCDataType> subTypes;
|
||||
subTypes.PushLast(*this);
|
||||
asCObjectType *at = engine->GetTemplateInstanceType(engine->defaultArrayObjectType, subTypes);
|
||||
asCObjectType *at = engine->GetTemplateInstanceType(engine->defaultArrayObjectType, subTypes, module);
|
||||
isReadOnly = tmpIsReadOnly;
|
||||
|
||||
isObjectHandle = false;
|
||||
@@ -305,7 +342,7 @@ int asCDataType::MakeHandleToConst(bool b)
|
||||
bool asCDataType::SupportHandles() const
|
||||
{
|
||||
if( objectType &&
|
||||
(objectType->flags & asOBJ_REF) &&
|
||||
(objectType->flags & (asOBJ_REF | asOBJ_ASHANDLE)) &&
|
||||
!(objectType->flags & asOBJ_NOHANDLE) &&
|
||||
!isObjectHandle )
|
||||
return true;
|
||||
@@ -313,19 +350,39 @@ bool asCDataType::SupportHandles() const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool asCDataType::CanBeInstanciated() const
|
||||
bool asCDataType::CanBeInstantiated() const
|
||||
{
|
||||
if( GetSizeOnStackDWords() == 0 ||
|
||||
(IsObject() &&
|
||||
(objectType->flags & asOBJ_REF) && // It's a ref type and
|
||||
((objectType->flags & asOBJ_NOHANDLE) || // the ref type doesn't support handles or
|
||||
(!IsObjectHandle() && // it's not a handle and
|
||||
objectType->beh.factories.GetLength() == 0))) ) // the ref type cannot be instanciated
|
||||
if( GetSizeOnStackDWords() == 0 ) // Void
|
||||
return false;
|
||||
|
||||
if( !IsObject() ) // 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
|
||||
return false;
|
||||
|
||||
if( (objectType->flags & asOBJ_ABSTRACT) && !IsObjectHandle() ) // Can't instantiate abstract classes
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool asCDataType::IsAbstractClass() const
|
||||
{
|
||||
return objectType && (objectType->flags & asOBJ_ABSTRACT) ? true : false;
|
||||
}
|
||||
|
||||
bool asCDataType::IsInterface() const
|
||||
{
|
||||
return objectType && objectType->IsInterface();
|
||||
}
|
||||
|
||||
bool asCDataType::CanBeCopied() const
|
||||
{
|
||||
// All primitives can be copied
|
||||
@@ -334,8 +391,8 @@ bool asCDataType::CanBeCopied() const
|
||||
// Plain-old-data structures can always be copied
|
||||
if( objectType->flags & asOBJ_POD ) return true;
|
||||
|
||||
// It must be possible to instanciate the type
|
||||
if( !CanBeInstanciated() ) return false;
|
||||
// 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 &&
|
||||
@@ -361,6 +418,14 @@ bool asCDataType::IsHandleToConst() const
|
||||
return isReadOnly;
|
||||
}
|
||||
|
||||
bool asCDataType::IsObjectConst() const
|
||||
{
|
||||
if( IsObjectHandle() )
|
||||
return IsHandleToConst();
|
||||
|
||||
return IsReadOnly();
|
||||
}
|
||||
|
||||
// TODO: 3.0.0: This should be removed
|
||||
bool asCDataType::IsArrayType() const
|
||||
{
|
||||
@@ -441,7 +506,7 @@ bool asCDataType::IsEqualExceptConst(const asCDataType &dt) const
|
||||
|
||||
bool asCDataType::IsPrimitive() const
|
||||
{
|
||||
// Enumerations are primitives
|
||||
// Enumerations are primitives
|
||||
if( IsEnumType() )
|
||||
return true;
|
||||
|
||||
@@ -456,6 +521,16 @@ bool asCDataType::IsPrimitive() const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool asCDataType::IsMathType() const
|
||||
{
|
||||
if( tokenType == ttInt || tokenType == ttInt8 || tokenType == ttInt16 || tokenType == ttInt64 ||
|
||||
tokenType == ttUInt || tokenType == ttUInt8 || tokenType == ttUInt16 || tokenType == ttUInt64 ||
|
||||
tokenType == ttFloat || tokenType == ttDouble )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool asCDataType::IsIntegerType() const
|
||||
{
|
||||
if( tokenType == ttInt ||
|
||||
@@ -505,13 +580,14 @@ bool asCDataType::IsBooleanType() const
|
||||
|
||||
bool asCDataType::IsObject() const
|
||||
{
|
||||
// Enumerations are not objects, even though they are described with an objectType.
|
||||
if( IsEnumType() )
|
||||
if( IsPrimitive() )
|
||||
return false;
|
||||
|
||||
if( objectType ) return true;
|
||||
// Null handle doesn't have an object type but should still be considered an object
|
||||
if( objectType == 0 )
|
||||
return IsNullHandle();
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
int asCDataType::GetSizeInMemoryBytes() const
|
||||
@@ -569,6 +645,19 @@ int asCDataType::GetSizeOnStackDWords() const
|
||||
return GetSizeInMemoryDWords() + size;
|
||||
}
|
||||
|
||||
#ifdef WIP_16BYTE_ALIGN
|
||||
int asCDataType::GetAlignment() const
|
||||
{
|
||||
if( objectType == NULL )
|
||||
{
|
||||
// TODO: Small primitives should not be aligned to 4 byte boundaries
|
||||
return 4; //Default alignment
|
||||
}
|
||||
|
||||
return objectType->alignment;
|
||||
}
|
||||
#endif
|
||||
|
||||
asSTypeBehaviour *asCDataType::GetBehaviour() const
|
||||
{
|
||||
return objectType ? &objectType->beh : 0;
|
||||
@@ -576,6 +665,9 @@ asSTypeBehaviour *asCDataType::GetBehaviour() const
|
||||
|
||||
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 );
|
||||
|
||||
if( objectType && (objectType->flags & asOBJ_ENUM) )
|
||||
return true;
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -49,6 +49,8 @@ struct asSTypeBehaviour;
|
||||
class asCScriptEngine;
|
||||
class asCObjectType;
|
||||
class asCScriptFunction;
|
||||
class asCModule;
|
||||
struct asSNameSpace;
|
||||
|
||||
// TODO: refactor: Reference should not be part of the datatype. This should be stored separately, e.g. in asCTypeInfo
|
||||
// MakeReference, MakeReadOnly, IsReference, IsReadOnly should be removed
|
||||
@@ -62,36 +64,45 @@ public:
|
||||
|
||||
bool IsValid() const;
|
||||
|
||||
asCString Format(bool includeNamespace = false) const;
|
||||
asCString Format(asSNameSpace *currNs, bool includeNamespace = false) const;
|
||||
|
||||
static asCDataType CreatePrimitive(eTokenType tt, bool isConst);
|
||||
static asCDataType CreateObject(asCObjectType *ot, bool isConst);
|
||||
static asCDataType CreateAuto(bool isConst);
|
||||
static asCDataType CreateObjectHandle(asCObjectType *ot, bool isConst);
|
||||
static asCDataType CreateFuncDef(asCScriptFunction *ot);
|
||||
static asCDataType CreateNullHandle();
|
||||
|
||||
int MakeHandle(bool b, bool acceptHandleForScope = false);
|
||||
int MakeArray(asCScriptEngine *engine);
|
||||
int MakeArray(asCScriptEngine *engine, asCModule *requestingModule);
|
||||
int MakeReference(bool b);
|
||||
int MakeReadOnly(bool b);
|
||||
int MakeHandleToConst(bool b);
|
||||
|
||||
bool IsTemplate() const;
|
||||
bool IsScriptObject() const;
|
||||
bool IsPrimitive() const;
|
||||
bool IsObject() const;
|
||||
bool IsReference() const {return isReference;}
|
||||
bool IsReadOnly() const;
|
||||
bool IsIntegerType() const;
|
||||
bool IsUnsignedType() const;
|
||||
bool IsFloatType() const;
|
||||
bool IsDoubleType() const;
|
||||
bool IsBooleanType() const;
|
||||
bool IsObjectHandle() const {return isObjectHandle;}
|
||||
bool IsHandleToConst() const;
|
||||
bool IsArrayType() const;
|
||||
bool IsEnumType() const;
|
||||
bool IsAnyType() const {return tokenType == ttQuestion;}
|
||||
bool IsTemplate() const;
|
||||
bool IsScriptObject() const;
|
||||
bool IsPrimitive() const;
|
||||
bool IsMathType() const;
|
||||
bool IsObject() const;
|
||||
bool IsReference() const {return isReference;}
|
||||
bool IsAuto() const {return isAuto;}
|
||||
bool IsReadOnly() const;
|
||||
bool IsIntegerType() const;
|
||||
bool IsUnsignedType() const;
|
||||
bool IsFloatType() const;
|
||||
bool IsDoubleType() const;
|
||||
bool IsBooleanType() const;
|
||||
bool IsObjectHandle() const {return isObjectHandle;}
|
||||
bool IsHandleToAuto() const {return isAuto && isObjectHandle;}
|
||||
bool IsHandleToConst() const;
|
||||
bool IsArrayType() const;
|
||||
bool IsEnumType() const;
|
||||
bool IsAnyType() const {return tokenType == ttQuestion;}
|
||||
bool IsHandleToAsHandleType() const {return isHandleToAsHandleType;}
|
||||
bool IsAbstractClass() const;
|
||||
bool IsInterface() const;
|
||||
|
||||
bool IsObjectConst() const;
|
||||
|
||||
bool IsEqualExceptRef(const asCDataType &) const;
|
||||
bool IsEqualExceptRefAndConst(const asCDataType &) const;
|
||||
@@ -99,7 +110,7 @@ public:
|
||||
bool IsNullHandle() const;
|
||||
|
||||
bool SupportHandles() const;
|
||||
bool CanBeInstanciated() const;
|
||||
bool CanBeInstantiated() const;
|
||||
bool CanBeCopied() const;
|
||||
|
||||
bool operator ==(const asCDataType &) const;
|
||||
@@ -113,6 +124,9 @@ public:
|
||||
int GetSizeOnStackDWords() const;
|
||||
int GetSizeInMemoryBytes() const;
|
||||
int GetSizeInMemoryDWords() const;
|
||||
#ifdef WIP_16BYTE_ALIGN
|
||||
int GetAlignment() const;
|
||||
#endif
|
||||
|
||||
void SetTokenType(eTokenType tt) {tokenType = tt;}
|
||||
void SetObjectType(asCObjectType *obj) {objectType = obj;}
|
||||
@@ -135,7 +149,9 @@ protected:
|
||||
bool isReadOnly:1;
|
||||
bool isObjectHandle:1;
|
||||
bool isConstHandle:1;
|
||||
char dummy:4;
|
||||
bool isAuto:1;
|
||||
bool isHandleToAsHandleType:1; // Used by the compiler to know how to initialize the object
|
||||
char dummy:2;
|
||||
};
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2012 Andreas Jonsson
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -38,12 +38,16 @@
|
||||
|
||||
#include "as_config.h"
|
||||
|
||||
#if defined(AS_DEBUG)
|
||||
|
||||
#ifndef AS_WII
|
||||
// The Wii SDK doesn't have these, we'll survive without AS_DEBUG
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
// Neither does WinCE
|
||||
|
||||
#ifndef AS_PSVITA
|
||||
// Possible on PSVita, but requires SDK access
|
||||
|
||||
#if defined(__GNUC__) || defined( AS_MARMALADE )
|
||||
|
||||
@@ -256,10 +260,17 @@ END_AS_NAMESPACE
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // AS_PSVITA
|
||||
#endif // _WIN32_WCE
|
||||
#endif // AS_WII
|
||||
|
||||
#else // !defined(AS_DEBUG)
|
||||
|
||||
// Define it so nothing is done
|
||||
#define TimeIt(x)
|
||||
|
||||
#endif // !defined(AS_DEBUG)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2013 Andreas Jonsson
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -156,7 +156,14 @@ int asCGarbageCollector::GetObjectInGC(asUINT idx, asUINT *seqNbr, void **obj, a
|
||||
return asSUCCESS;
|
||||
}
|
||||
|
||||
int asCGarbageCollector::GarbageCollect(asDWORD flags)
|
||||
// TODO: Should have a flag to tell the garbage collector to automatically determine how many iterations are needed
|
||||
// It should then gather statistics such as how many objects has been created since last run, and how many objects
|
||||
// are destroyed per iteration, and how many objects are detected as cyclic garbage per iteration.
|
||||
// It should try to reach a stable number of objects, i.e. so that on average the number of objects added to
|
||||
// the garbage collector is the same as the number of objects destroyed. And it should try to minimize the number
|
||||
// of iterations of detections that must be executed per cycle while still identifying the cyclic garbage
|
||||
// These variables should also be available for inspection through the gcstatistics.
|
||||
int asCGarbageCollector::GarbageCollect(asDWORD flags, asUINT iterations)
|
||||
{
|
||||
// If the GC is already processing in another thread, then don't enter here again
|
||||
if( TRYENTERCRITICALSECTION(gcCollecting) )
|
||||
@@ -178,9 +185,8 @@ int asCGarbageCollector::GarbageCollect(asDWORD flags)
|
||||
// Reset the state
|
||||
if( doDetect )
|
||||
{
|
||||
// Move all objects to the old list, so we guarantee that all is detected
|
||||
for( asUINT n = (asUINT)gcNewObjects.GetLength(); n-- > 0; )
|
||||
MoveObjectToOldList(n);
|
||||
// Move all new objects to the old list, so we guarantee that all is detected
|
||||
MoveAllObjectsToOldList();
|
||||
detectState = clearCounters_init;
|
||||
}
|
||||
if( doDestroy )
|
||||
@@ -189,7 +195,10 @@ int asCGarbageCollector::GarbageCollect(asDWORD flags)
|
||||
destroyOldState = destroyGarbage_init;
|
||||
}
|
||||
|
||||
unsigned int count = (unsigned int)(gcNewObjects.GetLength() + gcOldObjects.GetLength());
|
||||
// The full cycle only works with the objects in the old list so that the
|
||||
// set of objects scanned for garbage is fixed even if new objects are added
|
||||
// by other threads in parallel.
|
||||
unsigned int count = (unsigned int)(gcOldObjects.GetLength());
|
||||
for(;;)
|
||||
{
|
||||
// Detect all garbage with cyclic references
|
||||
@@ -199,25 +208,16 @@ int asCGarbageCollector::GarbageCollect(asDWORD flags)
|
||||
// Now destroy all known garbage
|
||||
if( doDestroy )
|
||||
{
|
||||
while( DestroyNewGarbage() == 1 ) {}
|
||||
if( !doDetect )
|
||||
while( DestroyNewGarbage() == 1 ) {}
|
||||
while( DestroyOldGarbage() == 1 ) {}
|
||||
}
|
||||
|
||||
// Run another iteration if any garbage was destroyed
|
||||
if( count != (unsigned int)(gcNewObjects.GetLength() + gcOldObjects.GetLength()) )
|
||||
count = (unsigned int)(gcNewObjects.GetLength() + gcOldObjects.GetLength());
|
||||
if( count != (unsigned int)(gcOldObjects.GetLength()) )
|
||||
count = (unsigned int)(gcOldObjects.GetLength());
|
||||
else
|
||||
{
|
||||
// Let the engine destroy the types that reached refCount 0
|
||||
// If none were destroyed, then leave the GC
|
||||
// TODO: The asCObjectType should destroy its content when refCount reaches 0
|
||||
// since no-one is using them. The registered types should have their
|
||||
// refcount increased by the config groups. Doing it like that will allow
|
||||
// me to remove this call to ClearUnusedTypes() that the GC really
|
||||
// shouldn't be calling.
|
||||
if( engine->ClearUnusedTypes() == 0 )
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
isProcessing = false;
|
||||
@@ -226,16 +226,19 @@ int asCGarbageCollector::GarbageCollect(asDWORD flags)
|
||||
}
|
||||
else
|
||||
{
|
||||
// Destroy the garbage that we know of
|
||||
if( doDestroy )
|
||||
while( iterations-- > 0 )
|
||||
{
|
||||
DestroyNewGarbage();
|
||||
DestroyOldGarbage();
|
||||
}
|
||||
// Destroy the garbage that we know of
|
||||
if( doDestroy )
|
||||
{
|
||||
DestroyNewGarbage();
|
||||
DestroyOldGarbage();
|
||||
}
|
||||
|
||||
// Run another incremental step of the identification of cyclic references
|
||||
if( doDetect )
|
||||
IdentifyGarbageWithCyclicRefs();
|
||||
// Run another incremental step of the identification of cyclic references
|
||||
if( doDetect && gcOldObjects.GetLength() > 0 )
|
||||
IdentifyGarbageWithCyclicRefs();
|
||||
}
|
||||
}
|
||||
|
||||
isProcessing = false;
|
||||
@@ -246,19 +249,33 @@ int asCGarbageCollector::GarbageCollect(asDWORD flags)
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TODO: Additional statistics to gather
|
||||
//
|
||||
// - How many objects are added on average between each destroyed object
|
||||
// - How many objects are added on average between each detected object
|
||||
// - how many iterations are needed for each destroyed object
|
||||
// - how many iterations are needed for each detected object
|
||||
//
|
||||
// The average must have a decay so that long running applications will not suffer
|
||||
// from objects being created early on in the application and then never destroyed.
|
||||
//
|
||||
// This ought to be possible to accomplish by holding two buckets.
|
||||
// Numbers will be accumulated in one bucket while the other is held fixed.
|
||||
// When returning the average it should use a weighted average between the two buckets using the size as weight.
|
||||
// When a bucket is filled up, the buckets are switched, and then new bucket is emptied to gather new statistics.
|
||||
void asCGarbageCollector::GetStatistics(asUINT *currentSize, asUINT *totalDestroyed, asUINT *totalDetected, asUINT *newObjects, asUINT *totalNewDestroyed) const
|
||||
{
|
||||
// It's not necessary to protect this access, as
|
||||
// it doesn't matter if another thread is currently
|
||||
// appending a new object.
|
||||
// It is not necessary to protect this with critical sections, however
|
||||
// as it is not protected the variables can be filled in slightly different
|
||||
// moments and might not match perfectly when inspected by the application
|
||||
// afterwards.
|
||||
|
||||
if( currentSize )
|
||||
*currentSize = (asUINT)(gcNewObjects.GetLength() + gcOldObjects.GetLength());
|
||||
|
||||
if( totalDestroyed )
|
||||
*totalDestroyed = numDestroyed;
|
||||
|
||||
asASSERT( numAdded == gcNewObjects.GetLength() + gcOldObjects.GetLength() + numDestroyed );
|
||||
|
||||
if( totalDetected )
|
||||
*totalDetected = numDetected;
|
||||
|
||||
@@ -328,6 +345,16 @@ void asCGarbageCollector::MoveObjectToOldList(int idx)
|
||||
LEAVECRITICALSECTION(gcCritical);
|
||||
}
|
||||
|
||||
void asCGarbageCollector::MoveAllObjectsToOldList()
|
||||
{
|
||||
// We need to protect this update with a critical section as
|
||||
// another thread might be appending an object at the same time
|
||||
ENTERCRITICALSECTION(gcCritical);
|
||||
if( gcOldObjects.Concatenate(gcNewObjects) )
|
||||
gcNewObjects.SetLength(0);
|
||||
LEAVECRITICALSECTION(gcCritical);
|
||||
}
|
||||
|
||||
int asCGarbageCollector::DestroyNewGarbage()
|
||||
{
|
||||
// This function will only be called within the critical section gcCollecting
|
||||
@@ -900,8 +927,15 @@ asCGarbageCollector::asSMapNode_t *asCGarbageCollector::GetNode(void *obj, asSIn
|
||||
if( freeNodes.GetLength() )
|
||||
node = freeNodes.PopLast();
|
||||
else
|
||||
{
|
||||
node = asNEW(asSMapNode_t);
|
||||
|
||||
if( !node )
|
||||
{
|
||||
// Out of memory
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
node->Init(obj, it);
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2013 Andreas Jonsson
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
asCGarbageCollector();
|
||||
~asCGarbageCollector();
|
||||
|
||||
int GarbageCollect(asDWORD flags);
|
||||
int GarbageCollect(asDWORD flags, asUINT iterations);
|
||||
void GetStatistics(asUINT *currentSize, asUINT *totalDestroyed, asUINT *totalDetected, asUINT *newObjects, asUINT *totalNewDestroyed) const;
|
||||
void GCEnumCallback(void *reference);
|
||||
int AddScriptObjectToGC(void *obj, asCObjectType *objType);
|
||||
@@ -104,6 +104,7 @@ protected:
|
||||
void RemoveNewObjectAtIdx(int idx);
|
||||
void RemoveOldObjectAtIdx(int idx);
|
||||
void MoveObjectToOldList(int idx);
|
||||
void MoveAllObjectsToOldList();
|
||||
|
||||
// Holds all the objects known by the garbage collector
|
||||
asCArray<asSObjTypePair> gcNewObjects;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2012 Andreas Jonsson
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -50,31 +50,32 @@ asCGlobalProperty::asCGlobalProperty()
|
||||
|
||||
asCGlobalProperty::~asCGlobalProperty()
|
||||
{
|
||||
#ifndef WIP_16BYTE_ALIGNED
|
||||
if( memoryAllocated ) { asDELETEARRAY(memory); }
|
||||
#else
|
||||
if( memoryAllocated ) { asDELETEARRAYALIGNED(memory); }
|
||||
#endif
|
||||
|
||||
if( initFunc )
|
||||
initFunc->Release();
|
||||
initFunc->ReleaseInternal();
|
||||
}
|
||||
|
||||
void asCGlobalProperty::AddRef()
|
||||
{
|
||||
gcFlag = false;
|
||||
refCount.atomicInc();
|
||||
}
|
||||
|
||||
void asCGlobalProperty::Release()
|
||||
{
|
||||
gcFlag = false;
|
||||
if( refCount.atomicDec() == 0 )
|
||||
asDELETE(this, asCGlobalProperty);
|
||||
}
|
||||
|
||||
// The property doesn't delete itself. The
|
||||
// engine will do that at a later time
|
||||
if( refCount.atomicDec() == 2 && initFunc )
|
||||
void asCGlobalProperty::DestroyInternal()
|
||||
{
|
||||
if( initFunc )
|
||||
{
|
||||
// Since the initFunc holds references to the property,
|
||||
// we'll release it when we reach refCount 2. This will
|
||||
// break the circle and allow the engine to free the property
|
||||
// without the need for the GC to attempt finding circular
|
||||
// references.
|
||||
initFunc->Release();
|
||||
initFunc->ReleaseInternal();
|
||||
initFunc = 0;
|
||||
}
|
||||
}
|
||||
@@ -92,14 +93,19 @@ void asCGlobalProperty::AllocateMemory()
|
||||
{
|
||||
if( type.GetSizeOnStackDWords() > 2 )
|
||||
{
|
||||
#ifndef WIP_16BYTE_ALIGNED
|
||||
memory = asNEWARRAY(asDWORD, type.GetSizeOnStackDWords());
|
||||
#else
|
||||
// TODO: Avoid aligned allocation if not needed to reduce the waste of memory for the alignment
|
||||
memory = asNEWARRAYALIGNED(asDWORD, type.GetSizeOnStackDWords(), type.GetAlignment());
|
||||
#endif
|
||||
memoryAllocated = true;
|
||||
}
|
||||
}
|
||||
|
||||
void asCGlobalProperty::SetRegisteredAddress(void *p)
|
||||
{
|
||||
realAddress = p;
|
||||
realAddress = p;
|
||||
if( type.IsObject() && !type.IsReference() && !type.IsObjectHandle() )
|
||||
{
|
||||
// The global property is a pointer to a pointer
|
||||
@@ -114,60 +120,13 @@ void *asCGlobalProperty::GetRegisteredAddress() const
|
||||
return realAddress;
|
||||
}
|
||||
|
||||
int asCGlobalProperty::GetRefCount()
|
||||
{
|
||||
return refCount.get();
|
||||
}
|
||||
|
||||
void asCGlobalProperty::SetGCFlag()
|
||||
{
|
||||
gcFlag = true;
|
||||
}
|
||||
|
||||
bool asCGlobalProperty::GetGCFlag()
|
||||
{
|
||||
return gcFlag;
|
||||
}
|
||||
|
||||
void asCGlobalProperty::EnumReferences(asIScriptEngine *engine)
|
||||
{
|
||||
engine->GCEnumCallback(initFunc);
|
||||
}
|
||||
|
||||
void asCGlobalProperty::ReleaseAllHandles(asIScriptEngine *)
|
||||
{
|
||||
if( initFunc )
|
||||
{
|
||||
initFunc->Release();
|
||||
initFunc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void asCGlobalProperty::Orphan(asCModule *module)
|
||||
{
|
||||
if( initFunc && initFunc->module == module )
|
||||
{
|
||||
// The owning module is releasing the property, so we need to notify
|
||||
// the GC in order to resolve any circular references that may exists
|
||||
|
||||
// This will add the property
|
||||
initFunc->engine->gc.AddScriptObjectToGC(this, &initFunc->engine->globalPropertyBehaviours);
|
||||
|
||||
// This will add the function
|
||||
initFunc->AddRef();
|
||||
initFunc->Orphan(module);
|
||||
}
|
||||
|
||||
Release();
|
||||
}
|
||||
|
||||
void asCGlobalProperty::SetInitFunc(asCScriptFunction *initFunc)
|
||||
{
|
||||
// This should only be done once
|
||||
asASSERT( this->initFunc == 0 );
|
||||
|
||||
this->initFunc = initFunc;
|
||||
this->initFunc->AddRef();
|
||||
this->initFunc->AddRefInternal();
|
||||
}
|
||||
|
||||
asCScriptFunction *asCGlobalProperty::GetInitFunc()
|
||||
@@ -175,81 +134,4 @@ asCScriptFunction *asCGlobalProperty::GetInitFunc()
|
||||
return initFunc;
|
||||
}
|
||||
|
||||
|
||||
#ifdef AS_MAX_PORTABILITY
|
||||
|
||||
static void GlobalProperty_AddRef_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
asCGlobalProperty *self = (asCGlobalProperty*)gen->GetObject();
|
||||
self->AddRef();
|
||||
}
|
||||
|
||||
static void GlobalProperty_Release_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
asCGlobalProperty *self = (asCGlobalProperty*)gen->GetObject();
|
||||
self->Release();
|
||||
}
|
||||
|
||||
static void GlobalProperty_GetRefCount_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
asCGlobalProperty *self = (asCGlobalProperty*)gen->GetObject();
|
||||
*(int*)gen->GetAddressOfReturnLocation() = self->GetRefCount();
|
||||
}
|
||||
|
||||
static void GlobalProperty_SetGCFlag_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
asCGlobalProperty *self = (asCGlobalProperty*)gen->GetObject();
|
||||
self->SetGCFlag();
|
||||
}
|
||||
|
||||
static void GlobalProperty_GetGCFlag_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
asCGlobalProperty *self = (asCGlobalProperty*)gen->GetObject();
|
||||
*(bool*)gen->GetAddressOfReturnLocation() = self->GetGCFlag();
|
||||
}
|
||||
|
||||
static void GlobalProperty_EnumReferences_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
asCGlobalProperty *self = (asCGlobalProperty*)gen->GetObject();
|
||||
asIScriptEngine *engine = *(asIScriptEngine**)gen->GetAddressOfArg(0);
|
||||
self->EnumReferences(engine);
|
||||
}
|
||||
|
||||
static void GlobalProperty_ReleaseAllHandles_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
asCGlobalProperty *self = (asCGlobalProperty*)gen->GetObject();
|
||||
asIScriptEngine *engine = *(asIScriptEngine**)gen->GetAddressOfArg(0);
|
||||
self->ReleaseAllHandles(engine);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void asCGlobalProperty::RegisterGCBehaviours(asCScriptEngine *engine)
|
||||
{
|
||||
// Register the gc behaviours for the global properties
|
||||
int r = 0;
|
||||
UNUSED_VAR(r); // It is only used in debug mode
|
||||
engine->globalPropertyBehaviours.engine = engine;
|
||||
engine->globalPropertyBehaviours.flags = asOBJ_REF | asOBJ_GC;
|
||||
engine->globalPropertyBehaviours.name = "_builtin_globalprop_";
|
||||
#ifndef AS_MAX_PORTABILITY
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_ADDREF, "void f()", asMETHOD(asCGlobalProperty,AddRef), asCALL_THISCALL, 0); asASSERT( r >= 0 );
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_RELEASE, "void f()", asMETHOD(asCGlobalProperty,Release), asCALL_THISCALL, 0); asASSERT( r >= 0 );
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_GETREFCOUNT, "int f()", asMETHOD(asCGlobalProperty,GetRefCount), asCALL_THISCALL, 0); asASSERT( r >= 0 );
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_SETGCFLAG, "void f()", asMETHOD(asCGlobalProperty,SetGCFlag), asCALL_THISCALL, 0); asASSERT( r >= 0 );
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_GETGCFLAG, "bool f()", asMETHOD(asCGlobalProperty,GetGCFlag), asCALL_THISCALL, 0); asASSERT( r >= 0 );
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_ENUMREFS, "void f(int&in)", asMETHOD(asCGlobalProperty,EnumReferences), asCALL_THISCALL, 0); asASSERT( r >= 0 );
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_RELEASEREFS, "void f(int&in)", asMETHOD(asCGlobalProperty,ReleaseAllHandles), asCALL_THISCALL, 0); asASSERT( r >= 0 );
|
||||
#else
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_ADDREF, "void f()", asFUNCTION(GlobalProperty_AddRef_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_RELEASE, "void f()", asFUNCTION(GlobalProperty_Release_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_GETREFCOUNT, "int f()", asFUNCTION(GlobalProperty_GetRefCount_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_SETGCFLAG, "void f()", asFUNCTION(GlobalProperty_SetGCFlag_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_GETGCFLAG, "bool f()", asFUNCTION(GlobalProperty_GetGCFlag_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_ENUMREFS, "void f(int&in)", asFUNCTION(GlobalProperty_EnumReferences_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->globalPropertyBehaviours, asBEHAVE_RELEASEREFS, "void f(int&in)", asFUNCTION(GlobalProperty_ReleaseAllHandles_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
@@ -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
|
||||
@@ -49,6 +49,63 @@
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
#ifdef WIP_16BYTE_ALIGN
|
||||
|
||||
// TODO: Add support for 16byte aligned application types (e.g. __m128). The following is a list of things that needs to be implemented:
|
||||
//
|
||||
// ok - The script context must make sure to always allocate the local stack memory buffer on 16byte aligned boundaries (asCContext::ReserveStackSpace)
|
||||
// ok - The engine must make sure to always allocate the memory for the script objects on 16byte aligned boundaries (asCScriptEngine::CallAlloc)
|
||||
// ok - The application needs to inform a new flag when registering types that require 16byte alignment, e.g. asOBJ_APP_ALIGN16 (asCScriptEngine::RegisterObjectType)
|
||||
// ok - The script object type must make sure to align member properties of these types correctly (asCObjectType::AddPropertyToClass)
|
||||
// ok - Script global properties must allocate memory on 16byte boundaries if holding these types (asCGlobalProperty::AllocateMemory)
|
||||
// TODO - The script compiler must make sure to allocate the local variables on 16byte boundaries (asCCompiler::AllocateVariable)
|
||||
// TODO - The script compiler must add pad bytes on the stack for all function calls to guarantee that the stack position is 16byte aligned on entry in the called function (asCCompiler)
|
||||
// TODO - The bytecode serializer must be capable of adjusting these pad bytes to guarantee platform independent saved bytecode. Remember that the registered type may not be 16byte aligned on all platforms (asCWriter & asCReader)
|
||||
// TODO - The bytecode serializer must also be prepared to adjust the position of the local variables according to the need fro 16byte alignment (asCWriter & asCReader)
|
||||
// TODO - The code for the native calling conventions must be adjusted for all platforms that should support 16byte aligned types (as_callfunc...)
|
||||
// ok - When the context needs to grow the local stack memory it must copy the function arguments so that the stack entry position is 16byte aligned (asCContext::CallScriptFunction)
|
||||
// TODO - When the context is prepared for a new call, it must set the initial stack position so the stack entry position is 16byte aligned (asCContext::Prepare)
|
||||
//
|
||||
// http://www.gamedev.net/topic/650555-alignment-requirements/
|
||||
|
||||
|
||||
// TODO: Allow user to register its own aligned memory routines
|
||||
// Wrappers for aligned allocations
|
||||
void *debugAlignedMalloc(size_t size, size_t align, const char *file, int line)
|
||||
{
|
||||
void *mem = ((asALLOCFUNCDEBUG_t)userAlloc)(size + (align-1) + sizeof(void*), file, line);
|
||||
|
||||
char *amem = ((char*)mem) + sizeof(void*);
|
||||
if( (uintptr_t)amem & (align - 1) )
|
||||
amem += align - ((uintptr_t)amem & (align - 1));
|
||||
|
||||
((void**)amem)[-1] = mem;
|
||||
return amem;
|
||||
}
|
||||
|
||||
void *alignedMalloc(size_t size, size_t align)
|
||||
{
|
||||
void *mem = userAlloc(size + (align-1) + sizeof(void*));
|
||||
|
||||
char *amem = ((char*)mem) + sizeof(void*);
|
||||
if( (uintptr_t)amem & (align - 1) )
|
||||
amem += align - ((uintptr_t)amem & (align - 1));
|
||||
|
||||
((void**)amem)[-1] = mem;
|
||||
return amem;
|
||||
}
|
||||
|
||||
void alignedFree(void *mem)
|
||||
{
|
||||
userFree( ((void**)mem)[-1] );
|
||||
}
|
||||
|
||||
bool isAligned(const void* const pointer, asUINT alignment)
|
||||
{
|
||||
return (uintptr_t(pointer) % alignment) == 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// By default we'll use the standard memory management functions
|
||||
|
||||
// Make sure these globals are initialized first. Otherwise the
|
||||
@@ -61,25 +118,47 @@ BEGIN_AS_NAMESPACE
|
||||
#pragma init_seg(lib)
|
||||
asALLOCFUNC_t userAlloc = malloc;
|
||||
asFREEFUNC_t userFree = free;
|
||||
#ifdef WIP_16BYTE_ALIGN
|
||||
#ifdef AS_DEBUG
|
||||
asALLOCALIGNEDFUNC_t userAllocAligned = (asALLOCALIGNEDFUNC_t)debugAlignedMalloc;
|
||||
#else
|
||||
asALLOCALIGNEDFUNC_t userAllocAligned = alignedMalloc;
|
||||
#endif
|
||||
asFREEALIGNEDFUNC_t userFreeAligned = alignedFree;
|
||||
#endif
|
||||
#else
|
||||
// Other compilers will just have to rely on luck.
|
||||
asALLOCFUNC_t userAlloc = malloc;
|
||||
asFREEFUNC_t userFree = free;
|
||||
#ifdef WIP_16BYTE_ALIGN
|
||||
asALLOCALIGNEDFUNC_t userAllocAligned = alignedMalloc;
|
||||
asFREEALIGNEDFUNC_t userFreeAligned = alignedFree;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
// interface
|
||||
int asSetGlobalMemoryFunctions(asALLOCFUNC_t allocFunc, asFREEFUNC_t freeFunc)
|
||||
{
|
||||
// Clean-up thread local memory before changing the allocation routines to avoid
|
||||
// potential problem with trying to free memory using a different allocation
|
||||
// routine than used when allocating it.
|
||||
asThreadCleanup();
|
||||
|
||||
userAlloc = allocFunc;
|
||||
userFree = freeFunc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// interface
|
||||
int asResetGlobalMemoryFunctions()
|
||||
{
|
||||
// Clean-up thread local memory before changing the allocation routines to avoid
|
||||
// potential problem with trying to free memory using a different allocation
|
||||
// routine than used when allocating it.
|
||||
asThreadCleanup();
|
||||
|
||||
userAlloc = malloc;
|
||||
@@ -88,6 +167,18 @@ int asResetGlobalMemoryFunctions()
|
||||
return 0;
|
||||
}
|
||||
|
||||
// interface
|
||||
void *asAllocMem(size_t size)
|
||||
{
|
||||
return asNEWARRAY(asBYTE, size);
|
||||
}
|
||||
|
||||
// interface
|
||||
void asFreeMem(void *mem)
|
||||
{
|
||||
asDELETEARRAY(mem);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
asCMemoryMgr::asCMemoryMgr()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2012 Andreas Jonsson
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -48,6 +48,25 @@ BEGIN_AS_NAMESPACE
|
||||
extern asALLOCFUNC_t userAlloc;
|
||||
extern asFREEFUNC_t userFree;
|
||||
|
||||
#ifdef WIP_16BYTE_ALIGN
|
||||
|
||||
// TODO: This declaration should be in angelscript.h
|
||||
// when the application can register it's own
|
||||
// aligned memory routines
|
||||
typedef void *(*asALLOCALIGNEDFUNC_t)(size_t, size_t);
|
||||
typedef void (*asFREEALIGNEDFUNC_t)(void *);
|
||||
extern asALLOCALIGNEDFUNC_t userAllocAligned;
|
||||
extern asFREEALIGNEDFUNC_t userFreeAligned;
|
||||
typedef void *(*asALLOCALIGNEDFUNCDEBUG_t)(size_t, size_t, const char *, unsigned int);
|
||||
|
||||
// The maximum type alignment supported.
|
||||
const int MAX_TYPE_ALIGNMENT = 16;
|
||||
|
||||
// Utility function used for assertions.
|
||||
bool isAligned(const void* const pointer, asUINT alignment);
|
||||
|
||||
#endif // WIP_16BYTE_ALIGN
|
||||
|
||||
// We don't overload the new operator as that would affect the application as well
|
||||
|
||||
#ifndef AS_DEBUG
|
||||
@@ -58,6 +77,11 @@ extern asFREEFUNC_t userFree;
|
||||
#define asNEWARRAY(x,cnt) (x*)userAlloc(sizeof(x)*cnt)
|
||||
#define asDELETEARRAY(ptr) userFree(ptr)
|
||||
|
||||
#ifdef WIP_16BYTE_ALIGN
|
||||
#define asNEWARRAYALIGNED(x,cnt, alignment) (x*)userAllocAligned(sizeof(x)*cnt, alignment)
|
||||
#define asDELETEARRAYALIGNED(ptr) userFreeAligned(ptr)
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
typedef void *(*asALLOCFUNCDEBUG_t)(size_t, const char *, unsigned int);
|
||||
@@ -68,6 +92,12 @@ extern asFREEFUNC_t userFree;
|
||||
#define asNEWARRAY(x,cnt) (x*)((asALLOCFUNCDEBUG_t)(userAlloc))(sizeof(x)*cnt, __FILE__, __LINE__)
|
||||
#define asDELETEARRAY(ptr) userFree(ptr)
|
||||
|
||||
#ifdef WIP_16BYTE_ALIGN
|
||||
//TODO: Equivalent of debug allocation function with alignment?
|
||||
#define asNEWARRAYALIGNED(x,cnt, alignment) (x*)userAllocAligned(sizeof(x)*cnt, alignment)
|
||||
#define asDELETEARRAYALIGNED(ptr) userFreeAligned(ptr)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
@@ -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
|
||||
@@ -46,6 +46,33 @@
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
// TODO: 2.30.0: redesign: Improved method for discarding modules (faster clean-up, less abuse of garbage collector)
|
||||
//
|
||||
// I need to separate the reference counter for internal references and outside references:
|
||||
//
|
||||
// - Internal references are for example, when the module refers to a function or object since it is declared in the module, or when
|
||||
// a function refers to another function since it is being called in the code.
|
||||
// - Outside references are for example object instances holding a reference to the object type, or a context currently
|
||||
// executing a function.
|
||||
//
|
||||
// If no object instances are alive or no contexts are alive it is known that functions from a discarded module
|
||||
// can be called, so they can be destroyed without any need to execute the complex garbage collection routines.
|
||||
//
|
||||
// If there are live objects, the entire module should be kept for safe keeping, though no longer visible.
|
||||
//
|
||||
// TODO: It may not be necessary to keep track of internal references. Without keeping track of internal references, can I still
|
||||
// handle RemoveFunction and RemoveGlobalVariable correctly?
|
||||
//
|
||||
// TODO: How to avoid global variables keeping code alive? For example a script object, or a funcdef?
|
||||
// Can I do a quick check of the object types and functions to count number of outside references, and then do another
|
||||
// check over the global variables to subtract the outside references coming from these? What if the outside reference
|
||||
// is added by an application type in a global variable that the engine doesn't know about? Example, a global dictionary
|
||||
// holding object instances. Should discarding a module immediately destroy the content of the global variables? What if
|
||||
// a live object tries to access the global variable after it has been discarded? Throwing a script exception is acceptable?
|
||||
// Perhaps I need to allow the user to provide a clean-up routine that will be executed before destroying the objects.
|
||||
// Or I might just put that responsibility on the application.
|
||||
|
||||
|
||||
// internal
|
||||
asCModule::asCModule(const char *name, asCScriptEngine *engine)
|
||||
{
|
||||
@@ -66,6 +93,8 @@ asCModule::~asCModule()
|
||||
{
|
||||
InternalReset();
|
||||
|
||||
// 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 )
|
||||
{
|
||||
asDELETE(builder,asCBuilder);
|
||||
@@ -75,34 +104,114 @@ asCModule::~asCModule()
|
||||
if( engine )
|
||||
{
|
||||
// Clean the user data
|
||||
if( userData && engine->cleanModuleFunc )
|
||||
engine->cleanModuleFunc(this);
|
||||
for( asUINT n = 0; n < userData.GetLength(); n += 2 )
|
||||
{
|
||||
if( userData[n+1] )
|
||||
{
|
||||
for( asUINT c = 0; c < engine->cleanModuleFuncs.GetLength(); c++ )
|
||||
if( engine->cleanModuleFuncs[c].type == userData[n] )
|
||||
engine->cleanModuleFuncs[c].cleanFunc(this);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the module from the engine
|
||||
if( engine->lastModule == this )
|
||||
engine->lastModule = 0;
|
||||
engine->scriptModules.RemoveValue(this);
|
||||
ACQUIREEXCLUSIVE(engine->engineRWLock);
|
||||
// The module must have been discarded before it is deleted
|
||||
asASSERT( !engine->scriptModules.Exists(this) );
|
||||
engine->discardedModules.RemoveValue(this);
|
||||
RELEASEEXCLUSIVE(engine->engineRWLock);
|
||||
}
|
||||
}
|
||||
|
||||
// interface
|
||||
void asCModule::Discard()
|
||||
{
|
||||
asDELETE(this,asCModule);
|
||||
// Reset the global variables already so that no object in the global variables keep the module alive forever.
|
||||
// If any live object tries to access the global variables during clean up they will fail with a script exception,
|
||||
// so the application must keep that in mind before discarding a module.
|
||||
CallExit();
|
||||
|
||||
// Keep a local copy of the engine pointer, because once the module is moved do the discarded
|
||||
// pile, it is possible that another thread might discard it while we are still in here. So no
|
||||
// further access to members may be done after that
|
||||
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
|
||||
// external references to its entities have been released.
|
||||
ACQUIREEXCLUSIVE(engine->engineRWLock);
|
||||
if( lEngine->lastModule == this )
|
||||
lEngine->lastModule = 0;
|
||||
lEngine->scriptModules.RemoveValue(this);
|
||||
lEngine->discardedModules.PushLast(this);
|
||||
RELEASEEXCLUSIVE(lEngine->engineRWLock);
|
||||
|
||||
// Allow the engine to go over the list of discarded modules to see what can be cleaned up at this moment.
|
||||
// Don't do this if the engine is already shutting down, as it will be done explicitly by the engine itself with error reporting
|
||||
if( !lEngine->shuttingDown )
|
||||
{
|
||||
if( lEngine->ep.autoGarbageCollect )
|
||||
lEngine->GarbageCollect();
|
||||
else
|
||||
{
|
||||
// GarbageCollect calls DeleteDiscardedModules, so no need
|
||||
// to call it again if we already called GarbageCollect
|
||||
lEngine->DeleteDiscardedModules();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// interface
|
||||
void *asCModule::SetUserData(void *data)
|
||||
void *asCModule::SetUserData(void *data, asPWORD type)
|
||||
{
|
||||
void *oldData = userData;
|
||||
userData = data;
|
||||
return oldData;
|
||||
// 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);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// interface
|
||||
void *asCModule::GetUserData() const
|
||||
void *asCModule::GetUserData(asPWORD type) const
|
||||
{
|
||||
return userData;
|
||||
// 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 )
|
||||
{
|
||||
void *ud = reinterpret_cast<void*>(userData[n+1]);
|
||||
RELEASESHARED(engine->engineRWLock);
|
||||
return ud;
|
||||
}
|
||||
}
|
||||
|
||||
RELEASESHARED(engine->engineRWLock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// interface
|
||||
@@ -204,6 +313,15 @@ int asCModule::Build()
|
||||
#else
|
||||
TimeIt("asCModule::Build");
|
||||
|
||||
// Don't allow the module to be rebuilt if there are still
|
||||
// external references that will need the previous code
|
||||
// TODO: 2.30.0: interface: The asIScriptModule must have a method for querying if the module is used
|
||||
if( HasExternalReferences(false) )
|
||||
{
|
||||
engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_MODULE_IS_IN_USE);
|
||||
return asMODULE_IS_IN_USE;
|
||||
}
|
||||
|
||||
// Only one thread may build at one time
|
||||
// TODO: It should be possible to have multiple threads perform compilations
|
||||
int r = engine->RequestBuild();
|
||||
@@ -218,7 +336,7 @@ int asCModule::Build()
|
||||
return asINVALID_CONFIGURATION;
|
||||
}
|
||||
|
||||
InternalReset();
|
||||
InternalReset();
|
||||
|
||||
if( !builder )
|
||||
{
|
||||
@@ -306,8 +424,8 @@ int asCModule::CallInit(asIScriptContext *myCtx)
|
||||
{
|
||||
if( ctx == 0 )
|
||||
{
|
||||
r = engine->CreateContext(&ctx, true);
|
||||
if( r < 0 )
|
||||
ctx = engine->RequestContext();
|
||||
if( ctx == 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -346,7 +464,7 @@ int asCModule::CallInit(asIScriptContext *myCtx)
|
||||
|
||||
if( ctx && !myCtx )
|
||||
{
|
||||
ctx->Release();
|
||||
engine->ReturnContext(ctx);
|
||||
ctx = 0;
|
||||
}
|
||||
|
||||
@@ -401,33 +519,98 @@ void asCModule::CallExit()
|
||||
isGlobalVarInitialized = false;
|
||||
}
|
||||
|
||||
// internal
|
||||
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.
|
||||
|
||||
for( asUINT n = 0; n < scriptFunctions.GetLength(); n++ )
|
||||
if( scriptFunctions[n] && scriptFunctions[n]->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());
|
||||
|
||||
msg.Format(TXT_PREV_FUNC_IS_NAMED_s_TYPE_IS_d, scriptFunctions[n]->GetName(), scriptFunctions[n]->GetFuncType());
|
||||
engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, msg.AddressOf());
|
||||
}
|
||||
}
|
||||
|
||||
for( asUINT n = 0; n < classTypes.GetLength(); n++ )
|
||||
if( classTypes[n] && classTypes[n]->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());
|
||||
|
||||
msg.Format(TXT_PREV_TYPE_IS_NAMED_s, classTypes[n]->GetName());
|
||||
engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, msg.AddressOf());
|
||||
}
|
||||
}
|
||||
|
||||
for( asUINT n = 0; n < funcDefs.GetLength(); n++ )
|
||||
if( funcDefs[n] && funcDefs[n]->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());
|
||||
|
||||
msg.Format(TXT_PREV_FUNC_IS_NAMED_s_TYPE_IS_d, funcDefs[n]->GetName(), funcDefs[n]->GetFuncType());
|
||||
engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, msg.AddressOf());
|
||||
}
|
||||
}
|
||||
|
||||
for( asUINT n = 0; n < templateInstances.GetLength(); n++ )
|
||||
if( templateInstances[n] && templateInstances[n]->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());
|
||||
|
||||
msg.Format(TXT_PREV_TYPE_IS_NAMED_s, templateInstances[n]->GetName());
|
||||
engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, msg.AddressOf());
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// internal
|
||||
void asCModule::InternalReset()
|
||||
{
|
||||
CallExit();
|
||||
|
||||
size_t n;
|
||||
asUINT n;
|
||||
|
||||
// Release all global functions
|
||||
asCSymbolTable<asCScriptFunction>::iterator funcIt = globalFunctions.List();
|
||||
for( ; funcIt; funcIt++ )
|
||||
(*funcIt)->Release();
|
||||
// Remove all global functions
|
||||
globalFunctions.Clear();
|
||||
|
||||
// First release all compiled functions
|
||||
for( n = 0; n < scriptFunctions.GetLength(); n++ )
|
||||
if( scriptFunctions[n] )
|
||||
scriptFunctions[n]->Orphan(this);
|
||||
scriptFunctions.SetLength(0);
|
||||
|
||||
// Release the global properties declared in the module
|
||||
// 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();
|
||||
while( globIt )
|
||||
{
|
||||
(*globIt)->Orphan(this);
|
||||
(*globIt)->DestroyInternal();
|
||||
globIt++;
|
||||
}
|
||||
scriptGlobals.Clear();
|
||||
|
||||
UnbindAllImportedFunctions();
|
||||
|
||||
@@ -436,39 +619,156 @@ void asCModule::InternalReset()
|
||||
{
|
||||
if( bindInformations[n] )
|
||||
{
|
||||
asUINT id = bindInformations[n]->importedFunctionSignature->id & ~FUNC_IMPORTED;
|
||||
engine->importedFunctions[id] = 0;
|
||||
engine->freeImportedFunctionIdxs.PushLast(id);
|
||||
bindInformations[n]->importedFunctionSignature->ReleaseInternal();
|
||||
|
||||
asDELETE(bindInformations[n]->importedFunctionSignature, asCScriptFunction);
|
||||
asDELETE(bindInformations[n], sBindInfo);
|
||||
}
|
||||
}
|
||||
bindInformations.SetLength(0);
|
||||
|
||||
// Free declared types, including classes, typedefs, and enums
|
||||
// TODO: optimize: Check if it is possible to destroy the object directly without notifying the GC
|
||||
for( n = 0; n < templateInstances.GetLength(); n++ )
|
||||
{
|
||||
asCObjectType *type = templateInstances[n];
|
||||
if( engine->FindNewOwnerForSharedType(type, this) != this )
|
||||
{
|
||||
// The type is owned by another module, just release our reference
|
||||
type->ReleaseInternal();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Orphan the template instance
|
||||
type->module = 0;
|
||||
|
||||
// No other module is holding the template type
|
||||
engine->RemoveTemplateInstanceType(type);
|
||||
type->ReleaseInternal();
|
||||
}
|
||||
templateInstances.SetLength(0);
|
||||
for( n = 0; n < classTypes.GetLength(); n++ )
|
||||
classTypes[n]->Orphan(this);
|
||||
{
|
||||
asCObjectType *type = classTypes[n];
|
||||
if( type->IsShared() )
|
||||
{
|
||||
// The type is shared, so transfer ownership to another module that also uses it
|
||||
if( engine->FindNewOwnerForSharedType(type, this) != this )
|
||||
{
|
||||
// The type is owned by another module, just release our reference
|
||||
type->ReleaseInternal();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// The type should be destroyed now
|
||||
type->DestroyInternal();
|
||||
|
||||
// Remove the type from the engine
|
||||
if( type->IsShared() )
|
||||
{
|
||||
engine->sharedScriptTypes.RemoveValue(type);
|
||||
type->ReleaseInternal();
|
||||
}
|
||||
|
||||
// Release it from the module
|
||||
type->module = 0;
|
||||
type->ReleaseInternal();
|
||||
}
|
||||
classTypes.SetLength(0);
|
||||
for( n = 0; n < enumTypes.GetLength(); n++ )
|
||||
enumTypes[n]->Release();
|
||||
{
|
||||
asCObjectType *type = enumTypes[n];
|
||||
if( type->IsShared() )
|
||||
{
|
||||
// The type is shared, so transfer ownership to another module that also uses it
|
||||
if( engine->FindNewOwnerForSharedType(type, this) != this )
|
||||
{
|
||||
// The type is owned by another module, just release our reference
|
||||
type->ReleaseInternal();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// The type should be destroyed now
|
||||
type->DestroyInternal();
|
||||
|
||||
// Remove the type from the engine
|
||||
if( type->IsShared() )
|
||||
{
|
||||
engine->sharedScriptTypes.RemoveValue(type);
|
||||
type->ReleaseInternal();
|
||||
}
|
||||
|
||||
// Release it from the module
|
||||
type->module = 0;
|
||||
type->ReleaseInternal();
|
||||
}
|
||||
enumTypes.SetLength(0);
|
||||
for( n = 0; n < typeDefs.GetLength(); n++ )
|
||||
typeDefs[n]->Release();
|
||||
{
|
||||
asCObjectType *type = typeDefs[n];
|
||||
|
||||
// The type should be destroyed now
|
||||
type->DestroyInternal();
|
||||
|
||||
// Release it from the module
|
||||
type->module = 0;
|
||||
type->ReleaseInternal();
|
||||
}
|
||||
typeDefs.SetLength(0);
|
||||
|
||||
// Free funcdefs
|
||||
for( n = 0; n < funcDefs.GetLength(); n++ )
|
||||
{
|
||||
// The funcdefs are not removed from the engine at this moment as they may still be referred
|
||||
// to by other types. The engine's ClearUnusedTypes will take care of the clean up.
|
||||
funcDefs[n]->Release();
|
||||
asCScriptFunction *func = funcDefs[n];
|
||||
if( func->IsShared() )
|
||||
{
|
||||
// The func is shared, so transfer ownership to another module that also uses it
|
||||
if( engine->FindNewOwnerForSharedFunc(func, this) != this )
|
||||
{
|
||||
// The func is owned by another module, just release our reference
|
||||
func->ReleaseInternal();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
func->DestroyInternal();
|
||||
engine->RemoveFuncdef(func);
|
||||
func->module = 0;
|
||||
func->ReleaseInternal();
|
||||
}
|
||||
funcDefs.SetLength(0);
|
||||
|
||||
// Allow the engine to clean up what is not used
|
||||
engine->CleanupAfterDiscardModule();
|
||||
// Then release the functions
|
||||
for( n = 0; n < scriptFunctions.GetLength(); n++ )
|
||||
{
|
||||
asCScriptFunction *func = scriptFunctions[n];
|
||||
if( func->IsShared() )
|
||||
{
|
||||
// The func is shared, so transfer ownership to another module that also uses it
|
||||
if( engine->FindNewOwnerForSharedFunc(func, this) != this )
|
||||
{
|
||||
// The func is owned by another module, just release our reference
|
||||
func->ReleaseInternal();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
func->DestroyInternal();
|
||||
func->module = 0;
|
||||
func->ReleaseInternal();
|
||||
}
|
||||
scriptFunctions.SetLength(0);
|
||||
|
||||
// Now remove and release the global properties as there are no more references to them
|
||||
globIt = scriptGlobals.List();
|
||||
while( globIt )
|
||||
{
|
||||
engine->RemoveGlobalProperty(*globIt);
|
||||
asASSERT( (*globIt)->refCount.get() == 1 );
|
||||
(*globIt)->Release();
|
||||
globIt++;
|
||||
}
|
||||
scriptGlobals.Clear();
|
||||
|
||||
asASSERT( IsEmpty() );
|
||||
}
|
||||
@@ -476,12 +776,22 @@ void asCModule::InternalReset()
|
||||
// interface
|
||||
asIScriptFunction *asCModule::GetFunctionByName(const char *name) const
|
||||
{
|
||||
const asCArray<unsigned int> &idxs = globalFunctions.GetIndexes(defaultNamespace, name);
|
||||
if( idxs.GetLength() != 1 )
|
||||
return 0;
|
||||
asSNameSpace *ns = defaultNamespace;
|
||||
while( ns )
|
||||
{
|
||||
const asCArray<unsigned int> &idxs = globalFunctions.GetIndexes(ns, name);
|
||||
if( idxs.GetLength() != 1 )
|
||||
return 0;
|
||||
|
||||
const asIScriptFunction *func = globalFunctions.Get(idxs[0]);
|
||||
return const_cast<asIScriptFunction*>(func);
|
||||
const asIScriptFunction *func = globalFunctions.Get(idxs[0]);
|
||||
if( func )
|
||||
return const_cast<asIScriptFunction*>(func);
|
||||
|
||||
// Recursively search parent namespaces
|
||||
ns = engine->GetParentNameSpace(ns);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// interface
|
||||
@@ -562,38 +872,49 @@ asIScriptFunction *asCModule::GetFunctionByDecl(const char *decl) const
|
||||
asSNameSpace *ns = func.nameSpace == engine->nameSpaces[0] ? defaultNamespace : func.nameSpace;
|
||||
|
||||
// Search script functions for matching interface
|
||||
asIScriptFunction *f = 0;
|
||||
const asCArray<unsigned int> &idxs = globalFunctions.GetIndexes(ns, func.name);
|
||||
for( unsigned int n = 0; n < idxs.GetLength(); n++ )
|
||||
while( ns )
|
||||
{
|
||||
const asCScriptFunction *funcPtr = globalFunctions.Get(idxs[n]);
|
||||
if( funcPtr->objectType == 0 &&
|
||||
func.returnType == funcPtr->returnType &&
|
||||
func.parameterTypes.GetLength() == funcPtr->parameterTypes.GetLength()
|
||||
)
|
||||
asIScriptFunction *f = 0;
|
||||
const asCArray<unsigned int> &idxs = globalFunctions.GetIndexes(ns, func.name);
|
||||
for( unsigned int n = 0; n < idxs.GetLength(); n++ )
|
||||
{
|
||||
bool match = true;
|
||||
for( size_t p = 0; p < func.parameterTypes.GetLength(); ++p )
|
||||
const asCScriptFunction *funcPtr = globalFunctions.Get(idxs[n]);
|
||||
if( funcPtr->objectType == 0 &&
|
||||
func.returnType == funcPtr->returnType &&
|
||||
func.parameterTypes.GetLength() == funcPtr->parameterTypes.GetLength()
|
||||
)
|
||||
{
|
||||
if( func.parameterTypes[p] != funcPtr->parameterTypes[p] )
|
||||
bool match = true;
|
||||
for( asUINT p = 0; p < func.parameterTypes.GetLength(); ++p )
|
||||
{
|
||||
match = false;
|
||||
break;
|
||||
if( func.parameterTypes[p] != funcPtr->parameterTypes[p] )
|
||||
{
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( match )
|
||||
{
|
||||
if( f == 0 )
|
||||
f = const_cast<asCScriptFunction*>(funcPtr);
|
||||
else
|
||||
// Multiple functions
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( match )
|
||||
{
|
||||
if( f == 0 )
|
||||
f = const_cast<asCScriptFunction*>(funcPtr);
|
||||
else
|
||||
// Multiple functions
|
||||
return 0;
|
||||
}
|
||||
if( f )
|
||||
return f;
|
||||
else
|
||||
{
|
||||
// Search for matching functions in the parent namespace
|
||||
ns = engine->GetParentNameSpace(ns);
|
||||
}
|
||||
}
|
||||
|
||||
return f;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// interface
|
||||
@@ -605,21 +926,41 @@ asUINT asCModule::GetGlobalVarCount() const
|
||||
// interface
|
||||
int asCModule::GetGlobalVarIndexByName(const char *name) const
|
||||
{
|
||||
asSNameSpace *ns = defaultNamespace;
|
||||
|
||||
// Find the global var id
|
||||
int id = scriptGlobals.GetFirstIndex(defaultNamespace, name);
|
||||
while( ns )
|
||||
{
|
||||
int id = scriptGlobals.GetFirstIndex(ns, name);
|
||||
if( id >= 0 ) return id;
|
||||
|
||||
if( id == -1 ) return asNO_GLOBAL_VAR;
|
||||
// Recursively search parent namespaces
|
||||
ns = engine->GetParentNameSpace(ns);
|
||||
}
|
||||
|
||||
return id;
|
||||
return asNO_GLOBAL_VAR;
|
||||
}
|
||||
|
||||
// interface
|
||||
int asCModule::RemoveGlobalVar(asUINT index)
|
||||
{
|
||||
// TODO: 2.30.0: redesign: Before removing the variable, clear it to free the object
|
||||
// The property shouldn't be orphaned.
|
||||
|
||||
asCGlobalProperty *prop = scriptGlobals.Get(index);
|
||||
if( !prop )
|
||||
return asINVALID_ARG;
|
||||
prop->Orphan(this);
|
||||
|
||||
// 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
|
||||
// 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);
|
||||
|
||||
return 0;
|
||||
@@ -641,9 +982,15 @@ int asCModule::GetGlobalVarIndexByDecl(const char *decl) const
|
||||
return r;
|
||||
|
||||
// Search global variables for a match
|
||||
int id = scriptGlobals.GetFirstIndex(nameSpace, name, asCCompGlobPropType(dt));
|
||||
if( id != -1 )
|
||||
return id;
|
||||
while( nameSpace )
|
||||
{
|
||||
int id = scriptGlobals.GetFirstIndex(nameSpace, name, asCCompGlobPropType(dt));
|
||||
if( id != -1 )
|
||||
return id;
|
||||
|
||||
// Recursively search parent namespace
|
||||
nameSpace = engine->GetParentNameSpace(nameSpace);
|
||||
}
|
||||
|
||||
return asNO_GLOBAL_VAR;
|
||||
}
|
||||
@@ -670,9 +1017,9 @@ const char *asCModule::GetGlobalVarDeclaration(asUINT index, bool includeNamespa
|
||||
if (!prop) return 0;
|
||||
|
||||
asCString *tempString = &asCThreadManager::GetLocalData()->string;
|
||||
*tempString = prop->type.Format();
|
||||
*tempString = prop->type.Format(defaultNamespace);
|
||||
*tempString += " ";
|
||||
if( includeNamespace )
|
||||
if( includeNamespace && prop->nameSpace->name != "" )
|
||||
*tempString += prop->nameSpace->name + "::";
|
||||
*tempString += prop->name;
|
||||
|
||||
@@ -715,12 +1062,19 @@ asIObjectType *asCModule::GetObjectTypeByIndex(asUINT index) const
|
||||
// interface
|
||||
asIObjectType *asCModule::GetObjectTypeByName(const char *name) const
|
||||
{
|
||||
for( asUINT n = 0; n < classTypes.GetLength(); n++ )
|
||||
asSNameSpace *ns = defaultNamespace;
|
||||
while( ns )
|
||||
{
|
||||
if( classTypes[n] &&
|
||||
classTypes[n]->name == name &&
|
||||
classTypes[n]->nameSpace == defaultNamespace )
|
||||
return classTypes[n];
|
||||
for( asUINT n = 0; n < classTypes.GetLength(); n++ )
|
||||
{
|
||||
if( classTypes[n] &&
|
||||
classTypes[n]->name == name &&
|
||||
classTypes[n]->nameSpace == ns )
|
||||
return classTypes[n];
|
||||
}
|
||||
|
||||
// Recursively search parent namespace
|
||||
ns = engine->GetParentNameSpace(ns);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -744,6 +1098,24 @@ int asCModule::GetTypeIdByDecl(const char *decl) const
|
||||
return engine->GetTypeIdFromDataType(dt);
|
||||
}
|
||||
|
||||
// interface
|
||||
asIObjectType *asCModule::GetObjectTypeByDecl(const char *decl) const
|
||||
{
|
||||
asCDataType dt;
|
||||
|
||||
// This const cast is safe since we know the engine won't be modified
|
||||
asCBuilder bld(engine, const_cast<asCModule*>(this));
|
||||
|
||||
// Don't write parser errors to the message callback
|
||||
bld.silent = true;
|
||||
|
||||
int r = bld.ParseDataType(decl, &dt, defaultNamespace);
|
||||
if( r < 0 )
|
||||
return 0;
|
||||
|
||||
return dt.GetObjectType();
|
||||
}
|
||||
|
||||
// interface
|
||||
asUINT asCModule::GetEnumCount() const
|
||||
{
|
||||
@@ -827,7 +1199,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> ¶ms, const asCArray<asETypeModifiers> &inOutFlags, const asCArray<asCString *> &defaultArgs, bool isInterface, asCObjectType *objType, bool isConstMethod, bool isGlobalFunction, bool isPrivate, bool isFinal, bool isOverride, bool isShared, asSNameSpace *ns)
|
||||
int asCModule::AddScriptFunction(int sectionIdx, int declaredAt, int id, const asCString &name, const asCDataType &returnType, const asCArray<asCDataType> ¶ms, const asCArray<asCString> ¶mNames, 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)
|
||||
{
|
||||
asASSERT(id >= 0);
|
||||
|
||||
@@ -860,11 +1232,15 @@ int asCModule::AddScriptFunction(int sectionIdx, int declaredAt, int id, const a
|
||||
func->scriptData->declaredAt = declaredAt;
|
||||
}
|
||||
func->parameterTypes = params;
|
||||
func->parameterNames = paramNames;
|
||||
func->inOutFlags = inOutFlags;
|
||||
func->defaultArgs = defaultArgs;
|
||||
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;
|
||||
@@ -875,9 +1251,9 @@ int asCModule::AddScriptFunction(int sectionIdx, int declaredAt, int id, const a
|
||||
asASSERT( !(!objType && isFinal) );
|
||||
asASSERT( !(!objType && isOverride) );
|
||||
|
||||
// The script function's refCount was initialized to 1
|
||||
// The internal ref count was already set by the constructor
|
||||
scriptFunctions.PushLast(func);
|
||||
engine->SetScriptFunction(func);
|
||||
engine->AddScriptFunction(func);
|
||||
|
||||
// Compute the signature id
|
||||
if( objType )
|
||||
@@ -885,10 +1261,7 @@ int asCModule::AddScriptFunction(int sectionIdx, int declaredAt, int id, const a
|
||||
|
||||
// Add reference
|
||||
if( isGlobalFunction )
|
||||
{
|
||||
globalFunctions.Put(func);
|
||||
func->AddRef();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -897,8 +1270,8 @@ int asCModule::AddScriptFunction(int sectionIdx, int declaredAt, int id, const a
|
||||
int asCModule::AddScriptFunction(asCScriptFunction *func)
|
||||
{
|
||||
scriptFunctions.PushLast(func);
|
||||
func->AddRef();
|
||||
engine->SetScriptFunction(func);
|
||||
func->AddRefInternal();
|
||||
engine->AddScriptFunction(func);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -982,14 +1355,14 @@ int asCModule::BindImportedFunction(asUINT index, asIScriptFunction *func)
|
||||
if( dst->parameterTypes.GetLength() != src->parameterTypes.GetLength() )
|
||||
return asINVALID_INTERFACE;
|
||||
|
||||
for( size_t n = 0; n < dst->parameterTypes.GetLength(); ++n )
|
||||
for( asUINT n = 0; n < dst->parameterTypes.GetLength(); ++n )
|
||||
{
|
||||
if( dst->parameterTypes[n] != src->parameterTypes[n] )
|
||||
return asINVALID_INTERFACE;
|
||||
}
|
||||
|
||||
bindInformations[index]->boundFunctionId = src->GetId();
|
||||
src->AddRef();
|
||||
src->AddRefInternal();
|
||||
|
||||
return asSUCCESS;
|
||||
}
|
||||
@@ -1007,7 +1380,7 @@ int asCModule::UnbindImportedFunction(asUINT index)
|
||||
if( oldFuncID != -1 )
|
||||
{
|
||||
bindInformations[index]->boundFunctionId = -1;
|
||||
engine->scriptFunctions[oldFuncID]->Release();
|
||||
engine->scriptFunctions[oldFuncID]->ReleaseInternal();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1047,7 +1420,7 @@ int asCModule::BindAllImportedFunctions()
|
||||
asCScriptFunction *importFunc = GetImportedFunction(n);
|
||||
if( importFunc == 0 ) return asERROR;
|
||||
|
||||
asCString str = importFunc->GetDeclarationStr();
|
||||
asCString str = importFunc->GetDeclarationStr(false, true);
|
||||
|
||||
// Get module name from where the function should be imported
|
||||
const char *moduleName = GetImportedFunctionSourceModule(n);
|
||||
@@ -1086,7 +1459,7 @@ int asCModule::UnbindAllImportedFunctions()
|
||||
// internal
|
||||
asCObjectType *asCModule::GetObjectType(const char *type, asSNameSpace *ns)
|
||||
{
|
||||
size_t n;
|
||||
asUINT n;
|
||||
|
||||
// TODO: optimize: Improve linear search
|
||||
for( n = 0; n < classTypes.GetLength(); n++ )
|
||||
@@ -1121,8 +1494,9 @@ asCGlobalProperty *asCModule::AllocateGlobalProperty(const char *name, const asC
|
||||
// Make an entry in the address to variable map
|
||||
engine->varAddressMap.Insert(prop->GetAddressOfValue(), prop);
|
||||
|
||||
// Store the variable in the module scope (the reference count is already set to 1)
|
||||
// Store the variable in the module scope
|
||||
scriptGlobals.Put(prop);
|
||||
prop->AddRef();
|
||||
|
||||
return prop;
|
||||
}
|
||||
@@ -1166,6 +1540,14 @@ 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
|
||||
// external references that will need the previous code
|
||||
if( HasExternalReferences(false) )
|
||||
{
|
||||
engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_MODULE_IS_IN_USE);
|
||||
return asMODULE_IS_IN_USE;
|
||||
}
|
||||
|
||||
// Only permit loading bytecode if no other thread is currently compiling
|
||||
// TODO: It should be possible to have multiple threads perform compilations
|
||||
int r = engine->RequestBuild();
|
||||
@@ -1302,14 +1684,14 @@ int asCModule::CompileFunction(const char *sectionName, const char *code, int li
|
||||
|
||||
if( r >= 0 && outFunc && func )
|
||||
{
|
||||
// Return the function to the caller
|
||||
// Return the function to the caller and add an external reference
|
||||
*outFunc = func;
|
||||
func->AddRef();
|
||||
}
|
||||
|
||||
// Release our reference to the function
|
||||
if( func )
|
||||
func->Release();
|
||||
func->ReleaseInternal();
|
||||
|
||||
return r;
|
||||
#endif
|
||||
@@ -1318,15 +1700,24 @@ int asCModule::CompileFunction(const char *sectionName, const char *code, int li
|
||||
// interface
|
||||
int asCModule::RemoveFunction(asIScriptFunction *func)
|
||||
{
|
||||
// TODO: 2.30.0: redesign: Check if there are any references before removing the function
|
||||
// if there are, just hide it from the visible but do not destroy or
|
||||
// remove it from the module.
|
||||
//
|
||||
// Only if the function has no live references, nor internal references
|
||||
// can it be immediately removed, and its internal references released.
|
||||
//
|
||||
// Check if any previously hidden functions are without references,
|
||||
// if so they should removed too.
|
||||
|
||||
// Find the global function
|
||||
asCScriptFunction *f = static_cast<asCScriptFunction*>(func);
|
||||
int idx = globalFunctions.GetIndex(f);
|
||||
if( idx >= 0 )
|
||||
{
|
||||
globalFunctions.Erase(idx);
|
||||
f->Release();
|
||||
scriptFunctions.RemoveValue(f);
|
||||
f->Orphan(this);
|
||||
f->ReleaseInternal();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1348,7 +1739,7 @@ int asCModule::AddFuncDef(const asCString &name, asSNameSpace *ns)
|
||||
|
||||
engine->funcDefs.PushLast(func);
|
||||
func->id = engine->GetNextScriptFunctionId();
|
||||
engine->SetScriptFunction(func);
|
||||
engine->AddScriptFunction(func);
|
||||
|
||||
return (int)funcDefs.GetLength()-1;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2013 Andreas Jonsson
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -132,6 +132,7 @@ public:
|
||||
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 int GetTypeIdByDecl(const char *decl) const;
|
||||
|
||||
// Enums
|
||||
@@ -159,8 +160,8 @@ public:
|
||||
virtual int LoadByteCode(asIBinaryStream *in, bool *wasDebugInfoStripped);
|
||||
|
||||
// User data
|
||||
virtual void *SetUserData(void *data);
|
||||
virtual void *GetUserData() const;
|
||||
virtual void *SetUserData(void *data, asPWORD type);
|
||||
virtual void *GetUserData(asPWORD type) const;
|
||||
|
||||
//-----------------------------------------------
|
||||
// Internal
|
||||
@@ -177,6 +178,7 @@ public:
|
||||
|
||||
void InternalReset();
|
||||
bool IsEmpty() const;
|
||||
bool HasExternalReferences(bool shuttingDown);
|
||||
|
||||
int CallInit(asIScriptContext *ctx);
|
||||
void CallExit();
|
||||
@@ -184,7 +186,7 @@ public:
|
||||
void JITCompile();
|
||||
|
||||
#ifndef AS_NO_COMPILER
|
||||
int AddScriptFunction(int sectionIdx, int declaredAt, int id, const asCString &name, const asCDataType &returnType, const asCArray<asCDataType> ¶ms, const asCArray<asETypeModifiers> &inOutFlags, const asCArray<asCString *> &defaultArgs, bool isInterface, asCObjectType *objType = 0, bool isConstMethod = false, bool isGlobalFunction = false, bool isPrivate = 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> ¶ms, const asCArray<asCString> ¶mNames, 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(asCScriptFunction *func);
|
||||
int AddImportedFunction(int id, const asCString &name, const asCDataType &returnType, const asCArray<asCDataType> ¶ms, const asCArray<asETypeModifiers> &inOutFlags, const asCArray<asCString *> &defaultArgs, asSNameSpace *ns, const asCString &moduleName);
|
||||
int AddFuncDef(const asCString &name, asSNameSpace *ns);
|
||||
@@ -197,31 +199,35 @@ public:
|
||||
|
||||
asCString name;
|
||||
|
||||
asCScriptEngine *engine;
|
||||
asCBuilder *builder;
|
||||
void *userData;
|
||||
asDWORD accessMask;
|
||||
asSNameSpace *defaultNamespace;
|
||||
asCScriptEngine *engine;
|
||||
asCBuilder *builder;
|
||||
asCArray<asPWORD> userData;
|
||||
asDWORD accessMask;
|
||||
asSNameSpace *defaultNamespace;
|
||||
|
||||
// This array holds all functions, class members, factories, etc that were compiled with the module
|
||||
asCArray<asCScriptFunction *> scriptFunctions;
|
||||
// This array holds global functions declared in the module
|
||||
asCSymbolTable<asCScriptFunction> globalFunctions;
|
||||
// This array holds imported functions in the module
|
||||
asCArray<sBindInfo *> bindInformations;
|
||||
// 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,
|
||||
// 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.
|
||||
asCArray<sBindInfo *> bindInformations; // increases ref count
|
||||
// This array holds template instance types created for the module's object types
|
||||
asCArray<asCObjectType*> templateInstances; // increases ref count
|
||||
|
||||
// This array holds the global variables declared in the script
|
||||
asCSymbolTable<asCGlobalProperty> scriptGlobals;
|
||||
asCSymbolTable<asCGlobalProperty> scriptGlobals; // increases ref count
|
||||
bool isGlobalVarInitialized;
|
||||
|
||||
// This array holds class and interface types
|
||||
asCArray<asCObjectType*> classTypes;
|
||||
asCArray<asCObjectType*> classTypes; // increases ref count
|
||||
// This array holds enum types
|
||||
asCArray<asCObjectType*> enumTypes;
|
||||
asCArray<asCObjectType*> enumTypes; // increases ref count
|
||||
// This array holds typedefs
|
||||
asCArray<asCObjectType*> typeDefs;
|
||||
asCArray<asCObjectType*> typeDefs; // increases ref count
|
||||
// This array holds the funcdefs declared in the module
|
||||
asCArray<asCScriptFunction*> funcDefs;
|
||||
asCArray<asCScriptFunction*> funcDefs; // increases ref count
|
||||
};
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2013 Andreas Jonsson
|
||||
Copyright (c) 2013-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -73,4 +73,5 @@ struct asSNameSpaceNamePair
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -45,140 +45,95 @@
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
#ifdef AS_MAX_PORTABILITY
|
||||
|
||||
static void ObjectType_AddRef_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
asCObjectType *self = (asCObjectType*)gen->GetObject();
|
||||
self->AddRef();
|
||||
}
|
||||
|
||||
static void ObjectType_Release_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
asCObjectType *self = (asCObjectType*)gen->GetObject();
|
||||
self->Release();
|
||||
}
|
||||
|
||||
static void ObjectType_GetRefCount_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
asCObjectType *self = (asCObjectType*)gen->GetObject();
|
||||
*(int*)gen->GetAddressOfReturnLocation() = self->GetRefCount();
|
||||
}
|
||||
|
||||
static void ObjectType_SetGCFlag_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
asCObjectType *self = (asCObjectType*)gen->GetObject();
|
||||
self->SetGCFlag();
|
||||
}
|
||||
|
||||
static void ObjectType_GetGCFlag_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
asCObjectType *self = (asCObjectType*)gen->GetObject();
|
||||
*(bool*)gen->GetAddressOfReturnLocation() = self->GetGCFlag();
|
||||
}
|
||||
|
||||
static void ObjectType_EnumReferences_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
asCObjectType *self = (asCObjectType*)gen->GetObject();
|
||||
asIScriptEngine *engine = *(asIScriptEngine**)gen->GetAddressOfArg(0);
|
||||
self->EnumReferences(engine);
|
||||
}
|
||||
|
||||
static void ObjectType_ReleaseAllHandles_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
asCObjectType *self = (asCObjectType*)gen->GetObject();
|
||||
asIScriptEngine *engine = *(asIScriptEngine**)gen->GetAddressOfArg(0);
|
||||
self->ReleaseAllHandles(engine);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void RegisterObjectTypeGCBehaviours(asCScriptEngine *engine)
|
||||
{
|
||||
// Register the gc behaviours for the object types
|
||||
int r = 0;
|
||||
UNUSED_VAR(r); // It is only used in debug mode
|
||||
engine->objectTypeBehaviours.engine = engine;
|
||||
engine->objectTypeBehaviours.flags = asOBJ_REF | asOBJ_GC;
|
||||
engine->objectTypeBehaviours.name = "_builtin_objecttype_";
|
||||
#ifndef AS_MAX_PORTABILITY
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_ADDREF, "void f()", asMETHOD(asCObjectType,AddRef), asCALL_THISCALL, 0); asASSERT( r >= 0 );
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_RELEASE, "void f()", asMETHOD(asCObjectType,Release), asCALL_THISCALL, 0); asASSERT( r >= 0 );
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_GETREFCOUNT, "int f()", asMETHOD(asCObjectType,GetRefCount), asCALL_THISCALL, 0); asASSERT( r >= 0 );
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_SETGCFLAG, "void f()", asMETHOD(asCObjectType,SetGCFlag), asCALL_THISCALL, 0); asASSERT( r >= 0 );
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_GETGCFLAG, "bool f()", asMETHOD(asCObjectType,GetGCFlag), asCALL_THISCALL, 0); asASSERT( r >= 0 );
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_ENUMREFS, "void f(int&in)", asMETHOD(asCObjectType,EnumReferences), asCALL_THISCALL, 0); asASSERT( r >= 0 );
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_RELEASEREFS, "void f(int&in)", asMETHOD(asCObjectType,ReleaseAllHandles), asCALL_THISCALL, 0); asASSERT( r >= 0 );
|
||||
#else
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_ADDREF, "void f()", asFUNCTION(ObjectType_AddRef_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_RELEASE, "void f()", asFUNCTION(ObjectType_Release_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_GETREFCOUNT, "int f()", asFUNCTION(ObjectType_GetRefCount_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_SETGCFLAG, "void f()", asFUNCTION(ObjectType_SetGCFlag_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_GETGCFLAG, "bool f()", asFUNCTION(ObjectType_GetGCFlag_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_ENUMREFS, "void f(int&in)", asFUNCTION(ObjectType_EnumReferences_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
|
||||
r = engine->RegisterBehaviourToObjectType(&engine->objectTypeBehaviours, asBEHAVE_RELEASEREFS, "void f(int&in)", asFUNCTION(ObjectType_ReleaseAllHandles_Generic), asCALL_GENERIC, 0); asASSERT( r >= 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
asCObjectType::asCObjectType()
|
||||
{
|
||||
engine = 0;
|
||||
module = 0;
|
||||
refCount.set(0);
|
||||
externalRefCount.set(0);
|
||||
internalRefCount.set(1); // start with one internal ref-count
|
||||
engine = 0;
|
||||
module = 0;
|
||||
derivedFrom = 0;
|
||||
size = 0;
|
||||
|
||||
acceptValueSubType = true;
|
||||
acceptRefSubType = true;
|
||||
acceptRefSubType = true;
|
||||
|
||||
scriptSectionIdx = -1;
|
||||
declaredAt = 0;
|
||||
|
||||
accessMask = 0xFFFFFFFF;
|
||||
nameSpace = 0;
|
||||
nameSpace = 0;
|
||||
#ifdef WIP_16BYTE_ALIGN
|
||||
alignment = 4;
|
||||
#endif
|
||||
}
|
||||
|
||||
asCObjectType::asCObjectType(asCScriptEngine *engine)
|
||||
{
|
||||
externalRefCount.set(0);
|
||||
internalRefCount.set(1); // start with one internal ref count
|
||||
this->engine = engine;
|
||||
module = 0;
|
||||
refCount.set(0);
|
||||
module = 0;
|
||||
derivedFrom = 0;
|
||||
|
||||
acceptValueSubType = true;
|
||||
acceptRefSubType = true;
|
||||
acceptRefSubType = true;
|
||||
|
||||
scriptSectionIdx = -1;
|
||||
declaredAt = 0;
|
||||
|
||||
accessMask = 0xFFFFFFFF;
|
||||
nameSpace = engine->nameSpaces[0];
|
||||
nameSpace = engine->nameSpaces[0];
|
||||
#ifdef WIP_16BYTE_ALIGN
|
||||
alignment = 4;
|
||||
#endif
|
||||
}
|
||||
|
||||
int asCObjectType::AddRef() const
|
||||
{
|
||||
gcFlag = false;
|
||||
return refCount.atomicInc();
|
||||
return externalRefCount.atomicInc();
|
||||
}
|
||||
|
||||
int asCObjectType::Release() const
|
||||
{
|
||||
gcFlag = false;
|
||||
return refCount.atomicDec();
|
||||
}
|
||||
int r = externalRefCount.atomicDec();
|
||||
|
||||
void asCObjectType::Orphan(asCModule *mod)
|
||||
{
|
||||
if( mod && mod == module )
|
||||
if( r == 0 )
|
||||
{
|
||||
module = 0;
|
||||
if( flags & asOBJ_SCRIPT_OBJECT )
|
||||
// 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 )
|
||||
{
|
||||
// Tell the GC that this type exists so it can resolve potential circular references
|
||||
engine->gc.AddScriptObjectToGC(this, &engine->objectTypeBehaviours);
|
||||
|
||||
// It's necessary to orphan the template instance types that refer to this object type,
|
||||
// otherwise the garbage collector cannot identify the circular references that involve
|
||||
// the type and the template type
|
||||
engine->OrphanTemplateInstances(this);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
Release();
|
||||
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
|
||||
@@ -237,36 +192,29 @@ void *asCObjectType::GetUserData(asPWORD type) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
int asCObjectType::GetRefCount()
|
||||
void asCObjectType::DestroyInternal()
|
||||
{
|
||||
return refCount.get();
|
||||
}
|
||||
if( engine == 0 ) return;
|
||||
|
||||
bool asCObjectType::GetGCFlag()
|
||||
{
|
||||
return gcFlag;
|
||||
}
|
||||
|
||||
void asCObjectType::SetGCFlag()
|
||||
{
|
||||
gcFlag = true;
|
||||
}
|
||||
|
||||
asCObjectType::~asCObjectType()
|
||||
{
|
||||
// Skip this for list patterns as they do not increase the references
|
||||
if( flags & asOBJ_LIST_PATTERN )
|
||||
{
|
||||
// Clear the engine pointer to mark the object type as invalid
|
||||
engine = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Release the object types held by the templateSubTypes
|
||||
for( asUINT subtypeIndex = 0; subtypeIndex < templateSubTypes.GetLength(); subtypeIndex++ )
|
||||
{
|
||||
if( templateSubTypes[subtypeIndex].GetObjectType() )
|
||||
templateSubTypes[subtypeIndex].GetObjectType()->Release();
|
||||
templateSubTypes[subtypeIndex].GetObjectType()->ReleaseInternal();
|
||||
}
|
||||
templateSubTypes.SetLength(0);
|
||||
|
||||
if( derivedFrom )
|
||||
derivedFrom->Release();
|
||||
derivedFrom->ReleaseInternal();
|
||||
derivedFrom = 0;
|
||||
|
||||
ReleaseAllProperties();
|
||||
|
||||
@@ -290,6 +238,22 @@ asCObjectType::~asCObjectType()
|
||||
engine->cleanObjectTypeFuncs[c].cleanFunc(this);
|
||||
}
|
||||
}
|
||||
userData.SetLength(0);
|
||||
|
||||
// Remove the type from the engine
|
||||
engine->RemoveFromTypeIdMap(this);
|
||||
|
||||
// Clear the engine pointer to mark the object type as invalid
|
||||
engine = 0;
|
||||
}
|
||||
|
||||
asCObjectType::~asCObjectType()
|
||||
{
|
||||
if( engine == 0 )
|
||||
return;
|
||||
|
||||
// TODO: 2.30.0: redesign: Shouldn't this have been done already?
|
||||
DestroyInternal();
|
||||
}
|
||||
|
||||
// interface
|
||||
@@ -369,30 +333,23 @@ int asCObjectType::GetTypeId() const
|
||||
// interface
|
||||
int asCObjectType::GetSubTypeId(asUINT subtypeIndex) const
|
||||
{
|
||||
if( flags & asOBJ_TEMPLATE )
|
||||
{
|
||||
if( subtypeIndex >= templateSubTypes.GetLength() )
|
||||
return asINVALID_ARG;
|
||||
// This method is only supported for templates and template specializations
|
||||
if( templateSubTypes.GetLength() == 0 )
|
||||
return asERROR;
|
||||
|
||||
return engine->GetTypeIdFromDataType(templateSubTypes[subtypeIndex]);
|
||||
}
|
||||
if( subtypeIndex >= templateSubTypes.GetLength() )
|
||||
return asINVALID_ARG;
|
||||
|
||||
// Only template types have sub types
|
||||
return asERROR;
|
||||
return engine->GetTypeIdFromDataType(templateSubTypes[subtypeIndex]);
|
||||
}
|
||||
|
||||
// interface
|
||||
asIObjectType *asCObjectType::GetSubType(asUINT subtypeIndex) const
|
||||
{
|
||||
if( flags & asOBJ_TEMPLATE )
|
||||
{
|
||||
if( subtypeIndex >= templateSubTypes.GetLength() )
|
||||
return 0;
|
||||
if( subtypeIndex >= templateSubTypes.GetLength() )
|
||||
return 0;
|
||||
|
||||
return templateSubTypes[subtypeIndex].GetObjectType();
|
||||
}
|
||||
|
||||
return 0;
|
||||
return templateSubTypes[subtypeIndex].GetObjectType();
|
||||
}
|
||||
|
||||
asUINT asCObjectType::GetSubTypeCount() const
|
||||
@@ -475,7 +432,7 @@ asIScriptFunction *asCObjectType::GetMethodByIndex(asUINT index, bool getVirtual
|
||||
asIScriptFunction *asCObjectType::GetMethodByName(const char *name, bool getVirtual) const
|
||||
{
|
||||
int id = -1;
|
||||
for( size_t n = 0; n < methods.GetLength(); n++ )
|
||||
for( asUINT n = 0; n < methods.GetLength(); n++ )
|
||||
{
|
||||
if( engine->scriptFunctions[methods[n]]->name == name )
|
||||
{
|
||||
@@ -532,23 +489,26 @@ asUINT asCObjectType::GetPropertyCount() const
|
||||
}
|
||||
|
||||
// interface
|
||||
int asCObjectType::GetProperty(asUINT index, const char **name, int *typeId, bool *isPrivate, int *offset, bool *isReference, asDWORD *accessMask) const
|
||||
int asCObjectType::GetProperty(asUINT index, const char **name, int *typeId, bool *isPrivate, bool *isProtected, int *offset, bool *isReference, asDWORD *accessMask) const
|
||||
{
|
||||
if( index >= properties.GetLength() )
|
||||
return asINVALID_ARG;
|
||||
|
||||
asCObjectProperty *prop = properties[index];
|
||||
if( name )
|
||||
*name = properties[index]->name.AddressOf();
|
||||
*name = prop->name.AddressOf();
|
||||
if( typeId )
|
||||
*typeId = engine->GetTypeIdFromDataType(properties[index]->type);
|
||||
*typeId = engine->GetTypeIdFromDataType(prop->type);
|
||||
if( isPrivate )
|
||||
*isPrivate = properties[index]->isPrivate;
|
||||
*isPrivate = prop->isPrivate;
|
||||
if( isProtected )
|
||||
*isProtected = prop->isProtected;
|
||||
if( offset )
|
||||
*offset = properties[index]->byteOffset;
|
||||
*offset = prop->byteOffset;
|
||||
if( isReference )
|
||||
*isReference = properties[index]->type.IsReference();
|
||||
*isReference = prop->type.IsReference();
|
||||
if( accessMask )
|
||||
*accessMask = properties[index]->accessMask;
|
||||
*accessMask = prop->accessMask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -562,9 +522,11 @@ const char *asCObjectType::GetPropertyDeclaration(asUINT index, bool includeName
|
||||
asCString *tempString = &asCThreadManager::GetLocalData()->string;
|
||||
if( properties[index]->isPrivate )
|
||||
*tempString = "private ";
|
||||
else if( properties[index]->isProtected )
|
||||
*tempString = "protected ";
|
||||
else
|
||||
*tempString = "";
|
||||
*tempString += properties[index]->type.Format(includeNamespace);
|
||||
*tempString += properties[index]->type.Format(nameSpace, includeNamespace);
|
||||
*tempString += " ";
|
||||
*tempString += properties[index]->name;
|
||||
|
||||
@@ -596,7 +558,6 @@ asUINT asCObjectType::GetBehaviourCount() const
|
||||
// For reference types, the factories are also stored in the constructor
|
||||
// list, so it is sufficient to enumerate only those
|
||||
count += (asUINT)beh.constructors.GetLength();
|
||||
count += (asUINT)beh.operators.GetLength() / 2;
|
||||
|
||||
return count;
|
||||
}
|
||||
@@ -689,14 +650,6 @@ asIScriptFunction *asCObjectType::GetBehaviourByIndex(asUINT index, asEBehaviour
|
||||
else
|
||||
count += (asUINT)beh.constructors.GetLength();
|
||||
|
||||
if( index - count < beh.operators.GetLength() / 2 )
|
||||
{
|
||||
index = 2*(index - count);
|
||||
|
||||
if( outBehaviour ) *outBehaviour = static_cast<asEBehaviours>(beh.operators[index]);
|
||||
return engine->scriptFunctions[beh.operators[index + 1]];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -717,10 +670,10 @@ asDWORD asCObjectType::GetAccessMask() const
|
||||
}
|
||||
|
||||
// internal
|
||||
asCObjectProperty *asCObjectType::AddPropertyToClass(const asCString &name, const asCDataType &dt, bool isPrivate)
|
||||
asCObjectProperty *asCObjectType::AddPropertyToClass(const asCString &name, const asCDataType &dt, bool isPrivate, bool isProtected, bool isInherited)
|
||||
{
|
||||
asASSERT( flags & asOBJ_SCRIPT_OBJECT );
|
||||
asASSERT( dt.CanBeInstanciated() );
|
||||
asASSERT( dt.CanBeInstantiated() );
|
||||
asASSERT( !IsInterface() );
|
||||
|
||||
// Store the properties in the object type descriptor
|
||||
@@ -731,9 +684,11 @@ asCObjectProperty *asCObjectType::AddPropertyToClass(const asCString &name, cons
|
||||
return 0;
|
||||
}
|
||||
|
||||
prop->name = name;
|
||||
prop->type = dt;
|
||||
prop->isPrivate = isPrivate;
|
||||
prop->name = name;
|
||||
prop->type = dt;
|
||||
prop->isPrivate = isPrivate;
|
||||
prop->isProtected = isProtected;
|
||||
prop->isInherited = isInherited;
|
||||
|
||||
int propSize;
|
||||
if( dt.IsObject() )
|
||||
@@ -755,8 +710,19 @@ asCObjectProperty *asCObjectType::AddPropertyToClass(const asCString &name, cons
|
||||
propSize = dt.GetSizeInMemoryBytes();
|
||||
|
||||
// Add extra bytes so that the property will be properly aligned
|
||||
#ifndef WIP_16BYTE_ALIGN
|
||||
if( propSize == 2 && (size & 1) ) size += 1;
|
||||
if( propSize > 2 && (size & 3) ) size += 4 - (size & 3);
|
||||
#else
|
||||
asUINT alignment = dt.GetAlignment();
|
||||
const asUINT propSizeAlignmentDifference = size & (alignment-1);
|
||||
if( propSizeAlignmentDifference != 0 )
|
||||
{
|
||||
size += (alignment - propSizeAlignmentDifference);
|
||||
}
|
||||
|
||||
asASSERT((size % alignment) == 0);
|
||||
#endif
|
||||
|
||||
prop->byteOffset = size;
|
||||
size += propSize;
|
||||
@@ -770,7 +736,7 @@ asCObjectProperty *asCObjectType::AddPropertyToClass(const asCString &name, cons
|
||||
// Add reference to object types
|
||||
asCObjectType *type = prop->type.GetObjectType();
|
||||
if( type )
|
||||
type->AddRef();
|
||||
type->AddRefInternal();
|
||||
|
||||
return prop;
|
||||
}
|
||||
@@ -791,7 +757,14 @@ void asCObjectType::ReleaseAllProperties()
|
||||
// Release references to objects types
|
||||
asCObjectType *type = properties[n]->type.GetObjectType();
|
||||
if( type )
|
||||
type->Release();
|
||||
type->ReleaseInternal();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Release template instance types (ref increased by RegisterObjectProperty)
|
||||
asCObjectType *type = properties[n]->type.GetObjectType();
|
||||
if( type )
|
||||
type->ReleaseInternal();
|
||||
}
|
||||
|
||||
asDELETE(properties[n],asCObjectProperty);
|
||||
@@ -801,13 +774,6 @@ void asCObjectType::ReleaseAllProperties()
|
||||
properties.SetLength(0);
|
||||
}
|
||||
|
||||
// internal
|
||||
void asCObjectType::ReleaseAllHandles(asIScriptEngine *)
|
||||
{
|
||||
ReleaseAllFunctions();
|
||||
ReleaseAllProperties();
|
||||
}
|
||||
|
||||
// internal
|
||||
void asCObjectType::ReleaseAllFunctions()
|
||||
{
|
||||
@@ -816,7 +782,7 @@ void asCObjectType::ReleaseAllFunctions()
|
||||
for( asUINT a = 0; a < beh.factories.GetLength(); a++ )
|
||||
{
|
||||
if( engine->scriptFunctions[beh.factories[a]] )
|
||||
engine->scriptFunctions[beh.factories[a]]->Release();
|
||||
engine->scriptFunctions[beh.factories[a]]->ReleaseInternal();
|
||||
}
|
||||
beh.factories.SetLength(0);
|
||||
|
||||
@@ -825,155 +791,74 @@ void asCObjectType::ReleaseAllFunctions()
|
||||
for( asUINT b = 0; b < beh.constructors.GetLength(); b++ )
|
||||
{
|
||||
if( engine->scriptFunctions[beh.constructors[b]] )
|
||||
engine->scriptFunctions[beh.constructors[b]]->Release();
|
||||
engine->scriptFunctions[beh.constructors[b]]->ReleaseInternal();
|
||||
}
|
||||
beh.constructors.SetLength(0);
|
||||
|
||||
if( beh.templateCallback )
|
||||
engine->scriptFunctions[beh.templateCallback]->Release();
|
||||
engine->scriptFunctions[beh.templateCallback]->ReleaseInternal();
|
||||
beh.templateCallback = 0;
|
||||
|
||||
if( beh.listFactory )
|
||||
engine->scriptFunctions[beh.listFactory]->Release();
|
||||
engine->scriptFunctions[beh.listFactory]->ReleaseInternal();
|
||||
beh.listFactory = 0;
|
||||
|
||||
if( beh.destruct )
|
||||
engine->scriptFunctions[beh.destruct]->Release();
|
||||
engine->scriptFunctions[beh.destruct]->ReleaseInternal();
|
||||
beh.destruct = 0;
|
||||
|
||||
if( beh.copy )
|
||||
engine->scriptFunctions[beh.copy]->Release();
|
||||
engine->scriptFunctions[beh.copy]->ReleaseInternal();
|
||||
beh.copy = 0;
|
||||
|
||||
for( asUINT e = 1; e < beh.operators.GetLength(); e += 2 )
|
||||
{
|
||||
if( engine->scriptFunctions[beh.operators[e]] )
|
||||
engine->scriptFunctions[beh.operators[e]]->Release();
|
||||
}
|
||||
beh.operators.SetLength(0);
|
||||
|
||||
for( asUINT c = 0; c < methods.GetLength(); c++ )
|
||||
{
|
||||
if( engine->scriptFunctions[methods[c]] )
|
||||
engine->scriptFunctions[methods[c]]->Release();
|
||||
engine->scriptFunctions[methods[c]]->ReleaseInternal();
|
||||
}
|
||||
methods.SetLength(0);
|
||||
|
||||
for( asUINT d = 0; d < virtualFunctionTable.GetLength(); d++ )
|
||||
{
|
||||
if( virtualFunctionTable[d] )
|
||||
virtualFunctionTable[d]->Release();
|
||||
virtualFunctionTable[d]->ReleaseInternal();
|
||||
}
|
||||
virtualFunctionTable.SetLength(0);
|
||||
|
||||
// GC behaviours
|
||||
if( beh.addref )
|
||||
engine->scriptFunctions[beh.addref]->Release();
|
||||
engine->scriptFunctions[beh.addref]->ReleaseInternal();
|
||||
beh.addref = 0;
|
||||
|
||||
if( beh.release )
|
||||
engine->scriptFunctions[beh.release]->Release();
|
||||
engine->scriptFunctions[beh.release]->ReleaseInternal();
|
||||
beh.release = 0;
|
||||
|
||||
if( beh.gcEnumReferences )
|
||||
engine->scriptFunctions[beh.gcEnumReferences]->Release();
|
||||
engine->scriptFunctions[beh.gcEnumReferences]->ReleaseInternal();
|
||||
beh.gcEnumReferences = 0;
|
||||
|
||||
if( beh.gcGetFlag )
|
||||
engine->scriptFunctions[beh.gcGetFlag]->Release();
|
||||
engine->scriptFunctions[beh.gcGetFlag]->ReleaseInternal();
|
||||
beh.gcGetFlag = 0;
|
||||
|
||||
if( beh.gcGetRefCount )
|
||||
engine->scriptFunctions[beh.gcGetRefCount]->Release();
|
||||
engine->scriptFunctions[beh.gcGetRefCount]->ReleaseInternal();
|
||||
beh.gcGetRefCount = 0;
|
||||
|
||||
if( beh.gcReleaseAllReferences )
|
||||
engine->scriptFunctions[beh.gcReleaseAllReferences]->Release();
|
||||
engine->scriptFunctions[beh.gcReleaseAllReferences]->ReleaseInternal();
|
||||
beh.gcReleaseAllReferences = 0;
|
||||
|
||||
if( beh.gcSetFlag )
|
||||
engine->scriptFunctions[beh.gcSetFlag]->Release();
|
||||
engine->scriptFunctions[beh.gcSetFlag]->ReleaseInternal();
|
||||
beh.gcSetFlag = 0;
|
||||
|
||||
if ( beh.getWeakRefFlag )
|
||||
engine->scriptFunctions[beh.getWeakRefFlag]->Release();
|
||||
engine->scriptFunctions[beh.getWeakRefFlag]->ReleaseInternal();
|
||||
beh.getWeakRefFlag = 0;
|
||||
}
|
||||
|
||||
// internal
|
||||
void asCObjectType::EnumReferences(asIScriptEngine *)
|
||||
{
|
||||
for( asUINT a = 0; a < beh.factories.GetLength(); a++ )
|
||||
if( engine->scriptFunctions[beh.factories[a]] )
|
||||
engine->GCEnumCallback(engine->scriptFunctions[beh.factories[a]]);
|
||||
|
||||
for( asUINT b = 0; b < beh.constructors.GetLength(); b++ )
|
||||
if( engine->scriptFunctions[beh.constructors[b]] )
|
||||
engine->GCEnumCallback(engine->scriptFunctions[beh.constructors[b]]);
|
||||
|
||||
if( beh.templateCallback )
|
||||
engine->GCEnumCallback(engine->scriptFunctions[beh.templateCallback]);
|
||||
|
||||
if( beh.listFactory )
|
||||
engine->GCEnumCallback(engine->scriptFunctions[beh.listFactory]);
|
||||
|
||||
if( beh.destruct )
|
||||
engine->GCEnumCallback(engine->scriptFunctions[beh.destruct]);
|
||||
|
||||
if( beh.addref )
|
||||
engine->GCEnumCallback(engine->scriptFunctions[beh.addref]);
|
||||
|
||||
if( beh.release )
|
||||
engine->GCEnumCallback(engine->scriptFunctions[beh.release]);
|
||||
|
||||
if( beh.copy )
|
||||
engine->GCEnumCallback(engine->scriptFunctions[beh.copy]);
|
||||
|
||||
if( beh.gcEnumReferences )
|
||||
engine->GCEnumCallback(engine->scriptFunctions[beh.gcEnumReferences]);
|
||||
|
||||
if( beh.gcGetFlag )
|
||||
engine->GCEnumCallback(engine->scriptFunctions[beh.gcGetFlag]);
|
||||
|
||||
if( beh.gcGetRefCount )
|
||||
engine->GCEnumCallback(engine->scriptFunctions[beh.gcGetRefCount]);
|
||||
|
||||
if( beh.gcReleaseAllReferences )
|
||||
engine->GCEnumCallback(engine->scriptFunctions[beh.gcReleaseAllReferences]);
|
||||
|
||||
if( beh.gcSetFlag )
|
||||
engine->GCEnumCallback(engine->scriptFunctions[beh.gcSetFlag]);
|
||||
|
||||
for( asUINT e = 1; e < beh.operators.GetLength(); e += 2 )
|
||||
if( engine->scriptFunctions[beh.operators[e]] )
|
||||
engine->GCEnumCallback(engine->scriptFunctions[beh.operators[e]]);
|
||||
|
||||
for( asUINT c = 0; c < methods.GetLength(); c++ )
|
||||
if( engine->scriptFunctions[methods[c]] )
|
||||
engine->GCEnumCallback(engine->scriptFunctions[methods[c]]);
|
||||
|
||||
for( asUINT d = 0; d < virtualFunctionTable.GetLength(); d++ )
|
||||
if( virtualFunctionTable[d] )
|
||||
engine->GCEnumCallback(virtualFunctionTable[d]);
|
||||
|
||||
for( asUINT p = 0; p < properties.GetLength(); p++ )
|
||||
{
|
||||
asCObjectType *type = properties[p]->type.GetObjectType();
|
||||
if( type )
|
||||
engine->GCEnumCallback(type);
|
||||
}
|
||||
|
||||
for( asUINT t = 0; t < templateSubTypes.GetLength(); t++ )
|
||||
if( templateSubTypes[t].GetObjectType() )
|
||||
engine->GCEnumCallback(templateSubTypes[t].GetObjectType());
|
||||
|
||||
if( beh.getWeakRefFlag )
|
||||
engine->GCEnumCallback(engine->scriptFunctions[beh.getWeakRefFlag]);
|
||||
|
||||
if( derivedFrom )
|
||||
engine->GCEnumCallback(derivedFrom);
|
||||
}
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2013 Andreas Jonsson
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -51,28 +51,6 @@ BEGIN_AS_NAMESPACE
|
||||
|
||||
// TODO: memory: Need to minimize used memory here, because not all types use all properties of the class
|
||||
|
||||
// TODO: The type id should have flags for differenciating between value types and reference types. It should also have a flag for differenciating interface types.
|
||||
|
||||
// Additional flag to the class object type
|
||||
const asDWORD asOBJ_IMPLICIT_HANDLE = 0x00400000;
|
||||
const asDWORD asOBJ_LIST_PATTERN = 0x08000000;
|
||||
const asDWORD asOBJ_ENUM = 0x10000000;
|
||||
const asDWORD asOBJ_TEMPLATE_SUBTYPE = 0x20000000;
|
||||
const asDWORD asOBJ_TYPEDEF = 0x40000000;
|
||||
|
||||
|
||||
|
||||
// asOBJ_GC is used to indicate that the type can potentially
|
||||
// form circular references, thus is garbage collected.
|
||||
|
||||
// The fact that an object is garbage collected doesn't imply that an other object
|
||||
// that can reference it also must be garbage collected, only if the garbage collected
|
||||
// object can reference the other object as well.
|
||||
|
||||
// For registered types however, we set the flag asOBJ_GC if the GC
|
||||
// behaviours are registered. For script types that contain any such type we
|
||||
// automatically make garbage collected as well, because we cannot know what type
|
||||
// of references that object can contain, and must assume the worst.
|
||||
|
||||
struct asSTypeBehaviour
|
||||
{
|
||||
@@ -119,7 +97,6 @@ struct asSTypeBehaviour
|
||||
|
||||
asCArray<int> factories;
|
||||
asCArray<int> constructors;
|
||||
asCArray<int> operators;
|
||||
};
|
||||
|
||||
struct asSEnumValue
|
||||
@@ -131,8 +108,6 @@ struct asSEnumValue
|
||||
class asCScriptEngine;
|
||||
struct asSNameSpace;
|
||||
|
||||
void RegisterObjectTypeGCBehaviours(asCScriptEngine *engine);
|
||||
|
||||
class asCObjectType : public asIObjectType
|
||||
{
|
||||
public:
|
||||
@@ -178,7 +153,7 @@ public:
|
||||
|
||||
// Properties
|
||||
asUINT GetPropertyCount() const;
|
||||
int GetProperty(asUINT index, const char **name, int *typeId, bool *isPrivate, int *offset, bool *isReference, asDWORD *accessMask) 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
|
||||
@@ -195,25 +170,27 @@ public:
|
||||
public:
|
||||
asCObjectType(asCScriptEngine *engine);
|
||||
~asCObjectType();
|
||||
void DestroyInternal();
|
||||
|
||||
void Orphan(asCModule *module);
|
||||
int GetRefCount();
|
||||
void SetGCFlag();
|
||||
bool GetGCFlag();
|
||||
void EnumReferences(asIScriptEngine *);
|
||||
void ReleaseAllHandles(asIScriptEngine *);
|
||||
// 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);
|
||||
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
|
||||
asCArray<asCObjectProperty*> properties;
|
||||
asCArray<int> methods;
|
||||
asCArray<asCObjectType*> interfaces;
|
||||
@@ -232,16 +209,23 @@ public:
|
||||
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 refCount;
|
||||
mutable bool gcFlag;
|
||||
mutable asCAtomic externalRefCount;
|
||||
asCAtomic internalRefCount;
|
||||
};
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2013 Andreas Jonsson
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -76,6 +76,7 @@ protected:
|
||||
void RewindTo(const sToken *token);
|
||||
void SetPos(size_t pos);
|
||||
void Error(const asCString &text, sToken *token);
|
||||
void Warning(const asCString &text, sToken *token);
|
||||
void Info(const asCString &text, sToken *token);
|
||||
|
||||
asCScriptNode *CreateNode(eScriptNode type);
|
||||
@@ -83,11 +84,11 @@ protected:
|
||||
asCScriptNode *ParseFunctionDefinition();
|
||||
asCScriptNode *ParseParameterList();
|
||||
asCScriptNode *SuperficiallyParseExpression();
|
||||
asCScriptNode *ParseType(bool allowConst, bool allowVariableType = false);
|
||||
asCScriptNode *ParseType(bool allowConst, bool allowVariableType = false, bool allowAuto = false);
|
||||
asCScriptNode *ParseTypeMod(bool isParam);
|
||||
void ParseOptionalScope(asCScriptNode *node);
|
||||
asCScriptNode *ParseRealType();
|
||||
asCScriptNode *ParseDataType(bool allowVariableType = false);
|
||||
asCScriptNode *ParseDataType(bool allowVariableType = false, bool allowAuto = false);
|
||||
asCScriptNode *ParseIdentifier();
|
||||
|
||||
asCScriptNode *ParseListPattern();
|
||||
@@ -143,7 +144,7 @@ protected:
|
||||
asCScriptNode *ParseExprPreOp();
|
||||
asCScriptNode *ParseExprPostOp();
|
||||
asCScriptNode *ParseExprValue();
|
||||
asCScriptNode *ParseArgList();
|
||||
asCScriptNode *ParseArgList(bool withParenthesis = true);
|
||||
asCScriptNode *ParseFunctionCall();
|
||||
asCScriptNode *ParseVariableAccess();
|
||||
asCScriptNode *ParseConstructCall();
|
||||
@@ -168,6 +169,7 @@ protected:
|
||||
asCString ExpectedTokens(const char *token1, const char *token2);
|
||||
asCString ExpectedOneOf(int *tokens, int count);
|
||||
asCString ExpectedOneOf(const char **tokens, int count);
|
||||
asCString InsteadFound(sToken &t);
|
||||
|
||||
bool errorWhileParsing;
|
||||
bool isSyntaxError;
|
||||
|
||||
@@ -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
|
||||
@@ -54,11 +54,14 @@ 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) {}
|
||||
asCString name;
|
||||
asCDataType type;
|
||||
int byteOffset;
|
||||
bool isPrivate;
|
||||
asDWORD accessMask;
|
||||
bool isPrivate;
|
||||
bool isProtected;
|
||||
bool isInherited;
|
||||
};
|
||||
|
||||
class asCGlobalProperty
|
||||
@@ -69,7 +72,7 @@ public:
|
||||
|
||||
void AddRef();
|
||||
void Release();
|
||||
int GetRefCount();
|
||||
void DestroyInternal();
|
||||
|
||||
void *GetAddressOfValue();
|
||||
void AllocateMemory();
|
||||
@@ -84,16 +87,7 @@ public:
|
||||
void SetInitFunc(asCScriptFunction *initFunc);
|
||||
asCScriptFunction *GetInitFunc();
|
||||
|
||||
static void RegisterGCBehaviours(asCScriptEngine *engine);
|
||||
|
||||
//protected:
|
||||
void SetGCFlag();
|
||||
bool GetGCFlag();
|
||||
void EnumReferences(asIScriptEngine *);
|
||||
void ReleaseAllHandles(asIScriptEngine *);
|
||||
|
||||
void Orphan(asCModule *module);
|
||||
|
||||
// This is only stored for registered properties, and keeps the pointer given by the application
|
||||
void *realAddress;
|
||||
|
||||
@@ -108,7 +102,6 @@ public:
|
||||
// The global property structure is reference counted, so that the
|
||||
// engine can keep track of how many references to the property there are.
|
||||
asCAtomic refCount;
|
||||
bool gcFlag;
|
||||
};
|
||||
|
||||
class asCCompGlobPropType : public asIFilter
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -124,9 +124,9 @@ protected:
|
||||
// Helper class for adjusting offsets within initialization list buffers
|
||||
struct SListAdjuster
|
||||
{
|
||||
SListAdjuster(asDWORD *bc, asCObjectType *ot);
|
||||
SListAdjuster(asCReader *rd, asDWORD *bc, asCObjectType *ot);
|
||||
void AdjustAllocMem();
|
||||
int AdjustOffset(int offset, asCObjectType *listPatternType);
|
||||
int AdjustOffset(int offset);
|
||||
void SetRepeatCount(asUINT rc);
|
||||
void SetNextType(int typeId);
|
||||
|
||||
@@ -137,11 +137,13 @@ protected:
|
||||
};
|
||||
asCArray<SInfo> stack;
|
||||
|
||||
asCReader *reader;
|
||||
asDWORD *allocMemBC;
|
||||
asUINT maxOffset;
|
||||
asCObjectType *patternType;
|
||||
asUINT repeatCount;
|
||||
int lastOffset;
|
||||
int nextOffset;
|
||||
asUINT lastAdjustedOffset;
|
||||
asSListPatternNode *patternNode;
|
||||
int nextTypeId;
|
||||
@@ -239,7 +241,8 @@ protected:
|
||||
asUINT repeatCount;
|
||||
asSListPatternNode *patternNode;
|
||||
asUINT entries;
|
||||
int lastOffset;
|
||||
int lastOffset; // Last offset adjusted
|
||||
int nextOffset; // next expected offset to be adjusted
|
||||
int nextTypeId;
|
||||
};
|
||||
asCArray<SListAdjuster*> listAdjusters;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user