Torque3D/Engine/source/console/torquescript/codeBlock.h
JeffR 171211c4e2 Caches the processed line in CodeBlock for better assert reporting
Adds additional context on eval and evaluate calls to better isolate script executions that are throwing errors, such as via command fields or eval() calls.
2026-02-21 11:03:07 -06:00

171 lines
6.3 KiB
C++

//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _CODEBLOCK_H_
#define _CODEBLOCK_H_
#include <vector>
#include <unordered_map>
#include "parser.h"
#include "console/runtime.h"
struct CompilerLocalVariableToRegisterMappingTable
{
struct RemappingTable
{
std::vector<StringTableEntry> varList;
};
std::unordered_map<StringTableEntry, RemappingTable> localVarToRegister;
void add(StringTableEntry functionName, StringTableEntry namespaceName, StringTableEntry varName);
S32 lookup(StringTableEntry namespaceName, StringTableEntry functionName, StringTableEntry varName);
CompilerLocalVariableToRegisterMappingTable copy();
void reset();
void write(Stream& stream);
};
#include "compiler.h"
class Stream;
class ConsoleValue;
/// Core TorqueScript code management class.
///
/// This class represents a block of code, usually mapped directly to a file.
class CodeBlock : Con::Module
{
private:
static CodeBlock* smCodeBlockList;
public:
static bool smInFunction;
static TorqueScriptParser * smCurrentParser;
static StringTableEntry smCurrentLineText;
static CodeBlock *getCodeBlockList()
{
return smCodeBlockList;
}
static CodeBlock *find(StringTableEntry);
CodeBlock();
~CodeBlock() override;
StringTableEntry name;
StringTableEntry fullPath;
StringTableEntry modPath;
char *globalStrings;
char *functionStrings;
U32 functionStringsMaxLen;
U32 globalStringsMaxLen;
F64 *globalFloats;
F64 *functionFloats;
U32 codeSize;
U32 *code;
CompilerLocalVariableToRegisterMappingTable variableRegisterTable;
U32 refCount;
U32 lineBreakPairCount;
U32 *lineBreakPairs;
Vector<U32> breakList;
CodeBlock *nextFile;
void addToCodeList();
void removeFromCodeList();
void calcBreakList();
void clearAllBreaks() override;
void setAllBreaks() override;
void dumpInstructions(U32 startIp = 0, bool upToReturn = false);
/// Returns the first breakable line or 0 if none was found.
/// @param lineNumber The one based line number.
U32 findFirstBreakLine(U32 lineNumber) override;
void clearBreakpoint(U32 lineNumber) override;
/// Set a OP_BREAK instruction on a line. If a break
/// is not possible on that line it returns false.
/// @param lineNumber The one based line number.
bool setBreakpoint(U32 lineNumber) override;
void findBreakLine(U32 ip, U32 &line, U32 &instruction) override;
const char *getFileLine(U32 ip) override;
///
String getFunctionArgs(U32 offset);
bool read(StringTableEntry fileName, Stream &st);
bool compile(const char *dsoName, StringTableEntry fileName, const char *script, bool overrideNoDso = false);
/// Compiles and executes a block of script storing the compiled code in this
/// CodeBlock. If there is no filename breakpoints will not be generated and
/// the CodeBlock will not be added to the linked list of loaded CodeBlocks.
/// Note that if the script contains no executable statements the CodeBlock
/// will delete itself on return an empty string. The return string is any
/// result of the code executed, if any, or an empty string.
///
/// @param fileName The file name, including path and extension, for the
/// block of code or an empty string.
/// @param script The script code to compile and execute.
/// @param noCalls Skips calling functions from the script.
/// @param setFrame A zero based index of the stack frame to execute the code
/// with, zero being the top of the stack. If the the index is
/// -1 a new frame is created. If the index is out of range the
/// top stack frame is used.
Con::EvalResult compileExec(StringTableEntry fileName, const char *script,
bool noCalls, S32 setFrame = -1);
/// Executes the existing code in the CodeBlock. The return string is any
/// result of the code executed, if any, or an empty string.
///
/// @param offset The instruction offset to start executing from.
/// @param fnName The name of the function to execute or null.
/// @param ns The namespace of the function to execute or null.
/// @param argc The number of parameters passed to the function or
/// zero to execute code outside of a function.
/// @param argv The function parameter list.
/// @param noCalls Skips calling functions from the script.
/// @param setFrame A zero based index of the stack frame to execute the code
/// with, zero being the top of the stack. If the the index is
/// -1 a new frame is created. If the index is out of range the
/// top stack frame is used.
/// @param packageName The code package name or null.
Con::EvalResult exec(U32 offset, const char* fnName, Namespace* ns, U32 argc,
ConsoleValue* argv, bool noCalls, StringTableEntry packageName,
S32 setFrame = -1) override;
const char* getFunctionArgs(StringTableEntry functionName, U32 functionOffset) override { return getFunctionArgs(functionOffset); }
const char* getPath() override { return fullPath; }
const char* getName() override { return name; }
Vector<U32> getBreakableLines() override { return breakList; }
};
#endif