summaryrefslogtreecommitdiff
path: root/indra/lscript/lscript_compile/lscript_tree.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/lscript/lscript_compile/lscript_tree.cpp')
-rw-r--r--indra/lscript/lscript_compile/lscript_tree.cpp1955
1 files changed, 1412 insertions, 543 deletions
diff --git a/indra/lscript/lscript_compile/lscript_tree.cpp b/indra/lscript/lscript_compile/lscript_tree.cpp
index efbbe374ed..8a70dd9ac1 100644
--- a/indra/lscript/lscript_compile/lscript_tree.cpp
+++ b/indra/lscript/lscript_compile/lscript_tree.cpp
@@ -2,30 +2,25 @@
* @file lscript_tree.cpp
* @brief implements methods for lscript_tree.h classes
*
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- *
- * Copyright (c) 2002-2007, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -43,32 +38,38 @@
//#define LSL_INCLUDE_DEBUG_INFO
-void print_cil_box(LLFILE* fp, LSCRIPTType type)
+
+static void print_cil_box(LLFILE* fp, LSCRIPTType type)
{
- switch(type)
+
+switch(type)
{
case LST_INTEGER:
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 +80,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 +192,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 +240,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 +257,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 +321,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 +332,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 +341,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 +415,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 +455,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 +530,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 +599,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 +614,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;
@@ -579,13 +625,14 @@ void print_cil_cast(LLFILE* fp, LSCRIPTType srcType, LSCRIPTType targetType)
switch(targetType)
{
case LST_INTEGER:
- fprintf(fp, "conv.i4\n");
+ fprintf(fp, "call int32 [LslLibrary]LindenLab.SecondLife.LslRunTime::ToInteger(float32)\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 +642,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 +669,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 +685,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 +701,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 +717,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 +728,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 +887,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 +1053,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 +1150,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 +1228,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 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");
+ 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 +1338,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 +1361,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 +1431,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 +1483,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 +1513,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 +1549,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 +1559,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 +1593,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 +1618,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 +1659,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 +1684,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 +1725,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 +1750,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 +1791,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 +1816,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 +1856,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 +1881,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 +1920,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 +1945,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 +1984,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 +2009,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 +2050,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 +2075,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 +2115,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 +2139,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 +2180,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 +2205,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 +2244,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 +2269,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 +2310,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 +2346,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 +2388,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 +2426,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 +2464,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 +2505,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 +2530,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 +2576,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 +2634,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 +2685,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 +2710,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 +2749,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 +2774,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 +2817,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 +2864,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 +2917,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 +2975,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 +3036,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 +3116,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 +3174,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 +3182,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 +3248,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);
@@ -2881,6 +3283,110 @@ S32 LLScriptHTTPResponseEvent::getSize()
return 16;
}
+void LLScriptHTTPRequestEvent::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())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "http_request( key ");
+ mRequestId->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", string ");
+ mMethod->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;
+
+ case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "http_request");
+ if (scope->checkEntry(mRequestId->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mRequestId->mScopeEntry = scope->addEntry(mRequestId->mName, LIT_VARIABLE, LST_KEY);
+ }
+
+ if (scope->checkEntry(mMethod->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mMethod->mScopeEntry = scope->addEntry(mMethod->mName, LIT_VARIABLE, LST_STRING);
+ }
+
+ if (scope->checkEntry(mBody->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mBody->mScopeEntry = scope->addEntry(mBody->mName, LIT_VARIABLE, LST_STRING);
+ }
+ break;
+
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mRequestId->mScopeEntry)
+ {
+ mRequestId->mScopeEntry->mOffset = (S32)count;
+ mRequestId->mScopeEntry->mSize = 4;
+ count += mRequestId->mScopeEntry->mSize;
+
+ mMethod->mScopeEntry->mOffset = (S32)count;
+ mMethod->mScopeEntry->mSize = 4;
+ count += mMethod->mScopeEntry->mSize;
+
+ mBody->mScopeEntry->mOffset = (S32)count;
+ mBody->mScopeEntry->mSize = 4;
+ count += mBody->mScopeEntry->mSize;
+ }
+ }
+ break;
+
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "http_request";
+ chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(mRequestId->mName, strlen(mRequestId->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(mMethod->mName, strlen(mMethod->mName) + 1); /*Flawfinder: ignore*/
+ chunk->addBytes(mBody->mName, strlen(mBody->mName) + 1); /*Flawfinder: ignore*/
+#endif
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "http_request( 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, ", string ");
+ mMethod->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);
+ mMethod->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mBody->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptHTTPRequestEvent::getSize()
+{
+ // key + string + string = 12
+ return 12;
+}
void LLScriptMoneyEvent::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)
{
@@ -2900,6 +3406,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 +3442,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 +3493,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 +3562,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 +3617,7 @@ void LLScriptRezEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompile
fprintf(fp, " )\n");
break;
case LSCP_SCOPE_PASS1:
+ checkForDuplicateHandler(fp, this, scope, "on_rez");
if (scope->checkEntry(mStartParam->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
@@ -3111,11 +3642,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 +3680,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 +3724,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 +3770,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 +3819,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 +3855,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 +3864,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 +3911,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 +3963,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 +4142,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 +4258,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 +4326,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 +4340,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 +4362,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 +4388,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 +4396,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 +4407,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 +4422,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 +4677,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 +4707,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 +4735,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 +4762,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 +4890,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 +4907,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 +4933,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 +4950,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 +4972,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 +5039,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 +5067,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 +5088,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 +5139,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 +5167,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 +5188,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;
+ }
+}
+
+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:
- // Numeric multiplication.
- fprintf(fp, "mul\n");
+ // 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 +5285,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 +5313,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 +5322,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 +5341,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 +5367,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 +5388,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 +5407,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 +5435,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 +5463,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 +5484,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 +5525,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 +5553,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 +5572,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 +5585,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 +5665,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 +5726,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 +5753,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 +5802,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 +5821,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 +5870,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 +5889,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 +5936,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 +5955,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 +6002,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 +6062,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 +6122,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 +6182,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 +6242,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 +6302,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 +6358,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 +6414,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 +6470,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 +6526,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 +6591,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 +6648,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 +6705,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 +6790,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 +6939,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 +6986,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 +7047,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 +7094,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 +7275,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 +7416,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 +7463,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 +7479,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 +7545,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 +7614,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 +7687,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 +7756,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 +7799,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 +7890,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 +7961,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 +7979,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, "%s", 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, "%s", mIdentifier->mName);
+ fprintf(fp, "'(");
+ print_cil_arg_list(fp, mIdentifier->mScopeEntry->mFunctionArgs);
fprintf(fp, ")\n");
}
break;
@@ -7287,6 +8035,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 +8157,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 +8208,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 +8223,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 +8256,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 +8295,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 +8304,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 +8344,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:
{
@@ -7609,11 +8367,19 @@ void LLScriptStateChange::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTComp
chunk->addInteger(mIdentifier->mScopeEntry->mCount);
}
break;
+ case LSCP_TYPE:
+ mReturnType = basetype;
+ 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");
+ // We are doing a state change. In the LSL interpreter, this is basically a longjmp. We emulate it
+ // here using a call to the ChangeState followed by a short cut return of the current method. To
+ // maintain type safety we need to push an arbitrary variable of the current method's return type
+ // onto the stack before returning. This will be ignored and discarded.
+ print_cil_init_variable(fp, mReturnType);
+ 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 +8413,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 +8583,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 +8630,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 +8670,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 +8716,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,15 +8793,16 @@ 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);
+ if (type == LST_NULL)
+ {
+ gErrorToText.writeError(fp, mExpression, LSERROR_TYPE_MISMATCH);
+ }
mType = type;
- mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
break;
case LSCP_EMIT_BYTE_CODE:
{
@@ -8004,6 +8822,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);
@@ -8063,6 +8882,10 @@ void LLScriptIfElse::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePa
break;
case LSCP_TYPE:
mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (type == LST_NULL)
+ {
+ gErrorToText.writeError(fp, mExpression, LSERROR_TYPE_MISMATCH);
+ }
mType = type;
mStatement1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mStatement2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -8093,6 +8916,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,15 +8979,16 @@ 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)
mSequence->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);
+ if (type == LST_NULL)
+ {
+ gErrorToText.writeError(fp, mExpression, LSERROR_TYPE_MISMATCH);
+ }
mType = type;
if(mExpressionList)
mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
@@ -8203,6 +9028,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,14 +9083,15 @@ 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);
mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (type == LST_NULL)
+ {
+ gErrorToText.writeError(fp, mExpression, LSERROR_TYPE_MISMATCH);
+ }
mType = type;
break;
case LSCP_EMIT_BYTE_CODE:
@@ -8287,6 +9114,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,13 +9159,14 @@ 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);
+ if (type == LST_NULL)
+ {
+ gErrorToText.writeError(fp, mExpression, LSERROR_TYPE_MISMATCH);
+ }
mType = type;
mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
break;
@@ -8367,6 +9196,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 +9259,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 +9431,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 +9567,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)
{
@@ -8946,6 +9762,11 @@ void LLScriptEventHandler::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCom
mScopeEntry->mFunctionArgs.addType(LST_LIST);
mScopeEntry->mFunctionArgs.addType(LST_STRING);
break;
+ case LSTT_HTTP_REQUEST:
+ mScopeEntry->mFunctionArgs.addType(LST_KEY);
+ mScopeEntry->mFunctionArgs.addType(LST_STRING);
+ mScopeEntry->mFunctionArgs.addType(LST_STRING);
+ break;
default:
break;
@@ -8956,6 +9777,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;
@@ -8974,6 +9799,9 @@ void LLScriptEventHandler::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCom
break;
case LSCP_EMIT_BYTE_CODE:
{
+ llassert(mEventp);
+ if (!mEventp) return;
+
// order for event handler
// set jump table value
S32 jumpoffset;
@@ -8987,13 +9815,11 @@ void LLScriptEventHandler::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCom
chunk->addBytes(4);
// null terminated event name and null terminated parameters
- if (mEventp)
- {
- LLScriptByteCodeChunk *event = new LLScriptByteCodeChunk(FALSE);
- mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, event, heap, stacksize, entry, entrycount, NULL);
- chunk->addBytes(event->mCodeChunk, event->mCurrentOffset);
- delete event;
- }
+ LLScriptByteCodeChunk *event = new LLScriptByteCodeChunk(FALSE);
+ mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, event, heap, stacksize, entry, entrycount, NULL);
+ chunk->addBytes(event->mCodeChunk, event->mCurrentOffset);
+ delete event;
+
chunk->addBytes(1);
// now we're at the first opcode
@@ -9024,8 +9850,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, "%s", 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 +9876,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 +9994,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 +10009,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 +10235,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 +10281,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, "%s", mIdentifier->mName);
+ fprintf(fp, "'");
if (mParameters)
{
fprintf(fp, "( ");
@@ -9473,6 +10312,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 +10427,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 +10491,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 +10535,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,8 +10578,8 @@ LLScriptScript::LLScriptScript(LLScritpGlobalStorage *globals,
mStates(states), mGlobalScope(NULL), mGlobals(NULL), mGlobalFunctions(NULL), mGodLike(FALSE)
{
const char DEFAULT_BYTECODE_FILENAME[] = "lscript.lso";
- strncpy(mBytecodeDest, DEFAULT_BYTECODE_FILENAME, sizeof(mBytecodeDest) -1); /*Flawfinder: ignore*/
- mBytecodeDest[MAX_STRING-1] = '\0';
+
+ mBytecodeDest = DEFAULT_BYTECODE_FILENAME;
LLScriptGlobalVariable *tvar;
LLScriptGlobalFunctions *tfunc;
LLScritpGlobalStorage *temp;
@@ -9747,21 +10621,20 @@ LLScriptScript::LLScriptScript(LLScritpGlobalStorage *globals,
}
temp = temp->mNextp;
}
+
+ mClassName[0] = '\0';
}
void LLScriptScript::setBytecodeDest(const char* dst_filename)
{
- strncpy(mBytecodeDest, dst_filename, MAX_STRING); /*Flawfinder: ignore*/
- mBytecodeDest[MAX_STRING-1] = '\0';
+ 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);
@@ -9803,20 +10676,21 @@ void LLScriptScript::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePa
{
mGlobalScope = new LLScriptScope(gScopeStringTable);
// zeroth, add library functions to global scope
- S32 i;
+ U16 function_index = 0;
const char *arg;
LLScriptScopeEntry *sentry;
- for (i = 0; i < gScriptLibrary.mNextNumber; i++)
+ for (std::vector<LLScriptLibraryFunction>::const_iterator i = gScriptLibrary.mFunctions.begin();
+ i != gScriptLibrary.mFunctions.end(); ++i)
{
// First, check to make sure this isn't a god only function, or that the viewer's agent is a god.
- if (!gScriptLibrary.mFunctions[i]->mGodOnly || mGodLike)
+ if (!i->mGodOnly || mGodLike)
{
- if (gScriptLibrary.mFunctions[i]->mReturnType)
- sentry = mGlobalScope->addEntry(gScriptLibrary.mFunctions[i]->mName, LIT_LIBRARY_FUNCTION, char2type(*gScriptLibrary.mFunctions[i]->mReturnType));
+ if (i->mReturnType)
+ sentry = mGlobalScope->addEntry(i->mName, LIT_LIBRARY_FUNCTION, char2type(*i->mReturnType));
else
- sentry = mGlobalScope->addEntry(gScriptLibrary.mFunctions[i]->mName, LIT_LIBRARY_FUNCTION, LST_NULL);
- sentry->mLibraryNumber = i;
- arg = gScriptLibrary.mFunctions[i]->mArgs;
+ sentry = mGlobalScope->addEntry(i->mName, LIT_LIBRARY_FUNCTION, LST_NULL);
+ sentry->mLibraryNumber = function_index;
+ arg = i->mArgs;
if (arg)
{
while (*arg)
@@ -9828,6 +10702,7 @@ void LLScriptScript::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePa
}
}
}
+ function_index++;
}
// first go and collect all the global variables
if (mGlobals)
@@ -9948,72 +10823,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)