зеркало из https://github.com/mozilla/pjs.git
actually free libPath after verifying that PR_GetLibraryPath really does copy the return value.
This commit is contained in:
Родитель
f0f98353a8
Коммит
03ae731064
|
@ -1,267 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
#include "NativeMethodDispatcher.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "prio.h"
|
||||
#include "plstr.h"
|
||||
#include "prprf.h"
|
||||
#include "prmem.h"
|
||||
|
||||
#include "CUtils.h"
|
||||
#include "StringUtils.h"
|
||||
#include "Address.h"
|
||||
#include "NameMangler.h"
|
||||
|
||||
/* Each of these manglers must be registered using
|
||||
* NativeMethodDispatcher::register
|
||||
*/
|
||||
#include "JNIManglers.h"
|
||||
#include "NetscapeManglers.h"
|
||||
|
||||
Vector<NameMangler *> NativeMethodDispatcher::manglers;
|
||||
|
||||
/*
|
||||
* create a string for the native function name by adding the
|
||||
* appropriate system-specific decorations.
|
||||
*
|
||||
* On Win32, "__stdcall" functions are exported differently, depending
|
||||
* on the compiler. In MSVC 4.0, they are decorated with a "_" in the
|
||||
* beginning, and @nnn in the end, where nnn is the number of bytes in
|
||||
* the arguments (in decimal). Borland C++ exports undecorated names.
|
||||
*
|
||||
* buildFunName handles different encodings depending on the value
|
||||
* of callType. It returns false when handed a callType it can't handle
|
||||
* or which does not apply to the current platform.
|
||||
*/
|
||||
bool NativeMethodDispatcher::buildFunName(char *name, Int32 nameMax,
|
||||
Method &m,
|
||||
NativeCallingConvention callType,
|
||||
NameMangler &mangler)
|
||||
{
|
||||
#if defined(XP_PC)
|
||||
if (callType == nativeCallingConventionStdCallMSVC) {
|
||||
/* For Microsoft MSVC 4.0/5.0 */
|
||||
char suffix[6]; /* This is enough since Java never has more than
|
||||
256 words of arguments. */
|
||||
int realArgsSize;
|
||||
int nameLen;
|
||||
int i;
|
||||
|
||||
realArgsSize = m.getArgsSize() +
|
||||
mangler.getExtraArgsSize((m.getModifiers() & CR_METHOD_STATIC) != 0);
|
||||
|
||||
PR_snprintf(suffix, sizeof(suffix), "@%d", realArgsSize);
|
||||
|
||||
nameLen = PL_strlen(name);
|
||||
|
||||
if (nameLen >= nameMax - 7)
|
||||
return false;
|
||||
|
||||
for(i = nameLen; i > 0; i--)
|
||||
name[i] = name[i-1];
|
||||
name[0] = '_';
|
||||
|
||||
PR_snprintf(name + nameLen + 1, sizeof(suffix), "%s", suffix);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(GLOBALS_NEED_UNDERSCORE)
|
||||
int nameLen;
|
||||
int i;
|
||||
|
||||
nameLen = PL_strlen(name);
|
||||
|
||||
for(i = nameLen; i > 0; i--)
|
||||
name[i] = name[i-1];
|
||||
name[0] = '_';
|
||||
#endif
|
||||
|
||||
if (callType == nativeCallingConventionDefault)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
addr NativeMethodDispatcher::resolve(Method &method)
|
||||
{
|
||||
const char *methodName = method.getName();
|
||||
const char *className = method.getDeclaringClass()->getName();
|
||||
|
||||
const char *signature = method.getSignatureString();
|
||||
|
||||
/* XXX This is not a correct upper-bound on the length */
|
||||
Int32 len = PL_strlen(methodName) + PL_strlen(className)*2 +
|
||||
PL_strlen(signature)*2 + sizeof("Netscape_Java___");
|
||||
|
||||
TemporaryBuffer buf(len);
|
||||
char *name = buf;
|
||||
|
||||
/* Try all the name-mangling schemes at our disposal, one after another..*/
|
||||
for (Uint32 i = 0; i < manglers.size(); i++) {
|
||||
if (!manglers[i]->mangle(className, methodName, signature, name, len))
|
||||
continue;
|
||||
|
||||
Int32 numConventions = manglers[i]->numNativeConventions();
|
||||
const NativeCallingConvention *conventions =
|
||||
manglers[i]->getNativeConventions();
|
||||
|
||||
/* Try all the calling conventions that this mangling scheme supports */
|
||||
for (Int32 j = 0; j < numConventions; j++) {
|
||||
if (!buildFunName(name, len, method, conventions[j],
|
||||
*manglers[i]))
|
||||
continue;
|
||||
|
||||
void *address;
|
||||
PRLibrary *lib;
|
||||
|
||||
if ((address = PR_FindSymbolAndLibrary(name, &lib)) != NULL)
|
||||
return functionAddress((void (*)())(manglers[i]->getCode(method, address)));
|
||||
}
|
||||
}
|
||||
|
||||
return functionAddress((void (*)()) 0);
|
||||
}
|
||||
|
||||
|
||||
void NativeMethodDispatcher::staticInit()
|
||||
{
|
||||
registerMangler(*new JNIShortMangler());
|
||||
registerMangler(*new JNILongMangler());
|
||||
registerMangler(*new NetscapeShortMangler());
|
||||
registerMangler(*new NetscapeLongMangler());
|
||||
}
|
||||
|
||||
PRLibrary *NativeMethodDispatcher::loadLibrary(const char *simpleLibName)
|
||||
{
|
||||
/* For now, we parse the path *each* time we load a library. In the future,
|
||||
* NativeMethodDispatcher must be capable of storing a set of paths, and
|
||||
* each path could potentially be a directory, zip or jar file.
|
||||
*/
|
||||
char *libPath = PR_GetLibraryPath();
|
||||
char *libName = 0;
|
||||
PRLibrary *lib = 0;
|
||||
#if defined(XP_PC)
|
||||
static const char* PATH_SEPARATOR = ";";
|
||||
#else
|
||||
static const char* PATH_SEPARATOR = ":";
|
||||
#endif
|
||||
|
||||
if (libPath) {
|
||||
Strtok tok(libPath);
|
||||
for (const char *token = tok.get(PATH_SEPARATOR); token; token = tok.get(PATH_SEPARATOR))
|
||||
if ((libName = PR_GetLibraryName(token, simpleLibName)) != 0) {
|
||||
lib = PR_LoadLibrary(libName);
|
||||
//free(libName);
|
||||
libName = 0;
|
||||
|
||||
if (lib)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Always search in the current directory */
|
||||
if (!lib && (libName = PR_GetLibraryName(".", simpleLibName)) != 0) {
|
||||
lib = PR_LoadLibrary(libName);
|
||||
//free(libName);
|
||||
}
|
||||
|
||||
/* XXX The NSPR doc says it's our responsibility to free this, but in
|
||||
* reality PR_GetLibraryPath() returns a pointer to the actual path.
|
||||
* So until they fix this or clarify how PR_GetLibraryPath() should
|
||||
* behave, this line shall remain commented out -- Sriram, 8/12/97
|
||||
*/
|
||||
/* if (libPath) PR_DELETE(libPath); */
|
||||
|
||||
return lib;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
char *NativeMethodDispatcher::mangle(const char *className,
|
||||
const char *methodName,
|
||||
const char *signature,
|
||||
char *buffer, Int32 len,
|
||||
NativeMethodDispatcher::MangleType mangleType)
|
||||
{
|
||||
char *bufptr = buffer;
|
||||
char *bufend = buffer + len;
|
||||
|
||||
/* For internal (Netscape-style) mangling, prefix a Netscape_ to the JNI-
|
||||
* style mangled name
|
||||
*/
|
||||
if (mangleType == mangleTypeNetscapeShort ||
|
||||
mangleType == mangleTypeNetscapeLong) {
|
||||
PR_snprintf(bufptr, bufend - bufptr, "Netscape_");
|
||||
bufptr += PL_strlen(bufptr);
|
||||
mangleType = (mangleType == mangleTypeNetscapeShort) ?
|
||||
mangleTypeJNIShort: mangleTypeJNILong;
|
||||
|
||||
} else
|
||||
*bufptr = 0;
|
||||
|
||||
/* Copy over Java_ */
|
||||
PL_strcat(bufptr, "Java_");
|
||||
bufptr += PL_strlen(bufptr);
|
||||
|
||||
bufptr += NativeMethodDispatcher::mangleUTFString(className, bufptr,
|
||||
bufend - bufptr,
|
||||
mangleUTFJNI);
|
||||
|
||||
if (bufend - bufptr > 1)
|
||||
*bufptr++ = '_';
|
||||
|
||||
bufptr += NativeMethodDispatcher::mangleUTFString(methodName, bufptr,
|
||||
bufend - bufptr,
|
||||
mangleUTFJNI);
|
||||
|
||||
/* JNI long name: includes a mangled signature. */
|
||||
if (mangleType == mangleTypeJNILong) {
|
||||
char sig[1024];
|
||||
int i;
|
||||
if (bufend - bufptr > 2) {
|
||||
*bufptr++ = '_';
|
||||
*bufptr++ = '_';
|
||||
}
|
||||
|
||||
for (i = 0; i<1023; i++)
|
||||
if ((sig[i] = signature[i]) == ')')
|
||||
break;
|
||||
|
||||
sig[i] = 0;
|
||||
bufptr += NativeMethodDispatcher::mangleUTFString(sig, bufptr,
|
||||
bufend - bufptr,
|
||||
mangleUTFJNI);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Загрузка…
Ссылка в новой задаче