summaryrefslogtreecommitdiff
path: root/basic/source/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'basic/source/runtime')
-rw-r--r--basic/source/runtime/dllmgr.cxx1157
-rw-r--r--basic/source/runtime/dllmgr.hxx71
-rw-r--r--basic/source/runtime/makefile.mk21
-rw-r--r--basic/source/runtime/methods1.cxx15
-rw-r--r--basic/source/runtime/os2.asm103
-rw-r--r--basic/source/runtime/rtlproto.hxx1
-rwxr-xr-xbasic/source/runtime/runtime.cxx7
-rw-r--r--basic/source/runtime/stdobj.cxx7
-rw-r--r--basic/source/runtime/step0.cxx37
-rw-r--r--basic/source/runtime/step1.cxx9
-rw-r--r--basic/source/runtime/step2.cxx32
-rw-r--r--basic/source/runtime/win.asm80
-rw-r--r--basic/source/runtime/wnt-mingw.s98
-rw-r--r--basic/source/runtime/wnt.asm100
14 files changed, 789 insertions, 949 deletions
diff --git a/basic/source/runtime/dllmgr.cxx b/basic/source/runtime/dllmgr.cxx
index 22014763bb29..bc08a8cb64bc 100644
--- a/basic/source/runtime/dllmgr.cxx
+++ b/basic/source/runtime/dllmgr.cxx
@@ -25,647 +25,714 @@
*
************************************************************************/
-// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_basic.hxx"
+#include "sal/config.h"
-#include <stdlib.h>
-#ifdef OS2
-#define INCL_DOSMODULEMGR
-#include <svpm.h>
-#endif
-
-#if defined( WIN ) || defined( WNT )
-#ifndef _SVWIN_H
-#undef WB_LEFT
-#undef WB_RIGHT
-#include <tools/svwin.h>
-#endif
-#endif
-#include <tools/debug.hxx>
-#include <tools/string.hxx>
-#include <tools/errcode.hxx>
-#include <basic/sbxvar.hxx>
-#include <basic/sbx.hxx>
-
-#if defined(WIN)
-typedef HINSTANCE SbiDllHandle;
-typedef FARPROC SbiDllProc;
-#elif defined(WNT)
-typedef HMODULE SbiDllHandle;
-typedef int(*SbiDllProc)();
-#elif defined(OS2)
-typedef HMODULE SbiDllHandle;
-typedef PFN SbiDllProc;
-#else
-typedef void* SbiDllHandle;
-typedef void* SbiDllProc;
-#endif
+#include <algorithm>
+#include <cstddef>
+#include <list>
+#include <map>
+#include <vector>
-#define _DLLMGR_CXX
-#include "dllmgr.hxx"
-#include <basic/sberrors.hxx>
+#include "basic/sbx.hxx"
+#include "basic/sbxvar.hxx"
+#include "osl/thread.h"
+#include "rtl/ref.hxx"
+#include "rtl/string.hxx"
+#include "rtl/ustring.hxx"
+#include "salhelper/simplereferenceobject.hxx"
+#include "tools/svwin.h"
-#ifndef WINAPI
-#ifdef WNT
-#define WINAPI __far __pascal
-#endif
-#endif
+#undef max
-extern "C" {
-#if defined(INTEL) && (defined(WIN) || defined(WNT))
+#include "dllmgr.hxx"
-extern INT16 WINAPI CallINT( SbiDllProc, char *stack, short nstack);
-extern INT32 WINAPI CallLNG( SbiDllProc, char *stack, short nstack);
-#ifndef WNT
-extern float WINAPI CallSNG( SbiDllProc, char *stack, short nstack);
-#endif
-extern double WINAPI CallDBL( SbiDllProc, char *stack, short nstack);
-extern char* WINAPI CallSTR( SbiDllProc, char *stack, short nstack);
-// extern CallFIX( SbiDllProc, char *stack, short nstack);
+/* Open issues:
-#else
+ Only 32-bit Windows for now.
-INT16 CallINT( SbiDllProc, char *, short ) { return 0; }
-INT32 CallLNG( SbiDllProc, char *, short ) { return 0; }
-float CallSNG( SbiDllProc, char *, short ) { return 0; }
-double CallDBL( SbiDllProc, char *, short) { return 0; }
-char* CallSTR( SbiDllProc, char *, short ) { return 0; }
-#endif
-}
+ Missing support for functions returning structs (see TODO in call()).
-SV_IMPL_OP_PTRARR_SORT(ImplDllArr,ByteStringPtr)
+ Missing support for additional data types (64 bit integers, Any, ...; would
+ trigger OSL_ASSERT(false) in various switches).
-/* mit Optimierung An stuerzt unter Win95 folgendes Makro ab:
-declare Sub MessageBeep Lib "user32" (ByVal long)
-sub main
- MessageBeep( 1 )
-end sub
+ It is assumed that the variables passed into SbiDllMgr::Call to represent
+ the arguments and return value have types that exactly match the Declare
+ statement; it would be better if this code had access to the function
+ signature from the Declare statement, so that it could convert the passed
+ variables accordingly.
*/
-#if defined (WNT) && defined (MSC)
-//#pragma optimize ("", off)
-#endif
-//
-// ***********************************************************************
-//
+#if defined WNT // only 32-bit Windows, actually
-class ImplSbiProc : public ByteString
-{
- SbiDllProc pProc;
- ImplSbiProc();
- ImplSbiProc( const ImplSbiProc& );
-
-public:
- ImplSbiProc( const ByteString& rName, SbiDllProc pFunc )
- : ByteString( rName ) { pProc = pFunc; }
- SbiDllProc GetProc() const { return pProc; }
-};
+extern "C" {
-//
-// ***********************************************************************
-//
+int __stdcall DllMgr_call32(FARPROC, void const * stack, std::size_t size);
+double __stdcall DllMgr_callFp(FARPROC, void const * stack, std::size_t size);
-class ImplSbiDll : public ByteString
-{
- ImplDllArr aProcArr;
- SbiDllHandle hDLL;
+}
- ImplSbiDll( const ImplSbiDll& );
-public:
- ImplSbiDll( const ByteString& rName, SbiDllHandle hHandle )
- : ByteString( rName ) { hDLL = hHandle; }
- ~ImplSbiDll();
- SbiDllHandle GetHandle() const { return hDLL; }
- SbiDllProc GetProc( const ByteString& rName ) const;
- void InsertProc( const ByteString& rName, SbiDllProc pProc );
-};
+namespace {
-ImplSbiDll::~ImplSbiDll()
-{
- USHORT nCount = aProcArr.Count();
- for( USHORT nCur = 0; nCur < nCount; nCur++ )
- {
- ImplSbiProc* pProc = (ImplSbiProc*)aProcArr.GetObject( nCur );
- delete pProc;
- }
+char * address(std::vector< char > & blob) {
+ return blob.empty() ? 0 : &blob[0];
}
-SbiDllProc ImplSbiDll::GetProc( const ByteString& rName ) const
-{
- USHORT nPos;
- BOOL bRet = aProcArr.Seek_Entry( (ByteStringPtr)&rName, &nPos );
- if( bRet )
- {
- ImplSbiProc* pImplProc = (ImplSbiProc*)aProcArr.GetObject(nPos);
- return pImplProc->GetProc();
- }
- return (SbiDllProc)0;
+SbError convert(rtl::OUString const & source, rtl::OString * target) {
+ return
+ source.convertToString(
+ target, osl_getThreadTextEncoding(),
+ (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))
+ ? ERRCODE_NONE : ERRCODE_BASIC_BAD_ARGUMENT;
+ //TODO: more specific errcode?
}
-void ImplSbiDll::InsertProc( const ByteString& rName, SbiDllProc pProc )
-{
- DBG_ASSERT(aProcArr.Seek_Entry((ByteStringPtr)&rName,0)==0,"InsertProc: Already in table");
- ImplSbiProc* pImplProc = new ImplSbiProc( rName, pProc );
- aProcArr.Insert( (ByteStringPtr)pImplProc );
+SbError convert(char const * source, sal_Int32 length, rtl::OUString * target) {
+ return
+ rtl_convertStringToUString(
+ &target->pData, source, length, osl_getThreadTextEncoding(),
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR))
+ ? ERRCODE_NONE : ERRCODE_BASIC_BAD_ARGUMENT;
+ //TODO: more specific errcode?
}
+struct UnmarshalData {
+ UnmarshalData(SbxVariable * theVariable, void * theBuffer):
+ variable(theVariable), buffer(theBuffer) {}
-//
-// ***********************************************************************
-//
+ SbxVariable * variable;
+ void * buffer;
+};
-SbiDllMgr::SbiDllMgr( const SbiDllMgr& )
-{
-}
+struct StringData: public UnmarshalData {
+ StringData(SbxVariable * theVariable, void * theBuffer, bool theSpecial):
+ UnmarshalData(theVariable, theBuffer), special(theSpecial) {}
-SbiDllMgr::SbiDllMgr()
-{
-}
+ bool special;
+};
-SbiDllMgr::~SbiDllMgr()
-{
- USHORT nCount = aDllArr.Count();
- for( USHORT nCur = 0; nCur < nCount; nCur++ )
- {
- ImplSbiDll* pDll = (ImplSbiDll*)aDllArr.GetObject( nCur );
- FreeDllHandle( pDll->GetHandle() );
- delete pDll;
+class MarshalData: private boost::noncopyable {
+public:
+ std::vector< char > * newBlob() {
+ blobs_.push_front(std::vector< char >());
+ return &blobs_.front();
}
-}
-void SbiDllMgr::FreeDll( const ByteString& rDllName )
-{
- USHORT nPos;
- BOOL bRet = aDllArr.Seek_Entry( (ByteStringPtr)&rDllName, &nPos );
- if( bRet )
- {
- ImplSbiDll* pDll = (ImplSbiDll*)aDllArr.GetObject(nPos);
- FreeDllHandle( pDll->GetHandle() );
- delete pDll;
- aDllArr.Remove( nPos, 1 );
- }
-}
+ std::vector< UnmarshalData > unmarshal;
+ std::vector< StringData > unmarshalStrings;
-ImplSbiDll* SbiDllMgr::GetDll( const ByteString& rDllName )
-{
- USHORT nPos;
- ImplSbiDll* pDll = 0;
- BOOL bRet = aDllArr.Seek_Entry( (ByteStringPtr)&rDllName, &nPos );
- if( bRet )
- pDll = (ImplSbiDll*)aDllArr.GetObject(nPos);
- else
- {
- SbiDllHandle hDll = CreateDllHandle( rDllName );
- if( hDll )
- {
- pDll = new ImplSbiDll( rDllName, hDll );
- aDllArr.Insert( (ByteStringPtr)pDll );
- }
- }
- return pDll;
+private:
+ std::list< std::vector< char > > blobs_;
+};
+
+std::size_t align(std::size_t address, std::size_t alignment) {
+ // alignment = 2^k for some k >= 0
+ return (address + (alignment - 1)) & ~(alignment - 1);
}
-SbiDllProc SbiDllMgr::GetProc( ImplSbiDll* pDll, const ByteString& rProcName )
+char * align(
+ std::vector< char > & blob, std::size_t alignment, std::size_t offset,
+ std::size_t add)
{
- DBG_ASSERT(pDll,"GetProc: No dll-ptr");
- SbiDllProc pProc;
- pProc = pDll->GetProc( rProcName );
- if( !pProc )
- {
- pProc = GetProcAddr( pDll->GetHandle(), rProcName );
- if( pProc )
- pDll->InsertProc( rProcName, pProc );
- }
- return pProc;
+ std::vector< char >::size_type n = blob.size();
+ n = align(n - offset, alignment) + offset; //TODO: overflow in align()
+ blob.resize(n + add); //TODO: overflow
+ return address(blob) + n;
}
-
-SbError SbiDllMgr::Call( const char* pProcName, const char* pDllName,
- SbxArray* pArgs, SbxVariable& rResult, BOOL bCDecl )
+template< typename T > void add(
+ std::vector< char > & blob, T const & data, std::size_t alignment,
+ std::size_t offset)
{
- DBG_ASSERT(pProcName&&pDllName,"Call: Bad parms");
- SbError nSbErr = 0;
- ByteString aDllName( pDllName );
- CheckDllName( aDllName );
- ImplSbiDll* pDll = GetDll( aDllName );
- if( pDll )
- {
- SbiDllProc pProc = GetProc( pDll, pProcName );
- if( pProc )
- {
- if( bCDecl )
- nSbErr = CallProcC( pProc, pArgs, rResult );
- else
- nSbErr = CallProc( pProc, pArgs, rResult );
+ *reinterpret_cast< T * >(align(blob, alignment, offset, sizeof (T))) = data;
+}
+
+std::size_t alignment(SbxVariable * variable) {
+ OSL_ASSERT(variable != 0);
+ if ((variable->GetType() & SbxARRAY) == 0) {
+ switch (variable->GetType()) {
+ case SbxINTEGER:
+ return 2;
+ case SbxLONG:
+ case SbxSINGLE:
+ case SbxSTRING:
+ return 4;
+ case SbxDOUBLE:
+ return 8;
+ case SbxOBJECT:
+ {
+ std::size_t n = 1;
+ SbxArray * props = PTR_CAST(SbxObject, variable->GetObject())->
+ GetProperties();
+ for (USHORT i = 0; i < props->Count(); ++i) {
+ n = std::max(n, alignment(props->Get(i)));
+ }
+ return n;
+ }
+ case SbxBOOL:
+ case SbxBYTE:
+ return 1;
+ default:
+ OSL_ASSERT(false);
+ return 1;
+ }
+ } else {
+ SbxDimArray * arr = PTR_CAST(SbxDimArray, variable->GetObject());
+ int dims = arr->GetDims();
+ std::vector< INT32 > low(dims);
+ for (int i = 0; i < dims; ++i) {
+ INT32 up;
+ arr->GetDim32(i + 1, low[i], up);
}
- else
- nSbErr = SbERR_PROC_UNDEFINED;
+ return alignment(arr->Get32(&low[0]));
}
- else
- nSbErr = SbERR_BAD_DLL_LOAD;
- return nSbErr;
}
-// ***********************************************************************
-// ******************* abhaengige Implementationen ***********************
-// ***********************************************************************
+SbError marshal(
+ bool outer, SbxVariable * variable, bool special,
+ std::vector< char > & blob, std::size_t offset, MarshalData & data);
-void SbiDllMgr::CheckDllName( ByteString& rDllName )
+SbError marshalString(
+ SbxVariable * variable, bool special, MarshalData & data, void ** buffer)
{
-#if defined(WIN) || defined(WNT) || defined(OS2)
- if( rDllName.Search('.') == STRING_NOTFOUND )
- rDllName += ".DLL";
-#else
- (void)rDllName;
-#endif
+ OSL_ASSERT(variable != 0 && buffer != 0);
+ rtl::OString str;
+ SbError e = convert(variable->GetString(), &str);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ std::vector< char > * blob = data.newBlob();
+ blob->insert(blob->begin(), str.getStr(), str.getStr() + str.getLength());
+ *buffer = address(*blob);
+ data.unmarshalStrings.push_back(StringData(variable, *buffer, special));
+ return ERRCODE_NONE;
}
-
-SbiDllHandle SbiDllMgr::CreateDllHandle( const ByteString& rDllName )
+SbError marshalStruct(
+ SbxVariable * variable, std::vector< char > & blob, std::size_t offset,
+ MarshalData & data)
{
- (void)rDllName;
-
-#if defined(UNX)
- SbiDllHandle hLib=0;
-#else
- SbiDllHandle hLib;
-#endif
-
-#if defined(WIN)
- hLib = LoadLibrary( (const char*)rDllName );
- if( (ULONG)hLib < 32 )
- hLib = 0;
-
-#elif defined(WNT)
- hLib = LoadLibrary( rDllName.GetBuffer() );
- if( !(ULONG)hLib )
- {
-#ifdef DBG_UTIL
- ULONG nLastErr;
- nLastErr = GetLastError();
-#endif
- hLib = 0;
+ OSL_ASSERT(variable != 0);
+ SbxArray * props = PTR_CAST(SbxObject, variable->GetObject())->
+ GetProperties();
+ for (USHORT i = 0; i < props->Count(); ++i) {
+ SbError e = marshal(false, props->Get(i), false, blob, offset, data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
}
-
-#elif defined(OS2)
- char cErr[ 100 ];
- if( DosLoadModule( (PSZ) cErr, 100, (const char*)rDllName.GetBuffer(), &hLib ) )
- hLib = 0;
-#endif
- return hLib;
+ return ERRCODE_NONE;
}
-void SbiDllMgr::FreeDllHandle( SbiDllHandle hLib )
+SbError marshalArray(
+ SbxVariable * variable, std::vector< char > & blob, std::size_t offset,
+ MarshalData & data)
{
-#if defined(WIN) || defined(WNT)
- if( hLib )
- FreeLibrary ((HINSTANCE) hLib);
-#elif defined(OS2)
- if( hLib )
- DosFreeModule( (HMODULE) hLib );
-#else
- (void)hLib;
-#endif
+ OSL_ASSERT(variable != 0);
+ SbxDimArray * arr = PTR_CAST(SbxDimArray, variable->GetObject());
+ int dims = arr->GetDims();
+ std::vector< INT32 > low(dims);
+ std::vector< INT32 > up(dims);
+ for (int i = 0; i < dims; ++i) {
+ arr->GetDim32(i + 1, low[i], up[i]);
+ }
+ for (std::vector< INT32 > idx = low;;) {
+ SbError e = marshal(
+ false, arr->Get32(&idx[0]), false, blob, offset, data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ int i = dims - 1;
+ while (idx[i] == up[i]) {
+ idx[i] = low[i];
+ if (i == 0) {
+ return ERRCODE_NONE;
+ }
+ --i;
+ }
+ ++idx[i];
+ }
}
-SbiDllProc SbiDllMgr::GetProcAddr(SbiDllHandle hLib, const ByteString& rProcName)
+// 8-aligned structs are only 4-aligned on stack, so alignment of members in
+// such structs must take that into account via "offset"
+SbError marshal(
+ bool outer, SbxVariable * variable, bool special,
+ std::vector< char > & blob, std::size_t offset, MarshalData & data)
{
- char buf1 [128] = "";
- char buf2 [128] = "";
-
- SbiDllProc pProc = 0;
- int nOrd = 0;
-
- // Ordinal?
- if( rProcName.GetBuffer()[0] == '@' )
- nOrd = atoi( rProcName.GetBuffer()+1 );
-
- // Moegliche Parameter weg:
- DBG_ASSERT( sizeof(buf1) > rProcName.Len(),
- "SbiDllMgr::GetProcAddr: buffer to small!" );
- strncpy( buf1, rProcName.GetBuffer(), sizeof(buf1)-1 );
- char *p = strchr( buf1, '#' );
- if( p )
- *p = 0;
-
- DBG_ASSERT( sizeof(buf2) > strlen(buf1) + 1,
- "SbiDllMgr::GetProcAddr: buffer to small!" );
- strncpy( buf2, "_", sizeof(buf2)-1 );
- strncat( buf2, buf1, sizeof(buf2)-1-strlen(buf2) );
-
-#if defined(WIN) || defined(WNT)
- if( nOrd > 0 )
- pProc = (SbiDllProc)GetProcAddress( hLib, (char*)(long) nOrd );
- else
- {
- // 2. mit Parametern:
- pProc = (SbiDllProc)GetProcAddress ( hLib, rProcName.GetBuffer() );
- // 3. nur der Name:
- if (!pProc)
- pProc = (SbiDllProc)GetProcAddress( hLib, buf1 );
- // 4. der Name mit Underline vorweg:
- if( !pProc )
- pProc = (SbiDllProc)GetProcAddress( hLib, buf2 );
+ OSL_ASSERT(variable != 0);
+ if ((variable->GetFlags() & SBX_REFERENCE) == 0) {
+ if ((variable->GetType() & SbxARRAY) == 0) {
+ switch (variable->GetType()) {
+ case SbxINTEGER:
+ add(blob, variable->GetInteger(), outer ? 4 : 2, offset);
+ break;
+ case SbxLONG:
+ add(blob, variable->GetLong(), 4, offset);
+ break;
+ case SbxSINGLE:
+ add(blob, variable->GetSingle(), 4, offset);
+ break;
+ case SbxDOUBLE:
+ add(blob, variable->GetDouble(), outer ? 4 : 8, offset);
+ break;
+ case SbxSTRING:
+ {
+ void * p;
+ SbError e = marshalString(variable, special, data, &p);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ add(blob, p, 4, offset);
+ break;
+ }
+ case SbxOBJECT:
+ {
+ align(blob, outer ? 4 : alignment(variable), offset, 0);
+ SbError e = marshalStruct(variable, blob, offset, data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ break;
+ }
+ case SbxBOOL:
+ add(blob, variable->GetBool(), outer ? 4 : 1, offset);
+ break;
+ case SbxBYTE:
+ add(blob, variable->GetByte(), outer ? 4 : 1, offset);
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ } else {
+ SbError e = marshalArray(variable, blob, offset, data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ }
+ } else {
+ if ((variable->GetType() & SbxARRAY) == 0) {
+ switch (variable->GetType()) {
+ case SbxINTEGER:
+ case SbxLONG:
+ case SbxSINGLE:
+ case SbxDOUBLE:
+ case SbxBOOL:
+ case SbxBYTE:
+ add(blob, variable->data(), 4, offset);
+ break;
+ case SbxSTRING:
+ {
+ std::vector< char > * blob2 = data.newBlob();
+ void * p;
+ SbError e = marshalString(variable, special, data, &p);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ add(*blob2, p, 4, 0);
+ add(blob, address(*blob2), 4, offset);
+ break;
+ }
+ case SbxOBJECT:
+ {
+ std::vector< char > * blob2 = data.newBlob();
+ SbError e = marshalStruct(variable, *blob2, 0, data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ void * p = address(*blob2);
+ if (outer) {
+ data.unmarshal.push_back(UnmarshalData(variable, p));
+ }
+ add(blob, p, 4, offset);
+ break;
+ }
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ } else {
+ std::vector< char > * blob2 = data.newBlob();
+ SbError e = marshalArray(variable, *blob2, 0, data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ void * p = address(*blob2);
+ if (outer) {
+ data.unmarshal.push_back(UnmarshalData(variable, p));
+ }
+ add(blob, p, 4, offset);
+ }
}
+ return ERRCODE_NONE;
+}
-#elif defined(OS2)
- PSZ pp;
- APIRET rc;
- // 1. Ordinal oder mit Parametern:
- rc = DosQueryProcAddr( hLib, nOrd, pp = (char*)rProcName.GetBuffer(), &pProc );
- // 2. nur der Name:
- if( rc )
- rc = DosQueryProcAddr( hLib, 0, pp = (PSZ)buf1, &pProc );
- // 3. der Name mit Underline vorweg:
- if( rc )
- rc = DosQueryProcAddr( hLib, 0, pp = (PSZ)buf2, &pProc );
- if( rc )
- pProc = NULL;
- else
- {
- // 16-bit oder 32-bit?
- ULONG nInfo = 0;
- if( DosQueryProcType( hLib, nOrd, pp, &nInfo ) )
- nInfo = 0;;
- }
-#else
- (void)hLib;
-#endif
- return pProc;
+template< typename T > T read(void const ** pointer) {
+ T const * p = static_cast< T const * >(*pointer);
+ *pointer = static_cast< void const * >(p + 1);
+ return *p;
}
-SbError SbiDllMgr::CallProc( SbiDllProc pProc, SbxArray* pArgs,
- SbxVariable& rResult )
-{
-// ByteString aStr("Calling DLL at ");
-// aStr += (ULONG)pProc;
-// InfoBox( 0, aStr ).Execute();
- INT16 nInt16; int nInt; INT32 nInt32; double nDouble;
- char* pStr;
-
- USHORT nSize;
- char* pStack = (char*)CreateStack( pArgs, nSize );
- switch( rResult.GetType() )
- {
+void const * unmarshal(SbxVariable * variable, void const * data) {
+ OSL_ASSERT(variable != 0);
+ if ((variable->GetType() & SbxARRAY) == 0) {
+ switch (variable->GetType()) {
case SbxINTEGER:
- nInt16 = CallINT(pProc, pStack, (short)nSize );
- rResult.PutInteger( nInt16 );
- break;
-
- case SbxUINT:
- case SbxUSHORT:
- nInt16 = (INT16)CallINT(pProc, pStack, (short)nSize );
- rResult.PutUShort( (USHORT)nInt16 );
- break;
-
- case SbxERROR:
- nInt16 = (INT16)CallINT(pProc, pStack, (short)nSize );
- rResult.PutErr( (USHORT)nInt16 );
- break;
-
- case SbxINT:
- nInt = CallINT(pProc, pStack, (short)nSize );
- rResult.PutInt( nInt );
+ variable->PutInteger(read< sal_Int16 >(&data));
break;
-
case SbxLONG:
- nInt32 = CallLNG(pProc, pStack, (short)nSize );
- rResult.PutLong( nInt32 );
+ variable->PutLong(read< sal_Int32 >(&data));
break;
-
- case SbxULONG:
- nInt32 = CallINT(pProc, pStack, (short)nSize );
- rResult.PutULong( (ULONG)nInt32 );
- break;
-
-#ifndef WNT
case SbxSINGLE:
- {
- float nSingle = CallSNG(pProc, pStack, (short)nSize );
- rResult.PutSingle( nSingle );
+ variable->PutSingle(read< float >(&data));
break;
- }
-#endif
-
case SbxDOUBLE:
-#ifdef WNT
- case SbxSINGLE:
-#endif
- nDouble = CallDBL(pProc, pStack, (short)nSize );
- rResult.PutDouble( nDouble );
+ variable->PutDouble(read< double >(&data));
break;
-
- case SbxDATE:
- nDouble = CallDBL(pProc, pStack, (short)nSize );
- rResult.PutDate( nDouble );
+ case SbxSTRING:
+ read< char * >(&data); // handled by unmarshalString
break;
-
- case SbxCHAR:
- case SbxBYTE:
+ case SbxOBJECT:
+ {
+ data = reinterpret_cast< void const * >(
+ align(
+ reinterpret_cast< sal_uIntPtr >(data),
+ alignment(variable)));
+ SbxArray * props = PTR_CAST(SbxObject, variable->GetObject())->
+ GetProperties();
+ for (USHORT i = 0; i < props->Count(); ++i) {
+ data = unmarshal(props->Get(i), data);
+ }
+ break;
+ }
case SbxBOOL:
- nInt16 = CallINT(pProc, pStack, (short)nSize );
- rResult.PutByte( (BYTE)nInt16 );
- break;
-
- case SbxSTRING:
- case SbxLPSTR:
- pStr = CallSTR(pProc, pStack, (short)nSize );
- rResult.PutString( String::CreateFromAscii( pStr ) );
+ variable->PutBool(read< sal_Bool >(&data));
break;
-
- case SbxNULL:
- case SbxEMPTY:
- nInt16 = CallINT(pProc, pStack, (short)nSize );
- // Rueckgabe nur zulaessig, wenn variant!
- if( !rResult.IsFixed() )
- rResult.PutInteger( nInt16 );
+ case SbxBYTE:
+ variable->PutByte(read< sal_uInt8 >(&data));
break;
-
- case SbxCURRENCY:
- case SbxOBJECT:
- case SbxDATAOBJECT:
default:
- CallINT(pProc, pStack, (short)nSize );
+ OSL_ASSERT(false);
break;
- }
- delete [] pStack;
-
- if( pArgs )
- {
- // die Laengen aller uebergebenen Strings anpassen
- USHORT nCount = pArgs->Count();
- for( USHORT nCur = 1; nCur < nCount; nCur++ )
- {
- SbxVariable* pVar = pArgs->Get( nCur );
- BOOL bIsString = ( pVar->GetType() == SbxSTRING ) ||
- ( pVar->GetType() == SbxLPSTR );
-
- if( pVar->GetFlags() & SBX_REFERENCE )
- {
- pVar->ResetFlag( SBX_REFERENCE ); // Sbx moechte es so
- if( bIsString )
- {
- ByteString aByteStr( (char*)pVar->GetUserData() );
- String aStr( aByteStr, gsl_getSystemTextEncoding() );
- pVar->PutString( aStr );
+ }
+ } else {
+ SbxDimArray * arr = PTR_CAST(SbxDimArray, variable->GetObject());
+ int dims = arr->GetDims();
+ std::vector< INT32 > low(dims);
+ std::vector< INT32 > up(dims);
+ for (int i = 0; i < dims; ++i) {
+ arr->GetDim32(i + 1, low[i], up[i]);
+ }
+ for (std::vector< INT32 > idx = low;;) {
+ data = unmarshal(arr->Get32(&idx[0]), data);
+ int i = dims - 1;
+ while (idx[i] == up[i]) {
+ idx[i] = low[i];
+ if (i == 0) {
+ goto done;
}
+ --i;
}
- if( bIsString )
- {
- delete (char*)(pVar->GetUserData());
- pVar->SetUserData( 0 );
- }
+ ++idx[i];
}
+ done:;
}
- return 0;
+ return data;
}
-SbError SbiDllMgr::CallProcC( SbiDllProc pProc, SbxArray* pArgs,
- SbxVariable& rResult )
-{
- (void)pProc;
- (void)pArgs;
- (void)rResult;
-
- DBG_ERROR("C calling convention not supported");
- return SbERR_BAD_ARGUMENT;
+SbError unmarshalString(StringData const & data, SbxVariable & result) {
+ rtl::OUString str;
+ if (data.buffer != 0) {
+ char const * p = static_cast< char const * >(data.buffer);
+ sal_Int32 len;
+ if (data.special) {
+ len = static_cast< sal_Int32 >(result.GetULong());
+ if (len < 0) { // i.e., DWORD result >= 2^31
+ return ERRCODE_BASIC_BAD_ARGUMENT;
+ //TODO: more specific errcode?
+ }
+ } else {
+ len = rtl_str_getLength(p);
+ }
+ SbError e = convert(p, len, &str);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ }
+ data.variable->PutString(String(str));
+ return ERRCODE_NONE;
}
-void* SbiDllMgr::CreateStack( SbxArray* pArgs, USHORT& rSize )
+struct ProcData {
+ rtl::OString name;
+ FARPROC proc;
+};
+
+SbError call(
+ rtl::OUString const & dll, ProcData const & proc, SbxArray * arguments,
+ SbxVariable & result)
{
- if( !pArgs )
+ std::vector< char > stack;
+ MarshalData data;
+ // For DWORD GetLogicalDriveStringsA(DWORD nBufferLength, LPSTR lpBuffer)
+ // from kernel32, upon return, filled lpBuffer length is result DWORD, which
+ // requires special handling in unmarshalString; other functions might
+ // require similar treatment, too:
+ bool special =
+ dll.equalsIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("KERNEL32.DLL")) &&
+ (proc.name ==
+ rtl::OString(RTL_CONSTASCII_STRINGPARAM("GetLogicalDriveStringsA")));
+ for (USHORT i = 1; i < (arguments == 0 ? 0 : arguments->Count()); ++i) {
+ SbError e = marshal(
+ true, arguments->Get(i), special && i == 2, stack, stack.size(),
+ data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ align(stack, 4, 0, 0);
+ }
+ switch (result.GetType()) {
+ case SbxEMPTY:
+ DllMgr_call32(proc.proc, address(stack), stack.size());
+ break;
+ case SbxINTEGER:
+ result.PutInteger(
+ static_cast< sal_Int16 >(
+ DllMgr_call32(proc.proc, address(stack), stack.size())));
+ break;
+ case SbxLONG:
+ result.PutLong(
+ static_cast< sal_Int32 >(
+ DllMgr_call32(proc.proc, address(stack), stack.size())));
+ break;
+ case SbxSINGLE:
+ result.PutSingle(
+ static_cast< float >(
+ DllMgr_callFp(proc.proc, address(stack), stack.size())));
+ break;
+ case SbxDOUBLE:
+ result.PutDouble(
+ DllMgr_callFp(proc.proc, address(stack), stack.size()));
+ break;
+ case SbxSTRING:
+ {
+ char const * s1 = reinterpret_cast< char const * >(
+ DllMgr_call32(proc.proc, address(stack), stack.size()));
+ rtl::OUString s2;
+ SbError e = convert(s1, rtl_str_getLength(s1), &s2);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ result.PutString(String(s2));
+ break;
+ }
+ case SbxOBJECT:
+ //TODO
+ DllMgr_call32(proc.proc, address(stack), stack.size());
+ break;
+ case SbxBOOL:
+ result.PutBool(
+ static_cast< sal_Bool >(
+ DllMgr_call32(proc.proc, address(stack), stack.size())));
+ break;
+ case SbxBYTE:
+ result.PutByte(
+ static_cast< sal_uInt8 >(
+ DllMgr_call32(proc.proc, address(stack), stack.size())));
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ for (USHORT i = 1; i < (arguments == 0 ? 0 : arguments->Count()); ++i) {
+ arguments->Get(i)->ResetFlag(SBX_REFERENCE);
+ //TODO: skipped for errors?!?
+ }
+ for (std::vector< UnmarshalData >::iterator i(data.unmarshal.begin());
+ i != data.unmarshal.end(); ++i)
{
- rSize = 0;
- return 0;
+ unmarshal(i->variable, i->buffer);
}
- char* pStack = new char[ 2048 ];
- char* pTop = pStack;
- USHORT nCount = pArgs->Count();
- // erstes Element ueberspringen
-#ifndef WIN
- for( USHORT nCur = 1; nCur < nCount; nCur++ )
-#else
- // unter 16-Bit Windows anders rum (OS/2 ?????)
- for( USHORT nCur = nCount-1; nCur >= 1; nCur-- )
-#endif
+ for (std::vector< StringData >::iterator i(data.unmarshalStrings.begin());
+ i != data.unmarshalStrings.end(); ++i)
{
- SbxVariable* pVar = pArgs->Get( nCur );
- // AB 22.1.1996, Referenz
- if( pVar->GetFlags() & SBX_REFERENCE ) // Es ist eine Referenz
- {
- switch( pVar->GetType() )
- {
- case SbxINTEGER:
- case SbxUINT:
- case SbxINT:
- case SbxUSHORT:
- case SbxLONG:
- case SbxULONG:
- case SbxSINGLE:
- case SbxDOUBLE:
- case SbxCHAR:
- case SbxBYTE:
- case SbxBOOL:
- *((void**)pTop) = (void*)&(pVar->aData);
- pTop += sizeof( void* );
- break;
-
- case SbxSTRING:
- case SbxLPSTR:
- {
- USHORT nLen = 256;
- ByteString rStr( pVar->GetString(), gsl_getSystemTextEncoding() );
- if( rStr.Len() > 255 )
- nLen = rStr.Len() + 1;
-
- char* pStr = new char[ nLen ];
- strcpy( pStr, rStr.GetBuffer() ); // #100211# - checked
- // ist nicht so sauber, aber wir sparen ein Pointerarray
- DBG_ASSERT(sizeof(UINT32)>=sizeof(char*),"Gleich krachts im Basic");
- pVar->SetUserData( (sal_uIntPtr)pStr );
- *((const char**)pTop) = pStr;
- pTop += sizeof( char* );
- }
- break;
+ SbError e = unmarshalString(*i, result);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ }
+ return ERRCODE_NONE;
+}
- case SbxNULL:
- case SbxEMPTY:
- case SbxERROR:
- case SbxDATE:
- case SbxCURRENCY:
- case SbxOBJECT:
- case SbxDATAOBJECT:
- default:
- break;
+SbError getProcData(HMODULE handle, rtl::OUString const & name, ProcData * proc)
+{
+ OSL_ASSERT(proc != 0);
+ if (name.getLength() != 0 && name[0] == '@') { //TODO: "@" vs. "#"???
+ sal_Int32 n = name.copy(1).toInt32(); //TODO: handle bad input
+ if (n <= 0 || n > 0xFFFF) {
+ return ERRCODE_BASIC_BAD_ARGUMENT; //TODO: more specific errcode?
+ }
+ FARPROC p = GetProcAddress(handle, reinterpret_cast< LPCSTR >(n));
+ if (p != 0) {
+ proc->name = rtl::OString(RTL_CONSTASCII_STRINGPARAM("#")) +
+ rtl::OString::valueOf(n);
+ proc->proc = p;
+ return ERRCODE_NONE;
+ }
+ } else {
+ rtl::OString name8;
+ SbError e = convert(name, &name8);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ FARPROC p = GetProcAddress(handle, name8.getStr());
+ if (p != 0) {
+ proc->name = name8;
+ proc->proc = p;
+ return ERRCODE_NONE;
+ }
+ sal_Int32 i = name8.indexOf('#');
+ if (i != -1) {
+ name8 = name8.copy(0, i);
+ p = GetProcAddress(handle, name8.getStr());
+ if (p != 0) {
+ proc->name = name8;
+ proc->proc = p;
+ return ERRCODE_NONE;
}
}
- else
- {
- // ByVal
- switch( pVar->GetType() )
- {
- case SbxINTEGER:
- case SbxUINT:
- case SbxINT:
- case SbxUSHORT:
- *((INT16*)pTop) = pVar->GetInteger();
- pTop += sizeof( INT16 );
- break;
+ rtl::OString real(
+ rtl::OString(RTL_CONSTASCII_STRINGPARAM("_")) + name8);
+ p = GetProcAddress(handle, real.getStr());
+ if (p != 0) {
+ proc->name = real;
+ proc->proc = p;
+ return ERRCODE_NONE;
+ }
+ real = name8 + rtl::OString(RTL_CONSTASCII_STRINGPARAM("A"));
+ p = GetProcAddress(handle, real.getStr());
+ if (p != 0) {
+ proc->name = real;
+ proc->proc = p;
+ return ERRCODE_NONE;
+ }
+ }
+ return ERRCODE_BASIC_PROC_UNDEFINED;
+}
- case SbxLONG:
- case SbxULONG:
- *((INT32*)pTop) = pVar->GetLong();
- pTop += sizeof( INT32 );
- break;
+struct Dll: public salhelper::SimpleReferenceObject {
+private:
+ typedef std::map< rtl::OUString, ProcData > Procs;
- case SbxSINGLE:
- *((float*)pTop) = pVar->GetSingle();
- pTop += sizeof( float );
- break;
+ virtual ~Dll();
- case SbxDOUBLE:
- *((double*)pTop) = pVar->GetDouble();
- pTop += sizeof( double );
- break;
+public:
+ Dll(): handle(0) {}
- case SbxSTRING:
- case SbxLPSTR:
- {
- char* pStr = new char[ pVar->GetString().Len() + 1 ];
- ByteString aByteStr( pVar->GetString(), gsl_getSystemTextEncoding() );
- strcpy( pStr, aByteStr.GetBuffer() ); // #100211# - checked
- // ist nicht so sauber, aber wir sparen ein Pointerarray
- DBG_ASSERT(sizeof(UINT32)>=sizeof(char*),"Gleich krachts im Basic");
- pVar->SetUserData( (sal_uIntPtr)pStr );
- *((const char**)pTop) = pStr;
- pTop += sizeof( char* );
- }
- break;
+ SbError getProc(rtl::OUString const & name, ProcData * proc);
- case SbxCHAR:
- case SbxBYTE:
- case SbxBOOL:
- *((BYTE*)pTop) = pVar->GetByte();
- pTop += sizeof( BYTE );
- break;
+ HMODULE handle;
+ Procs procs;
+};
- case SbxNULL:
- case SbxEMPTY:
- case SbxERROR:
- case SbxDATE:
- case SbxCURRENCY:
- case SbxOBJECT:
- case SbxDATAOBJECT:
- default:
- break;
- }
+Dll::~Dll() {
+ if (handle != 0 && !FreeLibrary(handle)) {
+ OSL_TRACE("FreeLibrary(%p) failed with %u", handle, GetLastError());
+ }
+}
+
+SbError Dll::getProc(rtl::OUString const & name, ProcData * proc) {
+ Procs::iterator i(procs.find(name));
+ if (i != procs.end()) {
+ *proc = i->second;
+ return ERRCODE_NONE;
+ }
+ SbError e = getProcData(handle, name, proc);
+ if (e == ERRCODE_NONE) {
+ procs.insert(Procs::value_type(name, *proc));
+ }
+ return e;
+}
+
+rtl::OUString fullDllName(rtl::OUString const & name) {
+ rtl::OUString full(name);
+ if (full.indexOf('.') == -1) {
+ full += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".DLL"));
+ }
+ return full;
+}
+
+}
+
+struct SbiDllMgr::Impl: private boost::noncopyable {
+private:
+ typedef std::map< rtl::OUString, rtl::Reference< Dll > > Dlls;
+
+public:
+ Dll * getDll(rtl::OUString const & name);
+
+ Dlls dlls;
+};
+
+Dll * SbiDllMgr::Impl::getDll(rtl::OUString const & name) {
+ Dlls::iterator i(dlls.find(name));
+ if (i == dlls.end()) {
+ i = dlls.insert(Dlls::value_type(name, new Dll)).first;
+ HMODULE h = LoadLibraryW(name);
+ if (h == 0) {
+ dlls.erase(i);
+ return 0;
}
+ i->second->handle = h;
}
- rSize = (USHORT)((ULONG)pTop - (ULONG)pStack);
- return pStack;
+ return i->second.get();
}
+SbError SbiDllMgr::Call(
+ rtl::OUString const & function, rtl::OUString const & library,
+ SbxArray * arguments, SbxVariable & result, bool cdeclConvention)
+{
+ if (cdeclConvention) {
+ return ERRCODE_BASIC_NOT_IMPLEMENTED;
+ }
+ rtl::OUString dllName(fullDllName(library));
+ Dll * dll = impl_->getDll(dllName);
+ if (dll == 0) {
+ return ERRCODE_BASIC_BAD_DLL_LOAD;
+ }
+ ProcData proc;
+ SbError e = dll->getProc(function, &proc);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ return call(dllName, proc, arguments, result);
+}
+
+void SbiDllMgr::FreeDll(rtl::OUString const & library) {
+ impl_->dlls.erase(library);
+}
+#else
+
+struct SbiDllMgr::Impl {};
+
+SbError SbiDllMgr::Call(
+ rtl::OUString const &, rtl::OUString const &, SbxArray *, SbxVariable &,
+ bool)
+{
+ return ERRCODE_BASIC_NOT_IMPLEMENTED;
+}
+
+void SbiDllMgr::FreeDll(rtl::OUString const &) {}
+
+#endif
+SbiDllMgr::SbiDllMgr(): impl_(new Impl) {}
+SbiDllMgr::~SbiDllMgr() {}
diff --git a/basic/source/runtime/dllmgr.hxx b/basic/source/runtime/dllmgr.hxx
index 2c71a2843c37..fdff8c2849be 100644
--- a/basic/source/runtime/dllmgr.hxx
+++ b/basic/source/runtime/dllmgr.hxx
@@ -25,71 +25,36 @@
*
************************************************************************/
-#ifndef _DLLMGR_HXX
-#define _DLLMGR_HXX
+#ifndef INCLUDED_BASIC_SOURCE_RUNTIME_DLLMGR_HXX
+#define INCLUDED_BASIC_SOURCE_RUNTIME_DLLMGR_HXX
-#define _SVSTDARR_BYTESTRINGSSORT
-#include <svl/svarray.hxx>
-#ifndef _SVSTDARR_HXX //autogen
-#include <svl/svstdarr.hxx>
-#endif
+#include "sal/config.h"
-// !!! nur zum debuggen fuer infoboxes !!!
-//#ifndef _SV_HXX
-//#include <sv.hxx>
-//#endif
+#include <memory>
-//#ifndef _TOOLS_HXX
-//#include <tools.hxx>
-//#endif
-#define _SVSTDARR_STRINGS
-//#ifndef _SVSTDARR_HXX
-//#include <svstdarr.hxx>
-//#endif
-#ifndef _SBERRORS_HXX
-#include <basic/sberrors.hxx>
-#endif
+#include "basic/sberrors.hxx"
+#include "boost/noncopyable.hpp"
+namespace rtl { class OUString; }
class SbxArray;
class SbxVariable;
-class ImplSbiDll;
-class ImplSbiProc;
-
-SV_DECL_PTRARR_SORT(ImplDllArr,ByteStringPtr,5,5)
-
-class SbiDllMgr
-{
- ImplDllArr aDllArr;
-
- SbiDllMgr( const SbiDllMgr& );
+class SbiDllMgr: private boost::noncopyable {
+public:
+ SbiDllMgr();
-#ifdef _DLLMGR_CXX
- ImplSbiDll* GetDll( const ByteString& rDllName );
- SbiDllProc GetProc( ImplSbiDll*, const ByteString& rProcName );
+ ~SbiDllMgr();
- SbiDllHandle CreateDllHandle( const ByteString& rDllName );
- void FreeDllHandle( SbiDllHandle );
- SbiDllProc GetProcAddr( SbiDllHandle, const ByteString& pProcName );
- SbError CallProc( SbiDllProc pProc, SbxArray* pArgs,
- SbxVariable& rResult );
- SbError CallProcC( SbiDllProc pProc, SbxArray* pArgs,
- SbxVariable& rResult );
- void* CreateStack( SbxArray* pArgs, USHORT& rSize );
- void CheckDllName( ByteString& rName );
-#endif
+ SbError Call(
+ rtl::OUString const & function, rtl::OUString const & library,
+ SbxArray * arguments, SbxVariable & result, bool cdeclConvention);
-public:
- SbiDllMgr();
- ~SbiDllMgr();
+ void FreeDll(rtl::OUString const & library);
- SbError Call( const char* pFunc, const char* pDll,
- SbxArray* pArgs, SbxVariable& rResult,
- BOOL bCDecl );
+private:
+ struct Impl;
- void FreeDll( const ByteString& rDllName );
+ std::auto_ptr< Impl > impl_;
};
-
-
#endif
diff --git a/basic/source/runtime/makefile.mk b/basic/source/runtime/makefile.mk
index 9bd197975ee6..f2ed11196b28 100644
--- a/basic/source/runtime/makefile.mk
+++ b/basic/source/runtime/makefile.mk
@@ -30,6 +30,8 @@ PRJ=..$/..
PRJNAME=basic
TARGET=runtime
+ENABLE_EXCEPTIONS = TRUE
+
# --- Settings -----------------------------------------------------------
.INCLUDE : settings.mk
@@ -53,29 +55,12 @@ SLOFILES= \
$(SLO)$/ddectrl.obj \
$(SLO)$/dllmgr.obj
-.IF "$(GUI)$(CPU)" == "WINI"
-SLOFILES+= $(SLO)$/win.obj
-.ENDIF
-
.IF "$(GUI)$(COM)$(CPU)" == "WNTMSCI"
SLOFILES+= $(SLO)$/wnt.obj
-.ENDIF
-
-.IF "$(GUI)$(COM)$(CPU)" == "WNTGCCI"
+.ELIF "$(GUI)$(COM)$(CPU)" == "WNTGCCI"
SLOFILES+= $(SLO)$/wnt-mingw.obj
.ENDIF
-.IF "$(GUI)$(CPU)" == "OS2I"
-#FIXME SLOFILES+= $(SLO)$/os2.obj
-.ENDIF
-
-EXCEPTIONSFILES=$(SLO)$/step0.obj \
- $(SLO)$/step2.obj \
- $(SLO)$/methods.obj \
- $(SLO)$/methods1.obj \
- $(SLO)$/iosys.obj \
- $(SLO)$/runtime.obj
-
# --- Targets -------------------------------------------------------------
.INCLUDE : target.mk
diff --git a/basic/source/runtime/methods1.cxx b/basic/source/runtime/methods1.cxx
index b25c213a493d..8c7da2403705 100644
--- a/basic/source/runtime/methods1.cxx
+++ b/basic/source/runtime/methods1.cxx
@@ -523,6 +523,18 @@ RTLFUNC(WaitUntil)
Wait_Impl( true, rPar );
}
+RTLFUNC(DoEvents)
+{
+ (void)pBasic;
+ (void)bWrite;
+ (void)rPar;
+ Timer aTimer;
+ aTimer.SetTimeout( 1 );
+ aTimer.Start();
+ while ( aTimer.IsActive() )
+ Application::Yield();
+}
+
RTLFUNC(GetGUIVersion)
{
(void)pBasic;
@@ -622,8 +634,7 @@ RTLFUNC(FreeLibrary)
if ( rPar.Count() != 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
- ByteString aByteDLLName( rPar.Get(1)->GetString(), gsl_getSystemTextEncoding() );
- pINST->GetDllMgr()->FreeDll( aByteDLLName );
+ pINST->GetDllMgr()->FreeDll( rPar.Get(1)->GetString() );
}
bool IsBaseIndexOne()
{
diff --git a/basic/source/runtime/os2.asm b/basic/source/runtime/os2.asm
deleted file mode 100644
index a56f0b74b89e..000000000000
--- a/basic/source/runtime/os2.asm
+++ /dev/null
@@ -1,103 +0,0 @@
-;*************************************************************************
-;
-; DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-;
-; Copyright 2000, 2010 Oracle and/or its affiliates.
-;
-; OpenOffice.org - a multi-platform office productivity suite
-;
-; This file is part of OpenOffice.org.
-;
-; OpenOffice.org is free software: you can redistribute it and/or modify
-; it under the terms of the GNU Lesser General Public License version 3
-; only, as published by the Free Software Foundation.
-;
-; OpenOffice.org 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 version 3 for more details
-; (a copy is included in the LICENSE file that accompanied this code).
-;
-; You should have received a copy of the GNU Lesser General Public License
-; version 3 along with OpenOffice.org. If not, see
-; <http://www.openoffice.org/license.html>
-; for a copy of the LGPLv3 License.
-;
-;*************************************************************************
-
-; Anmerkungen
-; Direktaufruf von C- und PASCAL-Routinen, OS/2
-;
-; Inhalt:
-; type = CallXXX (far *proc, char *stack, short nstack)
-;
-; Kopie des Basic-Stacks (nstack Bytes) auf den C-Stack
-; und Aufruf der Prozedur.
-
- .386
- .MODEL FLAT
-
- .CODE
-
- PUBLIC CallINT
- PUBLIC CallLNG
- PUBLIC CallSNG
- PUBLIC CallDBL
- PUBLIC CallSTR
- PUBLIC CallFIX
-
- PUBLIC _CallINT
- PUBLIC _CallLNG
- PUBLIC _CallSNG
- PUBLIC _CallDBL
- PUBLIC _CallSTR
- PUBLIC _CallFIX
-
-_CallINT LABEL byte
-_CallLNG LABEL byte
-_CallSNG LABEL byte
-_CallDBL LABEL byte
-_CallSTR LABEL byte
-_CallFIX LABEL byte
-
-CallINT LABEL byte
-CallLNG LABEL byte
-CallSNG LABEL byte
-CallDBL LABEL byte
-CallSTR LABEL byte
-CallFIX PROC
-
-p EQU [EBP+8]
-stk EQU [EBP+12]
-n EQU [EBP+16]
-
- PUSH EBP
- MOV EBP,ESP
- PUSH ESI
- PUSH EDI
- MOV DX,DS
- MOVZX ECX,word ptr [n]
- SUB ESP,ECX
- MOV EDI,ESP
- MOV AX,SS
- MOV ES,AX
- MOV ESI,[stk]
- SHR ECX,1
- CLD
- JCXZ $1
- REP MOVSW ; Stack uebernehmen
-$1: MOV DS,DX
- CALL LARGE [p] ; 32-bit
- MOV ECX,EBP
- SUB ECX,8 ; wegen gepushter Register
- MOV ESP,ECX
- POP EDI
- POP ESI
- POP EBP
-; Bei Borland C++ Calling Convention:
-; RET 12
-; CSet System-Calling Convention
- RET
-CallFIX ENDP
-
- END
diff --git a/basic/source/runtime/rtlproto.hxx b/basic/source/runtime/rtlproto.hxx
index 6c90c408cd93..1a1ae4f32283 100644
--- a/basic/source/runtime/rtlproto.hxx
+++ b/basic/source/runtime/rtlproto.hxx
@@ -166,6 +166,7 @@ extern RTLFUNC(RmDir); // JSM
extern RTLFUNC(SendKeys); // JSM
extern RTLFUNC(DimArray);
extern RTLFUNC(Dir);
+extern RTLFUNC(DoEvents);
extern RTLFUNC(Exp);
extern RTLFUNC(FileLen);
extern RTLFUNC(Fix);
diff --git a/basic/source/runtime/runtime.cxx b/basic/source/runtime/runtime.cxx
index ef3e4c056cb6..c3419adbfdb3 100755
--- a/basic/source/runtime/runtime.cxx
+++ b/basic/source/runtime/runtime.cxx
@@ -155,6 +155,7 @@ SbiRuntime::pStep0 SbiRuntime::aStep0[] = { // Alle Opcodes ohne Operanden
&SbiRuntime::StepVBASET,// vba-like set statement
&SbiRuntime::StepERASE_CLEAR,// vba-like set statement
&SbiRuntime::StepARRAYACCESS,// access TOS as array
+ &SbiRuntime::StepBYVAL, // access TOS as array
};
SbiRuntime::pStep1 SbiRuntime::aStep1[] = { // Alle Opcodes mit einem Operanden
@@ -906,7 +907,7 @@ sal_Int32 SbiRuntime::translateErrorToVba( SbError nError, String& rMsg )
{
// TEST, has to be vb here always
#ifdef DBG_UTIL
- SbError nTmp = StarBASIC::GetSfxFromVBError( USHORT( nError ) );
+ SbError nTmp = StarBASIC::GetSfxFromVBError( (USHORT)nError );
DBG_ASSERT( nTmp, "No VB error!" );
#endif
@@ -1231,9 +1232,7 @@ void SbiRuntime::DllCall
SbxVariable* pRes = new SbxVariable( eResType );
SbiDllMgr* pDllMgr = pInst->GetDllMgr();
- ByteString aByteFuncName( aFuncName, gsl_getSystemTextEncoding() );
- ByteString aByteDLLName( aDLLName, gsl_getSystemTextEncoding() );
- SbError nErr = pDllMgr->Call( aByteFuncName.GetBuffer(), aByteDLLName.GetBuffer(), pArgs, *pRes, bCDecl );
+ SbError nErr = pDllMgr->Call( aFuncName, aDLLName, pArgs, *pRes, bCDecl );
if( nErr )
Error( nErr );
PushVar( pRes );
diff --git a/basic/source/runtime/stdobj.cxx b/basic/source/runtime/stdobj.cxx
index 13bc8810144a..60d2e9cf448d 100644
--- a/basic/source/runtime/stdobj.cxx
+++ b/basic/source/runtime/stdobj.cxx
@@ -216,6 +216,7 @@ static Methods aMethods[] = {
{ "Dir", SbxSTRING, 2 | _FUNCTION, RTLNAME(Dir),0 },
{ "FileSpec", SbxSTRING, _OPT, NULL,0 },
{ "attrmask", SbxINTEGER, _OPT, NULL,0 },
+{ "DoEvents", SbxEMPTY, _FUNCTION, RTLNAME(DoEvents),0 },
{ "DumpAllObjects", SbxEMPTY, 2 | _SUB, RTLNAME(DumpAllObjects),0 },
{ "FileSpec", SbxSTRING, 0,NULL,0 },
{ "DumpAll", SbxINTEGER, _OPT, NULL,0 },
@@ -361,6 +362,8 @@ static Methods aMethods[] = {
{ "Count", SbxLONG, 0,NULL,0 },
{ "Len", SbxLONG, 1 | _FUNCTION, RTLNAME(Len),0 },
{ "StringOrVariant", SbxVARIANT, 0,NULL,0 },
+{ "LenB", SbxLONG, 1 | _FUNCTION, RTLNAME(Len),0 },
+ { "StringOrVariant", SbxVARIANT, 0,NULL,0 },
{ "Load", SbxNULL, 1 | _FUNCTION, RTLNAME(Load),0 },
{ "object", SbxOBJECT, 0,NULL,0 },
{ "LoadPicture", SbxOBJECT, 1 | _FUNCTION, RTLNAME(LoadPicture),0 },
@@ -628,6 +631,10 @@ SbiStdObject::SbiStdObject( const String& r, StarBASIC* pb ) : SbxObject( r )
p += ( p->nArgs & _ARGSMASK ) + 1;
}
+ // #i92642: Remove default properties
+ Remove( XubString( RTL_CONSTASCII_USTRINGPARAM("Name") ), SbxCLASS_DONTCARE );
+ Remove( XubString( RTL_CONSTASCII_USTRINGPARAM("Parent") ), SbxCLASS_DONTCARE );
+
SetParent( pb );
pStdFactory = new SbStdFactory;
diff --git a/basic/source/runtime/step0.cxx b/basic/source/runtime/step0.cxx
index 39af5ea4adc3..1d9333ff7555 100644
--- a/basic/source/runtime/step0.cxx
+++ b/basic/source/runtime/step0.cxx
@@ -43,6 +43,9 @@
#include <vcl/svapp.hxx>
#include <unotools/textsearch.hxx>
+Reference< XInterface > createComListener( const Any& aControlAny, const ::rtl::OUString& aVBAType,
+ const ::rtl::OUString& aPrefix, SbxObjectRef xScopeObj );
+
#include <algorithm>
SbxVariable* getDefaultProp( SbxVariable* pRef );
@@ -515,8 +518,29 @@ void SbiRuntime::StepSET_Impl( SbxVariableRef& refVal, SbxVariableRef& refVar, b
}
}
+ // Handle withevents
+ BOOL bWithEvents = refVar->IsSet( SBX_WITH_EVENTS );
+ Reference< XInterface > xComListener;
+ if( bWithEvents )
+ {
+ SbxBase* pObj = refVal->GetObject();
+ SbUnoObject* pUnoObj = (pObj != NULL) ? PTR_CAST(SbUnoObject,pObj) : NULL;
+ if( pUnoObj != NULL )
+ {
+ Any aControlAny = pUnoObj->getUnoAny();
+ String aDeclareClassName = refVar->GetDeclareClassName();
+ ::rtl::OUString aVBAType = aDeclareClassName;
+ ::rtl::OUString aPrefix = refVar->GetName();
+ SbxObjectRef xScopeObj = refVar->GetParent();
+ xComListener = createComListener( aControlAny, aVBAType, aPrefix, xScopeObj );
+ }
+ }
+
*refVar = *refVal;
+ if( bWithEvents )
+ refVar->SetComListener( xComListener ); // Hold reference
+
// lhs is a property who's value is currently (Empty e.g. no broadcast yet)
// in this case if there is a default prop involved the value of the
// default property may infact be void so the type will also be SbxEMPTY
@@ -908,6 +932,19 @@ void SbiRuntime::StepARRAYACCESS()
PushVar( CheckArray( refVar ) );
}
+void SbiRuntime::StepBYVAL()
+{
+ // Copy variable on stack to break call by reference
+ SbxVariableRef pVar = PopVar();
+ SbxDataType t = pVar->GetType();
+
+ SbxVariable* pCopyVar = new SbxVariable( t );
+ pCopyVar->SetFlag( SBX_READWRITE );
+ *pCopyVar = *pVar;
+
+ PushVar( pCopyVar );
+}
+
// Einrichten eines Argvs
// nOp1 bleibt so -> 1. Element ist Returnwert
diff --git a/basic/source/runtime/step1.cxx b/basic/source/runtime/step1.cxx
index c6f090048bf2..e23ef864218e 100644
--- a/basic/source/runtime/step1.cxx
+++ b/basic/source/runtime/step1.cxx
@@ -453,9 +453,9 @@ bool SbiRuntime::implIsClass( SbxObject* pObj, const String& aClass )
}
bool SbiRuntime::checkClass_Impl( const SbxVariableRef& refVal,
- const String& aClass, bool bRaiseErrors )
+ const String& aClass, bool bRaiseErrors, bool bDefault )
{
- bool bOk = true;
+ bool bOk = bDefault;
SbxDataType t = refVal->GetType();
if( t == SbxOBJECT )
@@ -489,6 +489,8 @@ bool SbiRuntime::checkClass_Impl( const SbxVariableRef& refVal,
}
else
{
+ bOk = true;
+
SbClassModuleObject* pClassModuleObject = PTR_CAST(SbClassModuleObject,pObj);
if( pClassModuleObject != NULL )
pClassModuleObject->triggerInitializeEvent();
@@ -532,7 +534,8 @@ void SbiRuntime::StepTESTCLASS( UINT32 nOp1 )
{
SbxVariableRef xObjVal = PopVar();
String aClass( pImg->GetString( static_cast<short>( nOp1 ) ) );
- bool bOk = checkClass_Impl( xObjVal, aClass, false );
+ bool bDefault = !bVBAEnabled;
+ bool bOk = checkClass_Impl( xObjVal, aClass, false, bDefault );
SbxVariable* pRet = new SbxVariable;
pRet->PutBool( bOk );
diff --git a/basic/source/runtime/step2.cxx b/basic/source/runtime/step2.cxx
index 3a260ad203a3..72ea67dd8db4 100644
--- a/basic/source/runtime/step2.cxx
+++ b/basic/source/runtime/step2.cxx
@@ -1068,9 +1068,17 @@ void SbiRuntime::StepTCREATE( UINT32 nOp1, UINT32 nOp2 )
pCopyObj->SetName( aName );
SbxVariable* pNew = new SbxVariable;
pNew->PutObject( pCopyObj );
+ pNew->SetDeclareClassName( aClass );
PushVar( pNew );
}
+void SbiRuntime::implCreateFixedString( SbxVariable* pStrVar, UINT32 nOp2 )
+{
+ USHORT nCount = static_cast<USHORT>( nOp2 >> 17 ); // len = all bits above 0x10000
+ String aStr;
+ aStr.Fill( nCount, 0 );
+ pStrVar->PutString( aStr );
+}
// Einrichten einer lokalen Variablen (+StringID+Typ)
@@ -1081,9 +1089,15 @@ void SbiRuntime::StepLOCAL( UINT32 nOp1, UINT32 nOp2 )
String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
if( refLocals->Find( aName, SbxCLASS_DONTCARE ) == NULL )
{
- SbxDataType t = (SbxDataType) nOp2;
+ SbxDataType t = (SbxDataType)(nOp2 & 0xffff);
SbxVariable* p = new SbxVariable( t );
p->SetName( aName );
+ bool bWithEvents = ((t & 0xff) == SbxOBJECT && (nOp2 & SBX_TYPE_WITH_EVENTS_FLAG) != 0);
+ if( bWithEvents )
+ p->SetFlag( SBX_WITH_EVENTS );
+ bool bFixedString = ((t & 0xff) == SbxSTRING && (nOp2 & SBX_FIXED_LEN_STRING_FLAG) != 0);
+ if( bFixedString )
+ implCreateFixedString( p, nOp2 );
refLocals->Put( p, refLocals->Count() );
}
}
@@ -1093,7 +1107,7 @@ void SbiRuntime::StepLOCAL( UINT32 nOp1, UINT32 nOp2 )
void SbiRuntime::StepPUBLIC_Impl( UINT32 nOp1, UINT32 nOp2, bool bUsedForClassModule )
{
String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
- SbxDataType t = (SbxDataType) nOp2;
+ SbxDataType t = (SbxDataType)(SbxDataType)(nOp2 & 0xffff);;
BOOL bFlag = pMod->IsSet( SBX_NO_MODIFY );
pMod->SetFlag( SBX_NO_MODIFY );
SbxVariableRef p = pMod->Find( aName, SbxCLASS_PROPERTY );
@@ -1109,6 +1123,13 @@ void SbiRuntime::StepPUBLIC_Impl( UINT32 nOp1, UINT32 nOp2, bool bUsedForClassMo
pProp->SetFlag( SBX_DONTSTORE );
// AB: 2.7.1996: HACK wegen 'Referenz kann nicht gesichert werden'
pProp->SetFlag( SBX_NO_MODIFY);
+
+ bool bWithEvents = ((t & 0xff) == SbxOBJECT && (nOp2 & SBX_TYPE_WITH_EVENTS_FLAG) != 0);
+ if( bWithEvents )
+ pProp->SetFlag( SBX_WITH_EVENTS );
+ bool bFixedString = ((t & 0xff) == SbxSTRING && (nOp2 & SBX_FIXED_LEN_STRING_FLAG) != 0);
+ if( bFixedString )
+ implCreateFixedString( p, nOp2 );
}
}
@@ -1122,7 +1143,10 @@ void SbiRuntime::StepPUBLIC_P( UINT32 nOp1, UINT32 nOp2 )
// Creates module variable that isn't reinitialised when
// between invocations ( for VBASupport & document basic only )
if( pMod->pImage->bFirstInit )
- StepPUBLIC( nOp1, nOp2 );
+ {
+ bool bUsedForClassModule = pImg->GetFlag( SBIMG_CLASSMODULE );
+ StepPUBLIC_Impl( nOp1, nOp2, bUsedForClassModule );
+ }
}
// Einrichten einer globalen Variablen (+StringID+Typ)
@@ -1133,7 +1157,7 @@ void SbiRuntime::StepGLOBAL( UINT32 nOp1, UINT32 nOp2 )
StepPUBLIC_Impl( nOp1, nOp2, true );
String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
- SbxDataType t = (SbxDataType) nOp2;
+ SbxDataType t = (SbxDataType)(SbxDataType)(nOp2 & 0xffff);;
BOOL bFlag = rBasic.IsSet( SBX_NO_MODIFY );
rBasic.SetFlag( SBX_NO_MODIFY );
SbxVariableRef p = rBasic.Find( aName, SbxCLASS_PROPERTY );
diff --git a/basic/source/runtime/win.asm b/basic/source/runtime/win.asm
deleted file mode 100644
index dea597a4ce51..000000000000
--- a/basic/source/runtime/win.asm
+++ /dev/null
@@ -1,80 +0,0 @@
-;*************************************************************************
-;
-; DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-;
-; Copyright 2000, 2010 Oracle and/or its affiliates.
-;
-; OpenOffice.org - a multi-platform office productivity suite
-;
-; This file is part of OpenOffice.org.
-;
-; OpenOffice.org is free software: you can redistribute it and/or modify
-; it under the terms of the GNU Lesser General Public License version 3
-; only, as published by the Free Software Foundation.
-;
-; OpenOffice.org 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 version 3 for more details
-; (a copy is included in the LICENSE file that accompanied this code).
-;
-; You should have received a copy of the GNU Lesser General Public License
-; version 3 along with OpenOffice.org. If not, see
-; <http://www.openoffice.org/license.html>
-; for a copy of the LGPLv3 License.
-;
-;*************************************************************************
-
-; Anmerkungen
-; Direktaufruf von C- und PASCAL-Routinen, Windows und OS/2
-;
-; Inhalt:
-; type = CallXXX (far *proc, char *stack, short nstack)
-;
-; Kopie des Basic-Stacks (nstack Bytes) auf den C-Stack
-; und Aufruf der Prozedur.
-
- .MODEL LARGE,C
-
- .CODE
-
- PUBLIC CallINT
- PUBLIC CallLNG
- PUBLIC CallSNG
- PUBLIC CallDBL
- PUBLIC CallSTR
- PUBLIC CallFIX
-
-CallINT LABEL byte
-CallLNG LABEL byte
-CallSNG LABEL byte
-CallDBL LABEL byte
-CallSTR LABEL byte
-CallFIX PROC p:PTR,stk:PTR,n:WORD
-
- PUSH SI
- PUSH DI
- MOV DX,DS
- SUB SP,[n]
- MOV DI,SP
- MOV AX,SS
- MOV ES,AX
- LDS SI,[stk]
- MOV CX,[n]
- SHR CX,1
- CLD
- JCXZ $1
- REP MOVSW ; Stack uebernehmen
-$1: MOV DS,DX
- CALL [p] ; Aufruf der Prozedur
- CLI
- MOV SP,BP
- SUB SP,4 ; wegen gepushter Register
- STI
- POP DI
- POP SI
- RET
-
-CallFIX ENDP
-
- END
diff --git a/basic/source/runtime/wnt-mingw.s b/basic/source/runtime/wnt-mingw.s
index 1168804102d0..7868ddd386f0 100644
--- a/basic/source/runtime/wnt-mingw.s
+++ b/basic/source/runtime/wnt-mingw.s
@@ -1,7 +1,7 @@
#*************************************************************************
#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
+#
# Copyright 2000, 2010 Oracle and/or its affiliates.
#
# OpenOffice.org - a multi-platform office productivity suite
@@ -23,71 +23,31 @@
# <http://www.openoffice.org/license.html>
# for a copy of the LGPLv3 License.
#
-#*************************************************************************
-
-# Anmerkungen
-# Direktaufruf von C- und PASCAL-Routinen, Windows und OS/2
-#
-# Inhalt:
-# type = CallXXX (far *pProc, char *pStack, short nStack)
-#
-# Kopie des Basic-Stacks (nStack Bytes) auf den C-Stack
-# und Aufruf der Prozedur.
-
- .intel_syntax
- #.386
-
-#_TEXT SEGMENT DWORD PUBLIC 'CODE' USE32
-
- #ASSUME CS:_TEXT
-
-.globl _CallINT
-.globl _CallLNG
-.globl _CallDBL
-.globl _CallSTR
-.globl _CallFIX
-
-_CallINT:
-_CallLNG:
-_CallDBL:
-_CallSTR:
-
-_CallFIX: PUSH EBP
- MOV EBP,ESP
- PUSH ESI
- PUSH EDI
-
- PUSH ECX
- PUSH EDX
-
- MOV DX,DS
- MOVZX EAX,WORD PTR [EBP+16] # EAX == nStack
- SUB ESP,EAX # Stack um nStack Bytes vergroessern
- MOV EDI,ESP
- MOV AX,SS
- MOV ES,AX # ES:EDI = Startadresse des fuer
- # Parameter reservierten Stackbereichs
- MOV ESI,[EBP+12] # DS:ESI == pStack
-
- MOVZX ECX,WORD PTR [EBP+16] # ECX == nStack
- SHR ECX,1
- CLD
- JCXZ $1
- REP MOVSW # Stack uebernehmen
-$1: MOV DS,DX
- CALL DWORD PTR [EBP+8] # Aufruf der Prozedur
- # CLI # unter NT nicht erlaubt (privileged instruction)
- MOV ESP,EBP
- SUB ESP,16 # wegen gepushter Register
- # (ESI, EDI)
- # STI
- POP EDX
- POP ECX
- POP EDI
- POP ESI
- POP EBP
- RET 12
-
-#_TEXT ENDS
-
- #END
+#***********************************************************************/
+
+.intel_syntax
+
+.globl _DllMgr_call32
+.globl _DllMgr_callFp
+
+_DllMgr_call32:
+_DllMgr_callFp:
+ push ebp
+ mov ebp, esp
+ push esi
+ push edi
+ mov ecx, [ebp+16]
+ jecxz $1
+ sub esp, ecx
+ mov edi, esp
+ mov esi, [ebp+12]
+ shr ecx, 2
+ rep movsd
+$1: call DWORD PTR [ebp+8]
+ ; for extra safety, do not trust esp after call (in case the Basic Declare
+ ; signature is wrong):
+ mov edi, [ebp-8]
+ mov esi, [ebp-4]
+ mov esp, ebp
+ pop ebp
+ ret 12
diff --git a/basic/source/runtime/wnt.asm b/basic/source/runtime/wnt.asm
index 3824daae964b..2a8710e34243 100644
--- a/basic/source/runtime/wnt.asm
+++ b/basic/source/runtime/wnt.asm
@@ -1,7 +1,7 @@
;*************************************************************************
;
; DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-;
+;
; Copyright 2000, 2010 Oracle and/or its affiliates.
;
; OpenOffice.org - a multi-platform office productivity suite
@@ -23,70 +23,34 @@
; <http://www.openoffice.org/license.html>
; for a copy of the LGPLv3 License.
;
-;*************************************************************************
-
-; Anmerkungen
-; Direktaufruf von C- und PASCAL-Routinen, Windows und OS/2
-;
-; Inhalt:
-; type = CallXXX (far *pProc, char *pStack, short nStack)
-;
-; Kopie des Basic-Stacks (nStack Bytes) auf den C-Stack
-; und Aufruf der Prozedur.
-
- .386
-
-_TEXT SEGMENT DWORD PUBLIC 'CODE' USE32
-
- ASSUME CS:_TEXT
-
- PUBLIC _CallINT@12
- PUBLIC _CallLNG@12
- PUBLIC _CallDBL@12
- PUBLIC _CallSTR@12
- PUBLIC _CallFIX@12
-
-_CallINT@12 LABEL byte
-_CallLNG@12 LABEL byte
-_CallDBL@12 LABEL byte
-_CallSTR@12 LABEL byte
-
-_CallFIX@12: PUSH EBP
- MOV EBP,ESP
- PUSH ESI
- PUSH EDI
-
- PUSH ECX
- PUSH EDX
-
- MOV DX,DS
- MOVZX EAX,WORD PTR [EBP+16] ; EAX == nStack
- SUB ESP,EAX ; Stack um nStack Bytes vergroessern
- MOV EDI,ESP
- MOV AX,SS
- MOV ES,AX ; ES:EDI = Startadresse des fuer
- ; Parameter reservierten Stackbereichs
- MOV ESI,[EBP+12] ; DS:ESI == pStack
-
- MOVZX ECX,WORD PTR [EBP+16] ; ECX == nStack
- SHR ECX,1
- CLD
- JCXZ $1
- REP MOVSW ; Stack uebernehmen
-$1: MOV DS,DX
- CALL DWORD PTR [EBP+8] ; Aufruf der Prozedur
- ; CLI ; unter NT nicht erlaubt (privileged instruction)
- MOV ESP,EBP
- SUB ESP,16 ; wegen gepushter Register
- ; (ESI, EDI)
- ; STI
- POP EDX
- POP ECX
- POP EDI
- POP ESI
- POP EBP
- RET 12
-
-_TEXT ENDS
-
- END
+;***********************************************************************/
+
+.386
+
+PUBLIC _DllMgr_call32@12
+PUBLIC _DllMgr_callFp@12
+
+_TEXT SEGMENT
+_DllMgr_call32@12:
+_DllMgr_callFp@12:
+ push ebp
+ mov ebp, esp
+ push esi
+ push edi
+ mov ecx, [ebp+16]
+ jecxz $1
+ sub esp, ecx
+ mov edi, esp
+ mov esi, [ebp+12]
+ shr ecx, 2
+ rep movsd
+$1: call DWORD PTR [ebp+8]
+ ; for extra safety, do not trust esp after call (in case the Basic Declare
+ ; signature is wrong):
+ mov edi, [ebp-8]
+ mov esi, [ebp-4]
+ mov esp, ebp
+ pop ebp
+ ret 12
+_TEXT ENDS
+END