mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
not part of mozilla build - merging from SpiderMonkey140_BRANCH
This commit is contained in:
parent
58a2b541e3
commit
9cf5029cc2
18
js/jsd/README
Normal file
18
js/jsd/README
Normal file
@ -0,0 +1,18 @@
|
||||
/* jband - 10/26/98 - */
|
||||
|
||||
js/jsd contains code for debugging support for the C-based JavaScript engine
|
||||
in js/src.
|
||||
|
||||
Currently the makefiles are for Win32 only (using MS nmake.exe from MSDEV 4.2).
|
||||
jsd.mak will build a standalone dll. jsdshell.mak will build the dll and also
|
||||
a version of the js/src/js.c shell which will launch a Java VM and run the
|
||||
JavaSript Debugger (built in js/jsdj). This version assumes that you have a
|
||||
JRE compatible JVM installed. Only Windows is supported for this Java-based
|
||||
debugging.
|
||||
|
||||
Though only Windows makefiles are supplied, the basic code in js/jsd should
|
||||
compile for other platforms -- it is a newer version of code that builds and
|
||||
ships with Communicator 4.x on many platforms.
|
||||
|
||||
js/jsd/jsdb is a console debugger using only native code (see README in that
|
||||
directory)
|
35
js/jsd/java/jni_stubs.c
Normal file
35
js/jsd/java/jni_stubs.c
Normal file
@ -0,0 +1,35 @@
|
||||
/* -*- 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.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This supplies non-functional stubs for a couple of JNI functions we need
|
||||
* in order to link LiveConnect
|
||||
*/
|
||||
|
||||
#include "jni.h"
|
||||
|
||||
jint JNICALL JNI_GetDefaultJavaVMInitArgs(void * ignored)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
jint JNICALL JNI_CreateJavaVM(JavaVM ** vm, JNIEnv ** env, void * ignored)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
33
js/jsd/java/jniheadr.mak
Normal file
33
js/jsd/java/jniheadr.mak
Normal file
@ -0,0 +1,33 @@
|
||||
|
||||
JSDJNI = .
|
||||
#CLASS_DIR_BASE = $(JSDJNI)\..\..\..\jsdj\dist\classes
|
||||
# until jsdj moves to mozilla...
|
||||
CLASS_DIR_BASE = $(JSDJNI)\..\..\..\..\..\ns\js\jsdj\dist\classes
|
||||
GEN = $(JSDJNI)\_jni
|
||||
HEADER_FILE = $(GEN)\jsdjnih.h
|
||||
|
||||
PACKAGE_SLASH = netscape\jsdebug
|
||||
PACKAGE_DOT = netscape.jsdebug
|
||||
|
||||
STD_CLASSPATH = -classpath $(CLASS_DIR_BASE);$(CLASSPATH)
|
||||
|
||||
CLASSES_WITH_NATIVES = \
|
||||
$(PACKAGE_DOT).DebugController \
|
||||
$(PACKAGE_DOT).JSPC \
|
||||
$(PACKAGE_DOT).JSSourceTextProvider \
|
||||
$(PACKAGE_DOT).JSStackFrameInfo \
|
||||
$(PACKAGE_DOT).JSThreadState \
|
||||
$(PACKAGE_DOT).Script \
|
||||
$(PACKAGE_DOT).SourceTextProvider \
|
||||
$(PACKAGE_DOT).ThreadStateBase \
|
||||
$(PACKAGE_DOT).Value
|
||||
|
||||
all: $(GEN)
|
||||
@echo generating JNI headers
|
||||
@javah -jni -o "$(HEADER_FILE)" $(STD_CLASSPATH) $(CLASSES_WITH_NATIVES)
|
||||
|
||||
$(GEN) :
|
||||
@mkdir $(GEN)
|
||||
|
||||
clean:
|
||||
@if exist $(HEADER_FILE) @del $(HEADER_FILE) > NUL
|
134
js/jsd/java/jre/jre.c
Normal file
134
js/jsd/java/jre/jre.c
Normal file
@ -0,0 +1,134 @@
|
||||
/* -*- 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.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Sun Microsystems, Inc.
|
||||
* Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
|
||||
* modify and redistribute this software in source and binary code form,
|
||||
* provided that i) this copyright notice and license appear on all copies of
|
||||
* the software; and ii) Licensee does not utilize the software in a manner
|
||||
* which is disparaging to Sun.
|
||||
*
|
||||
* This software is provided "AS IS," without a warranty of any kind. ALL
|
||||
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
|
||||
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
|
||||
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
|
||||
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
|
||||
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
|
||||
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
|
||||
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
|
||||
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
|
||||
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*
|
||||
* This software is not designed or intended for use in on-line control of
|
||||
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
|
||||
* the design, construction, operation or maintenance of any nuclear
|
||||
* facility. Licensee represents and warrants that it will not use or
|
||||
* redistribute the Software for such purposes.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portable JRE support functions - pared this down to minimal set I need
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <jni.h>
|
||||
#include "jre.h"
|
||||
|
||||
/*
|
||||
* Exits the runtime with the specified error message.
|
||||
*/
|
||||
void
|
||||
JRE_FatalError(JNIEnv *env, const char *msg)
|
||||
{
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
(*env)->ExceptionDescribe(env);
|
||||
}
|
||||
(*env)->FatalError(env, msg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses a runtime version string. Returns 0 if the successful, otherwise
|
||||
* returns -1 if the format of the version string was invalid.
|
||||
*/
|
||||
jint
|
||||
JRE_ParseVersion(const char *ver, char **majorp, char **minorp, char **microp)
|
||||
{
|
||||
int n1 = 0, n2 = 0, n3 = 0;
|
||||
|
||||
sscanf(ver, "%*[0-9]%n.%*[0-9]%n.%*[0-9a-zA-Z]%n", &n1, &n2, &n3);
|
||||
if (n1 == 0 || n2 == 0) {
|
||||
return -1;
|
||||
}
|
||||
if (n3 != 0) {
|
||||
if (n3 != (int)strlen(ver)) {
|
||||
return -1;
|
||||
}
|
||||
} else if (n2 != (int)strlen(ver)) {
|
||||
return -1;
|
||||
}
|
||||
*majorp = JRE_Malloc(n1 + 1);
|
||||
strncpy(*majorp, ver, n1);
|
||||
(*majorp)[n1] = 0;
|
||||
*minorp = JRE_Malloc(n2 - n1);
|
||||
strncpy(*minorp, ver + n1 + 1, n2 - n1 - 1);
|
||||
(*minorp)[n2 - n1 - 1] = 0;
|
||||
if (n3 != 0) {
|
||||
*microp = JRE_Malloc(n3 - n2);
|
||||
strncpy(*microp, ver + n2 + 1, n3 - n2 - 1);
|
||||
(*microp)[n3 - n2 - 1] = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates a version number string from the specified major, minor, and
|
||||
* micro version numbers.
|
||||
*/
|
||||
char *
|
||||
JRE_MakeVersion(const char *major, const char *minor, const char *micro)
|
||||
{
|
||||
char *ver = 0;
|
||||
|
||||
if (major != 0 && minor != 0) {
|
||||
int len = strlen(major) + strlen(minor);
|
||||
if (micro != 0) {
|
||||
ver = JRE_Malloc(len + strlen(micro) + 3);
|
||||
sprintf(ver, "%s.%s.%s", major, minor, micro);
|
||||
} else {
|
||||
ver = JRE_Malloc(len + 2);
|
||||
sprintf(ver, "%s.%s", major, minor);
|
||||
}
|
||||
}
|
||||
return ver;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate memory or die.
|
||||
*/
|
||||
void *
|
||||
JRE_Malloc(size_t size)
|
||||
{
|
||||
void *p = malloc(size);
|
||||
if (p == 0) {
|
||||
perror("malloc");
|
||||
exit(1);
|
||||
}
|
||||
return p;
|
||||
}
|
85
js/jsd/java/jre/jre.h
Normal file
85
js/jsd/java/jre/jre.h
Normal file
@ -0,0 +1,85 @@
|
||||
/* -*- 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.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Sun Microsystems, Inc.
|
||||
* Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
|
||||
* modify and redistribute this software in source and binary code form,
|
||||
* provided that i) this copyright notice and license appear on all copies of
|
||||
* the software; and ii) Licensee does not utilize the software in a manner
|
||||
* which is disparaging to Sun.
|
||||
*
|
||||
* This software is provided "AS IS," without a warranty of any kind. ALL
|
||||
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
|
||||
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
|
||||
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
|
||||
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
|
||||
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
|
||||
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
|
||||
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
|
||||
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
|
||||
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*
|
||||
* This software is not designed or intended for use in on-line control of
|
||||
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
|
||||
* the design, construction, operation or maintenance of any nuclear
|
||||
* facility. Licensee represents and warrants that it will not use or
|
||||
* redistribute the Software for such purposes.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portable JRE support functions - pared this down to minimal set I need
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <jni.h>
|
||||
|
||||
#include "jre_md.h"
|
||||
|
||||
/*
|
||||
* Java runtime settings.
|
||||
*/
|
||||
typedef struct JRESettings {
|
||||
char *javaHome; /* Java home directory */
|
||||
char *runtimeLib; /* Runtime shared library or DLL */
|
||||
char *classPath; /* Default class path */
|
||||
char *compiler; /* Just-in-time (JIT) compiler */
|
||||
char *majorVersion; /* Major version of runtime */
|
||||
char *minorVersion; /* Minor version of runtime */
|
||||
char *microVersion; /* Micro version of runtime */
|
||||
} JRESettings;
|
||||
|
||||
/*
|
||||
* JRE functions.
|
||||
*/
|
||||
void *JRE_LoadLibrary(const char *path);
|
||||
void JRE_UnloadLibrary(void *handle);
|
||||
jint JRE_GetDefaultJavaVMInitArgs(void *handle, void *vmargsp);
|
||||
jint JRE_CreateJavaVM(void *handle, JavaVM **vmp, JNIEnv **envp,
|
||||
void *vmargsp);
|
||||
jint JRE_GetCurrentSettings(JRESettings *set);
|
||||
jint JRE_GetSettings(JRESettings *set, const char *ver);
|
||||
jint JRE_GetDefaultSettings(JRESettings *set);
|
||||
jint JRE_ParseVersion(const char *version,
|
||||
char **majorp, char **minorp, char **microp);
|
||||
char *JRE_MakeVersion(const char *major, const char *minor, const char *micro);
|
||||
void *JRE_Malloc(size_t size);
|
||||
void JRE_FatalError(JNIEnv *env, const char *msg);
|
||||
char *JRE_GetDefaultRuntimeLib(const char *dir);
|
||||
char *JRE_GetDefaultClassPath(const char *dir);
|
290
js/jsd/java/jre/win32/jre_md.c
Normal file
290
js/jsd/java/jre/win32/jre_md.c
Normal file
@ -0,0 +1,290 @@
|
||||
/*
|
||||
* @(#)jre_md.c 1.6 97/05/15 David Connelly
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
|
||||
* modify and redistribute this software in source and binary code form,
|
||||
* provided that i) this copyright notice and license appear on all copies of
|
||||
* the software; and ii) Licensee does not utilize the software in a manner
|
||||
* which is disparaging to Sun.
|
||||
*
|
||||
* This software is provided "AS IS," without a warranty of any kind. ALL
|
||||
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
|
||||
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
|
||||
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
|
||||
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
|
||||
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
|
||||
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
|
||||
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
|
||||
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
|
||||
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*
|
||||
* This software is not designed or intended for use in on-line control of
|
||||
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
|
||||
* the design, construction, operation or maintenance of any nuclear
|
||||
* facility. Licensee represents and warrants that it will not use or
|
||||
* redistribute the Software for such purposes.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Win32 specific JRE support functions
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
#include <jni.h>
|
||||
#include "jre.h"
|
||||
|
||||
#define JRE_KEY "Software\\JavaSoft\\Java Runtime Environment"
|
||||
#define JDK_KEY "Software\\JavaSoft\\Java Development Kit"
|
||||
|
||||
#define RUNTIME_LIB "javai.dll"
|
||||
|
||||
/* From jre_main.c */
|
||||
extern jboolean debug;
|
||||
|
||||
/* Forward Declarations */
|
||||
jint LoadSettings(JRESettings *set, HKEY key);
|
||||
jint GetSettings(JRESettings *set, const char *version, const char *keyname);
|
||||
char *GetStringValue(HKEY key, const char *name);
|
||||
|
||||
/*
|
||||
* Retrieve settings from registry for current runtime version. Returns
|
||||
* 0 if successful otherwise returns -1 if no installed runtime was found
|
||||
* or the registry data was invalid.
|
||||
*/
|
||||
jint
|
||||
JRE_GetCurrentSettings(JRESettings *set)
|
||||
{
|
||||
jint r = -1;
|
||||
HKEY key;
|
||||
|
||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, JRE_KEY, 0, KEY_READ, &key) == 0) {
|
||||
char *ver = GetStringValue(key, "CurrentVersion");
|
||||
if (ver != 0) {
|
||||
r = JRE_GetSettings(set, ver);
|
||||
}
|
||||
free(ver);
|
||||
RegCloseKey(key);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieves settings from registry for specified runtime version.
|
||||
* Searches for either installed JRE and JDK runtimes. Returns 0 if
|
||||
* successful otherwise returns -1 if requested version of runtime
|
||||
* could not be found.
|
||||
*/
|
||||
jint
|
||||
JRE_GetSettings(JRESettings *set, const char *version)
|
||||
{
|
||||
if (GetSettings(set, version, JRE_KEY) != 0) {
|
||||
return GetSettings(set, version, JDK_KEY);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
jint
|
||||
GetSettings(JRESettings *set, const char *version, const char *keyname)
|
||||
{
|
||||
HKEY key;
|
||||
int r = -1;
|
||||
|
||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &key) == 0) {
|
||||
char *major, *minor, *micro = 0;
|
||||
if (JRE_ParseVersion(version, &major, &minor, µ) == 0) {
|
||||
HKEY subkey;
|
||||
char *ver = JRE_MakeVersion(major, minor, 0);
|
||||
set->majorVersion = major;
|
||||
set->minorVersion = minor;
|
||||
if (RegOpenKeyEx(key, ver, 0, KEY_READ, &subkey) == 0) {
|
||||
if ((r = LoadSettings(set, subkey)) == 0) {
|
||||
if (micro != 0) {
|
||||
if (set->microVersion == 0 ||
|
||||
strcmp(micro, set->microVersion) != 0) {
|
||||
r = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
RegCloseKey(subkey);
|
||||
}
|
||||
free(ver);
|
||||
}
|
||||
RegCloseKey(key);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Load runtime settings from specified registry key. Returns 0 if
|
||||
* successful otherwise -1 if the registry data was invalid.
|
||||
*/
|
||||
static jint
|
||||
LoadSettings(JRESettings *set, HKEY key)
|
||||
{
|
||||
/* Full path name of JRE home directory (required) */
|
||||
set->javaHome = GetStringValue(key, "JavaHome");
|
||||
if (set->javaHome == 0) {
|
||||
return -1;
|
||||
}
|
||||
/* Full path name of JRE runtime DLL */
|
||||
set->runtimeLib = GetStringValue(key, "RuntimeLib");
|
||||
if (set->runtimeLib == 0) {
|
||||
set->runtimeLib = JRE_GetDefaultRuntimeLib(set->javaHome);
|
||||
}
|
||||
/* Class path setting to override default */
|
||||
set->classPath = GetStringValue(key, "ClassPath");
|
||||
if (set->classPath == 0) {
|
||||
set->classPath = JRE_GetDefaultClassPath(set->javaHome);
|
||||
}
|
||||
/* Optional JIT compiler library name */
|
||||
set->compiler = GetStringValue(key, "Compiler");
|
||||
/* Release micro-version */
|
||||
set->microVersion = GetStringValue(key, "MicroVersion");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns string data for the specified registry value name, or
|
||||
* NULL if not found.
|
||||
*/
|
||||
static char *
|
||||
GetStringValue(HKEY key, const char *name)
|
||||
{
|
||||
DWORD type, size;
|
||||
char *value = 0;
|
||||
|
||||
if (RegQueryValueEx(key, name, 0, &type, 0, &size) == 0 &&
|
||||
type == REG_SZ ) {
|
||||
value = JRE_Malloc(size);
|
||||
if (RegQueryValueEx(key, name, 0, 0, value, &size) != 0) {
|
||||
free(value);
|
||||
value = 0;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns default runtime settings based on location of this program.
|
||||
* Makes best attempt at determining location of runtime. Returns 0
|
||||
* if successful or -1 if a runtime could not be found.
|
||||
*/
|
||||
jint
|
||||
JRE_GetDefaultSettings(JRESettings *set)
|
||||
{
|
||||
char buf[MAX_PATH], *bp;
|
||||
int n;
|
||||
|
||||
// Try to obtain default value for Java home directory based on
|
||||
// location of this executable.
|
||||
|
||||
if ((n = GetModuleFileName(0, buf, MAX_PATH)) == 0) {
|
||||
return -1;
|
||||
}
|
||||
bp = buf + n;
|
||||
while (*--bp != '\\') ;
|
||||
bp -= 4;
|
||||
if (bp < buf || strnicmp(bp, "\\bin", 4) != 0) {
|
||||
return -1;
|
||||
}
|
||||
*bp = '\0';
|
||||
set->javaHome = strdup(buf);
|
||||
|
||||
// Get default runtime library
|
||||
set->runtimeLib = JRE_GetDefaultRuntimeLib(set->javaHome);
|
||||
|
||||
// Get default class path
|
||||
set->classPath = JRE_GetDefaultClassPath(set->javaHome);
|
||||
|
||||
// Reset other fields since these are unknown
|
||||
set->compiler = 0;
|
||||
set->majorVersion = 0;
|
||||
set->minorVersion = 0;
|
||||
set->microVersion = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return default runtime library for specified Java home directory.
|
||||
*/
|
||||
char *
|
||||
JRE_GetDefaultRuntimeLib(const char *dir)
|
||||
{
|
||||
char *cp = JRE_Malloc(strlen(dir) + sizeof(RUNTIME_LIB) + 8);
|
||||
sprintf(cp, "%s\\bin\\" RUNTIME_LIB, dir);
|
||||
return cp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return default class path for specified Java home directory.
|
||||
*/
|
||||
char *
|
||||
JRE_GetDefaultClassPath(const char *dir)
|
||||
{
|
||||
char *cp = JRE_Malloc(strlen(dir) * 4 + 64);
|
||||
sprintf(cp, "%s\\lib\\rt.jar;%s\\lib\\i18n.jar;%s\\lib\\classes.zip;"
|
||||
"%s\\classes", dir, dir, dir, dir);
|
||||
return cp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads the runtime library corresponding to 'libname' and returns
|
||||
* an opaque handle to the library.
|
||||
*/
|
||||
void *
|
||||
JRE_LoadLibrary(const char *path)
|
||||
{
|
||||
return (void *)LoadLibrary(path);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unloads the runtime library associated with handle.
|
||||
*/
|
||||
void
|
||||
JRE_UnloadLibrary(void *handle)
|
||||
{
|
||||
FreeLibrary(handle);
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads default VM args for the specified runtime library handle.
|
||||
*/
|
||||
jint
|
||||
JRE_GetDefaultJavaVMInitArgs(void *handle, void *vmargs)
|
||||
{
|
||||
FARPROC proc = GetProcAddress(handle, "JNI_GetDefaultJavaVMInitArgs");
|
||||
return proc != 0 ? ((*proc)(vmargs), 0) : -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates a Java VM for the specified runtime library handle.
|
||||
*/
|
||||
jint
|
||||
JRE_CreateJavaVM(void *handle, JavaVM **vmp, JNIEnv **envp, void *vmargs)
|
||||
{
|
||||
FARPROC proc = GetProcAddress(handle, "JNI_CreateJavaVM");
|
||||
return proc != 0 ? (*proc)(vmp, envp, vmargs) : -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Entry point for JREW (Windows-only) version of the runtime loader.
|
||||
* This entry point is called when the '-subsystem:windows' linker
|
||||
* option is used, and will cause the resulting executable to run
|
||||
* detached from the console.
|
||||
*/
|
||||
|
||||
/**
|
||||
* int WINAPI
|
||||
* WinMain(HINSTANCE inst, HINSTANCE prevInst, LPSTR cmdLine, int cmdShow)
|
||||
* {
|
||||
* __declspec(dllimport) char **__initenv;
|
||||
*
|
||||
* __initenv = _environ;
|
||||
* exit(main(__argc, __argv));
|
||||
* }
|
||||
*/
|
36
js/jsd/java/jre/win32/jre_md.h
Normal file
36
js/jsd/java/jre/win32/jre_md.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* @(#)jre_md.h 1.1 97/05/19 David Connelly
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
|
||||
* modify and redistribute this software in source and binary code form,
|
||||
* provided that i) this copyright notice and license appear on all copies of
|
||||
* the software; and ii) Licensee does not utilize the software in a manner
|
||||
* which is disparaging to Sun.
|
||||
*
|
||||
* This software is provided "AS IS," without a warranty of any kind. ALL
|
||||
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
|
||||
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
|
||||
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
|
||||
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
|
||||
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
|
||||
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
|
||||
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
|
||||
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
|
||||
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*
|
||||
* This software is not designed or intended for use in on-line control of
|
||||
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
|
||||
* the design, construction, operation or maintenance of any nuclear
|
||||
* facility. Licensee represents and warrants that it will not use or
|
||||
* redistribute the Software for such purposes.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Win32 specific JRE support definitions
|
||||
*/
|
||||
|
||||
#define FILE_SEPARATOR '\\'
|
||||
#define PATH_SEPARATOR ';'
|
2694
js/jsd/java/jsd_jntv.c
Normal file
2694
js/jsd/java/jsd_jntv.c
Normal file
File diff suppressed because it is too large
Load Diff
349
js/jsd/java/jsd_jvm.c
Normal file
349
js/jsd/java/jsd_jvm.c
Normal file
@ -0,0 +1,349 @@
|
||||
/* -*- 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.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Sun Microsystems, Inc.
|
||||
* Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
|
||||
* modify and redistribute this software in source and binary code form,
|
||||
* provided that i) this copyright notice and license appear on all copies of
|
||||
* the software; and ii) Licensee does not utilize the software in a manner
|
||||
* which is disparaging to Sun.
|
||||
*
|
||||
* This software is provided "AS IS," without a warranty of any kind. ALL
|
||||
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
|
||||
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
|
||||
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
|
||||
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
|
||||
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
|
||||
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
|
||||
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
|
||||
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
|
||||
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*
|
||||
* This software is not designed or intended for use in on-line control of
|
||||
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
|
||||
* the design, construction, operation or maintenance of any nuclear
|
||||
* facility. Licensee represents and warrants that it will not use or
|
||||
* redistribute the Software for such purposes.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Code to start a Java VM (*some* code from the JRE)
|
||||
*/
|
||||
|
||||
#include "jsdj.h"
|
||||
|
||||
/***************************************************************************/
|
||||
#ifdef JSD_STANDALONE_JAVA_VM
|
||||
#include "jre.h"
|
||||
|
||||
static char* more_classpath[] =
|
||||
{
|
||||
{"..\\..\\jsdj\\dist\\classes"},
|
||||
{"..\\..\\jsdj\\dist\\classes\\ifc11.jar"},
|
||||
|
||||
/*
|
||||
* {"..\\..\\..\\jsdj\\dist\\classes"},
|
||||
* {"..\\..\\..\\jsdj\\dist\\classes\\ifc12.jar"},
|
||||
*/
|
||||
|
||||
/*
|
||||
* {"..\\..\\samples\\jslogger"},
|
||||
* {"classes"},
|
||||
* {"ifc12.jar"},
|
||||
* {"jsd10.jar"},
|
||||
* {"jsdeb15.jar"}
|
||||
*/
|
||||
};
|
||||
#define MORE_CLASSPATH_COUNT (sizeof(more_classpath)/sizeof(more_classpath[0]))
|
||||
|
||||
/*
|
||||
* static char main_class[] = "callnative";
|
||||
* static char main_class[] = "simpleIFC";
|
||||
* static char* params[] = {"16 Dec 1997"};
|
||||
* #define PARAM_COUNT (sizeof(params)/sizeof(params[0]))
|
||||
*/
|
||||
|
||||
/*
|
||||
* static char main_class[] = "netscape/jslogger/JSLogger";
|
||||
* static char main_class[] = "LaunchJSDebugger";
|
||||
*/
|
||||
static char main_class[] = "com/netscape/jsdebugging/ifcui/launcher/local/LaunchJSDebugger";
|
||||
static char* params[] = {NULL};
|
||||
#define PARAM_COUNT 0
|
||||
|
||||
/* Globals */
|
||||
static char **props; /* User-defined properties */
|
||||
static int numProps, maxProps; /* Current, max number of properties */
|
||||
|
||||
static void *handle;
|
||||
static JavaVM *jvm;
|
||||
static JNIEnv *env;
|
||||
|
||||
/* Check for null value and return */
|
||||
#define NULL_CHECK(e) if ((e) == 0) return 0
|
||||
|
||||
/*
|
||||
* Adds a user-defined system property definition.
|
||||
*/
|
||||
void AddProperty(char *def)
|
||||
{
|
||||
if (numProps >= maxProps) {
|
||||
if (props == 0) {
|
||||
maxProps = 4;
|
||||
props = JRE_Malloc(maxProps * sizeof(char **));
|
||||
} else {
|
||||
char **tmp;
|
||||
maxProps *= 2;
|
||||
tmp = JRE_Malloc(maxProps * sizeof(char **));
|
||||
memcpy(tmp, props, numProps * sizeof(char **));
|
||||
free(props);
|
||||
props = tmp;
|
||||
}
|
||||
}
|
||||
props[numProps++] = def;
|
||||
}
|
||||
|
||||
/*
|
||||
* Deletes a property definition by name.
|
||||
*/
|
||||
void DeleteProperty(const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numProps; ) {
|
||||
char *def = props[i];
|
||||
char *c = strchr(def, '=');
|
||||
int n;
|
||||
if (c != 0) {
|
||||
n = c - def;
|
||||
} else {
|
||||
n = strlen(def);
|
||||
}
|
||||
if (strncmp(name, def, n) == 0) {
|
||||
if (i < --numProps) {
|
||||
memmove(&props[i], &props[i+1], (numProps-i) * sizeof(char **));
|
||||
}
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates an array of Java string objects from the specified array of C
|
||||
* strings. Returns 0 if the array could not be created.
|
||||
*/
|
||||
jarray NewStringArray(JNIEnv *env, char **cpp, int count)
|
||||
{
|
||||
jclass cls;
|
||||
jarray ary;
|
||||
int i;
|
||||
|
||||
NULL_CHECK(cls = (*env)->FindClass(env, "java/lang/String"));
|
||||
NULL_CHECK(ary = (*env)->NewObjectArray(env, count, cls, 0));
|
||||
for (i = 0; i < count; i++) {
|
||||
jstring str = (*env)->NewStringUTF(env, *cpp++);
|
||||
NULL_CHECK(str);
|
||||
(*env)->SetObjectArrayElement(env, ary, i, str);
|
||||
(*env)->DeleteLocalRef(env, str);
|
||||
}
|
||||
return ary;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static JNIEnv*
|
||||
_CreateJavaVM(void)
|
||||
{
|
||||
JNIEnv* env = NULL;
|
||||
JDK1_1InitArgs vmargs;
|
||||
JRESettings set;
|
||||
|
||||
printf("Starting Java...\n");
|
||||
|
||||
if(JRE_GetCurrentSettings(&set) != 0)
|
||||
{
|
||||
if(JRE_GetDefaultSettings(&set) != 0)
|
||||
{
|
||||
fprintf(stderr, "Could not locate Java runtime\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Load runtime library */
|
||||
handle = JRE_LoadLibrary(set.runtimeLib);
|
||||
if (handle == 0) {
|
||||
fprintf(stderr, "Could not load runtime library: %s\n",
|
||||
set.runtimeLib);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Add pre-defined system properties */
|
||||
if (set.javaHome != 0) {
|
||||
char *def = JRE_Malloc(strlen(set.javaHome) + 16);
|
||||
sprintf(def, "java.home=%s", set.javaHome);
|
||||
AddProperty(def);
|
||||
}
|
||||
|
||||
if (set.compiler != 0) {
|
||||
char *def = JRE_Malloc(strlen(set.compiler) + 16);
|
||||
sprintf(def, "java.compiler=%s", set.compiler);
|
||||
AddProperty(def);
|
||||
}
|
||||
|
||||
/*
|
||||
* The following is used to specify that we require at least
|
||||
* JNI version 1.1. Currently, this field is not checked but
|
||||
* will be starting with JDK/JRE 1.2. The value returned after
|
||||
* calling JNI_GetDefaultJavaVMInitArgs() is the actual JNI version
|
||||
* supported, and is always higher that the requested version.
|
||||
*/
|
||||
vmargs.version = 0x00010001;
|
||||
|
||||
if (JRE_GetDefaultJavaVMInitArgs(handle, &vmargs) != 0) {
|
||||
fprintf(stderr, "Could not initialize Java VM\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Tack on our classpath */
|
||||
if(MORE_CLASSPATH_COUNT)
|
||||
{
|
||||
int i;
|
||||
int size = strlen(set.classPath) + 1;
|
||||
char sep[2];
|
||||
|
||||
sep[0] = PATH_SEPARATOR;
|
||||
sep[1] = 0;
|
||||
|
||||
for(i = 0; i < MORE_CLASSPATH_COUNT; i++)
|
||||
size += strlen(more_classpath[i]) + 1;
|
||||
|
||||
vmargs.classpath = malloc(size);
|
||||
if(vmargs.classpath == 0)
|
||||
{
|
||||
fprintf(stderr, "malloc error\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strcpy(vmargs.classpath, set.classPath);
|
||||
for(i = 0; i < MORE_CLASSPATH_COUNT; i++)
|
||||
{
|
||||
strcat(vmargs.classpath, sep);
|
||||
strcat(vmargs.classpath, more_classpath[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vmargs.classpath = set.classPath;
|
||||
}
|
||||
|
||||
/*
|
||||
* fprintf(stderr, "classpath: %s\n", vmargs.classpath);
|
||||
*/
|
||||
|
||||
/* Set user-defined system properties for Java VM */
|
||||
if (props != 0) {
|
||||
if (numProps == maxProps) {
|
||||
char **tmp = JRE_Malloc((numProps + 1) * sizeof(char **));
|
||||
memcpy(tmp, props, numProps * sizeof(char **));
|
||||
free(props);
|
||||
props = tmp;
|
||||
}
|
||||
props[numProps] = 0;
|
||||
vmargs.properties = props;
|
||||
}
|
||||
|
||||
|
||||
/* verbose? */
|
||||
/*
|
||||
* vmargs.verbose = JNI_TRUE;
|
||||
*/
|
||||
|
||||
/* Load and initialize Java VM */
|
||||
if (JRE_CreateJavaVM(handle, &jvm, &env, &vmargs) != 0) {
|
||||
fprintf(stderr, "Could not create Java VM\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Free properties */
|
||||
if (props != 0) {
|
||||
free(props);
|
||||
}
|
||||
return env;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
_StartDebuggerFE(JNIEnv* env)
|
||||
{
|
||||
jclass clazz;
|
||||
jmethodID mid;
|
||||
jarray args;
|
||||
|
||||
/* Find class */
|
||||
clazz = (*env)->FindClass(env, main_class);
|
||||
if (clazz == 0) {
|
||||
fprintf(stderr, "Class not found: %s\n", main_class);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* Find main method of class */
|
||||
mid = (*env)->GetStaticMethodID(env, clazz, "main",
|
||||
"([Ljava/lang/String;)V");
|
||||
if (mid == 0) {
|
||||
fprintf(stderr, "In class %s: public static void main(String args[])"
|
||||
" is not defined\n");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* Invoke main method */
|
||||
args = NewStringArray(env, params, PARAM_COUNT);
|
||||
|
||||
if (args == 0) {
|
||||
JRE_FatalError(env, "Couldn't build argument list for main\n");
|
||||
}
|
||||
(*env)->CallStaticVoidMethod(env, clazz, mid, args);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
(*env)->ExceptionDescribe(env);
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JNIEnv*
|
||||
jsdj_CreateJavaVMAndStartDebugger(JSDJContext* jsdjc)
|
||||
{
|
||||
JNIEnv* env = NULL;
|
||||
|
||||
env = _CreateJavaVM();
|
||||
if( ! env )
|
||||
return NULL;
|
||||
|
||||
jsdj_SetJNIEnvForCurrentThread(jsdjc, env);
|
||||
if( ! jsdj_RegisterNatives(jsdjc) )
|
||||
return NULL;
|
||||
if( ! _StartDebuggerFE(env) )
|
||||
return NULL;
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
|
||||
#endif /* JSD_STANDALONE_JAVA_VM */
|
||||
/***************************************************************************/
|
||||
|
147
js/jsd/java/jsdj.h
Normal file
147
js/jsd/java/jsdj.h
Normal file
@ -0,0 +1,147 @@
|
||||
/* -*- 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.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Header for JavaScript Debugger JNI support (internal functions)
|
||||
*/
|
||||
|
||||
#ifndef jsdj_h___
|
||||
#define jsdj_h___
|
||||
|
||||
/* Get jstypes.h included first. After that we can use PR macros for doing
|
||||
* this extern "C" stuff!
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
#include "jstypes.h"
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
JS_BEGIN_EXTERN_C
|
||||
#include "jsutil.h" /* Added by JSIFY */
|
||||
#include "jshash.h" /* Added by JSIFY */
|
||||
#include "jsdjava.h"
|
||||
#include "jsobj.h"
|
||||
#include "jsfun.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
JS_END_EXTERN_C
|
||||
|
||||
JS_BEGIN_EXTERN_C
|
||||
|
||||
/***************************************************************************/
|
||||
/* defines copied from Java sources.
|
||||
** NOTE: javah used to put these in the h files, but with JNI does not seem
|
||||
** to do this anymore. Be careful with synchronization of these
|
||||
**
|
||||
*/
|
||||
|
||||
/* From: ThreadStateBase.java */
|
||||
|
||||
#define THR_STATUS_UNKNOWN 0x01
|
||||
#define THR_STATUS_ZOMBIE 0x02
|
||||
#define THR_STATUS_RUNNING 0x03
|
||||
#define THR_STATUS_SLEEPING 0x04
|
||||
#define THR_STATUS_MONWAIT 0x05
|
||||
#define THR_STATUS_CONDWAIT 0x06
|
||||
#define THR_STATUS_SUSPENDED 0x07
|
||||
#define THR_STATUS_BREAK 0x08
|
||||
|
||||
#define DEBUG_STATE_DEAD 0x01
|
||||
#define DEBUG_STATE_RUN 0x02
|
||||
#define DEBUG_STATE_RETURN 0x03
|
||||
#define DEBUG_STATE_THROW 0x04
|
||||
|
||||
/***************************************************************************/
|
||||
/* Our structures */
|
||||
|
||||
typedef struct JSDJContext
|
||||
{
|
||||
JSDContext* jsdc;
|
||||
JSHashTable* envTable;
|
||||
jobject controller;
|
||||
JSDJ_UserCallbacks callbacks;
|
||||
void* user;
|
||||
JSBool ownJSDC;
|
||||
} JSDJContext;
|
||||
|
||||
/***************************************************************************/
|
||||
/* Code validation support */
|
||||
|
||||
#ifdef DEBUG
|
||||
extern void JSDJ_ASSERT_VALID_CONTEXT(JSDJContext* jsdjc);
|
||||
#else
|
||||
#define JSDJ_ASSERT_VALID_CONTEXT(x) ((void)0)
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
/* higher level functions */
|
||||
|
||||
extern JSDJContext*
|
||||
jsdj_SimpleInitForSingleContextMode(JSDContext* jsdc,
|
||||
JSDJ_GetJNIEnvProc getEnvProc, void* user);
|
||||
extern JSBool
|
||||
jsdj_SetSingleContextMode();
|
||||
|
||||
extern JSDJContext*
|
||||
jsdj_CreateContext();
|
||||
|
||||
extern void
|
||||
jsdj_DestroyContext(JSDJContext* jsdjc);
|
||||
|
||||
extern void
|
||||
jsdj_SetUserCallbacks(JSDJContext* jsdjc, JSDJ_UserCallbacks* callbacks,
|
||||
void* user);
|
||||
extern void
|
||||
jsdj_SetJNIEnvForCurrentThread(JSDJContext* jsdjc, JNIEnv* env);
|
||||
|
||||
extern JNIEnv*
|
||||
jsdj_GetJNIEnvForCurrentThread(JSDJContext* jsdjc);
|
||||
|
||||
extern void
|
||||
jsdj_SetJSDContext(JSDJContext* jsdjc, JSDContext* jsdc);
|
||||
|
||||
extern JSDContext*
|
||||
jsdj_GetJSDContext(JSDJContext* jsdjc);
|
||||
|
||||
extern JSBool
|
||||
jsdj_RegisterNatives(JSDJContext* jsdjc);
|
||||
|
||||
/***************************************************************************/
|
||||
#ifdef JSD_STANDALONE_JAVA_VM
|
||||
|
||||
extern JNIEnv*
|
||||
jsdj_CreateJavaVMAndStartDebugger(JSDJContext* jsdjc);
|
||||
|
||||
/**
|
||||
* extern JNIEnv*
|
||||
* jsdj_CreateJavaVM(JSDContext* jsdc);
|
||||
*/
|
||||
|
||||
#endif /* JSD_STANDALONE_JAVA_VM */
|
||||
/***************************************************************************/
|
||||
|
||||
JS_END_EXTERN_C
|
||||
|
||||
#endif /* jsdj_h___ */
|
||||
|
110
js/jsd/java/jsdjava.c
Normal file
110
js/jsd/java/jsdjava.c
Normal file
@ -0,0 +1,110 @@
|
||||
/* -*- 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.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Public functions to reflect JSD into Java
|
||||
*/
|
||||
|
||||
#include "jsdj.h"
|
||||
|
||||
JSDJ_PUBLIC_API(JSDJContext*)
|
||||
JSDJ_SimpleInitForSingleContextMode(JSDContext* jsdc,
|
||||
JSDJ_GetJNIEnvProc getEnvProc, void* user)
|
||||
{
|
||||
return jsdj_SimpleInitForSingleContextMode(jsdc, getEnvProc, user);
|
||||
}
|
||||
|
||||
JSDJ_PUBLIC_API(JSBool)
|
||||
JSDJ_SetSingleContextMode()
|
||||
{
|
||||
return jsdj_SetSingleContextMode();
|
||||
}
|
||||
|
||||
JSDJ_PUBLIC_API(JSDJContext*)
|
||||
JSDJ_CreateContext()
|
||||
{
|
||||
return jsdj_CreateContext();
|
||||
}
|
||||
|
||||
JSDJ_PUBLIC_API(void)
|
||||
JSDJ_DestroyContext(JSDJContext* jsdjc)
|
||||
{
|
||||
JSDJ_ASSERT_VALID_CONTEXT(jsdjc);
|
||||
jsdj_DestroyContext(jsdjc);
|
||||
}
|
||||
|
||||
JSDJ_PUBLIC_API(void)
|
||||
JSDJ_SetUserCallbacks(JSDJContext* jsdjc, JSDJ_UserCallbacks* callbacks,
|
||||
void* user)
|
||||
{
|
||||
JSDJ_ASSERT_VALID_CONTEXT(jsdjc);
|
||||
JS_ASSERT(!callbacks ||
|
||||
(callbacks->size > 0 &&
|
||||
callbacks->size <= sizeof(JSDJ_UserCallbacks)));
|
||||
jsdj_SetUserCallbacks(jsdjc, callbacks, user);
|
||||
}
|
||||
|
||||
JSDJ_PUBLIC_API(void)
|
||||
JSDJ_SetJNIEnvForCurrentThread(JSDJContext* jsdjc, JNIEnv* env)
|
||||
{
|
||||
JSDJ_ASSERT_VALID_CONTEXT(jsdjc);
|
||||
JS_ASSERT(env);
|
||||
jsdj_SetJNIEnvForCurrentThread(jsdjc, env);
|
||||
}
|
||||
|
||||
JSDJ_PUBLIC_API(JNIEnv*)
|
||||
JSDJ_GetJNIEnvForCurrentThread(JSDJContext* jsdjc)
|
||||
{
|
||||
JSDJ_ASSERT_VALID_CONTEXT(jsdjc);
|
||||
return jsdj_GetJNIEnvForCurrentThread(jsdjc);
|
||||
}
|
||||
|
||||
JSDJ_PUBLIC_API(void)
|
||||
JSDJ_SetJSDContext(JSDJContext* jsdjc, JSDContext* jsdc)
|
||||
{
|
||||
JSDJ_ASSERT_VALID_CONTEXT(jsdjc);
|
||||
JS_ASSERT(jsdc);
|
||||
jsdj_SetJSDContext(jsdjc, jsdc);
|
||||
}
|
||||
|
||||
JSDJ_PUBLIC_API(JSDContext*)
|
||||
JSDJ_GetJSDContext(JSDJContext* jsdjc)
|
||||
{
|
||||
JSDJ_ASSERT_VALID_CONTEXT(jsdjc);
|
||||
return jsdj_GetJSDContext(jsdjc);
|
||||
}
|
||||
|
||||
JSDJ_PUBLIC_API(JSBool)
|
||||
JSDJ_RegisterNatives(JSDJContext* jsdjc)
|
||||
{
|
||||
JSDJ_ASSERT_VALID_CONTEXT(jsdjc);
|
||||
return jsdj_RegisterNatives(jsdjc);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
#ifdef JSD_STANDALONE_JAVA_VM
|
||||
|
||||
JSDJ_PUBLIC_API(JNIEnv*)
|
||||
JSDJ_CreateJavaVMAndStartDebugger(JSDJContext* jsdjc)
|
||||
{
|
||||
JSDJ_ASSERT_VALID_CONTEXT(jsdjc);
|
||||
return jsdj_CreateJavaVMAndStartDebugger(jsdjc);
|
||||
}
|
||||
|
||||
#endif /* JSD_STANDALONE_JAVA_VM */
|
||||
/***************************************************************************/
|
133
js/jsd/java/jsdjava.h
Normal file
133
js/jsd/java/jsdjava.h
Normal file
@ -0,0 +1,133 @@
|
||||
/* -*- 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.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Header for JavaScript Debugger JNI interfaces
|
||||
*/
|
||||
|
||||
#ifndef jsdjava_h___
|
||||
#define jsdjava_h___
|
||||
|
||||
/* Get jstypes.h included first. After that we can use PR macros for doing
|
||||
* this extern "C" stuff!
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
#include "jstypes.h"
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
JS_BEGIN_EXTERN_C
|
||||
#include "jsdebug.h"
|
||||
#include "jni.h"
|
||||
JS_END_EXTERN_C
|
||||
|
||||
|
||||
JS_BEGIN_EXTERN_C
|
||||
|
||||
/*
|
||||
* The linkage of JSDJ API functions differs depending on whether the file is
|
||||
* used within the JSDJ library or not. Any source file within the JSDJ
|
||||
* libraray should define EXPORT_JSDJ_API whereas any client of the library
|
||||
* should not.
|
||||
*/
|
||||
#ifdef EXPORT_JSDJ_API
|
||||
#define JSDJ_PUBLIC_API(t) JS_EXPORT_API(t)
|
||||
#define JSDJ_PUBLIC_DATA(t) JS_EXPORT_DATA(t)
|
||||
#else
|
||||
#define JSDJ_PUBLIC_API(t) JS_IMPORT_API(t)
|
||||
#define JSDJ_PUBLIC_DATA(t) JS_IMPORT_DATA(t)
|
||||
#endif
|
||||
|
||||
#define JSDJ_FRIEND_API(t) JSDJ_PUBLIC_API(t)
|
||||
#define JSDJ_FRIEND_DATA(t) JSDJ_PUBLIC_DATA(t)
|
||||
|
||||
/***************************************************************************/
|
||||
/* Opaque typedefs for handles */
|
||||
|
||||
typedef struct JSDJContext JSDJContext;
|
||||
|
||||
/***************************************************************************/
|
||||
/* High Level functions */
|
||||
|
||||
#define JSDJ_START_SUCCESS 1
|
||||
#define JSDJ_START_FAILURE 2
|
||||
#define JSDJ_STOP 3
|
||||
|
||||
typedef void
|
||||
(*JSDJ_StartStopProc)(JSDJContext* jsdjc, int event, void *user);
|
||||
|
||||
typedef JNIEnv*
|
||||
(*JSDJ_GetJNIEnvProc)(JSDJContext* jsdjc, void* user);
|
||||
|
||||
/* This struct could have more fields in future versions */
|
||||
typedef struct
|
||||
{
|
||||
uintN size; /* size of this struct (init before use)*/
|
||||
JSDJ_StartStopProc startStop;
|
||||
JSDJ_GetJNIEnvProc getJNIEnv;
|
||||
} JSDJ_UserCallbacks;
|
||||
|
||||
extern JSDJ_PUBLIC_API(JSDJContext*)
|
||||
JSDJ_SimpleInitForSingleContextMode(JSDContext* jsdc,
|
||||
JSDJ_GetJNIEnvProc getEnvProc, void* user);
|
||||
|
||||
extern JSDJ_PUBLIC_API(JSBool)
|
||||
JSDJ_SetSingleContextMode();
|
||||
|
||||
extern JSDJ_PUBLIC_API(JSDJContext*)
|
||||
JSDJ_CreateContext();
|
||||
|
||||
extern JSDJ_PUBLIC_API(void)
|
||||
JSDJ_DestroyContext(JSDJContext* jsdjc);
|
||||
|
||||
extern JSDJ_PUBLIC_API(void)
|
||||
JSDJ_SetUserCallbacks(JSDJContext* jsdjc, JSDJ_UserCallbacks* callbacks,
|
||||
void* user);
|
||||
|
||||
extern JSDJ_PUBLIC_API(void)
|
||||
JSDJ_SetJNIEnvForCurrentThread(JSDJContext* jsdjc, JNIEnv* env);
|
||||
|
||||
extern JSDJ_PUBLIC_API(JNIEnv*)
|
||||
JSDJ_GetJNIEnvForCurrentThread(JSDJContext* jsdjc);
|
||||
|
||||
extern JSDJ_PUBLIC_API(void)
|
||||
JSDJ_SetJSDContext(JSDJContext* jsdjc, JSDContext* jsdc);
|
||||
|
||||
extern JSDJ_PUBLIC_API(JSDContext*)
|
||||
JSDJ_GetJSDContext(JSDJContext* jsdjc);
|
||||
|
||||
extern JSDJ_PUBLIC_API(JSBool)
|
||||
JSDJ_RegisterNatives(JSDJContext* jsdjc);
|
||||
|
||||
/***************************************************************************/
|
||||
#ifdef JSD_STANDALONE_JAVA_VM
|
||||
|
||||
extern JSDJ_PUBLIC_API(JNIEnv*)
|
||||
JSDJ_CreateJavaVMAndStartDebugger(JSDJContext* jsdjc);
|
||||
|
||||
#endif /* JSD_STANDALONE_JAVA_VM */
|
||||
/***************************************************************************/
|
||||
|
||||
JS_END_EXTERN_C
|
||||
|
||||
#endif /* jsdjava_h___ */
|
||||
|
78
js/jsd/java/jsdjava.mak
Normal file
78
js/jsd/java/jsdjava.mak
Normal file
@ -0,0 +1,78 @@
|
||||
|
||||
PROJ = jsdjava
|
||||
JSDJAVA = .
|
||||
JSD = $(JSDJAVA)\..
|
||||
JS = $(JSD)\..\src
|
||||
JSPROJ = js32
|
||||
JSDPROJ = jsd
|
||||
|
||||
!IF "$(BUILD_OPT)" != ""
|
||||
OBJ = Release
|
||||
CC_FLAGS = /DNDEBUG
|
||||
!ELSE
|
||||
OBJ = Debug
|
||||
CC_FLAGS = /DDEBUG
|
||||
LINK_FLAGS = /DEBUG
|
||||
!ENDIF
|
||||
|
||||
QUIET=@
|
||||
|
||||
CFLAGS = /nologo /MDd /W3 /Gm /GX /Zi /Od\
|
||||
/I $(JS)\
|
||||
/I $(JSD)\
|
||||
/I $(JSDJAVA)\
|
||||
/DDEBUG /DWIN32 /DXP_PC /D_WINDOWS /D_WIN32\
|
||||
/DJSD_THREADSAFE\
|
||||
/DEXPORT_JSDJ_API\
|
||||
/DJSDEBUGGER\
|
||||
!IF "$(JSD_STANDALONE_JAVA_VM)" != ""
|
||||
/I $(JSDJAVA)\jre\
|
||||
/I $(JSDJAVA)\jre\win32\
|
||||
/DJSD_STANDALONE_JAVA_VM\
|
||||
!ENDIF
|
||||
$(CC_FLAGS)\
|
||||
/c /Fp$(OBJ)\$(PROJ).pch /Fd$(OBJ)\$(PROJ).pdb /YX -Fo$@ $<
|
||||
|
||||
LFLAGS = /nologo /subsystem:console /DLL /incremental:no /machine:I386 \
|
||||
$(LINK_FLAGS) /pdb:$(OBJ)\$(PROJ).pdb -out:$(OBJ)\$(PROJ).dll
|
||||
|
||||
LLIBS = kernel32.lib advapi32.lib \
|
||||
$(JS)\$(OBJ)\$(JSPROJ).lib $(JSD)\$(OBJ)\$(JSDPROJ).lib
|
||||
|
||||
CPP=cl.exe
|
||||
LINK32=link.exe
|
||||
|
||||
all: $(OBJ) $(OBJ)\$(PROJ).dll
|
||||
|
||||
|
||||
$(OBJ)\$(PROJ).dll: \
|
||||
!IF "$(JSD_STANDALONE_JAVA_VM)" != ""
|
||||
$(OBJ)\jsd_jvm.obj \
|
||||
$(OBJ)\jre.obj \
|
||||
$(OBJ)\jre_md.obj \
|
||||
!ENDIF
|
||||
$(OBJ)\jsdjava.obj \
|
||||
$(OBJ)\jsd_jntv.obj
|
||||
$(QUIET)$(LINK32) $(LFLAGS) $** $(LLIBS)
|
||||
|
||||
{$(JSDJAVA)}.c{$(OBJ)}.obj :
|
||||
$(QUIET)$(CPP) $(CFLAGS)
|
||||
|
||||
{$(JSDJAVA)\jre}.c{$(OBJ)}.obj :
|
||||
$(QUIET)$(CPP) $(CFLAGS)
|
||||
|
||||
{$(JSDJAVA)\jre\win32}.c{$(OBJ)}.obj :
|
||||
$(QUIET)$(CPP) $(CFLAGS)
|
||||
|
||||
$(OBJ) :
|
||||
$(QUIET)mkdir $(OBJ)
|
||||
|
||||
clean:
|
||||
@echo deleting old output
|
||||
$(QUIET)del $(OBJ)\*.pch >NUL
|
||||
$(QUIET)del $(OBJ)\*.obj >NUL
|
||||
$(QUIET)del $(OBJ)\*.exp >NUL
|
||||
$(QUIET)del $(OBJ)\*.lib >NUL
|
||||
$(QUIET)del $(OBJ)\*.idb >NUL
|
||||
$(QUIET)del $(OBJ)\*.pdb >NUL
|
||||
$(QUIET)del $(OBJ)\*.dll >NUL
|
147
js/jsd/javawrap/javawrap.mak
Normal file
147
js/jsd/javawrap/javawrap.mak
Normal file
@ -0,0 +1,147 @@
|
||||
|
||||
PROJ = nativejsengine
|
||||
PACKAGE_DOT = com.netscape.nativejsengine
|
||||
|
||||
NJSE = .
|
||||
TESTS = $(NJSE)\tests
|
||||
GEN = $(NJSE)\_jni
|
||||
JSD = $(NJSE)\..
|
||||
JS = $(JSD)\..\src
|
||||
JSDJAVA = $(JSD)\java
|
||||
|
||||
JSPROJ = js32
|
||||
JSDPROJ = jsd
|
||||
JSDJAVAPROJ = jsdjava
|
||||
|
||||
EXPORT_BIN_BASE_DIR = $(NJSE)\..\..\jsdj\dist\bin
|
||||
EXPORT_CLASSES_BASE_DIR = $(NJSE)\..\..\jsdj\dist\classes
|
||||
|
||||
!IF "$(BUILD_OPT)" != ""
|
||||
OBJ = Release
|
||||
CC_FLAGS = /DNDEBUG
|
||||
!ELSE
|
||||
OBJ = Debug
|
||||
CC_FLAGS = /DDEBUG
|
||||
LINK_FLAGS = /DEBUG
|
||||
!ENDIF
|
||||
|
||||
QUIET=@
|
||||
|
||||
EXPORT_BIN_DIR = $(EXPORT_BIN_BASE_DIR)\$(OBJ)
|
||||
|
||||
STD_CLASSPATH = -classpath $(EXPORT_CLASSES_BASE_DIR);$(CLASSPATH)
|
||||
|
||||
CFLAGS = /nologo /MDd /W3 /Gm /GX /Zi /Od\
|
||||
/DWIN32 /DXP_PC /D_WINDOWS /D_WIN32\
|
||||
/I $(JS)\
|
||||
/I $(JSD)\
|
||||
/I $(JSDJAVA)\
|
||||
/DJSDEBUGGER\
|
||||
/DJSD_THREADSAFE\
|
||||
$(CC_FLAGS)\
|
||||
/c /Fp$(OBJ)\$(PROJ).pch /Fd$(OBJ)\$(PROJ).pdb /YX -Fo$@ $<
|
||||
|
||||
LFLAGS = /nologo /subsystem:console /incremental:no /DLL /machine:I386 \
|
||||
$(LINK_FLAGS) /pdb:$(OBJ)\$(PROJ).pdb -out:$(OBJ)\$(PROJ).dll
|
||||
|
||||
LLIBS = kernel32.lib advapi32.lib \
|
||||
$(JS)\$(OBJ)\$(JSPROJ).lib \
|
||||
$(JSD)\$(OBJ)\$(JSDPROJ).lib \
|
||||
$(JSDJAVA)\$(OBJ)\$(JSDJAVAPROJ).lib
|
||||
|
||||
CPP=cl.exe
|
||||
LINK32=link.exe
|
||||
|
||||
CLASSES_WITH_NATIVES = \
|
||||
$(PACKAGE_DOT).JSRuntime\
|
||||
$(PACKAGE_DOT).JSContext
|
||||
|
||||
|
||||
all: $(GEN) $(OBJ) dlls mkjniheaders $(OBJ)\$(PROJ).dll export_binaries
|
||||
|
||||
$(OBJ)\$(PROJ).dll: \
|
||||
$(OBJ)\nativejsengine.obj
|
||||
$(QUIET)$(LINK32) $(LFLAGS) $** $(LLIBS)
|
||||
|
||||
.c{$(OBJ)}.obj:
|
||||
$(QUIET)$(CPP) $(CFLAGS)
|
||||
|
||||
$(GEN) :
|
||||
@mkdir $(GEN)
|
||||
|
||||
$(OBJ) :
|
||||
@mkdir $(OBJ)
|
||||
|
||||
dlls :
|
||||
$(QUIET)cd ..\..\src
|
||||
!IF "$(BUILD_OPT)" != ""
|
||||
$(QUIET)nmake -f js.mak CFG="js - Win32 Release"
|
||||
!ELSE
|
||||
$(QUIET)nmake -f js.mak CFG="js - Win32 Debug"
|
||||
!ENDIF
|
||||
$(QUIET)cd ..\jsd\javawrap
|
||||
$(QUIET)cd ..
|
||||
$(QUIET)nmake -f jsd.mak JSD_THREADSAFE=1 $(OPT)
|
||||
$(QUIET)cd javawrap
|
||||
$(QUIET)cd ..\java
|
||||
$(QUIET)nmake -f jsdjava.mak $(OPT)
|
||||
$(QUIET)cd ..\javawrap
|
||||
|
||||
|
||||
export_binaries : mk_export_dirs
|
||||
@echo exporting binaries
|
||||
$(QUIET)copy $(JS)\$(OBJ)\$(JSPROJ).dll $(EXPORT_BIN_DIR) >NUL
|
||||
$(QUIET)copy $(JS)\$(OBJ)\$(JSPROJ).pdb $(EXPORT_BIN_DIR) >NUL
|
||||
$(QUIET)copy $(JSD)\$(OBJ)\$(JSDPROJ).dll $(EXPORT_BIN_DIR) >NUL
|
||||
$(QUIET)copy $(JSD)\$(OBJ)\$(JSDPROJ).pdb $(EXPORT_BIN_DIR) >NUL
|
||||
$(QUIET)copy $(JSDJAVA)\$(OBJ)\$(JSDJAVAPROJ).dll $(EXPORT_BIN_DIR) >NUL
|
||||
$(QUIET)copy $(JSDJAVA)\$(OBJ)\$(JSDJAVAPROJ).pdb $(EXPORT_BIN_DIR) >NUL
|
||||
$(QUIET)copy $(OBJ)\$(PROJ).pdb $(EXPORT_BIN_DIR) >NUL
|
||||
$(QUIET)copy $(OBJ)\$(PROJ).dll $(EXPORT_BIN_DIR) >NUL
|
||||
|
||||
mkjniheaders :
|
||||
@echo generating JNI header
|
||||
$(QUIET)javah -jni -d "$(GEN)" $(STD_CLASSPATH) $(CLASSES_WITH_NATIVES)
|
||||
@touch *.c >NUL
|
||||
|
||||
mk_export_dirs:
|
||||
@if not exist $(JS)\..\jsdj\dist\NUL @mkdir $(JS)\..\jsdj\dist
|
||||
@if not exist $(JS)\..\jsdj\dist\bin\NUL @mkdir $(JS)\..\jsdj\dist\bin
|
||||
@if not exist $(EXPORT_BIN_DIR)\NUL @mkdir $(EXPORT_BIN_DIR)
|
||||
|
||||
#mktest :
|
||||
# @echo compiling Java test file
|
||||
# @sj $(JAVAFLAGS) $(TEST_CLASSPATH) $(TESTS)\Main.java
|
||||
# @echo copying js and jsd dlls
|
||||
# @copy $(JS)\$(OBJ)\$(JSPROJ).dll $(OBJ) >NUL
|
||||
# @copy $(JS)\$(OBJ)\$(JSPROJ).pdb $(OBJ) >NUL
|
||||
# @copy $(JSD)\$(OBJ)\$(JSDPROJ).dll $(OBJ) >NUL
|
||||
# @copy $(JSD)\$(OBJ)\$(JSDPROJ).pdb $(OBJ) >NUL
|
||||
# @copy $(TESTS)\*.js $(OBJ) >NUL
|
||||
|
||||
clean:
|
||||
@echo deleting old output
|
||||
$(QUIET)del $(OBJ)\*.pch >NUL
|
||||
$(QUIET)del $(OBJ)\*.obj >NUL
|
||||
$(QUIET)del $(OBJ)\*.exp >NUL
|
||||
$(QUIET)del $(OBJ)\*.lib >NUL
|
||||
$(QUIET)del $(OBJ)\*.idb >NUL
|
||||
$(QUIET)del $(OBJ)\*.pdb >NUL
|
||||
$(QUIET)del $(OBJ)\*.dll >NUL
|
||||
$(QUIET)del $(GEN)\*.h >NUL
|
||||
|
||||
|
||||
deep_clean: clean
|
||||
$(QUIET)cd ..\..\src
|
||||
!IF "$(BUILD_OPT)" != ""
|
||||
$(QUIET)nmake -f js.mak CFG="js - Win32 Release" clean
|
||||
!ELSE
|
||||
$(QUIET)nmake -f js.mak CFG="js - Win32 Debug" clean
|
||||
!ENDIF
|
||||
$(QUIET)cd ..\jsd\javawrap
|
||||
$(QUIET)cd ..
|
||||
$(QUIET)nmake -f jsd.mak clean
|
||||
$(QUIET)cd javawrap
|
||||
$(QUIET)cd ..\java
|
||||
$(QUIET)nmake -f jsdjava.mak clean
|
||||
$(QUIET)cd ..\javawrap
|
1
js/jsd/javawrap/mk.bat
Executable file
1
js/jsd/javawrap/mk.bat
Executable file
@ -0,0 +1 @@
|
||||
nmake -f javawrap.mak %1 %2 %3 %4 %5
|
616
js/jsd/javawrap/nativejsengine.c
Normal file
616
js/jsd/javawrap/nativejsengine.c
Normal file
@ -0,0 +1,616 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "_jni/com_netscape_nativejsengine_JSRuntime.h"
|
||||
#include "_jni/com_netscape_nativejsengine_JSContext.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jstypes.h"
|
||||
#include "jsutil.h" /* Added by JSIFY */
|
||||
|
||||
#ifdef JSDEBUGGER
|
||||
#include "jsdebug.h"
|
||||
#include "jsdjava.h"
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#define ASSERT_RETURN_VOID(x) \
|
||||
JS_BEGIN_MACRO \
|
||||
if(!(x)) \
|
||||
{ \
|
||||
JS_ASSERT(0); \
|
||||
return; \
|
||||
} \
|
||||
JS_END_MACRO
|
||||
|
||||
#define ASSERT_RETURN_VALUE(x,v)\
|
||||
JS_BEGIN_MACRO \
|
||||
if(!(x)) \
|
||||
{ \
|
||||
JS_ASSERT(0); \
|
||||
return v; \
|
||||
} \
|
||||
JS_END_MACRO
|
||||
|
||||
#define CHECK_RETURN_VOID(x) \
|
||||
JS_BEGIN_MACRO \
|
||||
if(!(x)) \
|
||||
{ \
|
||||
return; \
|
||||
} \
|
||||
JS_END_MACRO
|
||||
|
||||
#define CHECK_RETURN_VALUE(x,v) \
|
||||
JS_BEGIN_MACRO \
|
||||
if(!(x)) \
|
||||
{ \
|
||||
return v; \
|
||||
} \
|
||||
JS_END_MACRO
|
||||
|
||||
#define ASSERT_GOTO(x,w) \
|
||||
JS_BEGIN_MACRO \
|
||||
if(!(x)) \
|
||||
{ \
|
||||
JS_ASSERT(0); \
|
||||
goto w; \
|
||||
} \
|
||||
JS_END_MACRO
|
||||
|
||||
#define CHECK_GOTO(x,w) \
|
||||
JS_BEGIN_MACRO \
|
||||
if(!(x)) \
|
||||
{ \
|
||||
goto w; \
|
||||
} \
|
||||
JS_END_MACRO
|
||||
|
||||
#ifdef DEBUG
|
||||
#define ASSERT_CLEAR_EXCEPTION(e) \
|
||||
JS_BEGIN_MACRO \
|
||||
if((*e)->ExceptionOccurred(e)) \
|
||||
{ \
|
||||
(*e)->ExceptionDescribe(e); \
|
||||
JS_ASSERT(0); \
|
||||
} \
|
||||
(*e)->ExceptionClear(e); \
|
||||
JS_END_MACRO
|
||||
#else /* ! DEBUG */
|
||||
#define ASSERT_CLEAR_EXCEPTION(e) (*e)->ExceptionClear(e)
|
||||
#endif /* DEBUG */
|
||||
|
||||
#define CHECK_CLEAR_EXCEPTION(e) (*e)->ExceptionClear(e)
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
typedef struct ContextInfo {
|
||||
JNIEnv* env;
|
||||
jobject contextObject;
|
||||
} ContextInfo;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifdef JSDEBUGGER
|
||||
static void
|
||||
_jamSourceIntoJSD(JSContext *cx, const char* src, int len, const char* filename)
|
||||
{
|
||||
jclass clazz_self;
|
||||
jclass clazz;
|
||||
JSDJContext* jsdjc;
|
||||
jobject rtObject;
|
||||
jobject contextObject;
|
||||
jmethodID mid;
|
||||
jfieldID fid;
|
||||
ContextInfo* info;
|
||||
JNIEnv* env;
|
||||
|
||||
info = (ContextInfo*) JS_GetContextPrivate(cx);
|
||||
ASSERT_RETURN_VOID(info);
|
||||
|
||||
env = info->env;
|
||||
ASSERT_RETURN_VOID(env);
|
||||
|
||||
contextObject = info->contextObject;
|
||||
ASSERT_RETURN_VOID(contextObject);
|
||||
|
||||
clazz_self = (*env)->GetObjectClass(env, contextObject);
|
||||
ASSERT_RETURN_VOID(clazz_self);
|
||||
|
||||
fid = (*env)->GetFieldID(env, clazz_self, "_runtime",
|
||||
"Lcom/netscape/nativejsengine/JSRuntime;");
|
||||
ASSERT_RETURN_VOID(fid);
|
||||
|
||||
rtObject = (*env)->GetObjectField(env, contextObject, fid);
|
||||
ASSERT_RETURN_VOID(rtObject);
|
||||
|
||||
clazz = (*env)->GetObjectClass(env, rtObject);
|
||||
ASSERT_RETURN_VOID(clazz);
|
||||
|
||||
mid = (*env)->GetMethodID(env, clazz, "getNativeDebugSupport", "()J");
|
||||
ASSERT_RETURN_VOID(mid);
|
||||
|
||||
jsdjc = (JSDJContext*) (*env)->CallObjectMethod(env, rtObject, mid);
|
||||
if(jsdjc)
|
||||
{
|
||||
JSDContext* jsdc;
|
||||
|
||||
jsdc = JSDJ_GetJSDContext(jsdjc);
|
||||
ASSERT_RETURN_VOID(jsdc);
|
||||
|
||||
JSD_AddFullSourceText(jsdc, src, len, filename);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static JSBool
|
||||
_loadSingleFile(JSContext *cx, JSObject *obj, const char* filename)
|
||||
{
|
||||
char* buf;
|
||||
FILE* file;
|
||||
int file_len;
|
||||
jsval result;
|
||||
|
||||
errno = 0;
|
||||
file = fopen(filename, "rb");
|
||||
if (!file) {
|
||||
JS_ReportError(cx, "can't open %s: %s", filename, strerror(errno));
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
file_len = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
if(! file_len) {
|
||||
fclose(file);
|
||||
JS_ReportError(cx, "%s is empty", filename);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
buf = (char*) malloc(file_len);
|
||||
if(! buf) {
|
||||
fclose(file);
|
||||
JS_ReportError(cx, "memory alloc error while trying to read %s", filename);
|
||||
return JS_FALSE;
|
||||
}
|
||||
fread(buf, 1, file_len, file);
|
||||
fclose(file);
|
||||
|
||||
#ifdef JSDEBUGGER
|
||||
_jamSourceIntoJSD(cx, buf, file_len, filename);
|
||||
#endif
|
||||
|
||||
JS_EvaluateScript(cx, obj, buf, file_len, filename, 1, &result);
|
||||
|
||||
free(buf);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void _sendPrintStringToJava(JNIEnv* env, jobject contextObject,
|
||||
jmethodID mid, const char* str)
|
||||
{
|
||||
if(! str)
|
||||
return;
|
||||
(*env)->CallObjectMethod(env, contextObject, mid,
|
||||
(*env)->NewStringUTF(env, str));
|
||||
}
|
||||
|
||||
static JSBool
|
||||
Print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
uintN i, n;
|
||||
JSString *str;
|
||||
|
||||
ContextInfo* info;
|
||||
jmethodID mid;
|
||||
jclass clazz;
|
||||
JNIEnv* env;
|
||||
|
||||
info = (ContextInfo*) JS_GetContextPrivate(cx);
|
||||
ASSERT_RETURN_VALUE(info, JS_FALSE);
|
||||
|
||||
env = info->env;
|
||||
ASSERT_RETURN_VALUE(env, JS_FALSE);
|
||||
|
||||
clazz = (*env)->GetObjectClass(env, info->contextObject);
|
||||
ASSERT_RETURN_VALUE(clazz, JS_FALSE);
|
||||
|
||||
mid = (*env)->GetMethodID(env, clazz, "_print", "(Ljava/lang/String;)V");
|
||||
ASSERT_RETURN_VALUE(mid, JS_FALSE);
|
||||
|
||||
for (i = n = 0; i < argc; i++) {
|
||||
str = JS_ValueToString(cx, argv[i]);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
|
||||
if(i)
|
||||
_sendPrintStringToJava(env, info->contextObject, mid, "");
|
||||
_sendPrintStringToJava(env, info->contextObject, mid, JS_GetStringBytes(str));
|
||||
n++;
|
||||
}
|
||||
if (n)
|
||||
_sendPrintStringToJava(env, info->contextObject, mid, "\n");
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
Version(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
if (argc > 0 && JSVAL_IS_INT(argv[0]))
|
||||
*rval = INT_TO_JSVAL(JS_SetVersion(cx, JSVAL_TO_INT(argv[0])));
|
||||
else
|
||||
*rval = INT_TO_JSVAL(JS_GetVersion(cx));
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
Load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
uintN i;
|
||||
JSString *str;
|
||||
const char *filename;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
str = JS_ValueToString(cx, argv[i]);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
argv[i] = STRING_TO_JSVAL(str);
|
||||
filename = JS_GetStringBytes(str);
|
||||
|
||||
if(! _loadSingleFile(cx, obj, filename))
|
||||
return JS_FALSE;
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSFunctionSpec shell_functions[] = {
|
||||
{"version", Version, 0},
|
||||
{"load", Load, 1},
|
||||
{"print", Print, 0},
|
||||
{0}
|
||||
};
|
||||
|
||||
static void
|
||||
my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
|
||||
{
|
||||
ContextInfo* info;
|
||||
jmethodID mid;
|
||||
jclass clazz;
|
||||
JNIEnv* env;
|
||||
|
||||
jobject msg = NULL;
|
||||
jobject filename = NULL;
|
||||
jobject lineBuf = NULL;
|
||||
int lineno = 0;
|
||||
int offset = 0;
|
||||
|
||||
info = (ContextInfo*) JS_GetContextPrivate(cx);
|
||||
ASSERT_RETURN_VOID(info);
|
||||
|
||||
env = info->env;
|
||||
ASSERT_RETURN_VOID(env);
|
||||
|
||||
clazz = (*env)->GetObjectClass(env, info->contextObject);
|
||||
ASSERT_RETURN_VOID(clazz);
|
||||
|
||||
mid = (*env)->GetMethodID(env, clazz, "_reportError",
|
||||
"(Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;I)V");
|
||||
ASSERT_RETURN_VOID(mid);
|
||||
|
||||
|
||||
if(message)
|
||||
msg = (*env)->NewStringUTF(env, message);
|
||||
|
||||
if(report)
|
||||
{
|
||||
lineno = report->lineno;
|
||||
if(report->filename)
|
||||
filename = (*env)->NewStringUTF(env, report->filename);
|
||||
|
||||
if(report->linebuf)
|
||||
{
|
||||
lineBuf = (*env)->NewStringUTF(env, report->linebuf);
|
||||
if(report->tokenptr)
|
||||
offset = report->tokenptr - report->linebuf;
|
||||
}
|
||||
}
|
||||
|
||||
(*env)->CallObjectMethod(env, info->contextObject, mid,
|
||||
msg, filename, lineno, lineBuf, offset);
|
||||
|
||||
}
|
||||
|
||||
static JSClass global_class = {
|
||||
"global", 0,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
};
|
||||
|
||||
/*
|
||||
* Class: com_netscape_nativejsengine_JSRuntime
|
||||
* Method: _init
|
||||
* Signature: (Z)Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL Java_com_netscape_nativejsengine_JSRuntime__1init
|
||||
(JNIEnv * env, jobject self, jboolean enableDebugging)
|
||||
{
|
||||
JSRuntime *rt;
|
||||
jclass clazz;
|
||||
jfieldID fid;
|
||||
|
||||
rt = JS_NewRuntime(8L * 1024L * 1024L);
|
||||
ASSERT_RETURN_VALUE(rt, JNI_FALSE);
|
||||
|
||||
clazz = (*env)->GetObjectClass(env, self);
|
||||
ASSERT_RETURN_VALUE(clazz, JNI_FALSE);
|
||||
|
||||
fid = (*env)->GetFieldID(env, clazz, "_nativeRuntime", "J");
|
||||
ASSERT_RETURN_VALUE(fid, JNI_FALSE);
|
||||
(*env)->SetLongField(env, self, fid, (long) rt);
|
||||
|
||||
|
||||
#ifdef JSDEBUGGER
|
||||
if(enableDebugging)
|
||||
{
|
||||
JSDJContext* jsdjc;
|
||||
JSDContext* jsdc;
|
||||
|
||||
jsdc = JSD_DebuggerOnForUser(rt, NULL, NULL);
|
||||
ASSERT_RETURN_VALUE(jsdc, JNI_FALSE);
|
||||
|
||||
jsdjc = JSDJ_CreateContext();
|
||||
ASSERT_RETURN_VALUE(jsdjc, JNI_FALSE);
|
||||
|
||||
JSDJ_SetJSDContext(jsdjc, jsdc);
|
||||
JSDJ_SetJNIEnvForCurrentThread(jsdjc, env);
|
||||
|
||||
fid = (*env)->GetFieldID(env, clazz, "_nativeDebugSupport", "J");
|
||||
ASSERT_RETURN_VALUE(fid, JNI_FALSE);
|
||||
(*env)->SetLongField(env, self, fid, (long) jsdjc);
|
||||
}
|
||||
#else
|
||||
if(enableDebugging)
|
||||
printf("ERROR - Context created with enableDebugging flag, but no debugging support compiled in!");
|
||||
#endif
|
||||
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: com_netscape_nativejsengine_JSRuntime
|
||||
* Method: _exit
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_netscape_nativejsengine_JSRuntime__1exit
|
||||
(JNIEnv * env, jobject self)
|
||||
{
|
||||
jfieldID fid;
|
||||
jclass clazz;
|
||||
JSRuntime *rt;
|
||||
JSContext *iterp = NULL;
|
||||
|
||||
clazz = (*env)->GetObjectClass(env, self);
|
||||
ASSERT_RETURN_VOID(clazz);
|
||||
|
||||
fid = (*env)->GetFieldID(env, clazz, "_nativeRuntime", "J");
|
||||
ASSERT_RETURN_VOID(fid);
|
||||
rt = (JSRuntime *) (*env)->GetLongField(env, self, fid);
|
||||
ASSERT_RETURN_VOID(rt);
|
||||
|
||||
|
||||
/*
|
||||
* Can't kill runtime if it holds any contexts
|
||||
*
|
||||
* However, JSD may make it's own context(s), so don't ASSERT
|
||||
*/
|
||||
CHECK_RETURN_VOID(!JS_ContextIterator(rt, &iterp));
|
||||
|
||||
printf("runtime = %d\n", (int)rt);
|
||||
|
||||
JS_DestroyRuntime(rt);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* Class: com_netscape_nativejsengine_JSContext
|
||||
* Method: _init
|
||||
* Signature: ()Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL Java_com_netscape_nativejsengine_JSContext__1init
|
||||
(JNIEnv *env, jobject self)
|
||||
{
|
||||
JSContext *cx;
|
||||
JSObject *glob;
|
||||
jfieldID fid;
|
||||
jmethodID mid;
|
||||
JSRuntime *rt;
|
||||
jobject rtObject;
|
||||
jclass clazz;
|
||||
jclass clazz_self;
|
||||
JSBool ok;
|
||||
ContextInfo* info;
|
||||
|
||||
#ifdef JSDEBUGGER
|
||||
JSDJContext* jsdjc;
|
||||
#endif
|
||||
|
||||
clazz_self = (*env)->GetObjectClass(env, self);
|
||||
ASSERT_RETURN_VALUE(clazz_self, JNI_FALSE);
|
||||
|
||||
fid = (*env)->GetFieldID(env, clazz_self, "_runtime",
|
||||
"Lcom/netscape/nativejsengine/JSRuntime;");
|
||||
ASSERT_RETURN_VALUE(fid, JNI_FALSE);
|
||||
|
||||
rtObject = (*env)->GetObjectField(env, self, fid);
|
||||
ASSERT_RETURN_VALUE(rtObject, JNI_FALSE);
|
||||
|
||||
clazz = (*env)->GetObjectClass(env, rtObject);
|
||||
ASSERT_RETURN_VALUE(clazz, JNI_FALSE);
|
||||
|
||||
mid = (*env)->GetMethodID(env, clazz, "getNativeRuntime", "()J");
|
||||
ASSERT_RETURN_VALUE(mid, JNI_FALSE);
|
||||
|
||||
rt = (JSRuntime *) (*env)->CallObjectMethod(env, rtObject, mid);
|
||||
ASSERT_RETURN_VALUE(rt, JNI_FALSE);
|
||||
|
||||
cx = JS_NewContext(rt, 8192);
|
||||
ASSERT_RETURN_VALUE(cx, JNI_FALSE);
|
||||
|
||||
JS_SetErrorReporter(cx, my_ErrorReporter);
|
||||
|
||||
glob = JS_NewObject(cx, &global_class, NULL, NULL);
|
||||
ASSERT_RETURN_VALUE(glob, JNI_FALSE);
|
||||
|
||||
ok = JS_InitStandardClasses(cx, glob);
|
||||
ASSERT_RETURN_VALUE(ok, JNI_FALSE);
|
||||
|
||||
ok = JS_DefineFunctions(cx, glob, shell_functions);
|
||||
ASSERT_RETURN_VALUE(ok, JNI_FALSE);
|
||||
|
||||
fid = (*env)->GetFieldID(env, clazz_self, "_nativeContext", "J");
|
||||
ASSERT_RETURN_VALUE(fid, JNI_FALSE);
|
||||
(*env)->SetLongField(env, self, fid, (long) cx);
|
||||
|
||||
|
||||
info = (ContextInfo*) malloc(sizeof(ContextInfo));
|
||||
ASSERT_RETURN_VALUE(info, JNI_FALSE);
|
||||
|
||||
info->env = env;
|
||||
info->contextObject = self;
|
||||
|
||||
JS_SetContextPrivate(cx, info);
|
||||
|
||||
#ifdef JSDEBUGGER
|
||||
mid = (*env)->GetMethodID(env, clazz, "getNativeDebugSupport", "()J");
|
||||
ASSERT_RETURN_VALUE(mid, JNI_FALSE);
|
||||
|
||||
jsdjc = (JSDJContext*) (*env)->CallObjectMethod(env, rtObject, mid);
|
||||
if(jsdjc)
|
||||
{
|
||||
JSDContext* jsdc = JSDJ_GetJSDContext(jsdjc);
|
||||
ASSERT_RETURN_VALUE(jsdc, JNI_FALSE);
|
||||
|
||||
JSDJ_SetJNIEnvForCurrentThread(jsdjc, env);
|
||||
JSD_JSContextInUse(jsdc, cx);
|
||||
}
|
||||
#endif
|
||||
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: com_netscape_nativejsengine_JSContext
|
||||
* Method: _exit
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_netscape_nativejsengine_JSContext__1exit
|
||||
(JNIEnv *env, jobject self)
|
||||
{
|
||||
jfieldID fid;
|
||||
jclass clazz;
|
||||
JSContext *cx;
|
||||
ContextInfo* info;
|
||||
|
||||
clazz = (*env)->GetObjectClass(env, self);
|
||||
ASSERT_RETURN_VOID(clazz);
|
||||
|
||||
fid = (*env)->GetFieldID(env, clazz, "_nativeContext", "J");
|
||||
ASSERT_RETURN_VOID(fid);
|
||||
|
||||
cx = (JSContext *) (*env)->GetLongField(env, self, fid);
|
||||
ASSERT_RETURN_VOID(cx);
|
||||
|
||||
info = (ContextInfo*) JS_GetContextPrivate(cx);
|
||||
ASSERT_RETURN_VOID(info);
|
||||
free(info);
|
||||
|
||||
printf("context = %d\n", (int)cx);
|
||||
|
||||
JS_DestroyContext(cx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: com_netscape_nativejsengine_JSContext
|
||||
* Method: _eval
|
||||
* Signature: (Ljava/lang/String;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_netscape_nativejsengine_JSContext__1eval
|
||||
(JNIEnv * env, jobject self, jstring str, jstring filename, jint lineno)
|
||||
{
|
||||
jfieldID fid;
|
||||
jclass clazz_self;
|
||||
JSContext *cx;
|
||||
JSObject *glob;
|
||||
jsval rval;
|
||||
int len;
|
||||
const char* Cstr;
|
||||
const char* Cfilename;
|
||||
jboolean isCopy;
|
||||
|
||||
clazz_self = (*env)->GetObjectClass(env, self);
|
||||
ASSERT_RETURN_VOID(clazz_self);
|
||||
|
||||
fid = (*env)->GetFieldID(env, clazz_self, "_nativeContext", "J");
|
||||
ASSERT_RETURN_VOID(fid);
|
||||
|
||||
cx = (JSContext *) (*env)->GetLongField(env, self, fid);
|
||||
ASSERT_RETURN_VOID(cx);
|
||||
|
||||
glob = JS_GetGlobalObject(cx);
|
||||
ASSERT_RETURN_VOID(glob);
|
||||
|
||||
len = (*env)->GetStringUTFLength(env, str);
|
||||
Cstr = (*env)->GetStringUTFChars(env, str, &isCopy);
|
||||
Cfilename = (*env)->GetStringUTFChars(env, filename, &isCopy);
|
||||
|
||||
#ifdef JSDEBUGGER
|
||||
/*
|
||||
* XXX this just overwrites any previous source for this url!
|
||||
*/
|
||||
_jamSourceIntoJSD(cx, Cstr, len, Cfilename);
|
||||
#endif
|
||||
|
||||
JS_EvaluateScript(cx, glob, Cstr, len, Cfilename, lineno, &rval);
|
||||
|
||||
(*env)->ReleaseStringUTFChars(env, str, Cstr);
|
||||
(*env)->ReleaseStringUTFChars(env, filename, Cfilename);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: com_netscape_nativejsengine_JSContext
|
||||
* Method: _load
|
||||
* Signature: (Ljava/lang/String;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_netscape_nativejsengine_JSContext__1load
|
||||
(JNIEnv *env, jobject self, jstring filename)
|
||||
{
|
||||
jfieldID fid;
|
||||
jclass clazz;
|
||||
JSContext *cx;
|
||||
const char* Cfilename;
|
||||
jboolean isCopy;
|
||||
JSObject *glob;
|
||||
|
||||
clazz = (*env)->GetObjectClass(env, self);
|
||||
ASSERT_RETURN_VOID(clazz);
|
||||
|
||||
fid = (*env)->GetFieldID(env, clazz, "_nativeContext", "J");
|
||||
ASSERT_RETURN_VOID(fid);
|
||||
|
||||
cx = (JSContext *) (*env)->GetLongField(env, self, fid);
|
||||
ASSERT_RETURN_VOID(cx);
|
||||
|
||||
glob = JS_GetGlobalObject(cx);
|
||||
ASSERT_RETURN_VOID(glob);
|
||||
|
||||
Cfilename = (*env)->GetStringUTFChars(env, filename, &isCopy);
|
||||
|
||||
_loadSingleFile(cx, glob, Cfilename);
|
||||
|
||||
(*env)->ReleaseStringUTFChars(env, filename, Cfilename);
|
||||
}
|
865
js/jsd/jsd.h
865
js/jsd/jsd.h
File diff suppressed because it is too large
Load Diff
70
js/jsd/jsd.mak
Normal file
70
js/jsd/jsd.mak
Normal file
@ -0,0 +1,70 @@
|
||||
|
||||
PROJ = jsd
|
||||
JSD = .
|
||||
JS = $(JSD)\..\src
|
||||
JSPROJ = js32
|
||||
|
||||
!IF "$(BUILD_OPT)" != ""
|
||||
OBJ = Release
|
||||
CC_FLAGS = /DNDEBUG
|
||||
!ELSE
|
||||
OBJ = Debug
|
||||
CC_FLAGS = /DDEBUG
|
||||
LINK_FLAGS = /DEBUG
|
||||
!ENDIF
|
||||
|
||||
QUIET=@
|
||||
|
||||
CFLAGS = /nologo /MDd /W3 /Gm /GX /Zi /Od\
|
||||
/I $(JS)\
|
||||
/I $(JSD)\
|
||||
/DDEBUG /DWIN32 /D_CONSOLE /DXP_PC /D_WINDOWS /D_WIN32\
|
||||
/DJSDEBUGGER\
|
||||
!IF "$(JSD_THREADSAFE)" != ""
|
||||
/DJSD_THREADSAFE\
|
||||
!ENDIF
|
||||
/DEXPORT_JSD_API\
|
||||
$(CC_FLAGS)\
|
||||
/c /Fp$(OBJ)\$(PROJ).pch /Fd$(OBJ)\$(PROJ).pdb /YX -Fo$@ $<
|
||||
|
||||
LFLAGS = /nologo /subsystem:console /DLL /incremental:no /machine:I386 \
|
||||
$(LINK_FLAGS) /pdb:$(OBJ)\$(PROJ).pdb -out:$(OBJ)\$(PROJ).dll
|
||||
|
||||
LLIBS = kernel32.lib advapi32.lib $(JS)\$(OBJ)\$(JSPROJ).lib
|
||||
# unused... user32.lib gdi32.lib winspool.lib comdlg32.lib shell32.lib
|
||||
|
||||
CPP=cl.exe
|
||||
LINK32=link.exe
|
||||
|
||||
all: $(OBJ) $(OBJ)\$(PROJ).dll
|
||||
|
||||
|
||||
$(OBJ)\$(PROJ).dll: \
|
||||
$(OBJ)\jsdebug.obj \
|
||||
$(OBJ)\jsd_atom.obj \
|
||||
$(OBJ)\jsd_high.obj \
|
||||
$(OBJ)\jsd_hook.obj \
|
||||
$(OBJ)\jsd_obj.obj \
|
||||
$(OBJ)\jsd_scpt.obj \
|
||||
$(OBJ)\jsd_stak.obj \
|
||||
$(OBJ)\jsd_step.obj \
|
||||
$(OBJ)\jsd_text.obj \
|
||||
$(OBJ)\jsd_lock.obj \
|
||||
$(OBJ)\jsd_val.obj
|
||||
$(QUIET)$(LINK32) $(LFLAGS) $** $(LLIBS)
|
||||
|
||||
{$(JSD)}.c{$(OBJ)}.obj :
|
||||
$(QUIET)$(CPP) $(CFLAGS)
|
||||
|
||||
$(OBJ) :
|
||||
$(QUIET)mkdir $(OBJ)
|
||||
|
||||
clean:
|
||||
@echo deleting old output
|
||||
$(QUIET)del $(OBJ)\*.pch >NUL
|
||||
$(QUIET)del $(OBJ)\*.obj >NUL
|
||||
$(QUIET)del $(OBJ)\*.exp >NUL
|
||||
$(QUIET)del $(OBJ)\*.lib >NUL
|
||||
$(QUIET)del $(OBJ)\*.idb >NUL
|
||||
$(QUIET)del $(OBJ)\*.pdb >NUL
|
||||
$(QUIET)del $(OBJ)\*.dll >NUL
|
159
js/jsd/jsd_atom.c
Normal file
159
js/jsd/jsd_atom.c
Normal file
@ -0,0 +1,159 @@
|
||||
/* -*- 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.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* JavaScript Debugging support - Atom support
|
||||
*/
|
||||
|
||||
#include "jsd.h"
|
||||
|
||||
/* #define TEST_ATOMS 1 */
|
||||
|
||||
#ifdef TEST_ATOMS
|
||||
static void
|
||||
_testAtoms(JSDContext*jsdc)
|
||||
{
|
||||
JSDAtom* atom0 = jsd_AddAtom(jsdc, "foo");
|
||||
JSDAtom* atom1 = jsd_AddAtom(jsdc, "foo");
|
||||
JSDAtom* atom2 = jsd_AddAtom(jsdc, "bar");
|
||||
JSDAtom* atom3 = jsd_CloneAtom(jsdc, atom1);
|
||||
JSDAtom* atom4 = jsd_CloneAtom(jsdc, atom2);
|
||||
|
||||
const char* c0 = JSD_ATOM_TO_STRING(atom0);
|
||||
const char* c1 = JSD_ATOM_TO_STRING(atom1);
|
||||
const char* c2 = JSD_ATOM_TO_STRING(atom2);
|
||||
const char* c3 = JSD_ATOM_TO_STRING(atom3);
|
||||
const char* c4 = JSD_ATOM_TO_STRING(atom4);
|
||||
|
||||
jsd_DropAtom(jsdc, atom0);
|
||||
jsd_DropAtom(jsdc, atom1);
|
||||
jsd_DropAtom(jsdc, atom2);
|
||||
jsd_DropAtom(jsdc, atom3);
|
||||
jsd_DropAtom(jsdc, atom4);
|
||||
}
|
||||
#endif
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(intN)
|
||||
_atom_smasher(JSHashEntry *he, intN i, void *arg)
|
||||
{
|
||||
JS_ASSERT(he);
|
||||
JS_ASSERT(he->value);
|
||||
JS_ASSERT(((JSDAtom*)(he->value))->str);
|
||||
|
||||
free(((JSDAtom*)(he->value))->str);
|
||||
free(he->value);
|
||||
he->value = NULL;
|
||||
he->key = NULL;
|
||||
return HT_ENUMERATE_NEXT;
|
||||
}
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(intN)
|
||||
_compareAtomKeys(const void *v1, const void *v2)
|
||||
{
|
||||
return 0 == strcmp((const char*)v1, (const char*)v2);
|
||||
}
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(intN)
|
||||
_compareAtoms(const void *v1, const void *v2)
|
||||
{
|
||||
return 0 == strcmp(((JSDAtom*)v1)->str, ((JSDAtom*)v2)->str);
|
||||
}
|
||||
|
||||
|
||||
JSBool
|
||||
jsd_CreateAtomTable(JSDContext* jsdc)
|
||||
{
|
||||
jsdc->atoms = JS_NewHashTable(256, JS_HashString,
|
||||
_compareAtomKeys, _compareAtoms,
|
||||
NULL, NULL);
|
||||
#ifdef TEST_ATOMS
|
||||
_testAtoms(jsdc);
|
||||
#endif
|
||||
return (JSBool) jsdc->atoms;
|
||||
}
|
||||
|
||||
void
|
||||
jsd_DestroyAtomTable(JSDContext* jsdc)
|
||||
{
|
||||
if( jsdc->atoms )
|
||||
{
|
||||
JS_HashTableEnumerateEntries(jsdc->atoms, _atom_smasher, NULL);
|
||||
JS_HashTableDestroy(jsdc->atoms);
|
||||
jsdc->atoms = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
JSDAtom*
|
||||
jsd_AddAtom(JSDContext* jsdc, const char* str)
|
||||
{
|
||||
JSDAtom* atom;
|
||||
|
||||
if(!str)
|
||||
{
|
||||
JS_ASSERT(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JSD_LOCK_ATOMS(jsdc);
|
||||
|
||||
atom = (JSDAtom*) JS_HashTableLookup(jsdc->atoms, str);
|
||||
|
||||
if( atom )
|
||||
atom->refcount++;
|
||||
else
|
||||
{
|
||||
atom = (JSDAtom*) malloc(sizeof(JSDAtom));
|
||||
if( atom )
|
||||
{
|
||||
atom->str = strdup(str);
|
||||
atom->refcount = 1;
|
||||
if(!JS_HashTableAdd(jsdc->atoms, atom->str, atom))
|
||||
{
|
||||
free(atom->str);
|
||||
free(atom);
|
||||
atom = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSD_UNLOCK_ATOMS(jsdc);
|
||||
return atom;
|
||||
}
|
||||
|
||||
JSDAtom*
|
||||
jsd_CloneAtom(JSDContext* jsdc, JSDAtom* atom)
|
||||
{
|
||||
JSD_LOCK_ATOMS(jsdc);
|
||||
atom->refcount++;
|
||||
JSD_UNLOCK_ATOMS(jsdc);
|
||||
return atom;
|
||||
}
|
||||
|
||||
void
|
||||
jsd_DropAtom(JSDContext* jsdc, JSDAtom* atom)
|
||||
{
|
||||
JSD_LOCK_ATOMS(jsdc);
|
||||
if(! --atom->refcount)
|
||||
{
|
||||
JS_HashTableRemove(jsdc->atoms, atom->str);
|
||||
free(atom->str);
|
||||
free(atom);
|
||||
}
|
||||
JSD_UNLOCK_ATOMS(jsdc);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
/* -*- 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.0 (the "NPL"); you may not use this file except in
|
||||
@ -17,39 +17,38 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
** JavaScript Debugger Navigator API - 'High Level' functions
|
||||
*/
|
||||
* JavaScript Debugging support - 'High Level' functions
|
||||
*/
|
||||
|
||||
#include "jsd.h"
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
/* use a global context for now (avoid direct references to it!) */
|
||||
static JSDContext _static_context;
|
||||
|
||||
/* these are global now, they transcend our concept of JSDContext...*/
|
||||
/* XXX not 'static' because of old Mac CodeWarrior bug */
|
||||
JSCList _jsd_context_list = JS_INIT_STATIC_CLIST(&_jsd_context_list);
|
||||
|
||||
/* these are used to connect JSD_SetUserCallbacks() with JSD_DebuggerOn() */
|
||||
static JSD_UserCallbacks _callbacks;
|
||||
static void* _user;
|
||||
static JSTaskState* _jstaskstate;
|
||||
static PRThread * _dangerousThread1;
|
||||
static void* _user = NULL;
|
||||
static JSRuntime* _jsrt = NULL;
|
||||
|
||||
#ifdef DEBUG
|
||||
void JSD_ASSERT_VALID_CONTEXT( JSDContext* jsdc )
|
||||
{
|
||||
PR_ASSERT( jsdc == &_static_context );
|
||||
PR_ASSERT( jsdc->inited );
|
||||
PR_ASSERT( jsdc->jstaskstate );
|
||||
PR_ASSERT( jsdc->jscontexts );
|
||||
}
|
||||
#ifdef JSD_HAS_DANGEROUS_THREAD
|
||||
static void* _dangerousThread = NULL;
|
||||
#endif
|
||||
|
||||
static PRHashNumber
|
||||
_hash_root(const void *key)
|
||||
#ifdef JSD_THREADSAFE
|
||||
void* _jsd_global_lock = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
void JSD_ASSERT_VALID_CONTEXT(JSDContext* jsdc)
|
||||
{
|
||||
PRHashNumber num = (PRHashNumber) key;
|
||||
return num >> 2;
|
||||
JS_ASSERT(jsdc->inited);
|
||||
JS_ASSERT(jsdc->jsrt);
|
||||
JS_ASSERT(jsdc->dumbContext);
|
||||
JS_ASSERT(jsdc->glob);
|
||||
}
|
||||
#endif
|
||||
|
||||
static JSClass global_class = {
|
||||
"JSDGlobal", 0,
|
||||
@ -57,242 +56,293 @@ static JSClass global_class = {
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
};
|
||||
|
||||
static JSDContext*
|
||||
NewJSDContext(void)
|
||||
static JSBool
|
||||
_validateUserCallbacks(JSD_UserCallbacks* callbacks)
|
||||
{
|
||||
JSDContext* jsdc = &_static_context;
|
||||
return !callbacks ||
|
||||
(callbacks->size && callbacks->size <= sizeof(JSD_UserCallbacks));
|
||||
}
|
||||
|
||||
static JSDContext*
|
||||
_newJSDContext(JSRuntime* jsrt,
|
||||
JSD_UserCallbacks* callbacks,
|
||||
void* user)
|
||||
{
|
||||
JSDContext* jsdc = NULL;
|
||||
|
||||
if( ! jsrt )
|
||||
return NULL;
|
||||
|
||||
if( ! _validateUserCallbacks(callbacks) )
|
||||
return NULL;
|
||||
|
||||
jsdc = (JSDContext*) calloc(1, sizeof(JSDContext));
|
||||
if( ! jsdc )
|
||||
goto label_newJSDContext_failure;
|
||||
|
||||
if( ! JSD_INIT_LOCKS(jsdc) )
|
||||
goto label_newJSDContext_failure;
|
||||
|
||||
JS_INIT_CLIST(&jsdc->links);
|
||||
|
||||
jsdc->jsrt = jsrt;
|
||||
|
||||
if( callbacks )
|
||||
memcpy(&jsdc->userCallbacks, callbacks, callbacks->size);
|
||||
|
||||
if( jsdc->inited )
|
||||
return NULL;
|
||||
jsdc->user = user;
|
||||
|
||||
if( ! _jstaskstate )
|
||||
return NULL;
|
||||
#ifdef JSD_HAS_DANGEROUS_THREAD
|
||||
jsdc->dangerousThread = _dangerousThread;
|
||||
#endif
|
||||
|
||||
memset( jsdc, 0, sizeof(JSDContext) );
|
||||
jsdc->jstaskstate = _jstaskstate;
|
||||
JS_INIT_CLIST(&jsdc->threadsStates);
|
||||
JS_INIT_CLIST(&jsdc->scripts);
|
||||
JS_INIT_CLIST(&jsdc->sources);
|
||||
JS_INIT_CLIST(&jsdc->removedSources);
|
||||
|
||||
PR_INIT_CLIST(&jsdc->threadsStates);
|
||||
jsdc->sourceAlterCount = 1;
|
||||
|
||||
jsdc->dumbContext = JS_NewContext( _jstaskstate, 256 );
|
||||
if( ! jsd_CreateAtomTable(jsdc) )
|
||||
goto label_newJSDContext_failure;
|
||||
|
||||
if( ! jsd_InitObjectManager(jsdc) )
|
||||
goto label_newJSDContext_failure;
|
||||
|
||||
jsdc->dumbContext = JS_NewContext(jsdc->jsrt, 256);
|
||||
if( ! jsdc->dumbContext )
|
||||
return NULL;
|
||||
goto label_newJSDContext_failure;
|
||||
|
||||
jsdc->glob = JS_NewObject(jsdc->dumbContext, &global_class, NULL, NULL);
|
||||
if( ! jsdc->glob )
|
||||
return NULL;
|
||||
goto label_newJSDContext_failure;
|
||||
|
||||
if( ! JS_InitStandardClasses(jsdc->dumbContext, jsdc->glob) )
|
||||
return NULL;
|
||||
|
||||
jsdc->jscontexts = PR_NewHashTable(256, _hash_root,
|
||||
PR_CompareValues, PR_CompareValues,
|
||||
NULL, NULL);
|
||||
if( ! jsdc->jscontexts )
|
||||
return NULL;
|
||||
goto label_newJSDContext_failure;
|
||||
|
||||
jsdc->inited = JS_TRUE;
|
||||
return jsdc;
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(PRIntn)
|
||||
_hash_entry_zapper(PRHashEntry *he, PRIntn i, void *arg)
|
||||
{
|
||||
PR_FREEIF(he->value);
|
||||
he->value = NULL;
|
||||
he->key = NULL;
|
||||
return HT_ENUMERATE_NEXT;
|
||||
JSD_LOCK();
|
||||
JS_INSERT_LINK(&jsdc->links, &_jsd_context_list);
|
||||
JSD_UNLOCK();
|
||||
|
||||
return jsdc;
|
||||
|
||||
label_newJSDContext_failure:
|
||||
jsd_DestroyObjectManager(jsdc);
|
||||
jsd_DestroyAtomTable(jsdc);
|
||||
if( jsdc )
|
||||
free(jsdc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
DestroyJSDContext( JSDContext* jsdc )
|
||||
_destroyJSDContext(JSDContext* jsdc)
|
||||
{
|
||||
JSD_ASSERT_VALID_CONTEXT(jsdc);
|
||||
if( jsdc->jscontexts )
|
||||
{
|
||||
PR_HashTableEnumerateEntries(jsdc->jscontexts, _hash_entry_zapper, NULL);
|
||||
PR_HashTableDestroy(jsdc->jscontexts);
|
||||
}
|
||||
jsdc->inited = JS_FALSE;
|
||||
}
|
||||
|
||||
JSDContext*
|
||||
jsd_GetDefaultJSDContext(void)
|
||||
{
|
||||
JSDContext* jsdc = &_static_context;
|
||||
if( ! jsdc->inited )
|
||||
return NULL;
|
||||
return jsdc;
|
||||
JSD_LOCK();
|
||||
JS_REMOVE_LINK(&jsdc->links);
|
||||
JSD_UNLOCK();
|
||||
|
||||
jsd_DestroyObjectManager(jsdc);
|
||||
jsd_DestroyAtomTable(jsdc);
|
||||
|
||||
jsdc->inited = JS_FALSE;
|
||||
|
||||
/*
|
||||
* We should free jsdc here, but we let it leak in case there are any
|
||||
* asynchronous hooks calling into the system using it as a handle
|
||||
*
|
||||
* XXX we also leak the locks
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
JSDContext*
|
||||
jsd_DebuggerOnForUser(JSRuntime* jsrt,
|
||||
JSD_UserCallbacks* callbacks,
|
||||
void* user)
|
||||
{
|
||||
JSDContext* jsdc;
|
||||
JSContext* iter = NULL;
|
||||
|
||||
jsdc = _newJSDContext(jsrt, callbacks, user);
|
||||
if( ! jsdc )
|
||||
return NULL;
|
||||
|
||||
/* set hooks here */
|
||||
JS_SetNewScriptHookProc(jsdc->jsrt, jsd_NewScriptHookProc, jsdc);
|
||||
JS_SetDestroyScriptHookProc(jsdc->jsrt, jsd_DestroyScriptHookProc, jsdc);
|
||||
JS_SetDebuggerHandler(jsdc->jsrt, jsd_DebuggerHandler, jsdc);
|
||||
JS_SetExecuteHook(jsdc->jsrt, jsd_InterpreterHook, jsdc);
|
||||
JS_SetCallHook(jsdc->jsrt, jsd_InterpreterHook, jsdc);
|
||||
JS_SetObjectHook(jsdc->jsrt, jsd_ObjectHook, jsdc);
|
||||
JS_SetThrowHook(jsdc->jsrt, jsd_ThrowHandler, jsdc);
|
||||
JS_SetDebugErrorHook(jsdc->jsrt, jsd_DebugErrorHook, jsdc);
|
||||
#ifdef LIVEWIRE
|
||||
LWDBG_SetNewScriptHookProc(jsd_NewScriptHookProc, jsdc);
|
||||
#endif
|
||||
if( jsdc->userCallbacks.setContext )
|
||||
jsdc->userCallbacks.setContext(jsdc, jsdc->user);
|
||||
return jsdc;
|
||||
}
|
||||
|
||||
JSDContext*
|
||||
jsd_DebuggerOn(void)
|
||||
{
|
||||
JSDContext* jsdc = NewJSDContext();
|
||||
JSContext* iter = NULL;
|
||||
JSContext* cx;
|
||||
|
||||
if( ! jsdc )
|
||||
return NULL;
|
||||
|
||||
/* set hooks here */
|
||||
JS_SetNewScriptHookProc( jsdc->jstaskstate, jsd_NewScriptHookProc, jsdc );
|
||||
JS_SetDestroyScriptHookProc( jsdc->jstaskstate, jsd_DestroyScriptHookProc, jsdc );
|
||||
|
||||
/* enumerate contexts for JSTaskState and add them to our table */
|
||||
while( NULL != (cx = JS_ContextIterator(jsdc->jstaskstate, &iter)) )
|
||||
jsd_JSContextUsed( jsdc, cx );
|
||||
|
||||
if( _callbacks.setContext )
|
||||
_callbacks.setContext( jsdc, _user );
|
||||
|
||||
return jsdc;
|
||||
JS_ASSERT(_jsrt);
|
||||
JS_ASSERT(_validateUserCallbacks(&_callbacks));
|
||||
return jsd_DebuggerOnForUser(_jsrt, &_callbacks, _user);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
jsd_DebuggerOff(JSDContext* jsdc)
|
||||
{
|
||||
/* clear hooks here */
|
||||
JS_SetNewScriptHookProc( jsdc->jstaskstate, NULL, NULL );
|
||||
JS_SetDestroyScriptHookProc( jsdc->jstaskstate, NULL, NULL );
|
||||
JS_SetNewScriptHookProc(jsdc->jsrt, NULL, NULL);
|
||||
JS_SetDestroyScriptHookProc(jsdc->jsrt, NULL, NULL);
|
||||
JS_SetDebuggerHandler(jsdc->jsrt, NULL, NULL);
|
||||
JS_SetExecuteHook(jsdc->jsrt, NULL, NULL);
|
||||
JS_SetCallHook(jsdc->jsrt, NULL, NULL);
|
||||
JS_SetObjectHook(jsdc->jsrt, NULL, NULL);
|
||||
JS_SetThrowHook(jsdc->jsrt, NULL, NULL);
|
||||
JS_SetDebugErrorHook(jsdc->jsrt, NULL, NULL);
|
||||
#ifdef LIVEWIRE
|
||||
LWDBG_SetNewScriptHookProc(NULL,NULL);
|
||||
#endif
|
||||
|
||||
/* clean up */
|
||||
jsd_DestroyAllJSDScripts( jsdc );
|
||||
jsd_DestroyAllSources( jsdc );
|
||||
jsd_DestroyAllJSDScripts(jsdc);
|
||||
jsd_DestroyAllSources(jsdc);
|
||||
|
||||
DestroyJSDContext( jsdc );
|
||||
_destroyJSDContext(jsdc);
|
||||
|
||||
if( _callbacks.setContext )
|
||||
_callbacks.setContext( NULL, _user );
|
||||
if( jsdc->userCallbacks.setContext )
|
||||
jsdc->userCallbacks.setContext(NULL, jsdc->user);
|
||||
}
|
||||
|
||||
void
|
||||
jsd_SetUserCallbacks(JSTaskState* jstaskstate, JSD_UserCallbacks* callbacks, void* user)
|
||||
jsd_SetUserCallbacks(JSRuntime* jsrt, JSD_UserCallbacks* callbacks, void* user)
|
||||
{
|
||||
_jstaskstate = jstaskstate;
|
||||
_jsrt = jsrt;
|
||||
_user = user;
|
||||
_dangerousThread1 = PR_CurrentThread();
|
||||
|
||||
#ifdef JSD_HAS_DANGEROUS_THREAD
|
||||
_dangerousThread = JSD_CURRENT_THREAD();
|
||||
#endif
|
||||
|
||||
if( callbacks )
|
||||
memcpy( &_callbacks, callbacks, sizeof(JSD_UserCallbacks) );
|
||||
memcpy(&_callbacks, callbacks, sizeof(JSD_UserCallbacks));
|
||||
else
|
||||
memset( &_callbacks, 0 , sizeof(JSD_UserCallbacks) );
|
||||
|
||||
if( _callbacks.setContext && _static_context.inited )
|
||||
_callbacks.setContext( &_static_context, _user );
|
||||
memset(&_callbacks, 0 , sizeof(JSD_UserCallbacks));
|
||||
}
|
||||
|
||||
JSDContextWrapper*
|
||||
jsd_JSDContextWrapperForJSContext( JSDContext* jsdc, JSContext* context )
|
||||
JSDContext*
|
||||
jsd_JSDContextForJSContext(JSContext* context)
|
||||
{
|
||||
return (JSDContextWrapper*) PR_HashTableLookup(jsdc->jscontexts, context);
|
||||
}
|
||||
JSDContext* iter;
|
||||
JSDContext* jsdc = NULL;
|
||||
JSRuntime* runtime = JS_GetRuntime(context);
|
||||
|
||||
PR_STATIC_CALLBACK(void)
|
||||
jsd_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
|
||||
JSD_LOCK();
|
||||
for( iter = (JSDContext*)_jsd_context_list.next;
|
||||
iter != (JSDContext*)&_jsd_context_list;
|
||||
iter = (JSDContext*)iter->links.next )
|
||||
{
|
||||
if( runtime == iter->jsrt )
|
||||
{
|
||||
jsdc = iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
JSD_UNLOCK();
|
||||
return jsdc;
|
||||
}
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(JSBool)
|
||||
jsd_DebugErrorHook(JSContext *cx, const char *message,
|
||||
JSErrorReport *report, void *closure)
|
||||
{
|
||||
JSDContextWrapper* wrapper;
|
||||
JSDContext* jsdc;
|
||||
PRUintn action = JSD_ERROR_REPORTER_PASS_ALONG;
|
||||
|
||||
jsdc = jsd_GetDefaultJSDContext();
|
||||
JSDContext* jsdc = (JSDContext*) closure;
|
||||
JSD_ErrorReporter errorReporter;
|
||||
void* errorReporterData;
|
||||
|
||||
if( ! jsdc )
|
||||
{
|
||||
PR_ASSERT(0);
|
||||
return;
|
||||
JS_ASSERT(0);
|
||||
return JS_TRUE;
|
||||
}
|
||||
if( JSD_IS_DANGEROUS_THREAD(jsdc) )
|
||||
return JS_TRUE;
|
||||
|
||||
wrapper = jsd_JSDContextWrapperForJSContext( jsdc, cx );
|
||||
if( ! wrapper )
|
||||
{
|
||||
PR_ASSERT(0);
|
||||
return;
|
||||
}
|
||||
/* local in case hook gets cleared on another thread */
|
||||
JSD_LOCK();
|
||||
errorReporter = jsdc->errorReporter;
|
||||
errorReporterData = jsdc->errorReporterData;
|
||||
JSD_UNLOCK();
|
||||
|
||||
if( jsdc->errorReporter && ! jsd_IsCurrentThreadDangerous() )
|
||||
action = jsdc->errorReporter(jsdc, cx, message, report,
|
||||
jsdc->errorReporterData);
|
||||
if(!errorReporter)
|
||||
return JS_TRUE;
|
||||
|
||||
switch(action)
|
||||
switch(errorReporter(jsdc, cx, message, report, errorReporterData))
|
||||
{
|
||||
case JSD_ERROR_REPORTER_PASS_ALONG:
|
||||
if( wrapper->originalErrorReporter )
|
||||
wrapper->originalErrorReporter(cx, message, report);
|
||||
break;
|
||||
case JSD_ERROR_REPORTER_RETURN:
|
||||
break;
|
||||
return JS_TRUE;
|
||||
case JSD_ERROR_REPORTER_RETURN:
|
||||
return JS_FALSE;
|
||||
case JSD_ERROR_REPORTER_DEBUG:
|
||||
{
|
||||
JSDThreadState* jsdthreadstate;
|
||||
jsval rval;
|
||||
JSD_ExecutionHookProc hook;
|
||||
void* hookData;
|
||||
|
||||
if( ! jsdc->debugBreakHook )
|
||||
return;
|
||||
/* local in case hook gets cleared on another thread */
|
||||
JSD_LOCK();
|
||||
hook = jsdc->debugBreakHook;
|
||||
hookData = jsdc->debugBreakHookData;
|
||||
JSD_UNLOCK();
|
||||
|
||||
jsdthreadstate = jsd_NewThreadState(jsdc,cx);
|
||||
if( jsdthreadstate )
|
||||
{
|
||||
(*jsdc->debugBreakHook)(jsdc, jsdthreadstate,
|
||||
JSD_HOOK_DEBUG_REQUESTED,
|
||||
jsdc->debugBreakHookData );
|
||||
|
||||
jsd_DestroyThreadState(jsdc, jsdthreadstate);
|
||||
}
|
||||
jsd_CallExecutionHook(jsdc, cx, JSD_HOOK_DEBUG_REQUESTED,
|
||||
hook, hookData, &rval);
|
||||
/* XXX Should make this dependent on ExecutionHook retval */
|
||||
return JS_TRUE;
|
||||
}
|
||||
default:;
|
||||
case JSD_ERROR_REPORTER_CLEAR_RETURN:
|
||||
if(report && JSREPORT_IS_EXCEPTION(report->flags))
|
||||
JS_ClearPendingException(cx);
|
||||
return JS_FALSE;
|
||||
default:
|
||||
JS_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
jsd_JSContextUsed( JSDContext* jsdc, JSContext* context )
|
||||
{
|
||||
JSDContextWrapper* wrapper;
|
||||
|
||||
wrapper = jsd_JSDContextWrapperForJSContext(jsdc, context);
|
||||
if( wrapper )
|
||||
{
|
||||
/* error reporters are sometimes overwritten by other code... */
|
||||
JSErrorReporter oldrep = JS_SetErrorReporter(context, jsd_ErrorReporter);
|
||||
if( jsd_ErrorReporter != oldrep )
|
||||
wrapper->originalErrorReporter = oldrep;
|
||||
return;
|
||||
}
|
||||
|
||||
/* else... */
|
||||
wrapper = PR_NEWZAP(JSDContextWrapper);
|
||||
if( ! wrapper )
|
||||
return;
|
||||
|
||||
if( ! PR_HashTableAdd(jsdc->jscontexts, context, wrapper ) )
|
||||
{
|
||||
PR_FREEIF(wrapper);
|
||||
return;
|
||||
}
|
||||
|
||||
wrapper->context = context;
|
||||
wrapper->jsdc = jsdc;
|
||||
|
||||
/* add our error reporter */
|
||||
wrapper->originalErrorReporter = JS_SetErrorReporter(context, jsd_ErrorReporter);
|
||||
|
||||
/* add our printer */
|
||||
/* add our loader */
|
||||
}
|
||||
|
||||
JSD_ErrorReporter
|
||||
jsd_SetErrorReporter( JSDContext* jsdc, JSD_ErrorReporter reporter, void* callerdata)
|
||||
{
|
||||
JSD_ErrorReporter old = jsdc->errorReporter;
|
||||
|
||||
jsdc->errorReporter = reporter;
|
||||
jsdc->errorReporterData = callerdata;
|
||||
return old;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_IsCurrentThreadDangerous()
|
||||
jsd_SetErrorReporter(JSDContext* jsdc,
|
||||
JSD_ErrorReporter reporter,
|
||||
void* callerdata)
|
||||
{
|
||||
return PR_CurrentThread() == _dangerousThread1;
|
||||
JSD_LOCK();
|
||||
jsdc->errorReporter = reporter;
|
||||
jsdc->errorReporterData = callerdata;
|
||||
JSD_UNLOCK();
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_GetErrorReporter(JSDContext* jsdc,
|
||||
JSD_ErrorReporter* reporter,
|
||||
void** callerdata)
|
||||
{
|
||||
JSD_LOCK();
|
||||
if( reporter )
|
||||
*reporter = jsdc->errorReporter;
|
||||
if( callerdata )
|
||||
*callerdata = jsdc->errorReporterData;
|
||||
JSD_UNLOCK();
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
/* -*- 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.0 (the "NPL"); you may not use this file except in
|
||||
@ -17,85 +17,244 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
** JavaScript Debugger Navigator API - Hook support
|
||||
*/
|
||||
* JavaScript Debugging support - Hook support
|
||||
*/
|
||||
|
||||
#include "jsd.h"
|
||||
|
||||
JSTrapStatus PR_CALLBACK
|
||||
JSTrapStatus JS_DLL_CALLBACK
|
||||
jsd_InterruptHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval,
|
||||
void *closure)
|
||||
{
|
||||
PRUintn hookanswer = JSD_HOOK_RETURN_CONTINUE;
|
||||
JSDThreadState* jsdthreadstate;
|
||||
JSDScript* jsdscript;
|
||||
JSDContext* jsdc = (JSDContext*) closure;
|
||||
|
||||
if( jsd_IsCurrentThreadDangerous() )
|
||||
return JSTRAP_CONTINUE;
|
||||
JSD_ExecutionHookProc hook;
|
||||
void* hookData;
|
||||
|
||||
if( ! jsdc || ! jsdc->inited )
|
||||
return JSTRAP_CONTINUE;
|
||||
|
||||
jsd_JSContextUsed(jsdc, cx);
|
||||
|
||||
if( ! jsdc->interruptHook )
|
||||
|
||||
if( JSD_IS_DANGEROUS_THREAD(jsdc) )
|
||||
return JSTRAP_CONTINUE;
|
||||
|
||||
JSD_LOCK_SCRIPTS(jsdc);
|
||||
jsdscript = jsd_FindJSDScript(jsdc, script);
|
||||
JSD_UNLOCK_SCRIPTS(jsdc);
|
||||
if( ! jsdscript )
|
||||
return JSTRAP_CONTINUE;
|
||||
|
||||
jsdthreadstate = jsd_NewThreadState(jsdc,cx);
|
||||
if( jsdthreadstate )
|
||||
{
|
||||
hookanswer =
|
||||
(*jsdc->interruptHook)(jsdc, jsdthreadstate,
|
||||
JSD_HOOK_INTERRUPTED,
|
||||
jsdc->interruptHookData );
|
||||
#ifdef LIVEWIRE
|
||||
if( ! jsdlw_UserCodeAtPC(jsdc, jsdscript, (jsuword)pc) )
|
||||
return JSTRAP_CONTINUE;
|
||||
#endif
|
||||
|
||||
/* local in case jsdc->interruptHook gets cleared on another thread */
|
||||
JSD_LOCK();
|
||||
hook = jsdc->interruptHook;
|
||||
hookData = jsdc->interruptHookData;
|
||||
JSD_UNLOCK();
|
||||
|
||||
return jsd_CallExecutionHook(jsdc, cx, JSD_HOOK_INTERRUPTED,
|
||||
hook, hookData, rval);
|
||||
}
|
||||
|
||||
JSTrapStatus JS_DLL_CALLBACK
|
||||
jsd_DebuggerHandler(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
jsval *rval, void *closure)
|
||||
{
|
||||
JSDScript* jsdscript;
|
||||
JSDContext* jsdc = (JSDContext*) closure;
|
||||
JSD_ExecutionHookProc hook;
|
||||
void* hookData;
|
||||
|
||||
if( ! jsdc || ! jsdc->inited )
|
||||
return JSTRAP_CONTINUE;
|
||||
|
||||
if( JSD_IS_DANGEROUS_THREAD(jsdc) )
|
||||
return JSTRAP_CONTINUE;
|
||||
|
||||
JSD_LOCK_SCRIPTS(jsdc);
|
||||
jsdscript = jsd_FindJSDScript(jsdc, script);
|
||||
JSD_UNLOCK_SCRIPTS(jsdc);
|
||||
if( ! jsdscript )
|
||||
return JSTRAP_CONTINUE;
|
||||
|
||||
/* local in case jsdc->debuggerHook gets cleared on another thread */
|
||||
JSD_LOCK();
|
||||
hook = jsdc->debuggerHook;
|
||||
hookData = jsdc->debuggerHookData;
|
||||
JSD_UNLOCK();
|
||||
|
||||
return jsd_CallExecutionHook(jsdc, cx, JSD_HOOK_DEBUGGER_KEYWORD,
|
||||
hook, hookData, rval);
|
||||
}
|
||||
|
||||
|
||||
JSTrapStatus JS_DLL_CALLBACK
|
||||
jsd_ThrowHandler(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
jsval *rval, void *closure)
|
||||
{
|
||||
JSDScript* jsdscript;
|
||||
JSDContext* jsdc = (JSDContext*) closure;
|
||||
JSD_ExecutionHookProc hook;
|
||||
void* hookData;
|
||||
|
||||
JS_GetPendingException(cx, rval);
|
||||
|
||||
if( ! jsdc || ! jsdc->inited )
|
||||
return JSD_HOOK_RETURN_CONTINUE_THROW;
|
||||
|
||||
if( JSD_IS_DANGEROUS_THREAD(jsdc) )
|
||||
return JSD_HOOK_RETURN_CONTINUE_THROW;
|
||||
|
||||
JSD_LOCK_SCRIPTS(jsdc);
|
||||
jsdscript = jsd_FindJSDScript(jsdc, script);
|
||||
JSD_UNLOCK_SCRIPTS(jsdc);
|
||||
if( ! jsdscript )
|
||||
return JSD_HOOK_RETURN_CONTINUE_THROW;
|
||||
|
||||
/* local in case jsdc->throwHook gets cleared on another thread */
|
||||
JSD_LOCK();
|
||||
hook = jsdc->throwHook;
|
||||
hookData = jsdc->throwHookData;
|
||||
JSD_UNLOCK();
|
||||
|
||||
return jsd_CallExecutionHook(jsdc, cx, JSD_HOOK_THROW,
|
||||
hook, hookData, rval);
|
||||
}
|
||||
|
||||
JSTrapStatus
|
||||
jsd_CallExecutionHook(JSDContext* jsdc,
|
||||
JSContext *cx,
|
||||
uintN type,
|
||||
JSD_ExecutionHookProc hook,
|
||||
void* hookData,
|
||||
jsval* rval)
|
||||
{
|
||||
uintN hookanswer = JSD_HOOK_THROW == type ?
|
||||
JSD_HOOK_RETURN_CONTINUE_THROW :
|
||||
JSD_HOOK_RETURN_CONTINUE;
|
||||
JSDThreadState* jsdthreadstate;
|
||||
|
||||
if(hook && NULL != (jsdthreadstate = jsd_NewThreadState(jsdc,cx)))
|
||||
{
|
||||
hookanswer = hook(jsdc, jsdthreadstate, type, hookData, rval);
|
||||
jsd_DestroyThreadState(jsdc, jsdthreadstate);
|
||||
}
|
||||
|
||||
*rval = NULL; /* XXX fix this!!! */
|
||||
|
||||
if( JSD_HOOK_RETURN_ABORT == hookanswer )
|
||||
return JSTRAP_ERROR;
|
||||
|
||||
return JSTRAP_CONTINUE; /* XXX fix this!!! */
|
||||
switch(hookanswer)
|
||||
{
|
||||
case JSD_HOOK_RETURN_ABORT:
|
||||
case JSD_HOOK_RETURN_HOOK_ERROR:
|
||||
return JSTRAP_ERROR;
|
||||
case JSD_HOOK_RETURN_RET_WITH_VAL:
|
||||
return JSTRAP_RETURN;
|
||||
case JSD_HOOK_RETURN_THROW_WITH_VAL:
|
||||
return JSTRAP_THROW;
|
||||
case JSD_HOOK_RETURN_CONTINUE:
|
||||
break;
|
||||
case JSD_HOOK_RETURN_CONTINUE_THROW:
|
||||
/* only makes sense for jsd_ThrowHandler (which init'd rval) */
|
||||
JS_ASSERT(JSD_HOOK_THROW == type);
|
||||
return JSTRAP_THROW;
|
||||
default:
|
||||
JS_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
return JSTRAP_CONTINUE;
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_SetInterruptHook(JSDContext* jsdc,
|
||||
jsd_SetInterruptHook(JSDContext* jsdc,
|
||||
JSD_ExecutionHookProc hook,
|
||||
void* callerdata)
|
||||
{
|
||||
jsdc->interruptHook = hook;
|
||||
JSD_LOCK();
|
||||
jsdc->interruptHookData = callerdata;
|
||||
jsdc->interruptHook = hook;
|
||||
JS_SetInterrupt(jsdc->jsrt, jsd_InterruptHandler, (void*) jsdc);
|
||||
JSD_UNLOCK();
|
||||
|
||||
return JS_SetInterrupt(jsdc->jstaskstate, jsd_InterruptHandler, (void*) jsdc);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_ClearInterruptHook(JSDContext* jsdc)
|
||||
jsd_ClearInterruptHook(JSDContext* jsdc)
|
||||
{
|
||||
JSD_LOCK();
|
||||
JS_ClearInterrupt(jsdc->jsrt, NULL, NULL );
|
||||
jsdc->interruptHook = NULL;
|
||||
return JS_ClearInterrupt(jsdc->jstaskstate, NULL, NULL );
|
||||
JSD_UNLOCK();
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_SetDebugBreakHook(JSDContext* jsdc,
|
||||
jsd_SetDebugBreakHook(JSDContext* jsdc,
|
||||
JSD_ExecutionHookProc hook,
|
||||
void* callerdata)
|
||||
{
|
||||
jsdc->debugBreakHook = hook;
|
||||
JSD_LOCK();
|
||||
jsdc->debugBreakHookData = callerdata;
|
||||
jsdc->debugBreakHook = hook;
|
||||
JSD_UNLOCK();
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_ClearDebugBreakHook(JSDContext* jsdc)
|
||||
jsd_ClearDebugBreakHook(JSDContext* jsdc)
|
||||
{
|
||||
JSD_LOCK();
|
||||
jsdc->debugBreakHook = NULL;
|
||||
JSD_UNLOCK();
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_SetDebuggerHook(JSDContext* jsdc,
|
||||
JSD_ExecutionHookProc hook,
|
||||
void* callerdata)
|
||||
{
|
||||
JSD_LOCK();
|
||||
jsdc->debuggerHookData = callerdata;
|
||||
jsdc->debuggerHook = hook;
|
||||
JSD_UNLOCK();
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_ClearDebuggerHook(JSDContext* jsdc)
|
||||
{
|
||||
JSD_LOCK();
|
||||
jsdc->debuggerHook = NULL;
|
||||
JSD_UNLOCK();
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_SetThrowHook(JSDContext* jsdc,
|
||||
JSD_ExecutionHookProc hook,
|
||||
void* callerdata)
|
||||
{
|
||||
JSD_LOCK();
|
||||
jsdc->throwHookData = callerdata;
|
||||
jsdc->throwHook = hook;
|
||||
JSD_UNLOCK();
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_ClearThrowHook(JSDContext* jsdc)
|
||||
{
|
||||
JSD_LOCK();
|
||||
jsdc->throwHook = NULL;
|
||||
JSD_UNLOCK();
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,10 @@
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/* this is all going away... replaced by code in js/jsd/java */
|
||||
|
||||
#if 0
|
||||
|
||||
#include "native.h"
|
||||
#include "jsdebug.h"
|
||||
|
||||
@ -794,4 +798,4 @@ void netscape_jsdebug_JSSourceTextProvider_refreshSourceTextVector(struct Hnetsc
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
/* -*- 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.0 (the "NPL"); you may not use this file except in
|
||||
@ -17,8 +17,220 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* 2/17/98 jband
|
||||
* This is a temporary placeholder for this file
|
||||
* to supporet adding this file to existing makefiles before
|
||||
* the real file is pulled in off of a branch
|
||||
*/
|
||||
* JavaScript Debugging support - Locking and threading support
|
||||
*/
|
||||
|
||||
/*
|
||||
* ifdef JSD_USE_NSPR_LOCKS then you musat build and run against NSPR2.
|
||||
* Otherwise, there are stubs that can be filled in with your own locking
|
||||
* code. Also, note that these stubs include a jsd_CurrentThread()
|
||||
* implementation that only works on Win32 - this is needed for the inprocess
|
||||
* Java-based debugger.
|
||||
*/
|
||||
|
||||
#include "jsd.h"
|
||||
|
||||
#ifdef JSD_THREADSAFE
|
||||
|
||||
#ifdef JSD_USE_NSPR_LOCKS
|
||||
|
||||
#include "prlock.h"
|
||||
#include "prthread.h"
|
||||
|
||||
#ifdef JSD_ATTACH_THREAD_HACK
|
||||
#include "pprthred.h" /* need this as long as JS_AttachThread is needed */
|
||||
#endif
|
||||
|
||||
typedef struct JSDStaticLock
|
||||
{
|
||||
void* owner;
|
||||
PRLock* lock;
|
||||
int count;
|
||||
#ifdef DEBUG
|
||||
uint16 sig;
|
||||
#endif
|
||||
} JSDStaticLock;
|
||||
|
||||
/*
|
||||
* This exists to wrap non-NSPR theads (e.g. Java threads) in NSPR wrappers.
|
||||
* XXX We ignore the memory leak issue.
|
||||
* It is claimed that future versions of NSPR will automatically wrap on
|
||||
* the call to PR_GetCurrentThread.
|
||||
*
|
||||
* XXX We ignore the memory leak issue - i.e. we never call PR_DetachThread.
|
||||
*
|
||||
*/
|
||||
#undef _CURRENT_THREAD
|
||||
#ifdef JSD_ATTACH_THREAD_HACK
|
||||
#define _CURRENT_THREAD(out) \
|
||||
JS_BEGIN_MACRO \
|
||||
out = (void*) PR_GetCurrentThread(); \
|
||||
if(!out) \
|
||||
out = (void*) JS_AttachThread(PR_USER_THREAD,PR_PRIORITY_NORMAL,NULL);\
|
||||
JS_ASSERT(out); \
|
||||
JS_END_MACRO
|
||||
#else
|
||||
#define _CURRENT_THREAD(out) \
|
||||
JS_BEGIN_MACRO \
|
||||
out = (void*) PR_GetCurrentThread(); \
|
||||
JS_ASSERT(out); \
|
||||
JS_END_MACRO
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#define JSD_LOCK_SIG 0x10CC10CC
|
||||
void ASSERT_VALID_LOCK(JSDStaticLock* lock)
|
||||
{
|
||||
JS_ASSERT(lock);
|
||||
JS_ASSERT(lock->lock);
|
||||
JS_ASSERT(lock->count >= 0);
|
||||
JS_ASSERT((! lock->count && ! lock->owner) || (lock->count && lock->owner));
|
||||
JS_ASSERT(lock->sig == (uint16) JSD_LOCK_SIG);
|
||||
}
|
||||
#else
|
||||
#define ASSERT_VALID_LOCK(x) ((void)0)
|
||||
#endif
|
||||
|
||||
void*
|
||||
jsd_CreateLock()
|
||||
{
|
||||
JSDStaticLock* lock;
|
||||
|
||||
if( ! (lock = calloc(1, sizeof(JSDStaticLock))) ||
|
||||
! (lock->lock = PR_NewLock()) )
|
||||
{
|
||||
if(lock)
|
||||
{
|
||||
free(lock);
|
||||
lock = NULL;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if(lock) lock->sig = (uint16) JSD_LOCK_SIG;
|
||||
#endif
|
||||
return lock;
|
||||
}
|
||||
|
||||
void
|
||||
jsd_Lock(JSDStaticLock* lock)
|
||||
{
|
||||
void* me;
|
||||
|
||||
_CURRENT_THREAD(me);
|
||||
|
||||
ASSERT_VALID_LOCK(lock);
|
||||
|
||||
if(lock->owner == me)
|
||||
lock->count++;
|
||||
else
|
||||
{
|
||||
PR_Lock(lock->lock); /* this can block... */
|
||||
JS_ASSERT(lock->owner == 0);
|
||||
lock->count = 1;
|
||||
lock->owner = me;
|
||||
}
|
||||
ASSERT_VALID_LOCK(lock);
|
||||
}
|
||||
|
||||
void
|
||||
jsd_Unlock(JSDStaticLock* lock)
|
||||
{
|
||||
void* me;
|
||||
|
||||
ASSERT_VALID_LOCK(lock);
|
||||
_CURRENT_THREAD(me);
|
||||
|
||||
if(lock->owner != me)
|
||||
{
|
||||
JS_ASSERT(0); /* it's an error to unlock a lock you don't own */
|
||||
return;
|
||||
}
|
||||
if(--lock->count == 0)
|
||||
{
|
||||
lock->owner = NULL;
|
||||
PR_Unlock(lock->lock);
|
||||
}
|
||||
ASSERT_VALID_LOCK(lock);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
JSBool
|
||||
jsd_IsLocked(JSDStaticLock* lock)
|
||||
{
|
||||
void* me;
|
||||
ASSERT_VALID_LOCK(lock);
|
||||
_CURRENT_THREAD(me);
|
||||
return lock->owner == me ? JS_TRUE : JS_FALSE;
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
void*
|
||||
jsd_CurrentThread()
|
||||
{
|
||||
void* me;
|
||||
_CURRENT_THREAD(me);
|
||||
return me;
|
||||
}
|
||||
|
||||
|
||||
#else /* ! JSD_USE_NSPR_LOCKS */
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma message("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
|
||||
#pragma message("!! you are compiling the stubbed version of jsd_lock.c !!")
|
||||
#pragma message("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
|
||||
#endif
|
||||
|
||||
/*
|
||||
* NOTE: 'Real' versions of these locks must be reentrant in the sense that
|
||||
* they support nested calls to lock and unlock.
|
||||
*/
|
||||
|
||||
void*
|
||||
jsd_CreateLock()
|
||||
{
|
||||
return (void*)1;
|
||||
}
|
||||
|
||||
void
|
||||
jsd_Lock(void* lock)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
jsd_Unlock(void* lock)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
JSBool
|
||||
jsd_IsLocked(void* lock)
|
||||
{
|
||||
return JS_TRUE;
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* This Windows only thread id code is here to allow the Java-based
|
||||
* JSDebugger to work with the single threaded js.c shell (even without
|
||||
* real locking and threading support).
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
/* bogus (but good enough) declaration*/
|
||||
extern void* __stdcall GetCurrentThreadId(void);
|
||||
#endif
|
||||
|
||||
void*
|
||||
jsd_CurrentThread()
|
||||
{
|
||||
#ifdef WIN32
|
||||
return GetCurrentThreadId();
|
||||
#else
|
||||
return (void*)1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* JSD_USE_NSPR_LOCKS */
|
||||
|
||||
#endif /* JSD_THREADSAFE */
|
||||
|
53
js/jsd/jsd_lock.h
Normal file
53
js/jsd/jsd_lock.h
Normal file
@ -0,0 +1,53 @@
|
||||
/* -*- 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.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Header for JavaScript Debugging support - Locking and threading functions
|
||||
*/
|
||||
|
||||
#ifndef jsd_lock_h___
|
||||
#define jsd_lock_h___
|
||||
|
||||
/*
|
||||
* If you want to support threading and locking, define JSD_THREADSAFE and
|
||||
* implement the functions below.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE: These locks must be reentrant in the sense that they support
|
||||
* nested calls to lock and unlock.
|
||||
*/
|
||||
|
||||
extern void*
|
||||
jsd_CreateLock();
|
||||
|
||||
extern void
|
||||
jsd_Lock(void* lock);
|
||||
|
||||
extern void
|
||||
jsd_Unlock(void* lock);
|
||||
|
||||
#ifdef DEBUG
|
||||
extern JSBool
|
||||
jsd_IsLocked(void* lock);
|
||||
#endif /* DEBUG */
|
||||
|
||||
extern void*
|
||||
jsd_CurrentThread();
|
||||
|
||||
#endif /* jsd_lock_h___ */
|
307
js/jsd/jsd_obj.c
Normal file
307
js/jsd/jsd_obj.c
Normal file
@ -0,0 +1,307 @@
|
||||
/* -*- 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.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* JavaScript Debugging support - Object support
|
||||
*/
|
||||
|
||||
#include "jsd.h"
|
||||
|
||||
/*
|
||||
* #define JSD_TRACE 1
|
||||
*/
|
||||
|
||||
#ifdef JSD_TRACE
|
||||
#define TRACEOBJ(jsdc, jsdobj, which) _traceObj(jsdc, jsdobj, which)
|
||||
|
||||
static char *
|
||||
_describeObj(JSDContext* jsdc, JSDObject *jsdobj)
|
||||
{
|
||||
return
|
||||
JS_smprintf("%0x new'd in %s at line %d using ctor %s in %s at line %d",
|
||||
(int)jsdobj,
|
||||
JSD_GetObjectNewURL(jsdc, jsdobj),
|
||||
JSD_GetObjectNewLineNumber(jsdc, jsdobj),
|
||||
JSD_GetObjectConstructorName(jsdc, jsdobj),
|
||||
JSD_GetObjectConstructorURL(jsdc, jsdobj),
|
||||
JSD_GetObjectConstructorLineNumber(jsdc, jsdobj));
|
||||
}
|
||||
|
||||
static void
|
||||
_traceObj(JSDContext* jsdc, JSDObject* jsdobj, int which)
|
||||
{
|
||||
char* description;
|
||||
|
||||
if( !jsdobj )
|
||||
return;
|
||||
|
||||
description = _describeObj(jsdc, jsdobj);
|
||||
|
||||
printf("%s : %s\n",
|
||||
which == 0 ? "new " :
|
||||
which == 1 ? "final" :
|
||||
"ctor ",
|
||||
description);
|
||||
if(description)
|
||||
free(description);
|
||||
}
|
||||
#else
|
||||
#define TRACEOBJ(jsdc, jsdobj, which) ((void)0)
|
||||
#endif /* JSD_TRACE */
|
||||
|
||||
#ifdef DEBUG
|
||||
void JSD_ASSERT_VALID_OBJECT(JSDObject* jsdobj)
|
||||
{
|
||||
JS_ASSERT(jsdobj);
|
||||
JS_ASSERT(!JS_CLIST_IS_EMPTY(&jsdobj->links));
|
||||
JS_ASSERT(jsdobj->obj);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
_destroyJSDObject(JSDContext* jsdc, JSDObject* jsdobj)
|
||||
{
|
||||
JS_ASSERT(JSD_OBJECTS_LOCKED(jsdc));
|
||||
|
||||
JS_REMOVE_LINK(&jsdobj->links);
|
||||
JS_HashTableRemove(jsdc->objectsTable, jsdobj->obj);
|
||||
|
||||
if(jsdobj->newURL)
|
||||
jsd_DropAtom(jsdc, jsdobj->newURL);
|
||||
if(jsdobj->ctorURL)
|
||||
jsd_DropAtom(jsdc, jsdobj->ctorURL);
|
||||
if(jsdobj->ctorName)
|
||||
jsd_DropAtom(jsdc, jsdobj->ctorName);
|
||||
free(jsdobj);
|
||||
}
|
||||
|
||||
static JSDObject*
|
||||
_createJSDObject(JSDContext* jsdc, JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JSDObject* jsdobj;
|
||||
JSStackFrame* fp;
|
||||
JSStackFrame* iter = NULL;
|
||||
const char* newURL;
|
||||
jsbytecode* pc;
|
||||
|
||||
JS_ASSERT(JSD_OBJECTS_LOCKED(jsdc));
|
||||
|
||||
jsdobj = (JSDObject*) calloc(1, sizeof(JSDObject));
|
||||
if( jsdobj )
|
||||
{
|
||||
JS_INIT_CLIST(&jsdobj->links);
|
||||
JS_APPEND_LINK(&jsdobj->links, &jsdc->objectsList);
|
||||
jsdobj->obj = obj;
|
||||
JS_HashTableAdd(jsdc->objectsTable, obj, jsdobj);
|
||||
|
||||
/* walk the stack to find js frame (if any) causing creation */
|
||||
while( NULL != (fp = JS_FrameIterator(cx, &iter)) )
|
||||
{
|
||||
if( !JS_IsNativeFrame(cx, fp) )
|
||||
{
|
||||
JSScript* script = JS_GetFrameScript(cx, fp);
|
||||
if( !script )
|
||||
continue;
|
||||
|
||||
newURL = JS_GetScriptFilename(cx, script);
|
||||
if( newURL )
|
||||
jsdobj->newURL = jsd_AddAtom(jsdc, newURL);
|
||||
|
||||
pc = JS_GetFramePC(cx, fp);
|
||||
if( pc )
|
||||
jsdobj->newLineno = JS_PCToLineNumber(cx, script, pc);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return jsdobj;
|
||||
}
|
||||
|
||||
void JS_DLL_CALLBACK
|
||||
jsd_ObjectHook(JSContext *cx, JSObject *obj, JSBool isNew, void *closure)
|
||||
{
|
||||
JSDObject* jsdobj;
|
||||
JSDContext* jsdc = (JSDContext*) closure;
|
||||
|
||||
if( ! jsdc || ! jsdc->inited )
|
||||
return;
|
||||
|
||||
JSD_LOCK_OBJECTS(jsdc);
|
||||
if(isNew)
|
||||
{
|
||||
jsdobj = _createJSDObject(jsdc, cx, obj);
|
||||
TRACEOBJ(jsdc, jsdobj, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
jsdobj = jsd_GetJSDObjectForJSObject(jsdc, obj);
|
||||
if( jsdobj )
|
||||
{
|
||||
TRACEOBJ(jsdc, jsdobj, 1);
|
||||
_destroyJSDObject(jsdc, jsdobj);
|
||||
}
|
||||
}
|
||||
JSD_UNLOCK_OBJECTS(jsdc);
|
||||
}
|
||||
|
||||
void
|
||||
jsd_Constructing(JSDContext* jsdc, JSContext *cx, JSObject *obj,
|
||||
JSStackFrame *fp)
|
||||
{
|
||||
JSDObject* jsdobj;
|
||||
JSScript* script;
|
||||
JSDScript* jsdscript;
|
||||
const char* ctorURL;
|
||||
const char* ctorName;
|
||||
|
||||
JSD_LOCK_OBJECTS(jsdc);
|
||||
jsdobj = jsd_GetJSDObjectForJSObject(jsdc, obj);
|
||||
if( jsdobj && !jsdobj->ctorURL && !JS_IsNativeFrame(cx, fp) )
|
||||
{
|
||||
script = JS_GetFrameScript(cx, fp);
|
||||
if( script )
|
||||
{
|
||||
ctorURL = JS_GetScriptFilename(cx, script);
|
||||
if( ctorURL )
|
||||
jsdobj->ctorURL = jsd_AddAtom(jsdc, ctorURL);
|
||||
|
||||
JSD_LOCK_SCRIPTS(jsdc);
|
||||
jsdscript = jsd_FindJSDScript(jsdc, script);
|
||||
JSD_UNLOCK_SCRIPTS(jsdc);
|
||||
if( jsdscript )
|
||||
{
|
||||
ctorName = jsd_GetScriptFunctionName(jsdc, jsdscript);
|
||||
if( ctorName )
|
||||
jsdobj->ctorName = jsd_AddAtom(jsdc, ctorName);
|
||||
}
|
||||
jsdobj->ctorLineno = JS_GetScriptBaseLineNumber(cx, script);
|
||||
}
|
||||
}
|
||||
TRACEOBJ(jsdc, jsdobj, 3);
|
||||
JSD_UNLOCK_OBJECTS(jsdc);
|
||||
}
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(JSHashNumber)
|
||||
_hash_root(const void *key)
|
||||
{
|
||||
return ((JSHashNumber) key) >> 2; /* help lame MSVC1.5 on Win16 */
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_InitObjectManager(JSDContext* jsdc)
|
||||
{
|
||||
JS_INIT_CLIST(&jsdc->objectsList);
|
||||
jsdc->objectsTable = JS_NewHashTable(256, _hash_root,
|
||||
JS_CompareValues, JS_CompareValues,
|
||||
NULL, NULL);
|
||||
return (JSBool) jsdc->objectsTable;
|
||||
}
|
||||
|
||||
void
|
||||
jsd_DestroyObjectManager(JSDContext* jsdc)
|
||||
{
|
||||
JSD_LOCK_OBJECTS(jsdc);
|
||||
while( !JS_CLIST_IS_EMPTY(&jsdc->objectsList) )
|
||||
_destroyJSDObject(jsdc, (JSDObject*)JS_NEXT_LINK(&jsdc->objectsList));
|
||||
JS_HashTableDestroy(jsdc->objectsTable);
|
||||
JSD_UNLOCK_OBJECTS(jsdc);
|
||||
}
|
||||
|
||||
JSDObject*
|
||||
jsd_IterateObjects(JSDContext* jsdc, JSDObject** iterp)
|
||||
{
|
||||
JSDObject *jsdobj = *iterp;
|
||||
|
||||
JS_ASSERT(JSD_OBJECTS_LOCKED(jsdc));
|
||||
|
||||
if( !jsdobj )
|
||||
jsdobj = (JSDObject *)jsdc->objectsList.next;
|
||||
if( jsdobj == (JSDObject *)&jsdc->objectsList )
|
||||
return NULL;
|
||||
*iterp = (JSDObject*) jsdobj->links.next;
|
||||
return jsdobj;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
jsd_GetWrappedObject(JSDContext* jsdc, JSDObject* jsdobj)
|
||||
{
|
||||
return jsdobj->obj;
|
||||
}
|
||||
|
||||
const char*
|
||||
jsd_GetObjectNewURL(JSDContext* jsdc, JSDObject* jsdobj)
|
||||
{
|
||||
if( jsdobj->newURL )
|
||||
return JSD_ATOM_TO_STRING(jsdobj->newURL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uintN
|
||||
jsd_GetObjectNewLineNumber(JSDContext* jsdc, JSDObject* jsdobj)
|
||||
{
|
||||
return jsdobj->newLineno;
|
||||
}
|
||||
|
||||
const char*
|
||||
jsd_GetObjectConstructorURL(JSDContext* jsdc, JSDObject* jsdobj)
|
||||
{
|
||||
if( jsdobj->ctorURL )
|
||||
return JSD_ATOM_TO_STRING(jsdobj->ctorURL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uintN
|
||||
jsd_GetObjectConstructorLineNumber(JSDContext* jsdc, JSDObject* jsdobj)
|
||||
{
|
||||
return jsdobj->ctorLineno;
|
||||
}
|
||||
|
||||
const char*
|
||||
jsd_GetObjectConstructorName(JSDContext* jsdc, JSDObject* jsdobj)
|
||||
{
|
||||
if( jsdobj->ctorName )
|
||||
return JSD_ATOM_TO_STRING(jsdobj->ctorName);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JSDObject*
|
||||
jsd_GetJSDObjectForJSObject(JSDContext* jsdc, JSObject* jsobj)
|
||||
{
|
||||
JSDObject* jsdobj;
|
||||
|
||||
JSD_LOCK_OBJECTS(jsdc);
|
||||
jsdobj = (JSDObject*) JS_HashTableLookup(jsdc->objectsTable, jsobj);
|
||||
JSD_UNLOCK_OBJECTS(jsdc);
|
||||
return jsdobj;
|
||||
}
|
||||
|
||||
JSDObject*
|
||||
jsd_GetObjectForValue(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
return jsd_GetJSDObjectForJSObject(jsdc, JSVAL_TO_OBJECT(jsdval->val));
|
||||
}
|
||||
|
||||
JSDValue*
|
||||
jsd_GetValueForObject(JSDContext* jsdc, JSDObject* jsdobj)
|
||||
{
|
||||
return jsd_NewValue(jsdc, OBJECT_TO_JSVAL(jsdobj->obj));
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
/* -*- 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.0 (the "NPL"); you may not use this file except in
|
||||
@ -17,17 +17,10 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
** JavaScript Debugger Navigator API - Script support
|
||||
*/
|
||||
* JavaScript Debugging support - Script support
|
||||
*/
|
||||
|
||||
#include "jsd.h"
|
||||
#ifdef NSPR20
|
||||
#ifdef XP_MAC
|
||||
#include "prpriv.h"
|
||||
#else
|
||||
#include "private/prpriv.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Comment this out to disable (NT specific) dumping as we go */
|
||||
/*
|
||||
@ -39,75 +32,130 @@
|
||||
#define NOT_SET_YET -1
|
||||
|
||||
/***************************************************************************/
|
||||
PRCList jsd_script_list = PR_INIT_STATIC_CLIST(&jsd_script_list);
|
||||
|
||||
#ifdef DEBUG
|
||||
void JSD_ASSERT_VALID_SCRIPT( JSDScript* jsdscript )
|
||||
void JSD_ASSERT_VALID_SCRIPT(JSDScript* jsdscript)
|
||||
{
|
||||
PR_ASSERT( jsdscript );
|
||||
PR_ASSERT( jsdscript->script );
|
||||
JS_ASSERT(jsdscript);
|
||||
JS_ASSERT(jsdscript->script);
|
||||
}
|
||||
void JSD_ASSERT_VALID_EXEC_HOOK( JSDExecHook* jsdhook )
|
||||
void JSD_ASSERT_VALID_EXEC_HOOK(JSDExecHook* jsdhook)
|
||||
{
|
||||
PR_ASSERT( jsdhook );
|
||||
PR_ASSERT( jsdhook->hook );
|
||||
JS_ASSERT(jsdhook);
|
||||
JS_ASSERT(jsdhook->hook);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LIVEWIRE
|
||||
static JSBool
|
||||
HasFileExtention(const char* name, const char* ext)
|
||||
{
|
||||
int i;
|
||||
int len = strlen(ext);
|
||||
const char* p = strrchr(name,'.');
|
||||
if( !p )
|
||||
return JS_FALSE;
|
||||
p++;
|
||||
for(i = 0; i < len; i++ )
|
||||
{
|
||||
JS_ASSERT(islower(ext[i]));
|
||||
if( 0 == p[i] || tolower(p[i]) != ext[i] )
|
||||
return JS_FALSE;
|
||||
}
|
||||
if( 0 != p[i] )
|
||||
return JS_FALSE;
|
||||
return JS_TRUE;
|
||||
}
|
||||
#endif /* LIVEWIRE */
|
||||
|
||||
static JSDScript*
|
||||
NewJSDScript( JSDContext* jsdc,
|
||||
_newJSDScript(JSDContext* jsdc,
|
||||
JSContext *cx,
|
||||
JSScript *script,
|
||||
JSFunction* function )
|
||||
JSFunction* function)
|
||||
{
|
||||
JSDScript* jsdscript;
|
||||
PRUintn lineno;
|
||||
uintN lineno;
|
||||
const char* raw_filename;
|
||||
|
||||
JS_ASSERT(JSD_SCRIPTS_LOCKED(jsdc));
|
||||
|
||||
/* these are inlined javascript: urls and we can't handle them now */
|
||||
lineno = (PRUintn) JS_GetScriptBaseLineNumber(cx, script);
|
||||
lineno = (uintN) JS_GetScriptBaseLineNumber(cx, script);
|
||||
if( lineno == 0 )
|
||||
return NULL;
|
||||
|
||||
jsdscript = PR_NEWZAP(JSDScript);
|
||||
jsdscript = (JSDScript*) calloc(1, sizeof(JSDScript));
|
||||
if( ! jsdscript )
|
||||
return NULL;
|
||||
|
||||
raw_filename = JS_GetScriptFilename(cx,script);
|
||||
|
||||
PR_APPEND_LINK(&jsdscript->links, &jsd_script_list);
|
||||
JS_APPEND_LINK(&jsdscript->links, &jsdc->scripts);
|
||||
jsdscript->jsdc = jsdc;
|
||||
jsdscript->script = script;
|
||||
jsdscript->function = function;
|
||||
jsdscript->lineBase = lineno;
|
||||
jsdscript->lineExtent = (PRUintn)NOT_SET_YET;
|
||||
jsdscript->url = (char*)jsd_BuildNormalizedURL(JS_GetScriptFilename(cx,script));
|
||||
jsdscript->lineExtent = (uintN)NOT_SET_YET;
|
||||
#ifndef LIVEWIRE
|
||||
jsdscript->url = (char*) jsd_BuildNormalizedURL(raw_filename);
|
||||
#else
|
||||
jsdscript->app = LWDBG_GetCurrentApp();
|
||||
if( jsdscript->app && raw_filename )
|
||||
{
|
||||
jsdscript->url = jsdlw_BuildAppRelativeFilename(jsdscript->app, raw_filename);
|
||||
if( function )
|
||||
{
|
||||
jsdscript->lwscript =
|
||||
LWDBG_GetScriptOfFunction(jsdscript->app,
|
||||
JS_GetFunctionName(function));
|
||||
|
||||
/* also, make sure this file is added to filelist if is .js file */
|
||||
if( HasFileExtention(raw_filename,"js") ||
|
||||
HasFileExtention(raw_filename,"sjs") )
|
||||
{
|
||||
jsdlw_PreLoadSource(jsdc, jsdscript->app, raw_filename, JS_FALSE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
jsdscript->lwscript = LWDBG_GetCurrentTopLevelScript();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
PR_INIT_CLIST(&jsdscript->hooks);
|
||||
JS_INIT_CLIST(&jsdscript->hooks);
|
||||
|
||||
return jsdscript;
|
||||
}
|
||||
|
||||
static void
|
||||
DestroyJSDScript( JSDContext* jsdc,
|
||||
JSDScript* jsdscript )
|
||||
_destroyJSDScript(JSDContext* jsdc,
|
||||
JSDScript* jsdscript)
|
||||
{
|
||||
JS_ASSERT(JSD_SCRIPTS_LOCKED(jsdc));
|
||||
|
||||
/* destroy all hooks */
|
||||
jsd_ClearAllExecutionHooksForScript(jsdc, jsdscript);
|
||||
|
||||
PR_REMOVE_LINK(&jsdscript->links);
|
||||
PR_FREEIF(jsdscript->url);
|
||||
JS_REMOVE_LINK(&jsdscript->links);
|
||||
if(jsdscript->url)
|
||||
free(jsdscript->url);
|
||||
|
||||
PR_FREEIF(jsdscript);
|
||||
if(jsdscript)
|
||||
free(jsdscript);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifdef JSD_DUMP
|
||||
static void
|
||||
DumpJSDScript( JSDContext* jsdc, JSDScript* jsdscript, const char* leadingtext)
|
||||
_dumpJSDScript(JSDContext* jsdc, JSDScript* jsdscript, const char* leadingtext)
|
||||
{
|
||||
const char* name;
|
||||
const char* fun;
|
||||
PRUintn base;
|
||||
PRUintn extent;
|
||||
uintN base;
|
||||
uintN extent;
|
||||
char Buf[256];
|
||||
|
||||
name = jsd_GetScriptFilename(jsdc, jsdscript);
|
||||
@ -125,54 +173,32 @@ DumpJSDScript( JSDContext* jsdc, JSDScript* jsdscript, const char* leadingtext)
|
||||
}
|
||||
|
||||
static void
|
||||
DumpJSDScriptList( JSDContext* jsdc )
|
||||
_dumpJSDScriptList( JSDContext* jsdc )
|
||||
{
|
||||
JSDScript* iterp = NULL;
|
||||
JSDScript* jsdscript = NULL;
|
||||
|
||||
OutputDebugString( "*** JSDScriptDump\n" );
|
||||
while( NULL != (jsdscript = jsd_IterateScripts(jsdc, &iterp)) )
|
||||
DumpJSDScript( jsdc, jsdscript, " script: " );
|
||||
_dumpJSDScript( jsdc, jsdscript, " script: " );
|
||||
}
|
||||
#endif /* JSD_DUMP */
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifndef JSD_SIMULATION
|
||||
static PRMonitor *jsd_script_mon = NULL;
|
||||
#endif /* JSD_SIMULATION */
|
||||
|
||||
void
|
||||
jsd_LockScriptSubsystem(JSDContext* jsdc)
|
||||
{
|
||||
#ifndef JSD_SIMULATION
|
||||
if (jsd_script_mon == NULL)
|
||||
jsd_script_mon = PR_NewNamedMonitor("jsd-script-monitor");
|
||||
|
||||
PR_EnterMonitor(jsd_script_mon);
|
||||
#endif /* JSD_SIMULATION */
|
||||
}
|
||||
|
||||
void
|
||||
jsd_UnlockScriptSubsystem(JSDContext* jsdc)
|
||||
{
|
||||
#ifndef JSD_SIMULATION
|
||||
PR_ExitMonitor(jsd_script_mon);
|
||||
#endif /* JSD_SIMULATION */
|
||||
}
|
||||
|
||||
void
|
||||
jsd_DestroyAllJSDScripts( JSDContext* jsdc )
|
||||
{
|
||||
JSDScript *jsdscript;
|
||||
JSDScript *next;
|
||||
|
||||
for (jsdscript = (JSDScript*)jsd_script_list.next;
|
||||
jsdscript != (JSDScript*)&jsd_script_list;
|
||||
jsdscript = next)
|
||||
JS_ASSERT(JSD_SCRIPTS_LOCKED(jsdc));
|
||||
|
||||
for( jsdscript = (JSDScript*)jsdc->scripts.next;
|
||||
jsdscript != (JSDScript*)&jsdc->scripts;
|
||||
jsdscript = next )
|
||||
{
|
||||
next = (JSDScript*)jsdscript->links.next;
|
||||
DestroyJSDScript( jsdc, jsdscript );
|
||||
_destroyJSDScript( jsdc, jsdscript );
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,9 +208,12 @@ jsd_FindJSDScript( JSDContext* jsdc,
|
||||
{
|
||||
JSDScript *jsdscript;
|
||||
|
||||
for (jsdscript = (JSDScript *)jsd_script_list.next;
|
||||
jsdscript != (JSDScript *)&jsd_script_list;
|
||||
jsdscript = (JSDScript *)jsdscript->links.next) {
|
||||
JS_ASSERT(JSD_SCRIPTS_LOCKED(jsdc));
|
||||
|
||||
for( jsdscript = (JSDScript *)jsdc->scripts.next;
|
||||
jsdscript != (JSDScript *)&jsdc->scripts;
|
||||
jsdscript = (JSDScript *)jsdscript->links.next )
|
||||
{
|
||||
if (jsdscript->script == script)
|
||||
return jsdscript;
|
||||
}
|
||||
@ -196,14 +225,33 @@ jsd_IterateScripts(JSDContext* jsdc, JSDScript **iterp)
|
||||
{
|
||||
JSDScript *jsdscript = *iterp;
|
||||
|
||||
if (!jsdscript)
|
||||
jsdscript = (JSDScript *)jsd_script_list.next;
|
||||
if (jsdscript == (JSDScript *)&jsd_script_list)
|
||||
JS_ASSERT(JSD_SCRIPTS_LOCKED(jsdc));
|
||||
|
||||
if( !jsdscript )
|
||||
jsdscript = (JSDScript *)jsdc->scripts.next;
|
||||
if( jsdscript == (JSDScript *)&jsdc->scripts )
|
||||
return NULL;
|
||||
*iterp = (JSDScript *)jsdscript->links.next;
|
||||
*iterp = (JSDScript*) jsdscript->links.next;
|
||||
return jsdscript;
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_IsActiveScript(JSDContext* jsdc, JSDScript *jsdscript)
|
||||
{
|
||||
JSDScript *current;
|
||||
|
||||
JS_ASSERT(JSD_SCRIPTS_LOCKED(jsdc));
|
||||
|
||||
for( current = (JSDScript *)jsdc->scripts.next;
|
||||
current != (JSDScript *)&jsdc->scripts;
|
||||
current = (JSDScript *)current->links.next )
|
||||
{
|
||||
if(jsdscript == current)
|
||||
return JS_TRUE;
|
||||
}
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
const char*
|
||||
jsd_GetScriptFilename(JSDContext* jsdc, JSDScript *jsdscript)
|
||||
{
|
||||
@ -218,13 +266,13 @@ jsd_GetScriptFunctionName(JSDContext* jsdc, JSDScript *jsdscript)
|
||||
return JS_GetFunctionName(jsdscript->function);
|
||||
}
|
||||
|
||||
PRUintn
|
||||
uintN
|
||||
jsd_GetScriptBaseLineNumber(JSDContext* jsdc, JSDScript *jsdscript)
|
||||
{
|
||||
return jsdscript->lineBase;
|
||||
}
|
||||
|
||||
PRUintn
|
||||
uintN
|
||||
jsd_GetScriptLineExtent(JSDContext* jsdc, JSDScript *jsdscript)
|
||||
{
|
||||
if( NOT_SET_YET == jsdscript->lineExtent )
|
||||
@ -232,88 +280,120 @@ jsd_GetScriptLineExtent(JSDContext* jsdc, JSDScript *jsdscript)
|
||||
return jsdscript->lineExtent;
|
||||
}
|
||||
|
||||
prword_t
|
||||
jsd_GetClosestPC(JSDContext* jsdc, JSDScript* jsdscript, PRUintn line)
|
||||
jsuword
|
||||
jsd_GetClosestPC(JSDContext* jsdc, JSDScript* jsdscript, uintN line)
|
||||
{
|
||||
return (prword_t) JS_LineNumberToPC(jsdc->dumbContext,
|
||||
#ifdef LIVEWIRE
|
||||
if( jsdscript && jsdscript->lwscript )
|
||||
{
|
||||
uintN newline;
|
||||
jsdlw_RawToProcessedLineNumber(jsdc, jsdscript, line, &newline);
|
||||
if( line != newline )
|
||||
line = newline;
|
||||
}
|
||||
#endif
|
||||
|
||||
return (jsuword) JS_LineNumberToPC(jsdc->dumbContext,
|
||||
jsdscript->script, line );
|
||||
}
|
||||
|
||||
PRUintn
|
||||
jsd_GetClosestLine(JSDContext* jsdc, JSDScript* jsdscript, prword_t pc)
|
||||
uintN
|
||||
jsd_GetClosestLine(JSDContext* jsdc, JSDScript* jsdscript, jsuword pc)
|
||||
{
|
||||
PRUintn first = jsdscript->lineBase;
|
||||
PRUintn last = first + jsd_GetScriptLineExtent(jsdc, jsdscript) - 1;
|
||||
PRUintn line = JS_PCToLineNumber(jsdc->dumbContext,
|
||||
uintN first = jsdscript->lineBase;
|
||||
uintN last = first + jsd_GetScriptLineExtent(jsdc, jsdscript) - 1;
|
||||
uintN line = JS_PCToLineNumber(jsdc->dumbContext,
|
||||
jsdscript->script, (jsbytecode*)pc);
|
||||
|
||||
if( line < first )
|
||||
return first;
|
||||
if( line > last )
|
||||
return last;
|
||||
|
||||
#ifdef LIVEWIRE
|
||||
if( jsdscript && jsdscript->lwscript )
|
||||
{
|
||||
uintN newline;
|
||||
jsdlw_ProcessedToRawLineNumber(jsdc, jsdscript, line, &newline);
|
||||
line = newline;
|
||||
}
|
||||
#endif
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
JSD_ScriptHookProc
|
||||
JSBool
|
||||
jsd_SetScriptHook(JSDContext* jsdc, JSD_ScriptHookProc hook, void* callerdata)
|
||||
{
|
||||
JSD_ScriptHookProc oldHook = jsdc->scriptHook;
|
||||
JSD_LOCK();
|
||||
jsdc->scriptHook = hook;
|
||||
jsdc->scriptHookData = callerdata;
|
||||
return oldHook;
|
||||
JSD_UNLOCK();
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSD_ScriptHookProc
|
||||
jsd_GetScriptHook(JSDContext* jsdc)
|
||||
JSBool
|
||||
jsd_GetScriptHook(JSDContext* jsdc, JSD_ScriptHookProc* hook, void** callerdata)
|
||||
{
|
||||
return jsdc->scriptHook;
|
||||
}
|
||||
JSD_LOCK();
|
||||
if( hook )
|
||||
*hook = jsdc->scriptHook;
|
||||
if( callerdata )
|
||||
*callerdata = jsdc->scriptHookData;
|
||||
JSD_UNLOCK();
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void PR_CALLBACK
|
||||
void JS_DLL_CALLBACK
|
||||
jsd_NewScriptHookProc(
|
||||
JSContext *cx,
|
||||
const char *filename, /* URL this script loads from */
|
||||
PRUintn lineno, /* line where this script starts */
|
||||
uintN lineno, /* line where this script starts */
|
||||
JSScript *script,
|
||||
JSFunction *fun,
|
||||
void* callerdata )
|
||||
{
|
||||
JSDScript* jsdscript = NULL;
|
||||
JSDContext* jsdc = (JSDContext*) callerdata;
|
||||
|
||||
if( jsd_IsCurrentThreadDangerous() )
|
||||
return;
|
||||
JSD_ScriptHookProc hook;
|
||||
void* hookData;
|
||||
|
||||
JSD_ASSERT_VALID_CONTEXT(jsdc);
|
||||
|
||||
jsd_LockScriptSubsystem(jsdc);
|
||||
|
||||
jsd_JSContextUsed(jsdc, cx);
|
||||
|
||||
jsdscript = NewJSDScript( jsdc, cx, script, fun );
|
||||
if( ! jsdscript )
|
||||
{
|
||||
jsd_UnlockScriptSubsystem(jsdc);
|
||||
if( JSD_IS_DANGEROUS_THREAD(jsdc) )
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef LIVEWIRE
|
||||
if( 1 == lineno )
|
||||
jsdlw_PreLoadSource(jsdc, LWDBG_GetCurrentApp(), filename, JS_TRUE );
|
||||
#endif
|
||||
|
||||
JSD_LOCK_SCRIPTS(jsdc);
|
||||
jsdscript = _newJSDScript(jsdc, cx, script, fun);
|
||||
JSD_UNLOCK_SCRIPTS(jsdc);
|
||||
if( ! jsdscript )
|
||||
return;
|
||||
|
||||
#ifdef JSD_DUMP
|
||||
if( jsdscript )
|
||||
{
|
||||
DumpJSDScript( jsdc, jsdscript, "***NEW Script: " );
|
||||
DumpJSDScriptList( jsdc );
|
||||
}
|
||||
JSD_LOCK_SCRIPTS(jsdc);
|
||||
_dumpJSDScript(jsdc, jsdscript, "***NEW Script: ");
|
||||
_dumpJSDScriptList( jsdc );
|
||||
JSD_UNLOCK_SCRIPTS(jsdc);
|
||||
#endif /* JSD_DUMP */
|
||||
|
||||
if( jsdc->scriptHook )
|
||||
jsdc->scriptHook( jsdc, jsdscript, TRUE, jsdc->scriptHookData );
|
||||
|
||||
jsd_UnlockScriptSubsystem(jsdc);
|
||||
/* local in case jsdc->scriptHook gets cleared on another thread */
|
||||
JSD_LOCK();
|
||||
hook = jsdc->scriptHook;
|
||||
hookData = jsdc->scriptHookData;
|
||||
JSD_UNLOCK();
|
||||
|
||||
if( hook )
|
||||
hook(jsdc, jsdscript, JS_TRUE, hookData);
|
||||
}
|
||||
|
||||
void PR_CALLBACK
|
||||
void JS_DLL_CALLBACK
|
||||
jsd_DestroyScriptHookProc(
|
||||
JSContext *cx,
|
||||
JSScript *script,
|
||||
@ -321,51 +401,59 @@ jsd_DestroyScriptHookProc(
|
||||
{
|
||||
JSDScript* jsdscript = NULL;
|
||||
JSDContext* jsdc = (JSDContext*) callerdata;
|
||||
JSD_ScriptHookProc hook;
|
||||
void* hookData;
|
||||
|
||||
if( jsd_IsCurrentThreadDangerous() )
|
||||
return;
|
||||
|
||||
JSD_ASSERT_VALID_CONTEXT(jsdc);
|
||||
|
||||
jsd_LockScriptSubsystem(jsdc);
|
||||
|
||||
jsd_JSContextUsed(jsdc, cx);
|
||||
|
||||
jsdscript = jsd_FindJSDScript( jsdc, script );
|
||||
if( ! jsdscript )
|
||||
{
|
||||
jsd_UnlockScriptSubsystem(jsdc);
|
||||
if( JSD_IS_DANGEROUS_THREAD(jsdc) )
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef JSD_DUMP
|
||||
DumpJSDScript( jsdc, jsdscript, "***DESTROY Script: " );
|
||||
#endif /* JSD_DUMP */
|
||||
|
||||
if( jsdc->scriptHook )
|
||||
jsdc->scriptHook( jsdc, jsdscript, FALSE, jsdc->scriptHookData );
|
||||
JSD_LOCK_SCRIPTS(jsdc);
|
||||
jsdscript = jsd_FindJSDScript(jsdc, script);
|
||||
JSD_UNLOCK_SCRIPTS(jsdc);
|
||||
|
||||
if( ! jsdscript )
|
||||
return;
|
||||
|
||||
DestroyJSDScript( jsdc, jsdscript );
|
||||
|
||||
#ifdef JSD_DUMP
|
||||
DumpJSDScriptList( jsdc );
|
||||
JSD_LOCK_SCRIPTS(jsdc);
|
||||
_dumpJSDScript(jsdc, jsdscript, "***DESTROY Script: ");
|
||||
JSD_UNLOCK_SCRIPTS(jsdc);
|
||||
#endif /* JSD_DUMP */
|
||||
|
||||
jsd_UnlockScriptSubsystem(jsdc);
|
||||
/* local in case hook gets cleared on another thread */
|
||||
JSD_LOCK();
|
||||
hook = jsdc->scriptHook;
|
||||
hookData = jsdc->scriptHookData;
|
||||
JSD_UNLOCK();
|
||||
|
||||
if( hook )
|
||||
hook(jsdc, jsdscript, JS_FALSE, hookData);
|
||||
|
||||
JSD_LOCK_SCRIPTS(jsdc);
|
||||
_destroyJSDScript(jsdc, jsdscript);
|
||||
JSD_UNLOCK_SCRIPTS(jsdc);
|
||||
|
||||
#ifdef JSD_DUMP
|
||||
JSD_LOCK_SCRIPTS(jsdc);
|
||||
_dumpJSDScriptList(jsdc);
|
||||
JSD_UNLOCK_SCRIPTS(jsdc);
|
||||
#endif /* JSD_DUMP */
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static JSDExecHook*
|
||||
FindHook( JSDContext* jsdc, JSDScript* jsdscript, prword_t pc)
|
||||
_findHook(JSDContext* jsdc, JSDScript* jsdscript, jsuword pc)
|
||||
{
|
||||
JSDExecHook* jsdhook;
|
||||
PRCList* list = &jsdscript->hooks;
|
||||
JSCList* list = &jsdscript->hooks;
|
||||
|
||||
for (jsdhook = (JSDExecHook*)list->next;
|
||||
for( jsdhook = (JSDExecHook*)list->next;
|
||||
jsdhook != (JSDExecHook*)list;
|
||||
jsdhook = (JSDExecHook*)jsdhook->links.next)
|
||||
jsdhook = (JSDExecHook*)jsdhook->links.next )
|
||||
{
|
||||
if (jsdhook->pc == pc)
|
||||
return jsdhook;
|
||||
@ -373,45 +461,82 @@ FindHook( JSDContext* jsdc, JSDScript* jsdscript, prword_t pc)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JSTrapStatus PR_CALLBACK
|
||||
static JSBool
|
||||
_isActiveHook(JSDContext* jsdc, JSScript *script, JSDExecHook* jsdhook)
|
||||
{
|
||||
JSDExecHook* current;
|
||||
JSCList* list;
|
||||
JSDScript* jsdscript;
|
||||
|
||||
JSD_LOCK_SCRIPTS(jsdc);
|
||||
jsdscript = jsd_FindJSDScript(jsdc, script);
|
||||
if( ! jsdscript)
|
||||
{
|
||||
JSD_UNLOCK_SCRIPTS(jsdc);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
list = &jsdscript->hooks;
|
||||
|
||||
for( current = (JSDExecHook*)list->next;
|
||||
current != (JSDExecHook*)list;
|
||||
current = (JSDExecHook*)current->links.next )
|
||||
{
|
||||
if(current == jsdhook)
|
||||
{
|
||||
JSD_UNLOCK_SCRIPTS(jsdc);
|
||||
return JS_TRUE;
|
||||
}
|
||||
}
|
||||
JSD_UNLOCK_SCRIPTS(jsdc);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
||||
JSTrapStatus JS_DLL_CALLBACK
|
||||
jsd_TrapHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval,
|
||||
void *closure)
|
||||
{
|
||||
PRUintn hookanswer = JSD_HOOK_RETURN_CONTINUE;
|
||||
JSDThreadState* jsdthreadstate;
|
||||
JSDExecHook* jsdhook = (JSDExecHook*) closure;
|
||||
JSD_ExecutionHookProc hook;
|
||||
void* hookData;
|
||||
JSDContext* jsdc;
|
||||
JSDScript* jsdscript;
|
||||
|
||||
if( jsd_IsCurrentThreadDangerous() )
|
||||
JSD_LOCK();
|
||||
|
||||
if( NULL == (jsdc = jsd_JSDContextForJSContext(cx)) ||
|
||||
! _isActiveHook(jsdc, script, jsdhook) )
|
||||
{
|
||||
JSD_UNLOCK();
|
||||
return JSTRAP_CONTINUE;
|
||||
}
|
||||
|
||||
JSD_ASSERT_VALID_EXEC_HOOK(jsdhook);
|
||||
PR_ASSERT(jsdhook->pc == (prword_t)pc);
|
||||
PR_ASSERT(jsdhook->jsdscript->script == script);
|
||||
JS_ASSERT(jsdhook->pc == (jsuword)pc);
|
||||
JS_ASSERT(jsdhook->jsdscript->script == script);
|
||||
JS_ASSERT(jsdhook->jsdscript->jsdc == jsdc);
|
||||
|
||||
hook = jsdhook->hook;
|
||||
hookData = jsdhook->callerdata;
|
||||
jsdscript = jsdhook->jsdscript;
|
||||
|
||||
/* do not use jsdhook-> after this point */
|
||||
JSD_UNLOCK();
|
||||
|
||||
jsdc = jsdhook->jsdscript->jsdc;
|
||||
if( ! jsdc || ! jsdc->inited )
|
||||
return JSTRAP_CONTINUE;
|
||||
|
||||
jsd_JSContextUsed(jsdc, cx);
|
||||
if( JSD_IS_DANGEROUS_THREAD(jsdc) )
|
||||
return JSTRAP_CONTINUE;
|
||||
|
||||
jsdthreadstate = jsd_NewThreadState(jsdc,cx);
|
||||
if( jsdthreadstate )
|
||||
{
|
||||
hookanswer =
|
||||
(*jsdhook->hook)(jsdc, jsdthreadstate,
|
||||
JSD_HOOK_BREAKPOINT,
|
||||
jsdhook->callerdata );
|
||||
#ifdef LIVEWIRE
|
||||
if( ! jsdlw_UserCodeAtPC(jsdc, jsdscript, (jsuword)pc) )
|
||||
return JSTRAP_CONTINUE;
|
||||
#endif
|
||||
|
||||
jsd_DestroyThreadState(jsdc, jsdthreadstate);
|
||||
}
|
||||
|
||||
*rval = NULL; /* XXX fix this!!! */
|
||||
|
||||
if( JSD_HOOK_RETURN_ABORT == hookanswer )
|
||||
return JSTRAP_ERROR;
|
||||
|
||||
return JSTRAP_CONTINUE; /* XXX fix this!!! */
|
||||
return jsd_CallExecutionHook(jsdc, cx, JSD_HOOK_BREAKPOINT,
|
||||
hook, hookData, rval);
|
||||
}
|
||||
|
||||
|
||||
@ -419,16 +544,21 @@ jsd_TrapHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval,
|
||||
JSBool
|
||||
jsd_SetExecutionHook(JSDContext* jsdc,
|
||||
JSDScript* jsdscript,
|
||||
prword_t pc,
|
||||
jsuword pc,
|
||||
JSD_ExecutionHookProc hook,
|
||||
void* callerdata)
|
||||
{
|
||||
JSDExecHook* jsdhook;
|
||||
|
||||
JSD_LOCK();
|
||||
if( ! hook )
|
||||
return jsd_ClearExecutionHook(jsdc, jsdscript, pc);
|
||||
{
|
||||
jsd_ClearExecutionHook(jsdc, jsdscript, pc);
|
||||
JSD_UNLOCK();
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
jsdhook = FindHook(jsdc, jsdscript, pc);
|
||||
jsdhook = _findHook(jsdc, jsdscript, pc);
|
||||
if( jsdhook )
|
||||
{
|
||||
jsdhook->hook = hook;
|
||||
@ -437,7 +567,7 @@ jsd_SetExecutionHook(JSDContext* jsdc,
|
||||
}
|
||||
/* else... */
|
||||
|
||||
jsdhook = PR_NEWZAP(JSDExecHook);
|
||||
jsdhook = (JSDExecHook*)calloc(1, sizeof(JSDExecHook));
|
||||
if( ! jsdhook )
|
||||
return JS_FALSE;
|
||||
jsdhook->jsdscript = jsdscript;
|
||||
@ -448,34 +578,40 @@ jsd_SetExecutionHook(JSDContext* jsdc,
|
||||
if( ! JS_SetTrap(jsdc->dumbContext, jsdscript->script,
|
||||
(jsbytecode*)pc, jsd_TrapHandler, (void*) jsdhook) )
|
||||
{
|
||||
PR_FREEIF(jsdhook);
|
||||
free(jsdhook);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
PR_APPEND_LINK(&jsdhook->links, &jsdscript->hooks);
|
||||
JS_APPEND_LINK(&jsdhook->links, &jsdscript->hooks);
|
||||
JSD_UNLOCK();
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_ClearExecutionHook(JSDContext* jsdc,
|
||||
JSDScript* jsdscript,
|
||||
prword_t pc)
|
||||
jsuword pc)
|
||||
{
|
||||
JSDExecHook* jsdhook;
|
||||
|
||||
jsdhook = FindHook(jsdc, jsdscript, pc);
|
||||
JSD_LOCK();
|
||||
|
||||
jsdhook = _findHook(jsdc, jsdscript, pc);
|
||||
if( ! jsdhook )
|
||||
{
|
||||
PR_ASSERT(0);
|
||||
JS_ASSERT(0);
|
||||
JSD_UNLOCK();
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
JS_ClearTrap(jsdc->dumbContext, jsdscript->script,
|
||||
(jsbytecode*)pc, NULL, NULL );
|
||||
|
||||
PR_REMOVE_LINK(&jsdhook->links);
|
||||
PR_FREEIF(jsdhook);
|
||||
JS_REMOVE_LINK(&jsdhook->links);
|
||||
free(jsdhook);
|
||||
|
||||
JSD_UNLOCK();
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
@ -483,15 +619,19 @@ JSBool
|
||||
jsd_ClearAllExecutionHooksForScript(JSDContext* jsdc, JSDScript* jsdscript)
|
||||
{
|
||||
JSDExecHook* jsdhook;
|
||||
PRCList* list = &jsdscript->hooks;
|
||||
JSCList* list = &jsdscript->hooks;
|
||||
|
||||
JSD_LOCK();
|
||||
|
||||
while( (JSDExecHook*)list != (jsdhook = (JSDExecHook*)list->next) )
|
||||
{
|
||||
PR_REMOVE_LINK(&jsdhook->links);
|
||||
PR_FREEIF(jsdhook);
|
||||
JS_REMOVE_LINK(&jsdhook->links);
|
||||
free(jsdhook);
|
||||
}
|
||||
|
||||
JS_ClearScriptTraps(jsdc->dumbContext, jsdscript->script);
|
||||
JSD_UNLOCK();
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
@ -501,8 +641,28 @@ jsd_ClearAllExecutionHooks(JSDContext* jsdc)
|
||||
JSDScript* jsdscript;
|
||||
JSDScript* iterp = NULL;
|
||||
|
||||
JSD_LOCK();
|
||||
while( NULL != (jsdscript = jsd_IterateScripts(jsdc, &iterp)) )
|
||||
jsd_ClearAllExecutionHooksForScript(jsdc, jsdscript);
|
||||
JSD_UNLOCK();
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
jsd_ScriptCreated(JSDContext* jsdc,
|
||||
JSContext *cx,
|
||||
const char *filename, /* URL this script loads from */
|
||||
uintN lineno, /* line where this script starts */
|
||||
JSScript *script,
|
||||
JSFunction *fun)
|
||||
{
|
||||
jsd_NewScriptHookProc(cx, filename, lineno, script, fun, jsdc);
|
||||
}
|
||||
|
||||
void
|
||||
jsd_ScriptDestroyed(JSDContext* jsdc,
|
||||
JSContext *cx,
|
||||
JSScript *script)
|
||||
{
|
||||
jsd_DestroyScriptHookProc(cx, script, jsdc);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
/* -*- 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.0 (the "NPL"); you may not use this file except in
|
||||
@ -17,71 +17,63 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
** JavaScript Debugger Navigator API - Call Stack support
|
||||
*/
|
||||
* JavaScript Debugging support - Call stack support
|
||||
*/
|
||||
|
||||
#include "jsd.h"
|
||||
#ifdef NSPR20
|
||||
#ifdef XP_MAC
|
||||
#include "prpriv.h"
|
||||
#else
|
||||
#include "private/prpriv.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
void JSD_ASSERT_VALID_THREAD_STATE( JSDThreadState* jsdthreadstate )
|
||||
void JSD_ASSERT_VALID_THREAD_STATE(JSDThreadState* jsdthreadstate)
|
||||
{
|
||||
PR_ASSERT(jsdthreadstate);
|
||||
PR_ASSERT(jsdthreadstate->stackDepth > 0);
|
||||
JS_ASSERT(jsdthreadstate);
|
||||
JS_ASSERT(jsdthreadstate->stackDepth > 0);
|
||||
}
|
||||
|
||||
void JSD_ASSERT_VALID_STACK_FRAME( JSDStackFrameInfo* jsdframe )
|
||||
void JSD_ASSERT_VALID_STACK_FRAME(JSDStackFrameInfo* jsdframe)
|
||||
{
|
||||
PR_ASSERT(jsdframe);
|
||||
PR_ASSERT(jsdframe->jsdthreadstate);
|
||||
JS_ASSERT(jsdframe);
|
||||
JS_ASSERT(jsdframe->jsdthreadstate);
|
||||
}
|
||||
#endif
|
||||
|
||||
static JSDStackFrameInfo*
|
||||
AddNewFrame( JSDContext* jsdc,
|
||||
_addNewFrame(JSDContext* jsdc,
|
||||
JSDThreadState* jsdthreadstate,
|
||||
JSScript* script,
|
||||
prword_t pc,
|
||||
JSObject* object,
|
||||
JSObject* thisp,
|
||||
JSStackFrame* fp )
|
||||
jsuword pc,
|
||||
JSStackFrame* fp)
|
||||
{
|
||||
JSDStackFrameInfo* jsdframe;
|
||||
JSDScript* jsdscript;
|
||||
|
||||
JSD_LOCK_SCRIPTS(jsdc);
|
||||
jsdscript = jsd_FindJSDScript(jsdc, script);
|
||||
JSD_UNLOCK_SCRIPTS(jsdc);
|
||||
if( ! jsdscript )
|
||||
return NULL;
|
||||
|
||||
jsdframe = PR_NEWZAP(JSDStackFrameInfo);
|
||||
jsdframe = (JSDStackFrameInfo*) calloc(1, sizeof(JSDStackFrameInfo));
|
||||
if( ! jsdframe )
|
||||
return NULL;
|
||||
|
||||
jsdframe->jsdthreadstate = jsdthreadstate;
|
||||
jsdframe->jsdscript = jsdscript ;
|
||||
jsdframe->pc = pc ;
|
||||
jsdframe->object = object ;
|
||||
jsdframe->thisp = thisp ;
|
||||
jsdframe->fp = fp ;
|
||||
|
||||
PR_APPEND_LINK(&jsdframe->links, &jsdthreadstate->stack);
|
||||
JS_APPEND_LINK(&jsdframe->links, &jsdthreadstate->stack);
|
||||
jsdthreadstate->stackDepth++;
|
||||
|
||||
return jsdframe;
|
||||
}
|
||||
|
||||
static void
|
||||
DestroyFrame(JSDStackFrameInfo* jsdframe)
|
||||
_destroyFrame(JSDStackFrameInfo* jsdframe)
|
||||
{
|
||||
/* kill any alloc'd objects in frame here... */
|
||||
|
||||
PR_FREEIF(jsdframe);
|
||||
if( jsdframe )
|
||||
free(jsdframe);
|
||||
}
|
||||
|
||||
|
||||
@ -92,31 +84,36 @@ jsd_NewThreadState(JSDContext* jsdc, JSContext *cx )
|
||||
JSStackFrame * iter = NULL;
|
||||
JSStackFrame * fp;
|
||||
|
||||
jsdthreadstate = PR_NEWZAP(JSDThreadState);
|
||||
jsdthreadstate = (JSDThreadState*)calloc(1, sizeof(JSDThreadState));
|
||||
if( ! jsdthreadstate )
|
||||
return NULL;
|
||||
|
||||
jsdthreadstate->context = cx;
|
||||
jsdthreadstate->thread = PR_CurrentThread();
|
||||
PR_INIT_CLIST(&jsdthreadstate->stack);
|
||||
jsdthreadstate->thread = JSD_CURRENT_THREAD();
|
||||
JS_INIT_CLIST(&jsdthreadstate->stack);
|
||||
jsdthreadstate->stackDepth = 0;
|
||||
|
||||
while( NULL != (fp = JS_FrameIterator(cx, &iter)) )
|
||||
{
|
||||
JSScript* script = JS_GetFrameScript(cx, fp);
|
||||
prword_t pc = (prword_t) JS_GetFramePC(cx, fp);
|
||||
jsuword pc = (jsuword) JS_GetFramePC(cx, fp);
|
||||
|
||||
if( ! script || ! pc || JS_IsNativeFrame(cx, fp) )
|
||||
continue;
|
||||
|
||||
AddNewFrame( jsdc, jsdthreadstate, script, pc,
|
||||
JS_GetFrameObject(cx, fp),
|
||||
JS_GetFrameThis(cx, fp), fp );
|
||||
_addNewFrame( jsdc, jsdthreadstate, script, pc, fp );
|
||||
}
|
||||
|
||||
/* if there is no stack, then this threadstate can not be constructed */
|
||||
if( 0 == jsdthreadstate->stackDepth )
|
||||
{
|
||||
free(jsdthreadstate);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsd_LockThreadsStates(jsdc);
|
||||
PR_APPEND_LINK(&jsdthreadstate->links, &jsdc->threadsStates);
|
||||
jsd_UnlockThreadStates(jsdc);
|
||||
JSD_LOCK_THREADSTATES(jsdc);
|
||||
JS_APPEND_LINK(&jsdthreadstate->links, &jsdc->threadsStates);
|
||||
JSD_UNLOCK_THREADSTATES(jsdc);
|
||||
|
||||
return jsdthreadstate;
|
||||
}
|
||||
@ -125,50 +122,35 @@ void
|
||||
jsd_DestroyThreadState(JSDContext* jsdc, JSDThreadState* jsdthreadstate)
|
||||
{
|
||||
JSDStackFrameInfo* jsdframe;
|
||||
PRCList* list;
|
||||
int64 i;
|
||||
JSCList* list;
|
||||
|
||||
#ifndef NSPR20
|
||||
LL_I2L(i,100);
|
||||
#endif
|
||||
|
||||
/* we need to wait if someone else is using the threadstate */
|
||||
|
||||
jsd_LockThreadsStates(jsdc);
|
||||
while( jsdthreadstate->wait )
|
||||
{
|
||||
jsd_UnlockThreadStates(jsdc);
|
||||
#ifndef NSPR20
|
||||
PR_Sleep(i);
|
||||
#else
|
||||
PR_Sleep(PR_MicrosecondsToInterval(100));
|
||||
#endif
|
||||
jsd_LockThreadsStates(jsdc);
|
||||
}
|
||||
PR_REMOVE_LINK(&jsdthreadstate->links);
|
||||
jsd_UnlockThreadStates(jsdc);
|
||||
JSD_ASSERT_VALID_THREAD_STATE(jsdthreadstate);
|
||||
JS_ASSERT(JSD_CURRENT_THREAD() == jsdthreadstate->thread);
|
||||
|
||||
JSD_LOCK_THREADSTATES(jsdc);
|
||||
JS_REMOVE_LINK(&jsdthreadstate->links);
|
||||
JSD_UNLOCK_THREADSTATES(jsdc);
|
||||
|
||||
list = &jsdthreadstate->stack;
|
||||
while( (JSDStackFrameInfo*)list != (jsdframe = (JSDStackFrameInfo*)list->next) )
|
||||
{
|
||||
PR_REMOVE_LINK(&jsdframe->links);
|
||||
DestroyFrame(jsdframe);
|
||||
JS_REMOVE_LINK(&jsdframe->links);
|
||||
_destroyFrame(jsdframe);
|
||||
}
|
||||
PR_FREEIF(jsdthreadstate);
|
||||
free(jsdthreadstate);
|
||||
}
|
||||
|
||||
PRUintn
|
||||
uintN
|
||||
jsd_GetCountOfStackFrames(JSDContext* jsdc, JSDThreadState* jsdthreadstate)
|
||||
{
|
||||
PRUintn count = 0;
|
||||
uintN count = 0;
|
||||
|
||||
jsd_LockThreadsStates(jsdc);
|
||||
JSD_LOCK_THREADSTATES(jsdc);
|
||||
|
||||
if( jsd_IsValidThreadState(jsdc, jsdthreadstate) )
|
||||
count = jsdthreadstate->stackDepth;
|
||||
|
||||
jsd_UnlockThreadStates(jsdc);
|
||||
JSD_UNLOCK_THREADSTATES(jsdc);
|
||||
|
||||
return count;
|
||||
}
|
||||
@ -178,12 +160,11 @@ jsd_GetStackFrame(JSDContext* jsdc, JSDThreadState* jsdthreadstate)
|
||||
{
|
||||
JSDStackFrameInfo* jsdframe = NULL;
|
||||
|
||||
jsd_LockThreadsStates(jsdc);
|
||||
JSD_LOCK_THREADSTATES(jsdc);
|
||||
|
||||
if( jsd_IsValidThreadState(jsdc, jsdthreadstate) )
|
||||
jsdframe = (JSDStackFrameInfo*) PR_LIST_HEAD(&jsdthreadstate->stack);
|
||||
|
||||
jsd_UnlockThreadStates(jsdc);
|
||||
jsdframe = (JSDStackFrameInfo*) JS_LIST_HEAD(&jsdthreadstate->stack);
|
||||
JSD_UNLOCK_THREADSTATES(jsdc);
|
||||
|
||||
return jsdframe;
|
||||
}
|
||||
@ -195,13 +176,13 @@ jsd_GetCallingStackFrame(JSDContext* jsdc,
|
||||
{
|
||||
JSDStackFrameInfo* nextjsdframe = NULL;
|
||||
|
||||
jsd_LockThreadsStates(jsdc);
|
||||
JSD_LOCK_THREADSTATES(jsdc);
|
||||
|
||||
if( jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) )
|
||||
if( PR_LIST_HEAD(&jsdframe->links) != &jsdframe->jsdthreadstate->stack )
|
||||
nextjsdframe = (JSDStackFrameInfo*) PR_LIST_HEAD(&jsdframe->links);
|
||||
if( JS_LIST_HEAD(&jsdframe->links) != &jsdframe->jsdthreadstate->stack )
|
||||
nextjsdframe = (JSDStackFrameInfo*) JS_LIST_HEAD(&jsdframe->links);
|
||||
|
||||
jsd_UnlockThreadStates(jsdc);
|
||||
JSD_UNLOCK_THREADSTATES(jsdc);
|
||||
|
||||
return nextjsdframe;
|
||||
}
|
||||
@ -213,58 +194,130 @@ jsd_GetScriptForStackFrame(JSDContext* jsdc,
|
||||
{
|
||||
JSDScript* jsdscript = NULL;
|
||||
|
||||
jsd_LockThreadsStates(jsdc);
|
||||
JSD_LOCK_THREADSTATES(jsdc);
|
||||
|
||||
if( jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) )
|
||||
jsdscript = jsdframe->jsdscript;
|
||||
|
||||
jsd_UnlockThreadStates(jsdc);
|
||||
JSD_UNLOCK_THREADSTATES(jsdc);
|
||||
|
||||
return jsdscript;
|
||||
}
|
||||
|
||||
prword_t
|
||||
jsuword
|
||||
jsd_GetPCForStackFrame(JSDContext* jsdc,
|
||||
JSDThreadState* jsdthreadstate,
|
||||
JSDStackFrameInfo* jsdframe)
|
||||
{
|
||||
prword_t pc = 0;
|
||||
jsuword pc = 0;
|
||||
|
||||
jsd_LockThreadsStates(jsdc);
|
||||
JSD_LOCK_THREADSTATES(jsdc);
|
||||
|
||||
if( jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) )
|
||||
pc = jsdframe->pc;
|
||||
|
||||
jsd_UnlockThreadStates(jsdc);
|
||||
JSD_UNLOCK_THREADSTATES(jsdc);
|
||||
|
||||
return pc;
|
||||
}
|
||||
|
||||
JSDValue*
|
||||
jsd_GetCallObjectForStackFrame(JSDContext* jsdc,
|
||||
JSDThreadState* jsdthreadstate,
|
||||
JSDStackFrameInfo* jsdframe)
|
||||
{
|
||||
JSObject* obj;
|
||||
JSDValue* jsdval = NULL;
|
||||
|
||||
JSD_LOCK_THREADSTATES(jsdc);
|
||||
|
||||
if( jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) )
|
||||
{
|
||||
obj = JS_GetFrameCallObject(jsdthreadstate->context, jsdframe->fp);
|
||||
if(obj)
|
||||
jsdval = JSD_NewValue(jsdc, OBJECT_TO_JSVAL(obj));
|
||||
}
|
||||
|
||||
JSD_UNLOCK_THREADSTATES(jsdc);
|
||||
|
||||
return jsdval;
|
||||
}
|
||||
|
||||
JSDValue*
|
||||
jsd_GetScopeChainForStackFrame(JSDContext* jsdc,
|
||||
JSDThreadState* jsdthreadstate,
|
||||
JSDStackFrameInfo* jsdframe)
|
||||
{
|
||||
JSObject* obj;
|
||||
JSDValue* jsdval = NULL;
|
||||
|
||||
JSD_LOCK_THREADSTATES(jsdc);
|
||||
|
||||
if( jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) )
|
||||
{
|
||||
obj = JS_GetFrameScopeChain(jsdthreadstate->context, jsdframe->fp);
|
||||
if(obj)
|
||||
jsdval = JSD_NewValue(jsdc, OBJECT_TO_JSVAL(obj));
|
||||
}
|
||||
|
||||
JSD_UNLOCK_THREADSTATES(jsdc);
|
||||
|
||||
return jsdval;
|
||||
}
|
||||
|
||||
JSDValue*
|
||||
jsd_GetThisForStackFrame(JSDContext* jsdc,
|
||||
JSDThreadState* jsdthreadstate,
|
||||
JSDStackFrameInfo* jsdframe)
|
||||
{
|
||||
JSObject* obj;
|
||||
JSDValue* jsdval = NULL;
|
||||
|
||||
JSD_LOCK_THREADSTATES(jsdc);
|
||||
|
||||
if( jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) )
|
||||
{
|
||||
obj = JS_GetFrameThis(jsdthreadstate->context, jsdframe->fp);
|
||||
if(obj)
|
||||
jsdval = JSD_NewValue(jsdc, OBJECT_TO_JSVAL(obj));
|
||||
}
|
||||
|
||||
JSD_UNLOCK_THREADSTATES(jsdc);
|
||||
|
||||
return jsdval;
|
||||
}
|
||||
|
||||
|
||||
JSBool
|
||||
jsd_EvaluateScriptInStackFrame(JSDContext* jsdc,
|
||||
JSDThreadState* jsdthreadstate,
|
||||
JSDStackFrameInfo* jsdframe,
|
||||
const char *bytes, PRUintn length,
|
||||
const char *filename, PRUintn lineno, jsval *rval)
|
||||
const char *bytes, uintN length,
|
||||
const char *filename, uintN lineno, jsval *rval)
|
||||
{
|
||||
JSBool retval;
|
||||
JSBool valid;
|
||||
JSExceptionState* exceptionState;
|
||||
JSContext* cx;
|
||||
|
||||
jsd_LockThreadsStates(jsdc);
|
||||
JS_ASSERT(JSD_CURRENT_THREAD() == jsdthreadstate->thread);
|
||||
|
||||
if( ! jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) )
|
||||
{
|
||||
jsd_UnlockThreadStates(jsdc);
|
||||
JSD_LOCK_THREADSTATES(jsdc);
|
||||
valid = jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe);
|
||||
JSD_UNLOCK_THREADSTATES(jsdc);
|
||||
|
||||
if( ! valid )
|
||||
return JS_FALSE;
|
||||
}
|
||||
jsdthreadstate->wait++ ;
|
||||
jsd_UnlockThreadStates(jsdc);
|
||||
|
||||
retval = JS_EvaluateInStackFrame(jsdthreadstate->context, jsdframe->fp,
|
||||
bytes, length, filename, lineno, rval);
|
||||
cx = jsdthreadstate->context;
|
||||
JS_ASSERT(cx);
|
||||
|
||||
jsd_LockThreadsStates(jsdc);
|
||||
jsdthreadstate->wait-- ;
|
||||
jsd_UnlockThreadStates(jsdc);
|
||||
exceptionState = JS_SaveExceptionState(cx);
|
||||
jsd_StartingEvalUsingFilename(jsdc, filename);
|
||||
retval = JS_EvaluateInStackFrame(cx, jsdframe->fp, bytes, length,
|
||||
filename, lineno, rval);
|
||||
jsd_FinishedEvalUsingFilename(jsdc, filename);
|
||||
JS_RestoreExceptionState(cx, exceptionState);
|
||||
|
||||
return retval;
|
||||
}
|
||||
@ -275,72 +328,37 @@ jsd_ValToStringInStackFrame(JSDContext* jsdc,
|
||||
JSDStackFrameInfo* jsdframe,
|
||||
jsval val)
|
||||
{
|
||||
JSString* jsstr = NULL;
|
||||
JSBool valid;
|
||||
JSString* retval;
|
||||
JSExceptionState* exceptionState;
|
||||
JSContext* cx;
|
||||
|
||||
jsd_LockThreadsStates(jsdc);
|
||||
JSD_LOCK_THREADSTATES(jsdc);
|
||||
valid = jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe);
|
||||
JSD_UNLOCK_THREADSTATES(jsdc);
|
||||
|
||||
if( ! jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) )
|
||||
{
|
||||
jsd_UnlockThreadStates(jsdc);
|
||||
if( ! valid )
|
||||
return NULL;
|
||||
}
|
||||
jsdthreadstate->wait++ ;
|
||||
jsd_UnlockThreadStates(jsdc);
|
||||
|
||||
jsstr = JS_ValueToString(jsdthreadstate->context, val);
|
||||
cx = jsdthreadstate->context;
|
||||
JS_ASSERT(cx);
|
||||
|
||||
jsd_LockThreadsStates(jsdc);
|
||||
jsdthreadstate->wait-- ;
|
||||
jsd_UnlockThreadStates(jsdc);
|
||||
exceptionState = JS_SaveExceptionState(cx);
|
||||
retval = JS_ValueToString(cx, val);
|
||||
JS_RestoreExceptionState(cx, exceptionState);
|
||||
|
||||
return jsstr;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifndef JSD_SIMULATION
|
||||
static PRMonitor *jsd_threadstate_mon = NULL;
|
||||
#endif /* JSD_SIMULATION */
|
||||
|
||||
void
|
||||
jsd_LockThreadsStates(JSDContext* jsdc)
|
||||
{
|
||||
#ifndef JSD_SIMULATION
|
||||
if (jsd_threadstate_mon == NULL)
|
||||
jsd_threadstate_mon = PR_NewNamedMonitor("jsd-threadstate-monitor");
|
||||
|
||||
PR_EnterMonitor(jsd_threadstate_mon);
|
||||
#endif /* JSD_SIMULATION */
|
||||
}
|
||||
|
||||
void
|
||||
jsd_UnlockThreadStates(JSDContext* jsdc)
|
||||
{
|
||||
#ifndef JSD_SIMULATION
|
||||
PR_ExitMonitor(jsd_threadstate_mon);
|
||||
#endif /* JSD_SIMULATION */
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_ThreadStatesIsLocked(JSDContext* jsdc)
|
||||
{
|
||||
#ifndef JSD_SIMULATION
|
||||
return jsd_threadstate_mon && PR_InMonitor(jsd_threadstate_mon);
|
||||
#else
|
||||
return JS_TRUE;
|
||||
#endif /* JSD_SIMULATION */
|
||||
return retval;
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_IsValidThreadState(JSDContext* jsdc,
|
||||
JSDThreadState* jsdthreadstate )
|
||||
JSDThreadState* jsdthreadstate)
|
||||
{
|
||||
JSDThreadState *cur;
|
||||
|
||||
PR_ASSERT( jsd_ThreadStatesIsLocked(jsdc) );
|
||||
JS_ASSERT( JSD_THREADSTATES_LOCKED(jsdc) );
|
||||
|
||||
for (cur = (JSDThreadState*)jsdc->threadsStates.next;
|
||||
for( cur = (JSDThreadState*)jsdc->threadsStates.next;
|
||||
cur != (JSDThreadState*)&jsdc->threadsStates;
|
||||
cur = (JSDThreadState*)cur->links.next )
|
||||
{
|
||||
@ -353,9 +371,9 @@ jsd_IsValidThreadState(JSDContext* jsdc,
|
||||
JSBool
|
||||
jsd_IsValidFrameInThreadState(JSDContext* jsdc,
|
||||
JSDThreadState* jsdthreadstate,
|
||||
JSDStackFrameInfo* jsdframe )
|
||||
JSDStackFrameInfo* jsdframe)
|
||||
{
|
||||
PR_ASSERT( jsd_ThreadStatesIsLocked(jsdc) );
|
||||
JS_ASSERT(JSD_THREADSTATES_LOCKED(jsdc));
|
||||
|
||||
if( ! jsd_IsValidThreadState(jsdc, jsdthreadstate) )
|
||||
return JS_FALSE;
|
||||
@ -367,3 +385,45 @@ jsd_IsValidFrameInThreadState(JSDContext* jsdc,
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSContext*
|
||||
_getContextForThreadState(JSDContext* jsdc, JSDThreadState* jsdthreadstate)
|
||||
{
|
||||
JSBool valid;
|
||||
JSD_LOCK_THREADSTATES(jsdc);
|
||||
valid = jsd_IsValidThreadState(jsdc, jsdthreadstate);
|
||||
JSD_UNLOCK_THREADSTATES(jsdc);
|
||||
if( valid )
|
||||
return jsdthreadstate->context;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JSDValue*
|
||||
jsd_GetException(JSDContext* jsdc, JSDThreadState* jsdthreadstate)
|
||||
{
|
||||
JSContext* cx;
|
||||
jsval val;
|
||||
|
||||
if(!(cx = _getContextForThreadState(jsdc, jsdthreadstate)))
|
||||
return NULL;
|
||||
|
||||
if(JS_GetPendingException(cx, &val))
|
||||
return jsd_NewValue(jsdc, val);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_SetException(JSDContext* jsdc, JSDThreadState* jsdthreadstate,
|
||||
JSDValue* jsdval)
|
||||
{
|
||||
JSContext* cx;
|
||||
|
||||
if(!(cx = _getContextForThreadState(jsdc, jsdthreadstate)))
|
||||
return JS_FALSE;
|
||||
|
||||
if(jsdval)
|
||||
JS_SetPendingException(cx, JSD_GetValueWrappedJSVal(jsdc, jsdval));
|
||||
else
|
||||
JS_ClearPendingException(cx);
|
||||
return JS_TRUE;
|
||||
}
|
116
js/jsd/jsd_step.c
Normal file
116
js/jsd/jsd_step.c
Normal file
@ -0,0 +1,116 @@
|
||||
/* -*- 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.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* JavaScript Debugging support - Stepping support
|
||||
*/
|
||||
|
||||
#include "jsd.h"
|
||||
|
||||
/*
|
||||
* #define JSD_TRACE 1
|
||||
*/
|
||||
|
||||
#ifdef JSD_TRACE
|
||||
|
||||
static char*
|
||||
_indentSpaces(int i)
|
||||
{
|
||||
#define MAX_INDENT 63
|
||||
static char* p = NULL;
|
||||
if(!p)
|
||||
{
|
||||
p = calloc(1, MAX_INDENT+1);
|
||||
if(!p) return "";
|
||||
memset(p, ' ', MAX_INDENT);
|
||||
}
|
||||
if(i > MAX_INDENT) return p;
|
||||
return p + MAX_INDENT-i;
|
||||
}
|
||||
|
||||
static void
|
||||
_interpreterTrace(JSDContext* jsdc, JSContext *cx, JSStackFrame *fp,
|
||||
JSBool before, JSBool *ok)
|
||||
{
|
||||
JSDScript* jsdscript = NULL;
|
||||
JSScript * script;
|
||||
static indent = 0;
|
||||
char* buf;
|
||||
const char* funName = NULL;
|
||||
|
||||
script = JS_GetFrameScript(cx, fp);
|
||||
if(script)
|
||||
{
|
||||
JSD_LOCK_SCRIPTS(jsdc);
|
||||
jsdscript = jsd_FindJSDScript(jsdc, script);
|
||||
JSD_UNLOCK_SCRIPTS(jsdc);
|
||||
if(jsdscript)
|
||||
funName = JSD_GetScriptFunctionName(jsdc, jsdscript);
|
||||
}
|
||||
if(!funName)
|
||||
funName = "TOP_LEVEL";
|
||||
|
||||
if(before)
|
||||
{
|
||||
buf = JS_smprintf("%sentering %s %s this: %0x\n",
|
||||
_indentSpaces(indent++),
|
||||
funName,
|
||||
JS_IsContructorFrame(cx, fp) ? "constructing":"",
|
||||
(int)JS_GetFrameThis(cx, fp));
|
||||
}
|
||||
else
|
||||
{
|
||||
buf = JS_smprintf("%sleaving %s\n",
|
||||
_indentSpaces(--indent),
|
||||
funName);
|
||||
}
|
||||
JS_ASSERT(indent >= 0);
|
||||
|
||||
if(!buf)
|
||||
return;
|
||||
|
||||
printf(buf);
|
||||
free(buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
void * JS_DLL_CALLBACK
|
||||
jsd_InterpreterHook(JSContext *cx, JSStackFrame *fp, JSBool before,
|
||||
JSBool *ok, void *closure)
|
||||
{
|
||||
JSDContext* jsdc = (JSDContext*) closure;
|
||||
|
||||
if( ! jsdc || ! jsdc->inited )
|
||||
return NULL;
|
||||
|
||||
if(before && JS_IsContructorFrame(cx, fp))
|
||||
jsd_Constructing(jsdc, cx, JS_GetFrameThis(cx, fp), fp);
|
||||
|
||||
#ifdef JSD_TRACE
|
||||
_interpreterTrace(jsdc, cx, fp, before, ok);
|
||||
return closure;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
/*
|
||||
* use this before calling any hook...
|
||||
* if( JSD_IS_DANGEROUS_THREAD(jsdc) )
|
||||
* return NULL;
|
||||
*/
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
/* -*- 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.0 (the "NPL"); you may not use this file except in
|
||||
@ -17,182 +17,149 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
** JavaScript Debugger Navigator API - Source Text functions
|
||||
*/
|
||||
* JavaScript Debugging support - Source Text functions
|
||||
*/
|
||||
|
||||
#include "jsd.h"
|
||||
#ifdef NSPR20
|
||||
#ifdef XP_MAC
|
||||
#include "prpriv.h"
|
||||
#else
|
||||
#include "private/prpriv.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* XXX convert this and jsd_conv so that all accumulation of text done here
|
||||
* Also, use handle oriented alloc for Win16 64k limit problem
|
||||
*/
|
||||
|
||||
PRCList jsd_source_list = PR_INIT_STATIC_CLIST(&jsd_source_list);
|
||||
PRCList jsd_removed_source_list = PR_INIT_STATIC_CLIST(&jsd_removed_source_list);
|
||||
|
||||
/***************************************************************************/
|
||||
/*
|
||||
* typedef enum
|
||||
* {
|
||||
* JSD_SOURCE_INITED,
|
||||
* JSD_SOURCE_PARTIAL,
|
||||
* JSD_SOURCE_COMPLETED,
|
||||
* JSD_SOURCE_ABORTED,
|
||||
* JSD_SOURCE_FAILED
|
||||
*
|
||||
* } JSDSourceStatus;
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
void JSD_ASSERT_VALID_SOURCE_TEXT( JSDSourceText* jsdsrc )
|
||||
void JSD_ASSERT_VALID_SOURCE_TEXT(JSDSourceText* jsdsrc)
|
||||
{
|
||||
PR_ASSERT( jsdsrc );
|
||||
PR_ASSERT( jsdsrc->url );
|
||||
JS_ASSERT(jsdsrc);
|
||||
JS_ASSERT(jsdsrc->url);
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
/* XXX add serial number instead of dirty */
|
||||
/* XXX add notification */
|
||||
|
||||
static PRUintn g_alterCount = 1;
|
||||
|
||||
|
||||
static void
|
||||
ClearText( JSDContext* jsdc, JSDSourceText* jsdsrc )
|
||||
_clearText(JSDContext* jsdc, JSDSourceText* jsdsrc)
|
||||
{
|
||||
if( jsdsrc->text )
|
||||
MY_XP_HUGE_FREE(jsdsrc->text);
|
||||
free(jsdsrc->text);
|
||||
jsdsrc->text = NULL;
|
||||
jsdsrc->textLength = 0;
|
||||
jsdsrc->textSpace = 0;
|
||||
jsdsrc->status = JSD_SOURCE_CLEARED;
|
||||
jsdsrc->dirty = JS_TRUE;
|
||||
jsdsrc->alterCount = g_alterCount++ ;
|
||||
jsdsrc->alterCount = jsdc->sourceAlterCount++ ;
|
||||
jsdsrc->doingEval = JS_FALSE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
AppendText( JSDContext* jsdc, JSDSourceText* jsdsrc,
|
||||
const char* text, size_t length )
|
||||
_appendText(JSDContext* jsdc, JSDSourceText* jsdsrc,
|
||||
const char* text, size_t length)
|
||||
{
|
||||
#define MEMBUF_GROW 1000
|
||||
|
||||
PRUintn neededSize = jsdsrc->textLength + length;
|
||||
uintN neededSize = jsdsrc->textLength + length;
|
||||
|
||||
if( neededSize > jsdsrc->textSpace )
|
||||
{
|
||||
MY_XP_HUGE_CHAR_PTR pBuf;
|
||||
PRUintn iNewSize;
|
||||
char* newBuf;
|
||||
uintN iNewSize;
|
||||
|
||||
/* if this is the first alloc, the req might be all that's needed*/
|
||||
if( ! jsdsrc->textSpace )
|
||||
iNewSize = length;
|
||||
iNewSize = length;
|
||||
else
|
||||
iNewSize = (neededSize * 5 / 4) + MEMBUF_GROW;
|
||||
iNewSize = (neededSize * 5 / 4) + MEMBUF_GROW;
|
||||
|
||||
pBuf = (MY_XP_HUGE_CHAR_PTR) MY_XP_HUGE_ALLOC(iNewSize);
|
||||
if( pBuf )
|
||||
newBuf = (char*) realloc(jsdsrc->text, iNewSize);
|
||||
if( ! newBuf )
|
||||
{
|
||||
if( jsdsrc->text )
|
||||
/* try again with the minimal size really asked for */
|
||||
iNewSize = neededSize;
|
||||
newBuf = (char*) realloc(jsdsrc->text, iNewSize);
|
||||
if( ! newBuf )
|
||||
{
|
||||
MY_XP_HUGE_MEMCPY(pBuf, jsdsrc->text, jsdsrc->textLength);
|
||||
MY_XP_HUGE_FREE(jsdsrc->text);
|
||||
/* out of memory */
|
||||
_clearText( jsdc, jsdsrc );
|
||||
jsdsrc->status = JSD_SOURCE_FAILED;
|
||||
return JS_FALSE;
|
||||
}
|
||||
jsdsrc->text = pBuf;
|
||||
jsdsrc->textSpace = iNewSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* LTNOTE: throw an out of memory exception */
|
||||
ClearText( jsdc, jsdsrc );
|
||||
jsdsrc->status = JSD_SOURCE_FAILED;
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
jsdsrc->text = newBuf;
|
||||
jsdsrc->textSpace = iNewSize;
|
||||
}
|
||||
|
||||
MY_XP_HUGE_MEMCPY( &jsdsrc->text[jsdsrc->textLength], text, length );
|
||||
memcpy(jsdsrc->text + jsdsrc->textLength, text, length);
|
||||
jsdsrc->textLength += length;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSDSourceText*
|
||||
NewSource( JSDContext* jsdc, const char* url )
|
||||
_newSource(JSDContext* jsdc, const char* url)
|
||||
{
|
||||
JSDSourceText* jsdsrc = PR_NEWZAP(JSDSourceText);
|
||||
JSDSourceText* jsdsrc = (JSDSourceText*)calloc(1,sizeof(JSDSourceText));
|
||||
if( ! jsdsrc )
|
||||
return NULL;
|
||||
|
||||
jsdsrc->url = (char*) url; /* already a copy */
|
||||
jsdsrc->status = JSD_SOURCE_INITED;
|
||||
jsdsrc->dirty = JS_TRUE;
|
||||
jsdsrc->alterCount = g_alterCount++ ;
|
||||
jsdsrc->url = (char*) url; /* already a copy */
|
||||
jsdsrc->status = JSD_SOURCE_INITED;
|
||||
jsdsrc->dirty = JS_TRUE;
|
||||
jsdsrc->alterCount = jsdc->sourceAlterCount++ ;
|
||||
|
||||
return jsdsrc;
|
||||
}
|
||||
|
||||
static void
|
||||
DestroySource( JSDContext* jsdc, JSDSourceText* jsdsrc )
|
||||
_destroySource(JSDContext* jsdc, JSDSourceText* jsdsrc)
|
||||
{
|
||||
PR_ASSERT( NULL == jsdsrc->text ); /* must ClearText() first */
|
||||
MY_XP_FREE(jsdsrc->url);
|
||||
MY_XP_FREE(jsdsrc);
|
||||
JS_ASSERT(NULL == jsdsrc->text); /* must _clearText() first */
|
||||
free(jsdsrc->url);
|
||||
free(jsdsrc);
|
||||
}
|
||||
|
||||
static void
|
||||
RemoveSource( JSDContext* jsdc, JSDSourceText* jsdsrc )
|
||||
_removeSource(JSDContext* jsdc, JSDSourceText* jsdsrc)
|
||||
{
|
||||
PR_REMOVE_LINK(&jsdsrc->links);
|
||||
ClearText( jsdc, jsdsrc );
|
||||
DestroySource( jsdc, jsdsrc );
|
||||
JS_REMOVE_LINK(&jsdsrc->links);
|
||||
_clearText(jsdc, jsdsrc);
|
||||
_destroySource(jsdc, jsdsrc);
|
||||
}
|
||||
|
||||
static JSDSourceText*
|
||||
AddSource( JSDContext* jsdc, const char* url )
|
||||
_addSource(JSDContext* jsdc, const char* url)
|
||||
{
|
||||
JSDSourceText* jsdsrc = NewSource( jsdc, url );
|
||||
JSDSourceText* jsdsrc = _newSource(jsdc, url);
|
||||
if( ! jsdsrc )
|
||||
return NULL;
|
||||
PR_INSERT_LINK(&jsdsrc->links, &jsd_source_list);
|
||||
JS_INSERT_LINK(&jsdsrc->links, &jsdc->sources);
|
||||
return jsdsrc;
|
||||
}
|
||||
|
||||
static void
|
||||
MoveSourceToFront( JSDContext* jsdc, JSDSourceText* jsdsrc )
|
||||
_moveSourceToFront(JSDContext* jsdc, JSDSourceText* jsdsrc)
|
||||
{
|
||||
PR_REMOVE_LINK(&jsdsrc->links);
|
||||
PR_INSERT_LINK(&jsdsrc->links, &jsd_source_list);
|
||||
JS_REMOVE_LINK(&jsdsrc->links);
|
||||
JS_INSERT_LINK(&jsdsrc->links, &jsdc->sources);
|
||||
}
|
||||
|
||||
static void
|
||||
MoveSourceToRemovedList( JSDContext* jsdc, JSDSourceText* jsdsrc )
|
||||
_moveSourceToRemovedList(JSDContext* jsdc, JSDSourceText* jsdsrc)
|
||||
{
|
||||
ClearText(jsdc, jsdsrc);
|
||||
PR_REMOVE_LINK(&jsdsrc->links);
|
||||
PR_INSERT_LINK(&jsdsrc->links, &jsd_removed_source_list);
|
||||
_clearText(jsdc, jsdsrc);
|
||||
JS_REMOVE_LINK(&jsdsrc->links);
|
||||
JS_INSERT_LINK(&jsdsrc->links, &jsdc->removedSources);
|
||||
}
|
||||
|
||||
static void
|
||||
RemoveSourceFromRemovedList( JSDContext* jsdc, JSDSourceText* jsdsrc )
|
||||
_removeSourceFromRemovedList( JSDContext* jsdc, JSDSourceText* jsdsrc )
|
||||
{
|
||||
PR_REMOVE_LINK(&jsdsrc->links);
|
||||
DestroySource( jsdc, jsdsrc );
|
||||
JS_REMOVE_LINK(&jsdsrc->links);
|
||||
_destroySource( jsdc, jsdsrc );
|
||||
}
|
||||
|
||||
static JSBool
|
||||
IsSourceInSourceList( JSDContext* jsdc, JSDSourceText* jsdsrcToFind )
|
||||
_isSourceInSourceList(JSDContext* jsdc, JSDSourceText* jsdsrcToFind)
|
||||
{
|
||||
JSDSourceText *jsdsrc;
|
||||
|
||||
for (jsdsrc = (JSDSourceText*)jsd_source_list.next;
|
||||
jsdsrc != (JSDSourceText*)&jsd_source_list;
|
||||
for( jsdsrc = (JSDSourceText*)jsdc->sources.next;
|
||||
jsdsrc != (JSDSourceText*)&jsdc->sources;
|
||||
jsdsrc = (JSDSourceText*)jsdsrc->links.next )
|
||||
{
|
||||
if( jsdsrc == jsdsrcToFind )
|
||||
@ -201,26 +168,26 @@ IsSourceInSourceList( JSDContext* jsdc, JSDSourceText* jsdsrcToFind )
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* compare strings in a case insensitive manner with a length limit
|
||||
/* compare strings in a case insensitive manner with a length limit
|
||||
*/
|
||||
|
||||
static int
|
||||
strncasecomp (const char* one, const char * two, int n)
|
||||
{
|
||||
const char *pA;
|
||||
const char *pB;
|
||||
|
||||
for(pA=one, pB=two;; pA++, pB++)
|
||||
{
|
||||
int tmp;
|
||||
if (pA == one+n)
|
||||
return 0;
|
||||
if (!(*pA && *pB))
|
||||
return *pA - *pB;
|
||||
tmp = MY_XP_TO_LOWER(*pA) - MY_XP_TO_LOWER(*pB);
|
||||
if (tmp)
|
||||
return tmp;
|
||||
}
|
||||
const char *pA;
|
||||
const char *pB;
|
||||
|
||||
for(pA=one, pB=two;; pA++, pB++)
|
||||
{
|
||||
int tmp;
|
||||
if (pA == one+n)
|
||||
return 0;
|
||||
if (!(*pA && *pB))
|
||||
return *pA - *pB;
|
||||
tmp = tolower(*pA) - tolower(*pB);
|
||||
if (tmp)
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
static char file_url_prefix[] = "file:";
|
||||
@ -234,63 +201,40 @@ jsd_BuildNormalizedURL( const char* url_string )
|
||||
if( ! url_string )
|
||||
return NULL;
|
||||
|
||||
if (!MY_XP_STRNCASECMP(url_string, file_url_prefix, FILE_URL_PREFIX_LEN) &&
|
||||
if (!strncasecomp(url_string, file_url_prefix, FILE_URL_PREFIX_LEN) &&
|
||||
url_string[FILE_URL_PREFIX_LEN + 0] == '/' &&
|
||||
url_string[FILE_URL_PREFIX_LEN + 1] == '/') {
|
||||
new_url_string = PR_smprintf("%s%s",
|
||||
new_url_string = JS_smprintf("%s%s",
|
||||
file_url_prefix,
|
||||
url_string + FILE_URL_PREFIX_LEN + 2);
|
||||
} else {
|
||||
new_url_string = MY_XP_STRDUP(url_string);
|
||||
new_url_string = strdup(url_string);
|
||||
}
|
||||
return new_url_string;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifndef JSD_SIMULATION
|
||||
static PRMonitor *jsd_text_mon = NULL;
|
||||
#endif /* JSD_SIMULATION */
|
||||
|
||||
void
|
||||
jsd_LockSourceTextSubsystem(JSDContext* jsdc)
|
||||
{
|
||||
#ifndef JSD_SIMULATION
|
||||
if (jsd_text_mon == NULL)
|
||||
jsd_text_mon = PR_NewNamedMonitor("jsd-text-monitor");
|
||||
|
||||
PR_EnterMonitor(jsd_text_mon);
|
||||
#endif /* JSD_SIMULATION */
|
||||
}
|
||||
|
||||
void
|
||||
jsd_UnlockSourceTextSubsystem(JSDContext* jsdc)
|
||||
{
|
||||
#ifndef JSD_SIMULATION
|
||||
PR_ExitMonitor(jsd_text_mon);
|
||||
#endif /* JSD_SIMULATION */
|
||||
}
|
||||
|
||||
void
|
||||
jsd_DestroyAllSources( JSDContext* jsdc )
|
||||
{
|
||||
JSDSourceText *jsdsrc;
|
||||
JSDSourceText *next;
|
||||
|
||||
for (jsdsrc = (JSDSourceText*)jsd_source_list.next;
|
||||
jsdsrc != (JSDSourceText*)&jsd_source_list;
|
||||
jsdsrc = next)
|
||||
for( jsdsrc = (JSDSourceText*)jsdc->sources.next;
|
||||
jsdsrc != (JSDSourceText*)&jsdc->sources;
|
||||
jsdsrc = next )
|
||||
{
|
||||
next = (JSDSourceText*)jsdsrc->links.next;
|
||||
RemoveSource( jsdc, jsdsrc );
|
||||
_removeSource( jsdc, jsdsrc );
|
||||
}
|
||||
|
||||
for (jsdsrc = (JSDSourceText*)jsd_removed_source_list.next;
|
||||
jsdsrc != (JSDSourceText*)&jsd_removed_source_list;
|
||||
jsdsrc = next)
|
||||
for( jsdsrc = (JSDSourceText*)jsdc->removedSources.next;
|
||||
jsdsrc != (JSDSourceText*)&jsdc->removedSources;
|
||||
jsdsrc = next )
|
||||
{
|
||||
next = (JSDSourceText*)jsdsrc->links.next;
|
||||
RemoveSourceFromRemovedList( jsdc, jsdsrc );
|
||||
_removeSourceFromRemovedList( jsdc, jsdsrc );
|
||||
}
|
||||
|
||||
}
|
||||
@ -300,9 +244,9 @@ jsd_IterateSources(JSDContext* jsdc, JSDSourceText **iterp)
|
||||
{
|
||||
JSDSourceText *jsdsrc = *iterp;
|
||||
|
||||
if (!jsdsrc)
|
||||
jsdsrc = (JSDSourceText *)jsd_source_list.next;
|
||||
if (jsdsrc == (JSDSourceText *)&jsd_source_list)
|
||||
if( !jsdsrc )
|
||||
jsdsrc = (JSDSourceText *)jsdc->sources.next;
|
||||
if( jsdsrc == (JSDSourceText *)&jsdc->sources )
|
||||
return NULL;
|
||||
*iterp = (JSDSourceText *)jsdsrc->links.next;
|
||||
return jsdsrc;
|
||||
@ -313,10 +257,11 @@ jsd_FindSourceForURL(JSDContext* jsdc, const char* url)
|
||||
{
|
||||
JSDSourceText *jsdsrc;
|
||||
|
||||
for (jsdsrc = (JSDSourceText *)jsd_source_list.next;
|
||||
jsdsrc != (JSDSourceText *)&jsd_source_list;
|
||||
jsdsrc = (JSDSourceText *)jsdsrc->links.next) {
|
||||
if (0 == strcmp(jsdsrc->url, url))
|
||||
for( jsdsrc = (JSDSourceText *)jsdc->sources.next;
|
||||
jsdsrc != (JSDSourceText *)&jsdc->sources;
|
||||
jsdsrc = (JSDSourceText *)jsdsrc->links.next )
|
||||
{
|
||||
if( 0 == strcmp(jsdsrc->url, url) )
|
||||
return jsdsrc;
|
||||
}
|
||||
return NULL;
|
||||
@ -330,7 +275,7 @@ jsd_GetSourceURL(JSDContext* jsdc, JSDSourceText* jsdsrc)
|
||||
|
||||
JSBool
|
||||
jsd_GetSourceText(JSDContext* jsdc, JSDSourceText* jsdsrc,
|
||||
const char** ppBuf, int* pLen )
|
||||
const char** ppBuf, intN* pLen )
|
||||
{
|
||||
*ppBuf = jsdsrc->text;
|
||||
*pLen = jsdsrc->textLength;
|
||||
@ -343,7 +288,7 @@ jsd_ClearSourceText(JSDContext* jsdc, JSDSourceText* jsdsrc)
|
||||
if( JSD_SOURCE_INITED != jsdsrc->status &&
|
||||
JSD_SOURCE_PARTIAL != jsdsrc->status )
|
||||
{
|
||||
ClearText(jsdc, jsdsrc);
|
||||
_clearText(jsdc, jsdsrc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -365,16 +310,16 @@ jsd_SetSourceDirty(JSDContext* jsdc, JSDSourceText* jsdsrc, JSBool dirty)
|
||||
jsdsrc->dirty = dirty;
|
||||
}
|
||||
|
||||
PRUintn
|
||||
uintN
|
||||
jsd_GetSourceAlterCount(JSDContext* jsdc, JSDSourceText* jsdsrc)
|
||||
{
|
||||
return jsdsrc->alterCount;
|
||||
}
|
||||
|
||||
PRUintn
|
||||
uintN
|
||||
jsd_IncrementSourceAlterCount(JSDContext* jsdc, JSDSourceText* jsdsrc)
|
||||
{
|
||||
return ++jsdsrc->alterCount;
|
||||
return jsdsrc->alterCount = jsdc->sourceAlterCount++;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
@ -415,20 +360,35 @@ jsd_NewSourceText(JSDContext* jsdc, const char* url)
|
||||
JSDSourceText* jsdsrc;
|
||||
const char* new_url_string;
|
||||
|
||||
jsd_LockSourceTextSubsystem(jsdc);
|
||||
JSD_LOCK_SOURCE_TEXT(jsdc);
|
||||
|
||||
#ifdef LIVEWIRE
|
||||
new_url_string = url; /* we take ownership of alloc'd string */
|
||||
#else
|
||||
new_url_string = jsd_BuildNormalizedURL(url);
|
||||
#endif
|
||||
if( ! new_url_string )
|
||||
return NULL;
|
||||
|
||||
jsdsrc = jsd_FindSourceForURL(jsdc, new_url_string);
|
||||
|
||||
if( jsdsrc )
|
||||
MoveSourceToRemovedList(jsdc, jsdsrc);
|
||||
{
|
||||
if( jsdsrc->doingEval )
|
||||
{
|
||||
#ifdef LIVEWIRE
|
||||
free((char*)new_url_string);
|
||||
#endif
|
||||
JSD_UNLOCK_SOURCE_TEXT(jsdc);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
_moveSourceToRemovedList(jsdc, jsdsrc);
|
||||
}
|
||||
|
||||
jsdsrc = AddSource( jsdc, new_url_string );
|
||||
jsdsrc = _addSource( jsdc, new_url_string );
|
||||
|
||||
jsd_UnlockSourceTextSubsystem(jsdc);
|
||||
JSD_UNLOCK_SOURCE_TEXT(jsdc);
|
||||
|
||||
return jsdsrc;
|
||||
}
|
||||
@ -440,32 +400,148 @@ jsd_AppendSourceText(JSDContext* jsdc,
|
||||
size_t length,
|
||||
JSDSourceStatus status)
|
||||
{
|
||||
jsd_LockSourceTextSubsystem(jsdc);
|
||||
JSD_LOCK_SOURCE_TEXT(jsdc);
|
||||
|
||||
if( ! IsSourceInSourceList( jsdc, jsdsrc ) )
|
||||
if( jsdsrc->doingEval )
|
||||
{
|
||||
RemoveSourceFromRemovedList( jsdc, jsdsrc );
|
||||
jsd_UnlockSourceTextSubsystem(jsdc);
|
||||
JSD_UNLOCK_SOURCE_TEXT(jsdc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( text && length && ! AppendText( jsdc, jsdsrc, text, length ) )
|
||||
if( ! _isSourceInSourceList( jsdc, jsdsrc ) )
|
||||
{
|
||||
_removeSourceFromRemovedList( jsdc, jsdsrc );
|
||||
JSD_UNLOCK_SOURCE_TEXT(jsdc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( text && length && ! _appendText( jsdc, jsdsrc, text, length ) )
|
||||
{
|
||||
jsdsrc->dirty = JS_TRUE;
|
||||
jsdsrc->alterCount = g_alterCount++ ;
|
||||
jsdsrc->alterCount = jsdc->sourceAlterCount++ ;
|
||||
jsdsrc->status = JSD_SOURCE_FAILED;
|
||||
MoveSourceToRemovedList(jsdc, jsdsrc);
|
||||
jsd_UnlockSourceTextSubsystem(jsdc);
|
||||
_moveSourceToRemovedList(jsdc, jsdsrc);
|
||||
JSD_UNLOCK_SOURCE_TEXT(jsdc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsdsrc->dirty = JS_TRUE;
|
||||
jsdsrc->alterCount = g_alterCount++ ;
|
||||
jsdsrc->alterCount = jsdc->sourceAlterCount++ ;
|
||||
jsdsrc->status = status;
|
||||
DEBUG_ITERATE_SOURCES(jsdc);
|
||||
jsd_UnlockSourceTextSubsystem(jsdc);
|
||||
JSD_UNLOCK_SOURCE_TEXT(jsdc);
|
||||
return jsdsrc;
|
||||
}
|
||||
|
||||
JSDSourceText*
|
||||
jsd_AppendUCSourceText(JSDContext* jsdc,
|
||||
JSDSourceText* jsdsrc,
|
||||
const jschar* text, /* *not* zero terminated */
|
||||
size_t length,
|
||||
JSDSourceStatus status)
|
||||
{
|
||||
#define UNICODE_TRUNCATE_BUF_SIZE 1024
|
||||
static char* buf = NULL;
|
||||
int remaining = length;
|
||||
|
||||
if(!text || !length)
|
||||
return jsd_AppendSourceText(jsdc, jsdsrc, NULL, 0, status);
|
||||
|
||||
JSD_LOCK_SOURCE_TEXT(jsdc);
|
||||
if(!buf)
|
||||
{
|
||||
buf = malloc(UNICODE_TRUNCATE_BUF_SIZE);
|
||||
if(!buf)
|
||||
{
|
||||
JSD_UNLOCK_SOURCE_TEXT(jsdc);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
while(remaining && jsdsrc) {
|
||||
int bytes = JS_MIN(remaining, UNICODE_TRUNCATE_BUF_SIZE);
|
||||
int i;
|
||||
for(i = 0; i < bytes; i++)
|
||||
buf[i] = (const char) *(text++);
|
||||
jsdsrc = jsd_AppendSourceText(jsdc,jsdsrc,
|
||||
buf, bytes,
|
||||
JSD_SOURCE_PARTIAL);
|
||||
remaining -= bytes;
|
||||
}
|
||||
if(jsdsrc && status != JSD_SOURCE_PARTIAL)
|
||||
jsdsrc = jsd_AppendSourceText(jsdc, jsdsrc, NULL, 0, status);
|
||||
|
||||
JSD_UNLOCK_SOURCE_TEXT(jsdc);
|
||||
return jsdsrc;
|
||||
}
|
||||
|
||||
/* convienence function for adding complete source of url in one call */
|
||||
JSBool
|
||||
jsd_AddFullSourceText(JSDContext* jsdc,
|
||||
const char* text, /* *not* zero terminated */
|
||||
size_t length,
|
||||
const char* url)
|
||||
{
|
||||
JSDSourceText* jsdsrc;
|
||||
|
||||
JSD_LOCK_SOURCE_TEXT(jsdc);
|
||||
|
||||
jsdsrc = jsd_NewSourceText(jsdc, url);
|
||||
if( jsdsrc )
|
||||
jsdsrc = jsd_AppendSourceText(jsdc, jsdsrc,
|
||||
text, length, JSD_SOURCE_PARTIAL );
|
||||
if( jsdsrc )
|
||||
jsdsrc = jsd_AppendSourceText(jsdc, jsdsrc,
|
||||
NULL, 0, JSD_SOURCE_COMPLETED );
|
||||
|
||||
JSD_UNLOCK_SOURCE_TEXT(jsdc);
|
||||
|
||||
return jsdsrc ? JS_TRUE : JS_FALSE;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void
|
||||
jsd_StartingEvalUsingFilename(JSDContext* jsdc, const char* url)
|
||||
{
|
||||
JSDSourceText* jsdsrc;
|
||||
|
||||
/* NOTE: We leave it locked! */
|
||||
JSD_LOCK_SOURCE_TEXT(jsdc);
|
||||
|
||||
jsdsrc = jsd_FindSourceForURL(jsdc, url);
|
||||
if(jsdsrc)
|
||||
{
|
||||
#if 0
|
||||
#ifndef JSD_LOWLEVEL_SOURCE
|
||||
JS_ASSERT(! jsdsrc->doingEval);
|
||||
#endif
|
||||
#endif
|
||||
jsdsrc->doingEval = JS_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
jsd_FinishedEvalUsingFilename(JSDContext* jsdc, const char* url)
|
||||
{
|
||||
JSDSourceText* jsdsrc;
|
||||
|
||||
/* NOTE: We ASSUME it is locked! */
|
||||
|
||||
jsdsrc = jsd_FindSourceForURL(jsdc, url);
|
||||
if(jsdsrc)
|
||||
{
|
||||
#if 0
|
||||
#ifndef JSD_LOWLEVEL_SOURCE
|
||||
/*
|
||||
* when using this low level source addition, this jsdsrc might
|
||||
* not have existed before the eval, but does exist now (without
|
||||
* this flag set!)
|
||||
*/
|
||||
JS_ASSERT(jsdsrc->doingEval);
|
||||
#endif
|
||||
#endif
|
||||
jsdsrc->doingEval = JS_FALSE;
|
||||
}
|
||||
|
||||
JSD_UNLOCK_SOURCE_TEXT(jsdc);
|
||||
}
|
||||
|
601
js/jsd/jsd_val.c
Normal file
601
js/jsd/jsd_val.c
Normal file
@ -0,0 +1,601 @@
|
||||
/* -*- 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.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* JavaScript Debugging support - Value and Property support
|
||||
*/
|
||||
|
||||
#include "jsd.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
void JSD_ASSERT_VALID_VALUE(JSDValue* jsdval)
|
||||
{
|
||||
JS_ASSERT(jsdval);
|
||||
JS_ASSERT(jsdval->nref > 0);
|
||||
if(!JS_CLIST_IS_EMPTY(&jsdval->props))
|
||||
{
|
||||
JS_ASSERT(CHECK_BIT_FLAG(jsdval->flags, GOT_PROPS));
|
||||
JS_ASSERT(JSVAL_IS_OBJECT(jsdval->val));
|
||||
}
|
||||
|
||||
if(jsdval->proto)
|
||||
{
|
||||
JS_ASSERT(CHECK_BIT_FLAG(jsdval->flags, GOT_PROTO));
|
||||
JS_ASSERT(jsdval->proto->nref > 0);
|
||||
}
|
||||
if(jsdval->parent)
|
||||
{
|
||||
JS_ASSERT(CHECK_BIT_FLAG(jsdval->flags, GOT_PARENT));
|
||||
JS_ASSERT(jsdval->parent->nref > 0);
|
||||
}
|
||||
if(jsdval->ctor)
|
||||
{
|
||||
JS_ASSERT(CHECK_BIT_FLAG(jsdval->flags, GOT_CTOR));
|
||||
JS_ASSERT(jsdval->ctor->nref > 0);
|
||||
}
|
||||
}
|
||||
|
||||
void JSD_ASSERT_VALID_PROPERTY(JSDProperty* jsdprop)
|
||||
{
|
||||
JS_ASSERT(jsdprop);
|
||||
JS_ASSERT(jsdprop->name);
|
||||
JS_ASSERT(jsdprop->name->nref > 0);
|
||||
JS_ASSERT(jsdprop->val);
|
||||
JS_ASSERT(jsdprop->val->nref > 0);
|
||||
if(jsdprop->alias)
|
||||
JS_ASSERT(jsdprop->alias->nref > 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
JSBool
|
||||
jsd_IsValueObject(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
return JSVAL_IS_OBJECT(jsdval->val);
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_IsValueNumber(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
return JSVAL_IS_NUMBER(jsdval->val);
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_IsValueInt(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
return JSVAL_IS_INT(jsdval->val);
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_IsValueDouble(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
return JSVAL_IS_DOUBLE(jsdval->val);
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_IsValueString(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
return JSVAL_IS_STRING(jsdval->val);
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_IsValueBoolean(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
return JSVAL_IS_BOOLEAN(jsdval->val);
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_IsValueNull(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
return JSVAL_IS_NULL(jsdval->val);
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_IsValueVoid(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
return JSVAL_IS_VOID(jsdval->val);
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_IsValuePrimitive(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
return JSVAL_IS_PRIMITIVE(jsdval->val);
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_IsValueFunction(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
return JSVAL_IS_FUNCTION(jsdc->dumbContext, jsdval->val);
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsd_IsValueNative(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
JSContext* cx = jsdc->dumbContext;
|
||||
jsval val = jsdval->val;
|
||||
JSFunction* fun;
|
||||
JSExceptionState* exceptionState;
|
||||
|
||||
if(!JSVAL_IS_OBJECT(val))
|
||||
return JS_FALSE;
|
||||
|
||||
if(JSVAL_IS_FUNCTION(cx, val))
|
||||
{
|
||||
exceptionState = JS_SaveExceptionState(cx);
|
||||
fun = JS_ValueToFunction(cx, val);
|
||||
JS_RestoreExceptionState(cx, exceptionState);
|
||||
if(!fun)
|
||||
{
|
||||
JS_ASSERT(0);
|
||||
return JS_FALSE;
|
||||
}
|
||||
return JS_GetFunctionScript(cx, fun) ? JS_FALSE : JS_TRUE;
|
||||
}
|
||||
return JSVAL_TO_OBJECT(val) && OBJ_IS_NATIVE(JSVAL_TO_OBJECT(val));
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
JSBool
|
||||
jsd_GetValueBoolean(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
jsval val = jsdval->val;
|
||||
if(!JSVAL_IS_BOOLEAN(val))
|
||||
return JS_FALSE;
|
||||
return JSVAL_TO_BOOLEAN(val);
|
||||
}
|
||||
|
||||
int32
|
||||
jsd_GetValueInt(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
jsval val = jsdval->val;
|
||||
if(!JSVAL_IS_INT(val))
|
||||
return 0;
|
||||
return JSVAL_TO_INT(val);
|
||||
}
|
||||
|
||||
jsdouble*
|
||||
jsd_GetValueDouble(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
jsval val = jsdval->val;
|
||||
if(!JSVAL_IS_DOUBLE(val))
|
||||
return 0;
|
||||
return JSVAL_TO_DOUBLE(val);
|
||||
}
|
||||
|
||||
JSString*
|
||||
jsd_GetValueString(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
JSContext* cx = jsdc->dumbContext;
|
||||
JSExceptionState* exceptionState;
|
||||
|
||||
if(!jsdval->string)
|
||||
{
|
||||
/* if the jsval is a string, then we don't need to double root it */
|
||||
if(JSVAL_IS_STRING(jsdval->val))
|
||||
jsdval->string = JSVAL_TO_STRING(jsdval->val);
|
||||
else
|
||||
{
|
||||
exceptionState = JS_SaveExceptionState(cx);
|
||||
jsdval->string = JS_ValueToString(cx, jsdval->val);
|
||||
JS_RestoreExceptionState(cx, exceptionState);
|
||||
if(jsdval->string)
|
||||
{
|
||||
if(!JS_AddRoot(cx, &jsdval->string))
|
||||
jsdval->string = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return jsdval->string;
|
||||
}
|
||||
|
||||
const char*
|
||||
jsd_GetValueFunctionName(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
JSContext* cx = jsdc->dumbContext;
|
||||
jsval val = jsdval->val;
|
||||
JSFunction* fun;
|
||||
JSExceptionState* exceptionState;
|
||||
|
||||
if(!jsdval->funName && JSVAL_IS_FUNCTION(cx, val))
|
||||
{
|
||||
exceptionState = JS_SaveExceptionState(cx);
|
||||
fun = JS_ValueToFunction(cx, val);
|
||||
JS_RestoreExceptionState(cx, exceptionState);
|
||||
if(!fun)
|
||||
return NULL;
|
||||
jsdval->funName = JS_GetFunctionName(fun);
|
||||
}
|
||||
return jsdval->funName;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
JSDValue*
|
||||
jsd_NewValue(JSDContext* jsdc, jsval val)
|
||||
{
|
||||
JSDValue* jsdval;
|
||||
|
||||
if(!(jsdval = (JSDValue*) calloc(1, sizeof(JSDValue))))
|
||||
return NULL;
|
||||
|
||||
if(JSVAL_IS_GCTHING(val))
|
||||
{
|
||||
if(!JS_AddRoot(jsdc->dumbContext, &jsdval->val))
|
||||
{
|
||||
free(jsdval);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
jsdval->val = val;
|
||||
jsdval->nref = 1;
|
||||
JS_INIT_CLIST(&jsdval->props);
|
||||
|
||||
return jsdval;
|
||||
}
|
||||
|
||||
void
|
||||
jsd_DropValue(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
JS_ASSERT(jsdval->nref > 0);
|
||||
if(0 == --jsdval->nref)
|
||||
{
|
||||
jsd_RefreshValue(jsdc, jsdval);
|
||||
if(JSVAL_IS_GCTHING(jsdval->val))
|
||||
JS_RemoveRoot(jsdc->dumbContext, &jsdval->val);
|
||||
free(jsdval);
|
||||
}
|
||||
}
|
||||
|
||||
jsval
|
||||
jsd_GetValueWrappedJSVal(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
return jsdval->val;
|
||||
}
|
||||
|
||||
static JSDProperty* _newProperty(JSDContext* jsdc, JSPropertyDesc* pd,
|
||||
uintN additionalFlags)
|
||||
{
|
||||
JSDProperty* jsdprop;
|
||||
|
||||
if(!(jsdprop = (JSDProperty*) calloc(1, sizeof(JSDProperty))))
|
||||
return NULL;
|
||||
|
||||
JS_INIT_CLIST(&jsdprop->links);
|
||||
jsdprop->nref = 1;
|
||||
jsdprop->flags = pd->flags | additionalFlags;
|
||||
jsdprop->slot = pd->slot;
|
||||
|
||||
if(!(jsdprop->name = jsd_NewValue(jsdc, pd->id)))
|
||||
goto new_prop_fail;
|
||||
|
||||
if(!(jsdprop->val = jsd_NewValue(jsdc, pd->value)))
|
||||
goto new_prop_fail;
|
||||
|
||||
if((jsdprop->flags & JSDPD_ALIAS) &&
|
||||
!(jsdprop->alias = jsd_NewValue(jsdc, pd->alias)))
|
||||
goto new_prop_fail;
|
||||
|
||||
return jsdprop;
|
||||
new_prop_fail:
|
||||
jsd_DropProperty(jsdc, jsdprop);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void _freeProps(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
JSDProperty* jsdprop;
|
||||
|
||||
while(jsdprop = (JSDProperty*)jsdval->props.next,
|
||||
jsdprop != (JSDProperty*)&jsdval->props)
|
||||
{
|
||||
JS_REMOVE_AND_INIT_LINK(&jsdprop->links);
|
||||
jsd_DropProperty(jsdc, jsdprop);
|
||||
}
|
||||
JS_ASSERT(JS_CLIST_IS_EMPTY(&jsdval->props));
|
||||
CLEAR_BIT_FLAG(jsdval->flags, GOT_PROPS);
|
||||
}
|
||||
|
||||
static JSBool _buildProps(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
JSContext* cx = jsdc->dumbContext;
|
||||
JSPropertyDescArray pda;
|
||||
uintN i;
|
||||
|
||||
JS_ASSERT(JS_CLIST_IS_EMPTY(&jsdval->props));
|
||||
JS_ASSERT(!(CHECK_BIT_FLAG(jsdval->flags, GOT_PROPS)));
|
||||
JS_ASSERT(JSVAL_IS_OBJECT(jsdval->val));
|
||||
|
||||
if(!JSVAL_IS_OBJECT(jsdval->val) || JSVAL_IS_NULL(jsdval->val))
|
||||
return JS_FALSE;
|
||||
|
||||
if(!JS_GetPropertyDescArray(cx, JSVAL_TO_OBJECT(jsdval->val), &pda))
|
||||
return JS_FALSE;
|
||||
|
||||
for(i = 0; i < pda.length; i++)
|
||||
{
|
||||
JSDProperty* prop = _newProperty(jsdc, &pda.array[i], 0);
|
||||
if(!prop)
|
||||
{
|
||||
_freeProps(jsdc, jsdval);
|
||||
break;
|
||||
}
|
||||
JS_APPEND_LINK(&prop->links, &jsdval->props);
|
||||
}
|
||||
JS_PutPropertyDescArray(cx, &pda);
|
||||
SET_BIT_FLAG(jsdval->flags, GOT_PROPS);
|
||||
return !JS_CLIST_IS_EMPTY(&jsdval->props);
|
||||
}
|
||||
|
||||
#undef DROP_CLEAR_VALUE
|
||||
#define DROP_CLEAR_VALUE(jsdc, x) if(x){jsd_DropValue(jsdc,x); x = NULL;}
|
||||
|
||||
void
|
||||
jsd_RefreshValue(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
JSContext* cx = jsdc->dumbContext;
|
||||
|
||||
if(jsdval->string)
|
||||
{
|
||||
/* if the jsval is a string, then we didn't need to root the string */
|
||||
if(!JSVAL_IS_STRING(jsdval->val))
|
||||
JS_RemoveRoot(cx, &jsdval->string);
|
||||
jsdval->string = NULL;
|
||||
}
|
||||
|
||||
jsdval->funName = NULL;
|
||||
jsdval->className = NULL;
|
||||
DROP_CLEAR_VALUE(jsdc, jsdval->proto);
|
||||
DROP_CLEAR_VALUE(jsdc, jsdval->parent);
|
||||
DROP_CLEAR_VALUE(jsdc, jsdval->ctor);
|
||||
_freeProps(jsdc, jsdval);
|
||||
jsdval->flags = 0;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
uintN
|
||||
jsd_GetCountOfProperties(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
JSDProperty* jsdprop;
|
||||
uintN count = 0;
|
||||
|
||||
if(!(CHECK_BIT_FLAG(jsdval->flags, GOT_PROPS)))
|
||||
if(!_buildProps(jsdc, jsdval))
|
||||
return 0;
|
||||
|
||||
for(jsdprop = (JSDProperty*)jsdval->props.next;
|
||||
jsdprop != (JSDProperty*)&jsdval->props;
|
||||
jsdprop = (JSDProperty*)jsdprop->links.next)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
JSDProperty*
|
||||
jsd_IterateProperties(JSDContext* jsdc, JSDValue* jsdval, JSDProperty **iterp)
|
||||
{
|
||||
JSDProperty* jsdprop = *iterp;
|
||||
if(!(CHECK_BIT_FLAG(jsdval->flags, GOT_PROPS)))
|
||||
{
|
||||
JS_ASSERT(!jsdprop);
|
||||
if(!_buildProps(jsdc, jsdval))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!jsdprop)
|
||||
jsdprop = (JSDProperty*)jsdval->props.next;
|
||||
if(jsdprop == (JSDProperty*)&jsdval->props)
|
||||
return NULL;
|
||||
*iterp = (JSDProperty*)jsdprop->links.next;
|
||||
|
||||
JS_ASSERT(jsdprop);
|
||||
jsdprop->nref++;
|
||||
return jsdprop;
|
||||
}
|
||||
|
||||
JSDProperty*
|
||||
jsd_GetValueProperty(JSDContext* jsdc, JSDValue* jsdval, JSString* name)
|
||||
{
|
||||
JSContext* cx = jsdc->dumbContext;
|
||||
JSDProperty* jsdprop;
|
||||
JSDProperty* iter = NULL;
|
||||
JSObject* obj;
|
||||
uintN attrs = 0;
|
||||
JSBool found;
|
||||
JSPropertyDesc pd;
|
||||
const jschar * nameChars;
|
||||
size_t nameLen;
|
||||
jsval val;
|
||||
|
||||
if(!jsd_IsValueObject(jsdc, jsdval))
|
||||
return NULL;
|
||||
|
||||
/* If we already have the prop, then return it */
|
||||
while(NULL != (jsdprop = jsd_IterateProperties(jsdc, jsdval, &iter)))
|
||||
{
|
||||
JSString* propName = jsd_GetValueString(jsdc, jsdprop->name);
|
||||
if(propName && !JS_CompareStrings(propName, name))
|
||||
return jsdprop;
|
||||
JSD_DropProperty(jsdc, jsdprop);
|
||||
}
|
||||
/* Not found in property list, look it up explicitly */
|
||||
|
||||
if(!(obj = JSVAL_TO_OBJECT(jsdval->val)))
|
||||
return NULL;
|
||||
|
||||
nameChars = JS_GetStringChars(name);
|
||||
nameLen = JS_GetStringLength(name);
|
||||
|
||||
/* It's OK if this fails - we just don't get attribs */
|
||||
JS_GetUCPropertyAttributes(cx, obj, nameChars, nameLen, &attrs, &found);
|
||||
|
||||
if(!JS_GetUCProperty(cx, obj, nameChars, nameLen, &val))
|
||||
return NULL;
|
||||
|
||||
/* XXX screwy! no good way to detect that property does not exist at all */
|
||||
if(!found && JSVAL_IS_VOID(val))
|
||||
return NULL;
|
||||
|
||||
pd.id = STRING_TO_JSVAL(name);
|
||||
pd.value = val;
|
||||
pd.alias = pd.slot = pd.spare = 0;
|
||||
pd.flags = 0
|
||||
| (attrs & JSPROP_ENUMERATE) ? JSPD_ENUMERATE : 0
|
||||
| (attrs & JSPROP_READONLY) ? JSPD_READONLY : 0
|
||||
| (attrs & JSPROP_PERMANENT) ? JSPD_PERMANENT : 0;
|
||||
|
||||
return _newProperty(jsdc, &pd, JSDPD_HINTED);
|
||||
}
|
||||
|
||||
|
||||
JSDValue*
|
||||
jsd_GetValuePrototype(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
if(!(CHECK_BIT_FLAG(jsdval->flags, GOT_PROTO)))
|
||||
{
|
||||
JSObject* obj;
|
||||
JSObject* proto;
|
||||
JS_ASSERT(!jsdval->proto);
|
||||
SET_BIT_FLAG(jsdval->flags, GOT_PROTO);
|
||||
if(!JSVAL_IS_OBJECT(jsdval->val))
|
||||
return NULL;
|
||||
if(!(obj = JSVAL_TO_OBJECT(jsdval->val)))
|
||||
return NULL;
|
||||
if(!(proto = OBJ_GET_PROTO(jsdc->dumbContext,obj)))
|
||||
return NULL;
|
||||
jsdval->proto = jsd_NewValue(jsdc, OBJECT_TO_JSVAL(proto));
|
||||
}
|
||||
if(jsdval->proto)
|
||||
jsdval->proto->nref++;
|
||||
return jsdval->proto;
|
||||
}
|
||||
|
||||
JSDValue*
|
||||
jsd_GetValueParent(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
if(!(CHECK_BIT_FLAG(jsdval->flags, GOT_PARENT)))
|
||||
{
|
||||
JSObject* obj;
|
||||
JSObject* parent;
|
||||
JS_ASSERT(!jsdval->parent);
|
||||
SET_BIT_FLAG(jsdval->flags, GOT_PARENT);
|
||||
if(!JSVAL_IS_OBJECT(jsdval->val))
|
||||
return NULL;
|
||||
if(!(obj = JSVAL_TO_OBJECT(jsdval->val)))
|
||||
return NULL;
|
||||
if(!(parent = OBJ_GET_PARENT(jsdc->dumbContext,obj)))
|
||||
return NULL;
|
||||
jsdval->parent = jsd_NewValue(jsdc, OBJECT_TO_JSVAL(parent));
|
||||
}
|
||||
if(jsdval->parent)
|
||||
jsdval->parent->nref++;
|
||||
return jsdval->parent;
|
||||
}
|
||||
|
||||
JSDValue*
|
||||
jsd_GetValueConstructor(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
if(!(CHECK_BIT_FLAG(jsdval->flags, GOT_CTOR)))
|
||||
{
|
||||
JSObject* obj;
|
||||
JSObject* proto;
|
||||
JSObject* ctor;
|
||||
JS_ASSERT(!jsdval->ctor);
|
||||
SET_BIT_FLAG(jsdval->flags, GOT_CTOR);
|
||||
if(!JSVAL_IS_OBJECT(jsdval->val))
|
||||
return NULL;
|
||||
if(!(obj = JSVAL_TO_OBJECT(jsdval->val)))
|
||||
return NULL;
|
||||
if(!(proto = OBJ_GET_PROTO(jsdc->dumbContext,obj)))
|
||||
return NULL;
|
||||
if(!(ctor = JS_GetConstructor(jsdc->dumbContext,proto)))
|
||||
return NULL;
|
||||
jsdval->ctor = jsd_NewValue(jsdc, OBJECT_TO_JSVAL(ctor));
|
||||
}
|
||||
if(jsdval->ctor)
|
||||
jsdval->ctor->nref++;
|
||||
return jsdval->ctor;
|
||||
}
|
||||
|
||||
const char*
|
||||
jsd_GetValueClassName(JSDContext* jsdc, JSDValue* jsdval)
|
||||
{
|
||||
jsval val = jsdval->val;
|
||||
if(!jsdval->className && JSVAL_IS_OBJECT(val))
|
||||
{
|
||||
JSObject* obj;
|
||||
if(!(obj = JSVAL_TO_OBJECT(val)))
|
||||
return NULL;
|
||||
if(OBJ_GET_CLASS(jsdc->dumbContext, obj))
|
||||
jsdval->className = OBJ_GET_CLASS(jsdc->dumbContext, obj)->name;
|
||||
}
|
||||
return jsdval->className;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/***************************************************************************/
|
||||
|
||||
JSDValue*
|
||||
jsd_GetPropertyName(JSDContext* jsdc, JSDProperty* jsdprop)
|
||||
{
|
||||
jsdprop->name->nref++;
|
||||
return jsdprop->name;
|
||||
}
|
||||
|
||||
JSDValue*
|
||||
jsd_GetPropertyValue(JSDContext* jsdc, JSDProperty* jsdprop)
|
||||
{
|
||||
jsdprop->val->nref++;
|
||||
return jsdprop->val;
|
||||
}
|
||||
|
||||
JSDValue*
|
||||
jsd_GetPropertyAlias(JSDContext* jsdc, JSDProperty* jsdprop)
|
||||
{
|
||||
if(jsdprop->alias)
|
||||
jsdprop->alias->nref++;
|
||||
return jsdprop->alias;
|
||||
}
|
||||
|
||||
uintN
|
||||
jsd_GetPropertyFlags(JSDContext* jsdc, JSDProperty* jsdprop)
|
||||
{
|
||||
return jsdprop->flags;
|
||||
}
|
||||
|
||||
uintN
|
||||
jsd_GetPropertyVarArgSlot(JSDContext* jsdc, JSDProperty* jsdprop)
|
||||
{
|
||||
return jsdprop->slot;
|
||||
}
|
||||
|
||||
void
|
||||
jsd_DropProperty(JSDContext* jsdc, JSDProperty* jsdprop)
|
||||
{
|
||||
JS_ASSERT(jsdprop->nref > 0);
|
||||
if(0 == --jsdprop->nref)
|
||||
{
|
||||
JS_ASSERT(JS_CLIST_IS_EMPTY(&jsdprop->links));
|
||||
DROP_CLEAR_VALUE(jsdc, jsdprop->val);
|
||||
DROP_CLEAR_VALUE(jsdc, jsdprop->name);
|
||||
DROP_CLEAR_VALUE(jsdc, jsdprop->alias);
|
||||
free(jsdprop);
|
||||
}
|
||||
}
|
12
js/jsd/jsdb/README
Normal file
12
js/jsd/jsdb/README
Normal file
@ -0,0 +1,12 @@
|
||||
/* jband - 10/26/98 - */
|
||||
|
||||
js/jsd/jsdb is a console debugger using only native code. It is experimental.
|
||||
The only makefile supplied is for Win32.
|
||||
|
||||
jsdb.mak will build a debugger enabled js/src/js.c shell. The debugger is
|
||||
implemented by reflecting the JSD api into JavaScript. The actual debugger
|
||||
logic is fully implemented in debugger.js. The debugger can debug itself. It
|
||||
can also be modified and reloaded at runtime.
|
||||
|
||||
The JavaScript keyword 'debugger' is used to break into the debugger. A 'help()'
|
||||
command is supplied to show available commands when exectution is stopped.
|
1017
js/jsd/jsdb/debugger.js
Normal file
1017
js/jsd/jsdb/debugger.js
Normal file
File diff suppressed because it is too large
Load Diff
46
js/jsd/jsdb/f.js
Normal file
46
js/jsd/jsdb/f.js
Normal file
@ -0,0 +1,46 @@
|
||||
|
||||
/**
|
||||
* for(var p in Script.scripts) {
|
||||
*
|
||||
* var script = Script.scripts[p];
|
||||
* var handle = script.handle;
|
||||
* var base = script.base;
|
||||
* var limit = base + script.extent;
|
||||
*
|
||||
* print(script+"\n");
|
||||
*
|
||||
* for(var i = base; i < limit; i++) {
|
||||
* var pc = jsd.GetClosestPC(handle,i)
|
||||
* var hascode = String(pc).length && i == jsd.GetClosestLine(handle,pc);
|
||||
* print("line "+i+" "+ (hascode ? "has code" : "has NO code"));
|
||||
* }
|
||||
* print("...............................\n");
|
||||
* }
|
||||
*/
|
||||
|
||||
function rlocals()
|
||||
{
|
||||
var retval = "";
|
||||
var name = "___UNIQUE_NAME__";
|
||||
var fun = ""+
|
||||
"var text = \\\"\\\";"+
|
||||
"for(var p in ob)"+
|
||||
"{"+
|
||||
" if(text != \\\"\\\")"+
|
||||
" text += \\\",\\\";"+
|
||||
" text += p;"+
|
||||
"}"+
|
||||
"return text;";
|
||||
|
||||
reval(name+" = new Function(\"ob\",\""+fun+"\")");
|
||||
// show(name);
|
||||
retval = _reval([name+"("+"arguments.callee"+")"]);
|
||||
reval("delete "+name);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
function e(a)
|
||||
{
|
||||
return eval(a);
|
||||
}
|
449
js/jsd/jsdb/jsdb.c
Normal file
449
js/jsd/jsdb/jsdb.c
Normal file
@ -0,0 +1,449 @@
|
||||
/* -*- 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.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* JSDB public and callback functions
|
||||
*/
|
||||
|
||||
#include "jsdbpriv.h"
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(void)
|
||||
_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
|
||||
{
|
||||
int i, j, k, n;
|
||||
|
||||
fputs("jsdb: ", stderr);
|
||||
if (!report) {
|
||||
fprintf(stderr, "%s\n", message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (report->filename)
|
||||
fprintf(stderr, "%s, ", report->filename);
|
||||
if (report->lineno)
|
||||
fprintf(stderr, "line %u: ", report->lineno);
|
||||
fputs(message, stderr);
|
||||
if (!report->linebuf) {
|
||||
putc('\n', stderr);
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(stderr, ":\n%s\n", report->linebuf);
|
||||
n = report->tokenptr - report->linebuf;
|
||||
for (i = j = 0; i < n; i++) {
|
||||
if (report->linebuf[i] == '\t') {
|
||||
for (k = (j + 8) & ~7; j < k; j++)
|
||||
putc('.', stderr);
|
||||
continue;
|
||||
}
|
||||
putc('.', stderr);
|
||||
j++;
|
||||
}
|
||||
fputs("^\n", stderr);
|
||||
}
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(void)
|
||||
jsdb_ScriptHookProc(JSDContext* jsdc,
|
||||
JSDScript* jsdscript,
|
||||
JSBool creating,
|
||||
void* callerdata)
|
||||
{
|
||||
JSDB_Data* data = (JSDB_Data*) callerdata;
|
||||
JSFunction* fun;
|
||||
|
||||
if(data->jsScriptHook &&
|
||||
NULL != (fun = JS_ValueToFunction(data->cxDebugger, data->jsScriptHook)))
|
||||
{
|
||||
jsval result;
|
||||
jsval args[2] = {P2H_SCRIPT(data->cxDebugger, jsdscript),
|
||||
creating ? JSVAL_TRUE : JSVAL_FALSE };
|
||||
JS_CallFunction(data->cxDebugger, NULL, fun, 2, args, &result);
|
||||
}
|
||||
}
|
||||
|
||||
uintN JS_DLL_CALLBACK
|
||||
jsdb_ExecHookHandler(JSDContext* jsdc,
|
||||
JSDThreadState* jsdthreadstate,
|
||||
uintN type,
|
||||
void* callerdata,
|
||||
jsval* rval)
|
||||
{
|
||||
uintN ourRetVal = JSD_HOOK_RETURN_CONTINUE;
|
||||
jsval result;
|
||||
JSFunction* fun;
|
||||
int answer;
|
||||
JSDB_Data* data = (JSDB_Data*) callerdata;
|
||||
JS_ASSERT(data);
|
||||
|
||||
/* if we're already stopped, then don't stop */
|
||||
if(data->jsdthreadstate)
|
||||
return JSD_HOOK_RETURN_CONTINUE;
|
||||
|
||||
if(!jsdb_SetThreadState(data, jsdthreadstate))
|
||||
goto label_bail;
|
||||
|
||||
if(data->jsExecutionHook &&
|
||||
NULL != (fun = JS_ValueToFunction(data->cxDebugger, data->jsExecutionHook)))
|
||||
{
|
||||
jsval arg = INT_TO_JSVAL((int)type);
|
||||
if(!JS_CallFunction(data->cxDebugger, NULL, fun, 1, &arg, &result))
|
||||
goto label_bail;
|
||||
if(!JSVAL_IS_INT(result))
|
||||
goto label_bail;
|
||||
answer = JSVAL_TO_INT(result);
|
||||
|
||||
|
||||
if((answer == JSD_HOOK_RETURN_RET_WITH_VAL ||
|
||||
answer == JSD_HOOK_RETURN_THROW_WITH_VAL) &&
|
||||
!jsdb_EvalReturnExpression(data, rval))
|
||||
{
|
||||
goto label_bail;
|
||||
}
|
||||
|
||||
if(answer >= JSD_HOOK_RETURN_HOOK_ERROR &&
|
||||
answer <= JSD_HOOK_RETURN_CONTINUE_THROW)
|
||||
ourRetVal = answer;
|
||||
else
|
||||
ourRetVal = JSD_HOOK_RETURN_CONTINUE;
|
||||
}
|
||||
|
||||
label_bail:
|
||||
jsdb_SetThreadState(data, NULL);
|
||||
return ourRetVal;
|
||||
}
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ARG_MSG = 0,
|
||||
ARG_FILENAME,
|
||||
ARG_LINENO,
|
||||
ARG_LINEBUF,
|
||||
ARG_TOKEN_OFFSET,
|
||||
ARG_LIMIT
|
||||
} ER_ARGS;
|
||||
|
||||
uintN JS_DLL_CALLBACK
|
||||
jsdb_ErrorReporter(JSDContext* jsdc,
|
||||
JSContext* cx,
|
||||
const char* message,
|
||||
JSErrorReport* report,
|
||||
void* callerdata)
|
||||
{
|
||||
uintN ourRetVal = JSD_ERROR_REPORTER_PASS_ALONG;
|
||||
jsval result;
|
||||
JSFunction* fun;
|
||||
int32 answer;
|
||||
JSDB_Data* data = (JSDB_Data*) callerdata;
|
||||
JS_ASSERT(data);
|
||||
|
||||
if(data->jsErrorReporterHook &&
|
||||
NULL != (fun = JS_ValueToFunction(data->cxDebugger,
|
||||
data->jsErrorReporterHook)))
|
||||
{
|
||||
jsval args[ARG_LIMIT] = {JSVAL_NULL};
|
||||
|
||||
if(message)
|
||||
args[ARG_MSG] =
|
||||
STRING_TO_JSVAL(JS_NewStringCopyZ(cx, message));
|
||||
if(report && report->filename)
|
||||
args[ARG_FILENAME] =
|
||||
STRING_TO_JSVAL(JS_NewStringCopyZ(cx, report->filename));
|
||||
if(report && report->linebuf)
|
||||
args[ARG_LINEBUF] =
|
||||
STRING_TO_JSVAL(JS_NewStringCopyZ(cx, report->linebuf));
|
||||
if(report)
|
||||
args[ARG_LINENO] =
|
||||
INT_TO_JSVAL(report->lineno);
|
||||
if(report && report->linebuf && report->tokenptr)
|
||||
args[ARG_TOKEN_OFFSET] =
|
||||
INT_TO_JSVAL((int)(report->tokenptr - report->linebuf));
|
||||
|
||||
if(!JS_CallFunction(data->cxDebugger, NULL, fun, ARG_LIMIT, args, &result))
|
||||
return ourRetVal;
|
||||
|
||||
if(JS_ValueToInt32(data->cxDebugger, result, &answer))
|
||||
ourRetVal = (uintN) answer;
|
||||
}
|
||||
return ourRetVal;
|
||||
}
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(JSBool)
|
||||
Load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
uintN i;
|
||||
JSString *str;
|
||||
const char *filename;
|
||||
JSScript *script;
|
||||
JSBool ok;
|
||||
jsval result;
|
||||
|
||||
ok = JS_TRUE;
|
||||
for (i = 0; i < argc; i++) {
|
||||
str = JS_ValueToString(cx, argv[i]);
|
||||
if (!str) {
|
||||
ok = JS_FALSE;
|
||||
break;
|
||||
}
|
||||
argv[i] = STRING_TO_JSVAL(str);
|
||||
filename = JS_GetStringBytes(str);
|
||||
errno = 0;
|
||||
script = JS_CompileFile(cx, obj, filename);
|
||||
if (!script)
|
||||
continue;
|
||||
ok = JS_ExecuteScript(cx, obj, script, &result);
|
||||
JS_DestroyScript(cx, script);
|
||||
if (!ok)
|
||||
break;
|
||||
}
|
||||
JS_GC(cx);
|
||||
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx,""));
|
||||
return ok;
|
||||
}
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(JSBool)
|
||||
Write(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
JSString *str = JS_ValueToString(cx, argv[0]);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
printf(JS_GetStringBytes(str));
|
||||
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx,""));
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(JSBool)
|
||||
Gets(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
char buf[1024];
|
||||
if(! gets(buf))
|
||||
return JS_FALSE;
|
||||
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buf));
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(JSBool)
|
||||
Version(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
if (argc > 0 && JSVAL_IS_INT(argv[0]))
|
||||
*rval = INT_TO_JSVAL(JS_SetVersion(cx, JSVAL_TO_INT(argv[0])));
|
||||
else
|
||||
*rval = INT_TO_JSVAL(JS_GetVersion(cx));
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(JSBool)
|
||||
SafeEval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
static char default_filename[] = "jsdb_eval";
|
||||
/* JSContext *cx2; */
|
||||
JSString* textJSString;
|
||||
char* filename;
|
||||
int32 lineno;
|
||||
JSDB_Data* data = (JSDB_Data*) JS_GetContextPrivate(cx);
|
||||
JS_ASSERT(data);
|
||||
|
||||
if(argc < 1 || !(textJSString = JS_ValueToString(cx, argv[0])))
|
||||
{
|
||||
JS_ReportError(cx, "safeEval requires source text as a first argument");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if(argc < 2)
|
||||
filename = default_filename;
|
||||
else
|
||||
{
|
||||
JSString* filenameJSString;
|
||||
if(!(filenameJSString = JS_ValueToString(cx, argv[1])))
|
||||
{
|
||||
JS_ReportError(cx, "safeEval passed non-string filename as 2nd param");
|
||||
return JS_FALSE;
|
||||
}
|
||||
filename = JS_GetStringBytes(filenameJSString);
|
||||
}
|
||||
|
||||
if(argc < 3)
|
||||
lineno = 1;
|
||||
else
|
||||
{
|
||||
if(!JS_ValueToInt32(cx, argv[2], &lineno))
|
||||
{
|
||||
JS_ReportError(cx, "safeEval passed non-int lineno as 3rd param");
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if(! JS_EvaluateScript(cx, obj,
|
||||
JS_GetStringBytes(textJSString),
|
||||
JS_GetStringLength(textJSString),
|
||||
filename, lineno, rval))
|
||||
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx,""));
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(JSBool)
|
||||
NativeBreak(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
#ifdef _WINDOWS
|
||||
_asm int 3;
|
||||
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx,"did _asm int 3;"));
|
||||
#else
|
||||
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx,"only supported for Windows"));
|
||||
#endif
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSFunctionSpec debugger_functions[] = {
|
||||
{"version", Version, 0},
|
||||
{"load", Load, 1},
|
||||
{"write", Write, 0},
|
||||
{"gets", Gets, 0},
|
||||
{"safeEval", SafeEval, 3},
|
||||
{"nativeBreak", NativeBreak, 0},
|
||||
{0}
|
||||
};
|
||||
|
||||
static JSClass debugger_global_class = {
|
||||
"debugger_global", 0,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifdef JSD_LOWLEVEL_SOURCE
|
||||
/*
|
||||
* This facilitates sending source to JSD (the debugger system) in the shell
|
||||
* where the source is loaded using the JSFILE hack in jsscan. The function
|
||||
* below is used as a callback for the jsdbgapi JS_SetSourceHandler hook.
|
||||
* A more normal embedding (e.g. mozilla) loads source itself and can send
|
||||
* source directly to JSD without using this hook scheme.
|
||||
*/
|
||||
static void
|
||||
SendSourceToJSDebugger(const char *filename, uintN lineno,
|
||||
jschar *str, size_t length,
|
||||
void **listenerTSData, JSDContext* jsdc)
|
||||
{
|
||||
JSDSourceText *jsdsrc = (JSDSourceText *) *listenerTSData;
|
||||
|
||||
if (!jsdsrc) {
|
||||
if (!filename)
|
||||
filename = "typein";
|
||||
if (1 == lineno) {
|
||||
jsdsrc = JSD_NewSourceText(jsdc, filename);
|
||||
} else {
|
||||
jsdsrc = JSD_FindSourceForURL(jsdc, filename);
|
||||
if (jsdsrc && JSD_SOURCE_PARTIAL !=
|
||||
JSD_GetSourceStatus(jsdc, jsdsrc)) {
|
||||
jsdsrc = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (jsdsrc) {
|
||||
jsdsrc = JSD_AppendUCSourceText(jsdc,jsdsrc, str, length,
|
||||
JSD_SOURCE_PARTIAL);
|
||||
}
|
||||
*listenerTSData = jsdsrc;
|
||||
}
|
||||
#endif /* JSD_LOWLEVEL_SOURCE */
|
||||
|
||||
static JSBool
|
||||
_initReturn(const char* str, JSBool retval)
|
||||
{
|
||||
if(str)
|
||||
printf("%s\n", str);
|
||||
if(retval)
|
||||
; /* printf("debugger initialized\n"); */
|
||||
else
|
||||
{
|
||||
JS_ASSERT(0);
|
||||
printf("debugger FAILED to initialize\n");
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
#define MAX_DEBUGGER_DEPTH 3
|
||||
|
||||
JS_EXPORT_API(JSBool)
|
||||
JSDB_InitDebugger(JSRuntime* rt, JSDContext* jsdc, int depth)
|
||||
{
|
||||
jsval rvalIgnore;
|
||||
static char load_deb[] = "load('debugger.js')";
|
||||
|
||||
JSDB_Data* data = (JSDB_Data*) calloc(1, sizeof(JSDB_Data));
|
||||
if(!data)
|
||||
return _initReturn("memory alloc error", JS_FALSE);
|
||||
|
||||
data->rtTarget = rt;
|
||||
data->jsdcTarget = jsdc;
|
||||
data->debuggerDepth = depth+1;
|
||||
|
||||
if(!(data->rtDebugger = JS_NewRuntime(8L * 1024L * 1024L)))
|
||||
return _initReturn("debugger runtime creation error", JS_FALSE);
|
||||
|
||||
if(!(data->cxDebugger = JS_NewContext(data->rtDebugger, 8192)))
|
||||
return _initReturn("debugger creation error", JS_FALSE);
|
||||
|
||||
JS_SetContextPrivate(data->cxDebugger, data);
|
||||
|
||||
JS_SetErrorReporter(data->cxDebugger, _ErrorReporter);
|
||||
|
||||
if(!(data->globDebugger =
|
||||
JS_NewObject(data->cxDebugger, &debugger_global_class, NULL, NULL)))
|
||||
return _initReturn("debugger global object creation error", JS_FALSE);
|
||||
|
||||
if(!JS_InitStandardClasses(data->cxDebugger, data->globDebugger))
|
||||
return _initReturn("debugger InitStandardClasses error", JS_FALSE);
|
||||
|
||||
if(!JS_DefineFunctions(data->cxDebugger, data->globDebugger, debugger_functions))
|
||||
return _initReturn("debugger DefineFunctions error", JS_FALSE);
|
||||
|
||||
if(!jsdb_ReflectJSD(data))
|
||||
return _initReturn("debugger reflection of JSD API error", JS_FALSE);
|
||||
|
||||
if(data->debuggerDepth < MAX_DEBUGGER_DEPTH)
|
||||
{
|
||||
JSDContext* jsdc;
|
||||
if(!(jsdc = JSD_DebuggerOnForUser(data->rtDebugger, NULL, NULL)))
|
||||
return _initReturn("failed to create jsdc for nested debugger", JS_FALSE);
|
||||
JSD_JSContextInUse(jsdc, data->cxDebugger);
|
||||
if(!JSDB_InitDebugger(data->rtDebugger, jsdc, data->debuggerDepth))
|
||||
return _initReturn("failed to init nested debugger", JS_FALSE);
|
||||
}
|
||||
|
||||
JSD_SetScriptHook(jsdc, jsdb_ScriptHookProc, data);
|
||||
JSD_SetDebuggerHook(jsdc, jsdb_ExecHookHandler, data);
|
||||
JSD_SetThrowHook(jsdc, jsdb_ExecHookHandler, data);
|
||||
JSD_SetDebugBreakHook(jsdc, jsdb_ExecHookHandler, data);
|
||||
JSD_SetErrorReporter(jsdc, jsdb_ErrorReporter, data);
|
||||
|
||||
#ifdef JSD_LOWLEVEL_SOURCE
|
||||
JS_SetSourceHandler(data->rtDebugger, SendSourceToJSDebugger, jsdc);
|
||||
#endif /* JSD_LOWLEVEL_SOURCE */
|
||||
|
||||
JS_EvaluateScript(data->cxDebugger, data->globDebugger,
|
||||
load_deb, sizeof(load_deb)-1, "jsdb_autoload", 1,
|
||||
&rvalIgnore);
|
||||
|
||||
return _initReturn(NULL, JS_TRUE);
|
||||
}
|
||||
|
50
js/jsd/jsdb/jsdb.h
Normal file
50
js/jsd/jsdb/jsdb.h
Normal file
@ -0,0 +1,50 @@
|
||||
/* -*- 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.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Public headers for JSDB
|
||||
*/
|
||||
|
||||
#ifndef jsdb_h___
|
||||
#define jsdb_h___
|
||||
|
||||
/* Get jstypes.h included first. After that we can use PR macros for doing
|
||||
* this extern "C" stuff!
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
#include "jstypes.h"
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
JS_BEGIN_EXTERN_C
|
||||
#include "jsapi.h"
|
||||
#include "jsdebug.h"
|
||||
JS_END_EXTERN_C
|
||||
|
||||
JS_BEGIN_EXTERN_C
|
||||
|
||||
extern JS_EXPORT_API(JSBool)
|
||||
JSDB_InitDebugger(JSRuntime* rt, JSDContext* jsdc, int depth);
|
||||
|
||||
JS_END_EXTERN_C
|
||||
|
||||
#endif /* jsdb_h___ */
|
102
js/jsd/jsdb/jsdb.mak
Normal file
102
js/jsd/jsdb/jsdb.mak
Normal file
@ -0,0 +1,102 @@
|
||||
|
||||
PROJ = jsdb
|
||||
JSDB = .
|
||||
JSD = $(JSDB)\..
|
||||
JSSRC = $(JSD)\..\src
|
||||
|
||||
!IF "$(BUILD_OPT)" != ""
|
||||
OBJ = Release
|
||||
CC_FLAGS = /DNDEBUG
|
||||
!ELSE
|
||||
OBJ = Debug
|
||||
CC_FLAGS = /DDEBUG
|
||||
LINK_FLAGS = /DEBUG
|
||||
!ENDIF
|
||||
|
||||
CFLAGS = /nologo /MDd /W3 /Gm /GX /Zi /Od\
|
||||
/I $(JSSRC)\
|
||||
/I $(JSD)\
|
||||
/I $(JSDB)\
|
||||
$(CC_FLAGS)\
|
||||
/DWIN32 /DXP_PC /D_WINDOWS /D_WIN32\
|
||||
/DJSDEBUGGER\
|
||||
/DJSDEBUGGER_C_UI\
|
||||
/DJSD_LOWLEVEL_SOURCE\
|
||||
/DJSFILE\
|
||||
/c /Fp$(OBJ)\$(PROJ).pch /Fd$(OBJ)\$(PROJ).pdb /YX -Fo$@ $<
|
||||
|
||||
LFLAGS = /nologo /subsystem:console /incremental:no /machine:I386 $(LINK_FLAGS)\
|
||||
/pdb:$(OBJ)\$(PROJ).pdb -out:$(OBJ)\$(PROJ).exe
|
||||
|
||||
LLIBS = kernel32.lib advapi32.lib $(JSSRC)\$(OBJ)\js32.lib $(JSD)\$(OBJ)\jsd.lib
|
||||
|
||||
CPP=cl.exe
|
||||
LINK32=link.exe
|
||||
|
||||
all: $(OBJ) dlls $(OBJ)\$(PROJ).exe $(OBJ)\debugger.js
|
||||
|
||||
|
||||
HEADERS = $(JSDB)\jsdb.h \
|
||||
$(JSDB)\jsdbpriv.h
|
||||
|
||||
|
||||
OBJECTS = $(OBJ)\js.obj \
|
||||
$(OBJ)\jsdb.obj \
|
||||
$(OBJ)\jsdrefl.obj
|
||||
|
||||
|
||||
$(OBJECTS) : $(HEADERS)
|
||||
|
||||
|
||||
$(OBJ)\$(PROJ).exe: $(OBJECTS)
|
||||
$(LINK32) $(LFLAGS) $** $(LLIBS)
|
||||
|
||||
.c{$(OBJ)}.obj:
|
||||
$(CPP) $(CFLAGS)
|
||||
|
||||
{$(JSSRC)}.c.obj:
|
||||
$(CPP) $(CFLAGS)
|
||||
|
||||
$(OBJ) :
|
||||
mkdir $(OBJ)
|
||||
|
||||
$(OBJ)\js32.dll :
|
||||
@cd ..\..\src
|
||||
@nmake -f js.mak CFG="js - Win32 Debug"
|
||||
@cd ..\jsd\jsdb
|
||||
@echo Copying dll from js/src
|
||||
@copy $(JSSRC)\$(OBJ)\js32.dll $(OBJ) >NUL
|
||||
@copy $(JSSRC)\$(OBJ)\js32.pdb $(OBJ) >NUL
|
||||
|
||||
$(OBJ)\jsd.dll :
|
||||
@cd ..
|
||||
@nmake -f jsd.mak JSD_THREADSAFE=1
|
||||
@cd jsdb
|
||||
@echo Copying dll from js/jsd
|
||||
@copy $(JSD)\$(OBJ)\jsd.dll $(OBJ) >NUL
|
||||
@copy $(JSD)\$(OBJ)\jsd.pdb $(OBJ) >NUL
|
||||
|
||||
dlls : $(OBJ)\js32.dll $(OBJ)\jsd.dll
|
||||
|
||||
$(OBJ)\debugger.js: *.js
|
||||
@echo Copying *.js
|
||||
@copy *.js $(OBJ) >NUL
|
||||
|
||||
clean:
|
||||
@echo Deleting built files
|
||||
@del $(OBJ)\*.pch >NUL
|
||||
@del $(OBJ)\*.obj >NUL
|
||||
@del $(OBJ)\*.exp >NUL
|
||||
@del $(OBJ)\*.lib >NUL
|
||||
@del $(OBJ)\*.idb >NUL
|
||||
@del $(OBJ)\*.pdb >NUL
|
||||
@del $(OBJ)\*.dll >NUL
|
||||
@del $(OBJ)\*.exe >NUL
|
||||
|
||||
deep_clean: clean
|
||||
@cd ..\..\src
|
||||
@nmake -f js.mak CFG="js - Win32 Debug" clean
|
||||
@cd ..\jsd\jsdb
|
||||
@cd ..
|
||||
@nmake -f jsd.mak clean
|
||||
@cd jsdb
|
117
js/jsd/jsdb/jsdbpriv.h
Normal file
117
js/jsd/jsdb/jsdbpriv.h
Normal file
@ -0,0 +1,117 @@
|
||||
/* -*- 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.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Private Headers for JSDB
|
||||
*/
|
||||
|
||||
#ifndef jsdbpriv_h___
|
||||
#define jsdbpriv_h___
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "jstypes.h"
|
||||
#include "jsutil.h" /* Added by JSIFY */
|
||||
#include "jsprf.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "jsdb.h"
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
typedef struct JSDB_Data
|
||||
{
|
||||
JSDContext* jsdcTarget;
|
||||
JSRuntime* rtTarget;
|
||||
JSRuntime* rtDebugger;
|
||||
JSContext* cxDebugger;
|
||||
JSObject* globDebugger;
|
||||
JSObject* jsdOb;
|
||||
jsval jsScriptHook;
|
||||
jsval jsExecutionHook;
|
||||
jsval jsErrorReporterHook;
|
||||
JSDThreadState* jsdthreadstate;
|
||||
int debuggerDepth;
|
||||
|
||||
} JSDB_Data;
|
||||
|
||||
extern JSBool
|
||||
jsdb_ReflectJSD(JSDB_Data* data);
|
||||
|
||||
/***********************************/
|
||||
/*
|
||||
* System to store JSD_xxx handles in jsvals. This supports tracking the
|
||||
* handle's type - both for debugging and for automatic 'dropping' of
|
||||
* reference counted handle types (e.g. JSDValue).
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
JSDB_GENERIC = 0,
|
||||
JSDB_CONTEXT,
|
||||
JSDB_SCRIPT,
|
||||
JSDB_SOURCETEXT,
|
||||
JSDB_THREADSTATE,
|
||||
JSDB_STACKFRAMEINFO,
|
||||
JSDB_VALUE,
|
||||
JSDB_PROPERTY,
|
||||
JSDB_OBJECT
|
||||
} JSDBHandleType;
|
||||
|
||||
#define H2P_GENERIC(cx,val) (void*) jsdb_HandleValToPointer((cx),(val),JSDB_GENERIC)
|
||||
#define H2P_CONTEXT(cx,val) (JSDContext*) jsdb_HandleValToPointer((cx),(val),JSDB_CONTEXT)
|
||||
#define H2P_SCRIPT(cx,val) (JSDScript*) jsdb_HandleValToPointer((cx),(val),JSDB_SCRIPT)
|
||||
#define H2P_SOURCETEXT(cx,val) (JSDSourceText*) jsdb_HandleValToPointer((cx),(val),JSDB_SOURCETEXT)
|
||||
#define H2P_THREADSTATE(cx,val) (JSDThreadState*) jsdb_HandleValToPointer((cx),(val),JSDB_THREADSTATE)
|
||||
#define H2P_STACKFRAMEINFO(cx,val) (JSDStackFrameInfo*) jsdb_HandleValToPointer((cx),(val),JSDB_STACKFRAMEINFO)
|
||||
#define H2P_VALUE(cx,val) (JSDValue*) jsdb_HandleValToPointer((cx),(val),JSDB_VALUE)
|
||||
#define H2P_PROPERTY(cx,val) (JSDProperty*) jsdb_HandleValToPointer((cx),(val),JSDB_PROPERTY)
|
||||
#define H2P_OBJECT(cx,val) (JSDObject*) jsdb_HandleValToPointer((cx),(val),JSDB_OBJECT)
|
||||
|
||||
#define P2H_GENERIC(cx,ptr) jsdb_PointerToNewHandleVal((cx),(ptr),JSDB_GENERIC)
|
||||
#define P2H_CONTEXT(cx,ptr) jsdb_PointerToNewHandleVal((cx),(ptr),JSDB_CONTEXT)
|
||||
#define P2H_SCRIPT(cx,ptr) jsdb_PointerToNewHandleVal((cx),(ptr),JSDB_SCRIPT)
|
||||
#define P2H_SOURCETEXT(cx,ptr) jsdb_PointerToNewHandleVal((cx),(ptr),JSDB_SOURCETEXT)
|
||||
#define P2H_THREADSTATE(cx,ptr) jsdb_PointerToNewHandleVal((cx),(ptr),JSDB_THREADSTATE)
|
||||
#define P2H_STACKFRAMEINFO(cx,ptr) jsdb_PointerToNewHandleVal((cx),(ptr),JSDB_STACKFRAMEINFO)
|
||||
#define P2H_VALUE(cx,ptr) jsdb_PointerToNewHandleVal((cx),(ptr),JSDB_VALUE)
|
||||
#define P2H_PROPERTY(cx,ptr) jsdb_PointerToNewHandleVal((cx),(ptr),JSDB_PROPERTY)
|
||||
#define P2H_OBJECT(cx,ptr) jsdb_PointerToNewHandleVal((cx),(ptr),JSDB_OBJECT)
|
||||
|
||||
extern jsval
|
||||
jsdb_PointerToNewHandleVal(JSContext *cx, void* ptr, JSDBHandleType type);
|
||||
|
||||
extern void*
|
||||
jsdb_HandleValToPointer(JSContext *cx, jsval val, JSDBHandleType type);
|
||||
|
||||
/***********************************/
|
||||
|
||||
extern JSBool
|
||||
jsdb_SetThreadState(JSDB_Data* data, JSDThreadState* jsdthreadstate);
|
||||
|
||||
extern uintN JS_DLL_CALLBACK
|
||||
jsdb_ExecHookHandler(JSDContext* jsdc,
|
||||
JSDThreadState* jsdthreadstate,
|
||||
uintN type,
|
||||
void* callerdata,
|
||||
jsval* rval);
|
||||
|
||||
extern JSBool
|
||||
jsdb_EvalReturnExpression(JSDB_Data* data, jsval* rval);
|
||||
|
||||
#endif /* jsdbpriv_h___ */
|
2184
js/jsd/jsdb/jsdrefl.c
Normal file
2184
js/jsd/jsdb/jsdrefl.c
Normal file
File diff suppressed because it is too large
Load Diff
1
js/jsd/jsdb/mk.bat
Executable file
1
js/jsd/jsdb/mk.bat
Executable file
@ -0,0 +1 @@
|
||||
nmake -f jsdb.mak %1 %2 %3 %4 %5 %6 %7 %8 %9
|
56
js/jsd/jsdb/objects.js
Normal file
56
js/jsd/jsdb/objects.js
Normal file
@ -0,0 +1,56 @@
|
||||
// some tests...
|
||||
|
||||
function set_a(a) {this.a = a;}
|
||||
function set_b(b) {this.b = b;}
|
||||
function set_c(c) {this.c = c;}
|
||||
|
||||
function f_ctor(a,b,c)
|
||||
{
|
||||
this.set_a = set_a;
|
||||
this.set_b = set_b;
|
||||
this.set_c = set_c;
|
||||
|
||||
// NOTE: these break JSD_LOWLEVEL_SOURCE in shell debugger
|
||||
this.get_a = new Function("return this.a;");
|
||||
// this.get_b = new Function("return this.b;");
|
||||
// this.get_c = new Function("return this.c;");
|
||||
|
||||
// this.get_a = function() {return this.a;};
|
||||
this.get_b = function() {return this.b;};
|
||||
this.get_c = function() {return this.c;};
|
||||
|
||||
this.set_a(a);
|
||||
this.set_b(b);
|
||||
this.set_c(c);
|
||||
}
|
||||
|
||||
function f2_ctor(param)
|
||||
{
|
||||
this.A = new f_ctor(1,2,3);
|
||||
this.b = new f_ctor("A","B","C");
|
||||
this.number = param;
|
||||
}
|
||||
|
||||
function callMe()
|
||||
{
|
||||
var A = new f2_ctor(1);
|
||||
debugger;
|
||||
var b = new f2_ctor(5);
|
||||
}
|
||||
|
||||
function foo(a,b,c,d,e,f)
|
||||
{
|
||||
var g;
|
||||
var h;
|
||||
var i;
|
||||
var j;
|
||||
debugger;
|
||||
}
|
||||
|
||||
A = new f2_ctor(0);
|
||||
AA = new f2_ctor(100);
|
||||
callMe();
|
||||
foo(1,2,3,4,5);
|
||||
|
||||
A.A.set_b(8);
|
||||
print(A.A.get_b());
|
1
js/jsd/jsdb/test.js
Normal file
1
js/jsd/jsdb/test.js
Normal file
@ -0,0 +1 @@
|
||||
load('objects.js')
|
841
js/jsd/jsdebug.c
841
js/jsd/jsdebug.c
File diff suppressed because it is too large
Load Diff
1191
js/jsd/jsdebug.h
1191
js/jsd/jsdebug.h
File diff suppressed because it is too large
Load Diff
112
js/jsd/jsdshell.mak
Normal file
112
js/jsd/jsdshell.mak
Normal file
@ -0,0 +1,112 @@
|
||||
|
||||
PROJ = jsdshell
|
||||
JSD = .
|
||||
JSDJAVA = $(JSD)\java
|
||||
JS = $(JSD)\..\src
|
||||
RUN = $(JSD)\run
|
||||
JSPROJ = js32
|
||||
JSDPROJ = jsd
|
||||
JSDJAVAPROJ = jsdjava
|
||||
|
||||
!IF "$(BUILD_OPT)" != ""
|
||||
OPT = BUILD_OPT=1
|
||||
OBJ = Release
|
||||
CC_FLAGS = /DNDEBUG
|
||||
!ELSE
|
||||
OPT =
|
||||
OBJ = Debug
|
||||
CC_FLAGS = /DDEBUG
|
||||
LINK_FLAGS = /DEBUG
|
||||
!ENDIF
|
||||
|
||||
QUIET=@
|
||||
|
||||
CFLAGS = /nologo /MDd /W3 /Gm /GX /Zi /Od\
|
||||
/I $(JS)\
|
||||
/I $(JSD)\
|
||||
/DDEBUG /DWIN32 /D_CONSOLE /DXP_PC /D_WINDOWS /D_WIN32\
|
||||
/DJSDEBUGGER\
|
||||
!IF "$(JSDEBUGGER_JAVA_UI)" != ""
|
||||
/I $(JSDJAVA)\
|
||||
/DJSDEBUGGER_JAVA_UI\
|
||||
/DJSD_STANDALONE_JAVA_VM\
|
||||
!ENDIF
|
||||
/DJSD_LOWLEVEL_SOURCE\
|
||||
/DJSFILE\
|
||||
$(CC_FLAGS)\
|
||||
/c /Fp$(OBJ)\$(PROJ).pch /Fd$(OBJ)\$(PROJ).pdb /YX -Fo$@ $<
|
||||
|
||||
LFLAGS = /nologo /subsystem:console /incremental:no /machine:I386 \
|
||||
$(LINK_FLAGS) /pdb:$(OBJ)\$(PROJ).pdb -out:$(OBJ)\$(PROJ).exe
|
||||
|
||||
LLIBS = kernel32.lib advapi32.lib \
|
||||
$(JS)\$(OBJ)\$(JSPROJ).lib \
|
||||
$(JSD)\$(OBJ)\$(JSDPROJ).lib \
|
||||
$(JSDJAVA)\$(OBJ)\$(JSDJAVAPROJ).lib
|
||||
|
||||
CPP=cl.exe
|
||||
LINK32=link.exe
|
||||
|
||||
all: $(OBJ) $(RUN) dlls $(OBJ)\$(PROJ).exe copy_binaries
|
||||
|
||||
$(OBJ)\$(PROJ).exe: \
|
||||
$(OBJ)\js.obj
|
||||
$(QUIET)$(LINK32) $(LFLAGS) $** $(LLIBS)
|
||||
|
||||
|
||||
{$(JS)}.c{$(OBJ)}.obj :
|
||||
$(QUIET)$(CPP) $(CFLAGS)
|
||||
|
||||
dlls :
|
||||
$(QUIET)cd ..\src
|
||||
!IF "$(BUILD_OPT)" != ""
|
||||
$(QUIET)nmake -f js.mak CFG="js - Win32 Release"
|
||||
!ELSE
|
||||
$(QUIET)nmake -f js.mak CFG="js - Win32 Debug"
|
||||
!ENDIF
|
||||
$(QUIET)cd ..\jsd
|
||||
$(QUIET)nmake -f jsd.mak JSD_THREADSAFE=1 $(OPT)
|
||||
$(QUIET)cd java
|
||||
$(QUIET)nmake -f jsdjava.mak JSD_STANDALONE_JAVA_VM=1 $(OPT)
|
||||
$(QUIET)cd ..
|
||||
|
||||
copy_binaries :
|
||||
@echo copying binaries
|
||||
$(QUIET)copy $(JS)\$(OBJ)\$(JSPROJ).dll $(RUN) >NUL
|
||||
$(QUIET)copy $(JS)\$(OBJ)\$(JSPROJ).pdb $(RUN) >NUL
|
||||
$(QUIET)copy $(JSD)\$(OBJ)\$(JSDPROJ).dll $(RUN) >NUL
|
||||
$(QUIET)copy $(JSD)\$(OBJ)\$(JSDPROJ).pdb $(RUN) >NUL
|
||||
$(QUIET)copy $(JSDJAVA)\$(OBJ)\$(JSDJAVAPROJ).dll $(RUN) >NUL
|
||||
$(QUIET)copy $(JSDJAVA)\$(OBJ)\$(JSDJAVAPROJ).pdb $(RUN) >NUL
|
||||
$(QUIET)copy $(OBJ)\$(PROJ).pdb $(RUN) >NUL
|
||||
$(QUIET)copy $(OBJ)\$(PROJ).exe $(RUN) >NUL
|
||||
|
||||
$(OBJ) :
|
||||
$(QUIET)mkdir $(OBJ)
|
||||
|
||||
$(RUN) :
|
||||
$(QUIET)mkdir $(RUN)
|
||||
|
||||
clean:
|
||||
@echo deleting old output
|
||||
$(QUIET)del $(OBJ)\js.obj >NUL
|
||||
$(QUIET)del $(OBJ)\$(PROJ).pch >NUL
|
||||
$(QUIET)del $(OBJ)\$(PROJ)*.idb >NUL
|
||||
$(QUIET)del $(OBJ)\$(PROJ).pdb >NUL
|
||||
$(QUIET)del $(OBJ)\$(PROJ).exe >NUL
|
||||
$(QUIET)del $(RUN)\*.pdb >NUL
|
||||
$(QUIET)del $(RUN)\*.exe >NUL
|
||||
$(QUIET)del $(RUN)\*.dll >NUL
|
||||
|
||||
deep_clean: clean
|
||||
$(QUIET)cd ..\src
|
||||
!IF "$(BUILD_OPT)" != ""
|
||||
$(QUIET)nmake -f js.mak CFG="js - Win32 Release" clean
|
||||
!ELSE
|
||||
$(QUIET)nmake -f js.mak CFG="js - Win32 Debug" clean
|
||||
!ENDIF
|
||||
$(QUIET)cd ..\jsd
|
||||
$(QUIET)nmake -f jsd.mak clean
|
||||
$(QUIET)cd java
|
||||
$(QUIET)nmake -f jsdjava.mak clean
|
||||
$(QUIET)cd ..
|
@ -16,6 +16,10 @@
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/* this is all going away... replaced by code in js/jsd/java */
|
||||
|
||||
#if 0
|
||||
|
||||
#ifndef XP_MAC
|
||||
#include "_stubs/netscape_jsdebug_Script.c"
|
||||
#include "_stubs/netscape_jsdebug_DebugController.c"
|
||||
@ -31,3 +35,5 @@
|
||||
#include "netscape_jsdebug_JSPC.c"
|
||||
#include "n_j_JSSourceTextProvider.c"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,35 +1,29 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
#// The contents of this file are subject to the Netscape Public License
|
||||
#// Version 1.0 (the "NPL"); you may not use this file except in
|
||||
#// compliance with the NPL. You may obtain a copy of the NPL at
|
||||
#// http://www.mozilla.org/NPL/
|
||||
#//
|
||||
#// Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
#// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
#// for the specific language governing rights and limitations under the
|
||||
#// NPL.
|
||||
#//
|
||||
#// The Initial Developer of this code under the NPL is Netscape
|
||||
#// Communications Corporation. Portions created by Netscape are
|
||||
#// Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
#// Reserved.
|
||||
|
||||
IGNORE_MANIFEST=1
|
||||
|
||||
#
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Specify the depth of the current directory relative to the
|
||||
#// root of NS
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
DEPTH=..\..
|
||||
include <$(DEPTH)\config\config.mak>
|
||||
|
||||
DEPTH = ..\..
|
||||
|
||||
# Turn on/off depending on
|
||||
!ifdef MOZ_JSD
|
||||
DIRS = classes
|
||||
!ifdef MOZ_OJI
|
||||
# DIRS = java classes
|
||||
!endif
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
@ -41,87 +35,58 @@ DIRS = classes
|
||||
DLLNAME = jsd$(MOZ_BITS)$(VERSION_NUMBER)
|
||||
PDBFILE = $(DLLNAME).pdb
|
||||
MAPFILE = $(DLLNAME).map
|
||||
RESFILE = $(DLLNAME).res
|
||||
RESFILE = jsd$(MOZ_BITS)40.res
|
||||
DLL =.\$(OBJDIR)\$(DLLNAME).dll
|
||||
MAKE_OBJ_TYPE = DLL
|
||||
|
||||
!if "$(MOZ_BITS)" != "16"
|
||||
LINCS = -I$(PUBLIC)/java \
|
||||
-I$(PUBLIC)/applet \
|
||||
-I$(DEPTH)\include
|
||||
LINCS = -I$(DEPTH)\include \
|
||||
-I$(PUBLIC)\js
|
||||
!endif
|
||||
|
||||
!if "$(MOZ_BITS)" == "16"
|
||||
DEFFILE = $(DLLNAME).def
|
||||
!endif
|
||||
|
||||
# LCFLAGS= $(LCFLAGS) -DEXPORT_JSD_API -DJSD_THREADSAFE
|
||||
|
||||
LLIBS= $(LIBNSPR) \
|
||||
$(DIST)\lib\js$(MOZ_BITS)$(VERSION_NUMBER).lib \
|
||||
$(DIST)\lib\jrt$(MOZ_BITS)$(VERSION_NUMBER).lib
|
||||
!ifdef MOZ_OJI
|
||||
$(DIST)\lib\oji$(MOZ_BITS).lib
|
||||
!endif
|
||||
|
||||
!if "$(MOZ_BITS)"=="32" && defined(MOZ_DEBUG) && defined(GLOWCODE)
|
||||
LLIBS=$(LLIBS) $(GLOWDIR)\glowcode.lib
|
||||
!endif
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Define the files necessary to build the target (ie. OBJS)
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
OBJS = \
|
||||
.\$(OBJDIR)\jsdebug.obj \
|
||||
.\$(OBJDIR)\jsd_high.obj \
|
||||
.\$(OBJDIR)\jsd_hook.obj \
|
||||
.\$(OBJDIR)\jsd_lock.obj \
|
||||
.\$(OBJDIR)\jsd_scpt.obj \
|
||||
.\$(OBJDIR)\jsd_stak.obj \
|
||||
.\$(OBJDIR)\jsd_step.obj \
|
||||
.\$(OBJDIR)\jsd_text.obj \
|
||||
.\$(OBJDIR)\jsd_val.obj \
|
||||
$(NULL)
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// install headers
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
|
||||
INSTALL_DIR=$(PUBLIC)\jsdebug
|
||||
|
||||
INSTALL_DIR=$(PUBLIC)\jsd
|
||||
INSTALL_FILE_LIST= \
|
||||
jsdebug.h \
|
||||
$(NULL)
|
||||
|
||||
|
||||
MODULE=jsdebug
|
||||
|
||||
REQUIRES=java js nspr
|
||||
|
||||
CSRCS= \
|
||||
jsdebug.c \
|
||||
jsd_high.c \
|
||||
jsd_hook.c \
|
||||
!ifdef MOZ_JSD
|
||||
jsdstubs.c \
|
||||
jsd_java.c \
|
||||
!endif
|
||||
jsd_scpt.c \
|
||||
jsd_stak.c \
|
||||
jsd_text.c
|
||||
|
||||
LIBRARY_NAME=jsd
|
||||
|
||||
!ifdef MOZ_JSD
|
||||
JDK_GEN=netscape.jsdebug.Script netscape.jsdebug.DebugController \
|
||||
netscape.jsdebug.JSThreadState netscape.jsdebug.JSStackFrameInfo \
|
||||
netscape.jsdebug.JSPC netscape.jsdebug.JSSourceTextProvider \
|
||||
netscape.jsdebug.JSErrorReporter
|
||||
!endif
|
||||
|
||||
EXPORTS=jsdebug.h
|
||||
|
||||
C_OBJS= \
|
||||
.\$(OBJDIR)\jsdebug.obj \
|
||||
.\$(OBJDIR)\jsd_high.obj \
|
||||
.\$(OBJDIR)\jsd_hook.obj \
|
||||
!ifdef MOZ_JSD
|
||||
.\$(OBJDIR)\jsdstubs.obj \
|
||||
.\$(OBJDIR)\jsd_java.obj \
|
||||
!endif
|
||||
.\$(OBJDIR)\jsd_scpt.obj \
|
||||
.\$(OBJDIR)\jsd_stak.obj \
|
||||
.\$(OBJDIR)\jsd_text.obj
|
||||
|
||||
|
||||
!if "$(MOZ_BITS)" != "16"
|
||||
LINCS=-I$(XPDIST)\public\java -I$(XPDIST)\public\js \
|
||||
-I$(XPDIST)\public\nspr
|
||||
!endif
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Include the common makefile rules
|
||||
@ -133,18 +98,6 @@ install:: $(DLL)
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).dll $(DIST)\bin
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).lib $(DIST)\lib
|
||||
|
||||
clobber::
|
||||
$(RM_R) _gen
|
||||
$(RM_R) _stubs
|
||||
|
||||
.\$(OBJDIR)\jsdstubs.o: \
|
||||
$(JDK_STUB_DIR)\netscape_jsdebug_Script.c \
|
||||
$(JDK_STUB_DIR)\netscape_jsdebug_DebugController.c \
|
||||
$(JDK_STUB_DIR)\netscape_jsdebug_JSThreadState.c \
|
||||
$(JDK_STUB_DIR)\netscape_jsdebug_JSStackFrameInfo.c \
|
||||
$(JDK_STUB_DIR)\netscape_jsdebug_JSPC.c \
|
||||
$(JDK_STUB_DIR)\netscape_jsdebug_JSSourceTextProvider.c
|
||||
|
||||
export:: INSTALL_FILES
|
||||
|
||||
|
||||
|
4
js/jsd/mkshell.bat
Executable file
4
js/jsd/mkshell.bat
Executable file
@ -0,0 +1,4 @@
|
||||
@echo off
|
||||
REM nmake -f jsdshell.mak JSDEBUGGER_JAVA_UI=1 LIVECONNECT=1 %1 %2 %3 %4 %5
|
||||
@echo on
|
||||
nmake -f jsdshell.mak JSDEBUGGER_JAVA_UI=1 %1 %2 %3 %4 %5
|
Loading…
Reference in New Issue
Block a user