summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorDave Hiller <daveh@lindenlab.com>2008-07-31 12:15:15 +0000
committerDave Hiller <daveh@lindenlab.com>2008-07-31 12:15:15 +0000
commit9a7d68cfce5f71cf9d89536431d72941dc369749 (patch)
treef7e0ce093abef0fcc7737cac63bc2a8dbf11b729 /indra
parentf0f2a416911ba8de9ac1e08cd90720c0d789bb2e (diff)
svn merge -r93014:93396 svn+ssh://svn.lindenlab.com/svn/linden/branches/mono-r93014-qar633 dataserver-is-deprecated
Diffstat (limited to 'indra')
-rw-r--r--indra/cmake/CMakeLists.txt3
-rw-r--r--indra/cmake/CSharpMacros.cmake142
-rw-r--r--indra/cmake/CopyBackToSource.cmake16
-rw-r--r--indra/cmake/FindMono.cmake68
-rw-r--r--indra/cmake/LScript.cmake7
-rw-r--r--indra/cmake/MonoDeps.cmake48
-rw-r--r--indra/cmake/MonoEmbed.cmake57
-rw-r--r--indra/llcommon/llassettype.cpp4
-rw-r--r--indra/llcommon/llstatenums.h3
-rw-r--r--indra/llmessage/llhttpclient.cpp29
-rw-r--r--indra/llmessage/llhttpclient.h6
-rw-r--r--indra/llmessage/llregionflags.h4
-rwxr-xr-xindra/llmessage/llsdmessagereader.cpp10
-rw-r--r--indra/lscript/CMakeLists.txt7
-rw-r--r--indra/lscript/lscript_byteconvert.h2
-rw-r--r--indra/lscript/lscript_byteformat.h16
-rw-r--r--indra/lscript/lscript_compile/indra.l29
-rw-r--r--indra/lscript/lscript_compile/lscript_error.cpp10
-rw-r--r--indra/lscript/lscript_compile/lscript_error.h5
-rw-r--r--indra/lscript/lscript_compile/lscript_tree.cpp1735
-rw-r--r--indra/lscript/lscript_compile/lscript_tree.h14
-rw-r--r--indra/lscript/lscript_compile/lscript_typecheck.cpp8
-rw-r--r--indra/lscript/lscript_execute.h150
-rw-r--r--indra/lscript/lscript_execute/lscript_execute.cpp923
-rw-r--r--indra/lscript/lscript_library.h4
-rw-r--r--indra/lscript/lscript_library/lscript_library.cpp21
-rw-r--r--indra/lscript/lscript_rt_interface.h4
-rw-r--r--indra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/English.lproj/InfoPlist.strings5
-rw-r--r--indra/newview/Info-SecondLife.plist2
-rw-r--r--indra/newview/llassetuploadqueue.cpp194
-rw-r--r--indra/newview/llassetuploadqueue.h74
-rw-r--r--indra/newview/llassetuploadresponders.cpp94
-rw-r--r--indra/newview/llassetuploadresponders.h23
-rw-r--r--indra/newview/llcompilequeue.cpp229
-rw-r--r--indra/newview/llcompilequeue.h38
-rw-r--r--indra/newview/llfloatertopobjects.cpp10
-rw-r--r--indra/newview/llpreviewscript.cpp115
-rw-r--r--indra/newview/llpreviewscript.h17
-rw-r--r--indra/newview/llstartup.cpp10
-rw-r--r--indra/newview/llviewermenu.cpp33
-rw-r--r--indra/newview/llviewermessage.cpp4
-rw-r--r--indra/newview/llviewerobject.cpp20
-rw-r--r--indra/newview/llviewerobject.h3
-rw-r--r--indra/newview/llviewerstats.h2
-rw-r--r--indra/newview/res/viewerRes.rc8
-rw-r--r--indra/test/llassetuploadqueue_tut.cpp178
-rw-r--r--indra/test/mock_http_client.cpp66
-rw-r--r--indra/test/mock_http_client.h174
49 files changed, 3525 insertions, 1101 deletions
diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index 22f6c5bd42..27ba04558e 100644
--- a/indra/cmake/CMakeLists.txt
+++ b/indra/cmake/CMakeLists.txt
@@ -17,6 +17,7 @@ set(cmake_SOURCE_FILES
CURL.cmake
CMakeCopyIfDifferent.cmake
CopyWinLibs.cmake
+ CSharpMacros.cmake
DirectX.cmake
ELFIO.cmake
EXPAT.cmake
@@ -25,6 +26,7 @@ set(cmake_SOURCE_FILES
FindCARes.cmake
FindELFIO.cmake
FindGooglePerfTools.cmake
+ FindMono.cmake
FindMySQL.cmake
FindOpenJPEG.cmake
FindXmlRpcEpi.cmake
@@ -55,6 +57,7 @@ set(cmake_SOURCE_FILES
LLXML.cmake
LScript.cmake
Linking.cmake
+ MonoEmbed.cmake
Mozlib.cmake
MySQL.cmake
NDOF.cmake
diff --git a/indra/cmake/CSharpMacros.cmake b/indra/cmake/CSharpMacros.cmake
new file mode 100644
index 0000000000..a4dd815043
--- /dev/null
+++ b/indra/cmake/CSharpMacros.cmake
@@ -0,0 +1,142 @@
+# - This is a support module for easy Mono/C# handling with CMake
+# It defines the following macros:
+#
+# ADD_CS_LIBRARY (<target> <source>)
+# ADD_CS_EXECUTABLE (<target> <source>)
+# INSTALL_GAC (<target>)
+#
+# Note that the order of the arguments is important.
+#
+# You can optionally set the variable CS_FLAGS to tell the macros whether
+# to pass additional flags to the compiler. This is particularly useful to
+# set assembly references, unsafe code, etc... These flags are always reset
+# after the target was added so you don't have to care about that.
+#
+# copyright (c) 2007 Arno Rehn arno@arnorehn.de
+#
+# Redistribution and use is allowed according to the terms of the GPL license.
+
+
+# ----- support macros -----
+MACRO(GET_CS_LIBRARY_TARGET_DIR)
+ IF (NOT LIBRARY_OUTPUT_PATH)
+ SET(CS_LIBRARY_TARGET_DIR ${CMAKE_CURRENT_BINARY_DIR})
+ ELSE (NOT LIBRARY_OUTPUT_PATH)
+ SET(CS_LIBRARY_TARGET_DIR ${LIBRARY_OUTPUT_PATH})
+ ENDIF (NOT LIBRARY_OUTPUT_PATH)
+ENDMACRO(GET_CS_LIBRARY_TARGET_DIR)
+
+MACRO(GET_CS_EXECUTABLE_TARGET_DIR)
+ IF (NOT EXECUTABLE_OUTPUT_PATH)
+ SET(CS_EXECUTABLE_TARGET_DIR ${CMAKE_CURRENT_BINARY_DIR})
+ ELSE (NOT EXECUTABLE_OUTPUT_PATH)
+ SET(CS_EXECUTABLE_TARGET_DIR ${EXECUTABLE_OUTPUT_PATH})
+ ENDIF (NOT EXECUTABLE_OUTPUT_PATH)
+ENDMACRO(GET_CS_EXECUTABLE_TARGET_DIR)
+
+MACRO(MAKE_PROPER_FILE_LIST)
+ FOREACH(file ${ARGN})
+ # first assume it's a relative path
+ FILE(GLOB globbed ${CMAKE_CURRENT_SOURCE_DIR}/${file})
+ IF(globbed)
+ FILE(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${file} native)
+ ELSE(globbed)
+ FILE(TO_NATIVE_PATH ${file} native)
+ ENDIF(globbed)
+ SET(proper_file_list ${proper_file_list} ${native})
+ SET(native "")
+ ENDFOREACH(file)
+ENDMACRO(MAKE_PROPER_FILE_LIST)
+# ----- end support macros -----
+
+MACRO(ADD_CS_LIBRARY target)
+ GET_CS_LIBRARY_TARGET_DIR()
+
+ SET(target_DLL "${CS_LIBRARY_TARGET_DIR}/${target}.dll")
+ MAKE_PROPER_FILE_LIST(${ARGN})
+ FILE(RELATIVE_PATH relative_path ${CMAKE_BINARY_DIR} ${target_DLL})
+
+ SET(target_KEY "${CMAKE_CURRENT_SOURCE_DIR}/${target}.key")
+ SET(target_CS_FLAGS "${CS_FLAGS}")
+ IF(${target}_CS_FLAGS)
+ LIST(APPEND target_CS_FLAGS ${${target}_CS_FLAGS})
+ ENDIF(${target}_CS_FLAGS)
+ IF(EXISTS ${target_KEY})
+ LIST(APPEND target_CS_FLAGS -keyfile:${target_KEY})
+ ENDIF(EXISTS ${target_KEY})
+
+ FOREACH(ref ${${target}_REFS})
+ SET(ref_DLL ${CMAKE_CURRENT_BINARY_DIR}/${ref}.dll)
+ IF(EXISTS ${ref_DLL})
+ LIST(APPEND target_CS_FLAGS -r:${ref_DLL})
+ ELSE(EXISTS ${ref_DLL})
+ LIST(APPEND target_CS_FLAGS -r:${ref})
+ ENDIF(EXISTS ${ref_DLL})
+ ENDFOREACH(ref ${${target}_REFS})
+
+ ADD_CUSTOM_COMMAND (OUTPUT ${target_DLL}
+ COMMAND ${MCS_EXECUTABLE} ${target_CS_FLAGS} -out:${target_DLL} -target:library ${proper_file_list}
+ MAIN_DEPENDENCY ${proper_file_list}
+ DEPENDS ${ARGN}
+ COMMENT "Building ${relative_path}")
+ ADD_CUSTOM_TARGET (${target} ALL DEPENDS ${target_DLL})
+
+ FOREACH(ref ${${target}_REFS})
+ GET_TARGET_PROPERTY(is_target ${ref} TYPE)
+ IF(is_target)
+ ADD_DEPENDENCIES(${target} ${ref})
+ ENDIF(is_target)
+ ENDFOREACH(ref ${${target}_REFS})
+
+ SET(relative_path "")
+ SET(proper_file_list "")
+ENDMACRO(ADD_CS_LIBRARY)
+
+MACRO(ADD_CS_EXECUTABLE target)
+ GET_CS_EXECUTABLE_TARGET_DIR()
+
+ # Seems like cmake doesn't like the ".exe" ending for custom commands.
+ # If we call it ${target}.exe, 'make' will later complain about a missing rule.
+ # Create a fake target instead.
+ SET(target_EXE "${CS_EXECUTABLE_TARGET_DIR}/${target}.exe")
+ SET(target_TOUCH "${CS_EXECUTABLE_TARGET_DIR}/${target}.exe-built")
+ GET_DIRECTORY_PROPERTY(clean ADDITIONAL_MAKE_CLEAN_FILES)
+ LIST(APPEND clean ${target}.exe)
+ SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${clean}")
+ MAKE_PROPER_FILE_LIST(${ARGN})
+ FILE(RELATIVE_PATH relative_path ${CMAKE_BINARY_DIR} ${target_EXE})
+ SET(target_CS_FLAGS "${CS_FLAGS}")
+
+ FOREACH(ref ${${target}_REFS})
+ SET(ref_DLL ${CMAKE_CURRENT_SOURCE_DIR}/${ref}.dll)
+ IF(EXISTS ${ref_DLL})
+ LIST(APPEND target_CS_FLAGS -r:${ref_DLL})
+ ELSE(EXISTS ${ref_DLL})
+ LIST(APPEND target_CS_FLAGS -r:${ref})
+ ENDIF(EXISTS ${ref_DLL})
+ ENDFOREACH(ref ${${target}_REFS})
+
+ ADD_CUSTOM_COMMAND (OUTPUT "${target_TOUCH}"
+ COMMAND ${MCS_EXECUTABLE} ${target_CS_FLAGS} -out:${target_EXE} ${proper_file_list}
+ COMMAND ${CMAKE_COMMAND} -E touch ${target_TOUCH}
+ MAIN_DEPENDENCY ${ARGN}
+ DEPENDS ${ARGN}
+ COMMENT "Building ${relative_path}")
+ ADD_CUSTOM_TARGET ("${target}" ALL DEPENDS "${target_TOUCH}")
+
+ FOREACH(ref ${${target}_REFS})
+ GET_TARGET_PROPERTY(is_target ${ref} TYPE)
+ IF(is_target)
+ ADD_DEPENDENCIES(${target} ${ref})
+ ENDIF(is_target)
+ ENDFOREACH(ref ${${target}_REFS})
+
+ SET(relative_path "")
+ SET(proper_file_list "")
+ENDMACRO(ADD_CS_EXECUTABLE)
+
+MACRO(INSTALL_GAC target)
+ GET_CS_LIBRARY_TARGET_DIR()
+
+ INSTALL(CODE "EXECUTE_PROCESS(COMMAND ${GACUTIL_EXECUTABLE} -i ${CS_LIBRARY_TARGET_DIR}/${target}.dll -package 2.0)")
+ENDMACRO(INSTALL_GAC target)
diff --git a/indra/cmake/CopyBackToSource.cmake b/indra/cmake/CopyBackToSource.cmake
new file mode 100644
index 0000000000..d217df9aec
--- /dev/null
+++ b/indra/cmake/CopyBackToSource.cmake
@@ -0,0 +1,16 @@
+# -*- cmake -*-
+# Copies a binary back to the source directory
+
+MACRO(COPY_BACK_TO_SOURCE target)
+ GET_TARGET_PROPERTY(FROM ${target} LOCATION)
+ SET(TO ${CMAKE_CURRENT_SOURCE_DIR})
+ #MESSAGE("TARGET ${target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${FROM} ${TO}")
+ ADD_CUSTOM_COMMAND(
+ TARGET ${target} POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy ${FROM} ${TO}
+ DEPENDS ${FROM}
+ COMMENT "Copying ${target} to ${CMAKE_CURRENT_BINARY_DIR}"
+ )
+ENDMACRO(COPY_BACK_TO_SOURCE)
+
+
diff --git a/indra/cmake/FindMono.cmake b/indra/cmake/FindMono.cmake
new file mode 100644
index 0000000000..f0a0705481
--- /dev/null
+++ b/indra/cmake/FindMono.cmake
@@ -0,0 +1,68 @@
+# - Try to find the mono, mcs, gmcs and gacutil
+#
+# defines
+#
+# MONO_FOUND - system has mono, mcs, gmcs and gacutil
+# MONO_PATH - where to find 'mono'
+# MCS_PATH - where to find 'mcs'
+# GMCS_PATH - where to find 'gmcs'
+# GACUTIL_PATH - where to find 'gacutil'
+#
+# copyright (c) 2007 Arno Rehn arno@arnorehn.de
+#
+# Redistribution and use is allowed according to the terms of the GPL license.
+# Removed the check for gmcs
+
+FIND_PROGRAM (MONO_EXECUTABLE mono
+ "C:/Program Files/Mono-1.9.1/bin"
+ "C:/Program Files/Mono-1.2.6/bin"
+ /bin
+ /usr/bin
+ /usr/local/bin
+)
+FIND_PROGRAM (MCS_EXECUTABLE mcs
+ "C:/Program Files/Mono-1.9.1/bin"
+ "C:/Program Files/Mono-1.2.6/bin"
+ /bin
+ /usr/bin
+ /usr/local/bin
+)
+FIND_PROGRAM (GMCS_EXECUTABLE gmcs
+ "C:/Program Files/Mono-1.9.1/bin"
+ "C:/Program Files/Mono-1.2.6/bin"
+ /bin
+ /usr/bin
+ /usr/local/bin
+)
+FIND_PROGRAM (GACUTIL_EXECUTABLE gacutil
+ "C:/Program Files/Mono-1.9.1/bin"
+ "C:/Program Files/Mono-1.2.6/bin"
+ /bin
+ /usr/bin
+ /usr/local/bin
+)
+FIND_PROGRAM (ILASM_EXECUTABLE
+ ilasm
+ NO_DEFAULT_PATH
+ PATHS "C:/Program Files/Mono-1.9.1/bin" "C:/Apps/Mono-1.2.6/bin" "C:/Program Files/Mono-1.2.6/bin" /bin /usr/bin /usr/local/bin
+)
+
+SET (MONO_FOUND FALSE)
+
+IF (MONO_EXECUTABLE AND MCS_EXECUTABLE AND GACUTIL_EXECUTABLE)
+ SET (MONO_FOUND TRUE)
+ENDIF (MONO_EXECUTABLE AND MCS_EXECUTABLE AND GACUTIL_EXECUTABLE)
+
+IF (MONO_FOUND)
+ IF (NOT Mono_FIND_QUIETLY)
+ MESSAGE(STATUS "Found mono: ${MONO_EXECUTABLE}")
+ MESSAGE(STATUS "Found mcs: ${MCS_EXECUTABLE}")
+ MESSAGE(STATUS "Found gacutil: ${GACUTIL_EXECUTABLE}")
+ ENDIF (NOT Mono_FIND_QUIETLY)
+ELSE (MONO_FOUND)
+ IF (Mono_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Could not find one or more of the following programs: mono, mcs, gacutil")
+ ENDIF (Mono_FIND_REQUIRED)
+ENDIF (MONO_FOUND)
+
+MARK_AS_ADVANCED(MONO_EXECUTABLE MCS_EXECUTABLE GACUTIL_EXECUTABLE)
diff --git a/indra/cmake/LScript.cmake b/indra/cmake/LScript.cmake
index 227e4aaeda..86bfcb7440 100644
--- a/indra/cmake/LScript.cmake
+++ b/indra/cmake/LScript.cmake
@@ -3,11 +3,14 @@
set(LSCRIPT_INCLUDE_DIRS
${LIBS_OPEN_DIR}/lscript
${LIBS_OPEN_DIR}/lscript/lscript_compile
- ${LIBS_OPEN_DIR}/lscript/lscript_execute
+ ${LIBS_OPEN_DIR}/lscript/lscript_execute
+ ${LIBS_OPEN_DIR}/lscript/lscript_execute_mono
)
set(LSCRIPT_LIBRARIES
lscript_compile
- lscript_execute
+ lscript_execute
lscript_library
)
+
+set(LSCRIPT_EXECUTE_MONO_LIBRARIES lscript_execute_mono) \ No newline at end of file
diff --git a/indra/cmake/MonoDeps.cmake b/indra/cmake/MonoDeps.cmake
new file mode 100644
index 0000000000..52d5491563
--- /dev/null
+++ b/indra/cmake/MonoDeps.cmake
@@ -0,0 +1,48 @@
+# -*- cmake -*-
+
+set(MONO_PREBUILT_LIBRARIES_DIR ${LIBS_PREBUILT_DIR}/mono/1.0)
+
+set(MONO_PREBUILT_LIBRARIES
+ Iesi.Collections.dll
+ Iesi.Collections.pdb
+ Mono.CompilerServices.SymbolWriter.dll
+ Mono.PEToolkit.dll
+ Mono.PEToolkit.pdb
+ Mono.Security.dll
+ PEAPI.dll
+ RAIL.dll
+ RAIL.pdb
+ )
+
+ set(MONO_CORE_LIBRARIES
+ System.dll
+ System.Xml.dll
+ mscorlib.dll)
+
+if(WINDOWS)
+ set(MONO_DEPENDENCIES
+ DomainCreator
+ DomainRegister
+ LslLibrary
+ LslUserScript
+ Script
+ ScriptTypes
+ TestFormat
+ UserScript
+ UThread
+ UThreadInjector
+ )
+else(WINDOWS)
+ set(MONO_DEPENDENCIES
+ DomainCreator_POST_BUILD
+ DomainRegister_POST_BUILD
+ LslLibrary_POST_BUILD
+ LslUserScript_POST_BUILD
+ Script_POST_BUILD
+ ScriptTypes_POST_BUILD
+ TestFormat_POST_BUILD
+ UserScript_POST_BUILD
+ UThread_POST_BUILD
+ UThreadInjector_POST_BUILD
+ )
+endif(WINDOWS)
diff --git a/indra/cmake/MonoEmbed.cmake b/indra/cmake/MonoEmbed.cmake
new file mode 100644
index 0000000000..a310cd9bac
--- /dev/null
+++ b/indra/cmake/MonoEmbed.cmake
@@ -0,0 +1,57 @@
+# -*- cmake -*-
+
+include(Prebuilt)
+use_prebuilt_binary(libmono)
+
+SET(GLIB_2_0 glib-2.0)
+
+if (WINDOWS)
+ SET(MONO_LIB mono)
+else (WINDOWS)
+ SET(MONO_LIB mono)
+ SET(M_LIBRARIES m)
+ SET(GTHREAD_2_0 gthread-2.0)
+endif(WINDOWS)
+
+
+IF (DARWIN)
+
+ FIND_LIBRARY(MONO_LIBRARY NAMES Mono)
+ # Find_file doesnt work as expected. Hardcode relative to Mono.framework.
+ #FIND_FILE(GLIB_CONFIG glibconfig.h ${MONO_LIBRARY})
+ #FIND_FILE(MONO_GLIB_LIBRARY glib.h ${MONO_LIBRARY})
+ SET(MONO_GLIB_LIBRARY ${MONO_LIBRARY}/Headers/glib-2.0/)
+ SET(GLIB_CONFIG ${MONO_LIBRARY}/Libraries/glib-2.0/include/)
+ SET(MONO_LIB_DIRECTORY ${MONO_LIBRARY}/Libraries)
+
+ IF (MONO_LIBRARY AND MONO_GLIB_LIBRARY AND GLIB_CONFIG)
+ MESSAGE("-- Found Mono for embedding")
+ INCLUDE_DIRECTORIES(${MONO_GLIB_LIBRARY} ${GLIB_CONFIG})
+ LINK_DIRECTORIES(${MONO_LIB_DIRECTORY})
+ ELSE (MONO_LIBRARY AND MONO_GLIB_LIBRARY AND GLIB_CONFIG)
+ MESSAGE("-- Mono not found for embedding")
+ MESSAGE(${MONO_LIBRARY})
+ MESSAGE(${MONO_GLIB_LIBRARY})
+ MESSAGE(${GLIB_CONFIG})
+ ENDIF (MONO_LIBRARY AND MONO_GLIB_LIBRARY AND GLIB_CONFIG)
+
+ELSE (DARWIN)
+
+ SET(MONO_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
+ SET(GLIB_2_0_PLATFORM_INCLUDE_DIR
+ ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/glib-2.0)
+ SET(GLIB_2_0_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/glib-2.0)
+
+ INCLUDE_DIRECTORIES(
+ ${MONO_INCLUDE_DIR}
+ ${GLIB_2_0_PLATFORM_INCLUDE_DIR}
+ ${GLIB_2_0_INCLUDE_DIR})
+
+ENDIF (DARWIN)
+
+SET(MONO_LIBRARIES
+ ${MONO_LIB}
+ ${M_LIBRARIES}
+ ${GLIB_2_0}
+ ${GTHREAD_2_0}
+)
diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp
index 368c85acb0..08dcef2538 100644
--- a/indra/llcommon/llassettype.cpp
+++ b/indra/llcommon/llassettype.cpp
@@ -128,7 +128,7 @@ const char* LLAssetType::mAssetTypeNames[LLAssetType::AT_COUNT] =
"jpeg",
"animatn",
"gesture",
- "simstate",
+ "simstate"
};
// This table is meant for decoding to human readable form. Put any
@@ -158,7 +158,7 @@ const char* LLAssetType::mAssetTypeHumanNames[LLAssetType::AT_COUNT] =
"jpeg image",
"animation",
"gesture",
- "simstate",
+ "simstate"
};
///----------------------------------------------------------------------------
diff --git a/indra/llcommon/llstatenums.h b/indra/llcommon/llstatenums.h
index a82996b852..45c4fa986b 100644
--- a/indra/llcommon/llstatenums.h
+++ b/indra/llcommon/llstatenums.h
@@ -63,7 +63,8 @@ enum
LL_SIM_STAT_SIMPHYSICSSTEPMS,
LL_SIM_STAT_SIMPHYSICSSHAPEMS,
LL_SIM_STAT_SIMPHYSICSOTHERMS,
- LL_SIM_STAT_SIMPHYSICSMEMORY
+ LL_SIM_STAT_SIMPHYSICSMEMORY,
+ LL_SIM_STAT_SCRIPT_EPS,
};
#endif
diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp
index 2937edd853..7a6add6282 100644
--- a/indra/llmessage/llhttpclient.cpp
+++ b/indra/llmessage/llhttpclient.cpp
@@ -122,7 +122,7 @@ namespace
{
public:
RawInjector(const U8* data, S32 size) : mData(data), mSize(size) {}
- virtual ~RawInjector() {}
+ virtual ~RawInjector() {delete mData;}
const char* contentType() { return "application/octet-stream"; }
@@ -153,16 +153,21 @@ namespace
LLBufferStream ostream(channels, buffer.get());
llifstream fstream(mFilename, std::iostream::binary | std::iostream::out);
- fstream.seekg(0, std::ios::end);
- U32 fileSize = fstream.tellg();
- fstream.seekg(0, std::ios::beg);
- char* fileBuffer;
- fileBuffer = new char [fileSize];
- fstream.read(fileBuffer, fileSize);
- ostream.write(fileBuffer, fileSize);
- fstream.close();
- eos = true;
- return STATUS_DONE;
+ if(fstream.is_open())
+ {
+ fstream.seekg(0, std::ios::end);
+ U32 fileSize = fstream.tellg();
+ fstream.seekg(0, std::ios::beg);
+ char* fileBuffer;
+ fileBuffer = new char [fileSize];
+ fstream.read(fileBuffer, fileSize);
+ ostream.write(fileBuffer, fileSize);
+ fstream.close();
+ eos = true;
+ return STATUS_DONE;
+ }
+
+ return STATUS_ERROR;
}
const std::string mFilename;
@@ -402,7 +407,7 @@ void LLHTTPClient::post(const std::string& url, const LLSD& body, ResponderPtr r
request(url, LLURLRequest::HTTP_POST, new LLSDInjector(body), responder, timeout);
}
-void LLHTTPClient::post(const std::string& url, const U8* data, S32 size, ResponderPtr responder, const F32 timeout)
+void LLHTTPClient::postRaw(const std::string& url, const U8* data, S32 size, ResponderPtr responder, const F32 timeout)
{
request(url, LLURLRequest::HTTP_POST, new RawInjector(data, size), responder, timeout);
}
diff --git a/indra/llmessage/llhttpclient.h b/indra/llmessage/llhttpclient.h
index 57895aeec9..af79662be9 100644
--- a/indra/llmessage/llhttpclient.h
+++ b/indra/llmessage/llhttpclient.h
@@ -72,8 +72,12 @@ public:
static void getHeaderOnly(const std::string& url, ResponderPtr, const LLSD& headers, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
static void post(const std::string& url, const LLSD& body, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
- static void post(const std::string& url, const U8* data, S32 size, ResponderPtr responder, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
+
+ /** Takes ownership of data and deletes it when sent */
+ static void postRaw(const std::string& url, const U8* data, S32 size, ResponderPtr responder, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
+
static void postFile(const std::string& url, const std::string& filename, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
+ #
static void postFile(const std::string& url, const LLUUID& uuid,
LLAssetType::EType asset_type, ResponderPtr responder, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
diff --git a/indra/llmessage/llregionflags.h b/indra/llmessage/llregionflags.h
index aa9964d46b..972a184a62 100644
--- a/indra/llmessage/llregionflags.h
+++ b/indra/llmessage/llregionflags.h
@@ -94,8 +94,8 @@ const U32 REGION_FLAGS_ABUSE_EMAIL_TO_ESTATE_OWNER = (1 << 27);
const U32 REGION_FLAGS_ALLOW_VOICE = (1 << 28);
const U32 REGION_FLAGS_BLOCK_PARCEL_SEARCH = (1 << 29);
-const U32 REGION_FLAGS_DENY_AGEUNVERIFIED = (1 << 30);
-
+const U32 REGION_FLAGS_DENY_AGEUNVERIFIED = (1 << 30);
+const U32 REGION_FLAGS_SKIP_MONO_SCRIPTS = (1 << 31);
const U32 REGION_FLAGS_DEFAULT = REGION_FLAGS_ALLOW_LANDMARK |
REGION_FLAGS_ALLOW_SET_HOME |
diff --git a/indra/llmessage/llsdmessagereader.cpp b/indra/llmessage/llsdmessagereader.cpp
index b7d0267423..5fb3708859 100755
--- a/indra/llmessage/llsdmessagereader.cpp
+++ b/indra/llmessage/llsdmessagereader.cpp
@@ -71,14 +71,20 @@ LLSD getLLSD(const LLSD& input, const char* block, const char* var, S32 blocknum
}
if(! input[block].isArray())
{
- llerrs << "block " << block << " not found" << llendl;
+ // NOTE: babbage: need to return default for missing blocks to allow
+ // backwards/forwards compatibility - handlers must cope with default
+ // values.
+ llwarns << "block " << block << " not found" << llendl;
return LLSD();
}
LLSD result = input[block][blocknum][var];
if(result.isUndefined())
{
- llerrs << "var " << var << " not found" << llendl;
+ // NOTE: babbage: need to return default for missing vars to allow
+ // backwards/forwards compatibility - handlers must cope with default
+ // values.
+ llwarns << "var " << var << " not found" << llendl;
}
return result;
}
diff --git a/indra/lscript/CMakeLists.txt b/indra/lscript/CMakeLists.txt
index d3e3dc1103..c655aef4d9 100644
--- a/indra/lscript/CMakeLists.txt
+++ b/indra/lscript/CMakeLists.txt
@@ -11,7 +11,8 @@ set(lscript_HEADER_FILES
lscript_rt_interface.h
)
-add_subdirectory (lscript_compile)
-add_subdirectory (lscript_execute)
-add_subdirectory (lscript_library)
+add_subdirectory(lscript_compile)
+add_subdirectory(lscript_execute)
+
+add_subdirectory(lscript_library)
diff --git a/indra/lscript/lscript_byteconvert.h b/indra/lscript/lscript_byteconvert.h
index 89f3cc4a21..b5e09602c7 100644
--- a/indra/lscript/lscript_byteconvert.h
+++ b/indra/lscript/lscript_byteconvert.h
@@ -415,7 +415,7 @@ inline void set_fault(const U8 *stream, LSCRIPTRunTimeFaults fault)
reset_hp_to_safe_spot(stream);
// lsa_print_heap((U8 *)stream);
}
- fr = LSCRIPTRunTimeFaultBits[fault];
+ fr = fault;
set_register((U8 *)stream, LREG_FR, fr);
}
}
diff --git a/indra/lscript/lscript_byteformat.h b/indra/lscript/lscript_byteformat.h
index 6edf2b740d..474e8a67a6 100644
--- a/indra/lscript/lscript_byteformat.h
+++ b/indra/lscript/lscript_byteformat.h
@@ -512,26 +512,12 @@ typedef enum e_lscript_runtime_faults
LSRF_CHAT_OVERRUN,
LSRF_TOO_MANY_LISTENS,
LSRF_NESTING_LISTS,
+ LSRF_CLI,
LSRF_EOF
} LSCRIPTRunTimeFaults;
extern const char* LSCRIPTRunTimeFaultStrings[LSRF_EOF]; /*Flawfinder: ignore*/
-const S32 LSCRIPTRunTimeFaultBits[LSRF_EOF] =
-{
- 0, // LSRF_INVALID
- 1, // LSRF_MATH
- 2, // LSRF_STACK_HEAP_COLLISION
- 3, // LSREF_BOUND_CHECK_ERROR
- 4, // LSREF_HEAP_ERROR
- 5, // LSREF_VERSION_MISMATCH
- 6, // LSREF_MISSING_INVENTORY
- 7, // LSRF_SANDBOX
- 8, // LSRF_CHAT_OVERRUN
- 9, // LSRF_TOO_MANY_LISTENS
- 10, // LSRF_NESTING_LISTS
-};
-
typedef enum e_lscript_runtime_permissions
{
SCRIPT_PERMISSION_DEBIT,
diff --git a/indra/lscript/lscript_compile/indra.l b/indra/lscript/lscript_compile/indra.l
index 14f8acb551..09008379a2 100644
--- a/indra/lscript/lscript_compile/indra.l
+++ b/indra/lscript/lscript_compile/indra.l
@@ -676,7 +676,7 @@ int yyerror(const char *fmt, ...)
//#define EMIT_CIL_ASSEMBLER
BOOL lscript_compile(const char* src_filename, const char* dst_filename,
- const char* err_filename, BOOL is_god_like)
+ const char* err_filename, BOOL compile_to_mono, const char* class_name, BOOL is_god_like)
{
BOOL b_parse_ok = FALSE;
BOOL b_dummy = FALSE;
@@ -718,6 +718,8 @@ BOOL lscript_compile(const char* src_filename, const char* dst_filename,
}
gScriptp->mGodLike = is_god_like;
+
+ gScriptp->setClassName(class_name);
gScopeStringTable = new LLStringTable(16384);
#ifdef EMERGENCY_DEBUG_PRINTOUTS
@@ -733,34 +735,25 @@ BOOL lscript_compile(const char* src_filename, const char* dst_filename,
#ifdef EMERGENCY_DEBUG_PRINTOUTS
gScriptp->recurse(yyout, 0, 0, LSCP_EMIT_ASSEMBLY, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL);
#endif
-#ifdef EMIT_CIL_ASSEMBLER
- const char* cil_output_file_name = dst_filename? dst_filename : "lscript.cil";
- LLFILE* cilout = LLFile::fopen(cil_output_file_name, "w");
- if(NULL == cilout)
+ if(TRUE == compile_to_mono)
{
- fprintf(yyout, "Error opening cil output file %s\n", cil_output_file_name);
+ gScriptp->recurse(yyout, 0, 0, LSCP_EMIT_CIL_ASSEMBLY, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL);
}
else
{
- gScriptp->recurse(cilout, 0, 0, LSCP_EMIT_CIL_ASSEMBLY, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL);
- if(fclose(cilout) == EOF)
- {
- fprintf(yyout, "Error closing cil output file %s\n", cil_output_file_name);
- }
+ gScriptp->recurse(yyout, 0, 0, LSCP_EMIT_BYTE_CODE, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL);
}
-#endif
- gScriptp->recurse(yyout, 0, 0, LSCP_EMIT_BYTE_CODE, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL);
}
delete gScopeStringTable;
gScopeStringTable = NULL;
#ifdef EMERGENCY_DEBUG_PRINTOUTS
fclose(compfile);
#endif
+ fclose(yyout);
}
- fclose(yyout);
+ fclose(yyin);
}
- fclose(yyin);
delete gAllocationManager;
delete gScopeStringTable;
@@ -768,13 +761,15 @@ BOOL lscript_compile(const char* src_filename, const char* dst_filename,
}
-BOOL lscript_compile(char *filename, BOOL is_god_like = FALSE)
+BOOL lscript_compile(char *filename, BOOL compile_to_mono, BOOL is_god_like = FALSE)
{
char src_filename[MAX_STRING];
sprintf(src_filename, "%s.lsl", filename);
char err_filename[MAX_STRING];
sprintf(err_filename, "%s.out", filename);
- return lscript_compile(src_filename, NULL, err_filename, is_god_like);
+ char class_name[MAX_STRING];
+ sprintf(class_name, "%s", filename);
+ return lscript_compile(src_filename, NULL, err_filename, compile_to_mono, class_name, is_god_like);
}
diff --git a/indra/lscript/lscript_compile/lscript_error.cpp b/indra/lscript/lscript_compile/lscript_error.cpp
index 309eb07dc2..5299d8c7e9 100644
--- a/indra/lscript/lscript_compile/lscript_error.cpp
+++ b/indra/lscript/lscript_compile/lscript_error.cpp
@@ -72,7 +72,10 @@ const char* gErrorText[LSERROR_EOF] = /*Flawfinder: ignore*/
"Use of vector or quaternion method on incorrect type",
"Lists can't be included in lists",
"Unitialized variables can't be included in lists",
- "Declaration requires a new scope -- use { and }"
+ "Declaration requires a new scope -- use { and }",
+ "CIL assembler failed",
+ "Bytecode transformer failed",
+ "Bytecode verification failed"
};
void LLScriptGenerateErrorText::writeWarning(LLFILE *fp, LLScriptFilePosition *pos, LSCRIPTWarnings warning)
@@ -98,3 +101,8 @@ void LLScriptGenerateErrorText::writeError(LLFILE *fp, S32 line, S32 col, LSCRIP
fprintf(fp, "(%d, %d) : ERROR : %s\n", line, col, gErrorText[error]);
mTotalErrors++;
}
+
+std::string getLScriptErrorString(LSCRIPTErrors error)
+{
+ return gErrorText[error];
+}
diff --git a/indra/lscript/lscript_compile/lscript_error.h b/indra/lscript/lscript_compile/lscript_error.h
index 8c9e35d56b..50276c2006 100644
--- a/indra/lscript/lscript_compile/lscript_error.h
+++ b/indra/lscript/lscript_compile/lscript_error.h
@@ -124,6 +124,9 @@ typedef enum e_lscript_errors
LSERROR_NO_LISTS_IN_LISTS,
LSERROR_NO_UNITIALIZED_VARIABLES_IN_LISTS,
LSERROR_NEED_NEW_SCOPE,
+ LSERROR_CIL_ASSEMBLER_FAILED = 16, // Mono build error.
+ LSERROR_BYTECODE_TRANSFORM_FAILED = 17, // Mono build error.
+ LSERROR_BYTECODE_VERIFICATION_FAILED, // Mono build error.
LSERROR_EOF
} LSCRIPTErrors;
@@ -147,6 +150,8 @@ public:
S32 mTotalWarnings;
};
+std::string getLScriptErrorString(LSCRIPTErrors error);
+
extern LLScriptGenerateErrorText gErrorToText;
#endif
diff --git a/indra/lscript/lscript_compile/lscript_tree.cpp b/indra/lscript/lscript_compile/lscript_tree.cpp
index 3a93f7b896..aabf0a3c38 100644
--- a/indra/lscript/lscript_compile/lscript_tree.cpp
+++ b/indra/lscript/lscript_compile/lscript_tree.cpp
@@ -43,7 +43,8 @@
//#define LSL_INCLUDE_DEBUG_INFO
-void print_cil_box(LLFILE* fp, LSCRIPTType type)
+
+static void print_cil_box(LLFILE* fp, LSCRIPTType type)
{
switch(type)
{
@@ -51,24 +52,28 @@ void print_cil_box(LLFILE* fp, LSCRIPTType type)
fprintf(fp, "box [mscorlib]System.Int32\n");
break;
case LST_FLOATINGPOINT:
- fprintf(fp, "box [mscorlib]System.Double\n");
+ fprintf(fp, "box [mscorlib]System.Single\n");
break;
case LST_STRING:
+ // System.String is not a System.ValueType,
+ // so does not need to be boxed.
+ break;
case LST_KEY:
- fprintf(fp, "box [mscorlib]System.String\n");
+ fprintf(fp, "box [ScriptTypes]LindenLab.SecondLife.Key\n");
break;
case LST_VECTOR:
- fprintf(fp, "box [LScriptLibrary]LLVector\n");
+ fprintf(fp, "box [ScriptTypes]LindenLab.SecondLife.Vector\n");
break;
case LST_QUATERNION:
- fprintf(fp, "box [LScriptLibrary]LLQuaternion\n");
+ fprintf(fp, "box [ScriptTypes]LindenLab.SecondLife.Quaternion\n");
break;
default:
+ llassert(false);
break;
}
}
-void print_cil_type(LLFILE* fp, LSCRIPTType type)
+static void print_cil_type(LLFILE* fp, LSCRIPTType type)
{
switch(type)
{
@@ -79,14 +84,16 @@ void print_cil_type(LLFILE* fp, LSCRIPTType type)
fprintf(fp, "float32");
break;
case LST_STRING:
- case LST_KEY:
fprintf(fp, "string");
+ break;
+ case LST_KEY:
+ fprintf(fp, "valuetype [ScriptTypes]LindenLab.SecondLife.Key");
break;
case LST_VECTOR:
- fprintf(fp, "valuetype [LScriptLibrary]LLVector");
+ fprintf(fp, "class [ScriptTypes]LindenLab.SecondLife.Vector");
break;
case LST_QUATERNION:
- fprintf(fp, "valuetype [LScriptLibrary]LLQuaternion");
+ fprintf(fp, "class [ScriptTypes]LindenLab.SecondLife.Quaternion");
break;
case LST_LIST:
fprintf(fp, "class [mscorlib]System.Collections.ArrayList");
@@ -189,6 +196,7 @@ void LLScriptConstantInteger::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPT
break;
case LSCP_EMIT_CIL_ASSEMBLY:
fprintf(fp, "ldc.i4 %d\n", mValue);
+ type = mType;
break;
default:
break;
@@ -236,7 +244,13 @@ void LLScriptConstantFloat::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCo
}
break;
case LSCP_EMIT_CIL_ASSEMBLY:
- fprintf(fp, "ldc.r8 %5.5f\n", mValue); // NOTE: Precision?
+ {
+ double v = (double)mValue;
+ U8 * p = (U8 *)&v; // See ECMA-335 Partition VI, Appendix C.4.6 Examples, line 4
+ fprintf(fp, "ldc.r8 (%02x %02x %02x %02x %02x %02x %02x %02x)\n", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+ type = mType;
+ }
+ break;
default:
break;
}
@@ -247,16 +261,34 @@ S32 LLScriptConstantFloat::getSize()
return LSCRIPTDataSize[LST_FLOATINGPOINT];
}
-void print_escape_quotes(LLFILE* fp, const char* str)
+void print_escaped(LLFILE* fp, const char* str)
{
putc('"', fp);
for(const char* c = str; *c != '\0'; ++c)
{
- if(*c == '"')
+ switch(*c)
{
- putc('\\', fp);
+ case '"':
+ putc('\\', fp);
+ putc(*c, fp);
+ break;
+ case '\n':
+ putc('\\', fp);
+ putc('n', fp);
+ break;
+ case '\t':
+ putc(' ', fp);
+ putc(' ', fp);
+ putc(' ', fp);
+ putc(' ', fp);
+ break;
+ case '\\':
+ putc('\\', fp);
+ putc('\\', fp);
+ break;
+ default:
+ putc(*c, fp);
}
- putc(*c, fp);
}
putc('"', fp);
}
@@ -293,7 +325,7 @@ void LLScriptConstantString::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTC
case LSCP_TO_STACK:
{
chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGS]);
- chunk->addBytes(mValue, (S32)strlen(mValue) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(mValue, (S32)strlen(mValue) + 1);
type = mType;
}
break;
@@ -304,7 +336,7 @@ void LLScriptConstantString::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTC
break;
case LSCP_EMIT_CIL_ASSEMBLY:
fprintf(fp, "ldstr ");
- print_escape_quotes(fp, mValue);
+ print_escaped(fp, mValue);
fprintf(fp, "\n");
default:
break;
@@ -313,10 +345,9 @@ void LLScriptConstantString::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTC
S32 LLScriptConstantString::getSize()
{
- return (S32)strlen(mValue) + 1; /*Flawfinder: ignore*/
+ return (S32)strlen(mValue) + 1;
}
-
void LLScriptIdentifier::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
{
if (gErrorToText.getErrors())
@@ -388,7 +419,7 @@ void LLScriptIdentifier::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompi
}
break;
case LSCP_EMIT_CIL_ASSEMBLY:
- fprintf(fp, "%s", mName);
+ fprintf(fp, "'%s'", mName);
break;
default:
break;
@@ -428,6 +459,12 @@ S32 LLScriptSimpleAssignable::getSize()
return 0;
}
+static void print_cil_member(LLFILE* fp, LLScriptIdentifier *ident)
+{
+ print_cil_type(fp, ident->mScopeEntry->mType);
+ fprintf(fp, " %s::'%s'\n", gScriptp->getClassName(), ident->mScopeEntry->mIdentifier);
+}
+
void LLScriptSAIdentifier::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
{
if (gErrorToText.getErrors())
@@ -497,6 +534,19 @@ void LLScriptSAIdentifier::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCom
}
}
break;
+
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ {
+ fprintf(fp, "ldarg.0\n");
+ fprintf(fp, "ldfld ");
+ print_cil_member(fp, mIdentifier);
+ fprintf(fp, "\n");
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ }
default:
mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
if (mNextp)
@@ -553,7 +603,8 @@ S32 LLScriptSAConstant::getSize()
return mConstant->getSize();
}
-void print_cil_cast(LLFILE* fp, LSCRIPTType srcType, LSCRIPTType targetType)
+
+static void print_cil_cast(LLFILE* fp, LSCRIPTType srcType, LSCRIPTType targetType)
{
switch(srcType)
{
@@ -567,9 +618,8 @@ void print_cil_cast(LLFILE* fp, LSCRIPTType srcType, LSCRIPTType targetType)
fprintf(fp, "call string class [mscorlib]System.Convert::ToString(int32)\n");
break;
case LST_LIST:
- fprintf(fp, "box [mscorlib]System.Int32\n");
- fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LScriptLibrary]LScriptInternal::CreateList()\n");
- fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LScriptLibrary]LScriptInternal::AddReturnList(object, class [mscorlib]System.Collections.ArrayList)\n");
+ print_cil_box(fp, LST_INTEGER);
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList(object)\n");
break;
default:
break;
@@ -582,10 +632,11 @@ void print_cil_cast(LLFILE* fp, LSCRIPTType srcType, LSCRIPTType targetType)
fprintf(fp, "conv.i4\n");
break;
case LST_STRING:
- fprintf(fp, "call string class [mscorlib]System.Convert::ToString(float32)\n");
+ fprintf(fp, "call string [LslLibrary]LindenLab.SecondLife.LslRunTime::ToString(float32)\n");
break;
case LST_LIST:
- fprintf(fp, "call class [mscorlib]System.Collections.ArrayList [LScriptLibrary]LScriptInternal::CreateList(object)\n");
+ print_cil_box(fp, LST_FLOATINGPOINT);
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList(object)\n");
break;
default:
break;
@@ -595,19 +646,22 @@ void print_cil_cast(LLFILE* fp, LSCRIPTType srcType, LSCRIPTType targetType)
switch(targetType)
{
case LST_INTEGER:
- fprintf(fp, "call int32 valuetype [mscorlib]System.Int32::Parse(string)\n");
+ fprintf(fp, "call int32 [LslLibrary]LindenLab.SecondLife.LslRunTime::StringToInt(string)\n");
break;
case LST_FLOATINGPOINT:
- fprintf(fp, "call float64 valuetype [mscorlib]System.Double::Parse(string)\n");
+ fprintf(fp, "call float32 [LslLibrary]LindenLab.SecondLife.LslRunTime::StringToFloat(string)\n");
break;
+ case LST_KEY:
+ fprintf(fp, "call valuetype [ScriptTypes]LindenLab.SecondLife.Key class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateKey'(string)\n");
+ break;
case LST_LIST:
- fprintf(fp, "call class [mscorlib]System.Collections.ArrayList [LScriptLibrary]LScriptInternal::CreateList(object)\n");
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList(object)\n");
break;
case LST_VECTOR:
- fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'Parse'(string)\n");
+ fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'ParseVector'(string)\n");
break;
case LST_QUATERNION:
- fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'Parse'(string)\n");
+ fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Quaternion class [LslUserScript]LindenLab.SecondLife.LslUserScript::'ParseQuaternion'(string)\n");
break;
default:
break;
@@ -619,9 +673,11 @@ void print_cil_cast(LLFILE* fp, LSCRIPTType srcType, LSCRIPTType targetType)
case LST_KEY:
break;
case LST_STRING:
+ fprintf(fp, "call string [LslUserScript]LindenLab.SecondLife.LslUserScript::'ToString'(valuetype [ScriptTypes]LindenLab.SecondLife.Key)\n");
break;
case LST_LIST:
- fprintf(fp, "call class [mscorlib]System.Collections.ArrayList [LScriptLibrary]LScriptInternal::CreateList(object)\n");
+ print_cil_box(fp, LST_KEY);
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList(object)\n");
break;
default:
break;
@@ -633,10 +689,11 @@ void print_cil_cast(LLFILE* fp, LSCRIPTType srcType, LSCRIPTType targetType)
case LST_VECTOR:
break;
case LST_STRING:
- fprintf(fp, "call string valuetype [LScriptLibrary]LLVector::'ToString'(valuetype [LScriptLibrary]LLVector)\n");
+ fprintf(fp, "call string [LslUserScript]LindenLab.SecondLife.LslUserScript::'ToString'(valuetype [ScriptTypes]LindenLab.SecondLife.Vector)\n");
break;
case LST_LIST:
- fprintf(fp, "call class [mscorlib]System.Collections.ArrayList [LScriptLibrary]LScriptInternal::CreateList(object)\n");
+ print_cil_box(fp, LST_VECTOR);
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList(object)\n");
break;
default:
break;
@@ -648,10 +705,11 @@ void print_cil_cast(LLFILE* fp, LSCRIPTType srcType, LSCRIPTType targetType)
case LST_QUATERNION:
break;
case LST_STRING:
- fprintf(fp, "call string valuetype [LScriptLibrary]LLQuaternion::'ToString'(valuetype [LScriptLibrary]LLQuaternion)\n");
+ fprintf(fp, "call string [LslUserScript]LindenLab.SecondLife.LslUserScript::'ToString'(valuetype [ScriptTypes]LindenLab.SecondLife.Quaternion)\n");
break;
case LST_LIST:
- fprintf(fp, "call class [mscorlib]System.Collections.ArrayList [LScriptLibrary]LScriptInternal::CreateList(object)\n");
+ print_cil_box(fp, LST_QUATERNION);
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList(object)\n");
break;
default:
break;
@@ -663,7 +721,7 @@ void print_cil_cast(LLFILE* fp, LSCRIPTType srcType, LSCRIPTType targetType)
case LST_LIST:
break;
case LST_STRING:
- fprintf(fp, "call string [LScriptLibrary]LScriptInternal::ListToString(class [mscorlib]System.Collections.ArrayList)\n");
+ fprintf(fp, "call string [LslLibrary]LindenLab.SecondLife.LslRunTime::ListToString(class [mscorlib]System.Collections.ArrayList)\n");
break;
default:
break;
@@ -674,10 +732,57 @@ void print_cil_cast(LLFILE* fp, LSCRIPTType srcType, LSCRIPTType targetType)
}
}
-bool is_SA_constant_integer(LLScriptSimpleAssignable* sa)
+static void print_cil_numeric_cast(LLFILE* fp, LSCRIPTType currentArg, LSCRIPTType otherArg)
{
- // HACK: Downcast based on type.
- return (sa->mType == LSSAT_CONSTANT && ((LLScriptSAConstant*) sa)->mConstant->mType == LST_INTEGER);
+ if((currentArg == LST_INTEGER) && ((otherArg == LST_FLOATINGPOINT) || (otherArg == LST_VECTOR)))
+ {
+ print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
+ }
+}
+
+static void print_cil_assignment_cast(LLFILE* fp, LSCRIPTType src,
+ LSCRIPTType dest)
+{
+ if (LST_STRING == src && LST_KEY == dest)
+ {
+ print_cil_cast(fp, src, dest);
+ }
+ else if(LST_KEY == src && LST_STRING == dest)
+ {
+ print_cil_cast(fp, src, dest);
+ }
+ else
+ {
+ print_cil_numeric_cast(fp, src, dest);
+ }
+}
+
+// HACK! Babbage: should be converted to virtual on LSCRIPTSimpleAssignableType to avoid downcasts.
+LSCRIPTType get_type(LLScriptSimpleAssignable* sa)
+{
+ LSCRIPTType result = LST_NULL;
+ switch(sa->mType)
+ {
+ case LSSAT_IDENTIFIER:
+ result = ((LLScriptSAIdentifier*) sa)->mIdentifier->mScopeEntry->mType;
+ break;
+ case LSSAT_CONSTANT:
+ result = ((LLScriptSAConstant*) sa)->mConstant->mType;
+ break;
+ case LSSAT_VECTOR_CONSTANT:
+ result = LST_VECTOR;
+ break;
+ case LSSAT_QUATERNION_CONSTANT:
+ result = LST_QUATERNION;
+ break;
+ case LSSAT_LIST_CONSTANT:
+ result = LST_LIST;
+ break;
+ default:
+ result = LST_UNDEFINED;
+ break;
+ }
+ return result;
}
void LLScriptSAVector::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
@@ -786,23 +891,23 @@ void LLScriptSAVector::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompile
// Load arguments.
mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- if(is_SA_constant_integer(mEntry1))
+ if(LST_INTEGER == get_type(mEntry1))
{
print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
}
mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- if(is_SA_constant_integer(mEntry3))
+ if(LST_INTEGER == get_type(mEntry2))
{
print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
}
mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- if(is_SA_constant_integer(mEntry3))
+ if(LST_INTEGER == get_type(mEntry3))
{
print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
}
// Call named ctor, which leaves new Vector on stack, so it can be saved in to local or argument just like a primitive type.
- fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'create'(float32, float32, float32)\n");
+ fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)\n");
// Next.
if (mNextp)
@@ -952,28 +1057,28 @@ void LLScriptSAQuaternion::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCom
// Load arguments.
mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- if(is_SA_constant_integer(mEntry1))
+ if(LST_INTEGER == get_type(mEntry1))
{
print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
}
mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- if(is_SA_constant_integer(mEntry2))
+ if(LST_INTEGER == get_type(mEntry2))
{
print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
}
mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- if(is_SA_constant_integer(mEntry3))
+ if(LST_INTEGER == get_type(mEntry3))
{
print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
}
mEntry4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- if(is_SA_constant_integer(mEntry4))
+ if(LST_INTEGER == get_type(mEntry4))
{
print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
}
// Call named ctor, which leaves new Vector on stack, so it can be saved in to local or argument just like a primitive type.
- fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'create'(float32, float32, float32, float32)\n");
+ fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Quaternion class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateQuaternion'(float32, float32, float32, float32)\n");
// Next.
if (mNextp)
@@ -1049,6 +1154,40 @@ void LLScriptSAList::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePa
}
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ {
+ // Create list.
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()\n");
+
+ // Add elements.
+ LLScriptSimpleAssignable* current_entry = mEntryList;
+ LLScriptSimpleAssignable* next_entry = NULL;
+ while(NULL != current_entry)
+ {
+ next_entry = current_entry->mNextp;
+
+ // Null mNextp pointer, so only current list element is processed.
+ current_entry->mNextp = NULL;
+ current_entry->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+
+ // Restore mNextp pointer.
+ current_entry->mNextp = next_entry;
+
+ // Box element and store in list.
+ print_cil_box(fp, get_type(current_entry));
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(class [mscorlib]System.Collections.ArrayList, object)\n");
+
+ // Process next element.
+ current_entry = next_entry;
+ }
+
+ // Process next list.
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ }
+ break;
default:
if (mEntryList)
mEntryList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, ldata);
@@ -1093,6 +1232,45 @@ void LLScriptGlobalVariable::gonext(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCo
}
}
+// Push initialised variable of type on to stack.
+static void print_cil_init_variable(LLFILE* fp, LSCRIPTType type)
+{
+ switch(type)
+ {
+ case LST_INTEGER:
+ fprintf(fp, "ldc.i4.0\n");
+ break;
+ case LST_FLOATINGPOINT:
+ fprintf(fp, "ldc.r8 0\n");
+ break;
+ case LST_STRING:
+ fprintf(fp, "ldstr \"\"\n");
+ break;
+ case LST_KEY:
+ fprintf(fp, "ldstr \"\"\n");
+ fprintf(fp, "call valuetype [ScriptTypes]LindenLab.SecondLife.Key class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateKey'(string)\n");
+ break;
+ case LST_VECTOR:
+ fprintf(fp, "ldc.r8 0\n");
+ fprintf(fp, "ldc.r8 0\n");
+ fprintf(fp, "ldc.r8 0\n");
+ fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)\n");
+ break;
+ case LST_QUATERNION:
+ fprintf(fp, "ldc.r8 1\n");
+ fprintf(fp, "ldc.r8 0\n");
+ fprintf(fp, "ldc.r8 0\n");
+ fprintf(fp, "ldc.r8 0\n");
+ fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Quaternion class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateQuaternion'(float32, float32, float32, float32)\n");
+ break;
+ case LST_LIST:
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()\n");
+ break;
+ default:
+ break;
+ }
+}
+
void LLScriptGlobalVariable::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
{
if (gErrorToText.getErrors())
@@ -1164,7 +1342,7 @@ void LLScriptGlobalVariable::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTC
// it also includes the name of the variable as well as the type
// plus 4 bytes of offset from it's apparent address to the actual data
#ifdef LSL_INCLUDE_DEBUG_INFO
- count += strlen(mIdentifier->mName) + 1 + 1 + 4; /*Flawfinder: ignore*/
+ count += strlen(mIdentifier->mName) + 1 + 1 + 4;
#else
count += 1 + 1 + 4;
#endif
@@ -1187,7 +1365,7 @@ void LLScriptGlobalVariable::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTC
chunk->addBytes(&vtype, 1);
// null terminated name
#ifdef LSL_INCLUDE_DEBUG_INFO
- chunk->addBytes(mIdentifier->mName, strlen(mIdentifier->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(mIdentifier->mName, strlen(mIdentifier->mName) + 1);
#else
chunk->addBytes(1);
#endif
@@ -1257,16 +1435,27 @@ void LLScriptGlobalVariable::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTC
case LSCP_EMIT_CIL_ASSEMBLY:
// Initialisation inside ctor.
+ fprintf(fp, "ldarg.0\n");
if (mAssignable)
{
- fprintf(fp, "ldarg.0\n");
- mAssignable->recurse(fp, tabs, tabsize, LSCP_EMIT_CIL_ASSEMBLY, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- fprintf(fp, "stfld ");
- mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- fprintf(fp," LSL::");
- mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- fprintf(fp, "\n");
+ // Initialise to value.
+ mAssignable->recurse(fp, tabs, tabsize, LSCP_EMIT_CIL_ASSEMBLY,
+ ptype, prunearg, scope, type, basetype,
+ count, chunk, heap, stacksize, entry,
+ entrycount, NULL);
+ print_cil_assignment_cast(fp, get_type(mAssignable), mType->mType);
+ }
+ else
+ {
+ // Initialise to zero.
+ print_cil_init_variable(fp, mType->mType);
}
+ // Store value.
+ fprintf(fp, "stfld ");
+ mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp," %s::", gScriptp->getClassName());
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "\n");
break;
default:
mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -1298,6 +1487,20 @@ S32 LLScriptEvent::getSize()
printf("Event Base Class -- should never get here!\n");
return 0;
}
+static void checkForDuplicateHandler(LLFILE *fp, LLScriptFilePosition *pos,
+ LLScriptScope *scope,
+ const char* name)
+{
+ LLScriptScope *parent = scope->mParentScope;
+ if (parent->checkEntry((char*)name))
+ {
+ gErrorToText.writeError(fp, pos, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ parent->addEntry(((char*)name), LIT_HANDLER, LST_NULL);
+ }
+}
void LLScriptStateEntryEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
{
@@ -1314,11 +1517,14 @@ void LLScriptStateEntryEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPT
case LSCP_EMIT_ASSEMBLY:
fprintf(fp, "state_entry()\n");
break;
+ case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "state_entry");
+ break;
case LSCP_EMIT_BYTE_CODE:
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "state_entry";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
#endif
}
break;
@@ -1347,6 +1553,9 @@ void LLScriptStateExitEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTC
fdotabs(fp, tabs, tabsize);
fprintf(fp, "state_exit()\n");
break;
+ case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "state_exit");
+ break;
case LSCP_EMIT_ASSEMBLY:
fprintf(fp, "state_exit()\n");
break;
@@ -1354,7 +1563,7 @@ void LLScriptStateExitEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTC
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "state_exit";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
#endif
}
break;
@@ -1388,6 +1597,7 @@ void LLScriptTouchStartEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPT
break;
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "touch_start");
if (scope->checkEntry(mCount->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -1412,11 +1622,18 @@ void LLScriptTouchStartEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPT
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "touch_start";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "touch_start( int32 ");
+ mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
+ break;
default:
mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
break;
@@ -1446,6 +1663,7 @@ void LLScriptTouchEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompi
break;
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "touch");
if (scope->checkEntry(mCount->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -1470,11 +1688,18 @@ void LLScriptTouchEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompi
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "touch";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "touch( int32 ");
+ mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
+ break;
default:
mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
break;
@@ -1504,6 +1729,7 @@ void LLScriptTouchEndEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCo
break;
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "touch_end");
if (scope->checkEntry(mCount->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -1528,11 +1754,18 @@ void LLScriptTouchEndEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCo
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "touch_end";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "touch_end( int32 ");
+ mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
+ break;
default:
mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
break;
@@ -1562,6 +1795,7 @@ void LLScriptCollisionStartEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSC
break;
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "collision_start");
if (scope->checkEntry(mCount->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -1586,11 +1820,17 @@ void LLScriptCollisionStartEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSC
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "collision_start";
- chunk->addBytes(name, (S32)strlen(name) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mCount->mName, (S32)strlen(mCount->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, (S32)strlen(name) + 1);
+ chunk->addBytes(mCount->mName, (S32)strlen(mCount->mName) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "collision_start( int32 ");
+ mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
default:
mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
break;
@@ -1620,6 +1860,7 @@ void LLScriptCollisionEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTC
break;
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "collision");
if (scope->checkEntry(mCount->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -1644,11 +1885,16 @@ void LLScriptCollisionEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTC
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "collision";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fprintf(fp, "collision( int32 ");
+ mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
default:
mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
break;
@@ -1678,6 +1924,7 @@ void LLScriptCollisionEndEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRI
break;
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "collision_end");
if (scope->checkEntry(mCount->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -1702,11 +1949,17 @@ void LLScriptCollisionEndEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRI
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "collision_end";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "collision_end( int32 ");
+ mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
default:
mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
break;
@@ -1735,6 +1988,7 @@ void LLScriptLandCollisionStartEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize,
fprintf(fp, " )\n");
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "land_collision_start");
if (scope->checkEntry(mPosition->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -1759,11 +2013,17 @@ void LLScriptLandCollisionStartEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize,
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "land_collision_start";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mPosition->mName, strlen(mPosition->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mPosition->mName, strlen(mPosition->mName) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "land_collision_start( class [ScriptTypes]LindenLab.SecondLife.Vector ");
+ mPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
default:
mPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
break;
@@ -1794,6 +2054,7 @@ void LLScriptLandCollisionEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCR
fprintf(fp, " )\n");
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "land_collision");
if (scope->checkEntry(mPosition->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -1818,11 +2079,17 @@ void LLScriptLandCollisionEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCR
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "land_collision";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mPosition->mName, strlen(mPosition->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mPosition->mName, strlen(mPosition->mName) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "land_collision( class [ScriptTypes]LindenLab.SecondLife.Vector ");
+ mPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
default:
mPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
break;
@@ -1852,6 +2119,7 @@ void LLScriptLandCollisionEndEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, L
fprintf(fp, " )\n");
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "land_collision_end");
if (scope->checkEntry(mPosition->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -1875,12 +2143,18 @@ void LLScriptLandCollisionEndEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, L
case LSCP_EMIT_BYTE_CODE:
{
#ifdef LSL_INCLUDE_DEBUG_INFO
- char name[] = "land_collision_end"; /*Flawfinder: ignore*/
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mPosition->mName, strlen(mPosition->mName) + 1); /*Flawfinder: ignore*/
+ char name[] = "land_collision_end";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mPosition->mName, strlen(mPosition->mName) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "land_collision_end( class [ScriptTypes]LindenLab.SecondLife.Vector ");
+ mPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
default:
mPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
break;
@@ -1910,6 +2184,7 @@ void LLScriptInventoryEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTC
fprintf(fp, " )\n");
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "changed");
if (scope->checkEntry(mChange->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -1934,11 +2209,17 @@ void LLScriptInventoryEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTC
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "changed";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mChange->mName, strlen(mChange->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mChange->mName, strlen(mChange->mName) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "changed( int32 ");
+ mChange->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
default:
mChange->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
break;
@@ -1967,6 +2248,7 @@ void LLScriptAttachEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTComp
fprintf(fp, " )\n");
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "attach");
if (scope->checkEntry(mAttach->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -1991,11 +2273,17 @@ void LLScriptAttachEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTComp
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "attach";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mAttach->mName, strlen(mAttach->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mAttach->mName, strlen(mAttach->mName) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "attach( valuetype [ScriptTypes]LindenLab.SecondLife.Key ");
+ mAttach->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
default:
mAttach->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
break;
@@ -2026,6 +2314,7 @@ void LLScriptDataserverEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPT
fprintf(fp, " )\n");
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "dataserver");
if (scope->checkEntry(mID->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -2061,12 +2350,20 @@ void LLScriptDataserverEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPT
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "dataserver";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mID->mName, strlen(mID->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mData->mName, strlen(mData->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mID->mName, strlen(mID->mName) + 1);
+ chunk->addBytes(mData->mName, strlen(mData->mName) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "dataserver( valuetype [ScriptTypes]LindenLab.SecondLife.Key ");
+ mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", string ");
+ mData->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
default:
mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mData->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -2095,14 +2392,21 @@ void LLScriptTimerEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompi
case LSCP_EMIT_ASSEMBLY:
fprintf(fp, "timer()\n");
break;
+ case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "timer");
+ break;
+
case LSCP_EMIT_BYTE_CODE:
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "timer";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fprintf(fp, "timer()");
+ break;
default:
break;
}
@@ -2126,14 +2430,21 @@ void LLScriptMovingStartEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIP
fdotabs(fp, tabs, tabsize);
fprintf(fp, "moving_start()\n");
break;
+ case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "moving_start");
+ break;
+
case LSCP_EMIT_BYTE_CODE:
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "moving_start";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fprintf(fp, "moving_start()");
+ break;
default:
break;
}
@@ -2157,14 +2468,21 @@ void LLScriptMovingEndEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTC
fdotabs(fp, tabs, tabsize);
fprintf(fp, "moving_end()\n");
break;
+ case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "moving_end");
+ break;
+
case LSCP_EMIT_BYTE_CODE:
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "moving_end";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fprintf(fp, "moving_end()");
+ break;
default:
break;
}
@@ -2191,6 +2509,7 @@ void LLScriptRTPEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompile
fprintf(fp, " )\n");
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "run_time_perms");
if (scope->checkEntry(mRTPermissions->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -2215,11 +2534,18 @@ void LLScriptRTPEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompile
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "chat";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mRTPermissions->mName, strlen(mRTPermissions->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mRTPermissions->mName, strlen(mRTPermissions->mName) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ // NOTE: Not replicating LSL2 bug by calling RTP event hander "chat"
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "run_time_perms( int32 ");
+ mRTPermissions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
default:
mRTPermissions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
break;
@@ -2254,6 +2580,7 @@ void LLScriptChatEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompil
fprintf(fp, " )\n");
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "listen"); // note: this is actually listen in lsl source
if (scope->checkEntry(mChannel->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -2311,14 +2638,26 @@ void LLScriptChatEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompil
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "chat";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mChannel->mName, strlen(mChannel->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mName->mName, strlen(mName->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mID->mName, strlen(mID->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mMessage->mName, strlen(mMessage->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mChannel->mName, strlen(mChannel->mName) + 1);
+ chunk->addBytes(mName->mName, strlen(mName->mName) + 1);
+ chunk->addBytes(mID->mName, strlen(mID->mName) + 1);
+ chunk->addBytes(mMessage->mName, strlen(mMessage->mName) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "chat( int32 ");
+ mChannel->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", string ");
+ mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", valuetype [ScriptTypes]LindenLab.SecondLife.Key ");
+ mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", string ");
+ mMessage->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
default:
mChannel->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -2350,6 +2689,7 @@ void LLScriptSensorEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTComp
fprintf(fp, " )\n");
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "sensor");
if (scope->checkEntry(mNumber->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -2374,11 +2714,17 @@ void LLScriptSensorEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTComp
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "sensor";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mNumber->mName, strlen(mNumber->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mNumber->mName, strlen(mNumber->mName) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "sensor( int32 ");
+ mNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
default:
mNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
break;
@@ -2407,6 +2753,7 @@ void LLScriptObjectRezEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTC
fprintf(fp, " )\n");
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "object_rez");
if (scope->checkEntry(mID->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -2431,11 +2778,17 @@ void LLScriptObjectRezEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTC
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "sensor";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mID->mName, strlen(mID->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mID->mName, strlen(mID->mName) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "object_rez( valuetype [ScriptTypes]LindenLab.SecondLife.Key ");
+ mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
default:
mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
break;
@@ -2468,6 +2821,7 @@ void LLScriptControlEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCom
fprintf(fp, " )\n");
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "control");
if (scope->checkEntry(mName->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -2514,13 +2868,23 @@ void LLScriptControlEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCom
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "control";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mName->mName, strlen(mName->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mLevels->mName, strlen(mLevels->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mEdges->mName, strlen(mEdges->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mName->mName, strlen(mName->mName) + 1);
+ chunk->addBytes(mLevels->mName, strlen(mLevels->mName) + 1);
+ chunk->addBytes(mEdges->mName, strlen(mEdges->mName) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "control( valuetype [ScriptTypes]LindenLab.SecondLife.Key ");
+ mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", int32 ");
+ mLevels->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", int32 ");
+ mEdges->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
default:
mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mLevels->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -2557,6 +2921,7 @@ void LLScriptLinkMessageEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIP
fprintf(fp, " )\n");
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "link_message");
if (scope->checkEntry(mSender->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -2614,14 +2979,26 @@ void LLScriptLinkMessageEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIP
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "link_message";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mSender->mName, strlen(mSender->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mNum->mName, strlen(mNum->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mStr->mName, strlen(mStr->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mID->mName, strlen(mID->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mSender->mName, strlen(mSender->mName) + 1);
+ chunk->addBytes(mNum->mName, strlen(mNum->mName) + 1);
+ chunk->addBytes(mStr->mName, strlen(mStr->mName) + 1);
+ chunk->addBytes(mID->mName, strlen(mID->mName) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "link_message( int32 ");
+ mSender->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", int32 ");
+ mNum->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", string ");
+ mStr->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", valuetype [ScriptTypes]LindenLab.SecondLife.Key ");
+ mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
default:
mSender->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mNum->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -2663,6 +3040,7 @@ void LLScriptRemoteEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTComp
fprintf(fp, " )\n");
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "remote_event");
if (scope->checkEntry(mType->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -2742,16 +3120,32 @@ void LLScriptRemoteEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTComp
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "remote_event";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mType->mName, strlen(mType->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mChannel->mName, strlen(mChannel->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mMessageID->mName, strlen(mMessageID->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mSender->mName, strlen(mSender->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mIntVal->mName, strlen(mIntVal->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mStrVal->mName, strlen(mStrVal->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mType->mName, strlen(mType->mName) + 1);
+ chunk->addBytes(mChannel->mName, strlen(mChannel->mName) + 1);
+ chunk->addBytes(mMessageID->mName, strlen(mMessageID->mName) + 1);
+ chunk->addBytes(mSender->mName, strlen(mSender->mName) + 1);
+ chunk->addBytes(mIntVal->mName, strlen(mIntVal->mName) + 1);
+ chunk->addBytes(mStrVal->mName, strlen(mStrVal->mName) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "remote_event( int32 ");
+ mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", valuetype [ScriptTypes]LindenLab.SecondLife.Key ");
+ mChannel->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", valuetype [ScriptTypes]LindenLab.SecondLife.Key ");
+ mMessageID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", string ");
+ mSender->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", int32 ");
+ mIntVal->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", string ");
+ mStrVal->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
default:
mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mChannel->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -2784,7 +3178,7 @@ void LLScriptHTTPResponseEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRI
mRequestId->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, ", integer ");
mStatus->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- fprintf(fp, ", list ");
+ fprintf(fp, ", class [mscorlib]System.Collections.ArrayList ");
mMetadata->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, ", string ");
mBody->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -2792,6 +3186,7 @@ void LLScriptHTTPResponseEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRI
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "http_response");
if (scope->checkEntry(mRequestId->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -2857,15 +3252,26 @@ void LLScriptHTTPResponseEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRI
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "http_response";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mRequestId->mName, strlen(mRequestId->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mStatus->mName, strlen(mStatus->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mMetadata->mName, strlen(mMetadata->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mBody->mName, strlen(mBody->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mRequestId->mName, strlen(mRequestId->mName) + 1);
+ chunk->addBytes(mStatus->mName, strlen(mStatus->mName) + 1);
+ chunk->addBytes(mMetadata->mName, strlen(mMetadata->mName) + 1);
+ chunk->addBytes(mBody->mName, strlen(mBody->mName) + 1);
#endif
}
break;
-
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "http_response( valuetype [ScriptTypes]LindenLab.SecondLife.Key ");
+ mRequestId->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", int32 ");
+ mStatus->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", class [mscorlib]System.Collections.ArrayList ");
+ mMetadata->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", string ");
+ mBody->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
default:
mRequestId->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mStatus->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -2900,6 +3306,7 @@ void LLScriptMoneyEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompi
fprintf(fp, " )\n");
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "money");
if (scope->checkEntry(mName->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -2935,12 +3342,20 @@ void LLScriptMoneyEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompi
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "money";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mName->mName, strlen(mName->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mAmount->mName, strlen(mAmount->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mName->mName, strlen(mName->mName) + 1);
+ chunk->addBytes(mAmount->mName, strlen(mAmount->mName) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "money( valuetype [ScriptTypes]LindenLab.SecondLife.Key ");
+ mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", int32 ");
+ mAmount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
default:
mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mAmount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -2978,6 +3393,7 @@ void LLScriptEmailEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompi
fprintf(fp, " )\n");
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "email");
if (scope->checkEntry(mTime->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -3046,15 +3462,29 @@ void LLScriptEmailEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompi
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "email";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mTime->mName, strlen(mTime->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mAddress->mName, strlen(mAddress->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mSubject->mName, strlen(mSubject->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mBody->mName, strlen(mBody->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mNumber->mName, strlen(mNumber->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mTime->mName, strlen(mTime->mName) + 1);
+ chunk->addBytes(mAddress->mName, strlen(mAddress->mName) + 1);
+ chunk->addBytes(mSubject->mName, strlen(mSubject->mName) + 1);
+ chunk->addBytes(mBody->mName, strlen(mBody->mName) + 1);
+ chunk->addBytes(mNumber->mName, strlen(mNumber->mName) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "email( string ");
+ mTime->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", string ");
+ mAddress->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", string ");
+ mSubject->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", string ");
+ mBody->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", int32 ");
+ mNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
default:
mTime->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mAddress->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -3087,6 +3517,7 @@ void LLScriptRezEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompile
fprintf(fp, " )\n");
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "rez");
if (scope->checkEntry(mStartParam->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -3111,11 +3542,17 @@ void LLScriptRezEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompile
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "rez";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mStartParam->mName, strlen(mStartParam->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mStartParam->mName, strlen(mStartParam->mName) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "rez( int32 ");
+ mStartParam->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
default:
mStartParam->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
break;
@@ -3143,14 +3580,20 @@ void LLScriptNoSensorEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCo
case LSCP_EMIT_ASSEMBLY:
fprintf(fp, "no_sensor()\n");
break;
- case LSCP_EMIT_BYTE_CODE:
+ case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "no_sensor");
+ break;
+ case LSCP_EMIT_BYTE_CODE:
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "no_sensor";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fprintf(fp, "no_sensor()");
+ break;
default:
break;
}
@@ -3181,6 +3624,7 @@ void LLScriptAtTarget::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompile
fprintf(fp, " )\n");
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "at_target");
if (scope->checkEntry(mTargetNumber->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -3226,14 +3670,24 @@ void LLScriptAtTarget::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompile
case LSCP_EMIT_BYTE_CODE:
{
#ifdef LSL_INCLUDE_DEBUG_INFO
- char name[] = "at_target"; /*Flawfinder: ignore*/
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mTargetNumber->mName, strlen(mTargetNumber->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mTargetPosition->mName, strlen(mTargetPosition->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mOurPosition->mName, strlen(mOurPosition->mName) + 1); /*Flawfinder: ignore*/
+ char name[] = "at_target";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mTargetNumber->mName, strlen(mTargetNumber->mName) + 1);
+ chunk->addBytes(mTargetPosition->mName, strlen(mTargetPosition->mName) + 1);
+ chunk->addBytes(mOurPosition->mName, strlen(mOurPosition->mName) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "at_target( int32 ");
+ mTargetNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", class [ScriptTypes]LindenLab.SecondLife.Vector ");
+ mTargetPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", class [ScriptTypes]LindenLab.SecondLife.Vector ");
+ mOurPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
default:
mTargetNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mTargetPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -3265,14 +3719,21 @@ void LLScriptNotAtTarget::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTComp
case LSCP_EMIT_ASSEMBLY:
fprintf(fp, "not_at_target()\n");
break;
+ case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "not_at_target");
+ break;
+
case LSCP_EMIT_BYTE_CODE:
{
#ifdef LSL_INCLUDE_DEBUG_INFO
- char name[] = "not_at_target"; /*Flawfinder: ignore*/
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
+ char name[] = "not_at_target";
+ chunk->addBytes(name, strlen(name) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fprintf(fp, "not_at_target()");
+ break;
default:
break;
}
@@ -3294,7 +3755,7 @@ void LLScriptAtRotTarget::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTComp
case LSCP_PRETTY_PRINT:
case LSCP_EMIT_ASSEMBLY:
fdotabs(fp, tabs, tabsize);
- fprintf(fp, "at_target( integer ");
+ fprintf(fp, "at_rot_target( integer ");
mTargetNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, ", quaternion ");
mTargetRotation->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -3303,6 +3764,7 @@ void LLScriptAtRotTarget::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTComp
fprintf(fp, " )\n");
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "at_rot_target");
if (scope->checkEntry(mTargetNumber->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -3349,13 +3811,23 @@ void LLScriptAtRotTarget::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTComp
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "at_rot_target";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mTargetNumber->mName, strlen(mTargetNumber->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mTargetRotation->mName, strlen(mTargetRotation->mName) + 1); /*Flawfinder: ignore*/
- chunk->addBytes(mOurRotation->mName, strlen(mOurRotation->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mTargetNumber->mName, strlen(mTargetNumber->mName) + 1);
+ chunk->addBytes(mTargetRotation->mName, strlen(mTargetRotation->mName) + 1);
+ chunk->addBytes(mOurRotation->mName, strlen(mOurRotation->mName) + 1);
#endif
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "at_rot_target( int32 ");
+ mTargetNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", class [ScriptTypes]LindenLab.SecondLife.Quaternion ");
+ mTargetRotation->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", class [ScriptTypes]LindenLab.SecondLife.Quaternion ");
+ mOurRotation->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
default:
mTargetNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mTargetRotation->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -3391,10 +3863,17 @@ void LLScriptNotAtRotTarget::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTC
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "not_at_rot_target";
- chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(name, strlen(name) + 1);
#endif
}
break;
+ case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "not_at_rot_target");
+ break;
+
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fprintf(fp, "not_at_rot_target()");
+ break;
default:
break;
}
@@ -3563,6 +4042,25 @@ S32 LLScriptForExpressionList::getSize()
return 0;
}
+// CIL code generation requires both caller and callee scope entries, so cannot use normal recurse signature.
+// TODO: Refactor general purpose recurse calls in to pass specific virtuals using visitor pattern to select method by pass and node type.
+static void print_cil_func_expression_list(LLScriptFuncExpressionList* self, LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata, LLScriptScopeEntry *callee_entry)
+{
+ self->mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ LSCRIPTType argtype = callee_entry->mFunctionArgs.getType(entrycount);
+ if (argtype != self->mFirstp->mReturnType)
+ {
+ print_cil_cast(fp, self->mFirstp->mReturnType, argtype);
+ }
+ entrycount++;
+ if (self->mSecondp)
+ {
+ llassert(LET_FUNC_EXPRESSION_LIST == self->mSecondp->mType);
+ print_cil_func_expression_list((LLScriptFuncExpressionList*) self->mSecondp, fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL, callee_entry);
+
+ }
+}
+
void LLScriptFuncExpressionList::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
{
if (gErrorToText.getErrors())
@@ -3660,31 +4158,6 @@ void LLScriptFuncExpressionList::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCR
}
}
break;
- /* TODO: Fix conflict between global/local variable determination needing caller scope and cast determination here needs callee scope...
- case LSCP_EMIT_CIL_ASSEMBLY:
- {
- mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- LSCRIPTType argtype = entry->mFunctionArgs.getType(entrycount);
- if (argtype != mFirstp->mReturnType)
- {
- print_cil_cast(fp, mFirstp->mReturnType, argtype);
- }
- entrycount++;
- if (mSecondp)
- {
- mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- if (mSecondp->mReturnType)
- {
- argtype = entry->mFunctionArgs.getType(entrycount);
- if (argtype != mSecondp->mReturnType)
- {
- print_cil_cast(fp, mFirstp->mReturnType, argtype);
- }
- }
- }
- }
- break;
- */
default:
mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
if (mSecondp)
@@ -3753,8 +4226,13 @@ void LLScriptListExpressionList::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCR
}
break;
case LSCP_EMIT_CIL_ASSEMBLY:
- // Evaluate expressions in reverse order so first expression is on top of stack.
- // Results can then be popped and appended to list to result in list with correct order.
+ mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mFirstp->mType != LET_LIST_EXPRESSION_LIST)
+ {
+ // Box value.
+ print_cil_box(fp, mFirstp->mReturnType);
+ ++count;
+ }
if (mSecondp)
{
mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -3762,18 +4240,9 @@ void LLScriptListExpressionList::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCR
{
// Box value.
print_cil_box(fp, mSecondp->mReturnType);
-
++count;
}
}
- mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- if (mFirstp->mType != LET_LIST_EXPRESSION_LIST)
- {
- // Box value.
- print_cil_box(fp, mFirstp->mReturnType);
-
- ++count;
- }
break;
default:
mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -3793,14 +4262,22 @@ S32 LLScriptListExpressionList::getSize()
// Returns true if identifier is a parameter and false if identifier is a local variable within function_scope.
bool is_parameter(LLScriptIdentifier* identifier, LLScriptScopeEntry* function_scope)
{
- // Function offset stores offset of first local.
- // Compare variable offset with function offset to
- // determine whether variable is local or parameter.
- return (identifier->mScopeEntry->mOffset < function_scope->mOffset);
+ // Function stores offset of first local.
+ if(0 == function_scope->mOffset)
+ {
+ // Function offset 0 -> no parameters -> identifier is a local.
+ return false;
+ }
+ else
+ {
+ // Compare variable offset with function offset to
+ // determine whether variable is local or parameter.
+ return (identifier->mScopeEntry->mOffset < function_scope->mOffset);
+ }
}
// If assignment is to global variable, pushes this pointer on to stack.
-void print_cil_load_address(LLFILE* fp, LLScriptExpression* exp, LLScriptScopeEntry* function_scope)
+static void print_cil_load_address(LLFILE* fp, LLScriptExpression* exp, LLScriptScopeEntry* function_scope)
{
LLScriptLValue *lvalue = (LLScriptLValue *) exp;
LLScriptIdentifier *ident = lvalue->mIdentifier;
@@ -3811,7 +4288,7 @@ void print_cil_load_address(LLFILE* fp, LLScriptExpression* exp, LLScriptScopeEn
fprintf(fp, "ldarg.0\n");
}
- // If accessor, load address of object.
+ // If accessor, load value type address, consumed by ldfld.
if(lvalue->mAccessor)
{
if(ident->mScopeEntry->mIDType == LIT_VARIABLE)
@@ -3819,7 +4296,7 @@ void print_cil_load_address(LLFILE* fp, LLScriptExpression* exp, LLScriptScopeEn
if(is_parameter(ident, function_scope))
{
// Parameter, load by name.
- fprintf(fp, "ldarga.s %s\n", ident->mScopeEntry->mIdentifier);
+ fprintf(fp, "ldarga.s '%s'\n", ident->mScopeEntry->mIdentifier);
}
else
{
@@ -3830,13 +4307,13 @@ void print_cil_load_address(LLFILE* fp, LLScriptExpression* exp, LLScriptScopeEn
else if (ident->mScopeEntry->mIDType == LIT_GLOBAL)
{
fprintf(fp, "ldflda ");
- print_cil_type(fp, ident->mScopeEntry->mType);
- fprintf(fp, " LSL::%s\n", ident->mScopeEntry->mIdentifier);
+ print_cil_member(fp, ident);
}
}
}
-void print_cil_accessor(LLFILE* fp, LLScriptLValue *lvalue)
+static void print_cil_accessor(LLFILE* fp, LLScriptLValue *lvalue)
+
{
LLScriptIdentifier *ident = lvalue->mIdentifier;
print_cil_type(fp, lvalue->mReturnType);
@@ -3845,12 +4322,6 @@ void print_cil_accessor(LLFILE* fp, LLScriptLValue *lvalue)
fprintf(fp, "::%s\n", lvalue->mAccessor->mName);
}
-void print_cil_member(LLFILE* fp, LLScriptIdentifier *ident)
-{
- print_cil_type(fp, ident->mScopeEntry->mType);
- fprintf(fp, " LSL::%s\n", ident->mScopeEntry->mIdentifier);
-}
-
void LLScriptLValue::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
{
if (gErrorToText.getErrors())
@@ -4106,7 +4577,7 @@ void LLScriptLValue::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePa
if(is_parameter(mIdentifier, entry))
{
// Parameter, load by name.
- fprintf(fp, "ldarg.s %s\n", mIdentifier->mScopeEntry->mIdentifier);
+ fprintf(fp, "ldarg.s '%s'\n", mIdentifier->mScopeEntry->mIdentifier);
}
else
{
@@ -4136,7 +4607,7 @@ S32 LLScriptLValue::getSize()
return 0;
}
-void print_asignment(LLFILE *fp, LLScriptExpression *exp)
+static void print_assignment(LLFILE *fp, LLScriptExpression *exp)
{
LLScriptLValue *lvalue = (LLScriptLValue *)exp;
LLScriptIdentifier *ident = lvalue->mIdentifier;
@@ -4164,7 +4635,7 @@ void print_asignment(LLFILE *fp, LLScriptExpression *exp)
}
}
-void print_cil_asignment(LLFILE *fp, LLScriptExpression *exp, LLScriptScopeEntry* function_scope)
+static void print_cil_assignment(LLFILE *fp, LLScriptExpression *exp, LLScriptScopeEntry* function_scope)
{
LLScriptLValue *lvalue = (LLScriptLValue *) exp;
LLScriptIdentifier *ident = lvalue->mIdentifier;
@@ -4191,7 +4662,7 @@ void print_cil_asignment(LLFILE *fp, LLScriptExpression *exp, LLScriptScopeEntry
if(is_parameter(ident, function_scope))
{
// Parameter, store by name.
- fprintf(fp, "starg.s %s\n", ident->mScopeEntry->mIdentifier);
+ fprintf(fp, "starg.s '%s'\n", ident->mScopeEntry->mIdentifier);
}
else
{
@@ -4319,14 +4790,6 @@ void store2stack(LLScriptExpression *exp, LLScriptExpression *lv, LLScriptByteCo
chunk->addInteger(address);
}
-void print_cil_numeric_cast(LLFILE* fp, LSCRIPTType currentArg, LSCRIPTType otherArg)
-{
- if((currentArg == LST_INTEGER) && (otherArg == LST_FLOATINGPOINT))
- {
- print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
- }
-}
-
void LLScriptAssignment::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
{
if (gErrorToText.getErrors())
@@ -4344,7 +4807,7 @@ void LLScriptAssignment::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompi
{
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
print_cast(fp, mReturnType, mRightType);
- print_asignment(fp, mLValue);
+ print_assignment(fp, mLValue);
}
break;
case LSCP_TYPE:
@@ -4370,8 +4833,8 @@ void LLScriptAssignment::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompi
{
print_cil_load_address(fp, mLValue, entry);
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- print_cil_numeric_cast(fp, mRightType, mReturnType);
- print_cil_asignment(fp, mLValue, entry);
+ print_cil_assignment_cast(fp, mRightType, mReturnType);
+ print_cil_assignment(fp, mLValue, entry);
}
break;
default:
@@ -4387,8 +4850,15 @@ S32 LLScriptAssignment::getSize()
return 0;
}
-void print_cil_add(LLFILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
+static void print_cil_add(LLFILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
{
+ if(LST_LIST == right_type && LST_LIST != left_type)
+ {
+ print_cil_box(fp, left_type);
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Prepend(class [mscorlib]System.Collections.ArrayList, object)\n");
+ return;
+ }
+
switch(left_type)
{
case LST_INTEGER:
@@ -4402,27 +4872,49 @@ void print_cil_add(LLFILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
case LST_KEY:
// String concatenation.
- fprintf(fp, "call string valuetype [mscorlib]System.String::Concat(string, string)");
+ fprintf(fp, "call string valuetype [LslUserScript]LindenLab.SecondLife.LslUserScript::Add(string, string)\n");
break;
case LST_VECTOR:
// Vector addition.
- // TODO: Inline (requires temporary variables, which must be identified in earlier pass).
- fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'add_vec'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLVector)\n");
+ fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Add'(class [ScriptTypes]LindenLab.SecondLife.Vector, class [ScriptTypes]LindenLab.SecondLife.Vector)\n");
break;
case LST_QUATERNION:
// Rotation addition.
- // TODO: Inline (requires temporary variables, which must be identified in earlier pass).
- fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'add_quat'(valuetype [LScriptLibrary]LLQuaternion, valuetype [LScriptLibrary]LLQuaternion)\n");
+ fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Quaternion class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Add'(class [ScriptTypes]LindenLab.SecondLife.Quaternion, class [ScriptTypes]LindenLab.SecondLife.Quaternion)\n");
break;
case LST_LIST:
- print_cil_box(fp, right_type);
- fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LScriptLibrary]LScriptInternal::AddReturnList(class [mscorlib]System.Collections.ArrayList, object)\n");
- break;
+ switch(right_type)
+ {
+ case LST_LIST:
+ // Concatenate lists.
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(class [mscorlib]System.Collections.ArrayList, class [mscorlib]System.Collections.ArrayList)\n");
+ break;
+ case LST_INTEGER:
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(int32, class [mscorlib]System.Collections.ArrayList)\n");
+ break;
+ case LST_FLOATINGPOINT:
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(float32, class [mscorlib]System.Collections.ArrayList)\n");
+ break;
+ case LST_STRING:
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(string, class [mscorlib]System.Collections.ArrayList)\n");
+ break;
+ case LST_KEY:
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(valuetype [ScriptTypes]LindenLab.SecondLife.Key, class [mscorlib]System.Collections.ArrayList)\n");
+ break;
+ case LST_VECTOR:
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(valuetype [ScriptTypes]LindenLab.SecondLife.Vector, class [mscorlib]System.Collections.ArrayList)\n");
+ break;
+ case LST_QUATERNION:
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(valuetype [ScriptTypes]LindenLab.SecondLife.Quaternion, class [mscorlib]System.Collections.ArrayList)\n");
+ break;
+ default:
+ break;
+ }
default:
break;
@@ -4447,7 +4939,7 @@ void LLScriptAddAssignment::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCo
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, "ADD %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
- print_asignment(fp, mLValue);
+ print_assignment(fp, mLValue);
}
break;
case LSCP_TYPE:
@@ -4475,12 +4967,12 @@ void LLScriptAddAssignment::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCo
case LSCP_EMIT_CIL_ASSEMBLY:
{
print_cil_load_address(fp, mLValue, entry);
- mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- print_cil_numeric_cast(fp, mLValue->mReturnType, mRightSide->mReturnType);
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
print_cil_numeric_cast(fp, mRightSide->mReturnType, mLValue->mReturnType);
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mLValue->mReturnType, mRightSide->mReturnType);
print_cil_add(fp, mLValue->mReturnType, mRightSide->mReturnType);
- print_cil_asignment(fp, mLValue, entry);
+ print_cil_assignment(fp, mLValue, entry);
}
break;
default:
@@ -4496,29 +4988,30 @@ S32 LLScriptAddAssignment::getSize()
return 0;
}
-void print_cil_sub(LLFILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
+static void print_cil_sub(LLFILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
{
switch(left_type)
{
case LST_INTEGER:
+ if(LST_INTEGER == right_type)
+ {
+ fprintf(fp, "call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Subtract(int32, int32)\n");
+ break;
+ }
case LST_FLOATINGPOINT:
-
// Numeric subtraction.
- fprintf(fp, "sub\n");
+ fprintf(fp, "call float64 [LslUserScript]LindenLab.SecondLife.LslUserScript::Subtract(float64, float64)\n");
break;
-
case LST_VECTOR:
// Vector subtraction.
- // TODO: Inline (requires temporary variables, which must be identified in earlier pass).
- fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'subtract_vec'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLVector)\n");
+ fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Subtract'(class [ScriptTypes]LindenLab.SecondLife.Vector, class [ScriptTypes]LindenLab.SecondLife.Vector)\n");
break;
case LST_QUATERNION:
// Rotation subtraction.
- // TODO: Inline (requires temporary variables, which must be identified in earlier pass).
- fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'subtract_quat'(valuetype [LScriptLibrary]LLQuaternion, valuetype [LScriptLibrary]LLQuaternion)\n");
+ fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Quaternion class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Subtract'(class [ScriptTypes]LindenLab.SecondLife.Quaternion, class [ScriptTypes]LindenLab.SecondLife.Quaternion)\n");
break;
default:
@@ -4546,7 +5039,7 @@ void LLScriptSubAssignment::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCo
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, "SUB %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
- print_asignment(fp, mLValue);
+ print_assignment(fp, mLValue);
}
break;
case LSCP_TYPE:
@@ -4574,12 +5067,12 @@ void LLScriptSubAssignment::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCo
case LSCP_EMIT_CIL_ASSEMBLY:
{
print_cil_load_address(fp, mLValue, entry);
- mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- print_cil_numeric_cast(fp, mLValue->mReturnType, mRightSide->mReturnType);
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
print_cil_numeric_cast(fp, mRightSide->mReturnType, mLValue->mReturnType);
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mLValue->mReturnType, mRightSide->mReturnType);
print_cil_sub(fp, mLValue->mReturnType, mRightSide->mReturnType);
- print_cil_asignment(fp, mLValue, entry);
+ print_cil_assignment(fp, mLValue, entry);
}
break;
default:
@@ -4595,41 +5088,93 @@ S32 LLScriptSubAssignment::getSize()
return 0;
}
-void print_cil_mul(LLFILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
+static void print_cil_neg(LLFILE* fp, LSCRIPTType type)
{
- switch(left_type)
+ switch(type)
{
case LST_INTEGER:
case LST_FLOATINGPOINT:
+ fprintf(fp, "neg\n");
+ break;
+ case LST_VECTOR:
+ fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Negate'(class [ScriptTypes]LindenLab.SecondLife.Vector)\n");
+ break;
+ case LST_QUATERNION:
+ fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Quaternion class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Negate'(class [ScriptTypes]LindenLab.SecondLife.Quaternion)\n");
+ break;
+ default:
+ break;
+ }
+}
- // Numeric multiplication.
- fprintf(fp, "mul\n");
+static void print_cil_mul(LLFILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
+{
+ switch(left_type)
+ {
+ case LST_INTEGER:
+
+ switch(right_type)
+ {
+ case LST_INTEGER:
+ case LST_FLOATINGPOINT:
+
+ // Numeric multiplication.
+ fprintf(fp, "mul\n");
+ break;
+
+ case LST_VECTOR:
+
+ // Vector scaling.
+ fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Multiply'(class [ScriptTypes]LindenLab.SecondLife.Vector, float32)\n");
+ break;
+ default:
+ break;
+ }
break;
-
- case LST_VECTOR:
+
+ case LST_FLOATINGPOINT:
switch(right_type)
{
case LST_INTEGER:
+ case LST_FLOATINGPOINT:
- print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
+ // Numeric multiplication.
+ fprintf(fp, "mul\n");
+ break;
+
+ case LST_VECTOR:
+
+ // Vector scaling.
+ fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Multiply'(class [ScriptTypes]LindenLab.SecondLife.Vector, float32)\n");
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case LST_VECTOR:
+ switch(right_type)
+ {
+ case LST_INTEGER:
case LST_FLOATINGPOINT:
// Vector scaling.
- fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'multiply_float'(valuetype [LScriptLibrary]LLVector, float32)\n");
+ fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Multiply'(float32, class [ScriptTypes]LindenLab.SecondLife.Vector)\n");
break;
case LST_VECTOR:
// Dot product.
- fprintf(fp, "call float32 valuetype [LScriptLibrary]LLVector::'multiply_vec'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLVector)\n");
+ fprintf(fp, "call float32 class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Multiply'(class [ScriptTypes]LindenLab.SecondLife.Vector, class [ScriptTypes]LindenLab.SecondLife.Vector)\n");
break;
case LST_QUATERNION:
// Vector rotation.
- fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'multiply_quat'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLQuaternion)\n");
+ fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Multiply'(class [ScriptTypes]LindenLab.SecondLife.Quaternion, class [ScriptTypes]LindenLab.SecondLife.Vector)\n");
break;
default:
@@ -4640,7 +5185,7 @@ void print_cil_mul(LLFILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
case LST_QUATERNION:
// Rotation multiplication.
- fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'multiply_quat'(valuetype [LScriptLibrary]LLQuaternion, valuetype [LScriptLibrary]LLQuaternion)\n");
+ fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Quaternion class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Multiply'(class [ScriptTypes]LindenLab.SecondLife.Quaternion, class [ScriptTypes]LindenLab.SecondLife.Quaternion)\n");
break;
default:
@@ -4668,7 +5213,7 @@ void LLScriptMulAssignment::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCo
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, "MUL %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
- print_asignment(fp, mLValue);
+ print_assignment(fp, mLValue);
}
break;
case LSCP_TYPE:
@@ -4677,7 +5222,7 @@ void LLScriptMulAssignment::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCo
mLeftType = type;
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mRightType = type;
- if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
+ if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType) /*|| !legal_assignment(mLValue->mReturnType, mReturnType)*/)
{
gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
}
@@ -4696,12 +5241,17 @@ void LLScriptMulAssignment::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCo
case LSCP_EMIT_CIL_ASSEMBLY:
{
print_cil_load_address(fp, mLValue, entry);
- mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- print_cil_numeric_cast(fp, mLValue->mReturnType, mRightSide->mReturnType);
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
print_cil_numeric_cast(fp, mRightSide->mReturnType, mLValue->mReturnType);
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mLValue->mReturnType, mRightSide->mReturnType);
print_cil_mul(fp, mLValue->mReturnType, mRightSide->mReturnType);
- print_cil_asignment(fp, mLValue, entry);
+ if((mLValue->mReturnType == LST_INTEGER) &&
+ (mRightSide->mReturnType == LST_FLOATINGPOINT))
+ {
+ print_cil_cast(fp, LST_FLOATINGPOINT, LST_INTEGER);
+ }
+ print_cil_assignment(fp, mLValue, entry);
}
break;
default:
@@ -4717,15 +5267,20 @@ S32 LLScriptMulAssignment::getSize()
return 0;
}
-void print_cil_div(LLFILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
+static void print_cil_div(LLFILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
{
switch(left_type)
{
case LST_INTEGER:
+ if(LST_INTEGER == right_type)
+ {
+ fprintf(fp, "call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Divide(int32, int32)\n");
+ break;
+ }
case LST_FLOATINGPOINT:
- // Numeric addition.
- fprintf(fp, "div\n");
+ // Numeric division.
+ fprintf(fp, "call float64 [LslUserScript]LindenLab.SecondLife.LslUserScript::Divide(float64, float64)\n");
break;
case LST_VECTOR:
@@ -4733,19 +5288,16 @@ void print_cil_div(LLFILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
switch(right_type)
{
case LST_INTEGER:
-
- print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
-
case LST_FLOATINGPOINT:
// Scale.
- fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'divide_float'(valuetype [LScriptLibrary]LLVector, float32)\n");
+ fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Divide'(float32, class [ScriptTypes]LindenLab.SecondLife.Vector)\n");
break;
case LST_QUATERNION:
// Inverse rotation.
- fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'divide_quat'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLQuaternion)\n");
+ fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Divide'(class [ScriptTypes]LindenLab.SecondLife.Quaternion, class [ScriptTypes]LindenLab.SecondLife.Vector)\n");
break;
default:
@@ -4755,7 +5307,7 @@ void print_cil_div(LLFILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
case LST_QUATERNION:
- fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'divide_quat'(valuetype [LScriptLibrary]LLQuaternion, valuetype [LScriptLibrary]LLQuaternion)\n");
+ fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Quaternion class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Divide'(class [ScriptTypes]LindenLab.SecondLife.Quaternion, class [ScriptTypes]LindenLab.SecondLife.Quaternion)\n");
break;
default:
@@ -4783,7 +5335,7 @@ void LLScriptDivAssignment::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCo
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, "DIV %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
- print_asignment(fp, mLValue);
+ print_assignment(fp, mLValue);
}
break;
case LSCP_TYPE:
@@ -4811,12 +5363,12 @@ void LLScriptDivAssignment::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCo
case LSCP_EMIT_CIL_ASSEMBLY:
{
print_cil_load_address(fp, mLValue, entry);
- mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- print_cil_numeric_cast(fp, mLValue->mReturnType, mRightSide->mReturnType);
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
print_cil_numeric_cast(fp, mRightSide->mReturnType, mLValue->mReturnType);
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mLValue->mReturnType, mRightSide->mReturnType);
print_cil_div(fp, mLValue->mReturnType, mRightSide->mReturnType);
- print_cil_asignment(fp, mLValue, entry);
+ print_cil_assignment(fp, mLValue, entry);
}
break;
default:
@@ -4832,20 +5384,20 @@ S32 LLScriptDivAssignment::getSize()
return 0;
}
-void print_cil_mod(LLFILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
+static void print_cil_mod(LLFILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
{
switch(left_type)
{
case LST_INTEGER:
// Numeric remainder.
- fprintf(fp, "rem\n");
+ fprintf(fp, "call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Modulo(int32, int32)\n");
break;
case LST_VECTOR:
// Vector cross product.
- fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'mod_vec'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLVector)\n");
+ fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Modulo'(class [ScriptTypes]LindenLab.SecondLife.Vector, class [ScriptTypes]LindenLab.SecondLife.Vector)\n");
break;
default:
@@ -4873,7 +5425,7 @@ void LLScriptModAssignment::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCo
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, "MOD %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
- print_asignment(fp, mLValue);
+ print_assignment(fp, mLValue);
}
break;
case LSCP_TYPE:
@@ -4901,10 +5453,10 @@ void LLScriptModAssignment::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCo
case LSCP_EMIT_CIL_ASSEMBLY:
{
print_cil_load_address(fp, mLValue, entry);
- mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
print_cil_mod(fp, mLValue->mReturnType, mRightSide->mReturnType);
- print_cil_asignment(fp, mLValue, entry);
+ print_cil_assignment(fp, mLValue, entry);
}
break;
default:
@@ -4920,9 +5472,10 @@ S32 LLScriptModAssignment::getSize()
return 0;
}
-void print_cil_eq(LLFILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
+static void print_cil_eq(LLFILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
{
- switch(left_type)
+
+ switch(right_type)
{
case LST_INTEGER:
case LST_FLOATINGPOINT:
@@ -4932,26 +5485,36 @@ void print_cil_eq(LLFILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
break;
case LST_STRING:
- case LST_KEY:
-
+ // NOTE: babbage: strings and keys can be compared, so a cast
+ // may be required
+ print_cil_cast(fp, left_type, right_type);
// String equality.
fprintf(fp, "call bool valuetype [mscorlib]System.String::op_Equality(string, string)\n");
break;
+
+ case LST_KEY:
+ // NOTE: babbage: strings and keys can be compared, so a cast
+ // may be required
+ print_cil_cast(fp, left_type, right_type);
+
+ // Key equality.
+ fprintf(fp, "call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::'Equals'(valuetype [ScriptTypes]LindenLab.SecondLife.Key, valuetype [ScriptTypes]LindenLab.SecondLife.Key)\n");
+ break;
case LST_VECTOR:
// Vector equality.
- fprintf(fp, "call bool [LScriptLibrary]LLVector::'equals_vec'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLVector)\n");
+ fprintf(fp, "call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::'Equals'(class [ScriptTypes]LindenLab.SecondLife.Vector, class [ScriptTypes]LindenLab.SecondLife.Vector)\n");
break;
case LST_QUATERNION:
// Rotation equality.
- fprintf(fp, "call bool [LScriptLibrary]LLQuaternion::'equals_quat'(valuetype [LScriptLibrary]LLQuaternion, valuetype [LScriptLibrary]LLQuaternion)\n");
+ fprintf(fp, "call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::'Equals'(class [ScriptTypes]LindenLab.SecondLife.Quaternion, class [ScriptTypes]LindenLab.SecondLife.Quaternion)\n");
break;
case LST_LIST:
- fprintf(fp, "call bool [LScriptLibrary]LScriptInternal::EqualsList(class [mscorlib]System.Collections.ArrayList, class [mscorlib]System.Collections.ArrayList)\n");
+ fprintf(fp, "call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Equals(class [mscorlib]System.Collections.ArrayList, class [mscorlib]System.Collections.ArrayList)\n");
break;
default:
@@ -5002,10 +5565,10 @@ void LLScriptEquality::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompile
}
break;
case LSCP_EMIT_CIL_ASSEMBLY:
- mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
print_cil_eq(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
break;
default:
@@ -5063,10 +5626,19 @@ void LLScriptNotEquals::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompil
break;
case LSCP_EMIT_CIL_ASSEMBLY:
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- fprintf(fp, "ceq\n");
- fprintf(fp, "ldc.i4.0\n");
- fprintf(fp, "ceq\n"); // Compare result of first compare equal with 0 to get compare not equal.
+ print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
+ if (LST_LIST == mLeftSide->mReturnType)
+ {
+ fprintf(fp, "call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::NotEquals(class [mscorlib]System.Collections.ArrayList, class [mscorlib]System.Collections.ArrayList)\n");
+ }
+ else
+ {
+ print_cil_eq(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
+ fprintf(fp, "ldc.i4.0\n");
+ fprintf(fp, "ceq\n"); // Compare result of first compare equal with 0 to get compare not equal.
+ }
break;
default:
mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -5081,6 +5653,14 @@ S32 LLScriptNotEquals::getSize()
return 0;
}
+static void print_cil_lte(LLFILE* fp)
+{
+ // NOTE: LSL pushes operands backwards, so <= becomes >=
+ fprintf(fp, "clt\n");
+ fprintf(fp, "ldc.i4.0\n");
+ fprintf(fp, "ceq\n");
+}
+
void LLScriptLessEquals::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
{
if (gErrorToText.getErrors())
@@ -5122,11 +5702,11 @@ void LLScriptLessEquals::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompi
}
break;
case LSCP_EMIT_CIL_ASSEMBLY:
- mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- fprintf(fp, "cgt\n"); // Test greater than.
- fprintf(fp, "ldc.i4.0\n"); // Use (b == 0) implementation of boolean not.
- fprintf(fp, "ceq\n"); // Apply boolean not to greater than. If not greater than, then less or equal.
+ print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
+ print_cil_lte(fp);
break;
default:
mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -5141,6 +5721,14 @@ S32 LLScriptLessEquals::getSize()
return 0;
}
+static void print_cil_gte(LLFILE* fp)
+{
+ // NOTE: LSL pushes operands backwards, so >= becomes <=
+ fprintf(fp, "cgt\n");
+ fprintf(fp, "ldc.i4.0\n");
+ fprintf(fp, "ceq\n");
+}
+
void LLScriptGreaterEquals::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
{
if (gErrorToText.getErrors())
@@ -5182,11 +5770,11 @@ void LLScriptGreaterEquals::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCo
}
break;
case LSCP_EMIT_CIL_ASSEMBLY:
- mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- fprintf(fp, "clt\n"); // Test less than.
- fprintf(fp, "ldc.i4.0\n"); // Use (b == 0) implementation of boolean not.
- fprintf(fp, "ceq\n"); // Apply boolean not to less than. If not less than, then greater or equal.
+ print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
+ print_cil_gte(fp);
break;
default:
mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -5201,6 +5789,12 @@ S32 LLScriptGreaterEquals::getSize()
return 0;
}
+static void print_cil_lt(LLFILE* fp)
+{
+ // NOTE: LSL pushes operands backwards, so < becomes >
+ fprintf(fp, "cgt\n");
+}
+
void LLScriptLessThan::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
{
if (gErrorToText.getErrors())
@@ -5242,9 +5836,11 @@ void LLScriptLessThan::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompile
}
break;
case LSCP_EMIT_CIL_ASSEMBLY:
- mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- fprintf(fp, "clt\n");
+ print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
+ print_cil_lt(fp);
break;
default:
mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -5259,6 +5855,12 @@ S32 LLScriptLessThan::getSize()
return 0;
}
+static void print_cil_gt(LLFILE* fp)
+{
+ // NOTE: LSL pushes operands backwards, so > becomes <
+ fprintf(fp, "clt\n");
+}
+
void LLScriptGreaterThan::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
{
if (gErrorToText.getErrors())
@@ -5300,9 +5902,11 @@ void LLScriptGreaterThan::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTComp
}
break;
case LSCP_EMIT_CIL_ASSEMBLY:
- mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- fprintf(fp, "cgt\n");
+ print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
+ print_cil_gt(fp);
break;
default:
mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -5358,10 +5962,10 @@ void LLScriptPlus::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass
}
break;
case LSCP_EMIT_CIL_ASSEMBLY:
- mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
print_cil_add(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
break;
default:
@@ -5418,10 +6022,10 @@ void LLScriptMinus::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePas
}
break;
case LSCP_EMIT_CIL_ASSEMBLY:
- mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
print_cil_sub(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
break;
default:
@@ -5478,10 +6082,10 @@ void LLScriptTimes::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePas
}
break;
case LSCP_EMIT_CIL_ASSEMBLY:
- mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
print_cil_mul(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
break;
default:
@@ -5538,10 +6142,10 @@ void LLScriptDivide::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePa
}
break;
case LSCP_EMIT_CIL_ASSEMBLY:
- mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
print_cil_div(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
break;
default:
@@ -5598,8 +6202,8 @@ void LLScriptMod::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass
}
break;
case LSCP_EMIT_CIL_ASSEMBLY:
- mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
print_cil_mod(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
break;
default:
@@ -5654,8 +6258,8 @@ void LLScriptBitAnd::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePa
}
break;
case LSCP_EMIT_CIL_ASSEMBLY:
- mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, "and\n");
break;
default:
@@ -5710,8 +6314,8 @@ void LLScriptBitOr::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePas
}
break;
case LSCP_EMIT_CIL_ASSEMBLY:
- mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, "or\n");
break;
default:
@@ -5766,8 +6370,8 @@ void LLScriptBitXor::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePa
}
break;
case LSCP_EMIT_CIL_ASSEMBLY:
- mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, "xor\n");
break;
default:
@@ -5822,9 +6426,15 @@ void LLScriptBooleanAnd::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompi
}
break;
case LSCP_EMIT_CIL_ASSEMBLY:
- mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- fprintf(fp, "and\n");
+ fprintf(fp, "ldc.i4.0\n");
+ fprintf(fp, "ceq\n");
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "ldc.i4.0\n");
+ fprintf(fp, "ceq\n");
+ fprintf(fp, "or\n");
+ fprintf(fp, "ldc.i4.0\n");
+ fprintf(fp, "ceq\n");
break;
default:
mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -5881,6 +6491,10 @@ void LLScriptBooleanOr::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompil
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, "or\n");
+ fprintf(fp, "ldc.i4.0\n");
+ fprintf(fp, "ceq\n");
+ fprintf(fp, "ldc.i4.0\n");
+ fprintf(fp, "ceq\n");
break;
default:
mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -5934,9 +6548,9 @@ void LLScriptShiftLeft::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompil
}
break;
case LSCP_EMIT_CIL_ASSEMBLY:
- mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- fprintf(fp, "shl\n");
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::ShiftLeft(int32, int32)\n");
break;
default:
mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -5991,9 +6605,9 @@ void LLScriptShiftRight::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompi
}
break;
case LSCP_EMIT_CIL_ASSEMBLY:
- mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- fprintf(fp, "shr\n");
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::ShiftRight(int32, int32)\n");
break;
default:
mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -6076,6 +6690,12 @@ void LLScriptUnaryMinus::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompi
chunk->addByte(typebyte);
}
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ {
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_neg(fp, mLeftType);
+ }
+ break;
default:
mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
break;
@@ -6219,7 +6839,7 @@ void LLScriptPreIncrement::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCom
{
fprintf(fp, "Unexpected Type\n");
}
- print_asignment(fp, mExpression);
+ print_assignment(fp, mExpression);
}
break;
case LSCP_TYPE:
@@ -6266,21 +6886,21 @@ void LLScriptPreIncrement::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCom
print_cil_load_address(fp, mExpression, entry);
if (mReturnType == LST_INTEGER)
{
- fprintf(fp, "ldc.i4.1\n");
mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "ldc.i4.1\n");
fprintf(fp, "add\n");
}
else if (mReturnType == LST_FLOATINGPOINT)
{
- fprintf(fp, "ldc.r8.1\n");
mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "ldc.r8 1\n");
fprintf(fp, "add\n");
}
else
{
fprintf(fp, "Unexpected Type\n");
}
- print_cil_asignment(fp, mExpression, entry);
+ print_cil_assignment(fp, mExpression, entry);
}
break;
default:
@@ -6327,7 +6947,7 @@ void LLScriptPreDecrement::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCom
{
fprintf(fp, "Unexpected Type\n");
}
- print_asignment(fp, mExpression);
+ print_assignment(fp, mExpression);
}
break;
case LSCP_TYPE:
@@ -6374,21 +6994,21 @@ void LLScriptPreDecrement::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCom
print_cil_load_address(fp, mExpression, entry);
if (mReturnType == LST_INTEGER)
{
- fprintf(fp, "ldc.i4.1\n");
mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "ldc.i4.1\n");
fprintf(fp, "sub\n");
}
else if (mReturnType == LST_FLOATINGPOINT)
{
- fprintf(fp, "ldc.r8.1\n");
mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "ldc.r8 1\n");
fprintf(fp, "sub\n");
}
else
{
fprintf(fp, "Unexpected Type\n");
}
- print_cil_asignment(fp, mExpression, entry);
+ print_cil_assignment(fp, mExpression, entry);
}
break;
default:
@@ -6555,7 +7175,7 @@ void LLScriptVectorInitializer::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRI
print_cil_cast(fp, mExpression3->mReturnType, LST_FLOATINGPOINT);
}
// Call named ctor, which leaves new Vector on stack, so it can be saved in to local or argument just like a primitive type.
- fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'create'(float32, float32, float32)\n");
+ fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)\n");
break;
default:
mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -6696,7 +7316,7 @@ void LLScriptQuaternionInitializer::recurse(LLFILE *fp, S32 tabs, S32 tabsize, L
}
// Call named ctor, which leaves new Vector on stack, so it can be saved in to local or argument just like a primitive type.
- fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'create'(float32, float32, float32, float32)\n");
+ fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Quaternion class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateQuaternion'(float32, float32, float32, float32)\n");
break;
default:
mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -6743,14 +7363,15 @@ void LLScriptListInitializer::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPT
mReturnType = type = LST_LIST;
break;
case LSCP_TO_STACK:
+ {
if (mExpressionList)
{
pass = LSCP_TO_STACK;
- count = 0;
- mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ U64 list_element_count = 0;
+ mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, list_element_count, chunk, heap, stacksize, entry, entrycount, NULL);
chunk->addByte(LSCRIPTOpCodes[LOPC_STACKTOL]);
- chunk->addInteger((S32)count);
- count = 0;
+ chunk->addInteger((S32)list_element_count);
+
}
else
{
@@ -6758,26 +7379,26 @@ void LLScriptListInitializer::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPT
chunk->addInteger(0);
}
break;
+ }
case LSCP_EMIT_CIL_ASSEMBLY:
-
+ {
// Push boxed elements on stack.
- count = 0;
+ U64 list_element_count = 0;
if (mExpressionList)
{
- mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, list_element_count, chunk, heap, stacksize, entry, entrycount, NULL);
}
- // Create list on stack, consuming first boxed element.
- fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LScriptLibrary]LScriptInternal::CreateList()\n");
+ // Create list on stack.
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()\n");
- // Call AddReturnList to add remaining boxed expressions.
- for(U64 i = 0; i < count; i++)
+ // Call Prepend to add remaining boxed expressions.
+ for(U64 i = 0; i < list_element_count; i++)
{
- fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LScriptLibrary]LScriptInternal::AddReturnList(object, class [mscorlib]System.Collections.ArrayList)\n");
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Prepend(object, class [mscorlib]System.Collections.ArrayList)\n");
}
- count = 0;
-
break;
+ }
default:
if (mExpressionList)
{
@@ -6824,7 +7445,7 @@ void LLScriptPostIncrement::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCo
{
fprintf(fp, "Unexpected Type\n");
}
- print_asignment(fp, mExpression);
+ print_assignment(fp, mExpression);
fprintf(fp, "%s\n", LSCRIPTTypePop[mReturnType]);
}
break;
@@ -6893,24 +7514,34 @@ void LLScriptPostIncrement::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCo
break;
case LSCP_EMIT_CIL_ASSEMBLY:
{
+ // Push original value on to stack.
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+
+ // Load address if needed for store.
print_cil_load_address(fp, mExpression, entry);
+
+ // Load value again.
+ // TODO: Work out if sideeffects can result in 2 evaluations of expression giving different values.
+ // Original LSL2 uses this method, so any bugs due to side effects will probably be identical ;-)
mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- fprintf(fp,"dup\n"); // Copy expression result to use as increment operand.
if (mReturnType == LST_INTEGER)
{
fprintf(fp, "ldc.i4.1\n");
}
else if (mReturnType == LST_FLOATINGPOINT)
{
- fprintf(fp, "ldc.r8.1\n");
+ fprintf(fp, "ldc.r8 1\n");
}
else
{
fprintf(fp, "Unexpected Type\n");
}
fprintf(fp, "add\n");
- print_cil_asignment(fp, mExpression, entry);
- fprintf(fp, "pop\n"); // Pop assignment result to leave original expression result on stack. TODO: Optimise away redundant pop/dup pairs.
+ print_cil_assignment(fp, mExpression, entry);
+
+ // Pop assignment result to leave original expression result on stack.
+ // TODO: Optimise away redundant pop/dup pairs.
+ fprintf(fp, "pop\n");
}
break;
default:
@@ -6956,7 +7587,7 @@ void LLScriptPostDecrement::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCo
{
fprintf(fp, "Unexpected Type\n");
}
- print_asignment(fp, mExpression);
+ print_assignment(fp, mExpression);
fprintf(fp, "%s\n", LSCRIPTTypePop[mReturnType]);
}
break;
@@ -7025,24 +7656,34 @@ void LLScriptPostDecrement::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCo
break;
case LSCP_EMIT_CIL_ASSEMBLY:
{
+ // Push original value on to stack.
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+
+ // Load address if needed for store.
print_cil_load_address(fp, mExpression, entry);
+
+ // Load value again.
+ // TODO: Work out if sideeffects can result in 2 evaluations of expression giving different values.
+ // Original LSL2 uses this method, so any bugs due to side effects will probably be identical ;-)
mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- fprintf(fp,"dup\n"); // Copy expression result to use as decrement operand.
if (mReturnType == LST_INTEGER)
{
fprintf(fp, "ldc.i4.1\n");
}
else if (mReturnType == LST_FLOATINGPOINT)
{
- fprintf(fp, "ldc.r8.1\n");
+ fprintf(fp, "ldc.r8 1\n");
}
else
{
fprintf(fp, "Unexpected Type\n");
}
fprintf(fp, "sub\n");
- print_cil_asignment(fp, mExpression, entry);
- fprintf(fp, "pop\n"); // Pop assignment result to leave original expression result on stack. TODO: Optimise away redundant pop/dup pairs.
+ print_cil_assignment(fp, mExpression, entry);
+
+ // Pop assignment result to leave original expression result on stack.
+ // TODO: Optimise away redundant pop/dup pairs.
+ fprintf(fp, "pop\n");
}
break;
default:
@@ -7058,16 +7699,19 @@ S32 LLScriptPostDecrement::getSize()
}
// Generate arg list.
-void print_cil_arg_list(LLFILE *fp, LLScriptFuncExpressionList* exp_list)
+static void print_cil_arg_list(LLFILE *fp, LLScriptArgString& args)
{
- // Print first argument.
- print_cil_type(fp, exp_list->mFirstp->mReturnType);
-
- // Recursively print next arguments.
- if(exp_list->mSecondp != NULL)
+ int i = 0;
+ bool finished = (i >= args.getNumber());
+ while(! finished)
{
- fprintf(fp, ", ");
- print_cil_arg_list(fp, (LLScriptFuncExpressionList*) exp_list->mSecondp);
+ print_cil_type(fp, args.getType(i));
+ ++i;
+ finished = (i >= args.getNumber());
+ if(! finished)
+ {
+ fprintf(fp, ", ");
+ }
}
}
@@ -7146,7 +7790,7 @@ void LLScriptFunctionCall::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCom
gErrorToText.writeError(fp, this, LSERROR_FUNCTION_TYPE_ERROR);
}
}
- else if (argcount != strlen(mIdentifier->mScopeEntry->mFunctionArgs.mString)) /*Flawfinder: ignore*/
+ else if (argcount != strlen(mIdentifier->mScopeEntry->mFunctionArgs.mString))
{
gErrorToText.writeError(fp, this, LSERROR_FUNCTION_TYPE_ERROR);
}
@@ -7217,13 +7861,15 @@ void LLScriptFunctionCall::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCom
// Load args on to stack.
if (mExpressionList)
{
- mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry /* Needed for is_parameter calls */, 0, NULL);
+ //mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry /* Needed for is_parameter calls */, 0, NULL);
+ llassert(LET_FUNC_EXPRESSION_LIST == mExpressionList->mType);
+ print_cil_func_expression_list((LLScriptFuncExpressionList*) mExpressionList, fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry /* Caller entry needed for is_parameter calls */, 0, NULL, mIdentifier->mScopeEntry /* Callee entry needed for argument casting */);
}
// Make call.
if (! library_call)
{
- fprintf(fp, "callvirt instance ");
+ fprintf(fp, "call instance ");
}
else
{
@@ -7233,16 +7879,18 @@ void LLScriptFunctionCall::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCom
fprintf(fp, " class ");
if (library_call)
{
- fprintf(fp, "[LScriptLibrary]LScriptLibrary");
+ fprintf(fp, "[LslLibrary]LindenLab.SecondLife.Library::'");
}
else
{
- fprintf(fp, "LSL");
+ // Prefix function name with g to distinguish from
+ // event handlers.
+ fprintf(fp, gScriptp->getClassName());
+ fprintf(fp, "::'g");
}
- fprintf(fp, "::");
- mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- fprintf(fp, "(");
- if (mExpressionList) {print_cil_arg_list(fp, (LLScriptFuncExpressionList*) mExpressionList);}
+ fprintf(fp, mIdentifier->mName);
+ fprintf(fp, "'(");
+ print_cil_arg_list(fp, mIdentifier->mScopeEntry->mFunctionArgs);
fprintf(fp, ")\n");
}
break;
@@ -7287,6 +7935,11 @@ void LLScriptPrint::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePas
chunk->addByte(LSCRIPTOpCodes[LOPC_PRINT]);
chunk->addByte(LSCRIPTTypeByte[mLeftType]);
break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_cast(fp, mLeftType, LST_STRING);
+ fprintf(fp, "call void class [LslLibrary]LindenLab.SecondLife.Library::Print(string)");
+ break;
default:
mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
break;
@@ -7404,8 +8057,19 @@ void LLScriptStatementSequence::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRI
mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
if (prunearg)
{
+ // babbage: only warn on first dead code block found.
+ if(ptype != LSPRUNE_DEAD_CODE)
+ {
+ gErrorToText.writeWarning(fp, this, LSWARN_DEAD_CODE);
+ }
+
+ // babbage: set prune type to LSPRUNE_DEAD_CODE to mask other
+ // prune errors.
ptype = LSPRUNE_DEAD_CODE;
- gErrorToText.writeWarning(fp, this, LSWARN_DEAD_CODE);
+
+ // babbage: reset prunearg, to track whether return needed at
+ // end of dead code path as CIL always needs a return/throw.
+ prunearg = FALSE;
}
mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
break;
@@ -7444,10 +8108,7 @@ void LLScriptNOOP::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass
fprintf(fp, ";\n");
break;
case LSCP_PRUNE:
- if (ptype == LSPRUNE_DEAD_CODE)
- prunearg = TRUE;
- else
- prunearg = FALSE;
+ prunearg = FALSE;
break;
default:
break;
@@ -7462,7 +8123,7 @@ void add_exit_pops(LLScriptByteCodeChunk *chunk, LLScriptScopeEntry *entry)
if (entry->mLocals.mString)
{
- number = (S32)strlen(entry->mLocals.mString); /*Flawfinder: ignore*/
+ number = (S32)strlen(entry->mLocals.mString);
for (i = number - 1; i >= 0; i--)
{
switch(entry->mLocals.getType(i))
@@ -7495,7 +8156,7 @@ void add_exit_pops(LLScriptByteCodeChunk *chunk, LLScriptScopeEntry *entry)
if (entry->mFunctionArgs.mString)
{
- number = (S32)strlen(entry->mFunctionArgs.mString); /*Flawfinder: ignore*/
+ number = (S32)strlen(entry->mFunctionArgs.mString);
for (i = number - 1; i >= 0; i--)
{
switch(entry->mFunctionArgs.getType(i))
@@ -7534,7 +8195,7 @@ void print_exit_pops(LLFILE *fp, LLScriptScopeEntry *entry)
if (entry->mLocals.mString)
{
- number = (S32)strlen(entry->mLocals.mString); /*Flawfinder: ignore*/
+ number = (S32)strlen(entry->mLocals.mString);
for (i = number - 1; i >= 0; i--)
{
fprintf(fp, "%s", LSCRIPTTypePop[entry->mLocals.getType(i)]);
@@ -7543,7 +8204,7 @@ void print_exit_pops(LLFILE *fp, LLScriptScopeEntry *entry)
if (entry->mFunctionArgs.mString)
{
- number = (S32)strlen(entry->mFunctionArgs.mString); /*Flawfinder: ignore*/
+ number = (S32)strlen(entry->mFunctionArgs.mString);
for (i = number - 1; i >= 0; i--)
{
fprintf(fp, "%s", LSCRIPTTypePop[entry->mFunctionArgs.getType(i)]);
@@ -7583,10 +8244,7 @@ void LLScriptStateChange::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTComp
{
gErrorToText.writeError(fp, this, LSERROR_STATE_CHANGE_IN_GLOBAL);
}
- if (ptype == LSPRUNE_DEAD_CODE)
- prunearg = TRUE;
- else
- prunearg = FALSE;
+ prunearg = FALSE;
break;
case LSCP_SCOPE_PASS2:
{
@@ -7610,10 +8268,10 @@ void LLScriptStateChange::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTComp
}
break;
case LSCP_EMIT_CIL_ASSEMBLY:
- fprintf(fp, "ldstr \"");
- mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- fprintf(fp, "\"\n");
- fprintf(fp, "call void class [LScriptLibrary]LScriptInternal::change_state(string)\n");
+ fprintf(fp, "ldarg.0\n");
+ fprintf(fp, "ldstr \"%s\"\n", mIdentifier->mName);
+ fprintf(fp, "call instance void class [LslUserScript]LindenLab.SecondLife.LslUserScript::ChangeState(string)\n");
+ fprintf(fp, "ret\n");
break;
default:
mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -7647,10 +8305,7 @@ void LLScriptJump::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass
fprintf(fp, "\n");
break;
case LSCP_PRUNE:
- if (ptype == LSPRUNE_DEAD_CODE)
- prunearg = TRUE;
- else
- prunearg = FALSE;
+ prunearg = FALSE;
break;
case LSCP_SCOPE_PASS2:
{
@@ -7820,6 +8475,10 @@ void LLScriptReturn::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePa
mType = basetype;
}
}
+ else if (basetype != LST_NULL)
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
break;
case LSCP_EMIT_BYTE_CODE:
if (mExpression)
@@ -7863,6 +8522,7 @@ void LLScriptReturn::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePa
if (mExpression)
{
mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_cast(fp, mExpression->mReturnType, mType);
}
fprintf(fp, "ret\n");
break;
@@ -7902,10 +8562,7 @@ void LLScriptExpressionStatement::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSC
}
break;
case LSCP_PRUNE:
- if (ptype == LSPRUNE_DEAD_CODE)
- prunearg = TRUE;
- else
- prunearg = FALSE;
+ prunearg = FALSE;
break;
case LSCP_EMIT_BYTE_CODE:
mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -7951,6 +8608,58 @@ S32 LLScriptIf::getSize()
return 0;
}
+static void print_cil_if_test(LLFILE* fp, LSCRIPTType type)
+{
+ switch(type)
+ {
+ case LST_INTEGER:
+ break;
+ case LST_FLOATINGPOINT:
+ fprintf(fp, "ldc.r8 0\n");
+ fprintf(fp, "ceq\n");
+ fprintf(fp, "ldc.i4.0\n");
+ fprintf(fp, "ceq\n");
+ break;
+ case LST_VECTOR:
+ fprintf(fp, "ldc.r8 0\n");
+ fprintf(fp, "ldc.r8 0\n");
+ fprintf(fp, "ldc.r8 0\n");
+ fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)\n");
+ fprintf(fp, "call bool [LslUserScript]LindenLab.SecondLife.LslUserScript::'Equals'(class [ScriptTypes]LindenLab.SecondLife.Vector, class [ScriptTypes]LindenLab.SecondLife.Vector)\n");
+ fprintf(fp, "ldc.i4.0\n");
+ fprintf(fp, "ceq\n");
+ break;
+ case LST_QUATERNION:
+ fprintf(fp, "ldc.r8 0\n");
+ fprintf(fp, "ldc.r8 0\n");
+ fprintf(fp, "ldc.r8 0\n");
+ fprintf(fp, "ldc.r8 1\n");
+ fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Quaternion class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateQuaternion'(float32, float32, float32, float32)\n");
+ fprintf(fp, "call bool [LslUserScript]LindenLab.SecondLife.LslUserScript::'Equals'(class [ScriptTypes]LindenLab.SecondLife.Quaternion, class [ScriptTypes]LindenLab.SecondLife.Quaternion)\n");
+ fprintf(fp, "ldc.i4.0\n");
+ fprintf(fp, "ceq\n");
+ break;
+ case LST_KEY:
+ fprintf(fp, "call bool [LslUserScript]LindenLab.SecondLife.LslUserScript::'IsNonNullUuid'(valuetype [ScriptTypes]LindenLab.SecondLife.Key)\n");
+ break;
+ case LST_STRING:
+ fprintf(fp, "ldstr \"\"\n");
+ fprintf(fp, "call bool string::op_Equality(string, string)\n");
+ fprintf(fp, "ldc.i4.0\n");
+ fprintf(fp, "ceq\n");
+ break;
+ case LST_LIST:
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()\n");
+ fprintf(fp, "call bool [LslUserScript]LindenLab.SecondLife.LslUserScript::Equals(class [mscorlib]System.Collections.ArrayList, class [mscorlib]System.Collections.ArrayList)\n");
+ fprintf(fp, "ldc.i4.0\n");
+ fprintf(fp, "ceq\n");
+ break;
+ default:
+ break;
+ }
+
+}
+
void LLScriptIf::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
{
if (gErrorToText.getErrors())
@@ -7976,10 +8685,7 @@ void LLScriptIf::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass p
}
break;
case LSCP_PRUNE:
- if (ptype == LSPRUNE_DEAD_CODE)
- prunearg = TRUE;
- else
- prunearg = FALSE;
+ prunearg = FALSE;
break;
case LSCP_TYPE:
mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -8004,6 +8710,7 @@ void LLScriptIf::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass p
{
S32 tjump = gTempJumpCount++;
mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_if_test(fp, mExpression->mReturnType);
fprintf(fp, "brfalse LabelTempJump%d\n", tjump);
mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, "LabelTempJump%d:\n", tjump);
@@ -8093,6 +8800,7 @@ void LLScriptIfElse::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePa
S32 tjump1 = gTempJumpCount++;
S32 tjump2 = gTempJumpCount++;
mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_if_test(fp, mExpression->mReturnType);
fprintf(fp, "brfalse LabelTempJump%d\n", tjump1);
mStatement1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, "br LabelTempJump%d\n", tjump2);
@@ -8155,10 +8863,7 @@ void LLScriptFor::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass
}
break;
case LSCP_PRUNE:
- if (ptype == LSPRUNE_DEAD_CODE)
- prunearg = TRUE;
- else
- prunearg = FALSE;
+ prunearg = FALSE;
break;
case LSCP_TYPE:
if(mSequence)
@@ -8203,6 +8908,7 @@ void LLScriptFor::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass
mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, "LabelTempJump%d:\n", tjump1);
mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_if_test(fp, mExpression->mReturnType);
fprintf(fp, "brfalse LabelTempJump%d\n", tjump2);
if(mStatement)
mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -8257,10 +8963,7 @@ void LLScriptDoWhile::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompileP
}
break;
case LSCP_PRUNE:
- if (ptype == LSPRUNE_DEAD_CODE)
- prunearg = TRUE;
- else
- prunearg = FALSE;
+ prunearg = FALSE;
break;
case LSCP_TYPE:
mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -8287,6 +8990,7 @@ void LLScriptDoWhile::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompileP
fprintf(fp, "LabelTempJump%d:\n", tjump1);
mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_if_test(fp, mExpression->mReturnType);
fprintf(fp, "brtrue LabelTempJump%d\n", tjump1);
}
break;
@@ -8331,10 +9035,7 @@ void LLScriptWhile::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePas
}
break;
case LSCP_PRUNE:
- if (ptype == LSPRUNE_DEAD_CODE)
- prunearg = TRUE;
- else
- prunearg = FALSE;
+ prunearg = FALSE;
break;
case LSCP_TYPE:
mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -8367,6 +9068,7 @@ void LLScriptWhile::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePas
S32 tjump2 = gTempJumpCount++;
fprintf(fp, "LabelTempJump%d:\n", tjump1);
mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_if_test(fp, mExpression->mReturnType);
fprintf(fp, "brfalse LabelTempJump%d\n", tjump2);
mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, "br LabelTempJump%d\n", tjump1);
@@ -8429,10 +9131,7 @@ void LLScriptDeclaration::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTComp
}
break;
case LSCP_PRUNE:
- if (ptype == LSPRUNE_DEAD_CODE)
- prunearg = TRUE;
- else
- prunearg = FALSE;
+ prunearg = FALSE;
break;
case LSCP_SCOPE_PASS1:
// Check to see if a declaration is valid here.
@@ -8604,24 +9303,13 @@ void LLScriptDeclaration::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTComp
if (mExpression)
{
mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
- {
- if(is_parameter(mIdentifier, entry))
- {
- // Parameter, store by name.
- fprintf(fp, "starg.s %s\n", mIdentifier->mScopeEntry->mIdentifier);
- }
- else
- {
- // Local, store by index.
- fprintf(fp, "stloc.s %d\n", mIdentifier->mScopeEntry->mCount);
- }
- }
- else if (mIdentifier->mScopeEntry->mIDType == LIT_GLOBAL)
- {
- gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
- }
+ print_cil_cast(fp, mExpression->mReturnType, mIdentifier->mScopeEntry->mType);
+ }
+ else
+ {
+ print_cil_init_variable(fp, mIdentifier->mScopeEntry->mType);
}
+ fprintf(fp, "stloc.s %d\n", mIdentifier->mScopeEntry->mCount);
break;
default:
if (mExpression)
@@ -8751,7 +9439,7 @@ S32 LLScriptEventHandler::getSize()
U64 gCurrentHandler = 0;
-void print_cil_local_init(LLFILE* fp, LLScriptScopeEntry* scopeEntry)
+static void print_cil_local_init(LLFILE* fp, LLScriptScopeEntry* scopeEntry)
{
if(scopeEntry->mLocals.getNumber() > 0)
{
@@ -8956,6 +9644,10 @@ void LLScriptEventHandler::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCom
// first determine resource counts for globals
count = 0;
mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+
+ // Store offset of first local as with global functions, so locals and arguments can be distinguished with is_parameter when compiling to CIL.
+ mScopeEntry->mOffset = (S32) count;
+
if (mStatement)
{
entrycount = 0;
@@ -9024,8 +9716,11 @@ void LLScriptEventHandler::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCom
// Method signature prefix.
fprintf(fp, ".method public hidebysig instance default void ");
- // Mangle event handler name by prefixing it with state name. Allows state changing by finding handlers prefixed with new state name.
- fprintf(fp, entry->mIdentifier); /*Flawfinder: ignore*/
+ // Mangle event handler name by prefixing it with state name.
+ // Allows state changing by finding handlers prefixed with new
+ // state name. Prefix disambiguates functions and event handlers.
+ fprintf(fp, "e");
+ fprintf(fp, entry->mIdentifier);
// Handler name and arguments.
mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -9047,7 +9742,11 @@ void LLScriptEventHandler::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCom
}
// Function footer.
- fprintf(fp, "\nret\n"); // TODO: Check whether return needed?
+ if (mbNeedTrailingReturn)
+ {
+ // TODO: throw exception?
+ fprintf(fp, "ret\n");
+ }
fprintf(fp, "}\n");
break;
@@ -9161,7 +9860,7 @@ void LLScriptFunctionDec::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTComp
chunk->addBytes(&typereturn, 1);
// name
#ifdef LSL_INCLUDE_DEBUG_INFO
- chunk->addBytes(mIdentifier->mName, strlen(mIdentifier->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(mIdentifier->mName, strlen(mIdentifier->mName) + 1);
#else
chunk->addBytes(1);
#endif
@@ -9176,6 +9875,10 @@ void LLScriptFunctionDec::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTComp
mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, " ");
mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if(NULL != mNextp)
+ {
+ fprintf(fp, ",");
+ }
break;
default:
mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -9398,7 +10101,7 @@ void LLScriptGlobalFunctions::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPT
// null terminated function name
#ifdef LSL_INCLUDE_DEBUG_INFO
- chunk->addBytes(mIdentifier->mName, strlen(mIdentifier->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(mIdentifier->mName, strlen(mIdentifier->mName) + 1);
#else
chunk->addBytes(1);
#endif
@@ -9444,11 +10147,13 @@ void LLScriptGlobalFunctions::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPT
break;
case LSCP_EMIT_CIL_ASSEMBLY:
{
- // Function header.
+ // Function header. Prefix function name with g to distinguish
+ // from event handlers.
fprintf(fp, ".method public hidebysig instance default ");
print_cil_type(fp, mType ? mType->mType : LST_NULL);
- fprintf(fp, " ");
- mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " 'g");
+ fprintf(fp, mIdentifier->mName);
+ fprintf(fp, "'");
if (mParameters)
{
fprintf(fp, "( ");
@@ -9473,6 +10178,7 @@ void LLScriptGlobalFunctions::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPT
// Function footer.
if (mbNeedTrailingReturn)
{
+ // TODO: throw exception?
fprintf(fp, "ret\n");
}
fprintf(fp, "}\n");
@@ -9587,10 +10293,12 @@ void LLScriptState::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePas
{
mIdentifier->mScopeEntry = scope->addEntry(mIdentifier->mName, LIT_STATE, LST_NULL);
}
+ mStateScope = new LLScriptScope(gScopeStringTable);
+ mStateScope->addParentScope(scope);
// now do the events
if (mEvent)
{
- mEvent->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mEvent->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mStateScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
}
break;
case LSCP_SCOPE_PASS2:
@@ -9649,7 +10357,7 @@ void LLScriptState::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePas
// null terminated state name
#ifdef LSL_INCLUDE_DEBUG_INFO
- chunk->addBytes(mIdentifier->mName, strlen(mIdentifier->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(mIdentifier->mName, strlen(mIdentifier->mName) + 1);
#else
chunk->addBytes(1);
#endif
@@ -9693,6 +10401,38 @@ void LLScriptState::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePas
gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
}
+// Converts string to a valid CIL class name and stores the result
+// in the supplied buffer, which should be at least 32 chars long.
+// If the string starts with a UUID, all characters in the UUID are included
+// in the generated name.
+void to_class_name(char* buffer, const char* string)
+{
+ strcpy(buffer, "LSL-");
+ strcat(buffer, string);
+ char* current_char = buffer;
+ while((*current_char) != 0)
+ {
+ if(isalnum(*current_char))
+ {
+ ++current_char;
+ }
+ else if((*current_char) == '-')
+ {
+ (*current_char) = '_';
+ ++current_char;
+ }
+ else
+ {
+ (*current_char) = 0;
+ }
+ }
+}
+
+void LLScriptScript::setClassName(const char* class_name)
+{
+ to_class_name(mClassName, class_name);
+}
+
S32 LLScriptScript::getSize()
{
return 0;
@@ -9704,6 +10444,7 @@ LLScriptScript::LLScriptScript(LLScritpGlobalStorage *globals,
mStates(states), mGlobalScope(NULL), mGlobals(NULL), mGlobalFunctions(NULL), mGodLike(FALSE)
{
const char DEFAULT_BYTECODE_FILENAME[] = "lscript.lso";
+
mBytecodeDest = DEFAULT_BYTECODE_FILENAME;
LLScriptGlobalVariable *tvar;
LLScriptGlobalFunctions *tfunc;
@@ -9753,13 +10494,11 @@ void LLScriptScript::setBytecodeDest(const char* dst_filename)
mBytecodeDest = ll_safe_string(dst_filename);
}
-void print_cil_globals(LLFILE* fp, LLScriptGlobalVariable* global)
+static void print_cil_globals(LLFILE* fp, LLScriptGlobalVariable* global)
{
- fprintf(fp, ".field private ");
+ fprintf(fp, ".field public ");
print_cil_type(fp, global->mType->mType);
- fprintf(fp, " ");
- fprintf(fp, global->mIdentifier->mName); /*Flawfinder: ignore*/
- fprintf(fp, "\n");
+ fprintf(fp, " '%s'\n", global->mIdentifier->mName);
if(NULL != global->mNextp)
{
print_cil_globals(fp, global->mNextp);
@@ -9946,72 +10685,66 @@ void LLScriptScript::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePa
}
break;
case LSCP_EMIT_CIL_ASSEMBLY:
+ {
+ LLFILE *bcfp = LLFile::fopen(mBytecodeDest, "wb");
- // Output dependencies.
- fprintf(fp, ".assembly extern mscorlib {.ver 1:0:5000:0}\n");
- fprintf(fp, ".assembly extern LScriptLibrary {.ver 0:0:0:0}\n");
+ // Output dependencies.
+ fprintf(bcfp, ".assembly extern mscorlib {.ver 1:0:5000:0}\n");
+ fprintf(bcfp, ".assembly extern LslLibrary {.ver 0:1:0:0}\n");
+ fprintf(bcfp, ".assembly extern LslUserScript {.ver 0:1:0:0}\n");
+ fprintf(bcfp, ".assembly extern ScriptTypes {.ver 0:1:0:0}\n");
- // Output assembly name.
- fprintf(fp, ".assembly 'lsl' {.ver 0:0:0:0}\n");
+ // Output assembly name.
+ fprintf(bcfp, ".assembly '%s' {.ver 0:0:0:0}\n", gScriptp->getClassName());
- // Output class header.
- fprintf(fp, ".class public auto ansi beforefieldinit LSL extends [mscorlib]System.Object\n");
- fprintf(fp, "{\n");
+ // Output class header.
+ fprintf(bcfp, ".class public auto ansi serializable beforefieldinit %s extends [LslUserScript]LindenLab.SecondLife.LslUserScript\n", gScriptp->getClassName());
+ fprintf(bcfp, "{\n");
- // Output globals as members.
- if(NULL != mGlobals)
- {
- print_cil_globals(fp, mGlobals);
- }
-
- // Output "runtime". Only needed to allow stand alone execution. Not needed when compiling to DLL and using embedded runtime.
- fprintf(fp, ".method public static hidebysig default void Main () cil managed\n");
- fprintf(fp, "{\n");
- fprintf(fp, ".entrypoint\n");
- fprintf(fp, ".maxstack 2\n");
- fprintf(fp, ".locals init (class LSL V_0)\n");
- fprintf(fp, "newobj instance void class LSL::.ctor()\n");
- fprintf(fp, "stloc.0\n");
- fprintf(fp, "ldloc.0\n");
- fprintf(fp, "callvirt instance void class LSL::defaultstate_entry()\n");
- fprintf(fp, "ret\n");
- fprintf(fp, "}\n");
+ // Output globals as members.
+ if(NULL != mGlobals)
+ {
+ print_cil_globals(bcfp, mGlobals);
+ }
- // Output ctor header.
- fprintf(fp, ".method public hidebysig specialname rtspecialname instance default void .ctor () cil managed\n");
- fprintf(fp, "{\n");
- fprintf(fp, ".maxstack 500\n");
+ // Output ctor header.
+ fprintf(bcfp, ".method public hidebysig specialname rtspecialname instance default void .ctor () cil managed\n");
+ fprintf(bcfp, "{\n");
+ fprintf(bcfp, ".maxstack 500\n");
- // Initialise globals as members in ctor.
- if (mGlobals)
- {
- fdotabs(fp, tabs, tabsize);
- mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- fprintf(fp, "\n");
- }
+ // Initialise globals as members in ctor.
+ if (mGlobals)
+ {
+ fdotabs(bcfp, tabs, tabsize);
+ mGlobals->recurse(bcfp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(bcfp, "\n");
+ }
- // Output ctor footer.
- fprintf(fp, "ldarg.0\n");
- fprintf(fp, "call instance void valuetype [mscorlib]System.Object::.ctor()\n");
- fprintf(fp, "ret\n");
- fprintf(fp, "}\n");
+ // Output ctor footer.
+ fprintf(bcfp, "ldarg.0\n");
+ fprintf(bcfp, "call instance void [LslUserScript]LindenLab.SecondLife.LslUserScript::.ctor()\n");
+ fprintf(bcfp, "ret\n");
+ fprintf(bcfp, "}\n");
- // Output functions as methods.
- if (mGlobalFunctions)
- {
- fdotabs(fp, tabs, tabsize);
- mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- fprintf(fp, "\n");
- }
+ // Output functions as methods.
+ if (mGlobalFunctions)
+ {
+ fdotabs(bcfp, tabs, tabsize);
+ mGlobalFunctions->recurse(bcfp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(bcfp, "\n");
+ }
- // Output states as name mangled methods.
- fdotabs(fp, tabs, tabsize);
- mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
- fprintf(fp, "\n");
+ // Output states as name mangled methods.
+ fdotabs(bcfp, tabs, tabsize);
+ mStates->recurse(bcfp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(bcfp, "\n");
- // Output class footer.
- fprintf(fp, "}\n");
+ // Output class footer.
+ fprintf(bcfp, "}\n");
+ // Close file.
+ fclose(bcfp);
+ }
break;
default:
if (mGlobals)
diff --git a/indra/lscript/lscript_compile/lscript_tree.h b/indra/lscript/lscript_compile/lscript_tree.h
index 4c25c097d8..57228dd24c 100644
--- a/indra/lscript/lscript_compile/lscript_tree.h
+++ b/indra/lscript/lscript_compile/lscript_tree.h
@@ -2197,11 +2197,11 @@ public:
void recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
S32 getSize();
- LSCRIPTStateType mType;
- LLScriptIdentifier *mIdentifier;
- LLScriptEventHandler *mEvent;
- LLScriptState *mNextp;
-
+ LSCRIPTStateType mType;
+ LLScriptIdentifier *mIdentifier;
+ LLScriptEventHandler *mEvent;
+ LLScriptState *mNextp;
+ LLScriptScope *mStateScope;
};
class LLScritpGlobalStorage : public LLScriptFilePosition
@@ -2262,6 +2262,9 @@ public:
void setBytecodeDest(const char* dst_filename);
+ void setClassName(const char* class_name);
+ const char* getClassName() {return mClassName;}
+
LLScriptState *mStates;
LLScriptScope *mGlobalScope;
LLScriptGlobalVariable *mGlobals;
@@ -2270,6 +2273,7 @@ public:
private:
std::string mBytecodeDest;
+ char mClassName[MAX_STRING];
};
class LLScriptAllocationManager
diff --git a/indra/lscript/lscript_compile/lscript_typecheck.cpp b/indra/lscript/lscript_compile/lscript_typecheck.cpp
index 1030e8c70d..bfa5a66c7b 100644
--- a/indra/lscript/lscript_compile/lscript_typecheck.cpp
+++ b/indra/lscript/lscript_compile/lscript_typecheck.cpp
@@ -66,7 +66,13 @@ LSCRIPTType implicit_casts(LSCRIPTType left_side, LSCRIPTType right_side)
{
// shouldn't be doing an operation on void types
case LST_NULL:
- return LST_NULL;
+ switch(right_side)
+ {
+ case LST_NULL:
+ return LST_NULL;
+ default:
+ return LST_UNDEFINED;
+ }
// shouldn't be doing an operation on undefined types
case LST_UNDEFINED:
return LST_UNDEFINED;
diff --git a/indra/lscript/lscript_execute.h b/indra/lscript/lscript_execute.h
index dd1aa97e71..f46256eb5e 100644
--- a/indra/lscript/lscript_execute.h
+++ b/indra/lscript/lscript_execute.h
@@ -367,20 +367,158 @@ public:
class LLScriptExecute
{
public:
- LLScriptExecute(LLFILE *fp);
- LLScriptExecute(U8 *buffer);
- ~LLScriptExecute();
+ LLScriptExecute();
+ virtual ~LLScriptExecute() {;}
+
+ virtual S32 getVersion() = 0;
+ virtual void deleteAllEvents() = 0;
+ virtual void addEvent(LLScriptDataCollection* event) = 0;
+ virtual U32 getEventCount() = 0;
+ virtual void removeEventType(LSCRIPTStateEventType event_type) = 0;
+ virtual S32 getFaults() = 0;
+ virtual void setFault(LSCRIPTRunTimeFaults fault) = 0;
+ virtual U32 getFreeMemory() = 0;
+ virtual S32 getParameter() = 0;
+ virtual void setParameter(S32 value) = 0;
+ virtual F32 getSleep() const = 0;
+ virtual void setSleep(F32 value) = 0;
+ virtual F32 getEnergy() const = 0;
+ virtual void setEnergy(F32 value) = 0;
+ virtual U64 getCurrentEvents(S32 version) = 0;
+ virtual void setCurrentEvents(U64 value, S32 version) = 0;
+ virtual U64 getEventHandlers(S32 version) = 0;
+ virtual void setEventHandlers(U64 value, S32 version) = 0;
+ virtual U64 getCurrentHandler(S32 version) = 0;
+ virtual void setCurrentHandler(U64 value, S32 version) = 0;
+ virtual BOOL isFinished() const = 0;
+ virtual BOOL isStateChangePending() const = 0;
+ virtual S32 writeState(U8 **dest, U32 header_size, U32 footer_size) = 0; // Allocate memory for header, state and footer return size of state.
+ virtual U32 getEventsSavedSize() = 0; // Returns 0 if events are written with state.
+ virtual S32 writeEvents(U8 *dest) = 0; // Must write and return exactly the number of bytes returned by getEventsSavedSize.
+ virtual void readEvents(U8* src, S32& offset) = 0;
+ virtual S32 readState(U8 *src) = 0; // Returns number of bytes read.
+ virtual void reset();
+ virtual const U8* getBytecode() const = 0;
+ virtual U32 getBytecodeSize() const = 0;
+ virtual bool isMono() const = 0;
+ virtual void error() {;} // Processing that must be performed when error flag is set and so run is not called.
+
+ // Run current event handler for a maximum of time_slice seconds.
+ // Updates current handler and current events registers.
+ virtual void resumeEventHandler(BOOL b_print, const LLUUID &id, F32 time_slice) = 0;
+
+ // Run handler for event for a maximum of time_slice seconds.
+ // Updates current handler and current events registers.
+ virtual void callEventHandler(LSCRIPTStateEventType event, S32 major_version, const LLUUID &id, F32 time_slice) = 0;;
+
+ // Run handler for next queued event for maximum of time_slice seconds.
+ // Updates current handler and current events registers.
+ // Removes processed event from queue.
+ virtual void callNextQueuedEventHandler(U64 event_register, S32 major_version, const LLUUID &id, F32 time_slice) = 0;
+
+ // Run handler for event for a maximum of time_slice seconds.
+ // Updates current handler and current events registers.
+ // Removes processed event from queue.
+ virtual void callQueuedEventHandler(LSCRIPTStateEventType event, S32 major_version, const LLUUID &id, F32 time_slice) = 0;
+
+ // Switch to next state.
+ // Returns new set of handled events.
+ virtual U64 nextState() = 0;
+
+ // Returns time taken.
+ virtual F32 runQuanta(BOOL b_print, const LLUUID &id,
+ const char **errorstr,
+ BOOL &state_transition, F32 quanta,
+ U32& events_processed, LLTimer& timer);
+
+ // Run smallest possible amount of code: an instruction for LSL2, a segment
+ // between save tests for Mono
+ void runInstructions(BOOL b_print, const LLUUID &id,
+ const char **errorstr,
+ BOOL &state_transition, U32& events_processed,
+ F32 quanta);
+
+ bool isYieldDue() const;
+
+ void setReset(BOOL b) {mReset = b;}
+ BOOL getReset() const { return mReset; }
+
+private:
+
+ BOOL mReset;
+};
+
+class LLScriptExecuteLSL2 : public LLScriptExecute
+{
+public:
+ LLScriptExecuteLSL2(LLFILE *fp);
+ LLScriptExecuteLSL2(const U8* bytecode, U32 bytecode_size);
+ virtual ~LLScriptExecuteLSL2();
+
+ virtual S32 getVersion() {return get_register(mBuffer, LREG_VN);}
+ virtual void deleteAllEvents() {mEventData.mEventDataList.deleteAllData();}
+ virtual void addEvent(LLScriptDataCollection* event);
+ virtual U32 getEventCount() {return mEventData.mEventDataList.getLength();}
+ virtual void removeEventType(LSCRIPTStateEventType event_type);
+ virtual S32 getFaults() {return get_register(mBuffer, LREG_FR);}
+ virtual void setFault(LSCRIPTRunTimeFaults fault) {set_fault(mBuffer, fault);}
+ virtual U32 getFreeMemory();
+ virtual S32 getParameter();
+ virtual void setParameter(S32 value);
+ virtual F32 getSleep() const;
+ virtual void setSleep(F32 value);
+ virtual F32 getEnergy() const;
+ virtual void setEnergy(F32 value);
+ virtual U64 getCurrentEvents(S32 version) {return get_event_register(mBuffer, LREG_CE, version);}
+ virtual void setCurrentEvents(U64 value, S32 version) {return set_event_register(mBuffer, LREG_CE, value, version);}
+ virtual U64 getEventHandlers(S32 version) {return get_event_register(mBuffer, LREG_ER, version);}
+ virtual void setEventHandlers(U64 value, S32 version) {set_event_register(mBuffer, LREG_ER, value, version);}
+ virtual U64 getCurrentHandler(S32 version);
+ virtual void setCurrentHandler(U64 value, S32 version) {return set_event_register(mBuffer, LREG_IE, value, version);}
+ virtual BOOL isFinished() const {return get_register(mBuffer, LREG_IP) == 0;}
+ virtual BOOL isStateChangePending() const {return get_register(mBuffer, LREG_CS) != get_register(mBuffer, LREG_NS);}
+ virtual S32 writeState(U8 **dest, U32 header_size, U32 footer_size); // Not including Events.
+ virtual U32 getEventsSavedSize() {return mEventData.getSavedSize();}
+ virtual S32 writeEvents(U8 *dest) {return mEventData.write2bytestream(dest);}
+ virtual void readEvents(U8* src, S32& offset) {mEventData.set(src, offset);}
+ virtual S32 writeBytecode(U8 **dest);
+ virtual S32 readState(U8 *src);
+ virtual void reset();
+ virtual const U8* getBytecode() const {return mBytecode;}
+ virtual U32 getBytecodeSize() const {return mBytecodeSize;}
+ virtual bool isMono() const {return false;}
+
+ // Run current event handler for a maximum of time_slice seconds.
+ // Updates current handler and current events registers.
+ virtual void resumeEventHandler(BOOL b_print, const LLUUID &id, F32 time_slice);
+
+ // Run handler for event for a maximum of time_slice seconds.
+ // Updates current handler and current events registers.
+ virtual void callEventHandler(LSCRIPTStateEventType event, S32 major_version, const LLUUID &id, F32 time_slice);
+
+ // Run handler for next queued event for maximum of time_slice seconds.
+ // Updates current handler and current events registers.
+ // Removes processed event from queue.
+ virtual void callNextQueuedEventHandler(U64 event_register, S32 major_version, const LLUUID &id, F32 time_slice);
+
+ // Run handler for event for a maximum of time_slice seconds.
+ // Updates current handler and current events registers.
+ // Removes processed event from queue.
+ virtual void callQueuedEventHandler(LSCRIPTStateEventType event, S32 major_version, const LLUUID &id, F32 time_slice);
+
+ // Switch to next state.
+ // Returns new set of handled events.
+ virtual U64 nextState();
void init();
- U32 run(BOOL b_print, const LLUUID &id, const char **errorstr, BOOL &state_transition);
BOOL (*mExecuteFuncs[0x100])(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
U32 mInstructionCount;
U8 *mBuffer;
LLScriptEventData mEventData;
-
- static S64 sGlobalInstructionCount;
+ U8* mBytecode; // Initial state and bytecode.
+ U32 mBytecodeSize;
private:
void recordBoundaryError( const LLUUID &id );
diff --git a/indra/lscript/lscript_execute/lscript_execute.cpp b/indra/lscript/lscript_execute/lscript_execute.cpp
index aa73025b7f..e863c1668e 100644
--- a/indra/lscript/lscript_execute/lscript_execute.cpp
+++ b/indra/lscript/lscript_execute/lscript_execute.cpp
@@ -31,6 +31,7 @@
#include "linden_common.h"
+#include <algorithm>
#include <sstream>
#include "lscript_execute.h"
@@ -45,7 +46,7 @@ void (*unary_operations[LST_EOF])(U8 *buffer, LSCRIPTOpCodesEnum opcode);
const char* LSCRIPTRunTimeFaultStrings[LSRF_EOF] = /*Flawfinder: ignore*/
{
- "invalid", // LSRF_INVALID,
+ "Invalid", // LSRF_INVALID,
"Math Error", // LSRF_MATH,
"Stack-Heap Collision", // LSRF_STACK_HEAP_COLLISION,
"Bounds Check Error", // LSRF_BOUND_CHECK_ERROR,
@@ -55,13 +56,11 @@ const char* LSCRIPTRunTimeFaultStrings[LSRF_EOF] = /*Flawfinder: ignore*/
"Hit Sandbox Limit", // LSRF_SANDBOX,
"Chat Overrun", // LSRF_CHAT_OVERRUN,
"Too Many Listens", // LSRF_TOO_MANY_LISTENS,
- "Lists may not contain lists" // LSRF_NESTING_LISTS,
+ "Lists may not contain lists", // LSRF_NESTING_LISTS,
+ "CLI Exception" // LSRF_CLI
};
-//static
-S64 LLScriptExecute::sGlobalInstructionCount = 0;
-
-LLScriptExecute::LLScriptExecute(LLFILE *fp)
+LLScriptExecuteLSL2::LLScriptExecuteLSL2(LLFILE *fp)
{
U8 sizearray[4];
S32 filesize;
@@ -84,19 +83,26 @@ LLScriptExecute::LLScriptExecute(LLFILE *fp)
init();
}
-LLScriptExecute::LLScriptExecute(U8 *buffer)
+LLScriptExecuteLSL2::LLScriptExecuteLSL2(const U8* bytecode, U32 bytecode_size)
{
- mBuffer = buffer;
-
+ mBuffer = new U8[TOP_OF_MEMORY];
+ memset(mBuffer + bytecode_size, 0, TOP_OF_MEMORY - bytecode_size);
+ S32 src_offset = 0;
+ S32 dest_offset = 0;
+ bytestream2bytestream(mBuffer, dest_offset, bytecode, src_offset, bytecode_size);
+ mBytecodeSize = bytecode_size;
+ mBytecode = new U8[mBytecodeSize];
+ memcpy(mBytecode, bytecode, mBytecodeSize);
init();
}
-LLScriptExecute::~LLScriptExecute()
+LLScriptExecuteLSL2::~LLScriptExecuteLSL2()
{
- delete [] mBuffer;
+ delete[] mBuffer;
+ delete[] mBytecode;
}
-void LLScriptExecute::init()
+void LLScriptExecuteLSL2::init()
{
S32 i, j;
@@ -270,7 +276,7 @@ void LLScriptExecute::init()
// Utility routine for when there's a boundary error parsing bytecode
-void LLScriptExecute::recordBoundaryError( const LLUUID &id )
+void LLScriptExecuteLSL2::recordBoundaryError( const LLUUID &id )
{
set_fault(mBuffer, LSRF_BOUND_CHECK_ERROR);
llwarns << "Script boundary error for ID " << id << llendl;
@@ -278,7 +284,7 @@ void LLScriptExecute::recordBoundaryError( const LLUUID &id )
// set IP to the event handler with some error checking
-void LLScriptExecute::setStateEventOpcoodeStartSafely( S32 state, LSCRIPTStateEventType event, const LLUUID &id )
+void LLScriptExecuteLSL2::setStateEventOpcoodeStartSafely( S32 state, LSCRIPTStateEventType event, const LLUUID &id )
{
S32 opcode_start = get_state_event_opcoode_start( mBuffer, state, event );
if ( opcode_start == -1 )
@@ -296,12 +302,474 @@ void LLScriptExecute::setStateEventOpcoodeStartSafely( S32 state, LSCRIPTStateEv
S32 lscript_push_variable(LLScriptLibData *data, U8 *buffer);
-U32 LLScriptExecute::run(BOOL b_print, const LLUUID &id, const char **errorstr, BOOL &state_transition)
+void LLScriptExecuteLSL2::resumeEventHandler(BOOL b_print, const LLUUID &id, F32 time_slice)
+{
+ // call opcode run function pointer with buffer and IP
+ mInstructionCount++;
+ S32 value = get_register(mBuffer, LREG_IP);
+ S32 tvalue = value;
+ S32 opcode = safe_instruction_bytestream2byte(mBuffer, tvalue);
+ mExecuteFuncs[opcode](mBuffer, value, b_print, id);
+ set_ip(mBuffer, value);
+ add_register_fp(mBuffer, LREG_ESR, -0.1f);
+ // lsa_print_heap(mBuffer);
+
+ if (b_print)
+ {
+ lsa_print_heap(mBuffer);
+ printf("ip: 0x%X\n", get_register(mBuffer, LREG_IP));
+ printf("sp: 0x%X\n", get_register(mBuffer, LREG_SP));
+ printf("bp: 0x%X\n", get_register(mBuffer, LREG_BP));
+ printf("hr: 0x%X\n", get_register(mBuffer, LREG_HR));
+ printf("hp: 0x%X\n", get_register(mBuffer, LREG_HP));
+ }
+
+ // NOTE: Babbage: all mExecuteFuncs return false.
+}
+
+void LLScriptExecuteLSL2::callEventHandler(LSCRIPTStateEventType event, S32 major_version, const LLUUID &id, F32 time_slice)
+{
+ // push a zero to be popped
+ lscript_push(mBuffer, 0);
+ // push sp as current bp
+ S32 sp = get_register(mBuffer, LREG_SP);
+ lscript_push(mBuffer, sp);
+
+ // Update current handler and current events registers.
+ set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
+ U64 current_events = get_event_register(mBuffer, LREG_CE, major_version);
+ current_events &= ~LSCRIPTStateBitField[event];
+ set_event_register(mBuffer, LREG_CE, current_events, major_version);
+
+ // now, push any additional stack space
+ U32 current_state = get_register(mBuffer, LREG_CS);
+ S32 additional_size = get_event_stack_size(mBuffer, current_state, event);
+ lscript_pusharge(mBuffer, additional_size);
+
+ // now set the bp correctly
+ sp = get_register(mBuffer, LREG_SP);
+ sp += additional_size;
+ set_bp(mBuffer, sp);
+
+ // set IP to the function
+ S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
+ set_ip(mBuffer, opcode_start);
+}
+
+//void callStateExitHandler()
+//{
+// // push a zero to be popped
+// lscript_push(mBuffer, 0);
+// // push sp as current bp
+// S32 sp = get_register(mBuffer, LREG_SP);
+// lscript_push(mBuffer, sp);
+//
+// // now, push any additional stack space
+// S32 additional_size = get_event_stack_size(mBuffer, current_state, LSTT_STATE_EXIT);
+// lscript_pusharge(mBuffer, additional_size);
+//
+// sp = get_register(mBuffer, LREG_SP);
+// sp += additional_size;
+// set_bp(mBuffer, sp);
+//
+// // set IP to the event handler
+// S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, LSTT_STATE_EXIT);
+// set_ip(mBuffer, opcode_start);
+//}
+//
+//void callStateEntryHandler()
+//{
+// // push a zero to be popped
+// lscript_push(mBuffer, 0);
+// // push sp as current bp
+// S32 sp = get_register(mBuffer, LREG_SP);
+// lscript_push(mBuffer, sp);
+//
+// event = return_first_event((S32)LSCRIPTStateBitField[LSTT_STATE_ENTRY]);
+// set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
+// current_events &= ~LSCRIPTStateBitField[event];
+// set_event_register(mBuffer, LREG_CE, current_events, major_version);
+//
+// // now, push any additional stack space
+// S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size;
+// lscript_pusharge(mBuffer, additional_size);
+//
+// // now set the bp correctly
+// sp = get_register(mBuffer, LREG_SP);
+// sp += additional_size + size;
+// set_bp(mBuffer, sp);
+// // set IP to the function
+// S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
+// set_ip(mBuffer, opcode_start);
+//}
+
+void LLScriptExecuteLSL2::callQueuedEventHandler(LSCRIPTStateEventType event, S32 major_version, const LLUUID &id, F32 time_slice)
+{
+ LLScriptDataCollection* eventdata;
+
+ for (eventdata = mEventData.mEventDataList.getFirstData(); eventdata; eventdata = mEventData.mEventDataList.getNextData())
+ {
+ if (eventdata->mType == event)
+ {
+ // push a zero to be popped
+ lscript_push(mBuffer, 0);
+ // push sp as current bp
+ S32 sp = get_register(mBuffer, LREG_SP);
+ lscript_push(mBuffer, sp);
+
+ // Update current handler and current events registers.
+ set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
+ U64 current_events = get_event_register(mBuffer, LREG_CE, major_version);
+ current_events &= ~LSCRIPTStateBitField[event];
+ set_event_register(mBuffer, LREG_CE, current_events, major_version);
+
+ // push any arguments that need to be pushed onto the stack
+ // last piece of data will be type LST_NULL
+ LLScriptLibData *data = eventdata->mData;
+ U32 size = 0;
+ while (data->mType)
+ {
+ size += lscript_push_variable(data, mBuffer);
+ data++;
+ }
+ // now, push any additional stack space
+ U32 current_state = get_register(mBuffer, LREG_CS);
+ S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size;
+ lscript_pusharge(mBuffer, additional_size);
+
+ // now set the bp correctly
+ sp = get_register(mBuffer, LREG_SP);
+ sp += additional_size + size;
+ set_bp(mBuffer, sp);
+
+ // set IP to the function
+ S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
+ set_ip(mBuffer, opcode_start);
+
+ mEventData.mEventDataList.deleteCurrentData();
+ break;
+ }
+ }
+}
+
+void LLScriptExecuteLSL2::callNextQueuedEventHandler(U64 event_register, S32 major_version, const LLUUID &id, F32 time_slice)
+{
+ LLScriptDataCollection* eventdata = mEventData.getNextEvent();
+ if (eventdata)
+ {
+ LSCRIPTStateEventType event = eventdata->mType;
+
+ // make sure that we can actually handle this one
+ if (LSCRIPTStateBitField[event] & event_register)
+ {
+ // push a zero to be popped
+ lscript_push(mBuffer, 0);
+ // push sp as current bp
+ S32 sp = get_register(mBuffer, LREG_SP);
+ lscript_push(mBuffer, sp);
+
+ // Update current handler and current events registers.
+ set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
+ U64 current_events = get_event_register(mBuffer, LREG_CE, major_version);
+ current_events &= ~LSCRIPTStateBitField[event];
+ set_event_register(mBuffer, LREG_CE, current_events, major_version);
+
+ // push any arguments that need to be pushed onto the stack
+ // last piece of data will be type LST_NULL
+ LLScriptLibData *data = eventdata->mData;
+ U32 size = 0;
+ while (data->mType)
+ {
+ size += lscript_push_variable(data, mBuffer);
+ data++;
+ }
+
+ // now, push any additional stack space
+ U32 current_state = get_register(mBuffer, LREG_CS);
+ S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size;
+ lscript_pusharge(mBuffer, additional_size);
+
+ // now set the bp correctly
+ sp = get_register(mBuffer, LREG_SP);
+ sp += additional_size + size;
+ set_bp(mBuffer, sp);
+
+ // set IP to the function
+ S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
+ set_ip(mBuffer, opcode_start);
+ }
+ else
+ {
+ llwarns << "Shit, somehow got an event that we're not registered for!" << llendl;
+ }
+ delete eventdata;
+ }
+}
+
+U64 LLScriptExecuteLSL2::nextState()
+{
+ // copy NS to CS
+ S32 next_state = get_register(mBuffer, LREG_NS);
+ set_register(mBuffer, LREG_CS, next_state);
+
+ // copy new state's handled events into ER (SR + CS*4 + 4)
+ return get_handled_events(mBuffer, next_state);
+}
+
+//virtual
+void LLScriptExecuteLSL2::addEvent(LLScriptDataCollection* event)
+{
+ mEventData.addEventData(event);
+}
+
+//virtual
+void LLScriptExecuteLSL2::removeEventType(LSCRIPTStateEventType event_type)
+{
+ mEventData.removeEventType(event_type);
+}
+
+//virtual
+F32 LLScriptExecuteLSL2::getSleep() const
+{
+ return get_register_fp(mBuffer, LREG_SLR);
+}
+
+//virtual
+void LLScriptExecuteLSL2::setSleep(F32 value)
+{
+ set_register_fp(mBuffer, LREG_SLR, value);
+}
+
+//virtual
+U64 LLScriptExecuteLSL2::getCurrentHandler(S32 version)
+{
+ return get_event_register(mBuffer, LREG_IE, version);
+}
+
+//virtual
+F32 LLScriptExecuteLSL2::getEnergy() const
+{
+ return get_register_fp(mBuffer, LREG_ESR);
+}
+
+//virtual
+void LLScriptExecuteLSL2::setEnergy(F32 value)
+{
+ set_register_fp(mBuffer, LREG_ESR, value);
+}
+
+//virtual
+U32 LLScriptExecuteLSL2::getFreeMemory()
+{
+ return get_register(mBuffer, LREG_SP) - get_register(mBuffer, LREG_HP);
+}
+
+//virtual
+S32 LLScriptExecuteLSL2::getParameter()
+{
+ return get_register(mBuffer, LREG_PR);
+}
+
+//virtual
+void LLScriptExecuteLSL2::setParameter(S32 value)
+{
+ set_register(mBuffer, LREG_PR, value);
+}
+
+
+S32 LLScriptExecuteLSL2::writeState(U8 **dest, U32 header_size, U32 footer_size)
+{
+ // data format:
+ // 4 bytes of size of Registers, Name and Description, and Global Variables
+ // Registers, Name and Description, and Global Variables data
+ // 4 bytes of size of Heap
+ // Heap data
+ // 4 bytes of stack size
+ // Stack data
+
+ S32 registers_size = get_register(mBuffer, LREG_GFR);
+
+ if (get_register(mBuffer, LREG_HP) > TOP_OF_MEMORY)
+ reset_hp_to_safe_spot(mBuffer);
+
+ S32 heap_size = get_register(mBuffer, LREG_HP) - get_register(mBuffer, LREG_HR);
+ S32 stack_size = get_register(mBuffer, LREG_TM) - get_register(mBuffer, LREG_SP);
+ S32 total_size = registers_size + LSCRIPTDataSize[LST_INTEGER] +
+ heap_size + LSCRIPTDataSize[LST_INTEGER] +
+ stack_size + LSCRIPTDataSize[LST_INTEGER];
+
+ // actually allocate data
+ delete[] *dest;
+ *dest = new U8[header_size + total_size + footer_size];
+ memset(*dest, 0, header_size + total_size + footer_size);
+ S32 dest_offset = header_size;
+ S32 src_offset = 0;
+
+ // registers
+ integer2bytestream(*dest, dest_offset, registers_size);
+
+ // llinfos << "Writing CE: " << getCurrentEvents() << llendl;
+ bytestream2bytestream(*dest, dest_offset, mBuffer, src_offset, registers_size);
+
+ // heap
+ integer2bytestream(*dest, dest_offset, heap_size);
+
+ src_offset = get_register(mBuffer, LREG_HR);
+ bytestream2bytestream(*dest, dest_offset, mBuffer, src_offset, heap_size);
+
+ // stack
+ integer2bytestream(*dest, dest_offset, stack_size);
+
+ src_offset = get_register(mBuffer, LREG_SP);
+ bytestream2bytestream(*dest, dest_offset, mBuffer, src_offset, stack_size);
+
+ return total_size;
+}
+
+S32 LLScriptExecuteLSL2::writeBytecode(U8 **dest)
+{
+ // data format:
+ // registers through top of heap
+ // Heap data
+ S32 total_size = get_register(mBuffer, LREG_HP);
+
+ // actually allocate data
+ delete [] *dest;
+ *dest = new U8[total_size];
+ S32 dest_offset = 0;
+ S32 src_offset = 0;
+
+ bytestream2bytestream(*dest, dest_offset, mBuffer, src_offset, total_size);
+
+ return total_size;
+}
+
+S32 LLScriptExecuteLSL2::readState(U8 *src)
+{
+ // first, blitz heap and stack
+ S32 hr = get_register(mBuffer, LREG_HR);
+ S32 tm = get_register(mBuffer, LREG_TM);
+ memset(mBuffer + hr, 0, tm - hr);
+
+ S32 src_offset = 0;
+ S32 dest_offset = 0;
+ S32 size;
+
+ // read register size
+ size = bytestream2integer(src, src_offset);
+
+ // copy data into register area
+ bytestream2bytestream(mBuffer, dest_offset, src, src_offset, size);
+// llinfos << "Read CE: " << getCurrentEvents() << llendl;
+ if (get_register(mBuffer, LREG_TM) != TOP_OF_MEMORY)
+ {
+ llwarns << "Invalid state. Top of memory register does not match"
+ << " constant." << llendl;
+ reset_hp_to_safe_spot(mBuffer);
+ return -1;
+ }
+
+ // read heap size
+ size = bytestream2integer(src, src_offset);
+
+ // set dest offset
+ dest_offset = get_register(mBuffer, LREG_HR);
+
+ if (dest_offset + size > TOP_OF_MEMORY)
+ {
+ reset_hp_to_safe_spot(mBuffer);
+ return -1;
+ }
+
+ // copy data into heap area
+ bytestream2bytestream(mBuffer, dest_offset, src, src_offset, size);
+
+ // read stack size
+ size = bytestream2integer(src, src_offset);
+
+ // set dest offset
+ dest_offset = get_register(mBuffer, LREG_SP);
+
+ if (dest_offset + size > TOP_OF_MEMORY)
+ {
+ reset_hp_to_safe_spot(mBuffer);
+ return -1;
+ }
+
+ // copy data into heap area
+ bytestream2bytestream(mBuffer, dest_offset, src, src_offset, size);
+
+ // Return offset to first byte after read data.
+ return src_offset;
+}
+
+void LLScriptExecuteLSL2::reset()
+{
+ LLScriptExecute::reset();
+
+ const U8 *src = getBytecode();
+ S32 size = getBytecodeSize();
+
+ if (!src)
+ return;
+
+ // first, blitz heap and stack
+ S32 hr = get_register(mBuffer, LREG_HR);
+ S32 tm = get_register(mBuffer, LREG_TM);
+ memset(mBuffer + hr, 0, tm - hr);
+
+ S32 dest_offset = 0;
+ S32 src_offset = 0;
+
+ bytestream2bytestream(mBuffer, dest_offset, src, src_offset, size);
+}
+
+LLScriptExecute::LLScriptExecute() :
+ mReset(FALSE)
+{
+}
+
+void LLScriptExecute::reset()
+{
+ mReset = FALSE;
+}
+
+bool LLScriptExecute::isYieldDue() const
+{
+ if(mReset)
+ {
+ return true;
+ }
+
+ if(getSleep() > 0.f)
+ {
+ return true;
+ }
+
+ if(isFinished())
+ {
+ return true;
+ }
+
+ if(isStateChangePending())
+ {
+ return true;
+ }
+
+ return false;
+}
+
+// Run smallest number of instructions possible:
+// a single instruction for LSL2, a segment between save tests for Mono
+void LLScriptExecute::runInstructions(BOOL b_print, const LLUUID &id,
+ const char **errorstr,
+ BOOL &state_transition,
+ U32& events_processed,
+ F32 quanta)
{
// is there a fault?
// if yes, print out message and exit
- state_transition = FALSE;
- S32 value = get_register(mBuffer, LREG_VN);
+ S32 value = getVersion();
S32 major_version = 0;
if (value == LSL2_VERSION1_END_NUMBER)
{
@@ -313,323 +781,151 @@ U32 LLScriptExecute::run(BOOL b_print, const LLUUID &id, const char **errorstr,
}
else
{
- set_fault(mBuffer, LSRF_VERSION_MISMATCH);
+ setFault(LSRF_VERSION_MISMATCH);
}
- value = get_register(mBuffer, LREG_FR);
- if (value)
+ value = getFaults();
+ if (value > LSRF_INVALID && value < LSRF_EOF)
{
if (b_print)
{
printf("Error!\n");
}
*errorstr = LSCRIPTRunTimeFaultStrings[value];
- return NO_DELETE_FLAG;
+ return;
}
else
{
*errorstr = NULL;
}
- // Get IP
- // is IP nonzero?
- value = get_register(mBuffer, LREG_IP);
-
- if (value)
+ if (! isFinished())
{
- // if yes, we're in opcodes, execute the next opcode by:
- // call opcode run function pointer with buffer and IP
- mInstructionCount++;
- sGlobalInstructionCount++;
- S32 tvalue = value;
- S32 opcode = safe_instruction_bytestream2byte(mBuffer, tvalue);
- S32 b_ret_val = mExecuteFuncs[opcode](mBuffer, value, b_print, id);
- set_ip(mBuffer, value);
- add_register_fp(mBuffer, LREG_ESR, -0.1f);
- // lsa_print_heap(mBuffer);
-
- if (b_print)
- {
- lsa_print_heap(mBuffer);
- printf("ip: 0x%X\n", get_register(mBuffer, LREG_IP));
- printf("sp: 0x%X\n", get_register(mBuffer, LREG_SP));
- printf("bp: 0x%X\n", get_register(mBuffer, LREG_BP));
- printf("hr: 0x%X\n", get_register(mBuffer, LREG_HR));
- printf("hp: 0x%X\n", get_register(mBuffer, LREG_HP));
- }
- // update IP
- if (b_ret_val)
- {
- return DELETE_FLAG | CREDIT_MONEY_FLAG;
- }
- else
- {
- return NO_DELETE_FLAG;
- }
+ resumeEventHandler(b_print, id, quanta);
+ return;
}
else
{
// make sure that IE is zero
- set_event_register(mBuffer, LREG_IE, 0, major_version);
-
- // if no, we're in a state and waiting for an event
- S32 next_state = get_register(mBuffer, LREG_NS);
- S32 current_state = get_register(mBuffer, LREG_CS);
- U64 current_events = get_event_register(mBuffer, LREG_CE, major_version);
- U64 event_register = get_event_register(mBuffer, LREG_ER, major_version);
- // check NS to see if need to switch states (NS != CS)
- if (next_state != current_state)
+ setCurrentHandler(0, major_version);
+
+ // if no, we're in a state and waiting for an event
+ U64 current_events = getCurrentEvents(major_version);
+ U64 event_register = getEventHandlers(major_version);
+
+ // check NS to see if need to switch states (NS != CS)
+ if (isStateChangePending())
{
state_transition = TRUE;
+
// ok, blow away any pending events
- mEventData.mEventDataList.deleteAllData();
+ deleteAllEvents();
- // if yes, check state exit flag is set
+ // if yes, check state exit flag is set
if (current_events & LSCRIPTStateBitField[LSTT_STATE_EXIT])
{
- // if yes, clear state exit flag
- set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[LSTT_STATE_EXIT], major_version);
+ // if yes, clear state exit flag
+ setCurrentHandler(LSCRIPTStateBitField[LSTT_STATE_EXIT], major_version);
current_events &= ~LSCRIPTStateBitField[LSTT_STATE_EXIT];
- set_event_register(mBuffer, LREG_CE, current_events, major_version);
- // check state exit event handler
- // if there is a handler, call it
+ setCurrentEvents(current_events, major_version);
+
+ // check state exit event handler
+ // if there is a handler, call it
if (event_register & LSCRIPTStateBitField[LSTT_STATE_EXIT])
{
- // push a zero to be popped
- lscript_push(mBuffer, 0);
- // push sp as current bp
- S32 sp = get_register(mBuffer, LREG_SP);
- lscript_push(mBuffer, sp);
-
- // now, push any additional stack space
- S32 additional_size = get_event_stack_size(mBuffer, current_state, LSTT_STATE_EXIT);
- if ( additional_size == -1 )
- {
- recordBoundaryError( id );
- }
- else
- {
- lscript_pusharge(mBuffer, additional_size);
-
- sp = get_register(mBuffer, LREG_SP);
- sp += additional_size;
- set_bp(mBuffer, sp);
- // set IP to the event handler
- setStateEventOpcoodeStartSafely( current_state, LSTT_STATE_EXIT, id );
- }
- return NO_DELETE_FLAG;
+ ++events_processed;
+ callEventHandler(LSTT_STATE_EXIT, major_version, id, quanta);
+ return;
}
}
- // if no handler or no state exit flag switch to new state
- // set state entry flag and clear other CE flags
+
+ // if no handler or no state exit flag switch to new state
+ // set state entry flag and clear other CE flags
current_events = LSCRIPTStateBitField[LSTT_STATE_ENTRY];
- set_event_register(mBuffer, LREG_CE, current_events, major_version);
- // copy NS to CS
- set_register(mBuffer, LREG_CS, next_state);
- // copy new state's handled events into ER (SR + CS*4 + 4)
- U64 handled_events = get_handled_events(mBuffer, next_state);
- set_event_register(mBuffer, LREG_ER, handled_events, major_version);
+ setCurrentEvents(current_events, major_version);
+
+ U64 handled_events = nextState();
+ setEventHandlers(handled_events, major_version);
}
-// check to see if any current events are covered by events handled by this state (CE & ER != 0)
-// now, we want to look like we were called like a function
-// 0x0000: 00 00 00 00 (return ip)
-// 0x0004: bp (current sp)
-// 0x0008: parameters
-// push sp
-// add parameter size
-// pop bp
-// set ip
-
- S32 size = 0;
-// try to get next event from stack
+
+ // try to get next event from stack
BOOL b_done = FALSE;
LSCRIPTStateEventType event = LSTT_NULL;
- LLScriptDataCollection *eventdata;
- next_state = get_register(mBuffer, LREG_NS);
- current_state = get_register(mBuffer, LREG_CS);
- current_events = get_event_register(mBuffer, LREG_CE, major_version);
- event_register = get_event_register(mBuffer, LREG_ER, major_version);
+ current_events = getCurrentEvents(major_version);
+ event_register = getEventHandlers(major_version);
// first, check to see if state_entry or onrez are raised and handled
- if ( (current_events & LSCRIPTStateBitField[LSTT_STATE_ENTRY])
+ if ((current_events & LSCRIPTStateBitField[LSTT_STATE_ENTRY])
&&(current_events & event_register))
{
- // ok, this is easy since there isn't any data waiting, just set it
- // push a zero to be popped
- lscript_push(mBuffer, 0);
-// push sp as current bp
- S32 sp = get_register(mBuffer, LREG_SP);
- lscript_push(mBuffer, sp);
-
- event = return_first_event((S32)LSCRIPTStateBitField[LSTT_STATE_ENTRY]);
- set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
- current_events &= ~LSCRIPTStateBitField[event];
- set_event_register(mBuffer, LREG_CE, current_events, major_version);
-// now, push any additional stack space
- S32 additional_size = get_event_stack_size(mBuffer, current_state, event);
- if ( additional_size == -1 )
- { // b_done will be set, so we'll exit the loop at the bottom
- recordBoundaryError( id );
- }
- else
- {
- additional_size -= size;
- lscript_pusharge(mBuffer, additional_size);
-
-// now set the bp correctly
- sp = get_register(mBuffer, LREG_SP);
- sp += additional_size + size;
- set_bp(mBuffer, sp);
-// set IP to the function
- setStateEventOpcoodeStartSafely( current_state, event, id );
- }
+ ++events_processed;
+ callEventHandler(LSTT_STATE_ENTRY, major_version, id, quanta);
b_done = TRUE;
}
- else if ( (current_events & LSCRIPTStateBitField[LSTT_REZ])
- &&(current_events & event_register))
+ else if ((current_events & LSCRIPTStateBitField[LSTT_REZ])
+ &&(current_events & event_register))
{
- for (eventdata = mEventData.mEventDataList.getFirstData(); eventdata; eventdata = mEventData.mEventDataList.getNextData())
- {
- if (eventdata->mType & LSCRIPTStateBitField[LSTT_REZ])
- {
- // push a zero to be popped
- lscript_push(mBuffer, 0);
- // push sp as current bp
- S32 sp = get_register(mBuffer, LREG_SP);
- lscript_push(mBuffer, sp);
-
- set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
- current_events &= ~LSCRIPTStateBitField[event];
- set_event_register(mBuffer, LREG_CE, current_events, major_version);
-
- // push any arguments that need to be pushed onto the stack
- // last piece of data will be type LST_NULL
- LLScriptLibData *data = eventdata->mData;
- while (data->mType)
- {
- size += lscript_push_variable(data, mBuffer);
- data++;
- }
- // now, push any additional stack space
- S32 additional_size = get_event_stack_size(mBuffer, current_state, event);
- if ( additional_size == -1 )
- { // b_done will be set, so we'll exit the loop at the bottom
- recordBoundaryError( id );
- }
- else
- {
- additional_size -= size;
- lscript_pusharge(mBuffer, additional_size);
-
- // now set the bp correctly
- sp = get_register(mBuffer, LREG_SP);
- sp += additional_size + size;
- set_bp(mBuffer, sp);
- // set IP to the function
- setStateEventOpcoodeStartSafely( current_state, event, id );
- mEventData.mEventDataList.deleteCurrentData();
- }
- b_done = TRUE;
- break;
- }
- }
+ ++events_processed;
+ callQueuedEventHandler(LSTT_REZ, major_version, id, quanta);
+ b_done = TRUE;
}
while (!b_done)
{
- eventdata = mEventData.getNextEvent();
- if (eventdata)
+ // Call handler for next queued event.
+ if(getEventCount() > 0)
{
- event = eventdata->mType;
-
- // make sure that we can actually handle this one
- if (LSCRIPTStateBitField[event] & event_register)
- {
- // push a zero to be popped
- lscript_push(mBuffer, 0);
- // push sp as current bp
- S32 sp = get_register(mBuffer, LREG_SP);
- lscript_push(mBuffer, sp);
-
- set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
- current_events &= ~LSCRIPTStateBitField[event];
- set_event_register(mBuffer, LREG_CE, current_events, major_version);
-
- // push any arguments that need to be pushed onto the stack
- // last piece of data will be type LST_NULL
- LLScriptLibData *data = eventdata->mData;
- while (data->mType)
- {
- size += lscript_push_variable(data, mBuffer);
- data++;
- }
- b_done = TRUE;
- // now, push any additional stack space
- S32 additional_size = get_event_stack_size(mBuffer, current_state, event);
- if ( additional_size == -1 )
- { // b_done was just set, so we'll exit the loop at the bottom
- recordBoundaryError( id );
- }
- else
- {
- additional_size -= size;
- lscript_pusharge(mBuffer, additional_size);
-
- // now set the bp correctly
- sp = get_register(mBuffer, LREG_SP);
- sp += additional_size + size;
- set_bp(mBuffer, sp);
- // set IP to the function
- setStateEventOpcoodeStartSafely( current_state, event, id );
- }
- }
- else
- {
- llwarns << "Shit, somehow got an event that we're not registered for!" << llendl;
- }
- delete eventdata;
+ ++events_processed;
+ callNextQueuedEventHandler(event_register, major_version, id, quanta);
+ b_done = TRUE;
}
else
{
-// if no data waiting, do it the old way:
+ // if no data waiting, do it the old way:
U64 handled_current = current_events & event_register;
if (handled_current)
{
- // push a zero to be popped
- lscript_push(mBuffer, 0);
- // push sp as current bp
- S32 sp = get_register(mBuffer, LREG_SP);
- lscript_push(mBuffer, sp);
-
event = return_first_event((S32)handled_current);
- set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
- current_events &= ~LSCRIPTStateBitField[event];
- set_event_register(mBuffer, LREG_CE, current_events, major_version);
- // now, push any additional stack space
- S32 additional_size = get_event_stack_size(mBuffer, current_state, event);
- if ( additional_size == -1 )
- { // b_done will be set, so we'll exit the loop at the bottom
- recordBoundaryError( id );
- }
- else
- {
- additional_size -= size;
- lscript_pusharge(mBuffer, additional_size);
-
- // now set the bp correctly
- sp = get_register(mBuffer, LREG_SP);
- sp += additional_size + size;
- set_bp(mBuffer, sp);
- // set IP to the function
- setStateEventOpcoodeStartSafely( current_state, event, id );
- }
+ ++events_processed;
+ callEventHandler(event, major_version, id, quanta);
}
b_done = TRUE;
}
- } // while (!b_done)
- } // end of else ... in state processing code
+ }
+ }
+}
+
+// Run for a single timeslice, or until a yield is due
+F32 LLScriptExecute::runQuanta(BOOL b_print, const LLUUID &id, const char **errorstr, BOOL &state_transition, F32 quanta, U32& events_processed, LLTimer& timer)
+{
+ U32 timer_checks = 0;
+ F32 inloop = 0;
- return NO_DELETE_FLAG;
+ // Loop while not finished, yield not due and time remaining
+ // NOTE: Default implementation does not do adaptive timer skipping
+ // to preserve current LSL behaviour and not break scripts that rely
+ // on current execution speed.
+ while(true)
+ {
+ runInstructions(b_print, id, errorstr, state_transition,
+ events_processed, quanta);
+
+ static const S32 lsl_timer_check_skip = 4;
+ if(isYieldDue())
+ {
+ break;
+ }
+ else if(timer_checks++ == lsl_timer_check_skip)
+ {
+ inloop = timer.getElapsedTimeF32();
+ if(inloop > quanta)
+ {
+ break;
+ }
+ timer_checks = 0;
+ }
+ }
+ return inloop;
}
BOOL run_noop(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
@@ -3687,6 +3983,11 @@ BOOL run_print(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
void lscript_run(const std::string& filename, BOOL b_debug)
{
LLTimer timer;
+
+ const char *error;
+ BOOL b_state;
+ LLScriptExecuteLSL2 *execute = NULL;
+
if (filename.empty())
{
llerrs << "filename is NULL" << llendl;
@@ -3694,47 +3995,35 @@ void lscript_run(const std::string& filename, BOOL b_debug)
// to check how to abort or error out gracefully
// from this function. XXXTBD
}
- else
+ LLFILE* file = LLFile::fopen(filename, "r"); /* Flawfinder: ignore */
+ if(file)
{
- const char *error;
- BOOL b_state;
- LLScriptExecute *execute = NULL;
-
- LLFILE* file = LLFile::fopen(filename, "r");
- if (file)
- {
- execute = new LLScriptExecute(file);
- // note: LLScriptExecute() closes file for us
- }
- file = LLFile::fopen(filename, "r");
- if (file)
- {
- std::string parsefile("lscript.parse");
- LLFILE* fp = LLFile::fopen(parsefile, "w"); /*Flawfinder: ignore*/
- LLScriptLSOParse *parse = new LLScriptLSOParse(file);
- parse->printData(fp);
- delete parse;
- fclose(file);
- fclose(fp);
- }
- file = LLFile::fopen(filename, "r");
- if (file && execute)
- {
- timer.reset();
- while (!execute->run(b_debug, LLUUID::null, &error, b_state))
- ;
- F32 time = timer.getElapsedTimeF32();
- F32 ips = execute->mInstructionCount / time;
- llinfos << execute->mInstructionCount << " instructions in " << time << " seconds" << llendl;
- llinfos << ips/1000 << "K instructions per second" << llendl;
- printf("ip: 0x%X\n", get_register(execute->mBuffer, LREG_IP));
- printf("sp: 0x%X\n", get_register(execute->mBuffer, LREG_SP));
- printf("bp: 0x%X\n", get_register(execute->mBuffer, LREG_BP));
- printf("hr: 0x%X\n", get_register(execute->mBuffer, LREG_HR));
- printf("hp: 0x%X\n", get_register(execute->mBuffer, LREG_HP));
- delete execute;
- fclose(file);
- }
+ execute = new LLScriptExecuteLSL2(file);
+ fclose(file);
+ }
+ if (execute)
+ {
+ timer.reset();
+ F32 time_slice = 3600.0f; // 1 hr.
+ U32 events_processed = 0;
+
+ do {
+ LLTimer timer2;
+ execute->runQuanta(b_debug, LLUUID::null, &error, b_state,
+ time_slice, events_processed, timer2);
+ } while (!execute->isFinished());
+
+ F32 time = timer.getElapsedTimeF32();
+ F32 ips = execute->mInstructionCount / time;
+ llinfos << execute->mInstructionCount << " instructions in " << time << " seconds" << llendl;
+ llinfos << ips/1000 << "K instructions per second" << llendl;
+ printf("ip: 0x%X\n", get_register(execute->mBuffer, LREG_IP));
+ printf("sp: 0x%X\n", get_register(execute->mBuffer, LREG_SP));
+ printf("bp: 0x%X\n", get_register(execute->mBuffer, LREG_BP));
+ printf("hr: 0x%X\n", get_register(execute->mBuffer, LREG_HR));
+ printf("hp: 0x%X\n", get_register(execute->mBuffer, LREG_HP));
+ delete execute;
+ fclose(file);
}
}
diff --git a/indra/lscript/lscript_library.h b/indra/lscript/lscript_library.h
index 74356256ae..a9db30670a 100644
--- a/indra/lscript/lscript_library.h
+++ b/indra/lscript/lscript_library.h
@@ -146,9 +146,9 @@ public:
return FALSE;
}
- S32 getListLength()
+ S32 getListLength() const
{
- LLScriptLibData *data = this;
+ const LLScriptLibData *data = this;
S32 retval = 0;
while (data->mListp)
{
diff --git a/indra/lscript/lscript_library/lscript_library.cpp b/indra/lscript/lscript_library/lscript_library.cpp
index b99bd64f2a..54d0154798 100644
--- a/indra/lscript/lscript_library/lscript_library.cpp
+++ b/indra/lscript/lscript_library/lscript_library.cpp
@@ -398,9 +398,8 @@ void LLScriptLibrary::init()
addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetCameraPos", "v", "", "vector llGetCameraPos()\nGets current camera position for agent task has permissions for."));
addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetCameraRot", "q", "", "rotation llGetCameraRot()\nGets current camera orientation for agent task has permissions for."));
- addFunction(new LLScriptLibraryFunction(10.f, 2.f, dummy_func, "llSetPrimURL", NULL, "s", "llSetPrimURL(string url)\nUpdates the URL for the web page shown on the sides of the object."));
+ addFunction(new LLScriptLibraryFunction(10.f, 20.f, dummy_func, "llSetPrimURL", NULL, "s", "llSetPrimURL(string url)\nUpdates the URL for the web page shown on the sides of the object."));
addFunction(new LLScriptLibraryFunction(10.f, 20.f, dummy_func, "llRefreshPrimURL", NULL, "", "llRefreshPrimURL()\nReloads the web page shown on the sides of the object."));
-
addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llEscapeURL", "s", "s", "string llEscapeURL(string url)\nReturns and escaped/encoded version of url, replacing spaces with %20 etc."));
addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llUnescapeURL", "s", "s", "string llUnescapeURL(string url)\nReturns and unescaped/unencoded version of url, replacing %20 with spaces etc."));
@@ -458,24 +457,6 @@ void LLScriptLibrary::init()
// existing scripts will crash.
}
- //Ventrella Follow Cam Script Stuff
- //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamPitch", NULL, "f", "llSetCamPitch(-45 to 80)\n(Adjusts the angular amount that the camera aims straight ahead vs. straight down, maintaining the same distance. Analogous to 'incidence'."));
- //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamVerticalOffset", NULL, "f", "llSetCamVerticalOffset(-2 to 2)\nAdjusts the vertical position of the camera focus position relative to the subject"));
- //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamPositionLag", NULL, "f", "llSetCamPositionLag(0 to 3) \nHow much the camera lags as it tries to move towards its 'ideal' position"));
- //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamFocusLag", NULL, "f", "llSetCamFocusLag(0 to 3)\nHow much the camera lags as it tries to aim towards the subject"));
- //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamDistance", NULL, "f", "llSetCamDistance(0.5 to 10)\nSets how far away the camera wants to be from its subject"));
- //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamBehindnessAngle", NULL, "f", "llSetCamBehindnessAngle(0 to 180)\nSets the angle in degrees within which the camera is not constrained by changes in subject rotation"));
- //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamBehindnessLag", NULL, "f", "llSetCamBehindnessLag(0 to 3)\nSets how strongly the camera is forced to stay behind the target if outside of behindness angle"));
- //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamPositionThreshold", NULL, "f", "llSetCamPositionThreshold(0 to 4)\nSets the radius of a sphere around the camera's ideal position within which it is not affected by subject motion"));
- //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamFocusThreshold", NULL, "f", "llSetCamFocusThreshold(0 to 4)\nSets the radius of a sphere around the camera's subject position within which its focus is not affected by subject motion"));
- //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamScriptControl", NULL, "i", "llSetCamScriptControl(TRUE or FALSE)\nTurns on or off scripted control of the camera"));
- //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamPosition", NULL, "v", "llSetCamPosition(vector)\nSets the position of the camera"));
- //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamFocus", NULL, "v", "llSetCamFocus(vector focus)\nSets the focus (target position) of the camera"));
- //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamPositionLocked", NULL, "i", "llSetCamPositionLocked(TRUE or FALSE)\nLocks the camera position so it will not move"));
- //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamFocusLocked", NULL, "i", "llSetCamFocusLocked(TRUE or FALSE)\nLocks the camera focus so it will not move"));
-
- //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetForSale", "i", "ii", "integer llSetForSale(integer selltype, integer price)\nSets this object for sale in mode selltype for price. Returns TRUE if successfully set for sale."));
-
LLScriptLibraryFunction::LLScriptLibraryFunction(F32 eu, F32 st, void (*exec_func)(LLScriptLibData *, LLScriptLibData *, const LLUUID &), const char *name, const char *ret_type, const char *args, const char *desc, BOOL god_only)
: mEnergyUse(eu), mSleepTime(st), mExecFunc(exec_func), mName(name), mReturnType(ret_type), mArgs(args), mGodOnly(god_only)
{
diff --git a/indra/lscript/lscript_rt_interface.h b/indra/lscript/lscript_rt_interface.h
index 3e05212c67..14559ab3e8 100644
--- a/indra/lscript/lscript_rt_interface.h
+++ b/indra/lscript/lscript_rt_interface.h
@@ -32,9 +32,9 @@
#ifndef LL_LSCRIPT_RT_INTERFACE_H
#define LL_LSCRIPT_RT_INTERFACE_H
-BOOL lscript_compile(char *filename, BOOL is_god_like = FALSE);
+BOOL lscript_compile(char *filename, BOOL compile_to_mono, BOOL is_god_like = FALSE);
BOOL lscript_compile(const char* src_filename, const char* dst_filename,
- const char* err_filename, BOOL is_god_like = FALSE);
+ const char* err_filename, BOOL compile_to_mono, const char* class_name, BOOL is_god_like = FALSE);
void lscript_run(const std::string& filename, BOOL b_debug);
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index e65721e124..0fea3076c3 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -66,6 +66,7 @@ set(viewer_SOURCE_FILES
llanimstatelabels.cpp
llappviewer.cpp
llassetuploadresponders.cpp
+ llassetuploadqueue.cpp
llaudiosourcevo.cpp
llbbox.cpp
llbox.cpp
@@ -454,6 +455,7 @@ set(viewer_HEADER_FILES
llappearance.h
llappviewer.h
llassetuploadresponders.h
+ llassetuploadqueue.h
llaudiosourcevo.h
llbbox.h
llbox.h
diff --git a/indra/newview/English.lproj/InfoPlist.strings b/indra/newview/English.lproj/InfoPlist.strings
index 7272173fed..881483e892 100644
--- a/indra/newview/English.lproj/InfoPlist.strings
+++ b/indra/newview/English.lproj/InfoPlist.strings
@@ -1,5 +1,6 @@
/* Localized versions of Info.plist keys */
CFBundleName = "Second Life";
-CFBundleShortVersionString = "Second Life version 1.20.6.86975";
-CFBundleGetInfoString = "Second Life version 1.20.6.86975, Copyright 2004-2008 Linden Research, Inc.";
+CFBundleShortVersionString = "Second Life version 1.20.9.87416";
+CFBundleGetInfoString = "Second Life version 1.20.9.87416, Copyright 2004-2008 Linden Research, Inc.";
+
diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist
index fa50503545..b889d45b9e 100644
--- a/indra/newview/Info-SecondLife.plist
+++ b/indra/newview/Info-SecondLife.plist
@@ -32,7 +32,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
- <string>1.20.6.86975</string>
+ <string>1.20.9.87416</string>
<key>CSResourcesFileMapped</key>
<true/>
</dict>
diff --git a/indra/newview/llassetuploadqueue.cpp b/indra/newview/llassetuploadqueue.cpp
new file mode 100644
index 0000000000..c52c189d56
--- /dev/null
+++ b/indra/newview/llassetuploadqueue.cpp
@@ -0,0 +1,194 @@
+/**
+ * @file llassetupload.cpp
+ * @brief Serializes asset upload request
+ * Copyright (c) 2007, Linden Research, Inc.
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llassetuploadqueue.h"
+#include "llviewerregion.h"
+#include "llviewerobjectlist.h"
+
+#include "llassetuploadresponders.h"
+#include "llsd.h"
+#include <iostream>
+
+class LLAssetUploadChainResponder : public LLUpdateTaskInventoryResponder
+{
+public:
+
+ LLAssetUploadChainResponder(const LLSD& post_data,
+ const std::string& file_name,
+ const LLUUID& queue_id,
+ U8* data,
+ U32 data_size,
+ std::string script_name,
+ LLAssetUploadQueueSupplier *supplier) :
+ LLUpdateTaskInventoryResponder(post_data, file_name, queue_id, LLAssetType::AT_LSL_TEXT),
+ mSupplier(supplier),
+ mData(data),
+ mDataSize(data_size),
+ mScriptName(script_name)
+ {
+ }
+
+ virtual ~LLAssetUploadChainResponder()
+ {
+ if(mSupplier)
+ {
+ LLAssetUploadQueue *queue = mSupplier->get();
+ if (queue)
+ {
+ // Give ownership of supplier back to queue.
+ queue->mSupplier = mSupplier;
+ mSupplier = NULL;
+ }
+ }
+ delete mSupplier;
+ delete mData;
+ }
+
+ virtual void error(U32 statusNum, const std::string& reason)
+ {
+ llwarns << "Error: " << reason << llendl;
+ LLUpdateTaskInventoryResponder::error(statusNum, reason);
+ LLAssetUploadQueue *queue = mSupplier->get();
+ if (queue)
+ {
+ queue->request(&mSupplier);
+ }
+ }
+
+ virtual void result(const LLSD& content)
+ {
+ LLUpdateTaskInventoryResponder::result(content);
+ LLAssetUploadQueue *queue = mSupplier->get();
+ if (queue)
+ {
+ // Responder is reused across 2 phase upload,
+ // so only start next upload after 2nd phase complete.
+ std::string state = content["state"];
+ if(state == "complete")
+ {
+ queue->request(&mSupplier);
+ }
+ }
+ }
+
+ virtual void uploadUpload(const LLSD& content)
+ {
+ std::string uploader = content["uploader"];
+
+ mSupplier->log(std::string("Compiling " + mScriptName).c_str());
+ llinfos << "Compiling " << llendl;
+
+ // postRaw takes ownership of mData and will delete it.
+ LLHTTPClient::postRaw(uploader, mData, mDataSize, this);
+ mData = NULL;
+ mDataSize = 0;
+ }
+
+ virtual void uploadComplete(const LLSD& content)
+ {
+ // Bytecode save completed
+ if (content["compiled"])
+ {
+ mSupplier->log("Compilation succeeded");
+ llinfos << "Compiled!" << llendl;
+ }
+ else
+ {
+ LLSD compile_errors = content["errors"];
+ for(LLSD::array_const_iterator line = compile_errors.beginArray();
+ line < compile_errors.endArray(); line++)
+ {
+ mSupplier->log(line->asString());
+ llinfos << content["errors"] << llendl;
+ }
+ }
+ LLUpdateTaskInventoryResponder::uploadComplete(content);
+ }
+
+ LLAssetUploadQueueSupplier *mSupplier;
+ U8* mData;
+ U32 mDataSize;
+ std::string mScriptName;
+};
+
+
+LLAssetUploadQueue::LLAssetUploadQueue(LLAssetUploadQueueSupplier *supplier) :
+ mSupplier(supplier)
+{
+}
+
+//virtual
+LLAssetUploadQueue::~LLAssetUploadQueue()
+{
+ delete mSupplier;
+}
+
+// Takes ownership of supplier.
+void LLAssetUploadQueue::request(LLAssetUploadQueueSupplier** supplier)
+{
+ if (mQueue.empty())
+ return;
+
+ UploadData data = mQueue.front();
+ mQueue.pop_front();
+
+ LLSD body;
+ body["task_id"] = data.mTaskId;
+ body["item_id"] = data.mItemId;
+ body["is_script_running"] = data.mIsRunning;
+ body["target"] = data.mIsTargetMono? "mono" : "lsl2";
+
+ std::string url = "";
+ LLViewerObject* object = gObjectList.findObject(data.mTaskId);
+ if (object)
+ {
+ url = object->getRegion()->getCapability("UpdateScriptTaskInventory");
+ LLHTTPClient::post(url, body,
+ new LLAssetUploadChainResponder(
+ body, data.mFilename, data.mQueueId,
+ data.mData, data.mDataSize, data.mScriptName, *supplier));
+ }
+
+ *supplier = NULL;
+}
+
+void LLAssetUploadQueue::queue(const std::string& filename,
+ const LLUUID& task_id,
+ const LLUUID& item_id,
+ BOOL is_running,
+ BOOL is_target_mono,
+ const LLUUID& queue_id,
+ U8* script_data,
+ U32 data_size,
+ std::string script_name)
+{
+ UploadData data;
+ data.mTaskId = task_id;
+ data.mItemId = item_id;
+ data.mIsRunning = is_running;
+ data.mIsTargetMono = is_target_mono;
+ data.mQueueId = queue_id;
+ data.mFilename = filename;
+ data.mData = script_data;
+ data.mDataSize = data_size;
+ data.mScriptName = script_name;
+
+ mQueue.push_back(data);
+
+ if(mSupplier)
+ {
+ request(&mSupplier);
+ }
+}
+
+LLAssetUploadQueueSupplier::~LLAssetUploadQueueSupplier()
+{
+}
diff --git a/indra/newview/llassetuploadqueue.h b/indra/newview/llassetuploadqueue.h
new file mode 100644
index 0000000000..6e4caa1b0f
--- /dev/null
+++ b/indra/newview/llassetuploadqueue.h
@@ -0,0 +1,74 @@
+/**
+ * @file llassetuploadqueue.h
+ * @brief Serializes asset upload request
+ * Copyright (c) 2007, Linden Research, Inc.
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLASSETUPLOADQUEUE_H
+#define LL_LLASSETUPLOADQUEUE_H
+
+#include "lluuid.h"
+
+#include <string>
+#include <deque>
+
+class LLAssetUploadQueueSupplier;
+
+class LLAssetUploadQueue
+{
+public:
+
+ // Takes ownership of supplier.
+ LLAssetUploadQueue(LLAssetUploadQueueSupplier* supplier);
+ virtual ~LLAssetUploadQueue();
+
+ void queue(const std::string& filename,
+ const LLUUID& task_id,
+ const LLUUID& item_id,
+ BOOL is_running,
+ BOOL is_target_mono,
+ const LLUUID& queue_id,
+ U8* data,
+ U32 data_size,
+ std::string script_name);
+
+ bool isEmpty() const {return mQueue.empty();}
+
+private:
+
+ friend class LLAssetUploadChainResponder;
+
+ struct UploadData
+ {
+ std::string mFilename;
+ LLUUID mTaskId;
+ LLUUID mItemId;
+ BOOL mIsRunning;
+ BOOL mIsTargetMono;
+ LLUUID mQueueId;
+ U8* mData;
+ U32 mDataSize;
+ std::string mScriptName;
+ };
+
+ // Ownership of mSupplier passed to currently waiting responder
+ // and returned to queue when no requests in progress.
+ LLAssetUploadQueueSupplier* mSupplier;
+ std::deque<UploadData> mQueue;
+
+ // Passes on ownership of mSupplier if request is made.
+ void request(LLAssetUploadQueueSupplier** supplier);
+};
+
+class LLAssetUploadQueueSupplier
+{
+public:
+ virtual ~LLAssetUploadQueueSupplier();
+ virtual LLAssetUploadQueue* get() const = 0;
+ virtual void log(std::string message) const = 0;
+};
+
+#endif // LL_LLASSETUPLOADQUEUE_H
diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp
index 3d91384f48..962066471f 100644
--- a/indra/newview/llassetuploadresponders.cpp
+++ b/indra/newview/llassetuploadresponders.cpp
@@ -34,6 +34,7 @@
#include "llassetuploadresponders.h"
#include "llagent.h"
+#include "llcompilequeue.h"
#include "llfloaterbuycurrency.h"
#include "lleconomy.h"
#include "llfilepicker.h"
@@ -73,11 +74,12 @@ LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data,
}
LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data,
- const std::string& file_name)
+ const std::string& file_name,
+ LLAssetType::EType asset_type)
: LLHTTPClient::Responder(),
mPostData(post_data),
- mAssetType(LLAssetType::AT_NONE),
- mFileName(file_name)
+ mFileName(file_name),
+ mAssetType(asset_type)
{
}
@@ -182,8 +184,8 @@ LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLSD& post_data
{
}
-LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLSD& post_data, const std::string& file_name)
-: LLAssetUploadResponder(post_data, file_name)
+LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLSD& post_data, const std::string& file_name, LLAssetType::EType asset_type)
+: LLAssetUploadResponder(post_data, file_name, asset_type)
{
}
@@ -301,8 +303,9 @@ LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(const LLSD& pos
}
LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(const LLSD& post_data,
- const std::string& file_name)
-: LLAssetUploadResponder(post_data, file_name)
+ const std::string& file_name,
+ LLAssetType::EType asset_type)
+: LLAssetUploadResponder(post_data, file_name, asset_type)
{
}
@@ -410,8 +413,17 @@ LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_
}
LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data,
- const std::string& file_name)
-: LLAssetUploadResponder(post_data, file_name)
+ const std::string& file_name,
+ LLAssetType::EType asset_type)
+: LLAssetUploadResponder(post_data, file_name, asset_type)
+{
+}
+
+LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data,
+ const std::string& file_name,
+ const LLUUID& queue_id,
+ LLAssetType::EType asset_type)
+: LLAssetUploadResponder(post_data, file_name, asset_type), mQueueId(queue_id)
{
}
@@ -422,35 +434,16 @@ void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content)
LLUUID item_id = mPostData["item_id"];
LLUUID task_id = mPostData["task_id"];
- LLViewerObject* object = gObjectList.findObject(task_id);
- if (!object)
- {
- llwarns << "LLUpdateTaskInventoryResponder::uploadComplete task " << task_id
- << " no longer exist." << llendl;
- return;
- }
- LLViewerInventoryItem* item = (LLViewerInventoryItem*)object->getInventoryObject(item_id);
- if (!item)
- {
- llwarns << "LLUpdateTaskInventoryResponder::uploadComplete item "
- << item_id << " is no longer in task " << task_id
- << "'s inventory." << llendl;
- return;
- }
- LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
- // Update Viewer inventory
- object->updateViewerInventoryAsset(new_item, content["new_asset"]);
dialog_refresh_all();
- LLInventoryType::EType inventory_type = new_item->getInventoryType();
- switch(inventory_type)
+ switch(mAssetType)
{
- case LLInventoryType::IT_NOTECARD:
+ case LLAssetType::AT_NOTECARD:
{
// Update the UI with the new asset.
LLPreviewNotecard* nc;
- nc = (LLPreviewNotecard*)LLPreview::find(new_item->getUUID());
+ nc = (LLPreviewNotecard*)LLPreview::find(item_id);
if(nc)
{
// *HACK: we have to delete the asset in the VFS so
@@ -470,28 +463,39 @@ void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content)
}
}
break;
- case LLInventoryType::IT_LSL:
+ case LLAssetType::AT_LSL_TEXT:
{
- LLLiveLSLEditor* preview = LLLiveLSLEditor::find(item_id, task_id);
- if (preview)
+ if(mQueueId.notNull())
{
- // Bytecode save completed
- if (content["compiled"])
+ LLFloaterCompileQueue* queue =
+ (LLFloaterCompileQueue*) LLFloaterScriptQueue::findInstance(mQueueId);
+ if(NULL != queue)
{
- preview->callbackLSLCompileSucceeded(
- task_id,
- item_id,
- mPostData["is_script_running"]);
+ queue->removeItemByItemID(item_id);
}
- else
+ }
+ else
+ {
+ LLLiveLSLEditor* preview = LLLiveLSLEditor::find(item_id, task_id);
+ if (preview)
{
- preview->callbackLSLCompileFailed(content["errors"]);
+ // Bytecode save completed
+ if (content["compiled"])
+ {
+ preview->callbackLSLCompileSucceeded(
+ task_id,
+ item_id,
+ mPostData["is_script_running"]);
+ }
+ else
+ {
+ preview->callbackLSLCompileFailed(content["errors"]);
+ }
}
}
}
break;
- case LLInventoryType::IT_WEARABLE:
- default:
- break;
+ default:
+ break;
}
}
diff --git a/indra/newview/llassetuploadresponders.h b/indra/newview/llassetuploadresponders.h
index 25f3f4c3b1..dc4f6e7bf0 100644
--- a/indra/newview/llassetuploadresponders.h
+++ b/indra/newview/llassetuploadresponders.h
@@ -42,7 +42,9 @@ public:
LLAssetUploadResponder(const LLSD& post_data,
const LLUUID& vfile_id,
LLAssetType::EType asset_type);
- LLAssetUploadResponder(const LLSD& post_data, const std::string& file_name);
+ LLAssetUploadResponder(const LLSD& post_data,
+ const std::string& file_name,
+ LLAssetType::EType asset_type);
~LLAssetUploadResponder();
virtual void error(U32 statusNum, const std::string& reason);
virtual void result(const LLSD& content);
@@ -52,8 +54,8 @@ public:
protected:
LLSD mPostData;
- LLUUID mVFileID;
LLAssetType::EType mAssetType;
+ LLUUID mVFileID;
std::string mFileName;
};
@@ -63,7 +65,8 @@ public:
LLNewAgentInventoryResponder(const LLSD& post_data,
const LLUUID& vfile_id,
LLAssetType::EType asset_type);
- LLNewAgentInventoryResponder(const LLSD& post_data, const std::string& file_name);
+ LLNewAgentInventoryResponder(const LLSD& post_data, const std::string& file_name,
+ LLAssetType::EType asset_type);
virtual void uploadComplete(const LLSD& content);
};
@@ -74,7 +77,8 @@ public:
const LLUUID& vfile_id,
LLAssetType::EType asset_type);
LLUpdateAgentInventoryResponder(const LLSD& post_data,
- const std::string& file_name);
+ const std::string& file_name,
+ LLAssetType::EType asset_type);
virtual void uploadComplete(const LLSD& content);
};
@@ -85,8 +89,17 @@ public:
const LLUUID& vfile_id,
LLAssetType::EType asset_type);
LLUpdateTaskInventoryResponder(const LLSD& post_data,
- const std::string& file_name);
+ const std::string& file_name,
+ LLAssetType::EType asset_type);
+ LLUpdateTaskInventoryResponder(const LLSD& post_data,
+ const std::string& file_name,
+ const LLUUID& queue_id,
+ LLAssetType::EType asset_type);
+
virtual void uploadComplete(const LLSD& content);
+
+private:
+ LLUUID mQueueId;
};
#endif // LL_LLASSETUPLOADRESPONDER_H
diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp
index 3ab340f66a..30d5dc206f 100644
--- a/indra/newview/llcompilequeue.cpp
+++ b/indra/newview/llcompilequeue.cpp
@@ -42,6 +42,8 @@
#include "llcompilequeue.h"
#include "llagent.h"
+#include "llassetuploadqueue.h"
+#include "llassetuploadresponders.h"
#include "llchat.h"
#include "llviewerwindow.h"
#include "llviewerobject.h"
@@ -72,20 +74,15 @@ const std::string RUN_START_STRING("set running");
const std::string NOT_RUN_QUEUE_TITLE("Set Not Running Progress");
const std::string NOT_RUN_START_STRING("set not running");
-struct LLCompileQueueData
-{
- LLUUID mQueueID;
- LLUUID mOldAssetID;
- LLCompileQueueData(const LLUUID& q_id, const LLUUID& old_asset_id) :
- mQueueID(q_id), mOldAssetID(old_asset_id) {}
-};
-
struct LLScriptQueueData
{
LLUUID mQueueID;
std::string mScriptName;
- LLScriptQueueData(const LLUUID& q_id, const std::string& name) :
- mQueueID(q_id), mScriptName(name) {}
+ LLUUID mTaskId;
+ LLUUID mItemId;
+ LLScriptQueueData(const LLUUID& q_id, const std::string& name, const LLUUID& task_id, const LLUUID& item_id) :
+ mQueueID(q_id), mScriptName(name), mTaskId(task_id), mItemId(item_id) {}
+
};
///----------------------------------------------------------------------------
@@ -105,7 +102,8 @@ LLFloaterScriptQueue::LLFloaterScriptQueue(const std::string& name,
RESIZE_YES, DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT,
DRAG_ON_TOP, MINIMIZE_YES, CLOSE_YES)
{
-
+ mID.generate();
+
LLUICtrlFactory::getInstance()->buildFloater(this,"floater_script_queue.xml");
childSetAction("close",onCloseBtn,this);
@@ -113,11 +111,8 @@ LLFloaterScriptQueue::LLFloaterScriptQueue(const std::string& name,
setTitle(title);
- if (!getHost())
- {
- LLRect curRect = getRect();
- translate(rect.mLeft - curRect.mLeft, rect.mTop - curRect.mTop);
- }
+ LLRect curRect = getRect();
+ translate(rect.mLeft - curRect.mLeft, rect.mTop - curRect.mTop);
mStartString = start_string;
mDone = FALSE;
@@ -279,14 +274,57 @@ BOOL LLFloaterScriptQueue::popNext()
///----------------------------------------------------------------------------
// static
-LLFloaterCompileQueue* LLFloaterCompileQueue::create()
+LLFloaterCompileQueue* LLFloaterCompileQueue::create(BOOL mono)
{
S32 left, top;
gFloaterView->getNewFloaterPosition(&left, &top);
LLRect rect = gSavedSettings.getRect("CompileOutputRect");
rect.translate(left - rect.mLeft, top - rect.mTop);
LLFloaterCompileQueue* new_queue = new LLFloaterCompileQueue("queue", rect);
- new_queue->open(); /*Flawfinder: ignore*/
+
+ class LLCompileFloaterUploadQueueSupplier : public LLAssetUploadQueueSupplier
+ {
+ public:
+
+ LLCompileFloaterUploadQueueSupplier(const LLUUID& queue_id) :
+ mQueueId(queue_id)
+ {
+ }
+
+ virtual LLAssetUploadQueue* get() const
+ {
+ LLFloaterCompileQueue* queue =
+ (LLFloaterCompileQueue*) LLFloaterScriptQueue::findInstance(mQueueId);
+
+ if(NULL == queue)
+ {
+ return NULL;
+ }
+
+ return queue->mUploadQueue;
+ }
+
+ virtual void log(std::string message) const
+ {
+ LLFloaterCompileQueue* queue =
+ (LLFloaterCompileQueue*) LLFloaterScriptQueue::findInstance(mQueueId);
+
+ if(NULL == queue)
+ {
+ return;
+ }
+
+ LLScrollListCtrl* list = queue->getChild<LLScrollListCtrl>("queue output");
+ list->addCommentText(message.c_str());
+ }
+
+ private:
+ LLUUID mQueueId;
+ };
+
+ new_queue->mUploadQueue = new LLAssetUploadQueue(new LLCompileFloaterUploadQueueSupplier(new_queue->getID()));
+ new_queue->mMono = mono;
+ new_queue->open();
return new_queue;
}
@@ -304,7 +342,7 @@ void LLFloaterCompileQueue::handleInventory(LLViewerObject *viewer_object,
// find all of the lsl, leaving off duplicates. We'll remove
// all matching asset uuids on compilation success.
- typedef std::map<LLUUID, LLPointer<LLInventoryItem> > uuid_item_map;
+ typedef std::multimap<LLUUID, LLPointer<LLInventoryItem> > uuid_item_map;
uuid_item_map asset_item_map;
InventoryObjectList::const_iterator it = inv->begin();
@@ -315,17 +353,12 @@ void LLFloaterCompileQueue::handleInventory(LLViewerObject *viewer_object,
{
LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it));
// Check permissions before allowing the user to retrieve data.
- if (item->getPermissions().allowModifyBy(gAgent.getID()) &&
- item->getPermissions().allowCopyBy(gAgent.getID()) )
+ if (item->getPermissions().allowModifyBy(gAgent.getID(), gAgent.getGroupID()) &&
+ item->getPermissions().allowCopyBy(gAgent.getID(), gAgent.getGroupID()) )
{
LLPointer<LLViewerInventoryItem> script = new LLViewerInventoryItem(item);
mCurrentScripts.put(script);
-
- if (!asset_item_map.count(item->getAssetUUID()))
- {
- // No entry, put in an entry for this supposedly permissive script
- asset_item_map[item->getAssetUUID()] = item;
- }
+ asset_item_map.insert(std::make_pair(item->getAssetUUID(), item));
}
}
}
@@ -342,7 +375,10 @@ void LLFloaterCompileQueue::handleInventory(LLViewerObject *viewer_object,
for(iter = asset_item_map.begin(); iter != asset_item_map.end(); iter++)
{
LLInventoryItem *itemp = iter->second;
- LLScriptQueueData* datap = new LLScriptQueueData(getID(), itemp->getName());
+ LLScriptQueueData* datap = new LLScriptQueueData(getID(),
+ itemp->getName(),
+ viewer_object->getID(),
+ itemp->getUUID());
//llinfos << "ITEM NAME 2: " << names.get(i) << llendl;
gAssetStorage->getInvItemAsset(viewer_object->getRegion()->getHost(),
@@ -359,7 +395,6 @@ void LLFloaterCompileQueue::handleInventory(LLViewerObject *viewer_object,
}
}
-
// This is the callback for when each script arrives
// static
void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id,
@@ -382,31 +417,58 @@ void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id,
std::string uuid_str;
asset_id.toString(uuid_str);
filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str) + llformat(".%s",LLAssetType::lookup(type));
-
- LLFILE *fp = LLFile::fopen(filename, "wb"); /*Flawfinder: ignore*/
- if (fp)
+
+ const bool is_running = true;
+ LLViewerObject* object = gObjectList.findObject(data->mTaskId);
+ if (object)
{
- const S32 buf_size = 65536;
- U8 copy_buf[buf_size];
- while (file.read(copy_buf, buf_size)) /*Flawfinder: ignore*/
+ std::string url = object->getRegion()->getCapability("UpdateScriptTaskInventory");
+ if(!url.empty())
+ {
+ // Read script source in to buffer.
+ U32 script_size = file.getSize();
+ U8* script_data = new U8[script_size];
+ file.read(script_data, script_size);
+
+ queue->mUploadQueue->queue(filename, data->mTaskId,
+ data->mItemId, is_running, queue->mMono, queue->getID(),
+ script_data, script_size, data->mScriptName);
+ }
+ else
{
- if (fwrite(copy_buf, file.getLastBytesRead(), 1, fp) < 1)
+ // It's now in the file, now compile it.
+ buffer = std::string("Downloaded, now compiling: ") + data->mScriptName; // *TODO: Translate
+
+ // Write script to local file for compilation.
+ LLFILE *fp = LLFile::fopen(filename, "wb"); /*Flawfinder: ignore*/
+ if (fp)
{
- // return a bad file error if we can't write the whole thing
- status = LL_ERR_CANNOT_OPEN_FILE;
+ const S32 buf_size = 65536;
+ U8 copy_buf[buf_size];
+
+ while (file.read(copy_buf, buf_size)) /*Flawfinder: ignore*/
+ {
+ if (fwrite(copy_buf, file.getLastBytesRead(), 1, fp) < 1)
+ {
+ // return a bad file error if we can't write the whole thing
+ status = LL_ERR_CANNOT_OPEN_FILE;
+ }
+ }
+
+ fclose(fp);
+ }
+ else
+ {
+ llerrs << "Unable to find object to compile" << llendl;
}
- }
- fclose(fp);
+ // TODO: babbage: No compile if no cap.
+ queue->compile(filename, data->mItemId);
+
+ // Delete it after we're done compiling?
+ LLFile::remove(filename);
+ }
}
-
- // *TODO: translate
- // It's now in the file, now compile it.
- buffer = std::string("Downloaded, now compiling: ") + data->mScriptName; // *TODO: Translate
- queue->compile(filename, asset_id);
-
- // Delete it after we're done compiling?
- LLFile::remove(filename);
}
else
{
@@ -430,9 +492,9 @@ void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id,
}
llwarns << "Problem downloading script asset." << llendl;
- if(queue) queue->removeItemByAssetID(asset_id);
+ if(queue) queue->removeItemByItemID(data->mItemId);
}
- if(queue)
+ if(queue && (buffer.size() > 0))
{
LLScrollListCtrl* list = queue->getChild<LLScrollListCtrl>("queue output");
list->addCommentText(buffer);
@@ -462,9 +524,8 @@ void LLFloaterCompileQueue::onSaveBytecodeComplete(const LLUUID& asset_id, void*
(LLFloaterScriptQueue::findInstance(data->mQueueID));
if(queue && (0 == status) && data)
{
- queue->updateAssetID(data->mOldAssetID, asset_id);
- queue->saveItemByAssetID(asset_id);
- queue->removeItemByAssetID(asset_id);
+ queue->saveItemByItemID(data->mItemId);
+ queue->removeItemByItemID(data->mItemId);
}
else
{
@@ -479,7 +540,7 @@ void LLFloaterCompileQueue::onSaveBytecodeComplete(const LLUUID& asset_id, void*
// compile the file given and save it out.
void LLFloaterCompileQueue::compile(const std::string& filename,
- const LLUUID& asset_id)
+ const LLUUID& item_id)
{
LLUUID new_asset_id;
LLTransactionID tid;
@@ -496,29 +557,34 @@ void LLFloaterCompileQueue::compile(const std::string& filename,
gAssetStorage->storeAssetData(filename, tid,
LLAssetType::AT_LSL_TEXT,
&onSaveTextComplete, NULL, FALSE);
- if(!lscript_compile(filename.c_str(), dst_filename.c_str(), err_filename.c_str(), gAgent.isGodlike()))
+
+ const BOOL compile_to_mono = FALSE;
+ if(!lscript_compile(filename.c_str(), dst_filename.c_str(),
+ err_filename.c_str(), compile_to_mono,
+ uuid_string.c_str(), gAgent.isGodlike()))
{
llwarns << "compile failed" << llendl;
- removeItemByAssetID(asset_id);
+ removeItemByItemID(item_id);
}
else
{
llinfos << "compile successful." << llendl;
- // Save the bytecode
- LLCompileQueueData* data = new LLCompileQueueData(mID, asset_id);
- gAssetStorage->storeAssetData(dst_filename, tid,
- LLAssetType::AT_LSL_BYTECODE,
- &onSaveBytecodeComplete,
- (void*)data, FALSE);
+
+ // Save LSL bytecode
+ LLCompileQueueData* data = new LLCompileQueueData(mID, item_id);
+ gAssetStorage->storeAssetData(dst_filename, new_asset_id,
+ LLAssetType::AT_LSL_BYTECODE,
+ &LLFloaterCompileQueue::onSaveBytecodeComplete,
+ (void*)data, FALSE);
}
}
-void LLFloaterCompileQueue::removeItemByAssetID(const LLUUID& asset_id)
+void LLFloaterCompileQueue::removeItemByItemID(const LLUUID& asset_id)
{
llinfos << "LLFloaterCompileQueue::removeItemByAssetID()" << llendl;
for(S32 i = 0; i < mCurrentScripts.count(); )
{
- if(asset_id == mCurrentScripts.get(i)->getAssetUUID())
+ if(asset_id == mCurrentScripts.get(i)->getUUID())
{
mCurrentScripts.remove(i);
}
@@ -533,7 +599,21 @@ void LLFloaterCompileQueue::removeItemByAssetID(const LLUUID& asset_id)
}
}
-void LLFloaterCompileQueue::saveItemByAssetID(const LLUUID& asset_id)
+const LLInventoryItem* LLFloaterCompileQueue::findItemByItemID(const LLUUID& asset_id) const
+{
+ LLInventoryItem* result = NULL;
+ S32 count = mCurrentScripts.count();
+ for(S32 i = 0; i < count; ++i)
+ {
+ if(asset_id == mCurrentScripts.get(i)->getUUID())
+ {
+ result = mCurrentScripts.get(i);
+ }
+ }
+ return result;
+}
+
+void LLFloaterCompileQueue::saveItemByItemID(const LLUUID& asset_id)
{
llinfos << "LLFloaterCompileQueue::saveItemByAssetID()" << llendl;
LLViewerObject* viewer_object = gObjectList.findObject(mCurrentObjectID);
@@ -542,7 +622,7 @@ void LLFloaterCompileQueue::saveItemByAssetID(const LLUUID& asset_id)
S32 count = mCurrentScripts.count();
for(S32 i = 0; i < count; ++i)
{
- if(asset_id == mCurrentScripts.get(i)->getAssetUUID())
+ if(asset_id == mCurrentScripts.get(i)->getUUID())
{
// *FIX: this auto-resets active to TRUE. That might
// be a bad idea.
@@ -556,20 +636,6 @@ void LLFloaterCompileQueue::saveItemByAssetID(const LLUUID& asset_id)
}
}
-// find old_asst_id, and set the asset id to new_asset_id
-void LLFloaterCompileQueue::updateAssetID(const LLUUID& old_asset_id,
- const LLUUID& new_asset_id)
-{
- S32 count = mCurrentScripts.count();
- for(S32 i = 0; i < count; ++i)
- {
- if(old_asset_id == mCurrentScripts.get(i)->getAssetUUID())
- {
- mCurrentScripts.get(i)->setAssetUUID(new_asset_id);
- }
- }
-}
-
///----------------------------------------------------------------------------
/// Class LLFloaterResetQueue
///----------------------------------------------------------------------------
@@ -582,7 +648,8 @@ LLFloaterResetQueue* LLFloaterResetQueue::create()
LLRect rect = gSavedSettings.getRect("CompileOutputRect");
rect.translate(left - rect.mLeft, top - rect.mTop);
LLFloaterResetQueue* new_queue = new LLFloaterResetQueue("queue", rect);
- new_queue->open(); /*Flawfinder: ignore*/
+ gFloaterView->addChild(new_queue);
+ new_queue->open();
return new_queue;
}
diff --git a/indra/newview/llcompilequeue.h b/indra/newview/llcompilequeue.h
index be7bbd5ceb..68e9a27266 100644
--- a/indra/newview/llcompilequeue.h
+++ b/indra/newview/llcompilequeue.h
@@ -64,6 +64,9 @@ public:
// start() returns TRUE if the queue has started, otherwise FALSE.
BOOL start();
+ // find an instance by ID. Return NULL if it does not exist.
+ static LLFloaterScriptQueue* findInstance(const LLUUID& id);
+
protected:
LLFloaterScriptQueue(const std::string& name, const LLRect& rect,
const std::string& title, const std::string& start_string);
@@ -92,9 +95,6 @@ protected:
// Get this instances ID.
const LLUUID& getID() const { return mID; }
-
- // find an instance by ID. Return NULL if it does not exist.
- static LLFloaterScriptQueue* findInstance(const LLUUID& id);
protected:
// UI
@@ -118,12 +118,29 @@ protected:
// This script queue will recompile each script.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+struct LLCompileQueueData
+{
+ LLUUID mQueueID;
+ LLUUID mItemId;
+ LLCompileQueueData(const LLUUID& q_id, const LLUUID& item_id) :
+ mQueueID(q_id), mItemId(item_id) {}
+};
+
+class LLAssetUploadQueue;
+
class LLFloaterCompileQueue : public LLFloaterScriptQueue
{
public:
// Use this method to create a compile queue. Once created, it
// will be responsible for it's own destruction.
- static LLFloaterCompileQueue* create();
+ static LLFloaterCompileQueue* create(BOOL mono);
+
+ static void onSaveBytecodeComplete(const LLUUID& asset_id,
+ void* user_data,
+ S32 status);
+
+ // remove any object in mScriptScripts with the matching uuid.
+ void removeItemByItemID(const LLUUID& item_id);
protected:
LLFloaterCompileQueue(const std::string& name, const LLRect& rect);
@@ -139,6 +156,7 @@ protected:
void* user_data, S32 status, LLExtStat ext_status);
static void onSaveTextComplete(const LLUUID& asset_id, void* user_data, S32 status, LLExtStat ext_status);
+
static void onSaveBytecodeComplete(const LLUUID& asset_id,
void* user_data,
S32 status, LLExtStat ext_status);
@@ -149,14 +167,18 @@ protected:
// remove any object in mScriptScripts with the matching uuid.
void removeItemByAssetID(const LLUUID& asset_id);
- // save the items indicatd by the asset id.
- void saveItemByAssetID(const LLUUID& asset_id);
+ // save the items indicated by the item id.
+ void saveItemByItemID(const LLUUID& item_id);
- // find old_asst_id, and set the asset id to new_asset_id
- void updateAssetID(const LLUUID& old_asset_id, const LLUUID& new_asset_id);
+ // find InventoryItem given item id.
+ const LLInventoryItem* findItemByItemID(const LLUUID& item_id) const;
protected:
LLViewerInventoryItem::item_array_t mCurrentScripts;
+
+private:
+ BOOL mMono; // Compile to mono.
+ LLAssetUploadQueue* mUploadQueue;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp
index 3c1b89d04b..2d0723f1eb 100644
--- a/indra/newview/llfloatertopobjects.cpp
+++ b/indra/newview/llfloatertopobjects.cpp
@@ -170,6 +170,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
F32 score;
std::string name_buf;
std::string owner_buf;
+ F32 mono_score;
msg->getU32Fast(_PREHASH_ReportData, _PREHASH_TaskLocalID, task_local_id, block);
msg->getUUIDFast(_PREHASH_ReportData, _PREHASH_TaskID, task_id, block);
@@ -192,6 +193,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
element["columns"][0]["column"] = "score";
element["columns"][0]["value"] = llformat("%0.3f", score);
element["columns"][0]["font"] = "SANSSERIF";
+
element["columns"][1]["column"] = "name";
element["columns"][1]["value"] = name_buf;
element["columns"][1]["font"] = "SANSSERIF";
@@ -205,6 +207,14 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
element["columns"][3]["value"] = formatted_time((time_t)time_stamp);
element["columns"][3]["font"] = "SANSSERIF";
+ if (mCurrentMode == STAT_REPORT_TOP_SCRIPTS)
+ {
+ msg->getF32Fast(_PREHASH_ReportData, "MonoScore", mono_score, block);
+ element["columns"][4]["column"] = "Mono Time";
+ element["columns"][4]["value"] = llformat("%0.3f", mono_score);
+ element["columns"][4]["font"] = "SANSSERIF";
+ }
+
list->addElement(element);
mObjectListData.append(element);
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 75e8f52cfc..71733e5cd7 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -139,6 +139,12 @@ const S32 TEXT_EDIT_COLUMN_HEIGHT = 16;
const S32 MAX_HISTORY_COUNT = 10;
const F32 LIVE_HELP_REFRESH_TIME = 1.f;
+static bool have_script_upload_cap(LLUUID& object_id)
+{
+ LLViewerObject* object = gObjectList.findObject(object_id);
+ return object && (! object->getRegion()->getCapability("UpdateScriptTaskInventory").empty());
+}
+
/// ---------------------------------------------------------------------------
/// LLFloaterScriptSearch
/// ---------------------------------------------------------------------------
@@ -173,7 +179,7 @@ private:
LLFloaterScriptSearch* LLFloaterScriptSearch::sInstance = NULL;
LLFloaterScriptSearch::LLFloaterScriptSearch(std::string title, LLRect rect, LLScriptEdCore* editor_core)
- : LLFloater(std::string("script search"),rect,title), mEditorCore(editor_core)
+ : LLFloater("script search",rect,title), mEditorCore(editor_core)
{
LLUICtrlFactory::getInstance()->buildFloater(this,"floater_script_search.xml");
@@ -306,14 +312,15 @@ LLScriptEdCore::LLScriptEdCore(
mUserdata( userdata ),
mForceClose( FALSE ),
mLastHelpToken(NULL),
- mLiveHelpHistorySize(0)
+ mLiveHelpHistorySize(0),
+ mEnableSave(FALSE)
{
setFollowsAll();
setBorderVisible(FALSE);
LLUICtrlFactory::getInstance()->buildPanel(this, "floater_script_ed_panel.xml");
-
+
mErrorList = getChild<LLScrollListCtrl>("lsl errors");
mFunctions = getChild<LLComboBox>( "Insert...");
@@ -439,13 +446,13 @@ BOOL LLScriptEdCore::hasChanged(void* userdata)
LLScriptEdCore* self = (LLScriptEdCore*)userdata;
if (!self || !self->mEditor) return FALSE;
- return !self->mEditor->isPristine();
+ return !self->mEditor->isPristine() || self->mEnableSave;
}
void LLScriptEdCore::draw()
{
- BOOL script_changed = !mEditor->isPristine();
- childSetEnabled("Save_btn", script_changed);
+ BOOL script_changed = hasChanged(this);
+ childSetEnabled("Save_btn", script_changed);
if( mEditor->hasFocus() )
{
@@ -594,7 +601,7 @@ void LLScriptEdCore::addHelpItemToHistory(const std::string& help_string)
BOOL LLScriptEdCore::canClose()
{
- if(mForceClose || mEditor->isPristine())
+ if(mForceClose || !hasChanged(this))
{
return TRUE;
}
@@ -1133,7 +1140,9 @@ void LLPreviewLSL::callbackLSLCompileFailed(const LLSD& compile_errors)
line++)
{
LLSD row;
- row["columns"][0]["value"] = line->asString();
+ std::string error_message = line->asString();
+ LLStringUtil::stripNonprintable(error_message);
+ row["columns"][0]["value"] = error_message;
row["columns"][0]["font"] = "OCRA";
mScriptEd->mErrorList->addElement(row);
}
@@ -1247,7 +1256,7 @@ void LLPreviewLSL::onSave(void* userdata, BOOL close_after_save)
void LLPreviewLSL::saveIfNeeded()
{
// llinfos << "LLPreviewLSL::saveIfNeeded()" << llendl;
- if(mScriptEd->mEditor->isPristine())
+ if(!LLScriptEdCore::hasChanged(mScriptEd))
{
return;
}
@@ -1305,7 +1314,8 @@ void LLPreviewLSL::uploadAssetViaCaps(const std::string& url,
llinfos << "Update Agent Inventory via capability" << llendl;
LLSD body;
body["item_id"] = item_id;
- LLHTTPClient::post(url, body, new LLUpdateAgentInventoryResponder(body, filename));
+ body["target"] = "lsl2";
+ LLHTTPClient::post(url, body, new LLUpdateAgentInventoryResponder(body, filename, LLAssetType::AT_LSL_TEXT));
}
void LLPreviewLSL::uploadAssetLegacy(const std::string& filename,
@@ -1326,9 +1336,12 @@ void LLPreviewLSL::uploadAssetLegacy(const std::string& filename,
std::string dst_filename = llformat("%s.lso", filepath.c_str());
std::string err_filename = llformat("%s.out", filepath.c_str());
+ const BOOL compile_to_mono = FALSE;
if(!lscript_compile(filename.c_str(),
dst_filename.c_str(),
err_filename.c_str(),
+ compile_to_mono,
+ asset_id.asString().c_str(),
gAgent.isGodlike()))
{
llinfos << "Compile failed!" << llendl;
@@ -1601,7 +1614,8 @@ LLLiveLSLEditor::LLLiveLSLEditor(const std::string& name,
mAskedForRunningInfo(FALSE),
mHaveRunningInfo(FALSE),
mCloseAfterSave(FALSE),
- mPendingUploads(0)
+ mPendingUploads(0),
+ mIsModifiable(FALSE)
{
@@ -1615,13 +1629,14 @@ LLLiveLSLEditor::LLLiveLSLEditor(const std::string& name,
LLLiveLSLEditor::sInstances.addData(mItemID ^ mObjectID, this);
-
-
LLCallbackMap::map_t factory_map;
factory_map["script ed panel"] = LLCallbackMap(LLLiveLSLEditor::createScriptEdPanel, this);
LLUICtrlFactory::getInstance()->buildFloater(this,"floater_live_lsleditor.xml", &factory_map);
-
+
+ mMonoCheckbox = getChild<LLCheckBoxCtrl>("mono");
+ childSetCommitCallback("mono", &LLLiveLSLEditor::onMonoCheckboxClicked, this);
+ childSetEnabled("mono", FALSE);
childSetCommitCallback("running", LLLiveLSLEditor::onRunningCheckboxClicked, this);
childSetEnabled("running", FALSE);
@@ -1633,7 +1648,6 @@ LLLiveLSLEditor::LLLiveLSLEditor(const std::string& name,
mScriptEd->mEditor->makePristine();
loadAsset(is_new);
mScriptEd->mEditor->setFocus(TRUE);
-
if (!getHost())
{
@@ -1677,7 +1691,9 @@ void LLLiveLSLEditor::callbackLSLCompileFailed(const LLSD& compile_errors)
line++)
{
LLSD row;
- row["columns"][0]["value"] = line->asString();
+ std::string error_message = line->asString();
+ LLStringUtil::stripNonprintable(error_message);
+ row["columns"][0]["value"] = error_message;
row["columns"][0]["font"] = "OCRA";
mScriptEd->mErrorList->addElement(row);
}
@@ -1712,6 +1728,7 @@ void LLLiveLSLEditor::loadAsset(BOOL is_new)
mScriptEd->mEditor->setText(getString("not_allowed"));
mScriptEd->mEditor->makePristine();
mScriptEd->mEditor->setEnabled(FALSE);
+ mScriptEd->enableSave(FALSE);
mAssetStatus = PREVIEW_ASSET_LOADED;
}
else if(item && mItem.notNull())
@@ -1745,12 +1762,14 @@ void LLLiveLSLEditor::loadAsset(BOOL is_new)
mAssetStatus = PREVIEW_ASSET_LOADED;
}
- if(item
- && !gAgent.allowOperation(PERM_MODIFY, item->getPermissions(),
- GP_OBJECT_MANIPULATE))
+ mIsModifiable = item && gAgent.allowOperation(PERM_MODIFY,
+ item->getPermissions(),
+ GP_OBJECT_MANIPULATE);
+ if(!mIsModifiable)
{
mScriptEd->mEditor->setEnabled(FALSE);
}
+
// This is commented out, because we don't completely
// handle script exports yet.
/*
@@ -1784,8 +1803,7 @@ void LLLiveLSLEditor::loadAsset(BOOL is_new)
else
{
mScriptEd->mEditor->setText(std::string(HELLO_LSL));
- //mScriptEd->mEditor->setText(LLStringUtil::null);
- //mScriptEd->mEditor->makePristine();
+ mScriptEd->enableSave(FALSE);
LLPermissions perm;
perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, gAgent.getGroupID());
perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, PERM_MOVE | PERM_TRANSFER);
@@ -1955,22 +1973,43 @@ void LLLiveLSLEditor::draw()
{
LLViewerObject* object = gObjectList.findObject(mObjectID);
LLCheckBoxCtrl* runningCheckbox = getChild<LLCheckBoxCtrl>( "running");
- if(object && mAskedForRunningInfo && mHaveRunningInfo)
+ if(object && mAskedForRunningInfo && mHaveRunningInfo)
{
if(object->permAnyOwner())
{
runningCheckbox->setLabel(getString("script_running"));
runningCheckbox->setEnabled(TRUE);
+
+ if(object->permAnyOwner())
+ {
+ runningCheckbox->setLabel(getString("script_running"));
+ runningCheckbox->setEnabled(TRUE);
+ }
+ else
+ {
+ runningCheckbox->setLabel(getString("public_objects_can_not_run"));
+ runningCheckbox->setEnabled(FALSE);
+ // *FIX: Set it to false so that the ui is correct for
+ // a box that is released to public. It could be
+ // incorrect after a release/claim cycle, but will be
+ // correct after clicking on it.
+ runningCheckbox->set(FALSE);
+ mMonoCheckbox->set(FALSE);
+ }
}
else
{
runningCheckbox->setLabel(getString("public_objects_can_not_run"));
runningCheckbox->setEnabled(FALSE);
+
// *FIX: Set it to false so that the ui is correct for
// a box that is released to public. It could be
// incorrect after a release/claim cycle, but will be
// correct after clicking on it.
runningCheckbox->set(FALSE);
+ mMonoCheckbox->setEnabled(FALSE);
+ // object may have fallen out of range.
+ mHaveRunningInfo = FALSE;
}
}
else if(!object)
@@ -2044,7 +2083,7 @@ void LLLiveLSLEditor::saveIfNeeded()
}
// Don't need to save if we're pristine
- if(mScriptEd->mEditor->isPristine())
+ if(!LLScriptEdCore::hasChanged(mScriptEd))
{
return;
}
@@ -2052,6 +2091,7 @@ void LLLiveLSLEditor::saveIfNeeded()
mPendingUploads = 0;
// save the script
+ mScriptEd->enableSave(FALSE);
mScriptEd->mEditor->makePristine();
mScriptEd->mErrorList->deleteAllItems();
@@ -2091,7 +2131,7 @@ void LLLiveLSLEditor::saveIfNeeded()
fp = NULL;
// save it out to asset server
- std::string url = gAgent.getRegion()->getCapability("UpdateScriptTaskInventory");
+ std::string url = object->getRegion()->getCapability("UpdateScriptTaskInventory");
getWindow()->incBusyCount();
mPendingUploads++;
BOOL is_running = getChild<LLCheckBoxCtrl>( "running")->get();
@@ -2117,8 +2157,9 @@ void LLLiveLSLEditor::uploadAssetViaCaps(const std::string& url,
body["task_id"] = task_id;
body["item_id"] = item_id;
body["is_script_running"] = is_running;
+ body["target"] = monoChecked() ? "mono" : "lsl2";
LLHTTPClient::post(url, body,
- new LLUpdateTaskInventoryResponder(body, filename));
+ new LLUpdateTaskInventoryResponder(body, filename, LLAssetType::AT_LSL_TEXT));
}
void LLLiveLSLEditor::uploadAssetLegacy(const std::string& filename,
@@ -2141,9 +2182,12 @@ void LLLiveLSLEditor::uploadAssetLegacy(const std::string& filename,
std::string err_filename = llformat("%s.out", filepath.c_str());
LLFILE *fp;
+ const BOOL compile_to_mono = FALSE;
if(!lscript_compile(filename.c_str(),
dst_filename.c_str(),
err_filename.c_str(),
+ compile_to_mono,
+ asset_id.asString().c_str(),
gAgent.isGodlike()))
{
// load the error file into the error scrolllist
@@ -2384,6 +2428,11 @@ void LLLiveLSLEditor::processScriptRunningReply(LLMessageSystem* msg, void**)
msg->getBOOLFast(_PREHASH_Script, _PREHASH_Running, running);
LLCheckBoxCtrl* runningCheckbox = instance->getChild<LLCheckBoxCtrl>("running");
runningCheckbox->set(running);
+ BOOL mono;
+ msg->getBOOLFast(_PREHASH_Script, "Mono", mono);
+ LLCheckBoxCtrl* monoCheckbox = instance->getChild<LLCheckBoxCtrl>("mono");
+ monoCheckbox->setEnabled(instance->getIsModifiable() && have_script_upload_cap(object_id));
+ monoCheckbox->set(mono);
}
}
@@ -2398,3 +2447,19 @@ void LLLiveLSLEditor::reshape(S32 width, S32 height, BOOL called_from_parent)
gSavedSettings.setRect("PreviewScriptRect", getRect());
}
}
+
+void LLLiveLSLEditor::onMonoCheckboxClicked(LLUICtrl*, void* userdata)
+{
+ LLLiveLSLEditor* self = static_cast<LLLiveLSLEditor*>(userdata);
+ self->mMonoCheckbox->setEnabled(have_script_upload_cap(self->mObjectID));
+ self->mScriptEd->enableSave(self->getIsModifiable());
+}
+
+BOOL LLLiveLSLEditor::monoChecked() const
+{
+ if(NULL != mMonoCheckbox)
+ {
+ return mMonoCheckbox->getValue()? TRUE : FALSE;
+ }
+ return FALSE;
+}
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index aec4bb2ab7..ca1c527cb2 100644
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -118,13 +118,14 @@ public:
void selectFirstError();
virtual BOOL handleKeyHere(KEY key, MASK mask);
+
+ void enableSave(BOOL b) {mEnableSave = b;}
protected:
void deleteBridges();
void setHelpPage(const std::string& help_string);
void updateDynamicHelp(BOOL immediate = FALSE);
void addHelpItemToHistory(const std::string& help_string);
-
static void onErrorList(LLUICtrl*, void* user_data);
virtual const char *getTitleName() const { return "Script"; }
@@ -147,6 +148,7 @@ private:
LLKeywordToken* mLastHelpToken;
LLFrameTimer mLiveHelpTimer;
S32 mLiveHelpHistorySize;
+ BOOL mEnableSave;
};
@@ -184,8 +186,9 @@ protected:
void* user_data, S32 status, LLExtStat ext_status);
static void onSaveComplete(const LLUUID& uuid, void* user_data, S32 status, LLExtStat ext_status);
static void onSaveBytecodeComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status);
+public:
static LLPreviewLSL* getInstance(const LLUUID& uuid);
-
+protected:
static void* createScriptEdPanel(void* userdata);
@@ -195,6 +198,7 @@ protected:
LLScriptEdCore* mScriptEd;
// Can safely close only after both text and bytecode are uploaded
S32 mPendingUploads;
+
};
@@ -277,6 +281,15 @@ protected:
S32 mPendingUploads;
static LLMap<LLUUID, LLLiveLSLEditor*> sInstances;
+ BOOL getIsModifiable() const { return mIsModifiable; } // Evaluated on load assert
+
+private:
+
+ static void onMonoCheckboxClicked(LLUICtrl*, void* userdata);
+ BOOL monoChecked() const;
+
+ LLCheckBoxCtrl* mMonoCheckbox;
+ BOOL mIsModifiable;
};
#endif // LL_LLPREVIEWSCRIPT_H
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index e37de3b2de..d24c738f2c 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -3381,13 +3381,13 @@ void init_stat_view()
stat_barp->mDisplayBar = FALSE;
stat_barp->mDisplayMean = FALSE;
- stat_barp = sim_statviewp->addStat("Script Perf", &(LLViewerStats::getInstance()->mSimLSLIPS));
- stat_barp->setUnitLabel(" ips");
+ stat_barp = sim_statviewp->addStat("Script Events", &(LLViewerStats::getInstance()->mSimScriptEPS));
+ stat_barp->setUnitLabel(" eps");
stat_barp->mPrecision = 0;
stat_barp->mMinBar = 0.f;
- stat_barp->mMaxBar = 100000.f;
- stat_barp->mTickSpacing = 25000.f;
- stat_barp->mLabelSpacing = 50000.f;
+ stat_barp->mMaxBar = 20000.f;
+ stat_barp->mTickSpacing = 2500.f;
+ stat_barp->mLabelSpacing = 5000.f;
stat_barp->mPerSec = FALSE;
stat_barp->mDisplayBar = FALSE;
stat_barp->mDisplayMean = FALSE;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index a095c9e159..771a71c5c5 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -6160,9 +6160,13 @@ class LLToolsSelectedScriptAction : public view_listener_t
{
std::string action = userdata.asString();
LLFloaterScriptQueue* queue = NULL;
- if (action == "compile")
+ if (action == "compile mono")
{
- queue = LLFloaterCompileQueue::create();
+ queue = LLFloaterCompileQueue::create(TRUE);
+ }
+ if (action == "compile lsl")
+ {
+ queue = LLFloaterCompileQueue::create(FALSE);
}
else if (action == "reset")
{
@@ -6405,16 +6409,36 @@ BOOL enable_more_than_one_selected(void* )
return (LLSelectMgr::getInstance()->getSelection()->getObjectCount() > 1);
}
+static bool is_editable_selected()
+{
+ return (LLSelectMgr::getInstance()->getSelection()->getFirstEditableObject() != NULL);
+}
+
class LLEditableSelected : public view_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
- bool new_value = (LLSelectMgr::getInstance()->getSelection()->getFirstEditableObject() != NULL);
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
+ gMenuHolder->findControl(userdata["control"].asString())->setValue(is_editable_selected());
return true;
}
};
+class LLEditableSelectedMono : public view_listener_t
+{
+ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ {
+ LLViewerRegion* region = gAgent.getRegion();
+ if(region && gMenuHolder && gMenuHolder->findControl(userdata["control"].asString()))
+ {
+ bool have_cap = (! region->getCapability("UpdateScriptTaskInventory").empty());
+ bool selected = is_editable_selected() && have_cap;
+ gMenuHolder->findControl(userdata["control"].asString())->setValue(selected);
+ return true;
+ }
+ return false;
+ }
+};
+
class LLToolsEnableTakeCopy : public view_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
@@ -7842,4 +7866,5 @@ void initialize_menus()
addMenu(new LLSomethingSelected(), "SomethingSelected");
addMenu(new LLSomethingSelectedNoHUD(), "SomethingSelectedNoHUD");
addMenu(new LLEditableSelected(), "EditableSelected");
+ addMenu(new LLEditableSelectedMono(), "EditableSelectedMono");
}
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index a082d6f1b5..d440491661 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -3464,8 +3464,8 @@ void process_sim_stats(LLMessageSystem *msg, void **user_data)
case LL_SIM_STAT_NUMSCRIPTSACTIVE:
LLViewerStats::getInstance()->mSimActiveScripts.addValue(stat_value);
break;
- case LL_SIM_STAT_LSLIPS:
- LLViewerStats::getInstance()->mSimLSLIPS.addValue(stat_value);
+ case LL_SIM_STAT_SCRIPT_EPS:
+ LLViewerStats::getInstance()->mSimScriptEPS.addValue(stat_value);
break;
case LL_SIM_STAT_INPPS:
LLViewerStats::getInstance()->mSimInPPS.addValue(stat_value);
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 1aa7d2c3ff..8745a73e79 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -2145,7 +2145,7 @@ void LLViewerObject::deleteInventoryItem(const LLUUID& item_id)
}
void LLViewerObject::doUpdateInventory(
- LLViewerInventoryItem* item,
+ LLPointer<LLViewerInventoryItem>& item,
U8 key,
bool is_new)
{
@@ -2217,7 +2217,8 @@ void LLViewerObject::doUpdateInventory(
--mInventorySerialNum;
}
}
- LLViewerInventoryItem* new_item = new LLViewerInventoryItem(item);
+ LLViewerInventoryItem* oldItem = item;
+ LLViewerInventoryItem* new_item = new LLViewerInventoryItem(oldItem);
new_item->setPermissions(perm);
mInventory->push_front(new_item);
doInventoryCallback();
@@ -2608,6 +2609,21 @@ void LLViewerObject::updateInventory(
doUpdateInventory(task_item, key, is_new);
}
+void LLViewerObject::updateInventoryLocal(LLInventoryItem* item, U8 key)
+{
+ LLPointer<LLViewerInventoryItem> task_item =
+ new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(),
+ item->getAssetUUID(), item->getType(),
+ item->getInventoryType(),
+ item->getName(), item->getDescription(),
+ item->getSaleInfo(), item->getFlags(),
+ item->getCreationDate());
+
+ // do the internal logic
+ const bool is_new = false;
+ doUpdateInventory(task_item, key, is_new);
+}
+
LLInventoryObject* LLViewerObject::getInventoryObject(const LLUUID& item_id)
{
LLInventoryObject* rv = NULL;
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index a143589ee9..1fd4a29238 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -384,6 +384,7 @@ public:
// manager, so do no call updateInventory() from the selection
// manager until we have better iterators.
void updateInventory(LLViewerInventoryItem* item, U8 key, bool is_new);
+ void updateInventoryLocal(LLInventoryItem* item, U8 key); // Update without messaging.
LLInventoryObject* getInventoryObject(const LLUUID& item_id);
void getInventoryContents(InventoryObjectList& objects);
LLInventoryObject* getInventoryRoot();
@@ -540,7 +541,7 @@ protected:
// do the update/caching logic. called by saveScript and
// updateInventory.
- void doUpdateInventory(LLViewerInventoryItem* item, U8 key, bool is_new);
+ void doUpdateInventory(LLPointer<LLViewerInventoryItem>& item, U8 key, bool is_new);
static LLViewerObject *createObject(const LLUUID &id, LLPCode pcode, LLViewerRegion *regionp);
diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h
index ccd3110758..446f8f026a 100644
--- a/indra/newview/llviewerstats.h
+++ b/indra/newview/llviewerstats.h
@@ -63,7 +63,7 @@ public:
LLStat mSimFPS;
LLStat mSimPhysicsFPS;
LLStat mSimAgentUPS;
- LLStat mSimLSLIPS;
+ LLStat mSimScriptEPS;
LLStat mSimFrameMsec;
LLStat mSimNetMsec;
diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc
index 20a572c8e0..a39bb9faf6 100644
--- a/indra/newview/res/viewerRes.rc
+++ b/indra/newview/res/viewerRes.rc
@@ -231,8 +231,8 @@ TOOLMEDIAOPEN CURSOR "toolmediaopen.cur"
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,19,1,83014
- PRODUCTVERSION 1,19,1,83014
+ FILEVERSION 1,20,9,87416
+ PRODUCTVERSION 1,20,9,87416
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -249,12 +249,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Linden Lab"
VALUE "FileDescription", "Second Life"
- VALUE "FileVersion", "1.19.1.83014"
+ VALUE "FileVersion", "1.20.9.87416"
VALUE "InternalName", "Second Life"
VALUE "LegalCopyright", "Copyright © 2001-2008, Linden Research, Inc."
VALUE "OriginalFilename", "SecondLife.exe"
VALUE "ProductName", "Second Life"
- VALUE "ProductVersion", "1.19.1.83014"
+ VALUE "ProductVersion", "1.20.9.87416"
END
END
BLOCK "VarFileInfo"
diff --git a/indra/test/llassetuploadqueue_tut.cpp b/indra/test/llassetuploadqueue_tut.cpp
new file mode 100644
index 0000000000..7c4b8a0c9c
--- /dev/null
+++ b/indra/test/llassetuploadqueue_tut.cpp
@@ -0,0 +1,178 @@
+/**
+ * @file asset_upload_queue_tut.cpp
+ * @brief Tests for newview/llassetuploadqueue.cpp
+ * Copyright (c) 2007, Linden Research, Inc.
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "lltut.h"
+
+#include "mock_http_client.h"
+#include "../newview/llassetuploadqueue.cpp"
+
+// Mock implementation.
+LLAssetUploadResponder::LLAssetUploadResponder(const LLSD& post_data,
+ const LLUUID& vfile_id,
+ LLAssetType::EType asset_type)
+{
+}
+
+LLAssetUploadResponder::LLAssetUploadResponder(const LLSD& post_data, const std::string& file_name)
+{
+}
+
+LLAssetUploadResponder::~LLAssetUploadResponder()
+{
+}
+
+void LLAssetUploadResponder::error(U32 statusNum, const std::string& reason)
+{
+}
+
+void LLAssetUploadResponder::result(const LLSD& content)
+{
+}
+
+void LLAssetUploadResponder::uploadUpload(const LLSD& content)
+{
+}
+
+void LLAssetUploadResponder::uploadComplete(const LLSD& content)
+{
+}
+
+void LLAssetUploadResponder::uploadFailure(const LLSD& content)
+{
+}
+
+LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data,
+ const LLUUID& vfile_id,
+ LLAssetType::EType asset_type) :
+ LLAssetUploadResponder(post_data, vfile_id, asset_type)
+{
+}
+
+LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data,
+ const std::string& file_name) :
+ LLAssetUploadResponder(post_data, file_name)
+{
+}
+
+LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data,
+ const std::string& file_name,
+ const LLUUID& queue_id) :
+ LLAssetUploadResponder(post_data, file_name)
+{
+}
+
+void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content)
+{
+}
+
+namespace tut
+{
+ class asset_upload_queue_test_data : public MockHttpClient {};
+ typedef test_group<asset_upload_queue_test_data> asset_upload_queue_test;
+ typedef asset_upload_queue_test::object asset_upload_queue_object;
+ tut::asset_upload_queue_test asset_upload_queue("asset_upload_queue");
+
+ void queue(LLAssetUploadQueue& q, const std::string& filename)
+ {
+ LLUUID task_id;
+ LLUUID item_id;
+ BOOL is_running = FALSE;
+ BOOL is_target_mono = TRUE;
+ LLUUID queue_id;
+ q.queue(filename, task_id, item_id, is_running, is_target_mono, queue_id);
+ }
+
+ class LLTestSupplier : public LLAssetUploadQueueSupplier
+ {
+ public:
+
+ void set(LLAssetUploadQueue* queue) {mQueue = queue;}
+
+ virtual LLAssetUploadQueue* get() const
+ {
+ return mQueue;
+ }
+
+ private:
+ LLAssetUploadQueue* mQueue;
+ };
+
+ template<> template<>
+ void asset_upload_queue_object::test<1>()
+ {
+ setupTheServer();
+ reset();
+ LLTestSupplier* supplier = new LLTestSupplier();
+ LLAssetUploadQueue q("http://localhost:8888/test/success", supplier);
+ supplier->set(&q);
+ queue(q, "foo.bar");
+ ensure("upload queue not empty before request", q.isEmpty());
+ runThePump(10);
+ ensure("upload queue not empty after request", q.isEmpty());
+ }
+
+ template<> template<>
+ void asset_upload_queue_object::test<2>()
+ {
+ reset();
+ LLTestSupplier* supplier = new LLTestSupplier();
+ LLAssetUploadQueue q("http://localhost:8888/test/error", supplier);
+ supplier->set(&q);
+ queue(q, "foo.bar");
+ ensure("upload queue not empty before request", q.isEmpty());
+ runThePump(10);
+ ensure("upload queue not empty after request", q.isEmpty());
+ }
+
+ template<> template<>
+ void asset_upload_queue_object::test<3>()
+ {
+ reset();
+ LLTestSupplier* supplier = new LLTestSupplier();
+ LLAssetUploadQueue q("http://localhost:8888/test/timeout", supplier);
+ supplier->set(&q);
+ queue(q, "foo.bar");
+ ensure("upload queue not empty before request", q.isEmpty());
+ runThePump(10);
+ ensure("upload queue not empty after request", q.isEmpty());
+ }
+
+ template<> template<>
+ void asset_upload_queue_object::test<4>()
+ {
+ reset();
+ LLTestSupplier* supplier = new LLTestSupplier();
+ LLAssetUploadQueue q("http://localhost:8888/test/success", supplier);
+ supplier->set(&q);
+ queue(q, "foo.bar");
+ queue(q, "baz.bar");
+ ensure("upload queue empty before request", !q.isEmpty());
+ runThePump(10);
+ ensure("upload queue not empty before request", q.isEmpty());
+ runThePump(10);
+ ensure("upload queue not empty after request", q.isEmpty());
+ }
+
+ template<> template<>
+ void asset_upload_queue_object::test<5>()
+ {
+ reset();
+ LLTestSupplier* supplier = new LLTestSupplier();
+ LLAssetUploadQueue q("http://localhost:8888/test/success", supplier);
+ supplier->set(&q);
+ queue(q, "foo.bar");
+ runThePump(10);
+ ensure("upload queue not empty before request", q.isEmpty());
+ queue(q, "baz.bar");
+ ensure("upload queue not empty after request", q.isEmpty());
+ runThePump(10);
+ killServer();
+ }
+}
diff --git a/indra/test/mock_http_client.cpp b/indra/test/mock_http_client.cpp
new file mode 100644
index 0000000000..6b273ee7b5
--- /dev/null
+++ b/indra/test/mock_http_client.cpp
@@ -0,0 +1,66 @@
+/**
+ * @file mock_http_client.cpp
+ * @brief Framework for testing HTTP requests
+ * Copyright (c) 2007, Linden Research, Inc.
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "llsdhttpserver.h"
+#include "lliohttpserver.h"
+
+namespace tut
+{
+ class SuccessNode : public LLHTTPNode
+ {
+ public:
+ void get(ResponsePtr r, const LLSD& context) const
+ {
+ LLSD result;
+ result["state"] = "complete";
+ result["test"] = "test";
+ r->result(result);
+ }
+ void post(ResponsePtr r, const LLSD& context, const LLSD& input) const
+ {
+ LLSD result;
+ result["state"] = "complete";
+ result["test"] = "test";
+ r->result(result);
+ }
+ };
+
+ class ErrorNode : public LLHTTPNode
+ {
+ public:
+ void get(ResponsePtr r, const LLSD& context) const
+ { r->status(599, "Intentional error"); }
+ void post(ResponsePtr r, const LLSD& context, const LLSD& input) const
+ { r->status(input["status"], input["reason"]); }
+ };
+
+ class TimeOutNode : public LLHTTPNode
+ {
+ public:
+ void get(ResponsePtr r, const LLSD& context) const
+ {
+ /* do nothing, the request will eventually time out */
+ }
+ };
+
+ LLSD storage;
+
+ class LLSDStorageNode : public LLHTTPNode
+ {
+ public:
+ LLSD get() const{ return storage; }
+ LLSD put(const LLSD& value) const{ storage = value; return LLSD(); }
+ };
+
+ LLHTTPRegistration<LLSDStorageNode> gStorageNode("/test/storage");
+ LLHTTPRegistration<SuccessNode> gSuccessNode("/test/success");
+ LLHTTPRegistration<ErrorNode> gErrorNode("/test/error");
+ LLHTTPRegistration<TimeOutNode> gTimeOutNode("/test/timeout");
+}
diff --git a/indra/test/mock_http_client.h b/indra/test/mock_http_client.h
new file mode 100644
index 0000000000..6476ea3783
--- /dev/null
+++ b/indra/test/mock_http_client.h
@@ -0,0 +1,174 @@
+/**
+ * @file mock_http_client.cpp
+ * @brief Framework for testing HTTP requests
+ * Copyright (c) 2007, Linden Research, Inc.
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ * $/LicenseInfo$
+ */
+
+#include "llsdhttpserver.h"
+#include "lliohttpserver.h"
+#include "llhttpclient.h"
+#include "llformat.h"
+#include "llpipeutil.h"
+#include "llpumpio.h"
+
+namespace tut
+{
+ struct MockHttpClient
+ {
+ public:
+ MockHttpClient()
+ {
+ apr_pool_create(&mPool, NULL);
+ mServerPump = new LLPumpIO(mPool);
+ mClientPump = new LLPumpIO(mPool);
+
+ LLHTTPClient::setPump(*mClientPump);
+ }
+
+ ~MockHttpClient()
+ {
+ delete mServerPump;
+ delete mClientPump;
+ apr_pool_destroy(mPool);
+ }
+
+ void setupTheServer()
+ {
+ LLHTTPNode& root = LLIOHTTPServer::create(mPool, *mServerPump, 8888);
+
+ LLHTTPStandardServices::useServices();
+ LLHTTPRegistrar::buildAllServices(root);
+ }
+
+ void runThePump(float timeout = 100.0f)
+ {
+ LLTimer timer;
+ timer.setTimerExpirySec(timeout);
+
+ while(!mSawCompleted && !timer.hasExpired())
+ {
+ if (mServerPump)
+ {
+ mServerPump->pump();
+ mServerPump->callback();
+ }
+ if (mClientPump)
+ {
+ mClientPump->pump();
+ mClientPump->callback();
+ }
+ }
+ }
+
+ void killServer()
+ {
+ delete mServerPump;
+ mServerPump = NULL;
+ }
+
+ private:
+ apr_pool_t* mPool;
+ LLPumpIO* mServerPump;
+ LLPumpIO* mClientPump;
+
+
+ protected:
+ void ensureStatusOK()
+ {
+ if (mSawError)
+ {
+ std::string msg =
+ llformat("error() called when not expected, status %d",
+ mStatus);
+ fail(msg);
+ }
+ }
+
+ void ensureStatusError()
+ {
+ if (!mSawError)
+ {
+ fail("error() wasn't called");
+ }
+ }
+
+ LLSD getResult()
+ {
+ return mResult;
+ }
+
+ protected:
+ bool mSawError;
+ U32 mStatus;
+ std::string mReason;
+ bool mSawCompleted;
+ LLSD mResult;
+ bool mResultDeleted;
+
+ class Result : public LLHTTPClient::Responder
+ {
+ protected:
+ Result(MockHttpClient& client)
+ : mClient(client)
+ {
+ }
+
+ public:
+ static boost::intrusive_ptr<Result> build(MockHttpClient& client)
+ {
+ return boost::intrusive_ptr<Result>(new Result(client));
+ }
+
+ ~Result()
+ {
+ mClient.mResultDeleted = true;
+ }
+
+ virtual void error(U32 status, const std::string& reason)
+ {
+ mClient.mSawError = true;
+ mClient.mStatus = status;
+ mClient.mReason = reason;
+ }
+
+ virtual void result(const LLSD& content)
+ {
+ mClient.mResult = content;
+ }
+
+ virtual void completed(
+ U32 status, const std::string& reason,
+ const LLSD& content)
+ {
+ LLHTTPClient::Responder::completed(status, reason, content);
+
+ mClient.mSawCompleted = true;
+ }
+
+ private:
+ MockHttpClient& mClient;
+ };
+
+ friend class Result;
+
+ protected:
+
+ void reset()
+ {
+ mSawError = false;
+ mStatus = 0;
+ mSawCompleted = false;
+ mResult.clear();
+ mResultDeleted = false;
+ }
+
+ LLHTTPClient::ResponderPtr newResult()
+ {
+ reset();
+ return Result::build(*this);
+ }
+ };
+}