1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_basic.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <stdio.h> 32*cdf0e10cSrcweir #include <string.h> 33*cdf0e10cSrcweir #include <tools/stream.hxx> 34*cdf0e10cSrcweir #include <basic/sbx.hxx> 35*cdf0e10cSrcweir #include "sb.hxx" 36*cdf0e10cSrcweir #include "iosys.hxx" 37*cdf0e10cSrcweir #include "disas.hxx" 38*cdf0e10cSrcweir #include "sbtrace.hxx" 39*cdf0e10cSrcweir 40*cdf0e10cSrcweir 41*cdf0e10cSrcweir static const char* pOp1[] = { 42*cdf0e10cSrcweir "NOP", 43*cdf0e10cSrcweir 44*cdf0e10cSrcweir // Operators 45*cdf0e10cSrcweir // the following operators have the same order as in 46*cdf0e10cSrcweir // enum SbxVarOp 47*cdf0e10cSrcweir "EXP", "MUL", "DIV", "MOD", "PLUS", "MINUS", "NEG", 48*cdf0e10cSrcweir "EQ", "NE", "LT", "GT", "LE", "GE", 49*cdf0e10cSrcweir "IDIV", "AND", "OR", "XOR", "EQV", "IMP", "NOT", 50*cdf0e10cSrcweir "CAT", 51*cdf0e10cSrcweir // End enum SbxVarOp 52*cdf0e10cSrcweir "LIKE", "IS", 53*cdf0e10cSrcweir // Load/Store 54*cdf0e10cSrcweir "ARGC", // Create new Argv 55*cdf0e10cSrcweir "ARGV", // TOS ==> current Argv 56*cdf0e10cSrcweir "INPUT", // Input ==> TOS 57*cdf0e10cSrcweir "LINPUT", // Line Input ==> TOS 58*cdf0e10cSrcweir "GET", // get TOS 59*cdf0e10cSrcweir "SET", // Save Object TOS ==> TOS-1 60*cdf0e10cSrcweir "PUT", // TOS ==> TOS-1 61*cdf0e10cSrcweir "CONST", // TOS ==> TOS-1, then ReadOnly 62*cdf0e10cSrcweir "DIM", // DIM 63*cdf0e10cSrcweir "REDIM", // REDIM 64*cdf0e10cSrcweir "REDIMP", // REDIM PRESERVE 65*cdf0e10cSrcweir "ERASE", // delete TOS 66*cdf0e10cSrcweir // Branch 67*cdf0e10cSrcweir "STOP", // End of program 68*cdf0e10cSrcweir "INITFOR", // FOR-Variable init 69*cdf0e10cSrcweir "NEXT", // FOR-Variable increment 70*cdf0e10cSrcweir "CASE", // Begin CASE 71*cdf0e10cSrcweir "ENDCASE", // End CASE 72*cdf0e10cSrcweir "STDERR", // Default error handling 73*cdf0e10cSrcweir "NOERROR", // No error handling 74*cdf0e10cSrcweir "LEAVE", // leave UP 75*cdf0e10cSrcweir // I/O 76*cdf0e10cSrcweir "CHANNEL", // TOS = Channelnumber 77*cdf0e10cSrcweir "PRINT", // print TOS 78*cdf0e10cSrcweir "PRINTF", // print TOS in field 79*cdf0e10cSrcweir "WRITE", // write TOS 80*cdf0e10cSrcweir "RENAME", // Rename Tos+1 to Tos 81*cdf0e10cSrcweir "PROMPT", // TOS = Prompt for Input 82*cdf0e10cSrcweir "RESTART", // Define restart point 83*cdf0e10cSrcweir "STDIO", // Switch to I/O channel 0 84*cdf0e10cSrcweir // Misc 85*cdf0e10cSrcweir "EMPTY", // Empty statement to stack 86*cdf0e10cSrcweir "ERROR", // TOS = error code 87*cdf0e10cSrcweir "LSET", // Save object TOS ==> TOS-1 88*cdf0e10cSrcweir "RSET", // Save object TOS ==> TOS-1 (TODO: Same as above?) 89*cdf0e10cSrcweir "REDIMP_ERASE", 90*cdf0e10cSrcweir "INITFOREACH", 91*cdf0e10cSrcweir "VBASET", 92*cdf0e10cSrcweir "ERASE_CLEAR", 93*cdf0e10cSrcweir "ARRAYACCESS", 94*cdf0e10cSrcweir "BYVAL" 95*cdf0e10cSrcweir }; 96*cdf0e10cSrcweir 97*cdf0e10cSrcweir static const char* pOp2[] = { 98*cdf0e10cSrcweir "NUMBER", // Load a numeric constant (+ID) 99*cdf0e10cSrcweir "STRING", // Load a string constant (+ID) 100*cdf0e10cSrcweir "CONSTANT", // Immediate Load (+value) 101*cdf0e10cSrcweir "ARGN", // Save named args in argv (+StringID) 102*cdf0e10cSrcweir "PAD", // Pad String to defined length (+length) 103*cdf0e10cSrcweir // Branches 104*cdf0e10cSrcweir "JUMP", // Jump to target (+Target) 105*cdf0e10cSrcweir "JUMP.T", // evaluate TOS, conditional jump (+Target) 106*cdf0e10cSrcweir "JUMP.F", // evaluate TOS, conditional jump (+Target) 107*cdf0e10cSrcweir "ONJUMP", // evaluate TOS, jump into JUMP-table (+MaxVal) 108*cdf0e10cSrcweir "GOSUB", // UP-Call (+Target) 109*cdf0e10cSrcweir "RETURN", // UP-Return (+0 or Target) 110*cdf0e10cSrcweir "TESTFOR", // Test FOR-Variable, increment (+Endlabel) 111*cdf0e10cSrcweir "CASETO", // Tos+1 <= Case <= Tos, 2xremove (+Target) 112*cdf0e10cSrcweir "ERRHDL", // Error-Handler (+Offset) 113*cdf0e10cSrcweir "RESUME", // Resume after errors (+0 or 1 or Label) 114*cdf0e10cSrcweir // I/O 115*cdf0e10cSrcweir "CLOSE", // (+channel/0) 116*cdf0e10cSrcweir "PRCHAR", // (+char) 117*cdf0e10cSrcweir // Objects 118*cdf0e10cSrcweir "SETCLASS", // Test Set + Classname (+StringId) 119*cdf0e10cSrcweir "TESTCLASS", // Check TOS class (+StringId) 120*cdf0e10cSrcweir "LIB", // Set Libname for Declare-Procs (+StringId) 121*cdf0e10cSrcweir // New since Beta 3 (TODO: Which Beta3?) 122*cdf0e10cSrcweir "BASED", // TOS is incremted about BASE, push BASE before 123*cdf0e10cSrcweir "ARGTYP", // Convert last parameter in argv (+Type) 124*cdf0e10cSrcweir "VBASETCLASS", 125*cdf0e10cSrcweir }; 126*cdf0e10cSrcweir 127*cdf0e10cSrcweir static const char* pOp3[] = { 128*cdf0e10cSrcweir // All opcodes with two operands 129*cdf0e10cSrcweir "RTL", // Load from RTL (+StringID+Typ) 130*cdf0e10cSrcweir "FIND", // Load (+StringID+Typ) 131*cdf0e10cSrcweir "ELEM", // Load element (+StringID+Typ) 132*cdf0e10cSrcweir "PARAM", // Parameter (+Offset+Typ) 133*cdf0e10cSrcweir 134*cdf0e10cSrcweir // Branching 135*cdf0e10cSrcweir "CALL", // Call DECLARE method (+StringID+Typ) 136*cdf0e10cSrcweir "CALL.C", // Call Cdecl-DECLARE method (+StringID+Typ) 137*cdf0e10cSrcweir "CASEIS", // Case-Test (+Test-Opcode+False-Target) 138*cdf0e10cSrcweir "STMNT", // Start of a statement (+Line+Col) 139*cdf0e10cSrcweir 140*cdf0e10cSrcweir // I/O 141*cdf0e10cSrcweir "OPEN", // (+SvStreamFlags+Flags) 142*cdf0e10cSrcweir 143*cdf0e10cSrcweir // Objects and variables 144*cdf0e10cSrcweir "LOCAL", // Local variables (+StringID+Typ) 145*cdf0e10cSrcweir "PUBLIC", // Modul global var (+StringID+Typ) 146*cdf0e10cSrcweir "GLOBAL", // Global var (+StringID+Typ) 147*cdf0e10cSrcweir "CREATE", // Create object (+StringId+StringId) 148*cdf0e10cSrcweir "STATIC", // Create static object (+StringId+StringId) 149*cdf0e10cSrcweir "TCREATE", // Create User defined Object (+StringId+StringId) 150*cdf0e10cSrcweir "DCREATE", // Create User defined Object-Array kreieren (+StringId+StringId) 151*cdf0e10cSrcweir "GLOBAL_P", // Define persistent global var (existing after basic restart) 152*cdf0e10cSrcweir // P=PERSIST (+StringID+Typ) 153*cdf0e10cSrcweir "FIND_G", // Searches for global var with special handling due to _GLOBAL_P 154*cdf0e10cSrcweir "DCREATE_REDIMP", // Change dimensions of a user defined Object-Array (+StringId+StringId) 155*cdf0e10cSrcweir "FIND_CM", // Search inside a class module (CM) to enable global search in time 156*cdf0e10cSrcweir "PUBLIC_P", // Module global Variable (persisted between calls)(+StringID+Typ) 157*cdf0e10cSrcweir "FIND_STATIC", // local static var lookup (+StringID+Typ) 158*cdf0e10cSrcweir }; 159*cdf0e10cSrcweir 160*cdf0e10cSrcweir static const char** pOps[3] = { pOp1, pOp2, pOp3 }; 161*cdf0e10cSrcweir 162*cdf0e10cSrcweir typedef void( SbiDisas::*Func )( String& ); // Processing routines 163*cdf0e10cSrcweir 164*cdf0e10cSrcweir static const Func pOperand2[] = { 165*cdf0e10cSrcweir &SbiDisas::StrOp, // Load a numeric constant (+ID) 166*cdf0e10cSrcweir &SbiDisas::StrOp, // Load a string constant (+ID) 167*cdf0e10cSrcweir &SbiDisas::ImmOp, // Immediate Load (+Wert) 168*cdf0e10cSrcweir &SbiDisas::StrOp, // Save a named argument (+ID) 169*cdf0e10cSrcweir &SbiDisas::ImmOp, // Strip String to fixed size (+length) 170*cdf0e10cSrcweir 171*cdf0e10cSrcweir // Branches 172*cdf0e10cSrcweir &SbiDisas::LblOp, // Jump (+Target) 173*cdf0e10cSrcweir &SbiDisas::LblOp, // eval TOS, conditional jump (+Target) 174*cdf0e10cSrcweir &SbiDisas::LblOp, // eval TOS, conditional jump (+Target) 175*cdf0e10cSrcweir &SbiDisas::OnOp, // eval TOS, jump in JUMP table (+MaxVal) 176*cdf0e10cSrcweir &SbiDisas::LblOp, // UP call (+Target) 177*cdf0e10cSrcweir &SbiDisas::ReturnOp, // UP Return (+0 or Target) 178*cdf0e10cSrcweir &SbiDisas::LblOp, // test FOR-Variable, increment (+Endlabel) 179*cdf0e10cSrcweir &SbiDisas::LblOp, // Tos+1 <= Case <= Tos), 2xremove (+Target) 180*cdf0e10cSrcweir &SbiDisas::LblOp, // Error handler (+Offset) 181*cdf0e10cSrcweir &SbiDisas::ResumeOp, // Resume after errors (+0 or 1 or Label) 182*cdf0e10cSrcweir 183*cdf0e10cSrcweir // I/O 184*cdf0e10cSrcweir &SbiDisas::CloseOp, // (+channel/0) 185*cdf0e10cSrcweir &SbiDisas::CharOp, // (+char) 186*cdf0e10cSrcweir 187*cdf0e10cSrcweir // Objects 188*cdf0e10cSrcweir &SbiDisas::StrOp, // Test classname (+StringId) 189*cdf0e10cSrcweir &SbiDisas::StrOp, // TESTCLASS, Check TOS class (+StringId) 190*cdf0e10cSrcweir &SbiDisas::StrOp, // Set libname for declare procs (+StringId) 191*cdf0e10cSrcweir &SbiDisas::ImmOp, // TOS is incremented about BASE erhoeht, BASE pushed before 192*cdf0e10cSrcweir &SbiDisas::TypeOp, // Convert last parameter to/in(?) argv (+Typ) 193*cdf0e10cSrcweir &SbiDisas::StrOp, // VBASETCLASS (+StringId) 194*cdf0e10cSrcweir }; 195*cdf0e10cSrcweir 196*cdf0e10cSrcweir static const Func pOperand3[] = { 197*cdf0e10cSrcweir // All opcodes with two operands 198*cdf0e10cSrcweir &SbiDisas::VarOp, // Load from RTL (+StringID+Typ) 199*cdf0e10cSrcweir &SbiDisas::VarOp, // Load (+StringID+Typ) 200*cdf0e10cSrcweir &SbiDisas::VarOp, // Load Element (+StringID+Typ) 201*cdf0e10cSrcweir &SbiDisas::OffOp, // Parameter (+Offset+Typ) 202*cdf0e10cSrcweir 203*cdf0e10cSrcweir // Branch 204*cdf0e10cSrcweir &SbiDisas::VarOp, // Call DECLARE-Method (+StringID+Typ) 205*cdf0e10cSrcweir &SbiDisas::VarOp, // Call CDecl-DECLARE-Methode (+StringID+Typ) 206*cdf0e10cSrcweir &SbiDisas::CaseOp, // Case-Test (+Test-Opcode+False-Target) 207*cdf0e10cSrcweir &SbiDisas::StmntOp, // Statement (+Row+Column) 208*cdf0e10cSrcweir 209*cdf0e10cSrcweir // I/O 210*cdf0e10cSrcweir &SbiDisas::StrmOp, // (+SvStreamFlags+Flags) 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir // Objects 213*cdf0e10cSrcweir &SbiDisas::VarDefOp, // Define local var (+StringID+Typ) 214*cdf0e10cSrcweir &SbiDisas::VarDefOp, // Define Module global var (+StringID+Typ) 215*cdf0e10cSrcweir &SbiDisas::VarDefOp, // Define global var (+StringID+Typ) 216*cdf0e10cSrcweir &SbiDisas::Str2Op, // Create object (+StringId+StringId) 217*cdf0e10cSrcweir &SbiDisas::VarDefOp, // Define static object (+StringID+Typ) 218*cdf0e10cSrcweir &SbiDisas::Str2Op, // Create User defined Object (+StringId+StringId) 219*cdf0e10cSrcweir &SbiDisas::Str2Op, // Create User defined Object-Array (+StringId+StringId) 220*cdf0e10cSrcweir &SbiDisas::VarDefOp, // Define persistent global var P=PERSIST (+StringID+Typ) 221*cdf0e10cSrcweir &SbiDisas::VarOp, // Searches for global var with special handling due to _GLOBAL_P 222*cdf0e10cSrcweir &SbiDisas::Str2Op, // Redimensionate User defined Object-Array (+StringId+StringId) 223*cdf0e10cSrcweir &SbiDisas::VarOp, // FIND_CM 224*cdf0e10cSrcweir &SbiDisas::VarDefOp, // PUBLIC_P 225*cdf0e10cSrcweir &SbiDisas::VarOp, // FIND_STATIC 226*cdf0e10cSrcweir }; 227*cdf0e10cSrcweir 228*cdf0e10cSrcweir // TODO: Why as method? Isn't a simple define sufficient? 229*cdf0e10cSrcweir static const char* _crlf() 230*cdf0e10cSrcweir { 231*cdf0e10cSrcweir #if defined (UNX) || defined( PM2 ) 232*cdf0e10cSrcweir return "\n"; 233*cdf0e10cSrcweir #else 234*cdf0e10cSrcweir return "\r\n"; 235*cdf0e10cSrcweir #endif 236*cdf0e10cSrcweir } 237*cdf0e10cSrcweir 238*cdf0e10cSrcweir // This method exists because we want to load the file as own segment 239*cdf0e10cSrcweir sal_Bool SbModule::Disassemble( String& rText ) 240*cdf0e10cSrcweir { 241*cdf0e10cSrcweir rText.Erase(); 242*cdf0e10cSrcweir if( pImage ) 243*cdf0e10cSrcweir { 244*cdf0e10cSrcweir SbiDisas aDisas( this, pImage ); 245*cdf0e10cSrcweir aDisas.Disas( rText ); 246*cdf0e10cSrcweir } 247*cdf0e10cSrcweir return sal_Bool( rText.Len() != 0 ); 248*cdf0e10cSrcweir } 249*cdf0e10cSrcweir 250*cdf0e10cSrcweir SbiDisas::SbiDisas( SbModule* p, const SbiImage* q ) : rImg( *q ), pMod( p ) 251*cdf0e10cSrcweir { 252*cdf0e10cSrcweir memset( cLabels, 0, 8192 ); 253*cdf0e10cSrcweir nLine = 0; 254*cdf0e10cSrcweir nOff = 0; 255*cdf0e10cSrcweir nPC = 0; 256*cdf0e10cSrcweir nOp1 = nOp2 = nParts = 0; 257*cdf0e10cSrcweir eOp = _NOP; 258*cdf0e10cSrcweir // Set Label-Bits 259*cdf0e10cSrcweir nOff = 0; 260*cdf0e10cSrcweir while( Fetch() ) 261*cdf0e10cSrcweir { 262*cdf0e10cSrcweir switch( eOp ) 263*cdf0e10cSrcweir { 264*cdf0e10cSrcweir case _RESUME: if( nOp1 <= 1 ) break; 265*cdf0e10cSrcweir case _RETURN: if( !nOp1 ) break; 266*cdf0e10cSrcweir case _JUMP: 267*cdf0e10cSrcweir case _JUMPT: 268*cdf0e10cSrcweir case _JUMPF: 269*cdf0e10cSrcweir case _GOSUB: 270*cdf0e10cSrcweir case _TESTFOR: 271*cdf0e10cSrcweir case _CASEIS: 272*cdf0e10cSrcweir case _CASETO: 273*cdf0e10cSrcweir case _ERRHDL: 274*cdf0e10cSrcweir cLabels[ (nOp1 & 0xffff) >> 3 ] |= ( 1 << ( nOp1 & 7 ) ); 275*cdf0e10cSrcweir break; 276*cdf0e10cSrcweir default: break; 277*cdf0e10cSrcweir } 278*cdf0e10cSrcweir } 279*cdf0e10cSrcweir nOff = 0; 280*cdf0e10cSrcweir // Add the publics 281*cdf0e10cSrcweir for( sal_uInt16 i = 0; i < pMod->GetMethods()->Count(); i++ ) 282*cdf0e10cSrcweir { 283*cdf0e10cSrcweir SbMethod* pMeth = PTR_CAST(SbMethod,pMod->GetMethods()->Get( i )); 284*cdf0e10cSrcweir if( pMeth ) 285*cdf0e10cSrcweir { 286*cdf0e10cSrcweir sal_uInt16 nPos = (sal_uInt16) (pMeth->GetId()); 287*cdf0e10cSrcweir cLabels[ nPos >> 3 ] |= ( 1 << ( nPos & 7 ) ); 288*cdf0e10cSrcweir } 289*cdf0e10cSrcweir } 290*cdf0e10cSrcweir } 291*cdf0e10cSrcweir 292*cdf0e10cSrcweir // Read current opcode 293*cdf0e10cSrcweir sal_Bool SbiDisas::Fetch() 294*cdf0e10cSrcweir { 295*cdf0e10cSrcweir nPC = nOff; 296*cdf0e10cSrcweir if( nOff >= rImg.GetCodeSize() ) 297*cdf0e10cSrcweir return sal_False; 298*cdf0e10cSrcweir const unsigned char* p = (const unsigned char*)( rImg.GetCode() + nOff ); 299*cdf0e10cSrcweir eOp = (SbiOpcode) ( *p++ & 0xFF ); 300*cdf0e10cSrcweir if( eOp <= SbOP0_END ) 301*cdf0e10cSrcweir { 302*cdf0e10cSrcweir nOp1 = nOp2 = 0; 303*cdf0e10cSrcweir nParts = 1; 304*cdf0e10cSrcweir nOff++; 305*cdf0e10cSrcweir return sal_True; 306*cdf0e10cSrcweir } 307*cdf0e10cSrcweir else if( eOp <= SbOP1_END ) 308*cdf0e10cSrcweir { 309*cdf0e10cSrcweir nOff += 5; 310*cdf0e10cSrcweir if( nOff > rImg.GetCodeSize() ) 311*cdf0e10cSrcweir return sal_False; 312*cdf0e10cSrcweir nOp1 = *p++; nOp1 |= *p++ << 8; nOp1 |= *p++ << 16; nOp1 |= *p++ << 24; 313*cdf0e10cSrcweir nParts = 2; 314*cdf0e10cSrcweir return sal_True; 315*cdf0e10cSrcweir } 316*cdf0e10cSrcweir else if( eOp <= SbOP2_END ) 317*cdf0e10cSrcweir { 318*cdf0e10cSrcweir nOff += 9; 319*cdf0e10cSrcweir if( nOff > rImg.GetCodeSize() ) 320*cdf0e10cSrcweir return sal_False; 321*cdf0e10cSrcweir nOp1 = *p++; nOp1 |= *p++ << 8; nOp1 |= *p++ << 16; nOp1 |= *p++ << 24; 322*cdf0e10cSrcweir nOp2 = *p++; nOp2 |= *p++ << 8; nOp2 |= *p++ << 16; nOp2 |= *p++ << 24; 323*cdf0e10cSrcweir nParts = 3; 324*cdf0e10cSrcweir return sal_True; 325*cdf0e10cSrcweir } 326*cdf0e10cSrcweir else 327*cdf0e10cSrcweir return sal_False; 328*cdf0e10cSrcweir } 329*cdf0e10cSrcweir 330*cdf0e10cSrcweir void SbiDisas::Disas( SvStream& r ) 331*cdf0e10cSrcweir { 332*cdf0e10cSrcweir String aText; 333*cdf0e10cSrcweir nOff = 0; 334*cdf0e10cSrcweir while( DisasLine( aText ) ) 335*cdf0e10cSrcweir { 336*cdf0e10cSrcweir ByteString aByteText( aText, gsl_getSystemTextEncoding() ); 337*cdf0e10cSrcweir r.WriteLine( aByteText ); 338*cdf0e10cSrcweir } 339*cdf0e10cSrcweir } 340*cdf0e10cSrcweir 341*cdf0e10cSrcweir void SbiDisas::Disas( String& r ) 342*cdf0e10cSrcweir { 343*cdf0e10cSrcweir r.Erase(); 344*cdf0e10cSrcweir String aText; 345*cdf0e10cSrcweir nOff = 0; 346*cdf0e10cSrcweir while( DisasLine( aText ) ) 347*cdf0e10cSrcweir { 348*cdf0e10cSrcweir r += aText; 349*cdf0e10cSrcweir r.AppendAscii( _crlf() ); 350*cdf0e10cSrcweir } 351*cdf0e10cSrcweir aText.ConvertLineEnd(); 352*cdf0e10cSrcweir } 353*cdf0e10cSrcweir 354*cdf0e10cSrcweir sal_Bool SbiDisas::DisasLine( String& rText ) 355*cdf0e10cSrcweir { 356*cdf0e10cSrcweir char cBuf[ 100 ]; 357*cdf0e10cSrcweir const char* pMask[] = { 358*cdf0e10cSrcweir "%08" SAL_PRIXUINT32 " ", 359*cdf0e10cSrcweir "%08" SAL_PRIXUINT32 " %02X ", 360*cdf0e10cSrcweir "%08" SAL_PRIXUINT32 " %02X %08X ", 361*cdf0e10cSrcweir "%08" SAL_PRIXUINT32 " %02X %08X %08X " }; 362*cdf0e10cSrcweir rText.Erase(); 363*cdf0e10cSrcweir if( !Fetch() ) 364*cdf0e10cSrcweir return sal_False; 365*cdf0e10cSrcweir 366*cdf0e10cSrcweir #ifdef DBG_TRACE_BASIC 367*cdf0e10cSrcweir String aTraceStr_STMNT; 368*cdf0e10cSrcweir #endif 369*cdf0e10cSrcweir 370*cdf0e10cSrcweir // New line? 371*cdf0e10cSrcweir if( eOp == _STMNT && nOp1 != nLine ) 372*cdf0e10cSrcweir { 373*cdf0e10cSrcweir // Find line 374*cdf0e10cSrcweir String aSource = rImg.aOUSource; 375*cdf0e10cSrcweir nLine = nOp1; 376*cdf0e10cSrcweir sal_uInt16 n = 0; 377*cdf0e10cSrcweir sal_uInt16 l = (sal_uInt16)nLine; 378*cdf0e10cSrcweir while( --l ) { 379*cdf0e10cSrcweir n = aSource.SearchAscii( "\n", n ); 380*cdf0e10cSrcweir if( n == STRING_NOTFOUND ) break; 381*cdf0e10cSrcweir else n++; 382*cdf0e10cSrcweir } 383*cdf0e10cSrcweir // Show position 384*cdf0e10cSrcweir if( n != STRING_NOTFOUND ) 385*cdf0e10cSrcweir { 386*cdf0e10cSrcweir sal_uInt16 n2 = aSource.SearchAscii( "\n", n ); 387*cdf0e10cSrcweir if( n2 == STRING_NOTFOUND ) n2 = aSource.Len() - n; 388*cdf0e10cSrcweir String s( aSource.Copy( n, n2 - n + 1 ) ); 389*cdf0e10cSrcweir sal_Bool bDone; 390*cdf0e10cSrcweir do { 391*cdf0e10cSrcweir bDone = sal_True; 392*cdf0e10cSrcweir n = s.Search( '\r' ); 393*cdf0e10cSrcweir if( n != STRING_NOTFOUND ) bDone = sal_False, s.Erase( n, 1 ); 394*cdf0e10cSrcweir n = s.Search( '\n' ); 395*cdf0e10cSrcweir if( n != STRING_NOTFOUND ) bDone = sal_False, s.Erase( n, 1 ); 396*cdf0e10cSrcweir } while( !bDone ); 397*cdf0e10cSrcweir // snprintf( cBuf, sizeof(cBuf), pMask[ 0 ], nPC ); 398*cdf0e10cSrcweir // rText += cBuf; 399*cdf0e10cSrcweir rText.AppendAscii( "; " ); 400*cdf0e10cSrcweir rText += s; 401*cdf0e10cSrcweir rText.AppendAscii( _crlf() ); 402*cdf0e10cSrcweir 403*cdf0e10cSrcweir #ifdef DBG_TRACE_BASIC 404*cdf0e10cSrcweir aTraceStr_STMNT = s; 405*cdf0e10cSrcweir #endif 406*cdf0e10cSrcweir } 407*cdf0e10cSrcweir } 408*cdf0e10cSrcweir 409*cdf0e10cSrcweir // Label? 410*cdf0e10cSrcweir const char* p = ""; 411*cdf0e10cSrcweir if( cLabels[ nPC >> 3 ] & ( 1 << ( nPC & 7 ) ) ) 412*cdf0e10cSrcweir { 413*cdf0e10cSrcweir // Public? 414*cdf0e10cSrcweir ByteString aByteMethName; 415*cdf0e10cSrcweir for( sal_uInt16 i = 0; i < pMod->GetMethods()->Count(); i++ ) 416*cdf0e10cSrcweir { 417*cdf0e10cSrcweir SbMethod* pMeth = PTR_CAST(SbMethod,pMod->GetMethods()->Get( i )); 418*cdf0e10cSrcweir if( pMeth ) 419*cdf0e10cSrcweir { 420*cdf0e10cSrcweir aByteMethName = ByteString( pMeth->GetName(), gsl_getSystemTextEncoding() ); 421*cdf0e10cSrcweir if( pMeth->GetId() == nPC ) 422*cdf0e10cSrcweir { 423*cdf0e10cSrcweir p = aByteMethName.GetBuffer(); 424*cdf0e10cSrcweir break; 425*cdf0e10cSrcweir } 426*cdf0e10cSrcweir if( pMeth->GetId() >= nPC ) 427*cdf0e10cSrcweir break; 428*cdf0e10cSrcweir } 429*cdf0e10cSrcweir } 430*cdf0e10cSrcweir snprintf( cBuf, sizeof(cBuf), pMask[ 0 ], nPC ); 431*cdf0e10cSrcweir rText.AppendAscii( cBuf ); 432*cdf0e10cSrcweir if( p && *p ) 433*cdf0e10cSrcweir { 434*cdf0e10cSrcweir rText.AppendAscii( p ); 435*cdf0e10cSrcweir } 436*cdf0e10cSrcweir else 437*cdf0e10cSrcweir { 438*cdf0e10cSrcweir // fix warning (now error) for "Lbl%04lX" format 439*cdf0e10cSrcweir snprintf( cBuf, sizeof(cBuf), "Lbl%08" SAL_PRIXUINT32, nPC ); 440*cdf0e10cSrcweir rText.AppendAscii( cBuf ); 441*cdf0e10cSrcweir } 442*cdf0e10cSrcweir rText += ':'; 443*cdf0e10cSrcweir rText.AppendAscii( _crlf() ); 444*cdf0e10cSrcweir } 445*cdf0e10cSrcweir snprintf( cBuf, sizeof(cBuf), pMask[ nParts ], nPC, (sal_uInt16) eOp, nOp1, nOp2 ); 446*cdf0e10cSrcweir 447*cdf0e10cSrcweir String aPCodeStr; 448*cdf0e10cSrcweir aPCodeStr.AppendAscii( cBuf ); 449*cdf0e10cSrcweir int n = eOp; 450*cdf0e10cSrcweir if( eOp >= SbOP2_START ) 451*cdf0e10cSrcweir n -= SbOP2_START; 452*cdf0e10cSrcweir else if( eOp >= SbOP1_START ) 453*cdf0e10cSrcweir n -= SbOP1_START; 454*cdf0e10cSrcweir aPCodeStr += '\t'; 455*cdf0e10cSrcweir aPCodeStr.AppendAscii( pOps[ nParts-1 ][ n ] ); 456*cdf0e10cSrcweir aPCodeStr += '\t'; 457*cdf0e10cSrcweir switch( nParts ) 458*cdf0e10cSrcweir { 459*cdf0e10cSrcweir case 2: (this->*( pOperand2[ n ] ) )( aPCodeStr ); break; 460*cdf0e10cSrcweir case 3: (this->*( pOperand3[ n ] ) )( aPCodeStr ); break; 461*cdf0e10cSrcweir } 462*cdf0e10cSrcweir 463*cdf0e10cSrcweir rText += aPCodeStr; 464*cdf0e10cSrcweir 465*cdf0e10cSrcweir #ifdef DBG_TRACE_BASIC 466*cdf0e10cSrcweir dbg_RegisterTraceTextForPC( pMod, nPC, aTraceStr_STMNT, aPCodeStr ); 467*cdf0e10cSrcweir #endif 468*cdf0e10cSrcweir 469*cdf0e10cSrcweir return sal_True; 470*cdf0e10cSrcweir } 471*cdf0e10cSrcweir 472*cdf0e10cSrcweir // Read from StringPool 473*cdf0e10cSrcweir void SbiDisas::StrOp( String& rText ) 474*cdf0e10cSrcweir { 475*cdf0e10cSrcweir String aStr = rImg.GetString( (sal_uInt16)nOp1 ); 476*cdf0e10cSrcweir ByteString aByteString( aStr, RTL_TEXTENCODING_ASCII_US ); 477*cdf0e10cSrcweir const char* p = aByteString.GetBuffer(); 478*cdf0e10cSrcweir if( p ) 479*cdf0e10cSrcweir { 480*cdf0e10cSrcweir rText += '"'; 481*cdf0e10cSrcweir rText.AppendAscii( p ); 482*cdf0e10cSrcweir rText += '"'; 483*cdf0e10cSrcweir } 484*cdf0e10cSrcweir else 485*cdf0e10cSrcweir { 486*cdf0e10cSrcweir rText.AppendAscii( "?String? " ); 487*cdf0e10cSrcweir rText += (sal_uInt16)nOp1; 488*cdf0e10cSrcweir } 489*cdf0e10cSrcweir } 490*cdf0e10cSrcweir 491*cdf0e10cSrcweir void SbiDisas::Str2Op( String& rText ) 492*cdf0e10cSrcweir { 493*cdf0e10cSrcweir StrOp( rText ); 494*cdf0e10cSrcweir rText += ','; 495*cdf0e10cSrcweir String s; 496*cdf0e10cSrcweir nOp1 = nOp2; 497*cdf0e10cSrcweir StrOp( s ); 498*cdf0e10cSrcweir rText += s; 499*cdf0e10cSrcweir } 500*cdf0e10cSrcweir 501*cdf0e10cSrcweir // Immediate Operand 502*cdf0e10cSrcweir void SbiDisas::ImmOp( String& rText ) 503*cdf0e10cSrcweir { 504*cdf0e10cSrcweir rText += String::CreateFromInt32(nOp1); 505*cdf0e10cSrcweir } 506*cdf0e10cSrcweir 507*cdf0e10cSrcweir // OnGoto Operand 508*cdf0e10cSrcweir void SbiDisas::OnOp( String& rText ) 509*cdf0e10cSrcweir { 510*cdf0e10cSrcweir rText += String::CreateFromInt32(nOp1 & 0x7FFF); 511*cdf0e10cSrcweir if( nOp1 & 0x800 ) 512*cdf0e10cSrcweir rText.AppendAscii( "\t; Gosub" ); 513*cdf0e10cSrcweir } 514*cdf0e10cSrcweir 515*cdf0e10cSrcweir // Label 516*cdf0e10cSrcweir void SbiDisas::LblOp( String& rText ) 517*cdf0e10cSrcweir { 518*cdf0e10cSrcweir char cBuf[ 10 ]; 519*cdf0e10cSrcweir snprintf( cBuf, sizeof(cBuf), "Lbl%04" SAL_PRIXUINT32, nOp1 ); 520*cdf0e10cSrcweir rText.AppendAscii( cBuf ); 521*cdf0e10cSrcweir } 522*cdf0e10cSrcweir 523*cdf0e10cSrcweir // 0 or Label 524*cdf0e10cSrcweir void SbiDisas::ReturnOp( String& rText ) 525*cdf0e10cSrcweir { 526*cdf0e10cSrcweir if( nOp1 ) 527*cdf0e10cSrcweir LblOp( rText ); 528*cdf0e10cSrcweir } 529*cdf0e10cSrcweir 530*cdf0e10cSrcweir // 0, 1 or Label 531*cdf0e10cSrcweir void SbiDisas::ResumeOp( String& rText ) 532*cdf0e10cSrcweir { 533*cdf0e10cSrcweir switch( nOp1 ) 534*cdf0e10cSrcweir { 535*cdf0e10cSrcweir case 1: rText.AppendAscii( "NEXT" ); break; 536*cdf0e10cSrcweir case 2: LblOp( rText ); 537*cdf0e10cSrcweir } 538*cdf0e10cSrcweir } 539*cdf0e10cSrcweir 540*cdf0e10cSrcweir // print Prompt 541*cdf0e10cSrcweir // sal_False/TRUE 542*cdf0e10cSrcweir void SbiDisas::PromptOp( String& rText ) 543*cdf0e10cSrcweir { 544*cdf0e10cSrcweir if( nOp1 ) 545*cdf0e10cSrcweir rText.AppendAscii( "\"? \"" ); 546*cdf0e10cSrcweir } 547*cdf0e10cSrcweir 548*cdf0e10cSrcweir // 0 or 1 549*cdf0e10cSrcweir void SbiDisas::CloseOp( String& rText ) 550*cdf0e10cSrcweir { 551*cdf0e10cSrcweir rText.AppendAscii( nOp1 ? "Channel" : "All" ); 552*cdf0e10cSrcweir } 553*cdf0e10cSrcweir 554*cdf0e10cSrcweir // Print character 555*cdf0e10cSrcweir void SbiDisas::CharOp( String& rText ) 556*cdf0e10cSrcweir { 557*cdf0e10cSrcweir const char* p = NULL; 558*cdf0e10cSrcweir switch( nOp1 ) 559*cdf0e10cSrcweir { 560*cdf0e10cSrcweir case 7: p = "'\\a'"; break; 561*cdf0e10cSrcweir case 9: p = "'\\t'"; break; 562*cdf0e10cSrcweir case 10: p = "'\\n'"; break; 563*cdf0e10cSrcweir case 12: p = "'\\f'"; break; 564*cdf0e10cSrcweir case 13: p = "'\\r'"; break; 565*cdf0e10cSrcweir } 566*cdf0e10cSrcweir if( p ) rText.AppendAscii( p ); 567*cdf0e10cSrcweir else if( nOp1 >= ' ' ) 568*cdf0e10cSrcweir rText += '\'', 569*cdf0e10cSrcweir rText += (char) nOp1, 570*cdf0e10cSrcweir rText += '\''; 571*cdf0e10cSrcweir else 572*cdf0e10cSrcweir rText.AppendAscii( "char " ), 573*cdf0e10cSrcweir rText += (sal_uInt16)nOp1; 574*cdf0e10cSrcweir } 575*cdf0e10cSrcweir 576*cdf0e10cSrcweir // Print var: String-ID and type 577*cdf0e10cSrcweir void SbiDisas::VarOp( String& rText ) 578*cdf0e10cSrcweir { 579*cdf0e10cSrcweir rText += rImg.GetString( (sal_uInt16)(nOp1 & 0x7FFF) ); 580*cdf0e10cSrcweir rText.AppendAscii( "\t; " ); 581*cdf0e10cSrcweir // The type 582*cdf0e10cSrcweir sal_uInt32 n = nOp1; 583*cdf0e10cSrcweir nOp1 = nOp2; 584*cdf0e10cSrcweir TypeOp( rText ); 585*cdf0e10cSrcweir if( n & 0x8000 ) 586*cdf0e10cSrcweir rText.AppendAscii( ", Args" ); 587*cdf0e10cSrcweir } 588*cdf0e10cSrcweir 589*cdf0e10cSrcweir // Define variable: String-ID and type 590*cdf0e10cSrcweir void SbiDisas::VarDefOp( String& rText ) 591*cdf0e10cSrcweir { 592*cdf0e10cSrcweir rText += rImg.GetString( (sal_uInt16)(nOp1 & 0x7FFF) ); 593*cdf0e10cSrcweir rText.AppendAscii( "\t; " ); 594*cdf0e10cSrcweir // The Typ 595*cdf0e10cSrcweir nOp1 = nOp2; 596*cdf0e10cSrcweir TypeOp( rText ); 597*cdf0e10cSrcweir } 598*cdf0e10cSrcweir 599*cdf0e10cSrcweir // Print variable: Offset and Typ 600*cdf0e10cSrcweir void SbiDisas::OffOp( String& rText ) 601*cdf0e10cSrcweir { 602*cdf0e10cSrcweir rText += String::CreateFromInt32( nOp1 & 0x7FFF ); 603*cdf0e10cSrcweir rText.AppendAscii( "\t; " ); 604*cdf0e10cSrcweir // The type 605*cdf0e10cSrcweir sal_uInt32 n = nOp1; 606*cdf0e10cSrcweir nOp1 = nOp2; 607*cdf0e10cSrcweir TypeOp( rText ); 608*cdf0e10cSrcweir if( n & 0x8000 ) 609*cdf0e10cSrcweir rText.AppendAscii( ", Args" ); 610*cdf0e10cSrcweir } 611*cdf0e10cSrcweir 612*cdf0e10cSrcweir // Data type 613*cdf0e10cSrcweir #ifdef HP9000 // TODO: remove this! 614*cdf0e10cSrcweir static char* SbiDisas_TypeOp_pTypes[13] = { 615*cdf0e10cSrcweir "Empty","Null","Integer","Long","Single","Double", 616*cdf0e10cSrcweir "Currency","Date","String","Object","Error","Boolean", 617*cdf0e10cSrcweir "Variant" }; 618*cdf0e10cSrcweir #define pTypes SbiDisas_TypeOp_pTypes 619*cdf0e10cSrcweir #endif 620*cdf0e10cSrcweir void SbiDisas::TypeOp( String& rText ) 621*cdf0e10cSrcweir { 622*cdf0e10cSrcweir // AB 19.1.96: Typ kann Flag f�r BYVAL enthalten (StepARGTYP) 623*cdf0e10cSrcweir if( nOp1 & 0x8000 ) 624*cdf0e10cSrcweir { 625*cdf0e10cSrcweir nOp1 &= 0x7FFF; // Flag wegfiltern 626*cdf0e10cSrcweir rText.AppendAscii( "BYVAL " ); 627*cdf0e10cSrcweir } 628*cdf0e10cSrcweir if( nOp1 < 13 ) 629*cdf0e10cSrcweir { 630*cdf0e10cSrcweir #ifndef HP9000 631*cdf0e10cSrcweir static char pTypes[][13] = { 632*cdf0e10cSrcweir "Empty","Null","Integer","Long","Single","Double", 633*cdf0e10cSrcweir "Currency","Date","String","Object","Error","Boolean", 634*cdf0e10cSrcweir "Variant" }; 635*cdf0e10cSrcweir #endif 636*cdf0e10cSrcweir rText.AppendAscii( pTypes[ nOp1 ] ); 637*cdf0e10cSrcweir } 638*cdf0e10cSrcweir else 639*cdf0e10cSrcweir { 640*cdf0e10cSrcweir rText.AppendAscii( "type " ); 641*cdf0e10cSrcweir rText += (sal_uInt16)nOp1; 642*cdf0e10cSrcweir } 643*cdf0e10cSrcweir } 644*cdf0e10cSrcweir #ifdef HP9000 645*cdf0e10cSrcweir #undef pTypes 646*cdf0e10cSrcweir #endif 647*cdf0e10cSrcweir 648*cdf0e10cSrcweir // sal_True-Label, condition Opcode 649*cdf0e10cSrcweir void SbiDisas::CaseOp( String& rText ) 650*cdf0e10cSrcweir { 651*cdf0e10cSrcweir LblOp( rText ); 652*cdf0e10cSrcweir rText += ','; 653*cdf0e10cSrcweir rText.AppendAscii( pOp1[ nOp2 - SbxEQ + _EQ ] ); 654*cdf0e10cSrcweir } 655*cdf0e10cSrcweir 656*cdf0e10cSrcweir // Row, column 657*cdf0e10cSrcweir void SbiDisas::StmntOp( String& rText ) 658*cdf0e10cSrcweir { 659*cdf0e10cSrcweir rText += String::CreateFromInt32( nOp1 ); 660*cdf0e10cSrcweir rText += ','; 661*cdf0e10cSrcweir sal_uInt32 nCol = nOp2 & 0xFF; 662*cdf0e10cSrcweir sal_uInt32 nFor = nOp2 / 0x100; 663*cdf0e10cSrcweir rText += String::CreateFromInt32( nCol ); 664*cdf0e10cSrcweir rText.AppendAscii( " (For-Level: " ); 665*cdf0e10cSrcweir rText += String::CreateFromInt32( nFor ); 666*cdf0e10cSrcweir rText += ')'; 667*cdf0e10cSrcweir } 668*cdf0e10cSrcweir 669*cdf0e10cSrcweir // open mode, flags 670*cdf0e10cSrcweir void SbiDisas::StrmOp( String& rText ) 671*cdf0e10cSrcweir { 672*cdf0e10cSrcweir char cBuf[ 10 ]; 673*cdf0e10cSrcweir snprintf( cBuf, sizeof(cBuf), "%04" SAL_PRIXUINT32, nOp1 ); 674*cdf0e10cSrcweir rText.AppendAscii( cBuf ); 675*cdf0e10cSrcweir if( nOp2 & SBSTRM_INPUT ) 676*cdf0e10cSrcweir rText.AppendAscii( ", Input" ); 677*cdf0e10cSrcweir if( nOp2 & SBSTRM_OUTPUT ) 678*cdf0e10cSrcweir rText.AppendAscii( ", Output" ); 679*cdf0e10cSrcweir if( nOp2 & SBSTRM_APPEND ) 680*cdf0e10cSrcweir rText.AppendAscii( ", Append" ); 681*cdf0e10cSrcweir if( nOp2 & SBSTRM_RANDOM ) 682*cdf0e10cSrcweir rText.AppendAscii( ", Random" ); 683*cdf0e10cSrcweir if( nOp2 & SBSTRM_BINARY ) 684*cdf0e10cSrcweir rText.AppendAscii( ", Binary" ); 685*cdf0e10cSrcweir } 686*cdf0e10cSrcweir 687*cdf0e10cSrcweir 688