void LldbEngine::activateFrame(int frameIndex) { if (state() != InferiorStopOk && state() != InferiorUnrunnable) return; StackHandler *handler = stackHandler(); const int n = handler->stackSize(); if (frameIndex == n) { DebuggerCommand cmd("reportStack"); cmd.arg("nativeMixed", isNativeMixedActive()); cmd.arg("stacklimit", n * 10 + 3); runCommand(cmd); return; } QTC_ASSERT(frameIndex < handler->stackSize(), return); handler->setCurrentIndex(frameIndex); gotoLocation(handler->currentFrame()); DebuggerCommand cmd("activateFrame"); cmd.arg("index", frameIndex); cmd.arg("thread", threadsHandler()->currentThread().raw()); cmd.arg("continuation", "updateLocals"); runCommand(cmd); }
void PdbEngine::activateFrame(int frameIndex) { resetLocation(); if (state() != InferiorStopOk && state() != InferiorUnrunnable) return; StackHandler *handler = stackHandler(); int oldIndex = handler->currentIndex(); //if (frameIndex == handler->stackSize()) { // reloadFullStack(); // return; //} QTC_ASSERT(frameIndex < handler->stackSize(), return); if (oldIndex != frameIndex) { // Assuming the command always succeeds this saves a roundtrip. // Otherwise the lines below would need to get triggered // after a response to this -stack-select-frame here. handler->setCurrentIndex(frameIndex); //postCommand("-stack-select-frame " + QByteArray::number(frameIndex), // CB(handleStackSelectFrame)); } gotoLocation(handler->currentFrame()); }
static int getInstanceVarInfo(StackHandler & sa,VarRefPtr & vr,SQUserPointer & data) { HSQOBJECT ho = sa.GetObjectHandle(1); SquirrelObject instance(ho); const SQChar * el = sa.GetString(2); ScriptStringVar256 varNameTag; getVarNameTag(varNameTag,sizeof(varNameTag),el); SQUserPointer ivrData=0; if (!instance.RawGetUserData(varNameTag,&ivrData)) { return sa.ThrowError(_SC("getInstanceVarInfo: Could not retrieve UserData")); // Results in variable not being found error. } vr = (VarRefPtr)ivrData; char * up; if (!(vr->m_access & (VAR_ACCESS_STATIC|VAR_ACCESS_CONSTANT))) { SQUserPointer typetag; instance.GetTypeTag(&typetag); #if defined(SQ_USE_CLASS_INHERITANCE) if (typetag != vr->instanceType) { SquirrelObject typeTable = instance.GetValue(SQ_CLASS_OBJECT_TABLE_NAME); up = (char *)typeTable.GetUserPointer(INT((size_t)vr->instanceType)); // <TODO> 64-bit compatible version. if (!up) { throw SquirrelError(_SC("Invalid Instance Type")); } } else { up = (char *)instance.GetInstanceUP(0); } // if #elif defined(SQ_USE_CLASS_INHERITANCE_SIMPLE) ClassTypeBase *ctb = (ClassTypeBase*)vr->instanceType; up = (char *)instance.GetInstanceUP(0); // Walk base classes until type tag match, adjust for inheritence offset while(ctb && typetag!=ctb) { up = (char*)up - ctb->m_offset; ctb = ctb->m_pbase; } if (!ctb) { throw SquirrelError(_SC("Invalid Instance Type")); } #else up = (char *)instance.GetInstanceUP(0); #endif #ifdef SQPLUS_SMARTPOINTER_OPT #define SQPLUS_SMARTPOINTER_INSTANCE_VARINFO #include "SqPlusSmartPointer.h" #endif up += (size_t)vr->offsetOrAddrOrConst; // Offset } else { up = (char *)vr->offsetOrAddrOrConst; // Address } // if data = up; return SQ_OK; } // getInstanceVarInfo
void PdbEngine::activateFrame(int frameIndex) { if (state() != InferiorStopOk && state() != InferiorUnrunnable) return; StackHandler *handler = stackHandler(); QTC_ASSERT(frameIndex < handler->stackSize(), return); handler->setCurrentIndex(frameIndex); gotoLocation(handler->currentFrame()); updateLocals(); }
static int getVarInfo(StackHandler & sa,VarRefPtr & vr) { HSQOBJECT htable = sa.GetObjectHandle(1); SquirrelObject table(htable); const SQChar * el = sa.GetString(2); ScriptStringVar256 varNameTag; getVarNameTag(varNameTag,sizeof(varNameTag),el); SQUserPointer data=0; if (!table.RawGetUserData(varNameTag,&data)) { return sa.ThrowError(_SC("getVarInfo: Could not retrieve UserData")); // Results in variable not being found error. } vr = (VarRefPtr)data; return SQ_OK; } // getVarInfo
static SQInteger getVarInfo(StackHandler & sa,VarRefPtr & vr) { HSQOBJECT htable = sa.GetObjectHandle(1); SquirrelObject table(htable); #ifdef _DEBUG SQObjectType type = (SQObjectType)sa.GetType(2); #endif const SQChar * el = sa.GetString(2); ScriptStringVar256 varNameTag; getVarNameTag(varNameTag,sizeof(varNameTag),el); SQUserPointer data=0; if (!table.RawGetUserData(varNameTag,&data)) { // throw SquirrelError("getVarInfo: Could not retrieve UserData"); return sa.ThrowError(sqT("getVarInfo: Could not retrieve UserData")); // Results in variable not being found error. } // if vr = (VarRefPtr)data; return SQ_OK; } // getVarInfo
static int getInstanceVarInfo(StackHandler & sa,VarRefPtr & vr,SQUserPointer & data) { HSQOBJECT ho = sa.GetObjectHandle(1); SquirrelObject instance(ho); #ifdef _DEBUG SQObjectType type = (SQObjectType)sa.GetType(2); #endif const SQChar * el = sa.GetString(2); ScriptStringVar256 varNameTag; getVarNameTag(varNameTag,sizeof(varNameTag),el); SQUserPointer ivrData=0; if (!instance.RawGetUserData(varNameTag,&ivrData)) { // throw SquirrelError("getInstanceVarInfo: Could not retrieve UserData"); return sa.ThrowError(_T("getInstanceVarInfo: Could not retrieve UserData")); // Results in variable not being found error. } // if vr = (VarRefPtr)ivrData; unsigned char * up; if (!(vr->access & (VAR_ACCESS_STATIC|VAR_ACCESS_CONSTANT))) { #ifdef SQ_USE_CLASS_INHERITANCE SQUserPointer typetag; instance.GetTypeTag(&typetag); if (typetag != vr->instanceType) { SquirrelObject typeTable = instance.GetValue(SQ_CLASS_OBJECT_TABLE_NAME); up = (unsigned char *)typeTable.GetUserPointer(INT((size_t)vr->instanceType)); // <TODO> 64-bit compatible version. if (!up) { #if defined( MONASQ ) return sa.ThrowError(_T("Invalid Instance Type")); #else throw SquirrelError(_T("Invalid Instance Type")); #endif } // if } else { up = (unsigned char *)instance.GetInstanceUP(0); } // if #else up = (unsigned char *)instance.GetInstanceUP(0); #endif up += (size_t)vr->offsetOrAddrOrConst; // Offset } else { up = (unsigned char *)vr->offsetOrAddrOrConst; // Address } // if data = up; return SQ_OK; } // getInstanceVarInfo
static int setVar(StackHandler & sa,VarRef * vr,void * data) { if (vr->access & (VAR_ACCESS_READ_ONLY|VAR_ACCESS_CONSTANT)) { ScriptStringVar256 msg; const SQChar * el = sa.GetString(2); SCSNPRINTF(msg.s,sizeof(msg),_T("setVar(): Cannot write to constant: %s"),el); #if defined( MONASQ ) return sa.ThrowError(msg.s); #else throw SquirrelError(msg.s); #endif } // if switch (vr->type) { case TypeInfo<INT>::TypeID: { INT * val = (INT *)data; // Address if (val) { *val = sa.GetInt(3); return sa.Return(*val); } // if break; } // case case TypeInfo<FLOAT>::TypeID: { FLOAT * val = (FLOAT *)data; // Address if (val) { *val = sa.GetFloat(3); return sa.Return(*val); } // if break; } // case case TypeInfo<bool>::TypeID: { bool * val = (bool *)data; // Address if (val) { *val = sa.GetBool(3) ? true : false; return sa.Return(*val); } // if break; } // case case VAR_TYPE_INSTANCE: { HSQUIRRELVM v = sa.GetVMPtr(); // vr->copyFunc is the LHS variable type: the RHS var's type is ClassType<>::type() (both point to ClassType<>::copy()). // src will be null if the LHS and RHS types don't match. SQUserPointer src = sa.GetInstanceUp(3,(SQUserPointer)vr->copyFunc); // Effectively performs: ClassType<>::type() == ClassType<>getCopyFunc(). #if defined( MONASQ ) if (!src) return sa.ThrowError(_T("INSTANCE type assignment mismatch")); #else if (!src) throw SquirrelError(_T("INSTANCE type assignment mismatch")); #endif vr->copyFunc(data,src); #if 0 // Return an instance on the stack (allocates memory) if (!CreateNativeClassInstance(sa.GetVMPtr(),vr->typeName,data,0)) { // data = address ScriptStringVar256 msg; SCSNPRINTF(msg.s,sizeof(msg),_T("getVar(): Could not create instance: %s"),vr->typeName); throw SquirrelError(msg.s); } // if return 1; #else // Don't return on stack. return 0; #endif } case TypeInfo<SQUserPointer>::TypeID: { ScriptStringVar256 msg; const SQChar * el = sa.GetString(2); SCSNPRINTF(msg.s,sizeof(msg),_T("setVar(): Cannot write to an SQUserPointer: %s"),el); #if defined( MONASQ ) return sa.ThrowError(msg.s); #else throw SquirrelError(msg.s); #endif } // case case TypeInfo<ScriptStringVarBase>::TypeID: { ScriptStringVarBase * val = (ScriptStringVarBase *)data; // Address if (val) { const SQChar * strVal = sa.GetString(3); if (strVal) { *val = strVal; return sa.Return(val->s); } // if } // if break; } // case } // switch return SQ_ERROR; } // setVar
static int getVar(StackHandler & sa,VarRef * vr,void * data) { switch (vr->type) { case TypeInfo<INT>::TypeID: { if (!(vr->access & VAR_ACCESS_CONSTANT)) { INT * val = (INT *)data; // Address if (val) { return sa.Return(*val); } // if } else { INT * val = (INT *)&data; // Constant value return sa.Return(*val); } // if break; } // case case TypeInfo<FLOAT>::TypeID: { if (!(vr->access & VAR_ACCESS_CONSTANT)) { FLOAT * val = (FLOAT *)data; // Address if (val) { return sa.Return(*val); } // if } else { FLOAT * val = (FLOAT *)&data; // Constant value return sa.Return(*val); } // if break; } // case case TypeInfo<bool>::TypeID: { if (!(vr->access & VAR_ACCESS_CONSTANT)) { bool * val = (bool *)data; // Address if (val) { return sa.Return(*val); } // if } else { bool * val = (bool *)&data; // Constant value return sa.Return(*val); } // if break; } // case case VAR_TYPE_INSTANCE: if (!CreateNativeClassInstance(sa.GetVMPtr(),vr->typeName,data,0)) { // data = address. Allocates memory. ScriptStringVar256 msg; SCSNPRINTF(msg.s,sizeof(msg),_T("getVar(): Could not create instance: %s"),vr->typeName); #if defined( MONASQ ) return sa.ThrowError(msg.s); #else throw SquirrelError(msg.s); #endif } // if return 1; case TypeInfo<SQUserPointer>::TypeID: { return sa.Return(data); // The address of member variable, not the variable itself. } // case case TypeInfo<ScriptStringVarBase>::TypeID: { if (!(vr->access & VAR_ACCESS_CONSTANT)) { ScriptStringVarBase * val = (ScriptStringVarBase *)data; // Address if (val) { return sa.Return(val->s); } // if } else { #if defined( MONASQ ) return sa.ThrowError(_T("getVar(): Invalid type+access: 'ScriptStringVarBase' with VAR_ACCESS_CONSTANT (use VAR_ACCESS_READ_ONLY instead)")); #else throw SquirrelError(_T("getVar(): Invalid type+access: 'ScriptStringVarBase' with VAR_ACCESS_CONSTANT (use VAR_ACCESS_READ_ONLY instead)")); #endif } // if break; } // case case TypeInfo<const SQChar *>::TypeID: { if (!(vr->access & VAR_ACCESS_CONSTANT)) { #if defined( MONASQ ) return sa.ThrowError(_T("getVar(): Invalid type+access: 'const SQChar *' without VAR_ACCESS_CONSTANT")); #else throw SquirrelError(_T("getVar(): Invalid type+access: 'const SQChar *' without VAR_ACCESS_CONSTANT")); #endif } else { return sa.Return((const SQChar *)data); // Address } // if break; } // case } // switch return SQ_ERROR; } // getVar
void StackTreeView::contextMenuEvent(QContextMenuEvent *ev) { DebuggerEngine *engine = currentEngine(); StackHandler *handler = engine->stackHandler(); const QModelIndex index = indexAt(ev->pos()); const int row = index.row(); StackFrame frame; if (row >= 0 && row < handler->stackSize()) frame = handler->frameAt(row); const quint64 address = frame.address; QMenu menu; menu.addAction(action(ExpandStack)); QAction *actCopyContents = menu.addAction(tr("Copy Contents to Clipboard")); actCopyContents->setEnabled(model() != 0); QAction *actSaveTaskFile = menu.addAction(tr("Save as Task File...")); actSaveTaskFile->setEnabled(model() != 0); if (engine->hasCapability(CreateFullBacktraceCapability)) menu.addAction(action(CreateFullBacktrace)); QAction *additionalQmlStackAction = 0; if (engine->hasCapability(AdditionalQmlStackCapability)) additionalQmlStackAction = menu.addAction(tr("Load QML Stack")); QAction *actShowMemory = 0; if (engine->hasCapability(ShowMemoryCapability)) { actShowMemory = menu.addAction(QString()); if (address == 0) { actShowMemory->setText(tr("Open Memory Editor")); actShowMemory->setEnabled(false); } else { actShowMemory->setText(tr("Open Memory Editor at 0x%1").arg(address, 0, 16)); actShowMemory->setEnabled(engine->hasCapability(ShowMemoryCapability)); } } QAction *actShowDisassemblerAt = 0; QAction *actShowDisassemblerAtAddress = 0; QAction *actShowDisassemblerAtFunction = 0; if (engine->hasCapability(DisassemblerCapability)) { actShowDisassemblerAt = menu.addAction(QString()); actShowDisassemblerAtAddress = menu.addAction(tr("Open Disassembler at Address...")); actShowDisassemblerAtFunction = menu.addAction(tr("Disassemble Function...")); if (address == 0) { actShowDisassemblerAt->setText(tr("Open Disassembler")); actShowDisassemblerAt->setEnabled(false); } else { actShowDisassemblerAt->setText(tr("Open Disassembler at 0x%1").arg(address, 0, 16)); } } QAction *actLoadSymbols = 0; if (engine->hasCapability(ShowModuleSymbolsCapability)) actLoadSymbols = menu.addAction(tr("Try to Load Unknown Symbols")); if (engine->hasCapability(MemoryAddressCapability)) menu.addAction(action(UseAddressInStackView)); menu.addSeparator(); menu.addAction(action(UseToolTipsInStackView)); menu.addSeparator(); menu.addAction(action(SettingsDialog)); QAction *act = menu.exec(ev->globalPos()); if (!act) return; if (act == actCopyContents) { copyContentsToClipboard(); } else if (act == actShowMemory) { MemoryViewSetupData data; data.startAddress = address; data.title = tr("Memory at Frame #%1 (%2) 0x%3"). arg(row).arg(frame.function).arg(address, 0, 16); data.markup.push_back(MemoryMarkup(address, 1, QColor(Qt::blue).lighter(), tr("Frame #%1 (%2)").arg(row).arg(frame.function))); engine->openMemoryView(data); } else if (act == actShowDisassemblerAtAddress) { AddressDialog dialog; if (address) dialog.setAddress(address); if (dialog.exec() == QDialog::Accepted) currentEngine()->openDisassemblerView(Location(dialog.address())); } else if (act == actShowDisassemblerAtFunction) { const StackFrame frame = inputFunctionForDisassembly(); if (!frame.function.isEmpty()) currentEngine()->openDisassemblerView(Location(frame)); } else if (act == actShowDisassemblerAt) engine->openDisassemblerView(frame); else if (act == actLoadSymbols) engine->loadSymbolsForStack(); else if (act == actSaveTaskFile) saveTaskFile(this, handler); else if (act == additionalQmlStackAction) engine->loadAdditionalQmlStack(); }
void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload) { switch (f) { default: { showMessage(QLatin1String("IPC Error: unhandled id in guest to host call")); const QString logMessage = tr("Fatal engine shutdown. Incompatible binary or IPC error."); showMessage(logMessage, LogError); showStatusMessage(logMessage); } nuke(); break; case IPCEngineGuest::NotifyEngineSetupOk: notifyEngineSetupOk(); break; case IPCEngineGuest::NotifyEngineSetupFailed: notifyEngineSetupFailed(); break; case IPCEngineGuest::NotifyEngineRunFailed: notifyEngineRunFailed(); break; case IPCEngineGuest::NotifyInferiorSetupOk: attemptBreakpointSynchronization(); notifyInferiorSetupOk(); break; case IPCEngineGuest::NotifyInferiorSetupFailed: notifyInferiorSetupFailed(); break; case IPCEngineGuest::NotifyEngineRunAndInferiorRunOk: notifyEngineRunAndInferiorRunOk(); break; case IPCEngineGuest::NotifyEngineRunAndInferiorStopOk: notifyEngineRunAndInferiorStopOk(); break; case IPCEngineGuest::NotifyInferiorRunRequested: notifyInferiorRunRequested(); break; case IPCEngineGuest::NotifyInferiorRunOk: notifyInferiorRunOk(); break; case IPCEngineGuest::NotifyInferiorRunFailed: notifyInferiorRunFailed(); break; case IPCEngineGuest::NotifyInferiorStopOk: notifyInferiorStopOk(); break; case IPCEngineGuest::NotifyInferiorSpontaneousStop: notifyInferiorSpontaneousStop(); break; case IPCEngineGuest::NotifyInferiorStopFailed: notifyInferiorStopFailed(); break; case IPCEngineGuest::NotifyInferiorExited: notifyInferiorExited(); break; case IPCEngineGuest::NotifyInferiorShutdownOk: notifyInferiorShutdownOk(); break; case IPCEngineGuest::NotifyInferiorShutdownFailed: notifyInferiorShutdownFailed(); break; case IPCEngineGuest::NotifyEngineSpontaneousShutdown: notifyEngineSpontaneousShutdown(); break; case IPCEngineGuest::NotifyEngineShutdownOk: notifyEngineShutdownOk(); break; case IPCEngineGuest::NotifyEngineShutdownFailed: notifyEngineShutdownFailed(); break; case IPCEngineGuest::NotifyInferiorIll: notifyInferiorIll(); break; case IPCEngineGuest::NotifyEngineIll: notifyEngineIll(); break; case IPCEngineGuest::NotifyInferiorPid: { QDataStream s(payload); SET_NATIVE_BYTE_ORDER(s); quint64 pid; s >> pid; notifyInferiorPid(pid); } break; case IPCEngineGuest::ShowStatusMessage: { QDataStream s(payload); SET_NATIVE_BYTE_ORDER(s); QString msg; qint64 timeout; s >> msg; s >> timeout; showStatusMessage(msg, timeout); } break; case IPCEngineGuest::ShowMessage: { QDataStream s(payload); SET_NATIVE_BYTE_ORDER(s); QString msg; qint16 channel; qint64 timeout; s >> msg; s >> channel; s >> timeout; showMessage(msg, channel, timeout); } break; case IPCEngineGuest::CurrentFrameChanged: { QDataStream s(payload); SET_NATIVE_BYTE_ORDER(s); quint64 token; s >> token; resetLocation(); StackHandler *sh = stackHandler(); sh->setCurrentIndex(token); if (!sh->currentFrame().isUsable() || QFileInfo(sh->currentFrame().file).exists()) gotoLocation(Location(sh->currentFrame(), true)); else if (!m_sourceAgents.contains(sh->currentFrame().file)) fetchFrameSource(token); foreach(SourceAgent *agent, m_sourceAgents.values()) agent->updateLocationMarker(); } break; case IPCEngineGuest::CurrentThreadChanged: { QDataStream s(payload); SET_NATIVE_BYTE_ORDER(s); quint64 token; s >> token; threadsHandler()->setCurrentThreadId(token); } break; case IPCEngineGuest::ListFrames: { QDataStream s(payload); SET_NATIVE_BYTE_ORDER(s); StackFrames frames; s >> frames; stackHandler()->setFrames(frames); } break; case IPCEngineGuest::ListThreads: { QDataStream s(payload); SET_NATIVE_BYTE_ORDER(s); Threads threads; s >> threads; threadsHandler()->setThreads(threads); } break; case IPCEngineGuest::Disassembled: { QDataStream s(payload); SET_NATIVE_BYTE_ORDER(s); quint64 pc; DisassemblerLines lines; s >> pc; s >> lines; DisassemblerAgent *view = m_frameToDisassemblerAgent.take(pc); if (view) view->setContents(lines); } break; case IPCEngineGuest::UpdateWatchData: { QDataStream s(payload); SET_NATIVE_BYTE_ORDER(s); bool fullCycle; qint64 count; QList<WatchData> wd; s >> fullCycle; s >> count; for (qint64 i = 0; i < count; ++i) { WatchData d; s >> d; wd.append(d); } WatchHandler *wh = watchHandler(); if (!wh) break; wh->beginCycle(fullCycle); wh->insertBulkData(wd); wh->endCycle(fullCycle); } break; case IPCEngineGuest::NotifyAddBreakpointOk: { attemptBreakpointSynchronization(); QDataStream s(payload); SET_NATIVE_BYTE_ORDER(s); BreakpointId id; s >> id; breakHandler()->notifyBreakpointInsertOk(id); } break; case IPCEngineGuest::NotifyAddBreakpointFailed: { QDataStream s(payload); SET_NATIVE_BYTE_ORDER(s); BreakpointId id; s >> id; breakHandler()->notifyBreakpointInsertFailed(id); } break; case IPCEngineGuest::NotifyRemoveBreakpointOk: { QDataStream s(payload); SET_NATIVE_BYTE_ORDER(s); BreakpointId id; s >> id; breakHandler()->notifyBreakpointRemoveOk(id); } break; case IPCEngineGuest::NotifyRemoveBreakpointFailed: { QDataStream s(payload); SET_NATIVE_BYTE_ORDER(s); BreakpointId id; s >> id; breakHandler()->notifyBreakpointRemoveFailed(id); } break; case IPCEngineGuest::NotifyChangeBreakpointOk: { QDataStream s(payload); SET_NATIVE_BYTE_ORDER(s); BreakpointId id; s >> id; breakHandler()->notifyBreakpointChangeOk(id); } break; case IPCEngineGuest::NotifyChangeBreakpointFailed: { QDataStream s(payload); SET_NATIVE_BYTE_ORDER(s); BreakpointId id; s >> id; breakHandler()->notifyBreakpointChangeFailed(id); } break; case IPCEngineGuest::NotifyBreakpointAdjusted: { QDataStream s(payload); SET_NATIVE_BYTE_ORDER(s); BreakpointId id; BreakpointParameters d; s >> id >> d; breakHandler()->notifyBreakpointAdjusted(id, d); } break; case IPCEngineGuest::FrameSourceFetched: { QDataStream s(payload); SET_NATIVE_BYTE_ORDER(s); qint64 token; QString path; QString source; s >> token >> path >> source; SourceAgent *agent = new SourceAgent(this); agent->setSourceProducerName(startParameters().connParams.host); agent->setContent(path, source); m_sourceAgents.insert(path, agent); agent->updateLocationMarker(); } break; } }
static int setVar(StackHandler & sa,VarRef * vr,void * data) { if (vr->m_access & (VAR_ACCESS_READ_ONLY|VAR_ACCESS_CONSTANT)) { const SQChar * el = sa.GetString(2); SCSNPRINTF(g_msg_throw.s,sizeof(g_msg_throw),_SC("setVar(): Cannot write to constant: %s"),el); throw SquirrelError(g_msg_throw.s); } // if switch (vr->m_type) { case TypeInfo<INT>::TypeID: { INT * val = (INT *)data; // Address if (val) { INT v = sa.GetInt(3); // Support for different int sizes switch( vr->m_size ) { case 1: v = (*(char*)val = (char)v); break; case 2: v = (*(short*)val = (short)v); break; #ifdef _SQ64 case 4: v = (*(int*)val = (int)v); break; #endif default: *val = v; } return sa.Return(v); } // if break; } // case case TypeInfo<unsigned>::TypeID: { unsigned * val = (unsigned *)data; // Address if (val) { *val = sa.GetInt(3); return sa.Return(static_cast<INT>(*val)); } // if break; } // case case TypeInfo<FLOAT>::TypeID: { FLOAT * val = (FLOAT *)data; // Address if (val) { *val = sa.GetFloat(3); return sa.Return(*val); } // if break; } // case case TypeInfo<bool>::TypeID: { bool * val = (bool *)data; // Address if (val) { *val = sa.GetBool(3) ? true : false; return sa.Return(*val); } // if break; } // case case VAR_TYPE_INSTANCE: { HSQUIRRELVM v = sa.GetVMPtr(); SQUserPointer src = sa.GetInstanceUp(3,(SQUserPointer)vr->varType); // Effectively performs: ClassType<>::type() == ClassType<>(). if (!src) { throw SquirrelError(_SC("INSTANCE type assignment mismatch")); } vr->varType->vgetCopyFunc()(data,src); return 0; } case TypeInfo<SQUserPointer>::TypeID: { const SQChar * el = sa.GetString(2); SCSNPRINTF(g_msg_throw.s,sizeof(g_msg_throw),_SC("setVar(): Cannot write to an SQUserPointer: %s"),el); throw SquirrelError(g_msg_throw.s); } // case case TypeInfo<ScriptStringVarBase>::TypeID: { ScriptStringVarBase * val = (ScriptStringVarBase *)data; // Address if (val) { const SQChar * strVal = sa.GetString(3); if (strVal) { *val = strVal; return sa.Return(val->s); } // if } // if break; } // case #if defined(SQPLUS_SUPPORT_STD_STRING) && !defined(SQUNICODE) case TypeInfo<std::string>::TypeID: { std::string *val = (std::string*)data; // Address if (val) { const SQChar *strVal = sa.GetString(3); if (strVal) { *val = strVal; return sa.Return(val->c_str()); } // if } // if break; } // case #endif } // switch return SQ_ERROR; } // setVar
static int getVar(StackHandler & sa,VarRef * vr,void * data) { switch (vr->m_type) { case TypeInfo<INT>::TypeID: { if (!(vr->m_access & VAR_ACCESS_CONSTANT)) { if (data) { INT v; // Support for different int sizes switch( vr->m_size ){ case 1: v = *(char*)data; break; case 2: v = *(short*)data; break; #ifdef _SQ64 case 4: v = *(int*)data; break; #endif default: v = *(INT*)data; } return sa.Return(v); } // if } else { INT * val = (INT *)&data; // Constant value return sa.Return(*val); } // if break; } // case case TypeInfo<unsigned>::TypeID: { if (!(vr->m_access & VAR_ACCESS_CONSTANT)) { unsigned * val = (unsigned *)data; // Address if (val){ return sa.Return(static_cast<INT>(*val)); } } else { unsigned * val = (unsigned *)&data; // Constant value return sa.Return(static_cast<INT>(*val)); } // if break; } // case case TypeInfo<FLOAT>::TypeID: { if (!(vr->m_access & VAR_ACCESS_CONSTANT)) { FLOAT * val = (FLOAT *)data; // Address if (val) { return sa.Return(*val); } // if } else { FLOAT * val = (FLOAT *)&data; // Constant value return sa.Return(*val); } // if break; } // case case TypeInfo<bool>::TypeID: { if (!(vr->m_access & VAR_ACCESS_CONSTANT)) { bool * val = (bool *)data; // Address if (val) { return sa.Return(*val); } // if } else { bool * val = (bool *)&data; // Constant value return sa.Return(*val); } // if break; } // case case VAR_TYPE_INSTANCE: if (!CreateNativeClassInstance(sa.GetVMPtr(),vr->varType->GetTypeName(),data,0)) { // data = address. Allocates memory. SCSNPRINTF(g_msg_throw.s,sizeof(g_msg_throw),_SC("getVar(): Could not create instance: %s"),vr->varType->GetTypeName()); throw SquirrelError(g_msg_throw.s); } // if return 1; case TypeInfo<SQUserPointer>::TypeID: return sa.Return(data); // The address of member variable, not the variable itself. case TypeInfo<ScriptStringVarBase>::TypeID: { if (!(vr->m_access & VAR_ACCESS_CONSTANT)) { ScriptStringVarBase * val = (ScriptStringVarBase *)data; // Address if (val) { return sa.Return(val->s); } // if } else { throw SquirrelError(_SC("getVar(): Invalid type+access: 'ScriptStringVarBase' with VAR_ACCESS_CONSTANT (use VAR_ACCESS_READ_ONLY instead)")); } break; } // case case TypeInfo<const SQChar *>::TypeID: { if (!(vr->m_access & VAR_ACCESS_CONSTANT)) { if( vr->m_access==VAR_ACCESS_READ_WRITE ) throw SquirrelError(_SC("getVar(): Invalid type+access: 'const SQChar *' without VAR_ACCESS_CONSTANT")); // It is OK to read from a SQChar* if requested return sa.Return(*(const SQChar **)data); // Address } else { return sa.Return((const SQChar *)data); // Address } break; } // case #ifdef SQPLUS_SUPPORT_STD_STRING case TypeInfo<std::string>::TypeID: { if (!(vr->m_access & VAR_ACCESS_CONSTANT)) { std::string *val = (std::string *)data; // Address if (val) { return sa.Return(val->c_str()); } } else { throw SquirrelError(_SC("getVar(): Invalid type+access: 'std::string' with VAR_ACCESS_CONSTANT (use VAR_ACCESS_READ_ONLY instead)")); } break; } // case #endif } // switch return SQ_ERROR; } // getVar