adding new files - not part of build
git-svn-id: svn://10.0.0.236/trunk@64331 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
f099924118
commit
25d93ece07
44
mozilla/js/src/xpconnect/tools/idl/makefile.win
Normal file
44
mozilla/js/src/xpconnect/tools/idl/makefile.win
Normal file
@ -0,0 +1,44 @@
|
||||
#!gmake
|
||||
#
|
||||
# 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 oqr
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Mozilla Communicator client code, released
|
||||
# March 31, 1998.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1999 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the NPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the NPL or the GPL.
|
||||
|
||||
DEPTH=..\..\..\..\..
|
||||
|
||||
MODULE=xpctools
|
||||
|
||||
XPIDLSRCS = \
|
||||
.\nsIXPCToolsCompiler.idl \
|
||||
.\nsIXPCToolsProfiler.idl \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
55
mozilla/js/src/xpconnect/tools/idl/nsIXPCToolsCompiler.idl
Normal file
55
mozilla/js/src/xpconnect/tools/idl/nsIXPCToolsCompiler.idl
Normal file
@ -0,0 +1,55 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code, released
|
||||
* March 31, 1998.
|
||||
*
|
||||
* 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):
|
||||
* John Bandhauer <jband@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
|
||||
/* Interface for JS code testing tool which does compile-time checking. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "nsILocalFile.idl"
|
||||
|
||||
[scriptable, uuid(71151570-e56f-11d3-8f65-0010a4e73d9a)]
|
||||
interface nsIXPCToolsCompiler : nsISupports
|
||||
{
|
||||
/**
|
||||
* XXX temporary hack because there does not seem to be another scriptable
|
||||
* way to get this info.
|
||||
*/
|
||||
readonly attribute nsILocalFile binDir;
|
||||
|
||||
void CompileFile(in nsILocalFile aFile, in PRBool strict);
|
||||
};
|
||||
|
||||
%{ C++
|
||||
#define XPCTOOLS_COMPILER_PROGID "xpctools.compiler.1"
|
||||
%}
|
||||
52
mozilla/js/src/xpconnect/tools/idl/nsIXPCToolsProfiler.idl
Normal file
52
mozilla/js/src/xpconnect/tools/idl/nsIXPCToolsProfiler.idl
Normal file
@ -0,0 +1,52 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code, released
|
||||
* March 31, 1998.
|
||||
*
|
||||
* 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):
|
||||
* John Bandhauer <jband@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
|
||||
/* Interface for JS code testing tool which does code coverage and profiling. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "nsILocalFile.idl"
|
||||
|
||||
[scriptable, uuid(09ef19b0-e97a-11d3-8f69-0010a4e73d9a)]
|
||||
interface nsIXPCToolsProfiler : nsISupports
|
||||
{
|
||||
void start();
|
||||
void stop();
|
||||
void clear();
|
||||
void writeResults(in nsILocalFile aFile);
|
||||
};
|
||||
|
||||
%{ C++
|
||||
#define XPCTOOLS_PROFILER_PROGID "xpctools.profiler.1"
|
||||
%}
|
||||
28
mozilla/js/src/xpconnect/tools/js/CompileJSFiles.js
Normal file
28
mozilla/js/src/xpconnect/tools/js/CompileJSFiles.js
Normal file
@ -0,0 +1,28 @@
|
||||
const nsIFile = Components.interfaces.nsIFile;
|
||||
var Compiler = new Components.Constructor("xpctools.compiler.1",
|
||||
"nsIXPCToolsCompiler");
|
||||
var c = new Compiler;
|
||||
|
||||
dump("\n");
|
||||
dump("Compiling all .js files under "+c.binDir.path+"\n");
|
||||
dump("Will report any compile-time errors...\n\n");
|
||||
dump( "compiled "+CompileJSFilesInDir(c.binDir)+" files\n\n");
|
||||
|
||||
function CompileJSFilesInDir(dir) {
|
||||
var count = 0;
|
||||
if(!dir.isDirectory())
|
||||
return;
|
||||
var list = dir.directoryEntries;
|
||||
while(list.HasMoreElements()) {
|
||||
file = list.GetNext().QueryInterface(nsIFile);
|
||||
if(file.isDirectory())
|
||||
count += CompileJSFilesInDir(file);
|
||||
else if(file.leafName.match(/\.js$/i)) {
|
||||
// dump("compiling... "+file.path+"\n");
|
||||
c.CompileFile(file, false);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
18
mozilla/js/src/xpconnect/tools/js/ListJSFiles.js
Normal file
18
mozilla/js/src/xpconnect/tools/js/ListJSFiles.js
Normal file
@ -0,0 +1,18 @@
|
||||
const nsIFile = Components.interfaces.nsIFile;
|
||||
var Compiler = new Components.Constructor("xpctools.compiler.1","nsIXPCToolsCompiler");
|
||||
var c = new Compiler;
|
||||
ListJSFilesInDir(c.binDir);
|
||||
|
||||
function ListJSFilesInDir(dir) {
|
||||
if(!dir.isDirectory())
|
||||
return;
|
||||
var list = dir.directoryEntries;
|
||||
while(list.HasMoreElements()) {
|
||||
file = list.GetNext().QueryInterface(nsIFile);
|
||||
if(file.isDirectory())
|
||||
ListJSFilesInDir(file);
|
||||
else if(file.leafName.match(/\.js$/i))
|
||||
dump(file.path+"\n");
|
||||
}
|
||||
}
|
||||
|
||||
38
mozilla/js/src/xpconnect/tools/makefile.win
Normal file
38
mozilla/js/src/xpconnect/tools/makefile.win
Normal file
@ -0,0 +1,38 @@
|
||||
#
|
||||
# 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 oqr
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Mozilla Communicator client code, released
|
||||
# March 31, 1998.
|
||||
#
|
||||
# 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):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the NPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the NPL or the GPL.
|
||||
|
||||
DEPTH=..\..\..\..
|
||||
|
||||
|
||||
DIRS=idl src
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
70
mozilla/js/src/xpconnect/tools/src/makefile.win
Normal file
70
mozilla/js/src/xpconnect/tools/src/makefile.win
Normal file
@ -0,0 +1,70 @@
|
||||
#!nmake
|
||||
#
|
||||
# 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 oqr
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Mozilla Communicator client code, released
|
||||
# March 31, 1998.
|
||||
#
|
||||
# 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):
|
||||
# John Bandhauer <jband@netscape.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the NPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the NPL or the GPL.
|
||||
|
||||
DEPTH=..\..\..\..\..
|
||||
|
||||
MAKE_OBJ_TYPE = DLL
|
||||
DLLNAME = xpctools
|
||||
DLL =.\$(OBJDIR)\$(DLLNAME).dll
|
||||
|
||||
MODULE=xpctools
|
||||
|
||||
DEFINES=-DWIN32_LEAN_AND_MEAN
|
||||
|
||||
OBJS= \
|
||||
.\$(OBJDIR)\nsXPCToolsCompiler.obj \
|
||||
.\$(OBJDIR)\nsXPCToolsProfiler.obj \
|
||||
.\$(OBJDIR)\nsXPCToolsModule.obj \
|
||||
$(NULL)
|
||||
|
||||
LCFLAGS = \
|
||||
$(LCFLAGS) \
|
||||
$(DEFINES) \
|
||||
$(NULL)
|
||||
|
||||
LLIBS= $(LIBNSPR) \
|
||||
$(DIST)\lib\js$(MOZ_BITS)$(VERSION_NUMBER).lib \
|
||||
$(DIST)\lib\xpcom.lib \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
install:: $(DLL)
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).dll $(DIST)\bin\components
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).lib $(DIST)\lib
|
||||
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\lib\$(DLLNAME).lib
|
||||
rm -f $(DIST)\bin\components\$(DLLNAME).dll
|
||||
160
mozilla/js/src/xpconnect/tools/src/nsXPCToolsCompiler.cpp
Normal file
160
mozilla/js/src/xpconnect/tools/src/nsXPCToolsCompiler.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code, released
|
||||
* March 31, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* John Bandhauer <jband@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
|
||||
/* Implements nsXPCToolsCompiler. */
|
||||
|
||||
#include "xpctools_private.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsXPCToolsCompiler, nsIXPCToolsCompiler)
|
||||
|
||||
nsXPCToolsCompiler::nsXPCToolsCompiler()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
nsXPCToolsCompiler::~nsXPCToolsCompiler()
|
||||
{
|
||||
}
|
||||
|
||||
/* readonly attribute nsILocalFile binDir; */
|
||||
NS_IMETHODIMP nsXPCToolsCompiler::GetBinDir(nsILocalFile * *aBinDir)
|
||||
{
|
||||
*aBinDir = nsnull;
|
||||
|
||||
nsCOMPtr<nsILocalFile> dir = do_CreateInstance(NS_LOCAL_FILE_PROGID);
|
||||
if(!dir)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult rv = dir->InitWithPath(
|
||||
nsSpecialSystemDirectory(
|
||||
nsSpecialSystemDirectory::OS_CurrentProcessDirectory));
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
NS_ADDREF(*aBinDir = dir);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static void ErrorReporter(JSContext *cx, const char *message,
|
||||
JSErrorReport *report)
|
||||
{
|
||||
printf("compile error!\n");
|
||||
}
|
||||
|
||||
static JSClass global_class = {
|
||||
"nsXPCToolsCompiler::global", 0,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
};
|
||||
|
||||
/* void CompileFile (in nsILocalFile aFile, in PRBool strict); */
|
||||
NS_IMETHODIMP nsXPCToolsCompiler::CompileFile(nsILocalFile *aFile, PRBool strict)
|
||||
{
|
||||
// use the xpccallcontext stuff to get the current JSContext
|
||||
|
||||
// get the xpconnect service
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIXPConnect, xpc, nsIXPConnect::GetCID(), &rv);
|
||||
if(NS_FAILED(rv))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// get the xpconnect native call context
|
||||
nsCOMPtr<nsIXPCNativeCallContext> callContext;
|
||||
xpc->GetCurrentNativeCallContext(getter_AddRefs(callContext));
|
||||
if(!callContext)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// verify that we are being called from JS (i.e. the current call is
|
||||
// to this object - though we don't verify that it is to this exact method)
|
||||
nsCOMPtr<nsISupports> callee;
|
||||
callContext->GetCallee(getter_AddRefs(callee));
|
||||
if(!callee || callee.get() != (nsISupports*)this)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Get JSContext of current call
|
||||
JSContext* cx;
|
||||
rv = callContext->GetJSContext(&cx);
|
||||
if(NS_FAILED(rv) || !cx)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
FILE* handle;
|
||||
if(NS_FAILED(aFile->OpenANSIFileDesc("r", &handle)))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
JSObject* glob = JS_NewObject(cx, &global_class, NULL, NULL);
|
||||
if (!glob)
|
||||
return NS_ERROR_FAILURE;
|
||||
if (!JS_InitStandardClasses(cx, glob))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
char * path = nsnull;
|
||||
if(NS_FAILED(aFile->GetPath(&path)))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
uint32 oldoptions = JS_GetOptions(cx);
|
||||
JS_SetOptions(cx, JSOPTION_WERROR | (strict ? JSOPTION_STRICT : 0));
|
||||
JSErrorReporter older = JS_SetErrorReporter(cx, ErrorReporter);
|
||||
JSExceptionState *es =JS_SaveExceptionState(cx);
|
||||
|
||||
if(!JS_CompileFileHandle(cx, glob, path, handle))
|
||||
{
|
||||
jsval v;
|
||||
JSErrorReport* report;
|
||||
if(JS_GetPendingException(cx, &v) &&
|
||||
nsnull != (report = JS_ErrorFromException(cx, v)))
|
||||
{
|
||||
JSString* str;
|
||||
const char* msg = "Error";
|
||||
str = JS_ValueToString(cx, v);
|
||||
if(str)
|
||||
msg = JS_GetStringBytes(str);
|
||||
printf("%s [%s,%d]\n\n",
|
||||
msg,
|
||||
report->filename,
|
||||
(int)report->lineno);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("no script and no error report!\n");
|
||||
}
|
||||
|
||||
}
|
||||
JS_RestoreExceptionState(cx, es);
|
||||
JS_SetErrorReporter(cx, older);
|
||||
JS_SetOptions(cx, oldoptions);
|
||||
|
||||
if(path)
|
||||
nsAllocator::Free(path);
|
||||
return NS_OK;
|
||||
}
|
||||
60
mozilla/js/src/xpconnect/tools/src/nsXPCToolsModule.cpp
Normal file
60
mozilla/js/src/xpconnect/tools/src/nsXPCToolsModule.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code, released
|
||||
* March 31, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* John Bandhauer <jband@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
|
||||
/* Module code for XPCTools. */
|
||||
|
||||
#include "xpctools_private.h"
|
||||
|
||||
// Module implementation for the xpctools library
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPCToolsCompiler)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPCToolsProfiler)
|
||||
|
||||
// {331148C0-E599-11d3-8F65-0010A4E73D9A}
|
||||
#define COMPILER_CID \
|
||||
{ 0x331148c0, 0xe599, 0x11d3, \
|
||||
{ 0x8f, 0x65, 0x0, 0x10, 0xa4, 0xe7, 0x3d, 0x9a } }
|
||||
|
||||
// {7F5D12E0-E97B-11d3-8F69-0010A4E73D9A}
|
||||
#define PROFILER_CID \
|
||||
{ 0x7f5d12e0, 0xe97b, 0x11d3, \
|
||||
{ 0x8f, 0x69, 0x0, 0x10, 0xa4, 0xe7, 0x3d, 0x9a } }
|
||||
|
||||
static nsModuleComponentInfo components[] = {
|
||||
{nsnull, COMPILER_CID, XPCTOOLS_COMPILER_PROGID, nsXPCToolsCompilerConstructor},
|
||||
{nsnull, PROFILER_CID, XPCTOOLS_PROFILER_PROGID, nsXPCToolsProfilerConstructor}
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE("xpctools", components)
|
||||
368
mozilla/js/src/xpconnect/tools/src/nsXPCToolsProfiler.cpp
Normal file
368
mozilla/js/src/xpconnect/tools/src/nsXPCToolsProfiler.cpp
Normal file
@ -0,0 +1,368 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code, released
|
||||
* March 31, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* John Bandhauer <jband@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
|
||||
/* Implements nsXPCToolsProfiler. */
|
||||
|
||||
#include "xpctools_private.h"
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
class FunctionKey : public nsHashKey {
|
||||
protected:
|
||||
uintN mLineno;
|
||||
uintN mExtent;
|
||||
|
||||
public:
|
||||
FunctionKey(uintN aLineno,
|
||||
uintN aExtent)
|
||||
: mLineno(aLineno), mExtent(aExtent) {}
|
||||
~FunctionKey(void) {}
|
||||
|
||||
PRUint32 HashValue(void) const
|
||||
{return (17*mLineno) + (7*mExtent);}
|
||||
PRBool Equals(const nsHashKey* aKey) const
|
||||
{const FunctionKey* o = (const FunctionKey*) aKey;
|
||||
return (mLineno == o->mLineno) && (mExtent == o->mExtent);}
|
||||
nsHashKey* Clone() const
|
||||
{return new FunctionKey(mLineno, mExtent);}
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
ProfilerFile::ProfilerFile(const char* filename)
|
||||
: mName(filename ? nsCRT::strdup(filename) : nsnull),
|
||||
mFunctionTable(new nsHashtable(16, PR_FALSE))
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
ProfilerFile::~ProfilerFile()
|
||||
{
|
||||
if(mName)
|
||||
nsCRT::free(mName);
|
||||
if(mFunctionTable)
|
||||
delete mFunctionTable;
|
||||
}
|
||||
|
||||
ProfilerFunction*
|
||||
ProfilerFile::FindOrAddFunction(const char* aName,
|
||||
uintN aBaseLineNumber,
|
||||
uintN aLineExtent)
|
||||
{
|
||||
if(!mFunctionTable)
|
||||
return nsnull;
|
||||
FunctionKey key(aBaseLineNumber, aLineExtent);
|
||||
ProfilerFunction* fun = (ProfilerFunction*) mFunctionTable->Get(&key);
|
||||
if(!fun)
|
||||
{
|
||||
fun = new ProfilerFunction(aName, aBaseLineNumber, aLineExtent, this);
|
||||
if(fun)
|
||||
mFunctionTable->Put(&key, fun);
|
||||
}
|
||||
return fun;
|
||||
}
|
||||
|
||||
void ProfilerFile::EnumerateFunctions(nsHashtableEnumFunc aEnumFunc, void* closure)
|
||||
{
|
||||
if(mFunctionTable)
|
||||
mFunctionTable->Enumerate(aEnumFunc, closure);
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
ProfilerFunction::ProfilerFunction(const char* name,
|
||||
uintN lineno, uintn extent,
|
||||
ProfilerFile* file)
|
||||
: mName(name ? nsCRT::strdup(name) : nsnull),
|
||||
mBaseLineNumber(lineno),
|
||||
mLineExtent(extent),
|
||||
mFile(file),
|
||||
mCallCount(0),
|
||||
mCompileCount(0)
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
ProfilerFunction::~ProfilerFunction()
|
||||
{
|
||||
if(mName)
|
||||
nsCRT::free(mName);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsXPCToolsProfiler, nsIXPCToolsProfiler)
|
||||
|
||||
nsXPCToolsProfiler::nsXPCToolsProfiler()
|
||||
: mLock(PR_NewLock()),
|
||||
mRuntime(nsnull),
|
||||
mFileTable(new nsHashtable(128, PR_FALSE)),
|
||||
mScriptTable(new nsHashtable(256, PR_FALSE))
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
InitializeRuntime();
|
||||
}
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(PRBool)
|
||||
xpctools_ProfilerFunctionDeleter(nsHashKey *aKey, void *aData, void* closure)
|
||||
{
|
||||
delete (ProfilerFunction*) aData;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(PRBool)
|
||||
xpctools_ProfilerFileDeleter(nsHashKey *aKey, void *aData, void* closure)
|
||||
{
|
||||
ProfilerFile* file = (ProfilerFile*) aData;
|
||||
file->EnumerateFunctions(xpctools_ProfilerFunctionDeleter, closure);
|
||||
delete file;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsXPCToolsProfiler::~nsXPCToolsProfiler()
|
||||
{
|
||||
Stop();
|
||||
if(mLock)
|
||||
PR_DestroyLock(mLock);
|
||||
if(mFileTable)
|
||||
{
|
||||
mFileTable->Reset(xpctools_ProfilerFileDeleter, this);
|
||||
delete mFileTable;
|
||||
}
|
||||
if(mScriptTable)
|
||||
{
|
||||
// elements not owned - don't purge them
|
||||
delete mScriptTable;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
// the hooks...
|
||||
|
||||
/* called just after script creation */
|
||||
JS_STATIC_DLL_CALLBACK(void)
|
||||
xpctools_JSNewScriptHook(JSContext *cx,
|
||||
const char *filename, /* URL of script */
|
||||
uintN lineno, /* line script starts */
|
||||
JSScript *script,
|
||||
JSFunction *fun,
|
||||
void *callerdata)
|
||||
{
|
||||
if(!script)
|
||||
return;
|
||||
if(!filename)
|
||||
filename = "<<<!!! has no name so may represent many different pages !!!>>>";
|
||||
nsXPCToolsProfiler* self = (nsXPCToolsProfiler*) callerdata;
|
||||
nsAutoLock lock(self->mLock);
|
||||
|
||||
if(self->mFileTable)
|
||||
{
|
||||
nsStringKey key(filename);
|
||||
ProfilerFile* file = (ProfilerFile*) self->mFileTable->Get(&key);
|
||||
if(!file)
|
||||
{
|
||||
file = new ProfilerFile(filename);
|
||||
self->mFileTable->Put(&key, file);
|
||||
}
|
||||
if(file)
|
||||
{
|
||||
ProfilerFunction* function =
|
||||
file->FindOrAddFunction(fun ? JS_GetFunctionName(fun) : nsnull,
|
||||
JS_GetScriptBaseLineNumber(cx, script),
|
||||
JS_GetScriptLineExtent(cx, script));
|
||||
if(function)
|
||||
{
|
||||
function->IncrementCompileCount();
|
||||
if(self->mScriptTable)
|
||||
{
|
||||
nsVoidKey scriptkey(script);
|
||||
self->mScriptTable->Put(&scriptkey, function);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* called just before script destruction */
|
||||
JS_STATIC_DLL_CALLBACK(void)
|
||||
xpctools_JSDestroyScriptHook(JSContext *cx,
|
||||
JSScript *script,
|
||||
void *callerdata)
|
||||
{
|
||||
if(!script)
|
||||
return;
|
||||
nsXPCToolsProfiler* self = (nsXPCToolsProfiler*) callerdata;
|
||||
nsAutoLock lock(self->mLock);
|
||||
if(self->mScriptTable)
|
||||
{
|
||||
nsVoidKey scriptkey(script);
|
||||
self->mScriptTable->Remove(&scriptkey);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* called on entry and return of functions and top level scripts */
|
||||
JS_STATIC_DLL_CALLBACK(void*)
|
||||
xpctools_InterpreterHook(JSContext *cx, JSStackFrame *fp, JSBool before,
|
||||
JSBool *ok, void *closure)
|
||||
{
|
||||
// ignore returns
|
||||
NS_ASSERTION(before, "engine should not do this cuz we return nsnull!");
|
||||
NS_ASSERTION(fp, "bad frame pointer!");
|
||||
|
||||
JSScript* script = fp->script;
|
||||
if(script)
|
||||
{
|
||||
nsXPCToolsProfiler* self = (nsXPCToolsProfiler*) closure;
|
||||
nsAutoLock lock(self->mLock);
|
||||
if(self->mScriptTable)
|
||||
{
|
||||
nsVoidKey scriptkey(script);
|
||||
ProfilerFunction* fun =
|
||||
(ProfilerFunction*) self->mScriptTable->Get(&scriptkey);
|
||||
if(fun)
|
||||
fun->IncrementCallCount();
|
||||
}
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
// interface methods
|
||||
|
||||
/* void start (); */
|
||||
NS_IMETHODIMP nsXPCToolsProfiler::Start()
|
||||
{
|
||||
nsAutoLock lock(mLock);
|
||||
if(!VerifyRuntime())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
JS_SetNewScriptHook(mRuntime, xpctools_JSNewScriptHook, this);
|
||||
JS_SetDestroyScriptHook(mRuntime, xpctools_JSDestroyScriptHook, this);
|
||||
JS_SetExecuteHook(mRuntime, xpctools_InterpreterHook, this);
|
||||
JS_SetCallHook(mRuntime, xpctools_InterpreterHook, this);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void stop (); */
|
||||
NS_IMETHODIMP nsXPCToolsProfiler::Stop()
|
||||
{
|
||||
nsAutoLock lock(mLock);
|
||||
if(!VerifyRuntime())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
JS_SetNewScriptHook(mRuntime, nsnull, nsnull);
|
||||
JS_SetDestroyScriptHook(mRuntime, nsnull, nsnull);
|
||||
JS_SetExecuteHook(mRuntime, nsnull, this);
|
||||
JS_SetCallHook(mRuntime, nsnull, this);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void clear (); */
|
||||
NS_IMETHODIMP nsXPCToolsProfiler::Clear()
|
||||
{
|
||||
// XXX implement me!
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(PRBool)
|
||||
xpctools_FuncionNamePrinter(nsHashKey *aKey, void *aData, void* closure)
|
||||
{
|
||||
ProfilerFunction* fun = (ProfilerFunction*) aData;
|
||||
FILE* out = (FILE*) closure;
|
||||
const char* name = fun->GetName();
|
||||
if(!name)
|
||||
name = "<top level>";
|
||||
fprintf(out,
|
||||
" [%lu,%lu] %s() {%d-%d}\n",
|
||||
(unsigned long) fun->GetCompileCount(),
|
||||
(unsigned long) fun->GetCallCount(),
|
||||
name,
|
||||
(int) fun->GetBaseLineNumber(),
|
||||
(int)(fun->GetBaseLineNumber()+fun->GetLineExtent()-1));
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(PRBool)
|
||||
xpctools_FilenamePrinter(nsHashKey *aKey, void *aData, void* closure)
|
||||
{
|
||||
ProfilerFile* file = (ProfilerFile*) aData;
|
||||
FILE* out = (FILE*) closure;
|
||||
fprintf(out, "%s\n", file->GetName());
|
||||
file->EnumerateFunctions(xpctools_FuncionNamePrinter, closure);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
/* void writeResults (in nsILocalFile aFile); */
|
||||
NS_IMETHODIMP nsXPCToolsProfiler::WriteResults(nsILocalFile *aFile)
|
||||
{
|
||||
nsAutoLock lock(mLock);
|
||||
if(!aFile)
|
||||
return NS_ERROR_FAILURE;
|
||||
FILE* out;
|
||||
if(NS_FAILED(aFile->OpenANSIFileDesc("w", &out)) || ! out)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if(mFileTable)
|
||||
mFileTable->Enumerate(xpctools_FilenamePrinter, out);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
// additional utility methods
|
||||
|
||||
JSBool
|
||||
nsXPCToolsProfiler::VerifyRuntime()
|
||||
{
|
||||
JSRuntime* rt;
|
||||
nsCOMPtr<nsIJSRuntimeService> rts = do_GetService("nsJSRuntimeService");
|
||||
return rts && NS_SUCCEEDED(rts->GetRuntime(&rt)) && rt && rt == mRuntime;
|
||||
}
|
||||
|
||||
JSBool
|
||||
nsXPCToolsProfiler::InitializeRuntime()
|
||||
{
|
||||
NS_ASSERTION(!mRuntime, "can't init runtime twice");
|
||||
JSRuntime* rt;
|
||||
nsCOMPtr<nsIJSRuntimeService> rts = do_GetService("nsJSRuntimeService");
|
||||
if(rts && NS_SUCCEEDED(rts->GetRuntime(&rt)) && rt)
|
||||
mRuntime = rt;
|
||||
return mRuntime != nsnull;
|
||||
}
|
||||
157
mozilla/js/src/xpconnect/tools/src/xpctools_private.h
Normal file
157
mozilla/js/src/xpconnect/tools/src/xpctools_private.h
Normal file
@ -0,0 +1,157 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code, released
|
||||
* March 31, 1998.
|
||||
*
|
||||
* 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):
|
||||
* John Bandhauer <jband@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
|
||||
/* All the XPCTools private declarations - only include locally. */
|
||||
|
||||
#ifndef xpctoolsprivate_h___
|
||||
#define xpctoolsprivate_h___
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "nscore.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsIAllocator.h"
|
||||
#include "nsIXPConnect.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIModule.h"
|
||||
#include "jsapi.h"
|
||||
#include "jshash.h"
|
||||
#include "jsprf.h"
|
||||
#include "jsinterp.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsdbgapi.h"
|
||||
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsSpecialSystemDirectory.h" /* for binDir hack */
|
||||
|
||||
#include "nsIJSRuntimeService.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsAutoLock.h"
|
||||
|
||||
#include "nsIXPCToolsCompiler.h"
|
||||
#include "nsIXPCToolsProfiler.h"
|
||||
|
||||
class nsXPCToolsCompiler : public nsIXPCToolsCompiler
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIXPCTOOLSCOMPILER
|
||||
|
||||
nsXPCToolsCompiler();
|
||||
virtual ~nsXPCToolsCompiler();
|
||||
// XXX add additional members
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
class ProfilerFunction;
|
||||
|
||||
class ProfilerFile
|
||||
{
|
||||
public:
|
||||
ProfilerFile(const char* filename);
|
||||
~ProfilerFile();
|
||||
|
||||
|
||||
ProfilerFunction* FindOrAddFunction(const char* aName,
|
||||
uintN aBaseLineNumber,
|
||||
uintN aLineExtent);
|
||||
void EnumerateFunctions(nsHashtableEnumFunc aEnumFunc, void* closure);
|
||||
const char* GetName() const {return mName;}
|
||||
|
||||
ProfilerFile(); // not implemented
|
||||
private:
|
||||
char* mName;
|
||||
nsHashtable* mFunctionTable;
|
||||
};
|
||||
|
||||
class ProfilerFunction
|
||||
{
|
||||
public:
|
||||
ProfilerFunction(const char* name,
|
||||
uintN lineno, uintn extent,
|
||||
ProfilerFile* file);
|
||||
~ProfilerFunction();
|
||||
|
||||
const char* GetName() const {return mName;}
|
||||
ProfilerFile* GetFile() const {return mFile;}
|
||||
uintN GetBaseLineNumber() const {return mBaseLineNumber;}
|
||||
uintN GetLineExtent() const {return mLineExtent;}
|
||||
void IncrementCallCount() {++mCallCount;}
|
||||
PRUint32 GetCallCount() {return mCallCount;}
|
||||
void IncrementCompileCount() {++mCompileCount;}
|
||||
PRUint32 GetCompileCount() {return mCompileCount;}
|
||||
|
||||
ProfilerFunction(); // not implemented
|
||||
|
||||
private:
|
||||
char* mName;
|
||||
uintN mBaseLineNumber;
|
||||
uintN mLineExtent;
|
||||
ProfilerFile* mFile;
|
||||
PRUint32 mCallCount;
|
||||
PRUint32 mCompileCount;
|
||||
};
|
||||
|
||||
|
||||
class nsXPCToolsProfiler : public nsIXPCToolsProfiler
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIXPCTOOLSPROFILER
|
||||
|
||||
nsXPCToolsProfiler();
|
||||
virtual ~nsXPCToolsProfiler();
|
||||
|
||||
private:
|
||||
JSBool InitializeRuntime();
|
||||
JSBool VerifyRuntime();
|
||||
|
||||
/* Taking the unusual step of making all data public to simplify
|
||||
* the implemetation of the "C" static debugger hooks.
|
||||
*/
|
||||
|
||||
public:
|
||||
PRLock* mLock;
|
||||
JSRuntime* mRuntime;
|
||||
nsHashtable* mFileTable;
|
||||
nsHashtable* mScriptTable;
|
||||
};
|
||||
|
||||
|
||||
#endif /* xpctoolsprivate_h___ */
|
||||
Loading…
x
Reference in New Issue
Block a user