(not part of mozilla build) added source hook to jsdbgapi so that debugger can get clean access to source from jsscan when the JSFILE hack is used

This commit is contained in:
jband%netscape.com 1998-09-11 04:04:26 +00:00
Родитель a65a3ac653
Коммит a176d21d9e
7 изменённых файлов: 83 добавлений и 317 удалений

Просмотреть файл

@ -1082,6 +1082,63 @@ static JSPropertySpec its_props[] = {
{0}
};
#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.
*
* XXX At some future point JSD will understand Unicode source and the
* *very* ugly conversion below will be unnecessary.
*/
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) {
/* here we convert our Unicode into a C string to pass to JSD */
#define JSD_BUF_SIZE 1024
static char* buf = NULL;
int remaining = length;
if (!buf)
buf = malloc(JSD_BUF_SIZE);
if (buf)
{
while (remaining && jsdsrc) {
int bytes = PR_MIN(remaining, JSD_BUF_SIZE);
int i;
for (i = 0; i < bytes; i++)
buf[i] = (const char) *(str++);
jsdsrc = JSD_AppendSourceText(jsdc,jsdsrc,
buf, bytes,
JSD_SOURCE_PARTIAL);
remaining -= bytes;
}
}
}
*listenerTSData = jsdsrc;
}
#endif /* JSD_LOWLEVEL_SOURCE */
static JSBool its_noisy; /* whether to be noisy when finalizing it */
static JSBool
@ -1438,7 +1495,9 @@ main(int argc, char **argv)
if (!_jsdc)
return 1;
JSD_JSContextInUse(_jsdc, cx);
#ifdef JSD_LOWLEVEL_SOURCE
JS_SetSourceHandler(rt, SendSourceToJSDebugger, _jsdc);
#endif /* JSD_LOWLEVEL_SOURCE */
#ifdef JSDEBUGGER_JAVA_UI
_jsdjc = JSDJ_CreateContext();
if (! _jsdjc)

Просмотреть файл

@ -82,6 +82,8 @@ struct JSRuntime {
void *destroyScriptHookData;
JSTrapHandler debuggerHandler;
void *debuggerHandlerData;
JSSourceHandler sourceHandler;
void *sourceHandlerData;
/* More debugging state, see jsdbgapi.c. */
PRCList trapList;

Просмотреть файл

@ -806,3 +806,11 @@ JS_SetDebuggerHandler(JSRuntime *rt, JSTrapHandler handler, void *closure)
rt->debuggerHandlerData = closure;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_SetSourceHandler(JSRuntime *rt, JSSourceHandler handler, void *closure)
{
rt->sourceHandler = handler;
rt->sourceHandlerData = closure;
return JS_TRUE;
}

Просмотреть файл

@ -223,6 +223,9 @@ JS_PutPropertyDescArray(JSContext *cx, JSPropertyDescArray *pda);
extern JS_PUBLIC_API(JSBool)
JS_SetDebuggerHandler(JSRuntime *rt, JSTrapHandler handler, void *closure);
extern JS_PUBLIC_API(JSBool)
JS_SetSourceHandler(JSRuntime *rt, JSSourceHandler handler, void *closure);
PR_END_EXTERN_C
#endif /* jsdbgapi_h___ */

Просмотреть файл

@ -96,4 +96,9 @@ typedef void
JSScript *script,
void *callerdata );
typedef void
(*JSSourceHandler)(const char *filename, uintN lineno,
jschar *str, size_t length,
void **listenerTSData, void *closure);
#endif /* jsprvtd_h___ */

Просмотреть файл

@ -201,9 +201,8 @@ js_NewBufferTokenStream(JSContext *cx, const jschar *base, size_t length)
ts->userbuf.base = (jschar *)base;
ts->userbuf.limit = (jschar *)base + length;
ts->userbuf.ptr = (jschar *)base;
#ifdef JSD_LOWLEVEL_SOURCE
ts->jsdc = JSD_JSDContextForJSContext(cx);
#endif
ts->listener = cx->runtime->sourceHandler;
ts->listenerData = cx->runtime->sourceHandlerData;
return ts;
}
@ -250,48 +249,6 @@ js_CloseTokenStream(JSContext *cx, JSTokenStream *ts)
#endif
}
#ifdef JSD_LOWLEVEL_SOURCE
static void
SendSourceToJSDebugger(JSTokenStream *ts, jschar *str, size_t length)
{
if (!ts->jsdsrc) {
const char* filename = ts->filename ? ts->filename : "typein";
if (1 == ts->lineno) {
ts->jsdsrc = JSD_NewSourceText(ts->jsdc, filename);
} else {
ts->jsdsrc = JSD_FindSourceForURL(ts->jsdc, filename);
if (ts->jsdsrc && JSD_SOURCE_PARTIAL !=
JSD_GetSourceStatus(ts->jsdc, ts->jsdsrc)) {
ts->jsdsrc = NULL;
}
}
}
if (ts->jsdsrc) {
/* here we convert our Unicode into a C string to pass to JSD */
#define JSD_BUF_SIZE 1024
static char* buf = NULL;
int remaining = length;
if (!buf)
buf = malloc(JSD_BUF_SIZE);
if (buf)
{
while (remaining && ts->jsdsrc) {
int bytes = PR_MIN(remaining, JSD_BUF_SIZE);
int i;
for (i = 0; i < bytes; i++)
buf[i] = (const char) *(str++);
ts->jsdsrc = JSD_AppendSourceText(ts->jsdc,ts->jsdsrc,
buf, bytes,
JSD_SOURCE_PARTIAL);
remaining -= bytes;
}
}
}
}
#endif
static int32
GetChar(JSTokenStream *ts)
{
@ -341,12 +298,9 @@ GetChar(JSTokenStream *ts)
return EOF;
}
}
#ifdef JSD_LOWLEVEL_SOURCE
if (ts->jsdc)
SendSourceToJSDebugger(ts, ts->userbuf.ptr, len);
#endif
if (ts->listener)
(*ts->listener)(ts->filename, ts->lineno, ts->userbuf.ptr, len,
&ts->listenerTSData, ts->listenerData);
/*
* Any one of \n, \r, or \r\n ends a line (longest match wins).
*/

Просмотреть файл

@ -1,265 +0,0 @@
/* -*- 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.
*/
#ifndef jsscan_h___
#define jsscan_h___
/*
* JS lexical scanner interface.
*/
#include <stddef.h>
#ifdef JSFILE
#include <stdio.h>
#endif
#include "jsopcode.h"
#include "jsprvtd.h"
#include "jspubtd.h"
#ifdef JSD_LOWLEVEL_SOURCE
#include "jsdebug.h"
#endif
PR_BEGIN_EXTERN_C
typedef enum JSTokenType {
TOK_ERROR = -1, /* well-known as the only code < EOF */
TOK_EOF = 0, /* end of file */
TOK_EOL = 1, /* end of line */
TOK_SEMI = 2, /* semicolon */
TOK_LB = 3, TOK_RB = 4, /* left and right brackets */
TOK_LC = 5, TOK_RC = 6, /* left and right curlies (braces) */
TOK_LP = 7, TOK_RP = 8, /* left and right parentheses */
TOK_COMMA = 9, /* comma operator */
TOK_ASSIGN = 10, /* assignment ops (= += -= etc.) */
TOK_HOOK = 11, TOK_COLON = 12, /* conditional (?:) */
TOK_OR = 13, /* logical or (||) */
TOK_AND = 14, /* logical and (&&) */
TOK_BITOR = 15, /* bitwise-or (|) */
TOK_BITXOR = 16, /* bitwise-xor (^) */
TOK_BITAND = 17, /* bitwise-and (&) */
TOK_EQOP = 18, /* equality ops (== !=) */
TOK_RELOP = 19, /* relational ops (< <= > >=) */
TOK_SHOP = 20, /* shift ops (<< >> >>>) */
TOK_PLUS = 21, /* plus */
TOK_MINUS = 22, /* minus */
TOK_STAR = 23, TOK_DIVOP = 24, /* multiply/divide ops (* / %) */
TOK_UNARYOP = 25, /* unary prefix operator */
TOK_INC = 26, TOK_DEC = 27, /* increment/decrement (++ --) */
TOK_DOT = 28, /* member operator (.) */
TOK_NAME = 29, /* identifier */
TOK_NUMBER = 30, /* numeric constant */
TOK_STRING = 31, /* string constant */
TOK_OBJECT = 32, /* RegExp or other object constant */
TOK_PRIMARY = 33, /* true, false, null, this, super */
TOK_FUNCTION = 34, /* function keyword */
TOK_EXPORT = 35, /* export keyword */
TOK_IMPORT = 36, /* import keyword */
TOK_IF = 37, /* if keyword */
TOK_ELSE = 38, /* else keyword */
TOK_SWITCH = 39, /* switch keyword */
TOK_CASE = 40, /* case keyword */
TOK_DEFAULT = 41, /* default keyword */
TOK_WHILE = 42, /* while keyword */
TOK_DO = 43, /* do keyword */
TOK_FOR = 44, /* for keyword */
TOK_BREAK = 45, /* break keyword */
TOK_CONTINUE = 46, /* continue keyword */
TOK_IN = 47, /* in keyword */
TOK_VAR = 48, /* var keyword */
TOK_WITH = 49, /* with keyword */
TOK_RETURN = 50, /* return keyword */
TOK_NEW = 51, /* new keyword */
TOK_DELETE = 52, /* delete keyword */
TOK_DEFSHARP = 53, /* #n= for object/array initializers */
TOK_USESHARP = 54, /* #n# for object/array initializers */
TOK_TRY = 55, /* try keyword */
TOK_CATCH = 56, /* catch keyword */
TOK_FINALLY = 57, /* finally keyword */
TOK_THROW = 58, /* throw keyword */
TOK_INSTANCEOF = 59, /* instanceof keyword */
TOK_DEBUGGER = 60, /* debugger keyword */
TOK_RESERVED, /* reserved keywords */
TOK_LIMIT /* domain size */
} JSTokenType;
#define IS_PRIMARY_TOKEN(tt) \
((uintN)((tt) - TOK_NAME) <= (uintN)(TOK_PRIMARY - TOK_NAME))
struct JSTokenPtr {
uint16 index; /* index of char in physical line */
uint16 lineno; /* physical line number */
};
struct JSTokenPos {
JSTokenPtr begin; /* first character and line of token */
JSTokenPtr end; /* index 1 past last char, last line */
};
struct JSToken {
JSTokenType type; /* char value or above enumerator */
JSTokenPos pos; /* token position in file */
jschar *ptr; /* beginning of token in line buffer */
union {
struct {
JSOp op; /* operator, for minimal parser */
JSAtom *atom; /* atom table entry */
} s;
jsdouble dval; /* floating point number */
} u;
};
#define t_op u.s.op
#define t_atom u.s.atom
#define t_dval u.dval
typedef struct JSTokenBuf {
jschar *base; /* base of line or stream buffer */
jschar *limit; /* limit for quick bounds check */
jschar *ptr; /* next char to get, or slot to use */
} JSTokenBuf;
#define JS_LINE_LIMIT 256 /* logical line buffer size limit --
physical line length is unlimited */
struct JSTokenStream {
JSToken token; /* last token scanned */
JSToken pushback; /* pushed-back already-scanned token */
uintN lineno; /* current line number */
uintN ungetpos; /* next free char slot in ungetbuf */
jschar ungetbuf[4]; /* at most 4, for \uXXXX lookahead */
uintN flags; /* flags -- see below */
ptrdiff_t linelen; /* physical linebuf segment length */
ptrdiff_t linepos; /* linebuf offset in physical line */
JSTokenBuf linebuf; /* line buffer for diagnostics */
JSTokenBuf userbuf; /* user input buffer if !file */
JSTokenBuf tokenbuf; /* current token string buffer */
const char *filename; /* input filename or null */
#ifdef JSFILE
FILE *file; /* stdio stream if reading from file */
#endif
JSPrincipals *principals; /* principals associated with given input */
#ifdef JSD_LOWLEVEL_SOURCE
JSDContext *jsdc; /* used to cram source into debugger */
JSDSourceText *jsdsrc; /* used to cram source into debugger */
#endif
};
/* JSTokenStream flags */
#define TSF_ERROR 0x01 /* fatal error while scanning */
#define TSF_EOF 0x02 /* hit end of file */
#define TSF_NEWLINES 0x04 /* tokenize newlines */
#define TSF_REGEXP 0x08 /* looking for a regular expression */
#define TSF_INTERACTIVE 0x10 /* interactive parsing mode */
#define TSF_NLFLAG 0x20 /* last linebuf ended with \n */
#define TSF_CRFLAG 0x40 /* linebuf would have ended with \r */
/*
* At most one non-EOF token can be pushed back onto a TokenStream between
* Get or successful Match operations. These macros manipulate the pushback
* token to clear it when changing scanning modes (upon initialzation, after
* errors, or between newline-sensitive and insensitive states).
*/
#define CLEAR_PUSHBACK(ts) ((ts)->pushback.type = TOK_EOF)
#define SCAN_NEWLINES(ts) ((ts)->flags |= TSF_NEWLINES)
#define HIDE_NEWLINES(ts) \
PR_BEGIN_MACRO \
(ts)->flags &= ~TSF_NEWLINES; \
if ((ts)->pushback.type == TOK_EOL) \
(ts)->pushback.type = TOK_EOF; \
PR_END_MACRO
/* Clear ts member that might point above a released cx->tempPool mark. */
#define RESET_TOKENBUF(ts) ((ts)->tokenbuf.base = (ts)->tokenbuf.limit = NULL)
/*
* Create a new token stream, either from an input buffer or from a file.
* Return null on file-open or memory-allocation failure.
*
* NB: All of js_New{,Buffer,File}TokenStream() return a pointer to transient
* memory in the current context's temp pool. This memory is deallocated via
* PR_ARENA_RELEASE() after parsing is finished.
*/
extern JSTokenStream *
js_NewTokenStream(JSContext *cx, const jschar *base, size_t length,
const char *filename, uintN lineno, JSPrincipals *principals);
extern JS_FRIEND_API(JSTokenStream *)
js_NewBufferTokenStream(JSContext *cx, const jschar *base, size_t length);
#ifdef JSFILE
extern JS_FRIEND_API(JSTokenStream *)
js_NewFileTokenStream(JSContext *cx, const char *filename, FILE *defaultfp);
#endif
extern JS_FRIEND_API(JSBool)
js_CloseTokenStream(JSContext *cx, JSTokenStream *ts);
/*
* Initialize the scanner, installing JS keywords into cx's global scope.
*/
extern JSBool
js_InitScanner(JSContext *cx);
/*
* Friend-exported API entry point to call a mapping function on each reserved
* identifier in the scanner's keyword table.
*/
extern JS_FRIEND_API(void)
js_MapKeywords(void (*mapfun)(const char *));
/*
* Report an error found while scanning ts to a window or other output device
* associated with cx.
*/
extern void
js_ReportCompileError(JSContext *cx, JSTokenStream *ts, uintN flags,
const char *format, ...);
void
js_ReportCompileErrorNumber(JSContext *cx, JSTokenStream *ts, uintN flags,
const uintN errorNumber, ...);
/*
* Look ahead one token and return its type.
*/
extern JSTokenType
js_PeekToken(JSContext *cx, JSTokenStream *ts);
extern JSTokenType
js_PeekTokenSameLine(JSContext *cx, JSTokenStream *ts);
/*
* Get the next token from ts.
*/
extern JSTokenType
js_GetToken(JSContext *cx, JSTokenStream *ts);
/*
* Push back the last scanned token onto ts.
*/
extern void
js_UngetToken(JSTokenStream *ts);
/*
* Get the next token from ts if its type is tt.
*/
extern JSBool
js_MatchToken(JSContext *cx, JSTokenStream *ts, JSTokenType tt);
PR_END_EXTERN_C
#endif /* jsscan_h___ */