jsapi.h | jsapi.h | |||
---|---|---|---|---|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- | |||
* vim: set ts=8 sw=4 et tw=78: | ||||
* | * | |||
* ***** BEGIN LICENSE BLOCK ***** | * ***** BEGIN LICENSE BLOCK ***** | |||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | |||
* | * | |||
* The contents of this file are subject to the Mozilla Public License Vers ion | * The contents of this file are subject to the Mozilla Public License Vers ion | |||
* 1.1 (the "License"); you may not use this file except in compliance with | * 1.1 (the "License"); you may not use this file except in compliance with | |||
* the License. You may obtain a copy of the License at | * the License. You may obtain a copy of the License at | |||
* http://www.mozilla.org/MPL/ | * http://www.mozilla.org/MPL/ | |||
* | * | |||
* Software distributed under the License is distributed on an "AS IS" basi s, | * Software distributed under the License is distributed on an "AS IS" basi s, | |||
skipping to change at line 48 | skipping to change at line 49 | |||
* ***** END LICENSE BLOCK ***** */ | * ***** END LICENSE BLOCK ***** */ | |||
#ifndef jsapi_h___ | #ifndef jsapi_h___ | |||
#define jsapi_h___ | #define jsapi_h___ | |||
/* | /* | |||
* JavaScript API. | * JavaScript API. | |||
*/ | */ | |||
#include <stddef.h> | #include <stddef.h> | |||
#include <stdio.h> | #include <stdio.h> | |||
#include "jspubtd.h" | #include "jspubtd.h" | |||
#include "jsutil.h" | ||||
JS_BEGIN_EXTERN_C | JS_BEGIN_EXTERN_C | |||
/* | /* | |||
* Type tags stored in the low bits of a jsval. | * Type tags stored in the low bits of a jsval. | |||
*/ | */ | |||
#define JSVAL_OBJECT 0x0 /* untagged reference to object */ | #define JSVAL_OBJECT 0x0 /* untagged reference to object */ | |||
#define JSVAL_INT 0x1 /* tagged 31-bit integer value */ | #define JSVAL_INT 0x1 /* tagged 31-bit integer value */ | |||
#define JSVAL_DOUBLE 0x2 /* tagged reference to double */ | #define JSVAL_DOUBLE 0x2 /* tagged reference to double */ | |||
#define JSVAL_STRING 0x4 /* tagged reference to string */ | #define JSVAL_STRING 0x4 /* tagged reference to string */ | |||
skipping to change at line 182 | skipping to change at line 184 | |||
#define JSFUN_GSFLAG2ATTR(f) JSFUN_GSFLAGS(f) | #define JSFUN_GSFLAG2ATTR(f) JSFUN_GSFLAGS(f) | |||
#define JSFUN_THISP_FLAGS(f) (f) | #define JSFUN_THISP_FLAGS(f) (f) | |||
#define JSFUN_THISP_TEST(f,t) ((f) & t) | #define JSFUN_THISP_TEST(f,t) ((f) & t) | |||
#define JSFUN_THISP_STRING 0x0100 /* |this| may be a primitive string */ | #define JSFUN_THISP_STRING 0x0100 /* |this| may be a primitive string */ | |||
#define JSFUN_THISP_NUMBER 0x0200 /* |this| may be a primitive number */ | #define JSFUN_THISP_NUMBER 0x0200 /* |this| may be a primitive number */ | |||
#define JSFUN_THISP_BOOLEAN 0x0400 /* |this| may be a primitive boolea n */ | #define JSFUN_THISP_BOOLEAN 0x0400 /* |this| may be a primitive boolea n */ | |||
#define JSFUN_THISP_PRIMITIVE 0x0700 /* |this| may be any primitive valu e */ | #define JSFUN_THISP_PRIMITIVE 0x0700 /* |this| may be any primitive valu e */ | |||
#define JSFUN_FLAGS_MASK 0x07f8 /* overlay JSFUN_* attributes -- | #define JSFUN_FAST_NATIVE 0x0800 /* JSFastNative needs no JSStackFra | |||
me */ | ||||
#define JSFUN_FLAGS_MASK 0x0ff8 /* overlay JSFUN_* attributes -- | ||||
note that bit #15 is used intern ally | note that bit #15 is used intern ally | |||
to flag interpreted functions */ | to flag interpreted functions */ | |||
#define JSFUN_STUB_GSOPS 0x1000 /* use JS_PropertyStub getter/sette | ||||
r | ||||
instead of defaulting to class g | ||||
sops | ||||
for property holding function */ | ||||
#endif | #endif | |||
/* | /* | |||
* Re-use JSFUN_LAMBDA, which applies only to scripted functions, for use i n | * Re-use JSFUN_LAMBDA, which applies only to scripted functions, for use i n | |||
* JSFunctionSpec arrays that specify generic native prototype methods, i.e ., | * JSFunctionSpec arrays that specify generic native prototype methods, i.e ., | |||
* methods of a class prototype that are exposed as static methods taking a n | * methods of a class prototype that are exposed as static methods taking a n | |||
* extra leading argument: the generic |this| parameter. | * extra leading argument: the generic |this| parameter. | |||
* | * | |||
* If you set this flag in a JSFunctionSpec struct's flags initializer, the n | * If you set this flag in a JSFunctionSpec struct's flags initializer, the n | |||
* that struct must live at least as long as the native static method objec t | * that struct must live at least as long as the native static method objec t | |||
skipping to change at line 217 | skipping to change at line 225 | |||
#define JSVAL_ZERO INT_TO_JSVAL(0) | #define JSVAL_ZERO INT_TO_JSVAL(0) | |||
#define JSVAL_ONE INT_TO_JSVAL(1) | #define JSVAL_ONE INT_TO_JSVAL(1) | |||
#define JSVAL_FALSE BOOLEAN_TO_JSVAL(JS_FALSE) | #define JSVAL_FALSE BOOLEAN_TO_JSVAL(JS_FALSE) | |||
#define JSVAL_TRUE BOOLEAN_TO_JSVAL(JS_TRUE) | #define JSVAL_TRUE BOOLEAN_TO_JSVAL(JS_TRUE) | |||
/* | /* | |||
* Microseconds since the epoch, midnight, January 1, 1970 UTC. See the | * Microseconds since the epoch, midnight, January 1, 1970 UTC. See the | |||
* comment in jstypes.h regarding safe int64 usage. | * comment in jstypes.h regarding safe int64 usage. | |||
*/ | */ | |||
extern JS_PUBLIC_API(int64) | extern JS_PUBLIC_API(int64) | |||
JS_Now(); | JS_Now(void); | |||
/* Don't want to export data, so provide accessors for non-inline jsvals. * / | /* Don't want to export data, so provide accessors for non-inline jsvals. * / | |||
extern JS_PUBLIC_API(jsval) | extern JS_PUBLIC_API(jsval) | |||
JS_GetNaNValue(JSContext *cx); | JS_GetNaNValue(JSContext *cx); | |||
extern JS_PUBLIC_API(jsval) | extern JS_PUBLIC_API(jsval) | |||
JS_GetNegativeInfinityValue(JSContext *cx); | JS_GetNegativeInfinityValue(JSContext *cx); | |||
extern JS_PUBLIC_API(jsval) | extern JS_PUBLIC_API(jsval) | |||
JS_GetPositiveInfinityValue(JSContext *cx); | JS_GetPositiveInfinityValue(JSContext *cx); | |||
skipping to change at line 405 | skipping to change at line 413 | |||
extern JS_PUBLIC_API(JSType) | extern JS_PUBLIC_API(JSType) | |||
JS_TypeOfValue(JSContext *cx, jsval v); | JS_TypeOfValue(JSContext *cx, jsval v); | |||
extern JS_PUBLIC_API(const char *) | extern JS_PUBLIC_API(const char *) | |||
JS_GetTypeName(JSContext *cx, JSType type); | JS_GetTypeName(JSContext *cx, JSType type); | |||
/************************************************************************/ | /************************************************************************/ | |||
/* | /* | |||
* Initialization, locking, contexts, and memory allocation. | * Initialization, locking, contexts, and memory allocation. | |||
* | ||||
* It is important that the first runtime and first context be created in a | ||||
* single-threaded fashion, otherwise the behavior of the library is undefi | ||||
ned. | ||||
* See: http://developer.mozilla.org/en/docs/Category:JSAPI_Reference | ||||
*/ | */ | |||
#define JS_NewRuntime JS_Init | #define JS_NewRuntime JS_Init | |||
#define JS_DestroyRuntime JS_Finish | #define JS_DestroyRuntime JS_Finish | |||
#define JS_LockRuntime JS_Lock | #define JS_LockRuntime JS_Lock | |||
#define JS_UnlockRuntime JS_Unlock | #define JS_UnlockRuntime JS_Unlock | |||
extern JS_PUBLIC_API(JSRuntime *) | extern JS_PUBLIC_API(JSRuntime *) | |||
JS_NewRuntime(uint32 maxbytes); | JS_NewRuntime(uint32 maxbytes); | |||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(void) | |||
skipping to change at line 426 | skipping to change at line 438 | |||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(void) | |||
JS_ShutDown(void); | JS_ShutDown(void); | |||
JS_PUBLIC_API(void *) | JS_PUBLIC_API(void *) | |||
JS_GetRuntimePrivate(JSRuntime *rt); | JS_GetRuntimePrivate(JSRuntime *rt); | |||
JS_PUBLIC_API(void) | JS_PUBLIC_API(void) | |||
JS_SetRuntimePrivate(JSRuntime *rt, void *data); | JS_SetRuntimePrivate(JSRuntime *rt, void *data); | |||
#ifdef JS_THREADSAFE | ||||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(void) | |||
JS_BeginRequest(JSContext *cx); | JS_BeginRequest(JSContext *cx); | |||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(void) | |||
JS_EndRequest(JSContext *cx); | JS_EndRequest(JSContext *cx); | |||
/* Yield to pending GC operations, regardless of request depth */ | /* Yield to pending GC operations, regardless of request depth */ | |||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(void) | |||
JS_YieldRequest(JSContext *cx); | JS_YieldRequest(JSContext *cx); | |||
skipping to change at line 477 | skipping to change at line 487 | |||
#if 0 | #if 0 | |||
private: | private: | |||
static void *operator new(size_t) CPP_THROW_NEW { return 0; }; | static void *operator new(size_t) CPP_THROW_NEW { return 0; }; | |||
static void operator delete(void *, size_t) { }; | static void operator delete(void *, size_t) { }; | |||
#endif | #endif | |||
}; | }; | |||
JS_BEGIN_EXTERN_C | JS_BEGIN_EXTERN_C | |||
#endif | #endif | |||
#endif /* JS_THREADSAFE */ | ||||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(void) | |||
JS_Lock(JSRuntime *rt); | JS_Lock(JSRuntime *rt); | |||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(void) | |||
JS_Unlock(JSRuntime *rt); | JS_Unlock(JSRuntime *rt); | |||
extern JS_PUBLIC_API(JSContextCallback) | extern JS_PUBLIC_API(JSContextCallback) | |||
JS_SetContextCallback(JSRuntime *rt, JSContextCallback cxCallback); | JS_SetContextCallback(JSRuntime *rt, JSContextCallback cxCallback); | |||
extern JS_PUBLIC_API(JSContext *) | extern JS_PUBLIC_API(JSContext *) | |||
skipping to change at line 559 | skipping to change at line 567 | |||
#define JSOPTION_XML JS_BIT(6) /* EMCAScript for XML suppo rt: | #define JSOPTION_XML JS_BIT(6) /* EMCAScript for XML suppo rt: | |||
parse <!-- --> as a toke n, | parse <!-- --> as a toke n, | |||
not backward compatible with | not backward compatible with | |||
the comment-hiding hack used | the comment-hiding hack used | |||
in HTML script tags. */ | in HTML script tags. */ | |||
#define JSOPTION_NATIVE_BRANCH_CALLBACK \ | #define JSOPTION_NATIVE_BRANCH_CALLBACK \ | |||
JS_BIT(7) /* the branch callback set by | JS_BIT(7) /* the branch callback set by | |||
JS_SetBranchCallback may be | JS_SetBranchCallback may be | |||
called with a null scrip t | called with a null scrip t | |||
parameter, by native cod e | parameter, by native cod e | |||
that loops intensively * | that loops intensively. | |||
/ | Deprecated, use | |||
JS_SetOperationCallback | ||||
instead */ | ||||
#define JSOPTION_DONT_REPORT_UNCAUGHT \ | #define JSOPTION_DONT_REPORT_UNCAUGHT \ | |||
JS_BIT(8) /* When returning from the | JS_BIT(8) /* When returning from the | |||
outermost API call, prev ent | outermost API call, prev ent | |||
uncaught exceptions from | uncaught exceptions from | |||
being converted to error | being converted to error | |||
reports */ | reports */ | |||
#define JSOPTION_RELIMIT JS_BIT(9) /* Throw exception on any | ||||
regular expression which | ||||
backtracks more than n^3 | ||||
times, where n is length | ||||
of the input string */ | ||||
#define JSOPTION_ANONFUNFIX JS_BIT(10) /* Disallow function () {} | ||||
in | ||||
statement context per | ||||
ECMA-262 Edition 3. */ | ||||
extern JS_PUBLIC_API(uint32) | extern JS_PUBLIC_API(uint32) | |||
JS_GetOptions(JSContext *cx); | JS_GetOptions(JSContext *cx); | |||
extern JS_PUBLIC_API(uint32) | extern JS_PUBLIC_API(uint32) | |||
JS_SetOptions(JSContext *cx, uint32 options); | JS_SetOptions(JSContext *cx, uint32 options); | |||
extern JS_PUBLIC_API(uint32) | extern JS_PUBLIC_API(uint32) | |||
JS_ToggleOptions(JSContext *cx, uint32 options); | JS_ToggleOptions(JSContext *cx, uint32 options); | |||
extern JS_PUBLIC_API(const char *) | extern JS_PUBLIC_API(const char *) | |||
skipping to change at line 631 | skipping to change at line 651 | |||
JS_EnumerateResolvedStandardClasses(JSContext *cx, JSObject *obj, | JS_EnumerateResolvedStandardClasses(JSContext *cx, JSObject *obj, | |||
JSIdArray *ida); | JSIdArray *ida); | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, | JS_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, | |||
JSObject **objp); | JSObject **objp); | |||
extern JS_PUBLIC_API(JSObject *) | extern JS_PUBLIC_API(JSObject *) | |||
JS_GetScopeChain(JSContext *cx); | JS_GetScopeChain(JSContext *cx); | |||
extern JS_PUBLIC_API(JSObject *) | ||||
JS_GetGlobalForObject(JSContext *cx, JSObject *obj); | ||||
/* | ||||
* Macros to hide interpreter stack layout details from a JSFastNative usin | ||||
g | ||||
* its jsval *vp parameter. The stack layout underlying invocation can't ch | ||||
ange | ||||
* without breaking source and binary compatibility (argv[-2] is well-known | ||||
to | ||||
* be the callee jsval, and argv[-1] is as well known to be |this|). | ||||
* | ||||
* Note well: However, argv[-1] may be JSVAL_NULL where with slow natives i | ||||
t | ||||
* is the global object, so embeddings implementing fast natives *must* cal | ||||
l | ||||
* JS_THIS or JS_THIS_OBJECT and test for failure indicated by a null retur | ||||
n, | ||||
* which should propagate as a false return from native functions and hooks | ||||
. | ||||
* | ||||
* To reduce boilerplace checks, JS_InstanceOf and JS_GetInstancePrivate no | ||||
w | ||||
* handle a null obj parameter by returning false (throwing a TypeError if | ||||
* given non-null argv), so most native functions that type-check their |th | ||||
is| | ||||
* parameter need not add null checking. | ||||
* | ||||
* NB: there is an anti-dependency between JS_CALLEE and JS_SET_RVAL: nativ | ||||
e | ||||
* methods that may inspect their callee must defer setting their return va | ||||
lue | ||||
* until after any such possible inspection. Otherwise the return value wil | ||||
l be | ||||
* inspected instead of the callee function object. | ||||
* | ||||
* WARNING: These are not (yet) mandatory macros, but new code outside of t | ||||
he | ||||
* engine should use them. In the Mozilla 2.0 milestone their definitions m | ||||
ay | ||||
* change incompatibly. | ||||
*/ | ||||
#define JS_CALLEE(cx,vp) ((vp)[0]) | ||||
#define JS_ARGV_CALLEE(argv) ((argv)[-2]) | ||||
#define JS_THIS(cx,vp) JS_ComputeThis(cx, vp) | ||||
#define JS_THIS_OBJECT(cx,vp) ((JSObject *) JS_THIS(cx,vp)) | ||||
#define JS_ARGV(cx,vp) ((vp) + 2) | ||||
#define JS_RVAL(cx,vp) (*(vp)) | ||||
#define JS_SET_RVAL(cx,vp,v) (*(vp) = (v)) | ||||
extern JS_PUBLIC_API(jsval) | ||||
JS_ComputeThis(JSContext *cx, jsval *vp); | ||||
extern JS_PUBLIC_API(void *) | extern JS_PUBLIC_API(void *) | |||
JS_malloc(JSContext *cx, size_t nbytes); | JS_malloc(JSContext *cx, size_t nbytes); | |||
extern JS_PUBLIC_API(void *) | extern JS_PUBLIC_API(void *) | |||
JS_realloc(JSContext *cx, void *p, size_t nbytes); | JS_realloc(JSContext *cx, void *p, size_t nbytes); | |||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(void) | |||
JS_free(JSContext *cx, void *p); | JS_free(JSContext *cx, void *p); | |||
extern JS_PUBLIC_API(char *) | extern JS_PUBLIC_API(char *) | |||
skipping to change at line 845 | skipping to change at line 904 | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_LockGCThingRT(JSRuntime *rt, void *thing); | JS_LockGCThingRT(JSRuntime *rt, void *thing); | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_UnlockGCThing(JSContext *cx, void *thing); | JS_UnlockGCThing(JSContext *cx, void *thing); | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_UnlockGCThingRT(JSRuntime *rt, void *thing); | JS_UnlockGCThingRT(JSRuntime *rt, void *thing); | |||
/* | /* | |||
* For implementors of JSObjectOps.mark, to mark a GC-thing reachable via a | * Register externally maintained GC roots. | |||
* property or other strong ref identified for debugging purposes by name. | ||||
* The name argument's storage needs to live only as long as the call to | ||||
* this routine. | ||||
* | ||||
* The final arg is used by GC_MARK_DEBUG code to build a ref path through | ||||
* the GC's live thing graph. Implementors of JSObjectOps.mark should pass | ||||
* its final arg through to this function when marking all GC-things that a | ||||
re | ||||
* directly reachable from the object being marked. | ||||
* | * | |||
* See the JSMarkOp typedef in jspubtd.h, and the JSObjectOps struct below. | * traceOp: the trace operation. For each root the implementation should ca | |||
ll | ||||
* JS_CallTracer whenever the root contains a traceable thing. | ||||
* data: the data argument to pass to each invocation of traceOp. | ||||
*/ | ||||
extern JS_PUBLIC_API(void) | ||||
JS_SetExtraGCRoots(JSRuntime *rt, JSTraceDataOp traceOp, void *data); | ||||
/* | ||||
* For implementors of JSMarkOp. All new code should implement JSTraceOp | ||||
* instead. | ||||
*/ | */ | |||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(void) | |||
JS_MarkGCThing(JSContext *cx, void *thing, const char *name, void *arg); | JS_MarkGCThing(JSContext *cx, void *thing, const char *name, void *arg); | |||
/* | ||||
* JS_CallTracer API and related macros for implementors of JSTraceOp, to | ||||
* enumerate all references to traceable things reachable via a property or | ||||
* other strong ref identified for debugging purposes by name or index or | ||||
* a naming callback. | ||||
* | ||||
* By definition references to traceable things include non-null pointers | ||||
* to JSObject, JSString and jsdouble and corresponding jsvals. | ||||
* | ||||
* See the JSTraceOp typedef in jspubtd.h. | ||||
*/ | ||||
/* Trace kinds to pass to JS_Tracing. */ | ||||
#define JSTRACE_OBJECT 0 | ||||
#define JSTRACE_DOUBLE 1 | ||||
#define JSTRACE_STRING 2 | ||||
/* | ||||
* Use the following macros to check if a particular jsval is a traceable | ||||
* thing and to extract the thing and its kind to pass to JS_CallTracer. | ||||
*/ | ||||
#define JSVAL_IS_TRACEABLE(v) (JSVAL_IS_GCTHING(v) && !JSVAL_IS_NULL(v)) | ||||
#define JSVAL_TO_TRACEABLE(v) (JSVAL_TO_GCTHING(v)) | ||||
#define JSVAL_TRACE_KIND(v) (JSVAL_TAG(v) >> 1) | ||||
JS_STATIC_ASSERT(JSVAL_TRACE_KIND(JSVAL_OBJECT) == JSTRACE_OBJECT); | ||||
JS_STATIC_ASSERT(JSVAL_TRACE_KIND(JSVAL_DOUBLE) == JSTRACE_DOUBLE); | ||||
JS_STATIC_ASSERT(JSVAL_TRACE_KIND(JSVAL_STRING) == JSTRACE_STRING); | ||||
struct JSTracer { | ||||
JSContext *context; | ||||
JSTraceCallback callback; | ||||
#ifdef DEBUG | ||||
JSTraceNamePrinter debugPrinter; | ||||
const void *debugPrintArg; | ||||
size_t debugPrintIndex; | ||||
#endif | ||||
}; | ||||
/* | ||||
* The method to call on each reference to a traceable thing stored in a | ||||
* particular JSObject or other runtime structure. With DEBUG defined the | ||||
* caller before calling JS_CallTracer must initialize JSTracer fields | ||||
* describing the reference using the macros below. | ||||
*/ | ||||
extern JS_PUBLIC_API(void) | ||||
JS_CallTracer(JSTracer *trc, void *thing, uint32 kind); | ||||
/* | ||||
* Set debugging information about a reference to a traceable thing to prep | ||||
are | ||||
* for the following call to JS_CallTracer. | ||||
* | ||||
* When printer is null, arg must be const char * or char * C string naming | ||||
* the reference and index must be either (size_t)-1 indicating that the na | ||||
me | ||||
* alone describes the reference or it must be an index into some array vec | ||||
tor | ||||
* that stores the reference. | ||||
* | ||||
* When printer callback is not null, the arg and index arguments are | ||||
* available to the callback as debugPrinterArg and debugPrintIndex fields | ||||
* of JSTracer. | ||||
* | ||||
* The storage for name or callback's arguments needs to live only until | ||||
* the following call to JS_CallTracer returns. | ||||
*/ | ||||
#ifdef DEBUG | ||||
# define JS_SET_TRACING_DETAILS(trc, printer, arg, index) | ||||
\ | ||||
JS_BEGIN_MACRO | ||||
\ | ||||
(trc)->debugPrinter = (printer); | ||||
\ | ||||
(trc)->debugPrintArg = (arg); | ||||
\ | ||||
(trc)->debugPrintIndex = (index); | ||||
\ | ||||
JS_END_MACRO | ||||
#else | ||||
# define JS_SET_TRACING_DETAILS(trc, printer, arg, index) | ||||
\ | ||||
JS_BEGIN_MACRO | ||||
\ | ||||
JS_END_MACRO | ||||
#endif | ||||
/* | ||||
* Convenience macro to describe the argument of JS_CallTracer using C stri | ||||
ng | ||||
* and index. | ||||
*/ | ||||
# define JS_SET_TRACING_INDEX(trc, name, index) | ||||
\ | ||||
JS_SET_TRACING_DETAILS(trc, NULL, name, index) | ||||
/* | ||||
* Convenience macro to describe the argument of JS_CallTracer using C stri | ||||
ng. | ||||
*/ | ||||
# define JS_SET_TRACING_NAME(trc, name) | ||||
\ | ||||
JS_SET_TRACING_DETAILS(trc, NULL, name, (size_t)-1) | ||||
/* | ||||
* Convenience macro to invoke JS_CallTracer using C string as the name for | ||||
* the reference to a traceable thing. | ||||
*/ | ||||
# define JS_CALL_TRACER(trc, thing, kind, name) | ||||
\ | ||||
JS_BEGIN_MACRO | ||||
\ | ||||
JS_SET_TRACING_NAME(trc, name); | ||||
\ | ||||
JS_CallTracer((trc), (thing), (kind)); | ||||
\ | ||||
JS_END_MACRO | ||||
/* | ||||
* Convenience macros to invoke JS_CallTracer when jsval represents a | ||||
* reference to a traceable thing. | ||||
*/ | ||||
#define JS_CALL_VALUE_TRACER(trc, val, name) | ||||
\ | ||||
JS_BEGIN_MACRO | ||||
\ | ||||
if (JSVAL_IS_TRACEABLE(val)) { | ||||
\ | ||||
JS_CALL_TRACER((trc), JSVAL_TO_GCTHING(val), | ||||
\ | ||||
JSVAL_TRACE_KIND(val), name); | ||||
\ | ||||
} | ||||
\ | ||||
JS_END_MACRO | ||||
#define JS_CALL_OBJECT_TRACER(trc, object, name) | ||||
\ | ||||
JS_BEGIN_MACRO | ||||
\ | ||||
JSObject *obj_ = (object); | ||||
\ | ||||
JS_ASSERT(obj_); | ||||
\ | ||||
JS_CALL_TRACER((trc), obj_, JSTRACE_OBJECT, name); | ||||
\ | ||||
JS_END_MACRO | ||||
#define JS_CALL_STRING_TRACER(trc, string, name) | ||||
\ | ||||
JS_BEGIN_MACRO | ||||
\ | ||||
JSString *str_ = (string); | ||||
\ | ||||
JS_ASSERT(str_); | ||||
\ | ||||
JS_CALL_TRACER((trc), str_, JSTRACE_STRING, name); | ||||
\ | ||||
JS_END_MACRO | ||||
#define JS_CALL_DOUBLE_TRACER(trc, number, name) | ||||
\ | ||||
JS_BEGIN_MACRO | ||||
\ | ||||
jsdouble *num_ = (number); | ||||
\ | ||||
JS_ASSERT(num_); | ||||
\ | ||||
JS_CALL_TRACER((trc), num_, JSTRACE_DOUBLE, name); | ||||
\ | ||||
JS_END_MACRO | ||||
/* | ||||
* API for JSTraceCallback implementations. | ||||
*/ | ||||
# define JS_TRACER_INIT(trc, cx_, callback_) | ||||
\ | ||||
JS_BEGIN_MACRO | ||||
\ | ||||
(trc)->context = (cx_); | ||||
\ | ||||
(trc)->callback = (callback_); | ||||
\ | ||||
JS_SET_TRACING_DETAILS(trc, NULL, NULL, (size_t)-1); | ||||
\ | ||||
JS_END_MACRO | ||||
extern JS_PUBLIC_API(void) | ||||
JS_TraceChildren(JSTracer *trc, void *thing, uint32 kind); | ||||
extern JS_PUBLIC_API(void) | ||||
JS_TraceRuntime(JSTracer *trc); | ||||
#ifdef DEBUG | ||||
extern JS_PUBLIC_API(void) | ||||
JS_PrintTraceThingInfo(char *buf, size_t bufsize, JSTracer *trc, | ||||
void *thing, uint32 kind, JSBool includeDetails); | ||||
/* | ||||
* DEBUG-only method to dump the object graph of heap-allocated things. | ||||
* | ||||
* fp: file for the dump output. | ||||
* start: when non-null, dump only things reachable from start | ||||
* thing. Otherwise dump all things reachable from the | ||||
* runtime roots. | ||||
* startKind: trace kind of start if start is not null. Must be 0 whe | ||||
n | ||||
* start is null. | ||||
* thingToFind: dump only paths in the object graph leading to thingToF | ||||
ind | ||||
* when non-null. | ||||
* maxDepth: the upper bound on the number of edges to descend from | ||||
the | ||||
* graph roots. | ||||
* thingToIgnore: thing to ignore during the graph traversal when non-nul | ||||
l. | ||||
*/ | ||||
extern JS_PUBLIC_API(JSBool) | ||||
JS_DumpHeap(JSContext *cx, FILE *fp, void* startThing, uint32 startKind, | ||||
void *thingToFind, size_t maxDepth, void *thingToIgnore); | ||||
#endif | ||||
/* | ||||
* Garbage collector API. | ||||
*/ | ||||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(void) | |||
JS_GC(JSContext *cx); | JS_GC(JSContext *cx); | |||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(void) | |||
JS_MaybeGC(JSContext *cx); | JS_MaybeGC(JSContext *cx); | |||
extern JS_PUBLIC_API(JSGCCallback) | extern JS_PUBLIC_API(JSGCCallback) | |||
JS_SetGCCallback(JSContext *cx, JSGCCallback cb); | JS_SetGCCallback(JSContext *cx, JSGCCallback cb); | |||
extern JS_PUBLIC_API(JSGCCallback) | extern JS_PUBLIC_API(JSGCCallback) | |||
JS_SetGCCallbackRT(JSRuntime *rt, JSGCCallback cb); | JS_SetGCCallbackRT(JSRuntime *rt, JSGCCallback cb); | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_IsGCMarkingTracer(JSTracer *trc); | ||||
extern JS_PUBLIC_API(JSBool) | ||||
JS_IsAboutToBeFinalized(JSContext *cx, void *thing); | JS_IsAboutToBeFinalized(JSContext *cx, void *thing); | |||
typedef enum JSGCParamKey { | typedef enum JSGCParamKey { | |||
JSGC_MAX_BYTES = 0, /* maximum nominal heap before last ditch G | /* Maximum nominal heap before last ditch GC. */ | |||
C */ | JSGC_MAX_BYTES = 0, | |||
JSGC_MAX_MALLOC_BYTES = 1 /* # of JS_malloc bytes before last ditch G | ||||
C */ | /* Number of JS_malloc bytes before last ditch GC. */ | |||
JSGC_MAX_MALLOC_BYTES = 1, | ||||
/* Hoard stackPools for this long, in ms, default is 30 seconds. */ | ||||
JSGC_STACKPOOL_LIFESPAN = 2 | ||||
} JSGCParamKey; | } JSGCParamKey; | |||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(void) | |||
JS_SetGCParameter(JSRuntime *rt, JSGCParamKey key, uint32 value); | JS_SetGCParameter(JSRuntime *rt, JSGCParamKey key, uint32 value); | |||
/* | /* | |||
* Add a finalizer for external strings created by JS_NewExternalString (se e | * Add a finalizer for external strings created by JS_NewExternalString (se e | |||
* below) using a type-code returned from this function, and that understan ds | * below) using a type-code returned from this function, and that understan ds | |||
* how to free or release the memory pointed at by JS_GetStringChars(str). | * how to free or release the memory pointed at by JS_GetStringChars(str). | |||
* | * | |||
skipping to change at line 937 | skipping to change at line 1185 | |||
JS_GetExternalStringGCType(JSRuntime *rt, JSString *str); | JS_GetExternalStringGCType(JSRuntime *rt, JSString *str); | |||
/* | /* | |||
* Sets maximum (if stack grows upward) or minimum (downward) legal stack b yte | * Sets maximum (if stack grows upward) or minimum (downward) legal stack b yte | |||
* address in limitAddr for the thread or process stack used by cx. To dis able | * address in limitAddr for the thread or process stack used by cx. To dis able | |||
* stack size checking, pass 0 for limitAddr. | * stack size checking, pass 0 for limitAddr. | |||
*/ | */ | |||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(void) | |||
JS_SetThreadStackLimit(JSContext *cx, jsuword limitAddr); | JS_SetThreadStackLimit(JSContext *cx, jsuword limitAddr); | |||
/* | ||||
* Set the quota on the number of bytes that stack-like data structures can | ||||
* use when the runtime compiles and executes scripts. These structures | ||||
* consume heap space, so JS_SetThreadStackLimit does not bound their size. | ||||
* The default quota is 32MB which is quite generous. | ||||
* | ||||
* The function must be called before any script compilation or execution A | ||||
PI | ||||
* calls, i.e. either immediately after JS_NewContext or from JSCONTEXT_NEW | ||||
* context callback. | ||||
*/ | ||||
extern JS_PUBLIC_API(void) | ||||
JS_SetScriptStackQuota(JSContext *cx, size_t quota); | ||||
#define JS_DEFAULT_SCRIPT_STACK_QUOTA ((size_t) 0x2000000) | ||||
/************************************************************************/ | /************************************************************************/ | |||
/* | /* | |||
* Classes, objects, and properties. | * Classes, objects, and properties. | |||
*/ | */ | |||
/* For detailed comments on the function pointer types, see jspubtd.h. */ | /* For detailed comments on the function pointer types, see jspubtd.h. */ | |||
struct JSClass { | struct JSClass { | |||
const char *name; | const char *name; | |||
uint32 flags; | uint32 flags; | |||
skipping to change at line 974 | skipping to change at line 1237 | |||
JSHasInstanceOp hasInstance; | JSHasInstanceOp hasInstance; | |||
JSMarkOp mark; | JSMarkOp mark; | |||
JSReserveSlotsOp reserveSlots; | JSReserveSlotsOp reserveSlots; | |||
}; | }; | |||
struct JSExtendedClass { | struct JSExtendedClass { | |||
JSClass base; | JSClass base; | |||
JSEqualityOp equality; | JSEqualityOp equality; | |||
JSObjectOp outerObject; | JSObjectOp outerObject; | |||
JSObjectOp innerObject; | JSObjectOp innerObject; | |||
void (*reserved0)(); | JSIteratorOp iteratorObject; | |||
void (*reserved1)(); | JSObjectOp wrappedObject; /* NB: infallible, null | |||
void (*reserved2)(); | returns are treated as | |||
void (*reserved3)(); | the original object */ | |||
void (*reserved4)(); | void (*reserved0)(void); | |||
void (*reserved1)(void); | ||||
void (*reserved2)(void); | ||||
}; | }; | |||
#define JSCLASS_HAS_PRIVATE (1<<0) /* objects have private slo t */ | #define JSCLASS_HAS_PRIVATE (1<<0) /* objects have private slo t */ | |||
#define JSCLASS_NEW_ENUMERATE (1<<1) /* has JSNewEnumerateOp hoo k */ | #define JSCLASS_NEW_ENUMERATE (1<<1) /* has JSNewEnumerateOp hoo k */ | |||
#define JSCLASS_NEW_RESOLVE (1<<2) /* has JSNewResolveOp hook */ | #define JSCLASS_NEW_RESOLVE (1<<2) /* has JSNewResolveOp hook */ | |||
#define JSCLASS_PRIVATE_IS_NSISUPPORTS (1<<3) /* private is (nsISupports *) */ | #define JSCLASS_PRIVATE_IS_NSISUPPORTS (1<<3) /* private is (nsISupports *) */ | |||
#define JSCLASS_SHARE_ALL_PROPERTIES (1<<4) /* all properties are SHARE D */ | #define JSCLASS_SHARE_ALL_PROPERTIES (1<<4) /* all properties are SHARE D */ | |||
#define JSCLASS_NEW_RESOLVE_GETS_START (1<<5) /* JSNewResolveOp gets star ting | #define JSCLASS_NEW_RESOLVE_GETS_START (1<<5) /* JSNewResolveOp gets star ting | |||
object in prototype chai n | object in prototype chai n | |||
passed in via *objp in/o ut | passed in via *objp in/o ut | |||
skipping to change at line 1016 | skipping to change at line 1281 | |||
& JSCLASS_RESERVED_SLOTS_MASK) | & JSCLASS_RESERVED_SLOTS_MASK) | |||
#define JSCLASS_HIGH_FLAGS_SHIFT (JSCLASS_RESERVED_SLOTS_SHIFT + \ | #define JSCLASS_HIGH_FLAGS_SHIFT (JSCLASS_RESERVED_SLOTS_SHIFT + \ | |||
JSCLASS_RESERVED_SLOTS_WIDTH) | JSCLASS_RESERVED_SLOTS_WIDTH) | |||
/* True if JSClass is really a JSExtendedClass. */ | /* True if JSClass is really a JSExtendedClass. */ | |||
#define JSCLASS_IS_EXTENDED (1<<(JSCLASS_HIGH_FLAGS_SHIFT+0)) | #define JSCLASS_IS_EXTENDED (1<<(JSCLASS_HIGH_FLAGS_SHIFT+0)) | |||
#define JSCLASS_IS_ANONYMOUS (1<<(JSCLASS_HIGH_FLAGS_SHIFT+1)) | #define JSCLASS_IS_ANONYMOUS (1<<(JSCLASS_HIGH_FLAGS_SHIFT+1)) | |||
#define JSCLASS_IS_GLOBAL (1<<(JSCLASS_HIGH_FLAGS_SHIFT+2)) | #define JSCLASS_IS_GLOBAL (1<<(JSCLASS_HIGH_FLAGS_SHIFT+2)) | |||
/* Indicates that JSClass.mark is a tracer with JSTraceOp type. */ | ||||
#define JSCLASS_MARK_IS_TRACE (1<<(JSCLASS_HIGH_FLAGS_SHIFT+3)) | ||||
/* | /* | |||
* ECMA-262 requires that most constructors used internally create objects | * ECMA-262 requires that most constructors used internally create objects | |||
* with "the original Foo.prototype value" as their [[Prototype]] (__proto_ _) | * with "the original Foo.prototype value" as their [[Prototype]] (__proto_ _) | |||
* member initial value. The "original ... value" verbiage is there becaus e | * member initial value. The "original ... value" verbiage is there becaus e | |||
* in ECMA-262, global properties naming class objects are read/write and | * in ECMA-262, global properties naming class objects are read/write and | |||
* deleteable, for the most part. | * deleteable, for the most part. | |||
* | * | |||
* Implementing this efficiently requires that global objects have classes | * Implementing this efficiently requires that global objects have classes | |||
* with the following flags. Failure to use JSCLASS_GLOBAL_FLAGS won't bre ak | * with the following flags. Failure to use JSCLASS_GLOBAL_FLAGS won't bre ak | |||
* anything except the ECMA-262 "original prototype value" behavior, which was | * anything except the ECMA-262 "original prototype value" behavior, which was | |||
skipping to change at line 1037 | skipping to change at line 1305 | |||
* get backward compatibility. | * get backward compatibility. | |||
*/ | */ | |||
#define JSCLASS_GLOBAL_FLAGS \ | #define JSCLASS_GLOBAL_FLAGS \ | |||
(JSCLASS_IS_GLOBAL | JSCLASS_HAS_RESERVED_SLOTS(JSProto_LIMIT)) | (JSCLASS_IS_GLOBAL | JSCLASS_HAS_RESERVED_SLOTS(JSProto_LIMIT)) | |||
/* Fast access to the original value of each standard class's prototype. */ | /* Fast access to the original value of each standard class's prototype. */ | |||
#define JSCLASS_CACHED_PROTO_SHIFT (JSCLASS_HIGH_FLAGS_SHIFT + 8) | #define JSCLASS_CACHED_PROTO_SHIFT (JSCLASS_HIGH_FLAGS_SHIFT + 8) | |||
#define JSCLASS_CACHED_PROTO_WIDTH 8 | #define JSCLASS_CACHED_PROTO_WIDTH 8 | |||
#define JSCLASS_CACHED_PROTO_MASK JS_BITMASK(JSCLASS_CACHED_PROTO_WID TH) | #define JSCLASS_CACHED_PROTO_MASK JS_BITMASK(JSCLASS_CACHED_PROTO_WID TH) | |||
#define JSCLASS_HAS_CACHED_PROTO(key) ((key) << JSCLASS_CACHED_PROTO_SHIF T) | #define JSCLASS_HAS_CACHED_PROTO(key) ((key) << JSCLASS_CACHED_PROTO_SHIF T) | |||
#define JSCLASS_CACHED_PROTO_KEY(clasp) (((clasp)->flags | #define JSCLASS_CACHED_PROTO_KEY(clasp) ((JSProtoKey) | |||
\ | \ | |||
>> JSCLASS_CACHED_PROTO_SHIFT) | (((clasp)->flags | |||
\ | \ | |||
& JSCLASS_CACHED_PROTO_MASK) | >> JSCLASS_CACHED_PROTO_SHIFT) | |||
\ | ||||
& JSCLASS_CACHED_PROTO_MASK)) | ||||
/* Initializer for unused members of statically initialized JSClass structs . */ | /* Initializer for unused members of statically initialized JSClass structs . */ | |||
#define JSCLASS_NO_OPTIONAL_MEMBERS 0,0,0,0,0,0,0,0 | #define JSCLASS_NO_OPTIONAL_MEMBERS 0,0,0,0,0,0,0,0 | |||
#define JSCLASS_NO_RESERVED_MEMBERS 0,0,0,0,0 | #define JSCLASS_NO_RESERVED_MEMBERS 0,0,0 | |||
/* For detailed comments on these function pointer types, see jspubtd.h. */ | /* For detailed comments on these function pointer types, see jspubtd.h. */ | |||
struct JSObjectOps { | struct JSObjectOps { | |||
/* Mandatory non-null function pointer members. */ | /* Mandatory non-null function pointer members. */ | |||
JSNewObjectMapOp newObjectMap; | JSNewObjectMapOp newObjectMap; | |||
JSObjectMapOp destroyObjectMap; | JSObjectMapOp destroyObjectMap; | |||
JSLookupPropOp lookupProperty; | JSLookupPropOp lookupProperty; | |||
JSDefinePropOp defineProperty; | JSDefinePropOp defineProperty; | |||
JSPropertyIdOp getProperty; | JSPropertyIdOp getProperty; | |||
JSPropertyIdOp setProperty; | JSPropertyIdOp setProperty; | |||
skipping to change at line 1070 | skipping to change at line 1339 | |||
/* Optionally non-null members start here. */ | /* Optionally non-null members start here. */ | |||
JSObjectOp thisObject; | JSObjectOp thisObject; | |||
JSPropertyRefOp dropProperty; | JSPropertyRefOp dropProperty; | |||
JSNative call; | JSNative call; | |||
JSNative construct; | JSNative construct; | |||
JSXDRObjectOp xdrObject; | JSXDRObjectOp xdrObject; | |||
JSHasInstanceOp hasInstance; | JSHasInstanceOp hasInstance; | |||
JSSetObjectSlotOp setProto; | JSSetObjectSlotOp setProto; | |||
JSSetObjectSlotOp setParent; | JSSetObjectSlotOp setParent; | |||
JSMarkOp mark; | JSTraceOp trace; | |||
JSFinalizeOp clear; | JSFinalizeOp clear; | |||
JSGetRequiredSlotOp getRequiredSlot; | JSGetRequiredSlotOp getRequiredSlot; | |||
JSSetRequiredSlotOp setRequiredSlot; | JSSetRequiredSlotOp setRequiredSlot; | |||
}; | }; | |||
struct JSXMLObjectOps { | struct JSXMLObjectOps { | |||
JSObjectOps base; | JSObjectOps base; | |||
JSGetMethodOp getMethod; | JSGetMethodOp getMethod; | |||
JSSetMethodOp setMethod; | JSSetMethodOp setMethod; | |||
JSEnumerateValuesOp enumerateValues; | JSEnumerateValuesOp enumerateValues; | |||
skipping to change at line 1174 | skipping to change at line 1443 | |||
struct JSFunctionSpec { | struct JSFunctionSpec { | |||
const char *name; | const char *name; | |||
JSNative call; | JSNative call; | |||
#ifdef MOZILLA_1_8_BRANCH | #ifdef MOZILLA_1_8_BRANCH | |||
uint8 nargs; | uint8 nargs; | |||
uint8 flags; | uint8 flags; | |||
uint16 extra; | uint16 extra; | |||
#else | #else | |||
uint16 nargs; | uint16 nargs; | |||
uint16 flags; | uint16 flags; | |||
uint32 extra; /* extra & 0xFFFF: | ||||
number of arg slots for local GC roots | /* | |||
extra >> 16: | * extra & 0xFFFF: Number of extra argument slots for local GC roots. | |||
reserved, must be zero */ | * If fast native, must be zero. | |||
* extra >> 16: If slow native, reserved for future use (must be 0) | ||||
. | ||||
* If fast native, minimum required argc. | ||||
*/ | ||||
uint32 extra; | ||||
#endif | #endif | |||
}; | }; | |||
/* | ||||
* Terminating sentinel initializer to put at the end of a JSFunctionSpec a | ||||
rray | ||||
* that's passed to JS_DefineFunctions or JS_InitClass. | ||||
*/ | ||||
#define JS_FS_END JS_FS(NULL,NULL,0,0,0) | ||||
/* | ||||
* Initializer macro for a JSFunctionSpec array element. This is the origin | ||||
al | ||||
* kind of native function specifier initializer. Use JS_FN ("fast native", | ||||
see | ||||
* JSFastNative in jspubtd.h) for all functions that do not need a stack fr | ||||
ame | ||||
* when activated. | ||||
*/ | ||||
#define JS_FS(name,call,nargs,flags,extra) | ||||
\ | ||||
{name, call, nargs, flags, extra} | ||||
/* | ||||
* "Fast native" initializer macro for a JSFunctionSpec array element. Use | ||||
this | ||||
* in preference to JS_FS if the native in question does not need its own s | ||||
tack | ||||
* frame when activated. | ||||
*/ | ||||
#define JS_FN(name,fastcall,minargs,nargs,flags) | ||||
\ | ||||
{name, (JSNative)(fastcall), nargs, | ||||
\ | ||||
(flags) | JSFUN_FAST_NATIVE | JSFUN_STUB_GSOPS, | ||||
\ | ||||
(minargs) << 16} | ||||
extern JS_PUBLIC_API(JSObject *) | extern JS_PUBLIC_API(JSObject *) | |||
JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto, | JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto, | |||
JSClass *clasp, JSNative constructor, uintN nargs, | JSClass *clasp, JSNative constructor, uintN nargs, | |||
JSPropertySpec *ps, JSFunctionSpec *fs, | JSPropertySpec *ps, JSFunctionSpec *fs, | |||
JSPropertySpec *static_ps, JSFunctionSpec *static_fs); | JSPropertySpec *static_ps, JSFunctionSpec *static_fs); | |||
#ifdef JS_THREADSAFE | #ifdef JS_THREADSAFE | |||
extern JS_PUBLIC_API(JSClass *) | extern JS_PUBLIC_API(JSClass *) | |||
JS_GetClass(JSContext *cx, JSObject *obj); | JS_GetClass(JSContext *cx, JSObject *obj); | |||
skipping to change at line 1241 | skipping to change at line 1539 | |||
* Get a unique identifier for obj, good for the lifetime of obj (even if i t | * Get a unique identifier for obj, good for the lifetime of obj (even if i t | |||
* is moved by a copying GC). Return false on failure (likely out of memor y), | * is moved by a copying GC). Return false on failure (likely out of memor y), | |||
* and true with *idp containing the unique id on success. | * and true with *idp containing the unique id on success. | |||
*/ | */ | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_GetObjectId(JSContext *cx, JSObject *obj, jsid *idp); | JS_GetObjectId(JSContext *cx, JSObject *obj, jsid *idp); | |||
extern JS_PUBLIC_API(JSObject *) | extern JS_PUBLIC_API(JSObject *) | |||
JS_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *pare nt); | JS_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *pare nt); | |||
/* | ||||
* Unlike JS_NewObject, JS_NewObjectWithGivenProto does not compute a defau | ||||
lt | ||||
* proto if proto's actual parameter value is null. | ||||
*/ | ||||
extern JS_PUBLIC_API(JSObject *) | ||||
JS_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto, | ||||
JSObject *parent); | ||||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_SealObject(JSContext *cx, JSObject *obj, JSBool deep); | JS_SealObject(JSContext *cx, JSObject *obj, JSBool deep); | |||
extern JS_PUBLIC_API(JSObject *) | extern JS_PUBLIC_API(JSObject *) | |||
JS_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto, | JS_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto, | |||
JSObject *parent); | JSObject *parent); | |||
extern JS_PUBLIC_API(JSObject *) | extern JS_PUBLIC_API(JSObject *) | |||
JS_ConstructObjectWithArguments(JSContext *cx, JSClass *clasp, JSObject *pr oto, | JS_ConstructObjectWithArguments(JSContext *cx, JSClass *clasp, JSObject *pr oto, | |||
JSObject *parent, uintN argc, jsval *argv); | JSObject *parent, uintN argc, jsval *argv); | |||
skipping to change at line 1309 | skipping to change at line 1615 | |||
JS_DefinePropertyWithTinyId(JSContext *cx, JSObject *obj, const char *name, | JS_DefinePropertyWithTinyId(JSContext *cx, JSObject *obj, const char *name, | |||
int8 tinyid, jsval value, | int8 tinyid, jsval value, | |||
JSPropertyOp getter, JSPropertyOp setter, | JSPropertyOp getter, JSPropertyOp setter, | |||
uintN attrs); | uintN attrs); | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_AliasProperty(JSContext *cx, JSObject *obj, const char *name, | JS_AliasProperty(JSContext *cx, JSObject *obj, const char *name, | |||
const char *alias); | const char *alias); | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_AlreadyHasOwnProperty(JSContext *cx, JSObject *obj, const char *name, | ||||
JSBool *foundp); | ||||
extern JS_PUBLIC_API(JSBool) | ||||
JS_HasProperty(JSContext *cx, JSObject *obj, const char *name, JSBool *foun dp); | JS_HasProperty(JSContext *cx, JSObject *obj, const char *name, JSBool *foun dp); | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_LookupProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp ); | JS_LookupProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp ); | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, const char *name, | JS_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, const char *name, | |||
uintN flags, jsval *vp); | uintN flags, jsval *vp); | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
skipping to change at line 1387 | skipping to change at line 1697 | |||
uintN attrs, JSBool *foundp); | uintN attrs, JSBool *foundp); | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_DefineUCPropertyWithTinyId(JSContext *cx, JSObject *obj, | JS_DefineUCPropertyWithTinyId(JSContext *cx, JSObject *obj, | |||
const jschar *name, size_t namelen, | const jschar *name, size_t namelen, | |||
int8 tinyid, jsval value, | int8 tinyid, jsval value, | |||
JSPropertyOp getter, JSPropertyOp setter, | JSPropertyOp getter, JSPropertyOp setter, | |||
uintN attrs); | uintN attrs); | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_AlreadyHasOwnUCProperty(JSContext *cx, JSObject *obj, const jschar *name | ||||
, | ||||
size_t namelen, JSBool *foundp); | ||||
extern JS_PUBLIC_API(JSBool) | ||||
JS_HasUCProperty(JSContext *cx, JSObject *obj, | JS_HasUCProperty(JSContext *cx, JSObject *obj, | |||
const jschar *name, size_t namelen, | const jschar *name, size_t namelen, | |||
JSBool *vp); | JSBool *vp); | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_LookupUCProperty(JSContext *cx, JSObject *obj, | JS_LookupUCProperty(JSContext *cx, JSObject *obj, | |||
const jschar *name, size_t namelen, | const jschar *name, size_t namelen, | |||
jsval *vp); | jsval *vp); | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
skipping to change at line 1434 | skipping to change at line 1748 | |||
JS_HasArrayLength(JSContext *cx, JSObject *obj, jsuint *lengthp); | JS_HasArrayLength(JSContext *cx, JSObject *obj, jsuint *lengthp); | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_DefineElement(JSContext *cx, JSObject *obj, jsint index, jsval value, | JS_DefineElement(JSContext *cx, JSObject *obj, jsint index, jsval value, | |||
JSPropertyOp getter, JSPropertyOp setter, uintN attrs); | JSPropertyOp getter, JSPropertyOp setter, uintN attrs); | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_AliasElement(JSContext *cx, JSObject *obj, const char *name, jsint alias ); | JS_AliasElement(JSContext *cx, JSObject *obj, const char *name, jsint alias ); | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_AlreadyHasOwnElement(JSContext *cx, JSObject *obj, jsint index, | ||||
JSBool *foundp); | ||||
extern JS_PUBLIC_API(JSBool) | ||||
JS_HasElement(JSContext *cx, JSObject *obj, jsint index, JSBool *foundp); | JS_HasElement(JSContext *cx, JSObject *obj, jsint index, JSBool *foundp); | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_LookupElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp); | JS_LookupElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp); | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_GetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp); | JS_GetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp); | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_SetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp); | JS_SetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp); | |||
skipping to change at line 1806 | skipping to change at line 2124 | |||
jsval *argv, jsval *rval); | jsval *argv, jsval *rval); | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_CallFunctionName(JSContext *cx, JSObject *obj, const char *name, uintN a rgc, | JS_CallFunctionName(JSContext *cx, JSObject *obj, const char *name, uintN a rgc, | |||
jsval *argv, jsval *rval); | jsval *argv, jsval *rval); | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_CallFunctionValue(JSContext *cx, JSObject *obj, jsval fval, uintN argc, | JS_CallFunctionValue(JSContext *cx, JSObject *obj, jsval fval, uintN argc, | |||
jsval *argv, jsval *rval); | jsval *argv, jsval *rval); | |||
/* | ||||
* The maximum value of the operation limit to pass to JS_SetOperationCallb | ||||
ack | ||||
* and JS_SetOperationLimit. | ||||
*/ | ||||
#define JS_MAX_OPERATION_LIMIT ((uint32) 0x7FFFFFFF) | ||||
#define JS_OPERATION_WEIGHT_BASE 4096 | ||||
/* | ||||
* Set the operation callback that the engine calls periodically after | ||||
* the internal operation count reaches the specified limit. | ||||
* | ||||
* When operationLimit is JS_OPERATION_WEIGHT_BASE, the callback will be | ||||
* called at least after each backward jump in the interpreter. To minimize | ||||
* the overhead of the callback invocation we suggest at least | ||||
* | ||||
* 100 * JS_OPERATION_WEIGHT_BASE | ||||
* | ||||
* as a value for operationLimit. | ||||
*/ | ||||
extern JS_PUBLIC_API(void) | ||||
JS_SetOperationCallback(JSContext *cx, JSOperationCallback callback, | ||||
uint32 operationLimit); | ||||
extern JS_PUBLIC_API(void) | ||||
JS_ClearOperationCallback(JSContext *cx); | ||||
extern JS_PUBLIC_API(JSOperationCallback) | ||||
JS_GetOperationCallback(JSContext *cx); | ||||
/* | ||||
* Get the operation limit associated with the operation callback. This API | ||||
* function may be called only when the result of JS_GetOperationCallback(c | ||||
x) | ||||
* is not null. | ||||
*/ | ||||
extern JS_PUBLIC_API(uint32) | ||||
JS_GetOperationLimit(JSContext *cx); | ||||
/* | ||||
* Change the operation limit associated with the operation callback. This | ||||
API | ||||
* function may be called only when the result of JS_GetOperationCallback(c | ||||
x) | ||||
* is not null. | ||||
*/ | ||||
extern JS_PUBLIC_API(void) | ||||
JS_SetOperationLimit(JSContext *cx, uint32 operationLimit); | ||||
/* | ||||
* Note well: JS_SetBranchCallback is deprecated. It is similar to | ||||
* | ||||
* JS_SetOperationCallback(cx, callback, 4096, NULL); | ||||
* | ||||
* except that the callback will not be called from a long-running native | ||||
* function when JSOPTION_NATIVE_BRANCH_CALLBACK is not set and the top-mos | ||||
t | ||||
* frame is native. | ||||
*/ | ||||
extern JS_PUBLIC_API(JSBranchCallback) | extern JS_PUBLIC_API(JSBranchCallback) | |||
JS_SetBranchCallback(JSContext *cx, JSBranchCallback cb); | JS_SetBranchCallback(JSContext *cx, JSBranchCallback cb); | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_IsRunning(JSContext *cx); | JS_IsRunning(JSContext *cx); | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_IsConstructing(JSContext *cx); | JS_IsConstructing(JSContext *cx); | |||
/* | /* | |||
skipping to change at line 1837 | skipping to change at line 2210 | |||
* and if the returned value is used on the left-hand side of an assignment | * and if the returned value is used on the left-hand side of an assignment | |||
* op, the identified property will be set. If the return value is in an | * op, the identified property will be set. If the return value is in an | |||
* r-value, the interpreter just gets obj[id]'s value. | * r-value, the interpreter just gets obj[id]'s value. | |||
*/ | */ | |||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(void) | |||
JS_SetCallReturnValue2(JSContext *cx, jsval v); | JS_SetCallReturnValue2(JSContext *cx, jsval v); | |||
/* | /* | |||
* Saving and restoring frame chains. | * Saving and restoring frame chains. | |||
* | * | |||
* These two functions are used to set aside cx->fp while that frame is | * These two functions are used to set aside cx's call stack while that sta | |||
* inactive. After a call to JS_SaveFrameChain, it looks as if there is no | ck | |||
* is inactive. After a call to JS_SaveFrameChain, it looks as if there is | ||||
no | ||||
* code running on cx. Before calling JS_RestoreFrameChain, cx's call stack | * code running on cx. Before calling JS_RestoreFrameChain, cx's call stack | |||
* must be balanced and all nested calls to JS_SaveFrameChain must have had | * must be balanced and all nested calls to JS_SaveFrameChain must have had | |||
* matching JS_RestoreFrameChain calls. | * matching JS_RestoreFrameChain calls. | |||
* | * | |||
* JS_SaveFrameChain deals with cx not having any code running on it. A nul l | * JS_SaveFrameChain deals with cx not having any code running on it. A nul l | |||
* return does not signify an error and JS_RestoreFrameChain handles null | * return does not signify an error, and JS_RestoreFrameChain handles a nul | |||
* frames. | l | |||
* frame pointer argument safely. | ||||
*/ | */ | |||
extern JS_PUBLIC_API(JSStackFrame *) | extern JS_PUBLIC_API(JSStackFrame *) | |||
JS_SaveFrameChain(JSContext *cx); | JS_SaveFrameChain(JSContext *cx); | |||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(void) | |||
JS_RestoreFrameChain(JSContext *cx, JSStackFrame *fp); | JS_RestoreFrameChain(JSContext *cx, JSStackFrame *fp); | |||
/************************************************************************/ | /************************************************************************/ | |||
/* | /* | |||
skipping to change at line 1960 | skipping to change at line 2333 | |||
/* | /* | |||
* Convert a mutable string (either growable or dependent) into an immutabl e, | * Convert a mutable string (either growable or dependent) into an immutabl e, | |||
* thread-safe one. | * thread-safe one. | |||
*/ | */ | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_MakeStringImmutable(JSContext *cx, JSString *str); | JS_MakeStringImmutable(JSContext *cx, JSString *str); | |||
/* | /* | |||
* Return JS_TRUE if C (char []) strings passed via the API and internally | * Return JS_TRUE if C (char []) strings passed via the API and internally | |||
* are UTF-8. The source must be compiled with JS_C_STRINGS_ARE_UTF8 define | * are UTF-8. | |||
d | ||||
* to get UTF-8 support. | ||||
*/ | */ | |||
JS_PUBLIC_API(JSBool) | JS_PUBLIC_API(JSBool) | |||
JS_CStringsAreUTF8(); | JS_CStringsAreUTF8(void); | |||
/* | ||||
* Update the value to be returned by JS_CStringsAreUTF8(). Once set, it | ||||
* can never be changed. This API must be called before the first call to | ||||
* JS_NewRuntime. | ||||
*/ | ||||
JS_PUBLIC_API(void) | ||||
JS_SetCStringsAreUTF8(void); | ||||
/* | /* | |||
* Character encoding support. | * Character encoding support. | |||
* | * | |||
* For both JS_EncodeCharacters and JS_DecodeBytes, set *dstlenp to the siz e | * For both JS_EncodeCharacters and JS_DecodeBytes, set *dstlenp to the siz e | |||
* of the destination buffer before the call; on return, *dstlenp contains the | * of the destination buffer before the call; on return, *dstlenp contains the | |||
* number of bytes (JS_EncodeCharacters) or jschars (JS_DecodeBytes) actual ly | * number of bytes (JS_EncodeCharacters) or jschars (JS_DecodeBytes) actual ly | |||
* stored. To determine the necessary destination buffer size, make a sizi ng | * stored. To determine the necessary destination buffer size, make a sizi ng | |||
* call that passes NULL for dst. | * call that passes NULL for dst. | |||
* | * | |||
* On errors, the functions report the error. In that case, *dstlenp contai ns | * On errors, the functions report the error. In that case, *dstlenp contai ns | |||
* the number of characters or bytes transferred so far. If cx is NULL, no | * the number of characters or bytes transferred so far. If cx is NULL, no | |||
* error is reported on failure, and the functions simply return JS_FALSE. | * error is reported on failure, and the functions simply return JS_FALSE. | |||
* | * | |||
* NB: Neither function stores an additional zero byte or jschar after the | * NB: Neither function stores an additional zero byte or jschar after the | |||
* transcoded string. | * transcoded string. | |||
* | * | |||
* If the source has been compiled with the #define JS_C_STRINGS_ARE_UTF8 t | * If JS_CStringsAreUTF8() is true then JS_EncodeCharacters encodes to | |||
o | * UTF-8, and JS_DecodeBytes decodes from UTF-8, which may create additiona | |||
* enable UTF-8 interpretation of C char[] strings, then JS_EncodeCharacter | l | |||
s | * errors if the character sequence is malformed. If UTF-8 support is | |||
* encodes to UTF-8, and JS_DecodeBytes decodes from UTF-8, which may creat | * disabled, the functions deflate and inflate, respectively. | |||
e | ||||
* addititional errors if the character sequence is malformed. If UTF-8 | ||||
* support is disabled, the functions deflate and inflate, respectively. | ||||
*/ | */ | |||
JS_PUBLIC_API(JSBool) | JS_PUBLIC_API(JSBool) | |||
JS_EncodeCharacters(JSContext *cx, const jschar *src, size_t srclen, char * dst, | JS_EncodeCharacters(JSContext *cx, const jschar *src, size_t srclen, char * dst, | |||
size_t *dstlenp); | size_t *dstlenp); | |||
JS_PUBLIC_API(JSBool) | JS_PUBLIC_API(JSBool) | |||
JS_DecodeBytes(JSContext *cx, const char *src, size_t srclen, jschar *dst, | JS_DecodeBytes(JSContext *cx, const char *src, size_t srclen, jschar *dst, | |||
size_t *dstlenp); | size_t *dstlenp); | |||
/* | ||||
* A variation on JS_EncodeCharacters where a null terminated string is | ||||
* returned that you are expected to call JS_free on when done. | ||||
*/ | ||||
JS_PUBLIC_API(char *) | ||||
JS_EncodeString(JSContext *cx, JSString *str); | ||||
/************************************************************************/ | /************************************************************************/ | |||
/* | /* | |||
* Locale specific string conversion and error message callbacks. | * Locale specific string conversion and error message callbacks. | |||
*/ | */ | |||
struct JSLocaleCallbacks { | struct JSLocaleCallbacks { | |||
JSLocaleToUpperCase localeToUpperCase; | JSLocaleToUpperCase localeToUpperCase; | |||
JSLocaleToLowerCase localeToLowerCase; | JSLocaleToLowerCase localeToLowerCase; | |||
JSLocaleCompare localeCompare; | JSLocaleCompare localeCompare; | |||
JSLocaleToUnicode localeToUnicode; | JSLocaleToUnicode localeToUnicode; | |||
skipping to change at line 2077 | skipping to change at line 2463 | |||
JS_ReportErrorFlagsAndNumberUC(JSContext *cx, uintN flags, | JS_ReportErrorFlagsAndNumberUC(JSContext *cx, uintN flags, | |||
JSErrorCallback errorCallback, void *userRef , | JSErrorCallback errorCallback, void *userRef , | |||
const uintN errorNumber, ...); | const uintN errorNumber, ...); | |||
/* | /* | |||
* Complain when out of memory. | * Complain when out of memory. | |||
*/ | */ | |||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(void) | |||
JS_ReportOutOfMemory(JSContext *cx); | JS_ReportOutOfMemory(JSContext *cx); | |||
/* | ||||
* Complain when an allocation size overflows the maximum supported limit. | ||||
*/ | ||||
extern JS_PUBLIC_API(void) | ||||
JS_ReportAllocationOverflow(JSContext *cx); | ||||
struct JSErrorReport { | struct JSErrorReport { | |||
const char *filename; /* source file name, URL, etc., or null */ | const char *filename; /* source file name, URL, etc., or null */ | |||
uintN lineno; /* source line number */ | uintN lineno; /* source line number */ | |||
const char *linebuf; /* offending source line without final \n */ | const char *linebuf; /* offending source line without final \n */ | |||
const char *tokenptr; /* pointer to error token in linebuf */ | const char *tokenptr; /* pointer to error token in linebuf */ | |||
const jschar *uclinebuf; /* unicode (original) line buffer */ | const jschar *uclinebuf; /* unicode (original) line buffer */ | |||
const jschar *uctokenptr; /* unicode (original) token pointer */ | const jschar *uctokenptr; /* unicode (original) token pointer */ | |||
uintN flags; /* error/warning, etc. */ | uintN flags; /* error/warning, etc. */ | |||
uintN errorNumber; /* the error number, e.g. see js.msg */ | uintN errorNumber; /* the error number, e.g. see js.msg */ | |||
const jschar *ucmessage; /* the (default) error message */ | const jschar *ucmessage; /* the (default) error message */ | |||
skipping to change at line 2120 | skipping to change at line 2512 | |||
JS_SetErrorReporter(JSContext *cx, JSErrorReporter er); | JS_SetErrorReporter(JSContext *cx, JSErrorReporter er); | |||
/************************************************************************/ | /************************************************************************/ | |||
/* | /* | |||
* Regular Expressions. | * Regular Expressions. | |||
*/ | */ | |||
#define JSREG_FOLD 0x01 /* fold uppercase to lowercase */ | #define JSREG_FOLD 0x01 /* fold uppercase to lowercase */ | |||
#define JSREG_GLOB 0x02 /* global exec, creates array of matches */ | #define JSREG_GLOB 0x02 /* global exec, creates array of matches */ | |||
#define JSREG_MULTILINE 0x04 /* treat ^ and $ as begin and end of line * / | #define JSREG_MULTILINE 0x04 /* treat ^ and $ as begin and end of line * / | |||
#define JSREG_STICKY 0x08 /* only match starting at lastIndex */ | ||||
extern JS_PUBLIC_API(JSObject *) | extern JS_PUBLIC_API(JSObject *) | |||
JS_NewRegExpObject(JSContext *cx, char *bytes, size_t length, uintN flags); | JS_NewRegExpObject(JSContext *cx, char *bytes, size_t length, uintN flags); | |||
extern JS_PUBLIC_API(JSObject *) | extern JS_PUBLIC_API(JSObject *) | |||
JS_NewUCRegExpObject(JSContext *cx, jschar *chars, size_t length, uintN fla gs); | JS_NewUCRegExpObject(JSContext *cx, jschar *chars, size_t length, uintN fla gs); | |||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(void) | |||
JS_SetRegExpInput(JSContext *cx, JSString *input, JSBool multiline); | JS_SetRegExpInput(JSContext *cx, JSString *input, JSBool multiline); | |||
skipping to change at line 2193 | skipping to change at line 2586 | |||
JS_ErrorFromException(JSContext *cx, jsval v); | JS_ErrorFromException(JSContext *cx, jsval v); | |||
/* | /* | |||
* Given a reported error's message and JSErrorReport struct pointer, throw | * Given a reported error's message and JSErrorReport struct pointer, throw | |||
* the corresponding exception on cx. | * the corresponding exception on cx. | |||
*/ | */ | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_ThrowReportedError(JSContext *cx, const char *message, | JS_ThrowReportedError(JSContext *cx, const char *message, | |||
JSErrorReport *reportp); | JSErrorReport *reportp); | |||
#ifdef JS_THREADSAFE | /* | |||
* Throws a StopIteration exception on cx. | ||||
*/ | ||||
extern JS_PUBLIC_API(JSBool) | ||||
JS_ThrowStopIteration(JSContext *cx); | ||||
/* | /* | |||
* Associate the current thread with the given context. This is done | * Associate the current thread with the given context. This is done | |||
* implicitly by JS_NewContext. | * implicitly by JS_NewContext. | |||
* | * | |||
* Returns the old thread id for this context, which should be treated as | * Returns the old thread id for this context, which should be treated as | |||
* an opaque value. This value is provided for comparison to 0, which | * an opaque value. This value is provided for comparison to 0, which | |||
* indicates that ClearContextThread has been called on this context | * indicates that ClearContextThread has been called on this context | |||
* since the last SetContextThread, or non-0, which indicates the opposite. | * since the last SetContextThread, or non-0, which indicates the opposite. | |||
*/ | */ | |||
extern JS_PUBLIC_API(jsword) | extern JS_PUBLIC_API(jsword) | |||
JS_GetContextThread(JSContext *cx); | JS_GetContextThread(JSContext *cx); | |||
extern JS_PUBLIC_API(jsword) | extern JS_PUBLIC_API(jsword) | |||
JS_SetContextThread(JSContext *cx); | JS_SetContextThread(JSContext *cx); | |||
extern JS_PUBLIC_API(jsword) | extern JS_PUBLIC_API(jsword) | |||
JS_ClearContextThread(JSContext *cx); | JS_ClearContextThread(JSContext *cx); | |||
#endif /* JS_THREADSAFE */ | ||||
/************************************************************************/ | /************************************************************************/ | |||
#ifdef DEBUG | ||||
#define JS_GC_ZEAL 1 | ||||
#endif | ||||
#ifdef JS_GC_ZEAL | ||||
extern JS_PUBLIC_API(void) | ||||
JS_SetGCZeal(JSContext *cx, uint8 zeal); | ||||
#endif | ||||
JS_END_EXTERN_C | JS_END_EXTERN_C | |||
#endif /* jsapi_h___ */ | #endif /* jsapi_h___ */ | |||
End of changes. 40 change blocks. | ||||
58 lines changed or deleted | 546 lines changed or added | |||
jsarena.h | jsarena.h | |||
---|---|---|---|---|
skipping to change at line 91 | skipping to change at line 91 | |||
size_t maxalloc; /* maximum allocation size in bytes */ | size_t maxalloc; /* maximum allocation size in bytes */ | |||
double variance; /* size variance accumulator */ | double variance; /* size variance accumulator */ | |||
}; | }; | |||
#endif | #endif | |||
struct JSArenaPool { | struct JSArenaPool { | |||
JSArena first; /* first arena in pool list */ | JSArena first; /* first arena in pool list */ | |||
JSArena *current; /* arena from which to allocate space */ | JSArena *current; /* arena from which to allocate space */ | |||
size_t arenasize; /* net exact size of a new arena */ | size_t arenasize; /* net exact size of a new arena */ | |||
jsuword mask; /* alignment mask (power-of-2 - 1) */ | jsuword mask; /* alignment mask (power-of-2 - 1) */ | |||
size_t *quotap; /* pointer to the quota on pool allocation | ||||
size or null if pool is unlimited */ | ||||
#ifdef JS_ARENAMETER | #ifdef JS_ARENAMETER | |||
JSArenaStats stats; | JSArenaStats stats; | |||
#endif | #endif | |||
}; | }; | |||
#ifdef JS_ARENAMETER | ||||
#define JS_INIT_NAMED_ARENA_POOL(pool, name, size, align, quotap) | ||||
\ | ||||
JS_InitArenaPool(pool, name, size, align, quotap) | ||||
#else | ||||
#define JS_INIT_NAMED_ARENA_POOL(pool, name, size, align, quotap) | ||||
\ | ||||
JS_InitArenaPool(pool, size, align, quotap) | ||||
#endif | ||||
/* | /* | |||
* If the including .c file uses only one power-of-2 alignment, it may defi ne | * If the including .c file uses only one power-of-2 alignment, it may defi ne | |||
* JS_ARENA_CONST_ALIGN_MASK to the alignment mask and save a few instructi ons | * JS_ARENA_CONST_ALIGN_MASK to the alignment mask and save a few instructi ons | |||
* per ALLOCATE and GROW. | * per ALLOCATE and GROW. | |||
*/ | */ | |||
#ifdef JS_ARENA_CONST_ALIGN_MASK | #ifdef JS_ARENA_CONST_ALIGN_MASK | |||
#define JS_ARENA_ALIGN(pool, n) (((jsuword)(n) + JS_ARENA_CONST_ALIGN_MASK) \ | #define JS_ARENA_ALIGN(pool, n) (((jsuword)(n) + JS_ARENA_CONST_ALIGN_MASK) \ | |||
& ~(jsuword)JS_ARENA_CONST_ALIGN_MASK) | & ~(jsuword)JS_ARENA_CONST_ALIGN_MASK) | |||
#define JS_INIT_ARENA_POOL(pool, name, size) \ | #define JS_INIT_ARENA_POOL(pool, name, size, quotap) | |||
JS_InitArenaPool(pool, name, size, JS_ARENA_CONST_ALIGN_MASK + 1) | \ | |||
JS_INIT_NAMED_ARENA_POOL(pool, name, size, JS_ARENA_CONST_ALIGN_MASK + | ||||
1, \ | ||||
quotap) | ||||
#else | #else | |||
#define JS_ARENA_ALIGN(pool, n) (((jsuword)(n) + (pool)->mask) & ~(pool)->m ask) | #define JS_ARENA_ALIGN(pool, n) (((jsuword)(n) + (pool)->mask) & ~(pool)->m ask) | |||
#define JS_INIT_ARENA_POOL(pool, name, size, align, quotap) | ||||
\ | ||||
JS_INIT_NAMED_ARENA_POOL(pool, name, size, align, quotap) | ||||
#endif | #endif | |||
#define JS_ARENA_ALLOCATE(p, pool, nb) \ | #define JS_ARENA_ALLOCATE(p, pool, nb) \ | |||
JS_ARENA_ALLOCATE_CAST(p, void *, pool, nb) | JS_ARENA_ALLOCATE_CAST(p, void *, pool, nb) | |||
#define JS_ARENA_ALLOCATE_TYPE(p, type, pool) \ | #define JS_ARENA_ALLOCATE_TYPE(p, type, pool) \ | |||
JS_ARENA_ALLOCATE_COMMON(p, type *, pool, sizeof(type), 0) | JS_ARENA_ALLOCATE_COMMON(p, type *, pool, sizeof(type), 0) | |||
#define JS_ARENA_ALLOCATE_CAST(p, type, pool, nb) \ | #define JS_ARENA_ALLOCATE_CAST(p, type, pool, nb) \ | |||
JS_ARENA_ALLOCATE_COMMON(p, type, pool, nb, _nb > _a->limit) | JS_ARENA_ALLOCATE_COMMON(p, type, pool, nb, _nb > _a->limit) | |||
skipping to change at line 169 | skipping to change at line 185 | |||
} \ | } \ | |||
} else { \ | } else { \ | |||
p = (type) JS_ArenaGrow(pool, p, size, incr); \ | p = (type) JS_ArenaGrow(pool, p, size, incr); \ | |||
} \ | } \ | |||
JS_ArenaCountGrowth(pool, size, incr); \ | JS_ArenaCountGrowth(pool, size, incr); \ | |||
JS_END_MACRO | JS_END_MACRO | |||
#define JS_ARENA_MARK(pool) ((void *) (pool)->current->avail) | #define JS_ARENA_MARK(pool) ((void *) (pool)->current->avail) | |||
#define JS_UPTRDIFF(p,q) ((jsuword)(p) - (jsuword)(q)) | #define JS_UPTRDIFF(p,q) ((jsuword)(p) - (jsuword)(q)) | |||
/* | ||||
* Check if the mark is inside arena's allocated area. | ||||
*/ | ||||
#define JS_ARENA_MARK_MATCH(a, mark) | ||||
\ | ||||
(JS_UPTRDIFF(mark, (a)->base) <= JS_UPTRDIFF((a)->avail, (a)->base)) | ||||
#ifdef DEBUG | #ifdef DEBUG | |||
#define JS_FREE_PATTERN 0xDA | #define JS_FREE_PATTERN 0xDA | |||
#define JS_CLEAR_UNUSED(a) (JS_ASSERT((a)->avail <= (a)->limit), \ | #define JS_CLEAR_UNUSED(a) (JS_ASSERT((a)->avail <= (a)->limit), \ | |||
memset((void*)(a)->avail, JS_FREE_PATTERN, \ | memset((void*)(a)->avail, JS_FREE_PATTERN, \ | |||
(a)->limit - (a)->avail)) | (a)->limit - (a)->avail)) | |||
#define JS_CLEAR_ARENA(a) memset((void*)(a), JS_FREE_PATTERN, \ | #define JS_CLEAR_ARENA(a) memset((void*)(a), JS_FREE_PATTERN, \ | |||
(a)->limit - (jsuword)(a)) | (a)->limit - (jsuword)(a)) | |||
#else | #else | |||
#define JS_CLEAR_UNUSED(a) /* nothing */ | #define JS_CLEAR_UNUSED(a) /* nothing */ | |||
#define JS_CLEAR_ARENA(a) /* nothing */ | #define JS_CLEAR_ARENA(a) /* nothing */ | |||
#endif | #endif | |||
#define JS_ARENA_RELEASE(pool, mark) \ | #define JS_ARENA_RELEASE(pool, mark) \ | |||
JS_BEGIN_MACRO \ | JS_BEGIN_MACRO \ | |||
char *_m = (char *)(mark); \ | char *_m = (char *)(mark); \ | |||
JSArena *_a = (pool)->current; \ | JSArena *_a = (pool)->current; \ | |||
if (_a != &(pool)->first && | if (_a != &(pool)->first && JS_ARENA_MARK_MATCH(_a, _m)) { | |||
\ | \ | |||
JS_UPTRDIFF(_m, _a->base) <= JS_UPTRDIFF(_a->avail, _a->base)) | ||||
{ \ | ||||
_a->avail = (jsuword)JS_ARENA_ALIGN(pool, _m); \ | _a->avail = (jsuword)JS_ARENA_ALIGN(pool, _m); \ | |||
JS_ASSERT(_a->avail <= _a->limit); \ | JS_ASSERT(_a->avail <= _a->limit); \ | |||
JS_CLEAR_UNUSED(_a); \ | JS_CLEAR_UNUSED(_a); \ | |||
JS_ArenaCountRetract(pool, _m); \ | JS_ArenaCountRetract(pool, _m); \ | |||
} else { \ | } else { \ | |||
JS_ArenaRelease(pool, _m); \ | JS_ArenaRelease(pool, _m); \ | |||
} \ | } \ | |||
JS_ArenaCountRelease(pool, _m); \ | JS_ArenaCountRelease(pool, _m); \ | |||
JS_END_MACRO | JS_END_MACRO | |||
skipping to change at line 214 | skipping to change at line 235 | |||
JS_BEGIN_MACRO \ | JS_BEGIN_MACRO \ | |||
JS_COUNT_ARENA(pool,--); \ | JS_COUNT_ARENA(pool,--); \ | |||
if ((pool)->current == (a)) (pool)->current = &(pool)->first; \ | if ((pool)->current == (a)) (pool)->current = &(pool)->first; \ | |||
*(pnext) = (a)->next; \ | *(pnext) = (a)->next; \ | |||
JS_CLEAR_ARENA(a); \ | JS_CLEAR_ARENA(a); \ | |||
free(a); \ | free(a); \ | |||
(a) = NULL; \ | (a) = NULL; \ | |||
JS_END_MACRO | JS_END_MACRO | |||
/* | /* | |||
* Initialize an arena pool with the given name for debugging and metering, | * Initialize an arena pool with a minimum size per arena of size bytes. | |||
* with a minimum size per arena of size bytes. | * Always call JS_SET_ARENA_METER_NAME before calling this or use | |||
* JS_INIT_ARENA_POOL macro to provide a name for for debugging and meterin | ||||
g. | ||||
*/ | */ | |||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(void) | |||
JS_InitArenaPool(JSArenaPool *pool, const char *name, size_t size, | JS_INIT_NAMED_ARENA_POOL(JSArenaPool *pool, const char *name, size_t size, | |||
size_t align); | size_t align, size_t *quotap); | |||
/* | /* | |||
* Free the arenas in pool. The user may continue to allocate from pool | * Free the arenas in pool. The user may continue to allocate from pool | |||
* after calling this function. There is no need to call JS_InitArenaPool( ) | * after calling this function. There is no need to call JS_InitArenaPool( ) | |||
* again unless JS_FinishArenaPool(pool) has been called. | * again unless JS_FinishArenaPool(pool) has been called. | |||
*/ | */ | |||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(void) | |||
JS_FreeArenaPool(JSArenaPool *pool); | JS_FreeArenaPool(JSArenaPool *pool); | |||
/* | /* | |||
skipping to change at line 262 | skipping to change at line 284 | |||
extern JS_PUBLIC_API(void *) | extern JS_PUBLIC_API(void *) | |||
JS_ArenaRealloc(JSArenaPool *pool, void *p, size_t size, size_t incr); | JS_ArenaRealloc(JSArenaPool *pool, void *p, size_t size, size_t incr); | |||
extern JS_PUBLIC_API(void *) | extern JS_PUBLIC_API(void *) | |||
JS_ArenaGrow(JSArenaPool *pool, void *p, size_t size, size_t incr); | JS_ArenaGrow(JSArenaPool *pool, void *p, size_t size, size_t incr); | |||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(void) | |||
JS_ArenaRelease(JSArenaPool *pool, char *mark); | JS_ArenaRelease(JSArenaPool *pool, char *mark); | |||
/* | ||||
* Function to be used directly when an allocation has likely grown to cons | ||||
ume | ||||
* an entire JSArena, in which case the arena is returned to the malloc hea | ||||
p. | ||||
*/ | ||||
extern JS_PUBLIC_API(void) | ||||
JS_ArenaFreeAllocation(JSArenaPool *pool, void *p, size_t size); | ||||
#ifdef JS_ARENAMETER | #ifdef JS_ARENAMETER | |||
#include <stdio.h> | #include <stdio.h> | |||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(void) | |||
JS_ArenaCountAllocation(JSArenaPool *pool, size_t nb); | JS_ArenaCountAllocation(JSArenaPool *pool, size_t nb); | |||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(void) | |||
JS_ArenaCountInplaceGrowth(JSArenaPool *pool, size_t size, size_t incr); | JS_ArenaCountInplaceGrowth(JSArenaPool *pool, size_t size, size_t incr); | |||
End of changes. 9 change blocks. | ||||
19 lines changed or deleted | 38 lines changed or added | |||
jsarray.h | jsarray.h | |||
---|---|---|---|---|
skipping to change at line 56 | skipping to change at line 56 | |||
#include "jspubtd.h" | #include "jspubtd.h" | |||
JS_BEGIN_EXTERN_C | JS_BEGIN_EXTERN_C | |||
/* Generous sanity-bound on length (in elements) of array initialiser. */ | /* Generous sanity-bound on length (in elements) of array initialiser. */ | |||
#define ARRAY_INIT_LIMIT JS_BIT(24) | #define ARRAY_INIT_LIMIT JS_BIT(24) | |||
extern JSBool | extern JSBool | |||
js_IdIsIndex(jsval id, jsuint *indexp); | js_IdIsIndex(jsval id, jsuint *indexp); | |||
extern JSClass js_ArrayClass; | extern JSClass js_ArrayClass, js_SlowArrayClass; | |||
#define OBJ_IS_DENSE_ARRAY(cx,obj) (OBJ_GET_CLASS(cx, obj) == &js_ArrayCla | ||||
ss) | ||||
#define OBJ_IS_ARRAY(cx,obj) (OBJ_IS_DENSE_ARRAY(cx, obj) || | ||||
\ | ||||
OBJ_GET_CLASS(cx, obj) == &js_SlowArrayCla | ||||
ss) | ||||
extern JSObject * | extern JSObject * | |||
js_InitArrayClass(JSContext *cx, JSObject *obj); | js_InitArrayClass(JSContext *cx, JSObject *obj); | |||
extern JSObject * | extern JSObject * | |||
js_NewArrayObject(JSContext *cx, jsuint length, jsval *vector); | js_NewArrayObject(JSContext *cx, jsuint length, jsval *vector); | |||
/* Create an array object that starts out already made slow/sparse. */ | ||||
extern JSObject * | ||||
js_NewSlowArrayObject(JSContext *cx); | ||||
extern JSBool | ||||
js_MakeArraySlow(JSContext *cx, JSObject *obj); | ||||
#define JSSLOT_ARRAY_LENGTH JSSLOT_PRIVATE | ||||
#define JSSLOT_ARRAY_COUNT (JSSLOT_ARRAY_LENGTH + 1) | ||||
#define JSSLOT_ARRAY_LOOKUP_HOLDER (JSSLOT_ARRAY_COUNT + 1) | ||||
#define ARRAY_DENSE_LENGTH(obj) | ||||
\ | ||||
(JS_ASSERT(OBJ_IS_DENSE_ARRAY(cx, obj)), | ||||
\ | ||||
(obj)->dslots ? (uint32)(obj)->dslots[-1] : 0) | ||||
extern JSBool | extern JSBool | |||
js_GetLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp); | js_GetLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp); | |||
extern JSBool | extern JSBool | |||
js_SetLengthProperty(JSContext *cx, JSObject *obj, jsuint length); | js_SetLengthProperty(JSContext *cx, JSObject *obj, jsuint length); | |||
extern JSBool | extern JSBool | |||
js_HasLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp); | js_HasLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp); | |||
/* | /* | |||
* Test whether an object is "array-like". Currently this means whether ob j | * Test whether an object is "array-like". Currently this means whether ob j | |||
* is an Array or an arguments object. We would like an API, and probably a | * is an Array or an arguments object. We would like an API, and probably a | |||
* way in the language, to bless other objects as array-like: having indexe d | * way in the language, to bless other objects as array-like: having indexe d | |||
* properties, and a 'length' property of uint32 value equal to one more th an | * properties, and a 'length' property of uint32 value equal to one more th an | |||
* the greatest index. | * the greatest index. | |||
*/ | */ | |||
extern JSBool | extern JSBool | |||
js_IsArrayLike(JSContext *cx, JSObject *obj, JSBool *answerp, jsuint *lengt hp); | js_IsArrayLike(JSContext *cx, JSObject *obj, JSBool *answerp, jsuint *lengt hp); | |||
/* | /* | |||
* JS-specific heap sort function. | * JS-specific merge sort function. | |||
*/ | */ | |||
typedef JSBool (*JSComparator)(void *arg, const void *a, const void *b, | typedef JSBool (*JSComparator)(void *arg, const void *a, const void *b, | |||
int *result); | int *result); | |||
/* | ||||
* NB: vec is the array to be sorted, tmp is temporary space at least as bi | ||||
g | ||||
* as vec. Both should be GC-rooted if appropriate. | ||||
* | ||||
* The sorted result is in vec. vec may be in an inconsistent state if the | ||||
* comparator function cmp returns an error inside a comparison, so remembe | ||||
r | ||||
* to check the return value of this function. | ||||
*/ | ||||
extern JSBool | ||||
js_MergeSort(void *vec, size_t nel, size_t elsize, JSComparator cmp, | ||||
void *arg, void *tmp); | ||||
#ifdef DEBUG_ARRAYS | ||||
extern JSBool | extern JSBool | |||
js_HeapSort(void *vec, size_t nel, void *pivot, size_t elsize, | js_ArrayInfo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval * | |||
JSComparator cmp, void *arg); | rval); | |||
#endif | ||||
JS_END_EXTERN_C | JS_END_EXTERN_C | |||
#endif /* jsarray_h___ */ | #endif /* jsarray_h___ */ | |||
End of changes. 6 change blocks. | ||||
4 lines changed or deleted | 44 lines changed or added | |||
jsatom.h | jsatom.h | |||
---|---|---|---|---|
skipping to change at line 46 | skipping to change at line 46 | |||
* the terms of any one of the MPL, the GPL or the LGPL. | * the terms of any one of the MPL, the GPL or the LGPL. | |||
* | * | |||
* ***** END LICENSE BLOCK ***** */ | * ***** END LICENSE BLOCK ***** */ | |||
#ifndef jsatom_h___ | #ifndef jsatom_h___ | |||
#define jsatom_h___ | #define jsatom_h___ | |||
/* | /* | |||
* JS atom table. | * JS atom table. | |||
*/ | */ | |||
#include <stddef.h> | #include <stddef.h> | |||
#include "jsconfig.h" | ||||
#include "jstypes.h" | #include "jstypes.h" | |||
#include "jshash.h" /* Added by JSIFY */ | #include "jshash.h" /* Added by JSIFY */ | |||
#include "jsdhash.h" | ||||
#include "jsapi.h" | #include "jsapi.h" | |||
#include "jsprvtd.h" | #include "jsprvtd.h" | |||
#include "jspubtd.h" | #include "jspubtd.h" | |||
#ifdef JS_THREADSAFE | ||||
#include "jslock.h" | #include "jslock.h" | |||
#endif | ||||
JS_BEGIN_EXTERN_C | JS_BEGIN_EXTERN_C | |||
#define ATOM_PINNED 0x01 /* atom is pinned against GC */ | #define ATOM_PINNED 0x1 /* atom is pinned against GC */ | |||
#define ATOM_INTERNED 0x02 /* pinned variant for JS_Intern* AP | #define ATOM_INTERNED 0x2 /* pinned variant for JS_Intern* API */ | |||
I */ | #define ATOM_NOCOPY 0x4 /* don't copy atom string bytes */ | |||
#define ATOM_MARK 0x04 /* atom is reachable via GC */ | #define ATOM_TMPSTR 0x8 /* internal, to avoid extra string */ | |||
#define ATOM_HIDDEN 0x08 /* atom is in special hidden subspa | ||||
ce */ | ||||
#define ATOM_NOCOPY 0x40 /* don't copy atom string bytes */ | ||||
#define ATOM_TMPSTR 0x80 /* internal, to avoid extra string | ||||
*/ | ||||
struct JSAtom { | ||||
JSHashEntry entry; /* key is jsval or unhidden atom | ||||
if ATOM_HIDDEN */ | ||||
uint32 flags; /* pinned, interned, and mark flags | ||||
*/ | ||||
jsatomid number; /* atom serial number and hash code | ||||
*/ | ||||
}; | ||||
#define ATOM_KEY(atom) ((jsval)(atom)->entry.key) | #define ATOM_KEY(atom) ((jsval)(atom)) | |||
#define ATOM_IS_OBJECT(atom) JSVAL_IS_OBJECT(ATOM_KEY(atom)) | ||||
#define ATOM_TO_OBJECT(atom) JSVAL_TO_OBJECT(ATOM_KEY(atom)) | ||||
#define ATOM_IS_INT(atom) JSVAL_IS_INT(ATOM_KEY(atom)) | ||||
#define ATOM_TO_INT(atom) JSVAL_TO_INT(ATOM_KEY(atom)) | ||||
#define ATOM_IS_DOUBLE(atom) JSVAL_IS_DOUBLE(ATOM_KEY(atom)) | #define ATOM_IS_DOUBLE(atom) JSVAL_IS_DOUBLE(ATOM_KEY(atom)) | |||
#define ATOM_TO_DOUBLE(atom) JSVAL_TO_DOUBLE(ATOM_KEY(atom)) | #define ATOM_TO_DOUBLE(atom) JSVAL_TO_DOUBLE(ATOM_KEY(atom)) | |||
#define ATOM_IS_STRING(atom) JSVAL_IS_STRING(ATOM_KEY(atom)) | #define ATOM_IS_STRING(atom) JSVAL_IS_STRING(ATOM_KEY(atom)) | |||
#define ATOM_TO_STRING(atom) JSVAL_TO_STRING(ATOM_KEY(atom)) | #define ATOM_TO_STRING(atom) JSVAL_TO_STRING(ATOM_KEY(atom)) | |||
#define ATOM_IS_BOOLEAN(atom) JSVAL_IS_BOOLEAN(ATOM_KEY(atom)) | ||||
#define ATOM_TO_BOOLEAN(atom) JSVAL_TO_BOOLEAN(ATOM_KEY(atom)) | JS_STATIC_ASSERT(sizeof(JSHashNumber) == 4); | |||
JS_STATIC_ASSERT(sizeof(JSAtom *) == JS_BYTES_PER_WORD); | ||||
#if JS_BYTES_PER_WORD == 4 | ||||
# define ATOM_HASH(atom) ((JSHashNumber)(atom) >> 2) | ||||
#elif JS_BYTES_PER_WORD == 8 | ||||
# define ATOM_HASH(atom) (((JSHashNumber)(jsuword)(atom) >> 3) ^ | ||||
\ | ||||
(JSHashNumber)((jsuword)(atom) >> 32)) | ||||
#else | ||||
# error "Unsupported configuration" | ||||
#endif | ||||
/* | /* | |||
* Return a printable, lossless char[] representation of a string-type atom . | * Return a printable, lossless char[] representation of a string-type atom . | |||
* The lifetime of the result extends at least until the next GC activation , | * The lifetime of the result extends at least until the next GC activation , | |||
* longer if cx's string newborn root is not overwritten. | * longer if cx's string newborn root is not overwritten. | |||
*/ | */ | |||
extern JS_FRIEND_API(const char *) | extern const char * | |||
js_AtomToPrintableString(JSContext *cx, JSAtom *atom); | js_AtomToPrintableString(JSContext *cx, JSAtom *atom); | |||
struct JSAtomListElement { | struct JSAtomListElement { | |||
JSHashEntry entry; | JSHashEntry entry; | |||
}; | }; | |||
#define ALE_ATOM(ale) ((JSAtom *) (ale)->entry.key) | #define ALE_ATOM(ale) ((JSAtom *) (ale)->entry.key) | |||
#define ALE_INDEX(ale) ((jsatomid) JS_PTR_TO_UINT32((ale)->entry.value)) | #define ALE_INDEX(ale) ((jsatomid) JS_PTR_TO_UINT32((ale)->entry.value)) | |||
#define ALE_JSOP(ale) ((JSOp) (ale)->entry.value) | #define ALE_JSOP(ale) ((JSOp) JS_PTR_TO_UINT32((ale)->entry.value)) | |||
#define ALE_VALUE(ale) ((jsval) (ale)->entry.value) | #define ALE_VALUE(ale) ((jsval) (ale)->entry.value) | |||
#define ALE_NEXT(ale) ((JSAtomListElement *) (ale)->entry.next) | #define ALE_NEXT(ale) ((JSAtomListElement *) (ale)->entry.next) | |||
#define ALE_SET_ATOM(ale,atom) ((ale)->entry.key = (const void *)(atom)) | #define ALE_SET_ATOM(ale,atom) ((ale)->entry.key = (const void *)(atom)) | |||
#define ALE_SET_INDEX(ale,index)((ale)->entry.value = JS_UINT32_TO_PTR(inde x)) | #define ALE_SET_INDEX(ale,index)((ale)->entry.value = JS_UINT32_TO_PTR(inde x)) | |||
#define ALE_SET_JSOP(ale,op) ((ale)->entry.value = JS_UINT32_TO_PTR(op)) | #define ALE_SET_JSOP(ale,op) ((ale)->entry.value = JS_UINT32_TO_PTR(op)) | |||
#define ALE_SET_VALUE(ale,val) ((ale)->entry.value = (JSHashEntry *)(val)) | ||||
#define ALE_SET_NEXT(ale,link) ((ale)->entry.next = (JSHashEntry *)(link)) | ||||
struct JSAtomList { | struct JSAtomList { | |||
JSAtomListElement *list; /* literals indexed for mapping */ | JSHashEntry *list; /* literals indexed for mapping */ | |||
JSHashTable *table; /* hash table if list gets too long */ | JSHashTable *table; /* hash table if list gets too long */ | |||
jsuint count; /* count of indexed literals */ | jsuint count; /* count of indexed literals */ | |||
}; | }; | |||
#define ATOM_LIST_INIT(al) ((al)->list = NULL, (al)->table = NULL, \ | #define ATOM_LIST_INIT(al) ((al)->list = NULL, (al)->table = NULL, \ | |||
(al)->count = 0) | (al)->count = 0) | |||
#define ATOM_LIST_SEARCH(_ale,_al,_atom) \ | #define ATOM_LIST_SEARCH(_ale,_al,_atom) \ | |||
JS_BEGIN_MACRO \ | JS_BEGIN_MACRO \ | |||
JSHashEntry **_hep; \ | JSHashEntry **_hep; \ | |||
ATOM_LIST_LOOKUP(_ale, _hep, _al, _atom); \ | ATOM_LIST_LOOKUP(_ale, _hep, _al, _atom); \ | |||
JS_END_MACRO | JS_END_MACRO | |||
#define ATOM_LIST_LOOKUP(_ale,_hep,_al,_atom) \ | #define ATOM_LIST_LOOKUP(_ale,_hep,_al,_atom) \ | |||
JS_BEGIN_MACRO \ | JS_BEGIN_MACRO \ | |||
if ((_al)->table) { \ | if ((_al)->table) { \ | |||
_hep = JS_HashTableRawLookup((_al)->table, _atom->number, _atom | _hep = JS_HashTableRawLookup((_al)->table, ATOM_HASH(_atom), | |||
); \ | \ | |||
_atom); | ||||
\ | ||||
_ale = *_hep ? (JSAtomListElement *) *_hep : NULL; \ | _ale = *_hep ? (JSAtomListElement *) *_hep : NULL; \ | |||
} else { \ | } else { \ | |||
JSAtomListElement **_alep = &(_al)->list; \ | JSHashEntry **_alep = &(_al)->list; \ | |||
_hep = NULL; \ | _hep = NULL; \ | |||
while ((_ale = *_alep) != NULL) { \ | while ((_ale = (JSAtomListElement *)*_alep) != NULL) { \ | |||
if (ALE_ATOM(_ale) == (_atom)) { \ | if (ALE_ATOM(_ale) == (_atom)) { \ | |||
/* Hit, move atom's element to the front of the list. * / \ | /* Hit, move atom's element to the front of the list. * / \ | |||
*_alep = ALE_NEXT(_ale); | *_alep = (_ale)->entry.next; | |||
\ | \ | |||
ALE_SET_NEXT(_ale, (_al)->list); | (_ale)->entry.next = (_al)->list; | |||
\ | \ | |||
(_al)->list = _ale; | (_al)->list = &_ale->entry; | |||
\ | \ | |||
break; \ | break; \ | |||
} \ | } \ | |||
_alep = (JSAtomListElement **)&_ale->entry.next; \ | _alep = &_ale->entry.next; \ | |||
} \ | } \ | |||
} \ | } \ | |||
JS_END_MACRO | JS_END_MACRO | |||
struct JSAtomMap { | struct JSAtomMap { | |||
JSAtom **vector; /* array of ptrs to indexed atoms * / | JSAtom **vector; /* array of ptrs to indexed atoms * / | |||
jsatomid length; /* count of (to-be-)indexed atoms * / | jsatomid length; /* count of (to-be-)indexed atoms * / | |||
}; | }; | |||
struct JSAtomState { | struct JSAtomState { | |||
JSRuntime *runtime; /* runtime that owns us */ | JSDHashTable stringAtoms; /* hash table with shared strings * | |||
JSHashTable *table; /* hash table containing all atoms | / | |||
*/ | JSDHashTable doubleAtoms; /* hash table with shared doubles * | |||
jsatomid number; /* one beyond greatest atom number | / | |||
*/ | #ifdef JS_THREADSAFE | |||
jsatomid liveAtoms; /* number of live atoms after last | JSThinLock lock; | |||
GC */ | #endif | |||
/* | ||||
* From this point until the end of struct definition the struct must | ||||
* contain only JSAtom fields. We use this to access the storage occupi | ||||
ed | ||||
* by the common atoms in js_FinishCommonAtoms. | ||||
* | ||||
* js_common_atom_names defined in jsatom.c contains C strings for atom | ||||
s | ||||
* in the order of atom fields here. Therefore you must update that arr | ||||
ay | ||||
* if you change member order here. | ||||
*/ | ||||
/* The rt->emptyString atom, see jsstr.c's js_InitRuntimeStringState. * / | /* The rt->emptyString atom, see jsstr.c's js_InitRuntimeStringState. * / | |||
JSAtom *emptyAtom; | JSAtom *emptyAtom; | |||
/* Type names and value literals. */ | /* Type names and value literals. */ | |||
JSAtom *typeAtoms[JSTYPE_LIMIT]; | JSAtom *typeAtoms[JSTYPE_LIMIT]; | |||
JSAtom *booleanAtoms[2]; | JSAtom *booleanAtoms[2]; | |||
JSAtom *nullAtom; | JSAtom *nullAtom; | |||
/* Standard class constructor or prototype names. */ | /* Standard class constructor or prototype names. */ | |||
JSAtom *classAtoms[JSProto_LIMIT]; | JSAtom *classAtoms[JSProto_LIMIT]; | |||
/* Various built-in or commonly-used atoms, pinned on first context. */ | /* Various built-in or commonly-used atoms, pinned on first context. */ | |||
JSAtom *anonymousAtom; | JSAtom *anonymousAtom; | |||
JSAtom *argumentsAtom; | JSAtom *argumentsAtom; | |||
JSAtom *arityAtom; | JSAtom *arityAtom; | |||
JSAtom *calleeAtom; | JSAtom *calleeAtom; | |||
JSAtom *callerAtom; | JSAtom *callerAtom; | |||
JSAtom *classPrototypeAtom; | JSAtom *classPrototypeAtom; | |||
JSAtom *closeAtom; | ||||
JSAtom *constructorAtom; | JSAtom *constructorAtom; | |||
JSAtom *countAtom; | JSAtom *countAtom; | |||
JSAtom *eachAtom; | JSAtom *eachAtom; | |||
JSAtom *etagoAtom; | ||||
JSAtom *evalAtom; | JSAtom *evalAtom; | |||
JSAtom *fileNameAtom; | JSAtom *fileNameAtom; | |||
JSAtom *getAtom; | JSAtom *getAtom; | |||
JSAtom *getterAtom; | JSAtom *getterAtom; | |||
JSAtom *indexAtom; | JSAtom *indexAtom; | |||
JSAtom *inputAtom; | JSAtom *inputAtom; | |||
JSAtom *iteratorAtom; | JSAtom *iteratorAtom; | |||
JSAtom *lengthAtom; | JSAtom *lengthAtom; | |||
JSAtom *lineNumberAtom; | JSAtom *lineNumberAtom; | |||
JSAtom *messageAtom; | JSAtom *messageAtom; | |||
JSAtom *nameAtom; | JSAtom *nameAtom; | |||
JSAtom *namespaceAtom; | ||||
JSAtom *nextAtom; | JSAtom *nextAtom; | |||
JSAtom *noSuchMethodAtom; | JSAtom *noSuchMethodAtom; | |||
JSAtom *parentAtom; | JSAtom *parentAtom; | |||
JSAtom *protoAtom; | JSAtom *protoAtom; | |||
JSAtom *ptagcAtom; | ||||
JSAtom *qualifierAtom; | ||||
JSAtom *setAtom; | JSAtom *setAtom; | |||
JSAtom *setterAtom; | JSAtom *setterAtom; | |||
JSAtom *spaceAtom; | ||||
JSAtom *stackAtom; | JSAtom *stackAtom; | |||
JSAtom *stagoAtom; | ||||
JSAtom *starAtom; | ||||
JSAtom *starQualifierAtom; | ||||
JSAtom *tagcAtom; | ||||
JSAtom *toLocaleStringAtom; | JSAtom *toLocaleStringAtom; | |||
JSAtom *toSourceAtom; | JSAtom *toSourceAtom; | |||
JSAtom *toStringAtom; | JSAtom *toStringAtom; | |||
JSAtom *valueOfAtom; | JSAtom *valueOfAtom; | |||
JSAtom *void0Atom; | ||||
#if JS_HAS_XML_SUPPORT | ||||
JSAtom *etagoAtom; | ||||
JSAtom *namespaceAtom; | ||||
JSAtom *ptagcAtom; | ||||
JSAtom *qualifierAtom; | ||||
JSAtom *spaceAtom; | ||||
JSAtom *stagoAtom; | ||||
JSAtom *starAtom; | ||||
JSAtom *starQualifierAtom; | ||||
JSAtom *tagcAtom; | ||||
JSAtom *xmlAtom; | JSAtom *xmlAtom; | |||
#endif | ||||
#ifdef NARCISSUS | ||||
JSAtom *callAtom; | ||||
JSAtom *constructAtom; | ||||
JSAtom *hasInstanceAtom; | ||||
JSAtom *ExecutionContextAtom; | ||||
JSAtom *currentAtom; | ||||
#endif | ||||
/* Less frequently used atoms, pinned lazily by JS_ResolveStandardClass . */ | /* Less frequently used atoms, pinned lazily by JS_ResolveStandardClass . */ | |||
struct { | struct { | |||
JSAtom *InfinityAtom; | JSAtom *InfinityAtom; | |||
JSAtom *NaNAtom; | JSAtom *NaNAtom; | |||
JSAtom *XMLListAtom; | JSAtom *XMLListAtom; | |||
JSAtom *decodeURIAtom; | JSAtom *decodeURIAtom; | |||
JSAtom *decodeURIComponentAtom; | JSAtom *decodeURIComponentAtom; | |||
JSAtom *defineGetterAtom; | JSAtom *defineGetterAtom; | |||
JSAtom *defineSetterAtom; | JSAtom *defineSetterAtom; | |||
skipping to change at line 238 | skipping to change at line 255 | |||
JSAtom *lookupGetterAtom; | JSAtom *lookupGetterAtom; | |||
JSAtom *lookupSetterAtom; | JSAtom *lookupSetterAtom; | |||
JSAtom *parseFloatAtom; | JSAtom *parseFloatAtom; | |||
JSAtom *parseIntAtom; | JSAtom *parseIntAtom; | |||
JSAtom *propertyIsEnumerableAtom; | JSAtom *propertyIsEnumerableAtom; | |||
JSAtom *unescapeAtom; | JSAtom *unescapeAtom; | |||
JSAtom *unevalAtom; | JSAtom *unevalAtom; | |||
JSAtom *unwatchAtom; | JSAtom *unwatchAtom; | |||
JSAtom *watchAtom; | JSAtom *watchAtom; | |||
} lazy; | } lazy; | |||
#ifdef JS_THREADSAFE | ||||
JSThinLock lock; | ||||
volatile uint32 tablegen; | ||||
#endif | ||||
#ifdef NARCISSUS | ||||
JSAtom *callAtom; | ||||
JSAtom *constructAtom; | ||||
JSAtom *hasInstanceAtom; | ||||
JSAtom *ExecutionContextAtom; | ||||
JSAtom *currentAtom; | ||||
#endif | ||||
}; | }; | |||
#define ATOM_OFFSET_START offsetof(JSAtomState, emptyAtom) | ||||
#define LAZY_ATOM_OFFSET_START offsetof(JSAtomState, lazy) | ||||
#define ATOM_OFFSET_LIMIT (sizeof(JSAtomState)) | ||||
#define COMMON_ATOMS_START(state) | ||||
\ | ||||
(JSAtom **)((uint8 *)(state) + ATOM_OFFSET_START) | ||||
/* Start and limit offsets should correspond to atoms. */ | ||||
JS_STATIC_ASSERT(ATOM_OFFSET_START % sizeof(JSAtom *) == 0); | ||||
JS_STATIC_ASSERT(ATOM_OFFSET_LIMIT % sizeof(JSAtom *) == 0); | ||||
#define ATOM_OFFSET(name) offsetof(JSAtomState, name##Atom) | ||||
#define OFFSET_TO_ATOM(rt,off) (*(JSAtom **)((char*)&(rt)->atomState + (of | ||||
f))) | ||||
#define CLASS_ATOM_OFFSET(name) offsetof(JSAtomState,classAtoms[JSProto_##n | ||||
ame]) | ||||
#define CLASS_ATOM(cx,name) \ | #define CLASS_ATOM(cx,name) \ | |||
((cx)->runtime->atomState.classAtoms[JSProto_##name]) | ((cx)->runtime->atomState.classAtoms[JSProto_##name]) | |||
/* Well-known predefined strings and their atoms. */ | extern const char *const js_common_atom_names[]; | |||
extern const char *js_type_strs[]; | ||||
extern const char *js_boolean_strs[]; | /* | |||
extern const char *js_proto_strs[]; | * Macros to access C strings for JSType and boolean literals together with | |||
* checks that type names and booleans starts from index 1 and 1+JSTYPE_LIM | ||||
IT | ||||
* correspondingly. | ||||
*/ | ||||
#define JS_TYPE_STR(type) (js_common_atom_names[1 + (type)]) | ||||
#define JS_BOOLEAN_STR(type) (js_common_atom_names[1 + JSTYPE_LIMIT + (type | ||||
)]) | ||||
JS_STATIC_ASSERT(1 * sizeof(JSAtom *) == | ||||
offsetof(JSAtomState, typeAtoms) - ATOM_OFFSET_START); | ||||
JS_STATIC_ASSERT((1 + JSTYPE_LIMIT) * sizeof(JSAtom *) == | ||||
offsetof(JSAtomState, booleanAtoms) - ATOM_OFFSET_START); | ||||
/* Well-known predefined C strings. */ | ||||
#define JS_PROTO(name,code,init) extern const char js_##name##_str[]; | #define JS_PROTO(name,code,init) extern const char js_##name##_str[]; | |||
#include "jsproto.tbl" | #include "jsproto.tbl" | |||
#undef JS_PROTO | #undef JS_PROTO | |||
extern const char js_anonymous_str[]; | extern const char js_anonymous_str[]; | |||
extern const char js_arguments_str[]; | extern const char js_arguments_str[]; | |||
extern const char js_arity_str[]; | extern const char js_arity_str[]; | |||
extern const char js_callee_str[]; | extern const char js_callee_str[]; | |||
extern const char js_caller_str[]; | extern const char js_caller_str[]; | |||
extern const char js_class_prototype_str[]; | extern const char js_class_prototype_str[]; | |||
skipping to change at line 291 | skipping to change at line 322 | |||
extern const char js_iterator_str[]; | extern const char js_iterator_str[]; | |||
extern const char js_length_str[]; | extern const char js_length_str[]; | |||
extern const char js_lineNumber_str[]; | extern const char js_lineNumber_str[]; | |||
extern const char js_message_str[]; | extern const char js_message_str[]; | |||
extern const char js_name_str[]; | extern const char js_name_str[]; | |||
extern const char js_namespace_str[]; | extern const char js_namespace_str[]; | |||
extern const char js_next_str[]; | extern const char js_next_str[]; | |||
extern const char js_noSuchMethod_str[]; | extern const char js_noSuchMethod_str[]; | |||
extern const char js_object_str[]; | extern const char js_object_str[]; | |||
extern const char js_parent_str[]; | extern const char js_parent_str[]; | |||
extern const char js_private_str[]; | ||||
extern const char js_proto_str[]; | extern const char js_proto_str[]; | |||
extern const char js_ptagc_str[]; | extern const char js_ptagc_str[]; | |||
extern const char js_qualifier_str[]; | extern const char js_qualifier_str[]; | |||
extern const char js_send_str[]; | extern const char js_send_str[]; | |||
extern const char js_setter_str[]; | extern const char js_setter_str[]; | |||
extern const char js_set_str[]; | extern const char js_set_str[]; | |||
extern const char js_space_str[]; | extern const char js_space_str[]; | |||
extern const char js_stack_str[]; | extern const char js_stack_str[]; | |||
extern const char js_stago_str[]; | extern const char js_stago_str[]; | |||
extern const char js_star_str[]; | extern const char js_star_str[]; | |||
extern const char js_starQualifier_str[]; | extern const char js_starQualifier_str[]; | |||
extern const char js_tagc_str[]; | extern const char js_tagc_str[]; | |||
extern const char js_toSource_str[]; | extern const char js_toSource_str[]; | |||
extern const char js_toString_str[]; | extern const char js_toString_str[]; | |||
extern const char js_toLocaleString_str[]; | extern const char js_toLocaleString_str[]; | |||
extern const char js_undefined_str[]; | ||||
extern const char js_valueOf_str[]; | extern const char js_valueOf_str[]; | |||
extern const char js_xml_str[]; | extern const char js_xml_str[]; | |||
#ifdef NARCISSUS | #ifdef NARCISSUS | |||
extern const char js_call_str[]; | extern const char js_call_str[]; | |||
extern const char js_construct_str[]; | extern const char js_construct_str[]; | |||
extern const char js_hasInstance_str[]; | extern const char js_hasInstance_str[]; | |||
extern const char js_ExecutionContext_str[]; | extern const char js_ExecutionContext_str[]; | |||
extern const char js_current_str[]; | extern const char js_current_str[]; | |||
#endif | #endif | |||
/* | /* | |||
* Initialize atom state. Return true on success, false with an out of | * Initialize atom state. Return true on success, false on failure to alloc | |||
* memory error report on failure. | ate | |||
* memory. The caller must zero rt->atomState before calling this function | ||||
and | ||||
* only call it after js_InitGC successfully returns. | ||||
*/ | */ | |||
extern JSBool | extern JSBool | |||
js_InitAtomState(JSContext *cx, JSAtomState *state); | js_InitAtomState(JSRuntime *rt); | |||
/* | ||||
* Free and clear atom state (except for any interned string atoms). | ||||
*/ | ||||
extern void | ||||
js_FreeAtomState(JSContext *cx, JSAtomState *state); | ||||
/* | /* | |||
* Interned strings are atoms that live until state's runtime is destroyed. | * Free and clear atom state including any interned string atoms. This | |||
* This function frees all interned string atoms, and then frees and clears | * function must be called before js_FinishGC. | |||
* state's members (just as js_FreeAtomState does), unless there aren't any | ||||
* interned strings in state -- in which case state must be "free" already. | ||||
* | ||||
* NB: js_FreeAtomState is called for each "last" context being destroyed i | ||||
n | ||||
* a runtime, where there may yet be another context created in the runtime | ||||
; | ||||
* whereas js_FinishAtomState is called from JS_DestroyRuntime, when we kno | ||||
w | ||||
* that no more contexts will be created. Thus we minimize garbage during | ||||
* context-free episodes on a runtime, while preserving atoms created by th | ||||
e | ||||
* JS_Intern*String APIs for the life of the runtime. | ||||
*/ | */ | |||
extern void | extern void | |||
js_FinishAtomState(JSAtomState *state); | js_FinishAtomState(JSRuntime *rt); | |||
/* | /* | |||
* Atom garbage collection hooks. | * Atom tracing and garbage collection hooks. | |||
*/ | */ | |||
typedef void | ||||
(*JSGCThingMarker)(void *thing, void *data); | ||||
extern void | extern void | |||
js_MarkAtomState(JSAtomState *state, JSBool keepAtoms, JSGCThingMarker mark | js_TraceAtomState(JSTracer *trc, JSBool allAtoms); | |||
, | ||||
void *data); | ||||
extern void | extern void | |||
js_SweepAtomState(JSAtomState *state); | js_SweepAtomState(JSContext *cx); | |||
extern JSBool | extern JSBool | |||
js_InitPinnedAtoms(JSContext *cx, JSAtomState *state); | js_InitCommonAtoms(JSContext *cx); | |||
extern void | extern void | |||
js_UnpinPinnedAtoms(JSAtomState *state); | js_FinishCommonAtoms(JSContext *cx); | |||
/* | ||||
* Find or create the atom for an object. If we create a new atom, give it | ||||
the | ||||
* type indicated in flags. Return 0 on failure to allocate memory. | ||||
*/ | ||||
extern JSAtom * | ||||
js_AtomizeObject(JSContext *cx, JSObject *obj, uintN flags); | ||||
/* | ||||
* Find or create the atom for a Boolean value. If we create a new atom, g | ||||
ive | ||||
* it the type indicated in flags. Return 0 on failure to allocate memory. | ||||
*/ | ||||
extern JSAtom * | ||||
js_AtomizeBoolean(JSContext *cx, JSBool b, uintN flags); | ||||
/* | ||||
* Find or create the atom for an integer value. If we create a new atom, | ||||
give | ||||
* it the type indicated in flags. Return 0 on failure to allocate memory. | ||||
*/ | ||||
extern JSAtom * | ||||
js_AtomizeInt(JSContext *cx, jsint i, uintN flags); | ||||
/* | /* | |||
* Find or create the atom for a double value. If we create a new atom, gi | * Find or create the atom for a double value. Return null on failure to | |||
ve | * allocate memory. | |||
* it the type indicated in flags. Return 0 on failure to allocate memory. | ||||
*/ | */ | |||
extern JSAtom * | extern JSAtom * | |||
js_AtomizeDouble(JSContext *cx, jsdouble d, uintN flags); | js_AtomizeDouble(JSContext *cx, jsdouble d); | |||
/* | /* | |||
* Find or create the atom for a string. If we create a new atom, give it | * Find or create the atom for a string. Return null on failure to allocate | |||
the | * memory. | |||
* type indicated in flags. Return 0 on failure to allocate memory. | ||||
*/ | */ | |||
extern JSAtom * | extern JSAtom * | |||
js_AtomizeString(JSContext *cx, JSString *str, uintN flags); | js_AtomizeString(JSContext *cx, JSString *str, uintN flags); | |||
extern JS_FRIEND_API(JSAtom *) | extern JSAtom * | |||
js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags); | js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags); | |||
extern JS_FRIEND_API(JSAtom *) | extern JSAtom * | |||
js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN fl ags); | js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN fl ags); | |||
/* | /* | |||
* Return an existing atom for the given char array or null if the char | * Return an existing atom for the given char array or null if the char | |||
* sequence is currently not atomized. | * sequence is currently not atomized. | |||
*/ | */ | |||
extern JSAtom * | extern JSAtom * | |||
js_GetExistingStringAtom(JSContext *cx, const jschar *chars, size_t length) ; | js_GetExistingStringAtom(JSContext *cx, const jschar *chars, size_t length) ; | |||
/* | /* | |||
* This variant handles all value tag types. | * This variant handles all primitive values. | |||
*/ | */ | |||
extern JSAtom * | JSBool | |||
js_AtomizeValue(JSContext *cx, jsval value, uintN flags); | js_AtomizePrimitiveValue(JSContext *cx, jsval v, JSAtom **atomp); | |||
/* | /* | |||
* Convert v to an atomized string. | * Convert v to an atomized string and wrap it as an id. | |||
*/ | */ | |||
extern JSAtom * | extern JSBool | |||
js_ValueToStringAtom(JSContext *cx, jsval v); | js_ValueToStringId(JSContext *cx, jsval v, jsid *idp); | |||
#ifdef DEBUG | ||||
extern JS_FRIEND_API(void) | ||||
js_DumpAtoms(JSContext *cx, FILE *fp); | ||||
#endif | ||||
/* | /* | |||
* Assign atom an index and insert it on al. | * Assign atom an index and insert it on al. | |||
*/ | */ | |||
extern JSAtomListElement * | extern JSAtomListElement * | |||
js_IndexAtom(JSContext *cx, JSAtom *atom, JSAtomList *al); | js_IndexAtom(JSContext *cx, JSAtom *atom, JSAtomList *al); | |||
/* | /* | |||
* Get the atom with index i from map. | ||||
*/ | ||||
extern JS_FRIEND_API(JSAtom *) | ||||
js_GetAtom(JSContext *cx, JSAtomMap *map, jsatomid i); | ||||
/* | ||||
* For all unmapped atoms recorded in al, add a mapping from the atom's ind ex | * For all unmapped atoms recorded in al, add a mapping from the atom's ind ex | |||
* to its address. The GC must not run until all indexed atoms in atomList | * to its address. map->length must already be set to the number of atoms i | |||
s | n | |||
* have been mapped by scripts connected to live objects (Function and Scri | * the list and map->vector must point to pre-allocated memory. | |||
pt | ||||
* class objects have scripts as/in their private data -- the GC knows abou | ||||
t | ||||
* these two classes). | ||||
*/ | */ | |||
extern JS_FRIEND_API(JSBool) | extern void | |||
js_InitAtomMap(JSContext *cx, JSAtomMap *map, JSAtomList *al); | js_InitAtomMap(JSContext *cx, JSAtomMap *map, JSAtomList *al); | |||
/* | ||||
* Free map->vector and clear map. | ||||
*/ | ||||
extern JS_FRIEND_API(void) | ||||
js_FreeAtomMap(JSContext *cx, JSAtomMap *map); | ||||
JS_END_EXTERN_C | JS_END_EXTERN_C | |||
#endif /* jsatom_h___ */ | #endif /* jsatom_h___ */ | |||
End of changes. 54 change blocks. | ||||
171 lines changed or deleted | 151 lines changed or added | |||
jsautocfg.h | jsautocfg.h | |||
---|---|---|---|---|
skipping to change at line 52 | skipping to change at line 52 | |||
#define JS_ALIGN_OF_DOUBLE 4L | #define JS_ALIGN_OF_DOUBLE 4L | |||
#define JS_ALIGN_OF_POINTER 4L | #define JS_ALIGN_OF_POINTER 4L | |||
#define JS_ALIGN_OF_WORD 4L | #define JS_ALIGN_OF_WORD 4L | |||
#define JS_BYTES_PER_WORD_LOG2 2L | #define JS_BYTES_PER_WORD_LOG2 2L | |||
#define JS_BYTES_PER_DWORD_LOG2 3L | #define JS_BYTES_PER_DWORD_LOG2 3L | |||
#define JS_WORDS_PER_DWORD_LOG2 1L | #define JS_WORDS_PER_DWORD_LOG2 1L | |||
#define JS_STACK_GROWTH_DIRECTION (-1) | #define JS_STACK_GROWTH_DIRECTION (-1) | |||
#define JS_HAVE_LONG_LONG | ||||
#endif /* js_cpucfg___ */ | #endif /* js_cpucfg___ */ | |||
End of changes. 1 change blocks. | ||||
0 lines changed or deleted | 2 lines changed or added | |||
jsbit.h | jsbit.h | |||
---|---|---|---|---|
skipping to change at line 53 | skipping to change at line 53 | |||
#include "jsutil.h" | #include "jsutil.h" | |||
JS_BEGIN_EXTERN_C | JS_BEGIN_EXTERN_C | |||
/* | /* | |||
** A jsbitmap_t is a long integer that can be used for bitmaps | ** A jsbitmap_t is a long integer that can be used for bitmaps | |||
*/ | */ | |||
typedef JSUword jsbitmap_t; /* NSPR name, a la Unix system types */ | typedef JSUword jsbitmap_t; /* NSPR name, a la Unix system types */ | |||
typedef jsbitmap_t jsbitmap; /* JS-style scalar typedef name */ | typedef jsbitmap_t jsbitmap; /* JS-style scalar typedef name */ | |||
#define JS_TEST_BIT(_map,_bit) \ | #define JS_BITMAP_SIZE(bits) (JS_HOWMANY(bits, JS_BITS_PER_WORD) * | |||
((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] & (1L << ((_bit) & (JS_BITS_PER_ | \ | |||
WORD-1)))) | sizeof(jsbitmap)) | |||
#define JS_SET_BIT(_map,_bit) \ | ||||
((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] |= (1L << ((_bit) & (JS_BITS_PER | #define JS_TEST_BIT(_map,_bit) ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] & | |||
_WORD-1)))) | \ | |||
#define JS_CLEAR_BIT(_map,_bit) \ | ((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1) | |||
((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] &= ~(1L << ((_bit) & (JS_BITS_PE | ))) | |||
R_WORD-1)))) | #define JS_SET_BIT(_map,_bit) ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] |= | |||
\ | ||||
((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1) | ||||
))) | ||||
#define JS_CLEAR_BIT(_map,_bit) ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] &= | ||||
\ | ||||
~((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1 | ||||
)))) | ||||
/* | /* | |||
** Compute the log of the least power of 2 greater than or equal to n | ** Compute the log of the least power of 2 greater than or equal to n | |||
*/ | */ | |||
extern JS_PUBLIC_API(JSIntn) JS_CeilingLog2(JSUint32 i); | extern JS_PUBLIC_API(JSIntn) JS_CeilingLog2(JSUint32 i); | |||
/* | /* | |||
** Compute the log of the greatest power of 2 less than or equal to n | ** Compute the log of the greatest power of 2 less than or equal to n | |||
*/ | */ | |||
extern JS_PUBLIC_API(JSIntn) JS_FloorLog2(JSUint32 i); | extern JS_PUBLIC_API(JSIntn) JS_FloorLog2(JSUint32 i); | |||
/* | /* | |||
* Check if __builtin_clz is available which apeared first in GCC 3.4. | * Replace bit-scanning code sequences with CPU-specific instructions to | |||
* The built-in allows to speedup calculations of ceiling/floor log2, | * speedup calculations of ceiling/floor log2. | |||
* see bug 327129. | * | |||
* With GCC 3.4 or later we can use __builtin_clz for that, see bug 327129. | ||||
* | ||||
* SWS: Added MSVC intrinsic bitscan support. See bugs 349364 and 356856. | ||||
*/ | */ | |||
#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) | #if defined(_WIN32) && (_MSC_VER >= 1300) && defined(_M_IX86) | |||
# define JS_HAS_GCC_BUILTIN_CLZ | ||||
unsigned char _BitScanForward(unsigned long * Index, unsigned long Mask); | ||||
unsigned char _BitScanReverse(unsigned long * Index, unsigned long Mask); | ||||
# pragma intrinsic(_BitScanForward,_BitScanReverse) | ||||
__forceinline static int | ||||
__BitScanForward32(unsigned int val) | ||||
{ | ||||
unsigned long idx; | ||||
_BitScanForward(&idx, (unsigned long)val); | ||||
return (int)idx; | ||||
} | ||||
__forceinline static int | ||||
__BitScanReverse32(unsigned int val) | ||||
{ | ||||
unsigned long idx; | ||||
_BitScanReverse(&idx, (unsigned long)val); | ||||
return (int)(31-idx); | ||||
} | ||||
# define js_bitscan_ctz32(val) __BitScanForward32(val) | ||||
# define js_bitscan_clz32(val) __BitScanReverse32(val) | ||||
# define JS_HAS_BUILTIN_BITSCAN32 | ||||
#elif (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) | ||||
# define js_bitscan_ctz32(val) __builtin_ctz(val) | ||||
# define js_bitscan_clz32(val) __builtin_clz(val) | ||||
# define JS_HAS_BUILTIN_BITSCAN32 | ||||
# if (JS_BYTES_PER_WORD == 8) | ||||
# define js_bitscan_ctz64(val) __builtin_ctzll(val) | ||||
# define js_bitscan_clz64(val) __builtin_clzll(val) | ||||
# define JS_HAS_BUILTIN_BITSCAN64 | ||||
# endif | ||||
#endif | #endif | |||
/* | /* | |||
** Macro version of JS_CeilingLog2: Compute the log of the least power of | ** Macro version of JS_CeilingLog2: Compute the log of the least power of | |||
** 2 greater than or equal to _n. The result is returned in _log2. | ** 2 greater than or equal to _n. The result is returned in _log2. | |||
*/ | */ | |||
#ifdef JS_HAS_GCC_BUILTIN_CLZ | #ifdef JS_HAS_BUILTIN_BITSCAN32 | |||
/* | /* | |||
* Use __builtin_clz or count-leading-zeros to calculate ceil(log2(_n)). | * Use intrinsic function or count-leading-zeros to calculate ceil(log2(_n) | |||
* The macro checks for "n <= 1" and not "n != 0" as __builtin_clz(0) is | ). | |||
* The macro checks for "n <= 1" and not "n != 0" as js_bitscan_clz32(0) is | ||||
* undefined. | * undefined. | |||
*/ | */ | |||
# define JS_CEILING_LOG2(_log2,_n) \ | # define JS_CEILING_LOG2(_log2,_n) \ | |||
JS_BEGIN_MACRO \ | JS_BEGIN_MACRO \ | |||
JS_STATIC_ASSERT(sizeof(unsigned int) == sizeof(JSUint32)); \ | JS_STATIC_ASSERT(sizeof(unsigned int) == sizeof(JSUint32)); \ | |||
unsigned int j_ = (unsigned int)(_n); \ | unsigned int j_ = (unsigned int)(_n); \ | |||
(_log2) = (j_ <= 1 ? 0 : 32 - __builtin_clz(j_ - 1)); \ | (_log2) = (j_ <= 1 ? 0 : 32 - js_bitscan_clz32(j_ - 1)); \ | |||
JS_END_MACRO | JS_END_MACRO | |||
#else | #else | |||
# define JS_CEILING_LOG2(_log2,_n) \ | # define JS_CEILING_LOG2(_log2,_n) \ | |||
JS_BEGIN_MACRO \ | JS_BEGIN_MACRO \ | |||
JSUint32 j_ = (JSUint32)(_n); \ | JSUint32 j_ = (JSUint32)(_n); \ | |||
(_log2) = 0; \ | (_log2) = 0; \ | |||
if ((j_) & ((j_)-1)) \ | if ((j_) & ((j_)-1)) \ | |||
(_log2) += 1; \ | (_log2) += 1; \ | |||
if ((j_) >> 16) \ | if ((j_) >> 16) \ | |||
(_log2) += 16, (j_) >>= 16; \ | (_log2) += 16, (j_) >>= 16; \ | |||
skipping to change at line 121 | skipping to change at line 162 | |||
(_log2) += 1; \ | (_log2) += 1; \ | |||
JS_END_MACRO | JS_END_MACRO | |||
#endif | #endif | |||
/* | /* | |||
** Macro version of JS_FloorLog2: Compute the log of the greatest power of | ** Macro version of JS_FloorLog2: Compute the log of the greatest power of | |||
** 2 less than or equal to _n. The result is returned in _log2. | ** 2 less than or equal to _n. The result is returned in _log2. | |||
** | ** | |||
** This is equivalent to finding the highest set bit in the word. | ** This is equivalent to finding the highest set bit in the word. | |||
*/ | */ | |||
#if JS_GCC_HAS_BUILTIN_CLZ | #ifdef JS_HAS_BUILTIN_BITSCAN32 | |||
/* | /* | |||
* Use __builtin_clz or count-leading-zeros to calculate floor(log2(_n)). | * Use js_bitscan_clz32 or count-leading-zeros to calculate floor(log2(_n)) | |||
* Since __builtin_clz(0) is undefined, the macro set the loweset bit to 1 | . | |||
* Since js_bitscan_clz32(0) is undefined, the macro set the loweset bit to | ||||
1 | ||||
* to ensure 0 result when _n == 0. | * to ensure 0 result when _n == 0. | |||
*/ | */ | |||
# define JS_FLOOR_LOG2(_log2,_n) \ | # define JS_FLOOR_LOG2(_log2,_n) \ | |||
JS_BEGIN_MACRO \ | JS_BEGIN_MACRO \ | |||
JS_STATIC_ASSERT(sizeof(unsigned int) == sizeof(JSUint32)); \ | JS_STATIC_ASSERT(sizeof(unsigned int) == sizeof(JSUint32)); \ | |||
(_log2) = 31 - __builtin_clz(((unsigned int)(_n)) | 1); \ | (_log2) = 31 - js_bitscan_clz32(((unsigned int)(_n)) | 1); \ | |||
JS_END_MACRO | JS_END_MACRO | |||
#else | #else | |||
# define JS_FLOOR_LOG2(_log2,_n) \ | # define JS_FLOOR_LOG2(_log2,_n) \ | |||
JS_BEGIN_MACRO \ | JS_BEGIN_MACRO \ | |||
JSUint32 j_ = (JSUint32)(_n); \ | JSUint32 j_ = (JSUint32)(_n); \ | |||
(_log2) = 0; \ | (_log2) = 0; \ | |||
if ((j_) >> 16) \ | if ((j_) >> 16) \ | |||
(_log2) += 16, (j_) >>= 16; \ | (_log2) += 16, (j_) >>= 16; \ | |||
if ((j_) >> 8) \ | if ((j_) >> 8) \ | |||
(_log2) += 8, (j_) >>= 8; \ | (_log2) += 8, (j_) >>= 8; \ | |||
skipping to change at line 166 | skipping to change at line 207 | |||
#define JS_CEILING_LOG2W(n) ((n) <= 1 ? 0 : 1 + JS_FLOOR_LOG2W((n) - 1)) | #define JS_CEILING_LOG2W(n) ((n) <= 1 ? 0 : 1 + JS_FLOOR_LOG2W((n) - 1)) | |||
/* | /* | |||
* Internal function. | * Internal function. | |||
* Compute the log of the greatest power of 2 less than or equal to n. | * Compute the log of the greatest power of 2 less than or equal to n. | |||
* This is a version of JS_FloorLog2 that operates on jsuword with | * This is a version of JS_FloorLog2 that operates on jsuword with | |||
* CPU-dependant size and requires that n != 0. | * CPU-dependant size and requires that n != 0. | |||
*/ | */ | |||
#define JS_FLOOR_LOG2W(n) (JS_ASSERT((n) != 0), js_FloorLog2wImpl(n)) | #define JS_FLOOR_LOG2W(n) (JS_ASSERT((n) != 0), js_FloorLog2wImpl(n)) | |||
#ifdef JS_HAS_GCC_BUILTIN_CLZ | #if JS_BYTES_PER_WORD == 4 | |||
# if JS_BYTES_PER_WORD == 4 | # ifdef JS_HAS_BUILTIN_BITSCAN32 | |||
JS_STATIC_ASSERT(sizeof(unsigned) == sizeof(JSUword)); | JS_STATIC_ASSERT(sizeof(unsigned) == sizeof(JSUword)); | |||
# define js_FloorLog2wImpl(n) \ | # define js_FloorLog2wImpl(n) \ | |||
((JSUword)(JS_BITS_PER_WORD - 1 - __builtin_clz(n))) | ((JSUword)(JS_BITS_PER_WORD - 1 - js_bitscan_clz32(n))) | |||
# elif JS_BYTES_PER_WORD == 8 | # else | |||
# define js_FloorLog2wImpl(n) ((JSUword)JS_FloorLog2(n)) | ||||
#endif | ||||
#elif JS_BYTES_PER_WORD == 8 | ||||
# ifdef JS_HAS_BUILTIN_BITSCAN64 | ||||
JS_STATIC_ASSERT(sizeof(unsigned long long) == sizeof(JSUword)); | JS_STATIC_ASSERT(sizeof(unsigned long long) == sizeof(JSUword)); | |||
# define js_FloorLog2wImpl(n) \ | # define js_FloorLog2wImpl(n) \ | |||
((JSUword)(JS_BITS_PER_WORD - 1 - __builtin_clzll(n))) | ((JSUword)(JS_BITS_PER_WORD - 1 - js_bitscan_clz64(n))) | |||
# else | # else | |||
# error "NOT SUPPORTED" | extern JSUword js_FloorLog2wImpl(JSUword n); | |||
# endif | # endif | |||
#else | #else | |||
# if JS_BYTES_PER_WORD == 4 | # error "NOT SUPPORTED" | |||
# define js_FloorLog2wImpl(n) ((JSUword)JS_FloorLog2(n)) | ||||
# elif JS_BYTES_PER_WORD == 8 | ||||
extern JSUword | ||||
js_FloorLog2wImpl(JSUword n); | ||||
# else | ||||
# error "NOT SUPPORTED" | ||||
# endif | ||||
#endif | #endif | |||
/* | ||||
* Macros for rotate left. There is no rotate operation in the C Language s | ||||
o | ||||
* the construct (a << 4) | (a >> 28) is used instead. Most compilers conve | ||||
rt | ||||
* this to a rotate instruction but some versions of MSVC don't without a | ||||
* little help. To get MSVC to generate a rotate instruction, we have to u | ||||
se | ||||
* the _rotl intrinsic and use a pragma to make _rotl inline. | ||||
* | ||||
* MSVC in VS2005 will do an inline rotate instruction on the above constru | ||||
ct. | ||||
*/ | ||||
#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || \ | ||||
defined(_M_X64)) | ||||
#include <stdlib.h> | ||||
#pragma intrinsic(_rotl) | ||||
#define JS_ROTATE_LEFT32(a, bits) _rotl(a, bits) | ||||
#else | ||||
#define JS_ROTATE_LEFT32(a, bits) (((a) << (bits)) | ((a) >> (32 - (bits))) | ||||
) | ||||
#endif | ||||
JS_END_EXTERN_C | JS_END_EXTERN_C | |||
#endif /* jsbit_h___ */ | #endif /* jsbit_h___ */ | |||
End of changes. 16 change blocks. | ||||
36 lines changed or deleted | 107 lines changed or added | |||
jsbool.h | jsbool.h | |||
---|---|---|---|---|
skipping to change at line 65 | skipping to change at line 65 | |||
* JSVAL_ARETURN is used to throw asynchronous return for generator.close() . | * JSVAL_ARETURN is used to throw asynchronous return for generator.close() . | |||
*/ | */ | |||
#define JSVAL_HOLE BOOLEAN_TO_JSVAL(2) | #define JSVAL_HOLE BOOLEAN_TO_JSVAL(2) | |||
#define JSVAL_ARETURN BOOLEAN_TO_JSVAL(3) | #define JSVAL_ARETURN BOOLEAN_TO_JSVAL(3) | |||
extern JSClass js_BooleanClass; | extern JSClass js_BooleanClass; | |||
extern JSObject * | extern JSObject * | |||
js_InitBooleanClass(JSContext *cx, JSObject *obj); | js_InitBooleanClass(JSContext *cx, JSObject *obj); | |||
extern JSObject * | ||||
js_BooleanToObject(JSContext *cx, JSBool b); | ||||
extern JSString * | extern JSString * | |||
js_BooleanToString(JSContext *cx, JSBool b); | js_BooleanToString(JSContext *cx, JSBool b); | |||
extern JSBool | extern JSBool | |||
js_ValueToBoolean(JSContext *cx, jsval v, JSBool *bp); | js_ValueToBoolean(jsval v); | |||
JS_END_EXTERN_C | JS_END_EXTERN_C | |||
#endif /* jsbool_h___ */ | #endif /* jsbool_h___ */ | |||
End of changes. 2 change blocks. | ||||
4 lines changed or deleted | 1 lines changed or added | |||
jscntxt.h | jscntxt.h | |||
---|---|---|---|---|
skipping to change at line 64 | skipping to change at line 64 | |||
#include "jsobj.h" | #include "jsobj.h" | |||
#include "jsprvtd.h" | #include "jsprvtd.h" | |||
#include "jspubtd.h" | #include "jspubtd.h" | |||
#include "jsregexp.h" | #include "jsregexp.h" | |||
#include "jsutil.h" | #include "jsutil.h" | |||
JS_BEGIN_EXTERN_C | JS_BEGIN_EXTERN_C | |||
/* | /* | |||
* js_GetSrcNote cache to avoid O(n^2) growth in finding a source note for a | * js_GetSrcNote cache to avoid O(n^2) growth in finding a source note for a | |||
* given pc in a script. | * given pc in a script. We use the script->code pointer to tag the cache, | |||
* instead of the script address itself, so that source notes are always fo | ||||
und | ||||
* by offset from the bytecode with which they were generated. | ||||
*/ | */ | |||
typedef struct JSGSNCache { | typedef struct JSGSNCache { | |||
JSScript *script; | jsbytecode *code; | |||
JSDHashTable table; | JSDHashTable table; | |||
#ifdef JS_GSNMETER | #ifdef JS_GSNMETER | |||
uint32 hits; | uint32 hits; | |||
uint32 misses; | uint32 misses; | |||
uint32 fills; | uint32 fills; | |||
uint32 clears; | uint32 clears; | |||
# define GSN_CACHE_METER(cache,cnt) (++(cache)->cnt) | # define GSN_CACHE_METER(cache,cnt) (++(cache)->cnt) | |||
#else | #else | |||
# define GSN_CACHE_METER(cache,cnt) /* nothing */ | # define GSN_CACHE_METER(cache,cnt) /* nothing */ | |||
#endif | #endif | |||
} JSGSNCache; | } JSGSNCache; | |||
#define GSN_CACHE_CLEAR(cache) \ | #define GSN_CACHE_CLEAR(cache) \ | |||
JS_BEGIN_MACRO \ | JS_BEGIN_MACRO \ | |||
(cache)->script = NULL; \ | (cache)->code = NULL; \ | |||
if ((cache)->table.ops) { \ | if ((cache)->table.ops) { \ | |||
JS_DHashTableFinish(&(cache)->table); \ | JS_DHashTableFinish(&(cache)->table); \ | |||
(cache)->table.ops = NULL; \ | (cache)->table.ops = NULL; \ | |||
} \ | } \ | |||
GSN_CACHE_METER(cache, clears); \ | GSN_CACHE_METER(cache, clears); \ | |||
JS_END_MACRO | JS_END_MACRO | |||
/* These helper macros take a cx as parameter and operate on its GSN cache. */ | /* These helper macros take a cx as parameter and operate on its GSN cache. */ | |||
#define JS_CLEAR_GSN_CACHE(cx) GSN_CACHE_CLEAR(&JS_GSN_CACHE(cx)) | #define JS_CLEAR_GSN_CACHE(cx) GSN_CACHE_CLEAR(&JS_GSN_CACHE(cx)) | |||
#define JS_METER_GSN_CACHE(cx,cnt) GSN_CACHE_METER(&JS_GSN_CACHE(cx), cnt) | #define JS_METER_GSN_CACHE(cx,cnt) GSN_CACHE_METER(&JS_GSN_CACHE(cx), cnt) | |||
skipping to change at line 107 | skipping to change at line 109 | |||
* Structure uniquely representing a thread. It holds thread-private data | * Structure uniquely representing a thread. It holds thread-private data | |||
* that can be accessed without a global lock. | * that can be accessed without a global lock. | |||
*/ | */ | |||
struct JSThread { | struct JSThread { | |||
/* Linked list of all contexts active on this thread. */ | /* Linked list of all contexts active on this thread. */ | |||
JSCList contextList; | JSCList contextList; | |||
/* Opaque thread-id, from NSPR's PR_GetCurrentThread(). */ | /* Opaque thread-id, from NSPR's PR_GetCurrentThread(). */ | |||
jsword id; | jsword id; | |||
/* Thread-local gc free lists array. */ | ||||
JSGCThing *gcFreeLists[GC_NUM_FREELISTS]; | ||||
/* | /* | |||
* Thread-local version of JSRuntime.gcMallocBytes to avoid taking | * Thread-local version of JSRuntime.gcMallocBytes to avoid taking | |||
* locks on each JS_malloc. | * locks on each JS_malloc. | |||
*/ | */ | |||
uint32 gcMallocBytes; | uint32 gcMallocBytes; | |||
#if JS_HAS_GENERATORS | /* Thread-local gc free lists array. */ | |||
/* Flag indicating that the current thread is executing close hooks. */ | JSGCThing *gcFreeLists[GC_NUM_FREELISTS]; | |||
JSBool gcRunningCloseHooks; | ||||
#endif | ||||
/* | /* | |||
* Store the GSN cache in struct JSThread, not struct JSContext, both t o | * Store the GSN cache in struct JSThread, not struct JSContext, both t o | |||
* save space and to simplify cleanup in js_GC. Any embedding (Firefox | * save space and to simplify cleanup in js_GC. Any embedding (Firefox | |||
* or another Gecko application) that uses many contexts per thread is | * or another Gecko application) that uses many contexts per thread is | |||
* unlikely to interleave js_GetSrcNote-intensive loops in the decompil er | * unlikely to interleave js_GetSrcNote-intensive loops in the decompil er | |||
* among two or more contexts running script in one thread. | * among two or more contexts running script in one thread. | |||
*/ | */ | |||
JSGSNCache gsnCache; | JSGSNCache gsnCache; | |||
/* Property cache for faster call/get/set invocation. */ | ||||
JSPropertyCache propertyCache; | ||||
}; | }; | |||
#define JS_GSN_CACHE(cx) ((cx)->thread->gsnCache) | #define JS_GSN_CACHE(cx) ((cx)->thread->gsnCache) | |||
#define JS_PROPERTY_CACHE(cx) ((cx)->thread->propertyCache) | ||||
extern void JS_DLL_CALLBACK | extern void JS_DLL_CALLBACK | |||
js_ThreadDestructorCB(void *ptr); | js_ThreadDestructorCB(void *ptr); | |||
extern JSBool | extern JSBool | |||
js_SetContextThread(JSContext *cx); | js_SetContextThread(JSContext *cx); | |||
extern void | extern void | |||
js_ClearContextThread(JSContext *cx); | js_ClearContextThread(JSContext *cx); | |||
skipping to change at line 171 | skipping to change at line 172 | |||
typedef struct JSPropertyTreeEntry { | typedef struct JSPropertyTreeEntry { | |||
JSDHashEntryHdr hdr; | JSDHashEntryHdr hdr; | |||
JSScopeProperty *child; | JSScopeProperty *child; | |||
} JSPropertyTreeEntry; | } JSPropertyTreeEntry; | |||
/* | /* | |||
* Forward declaration for opaque JSRuntime.nativeIteratorStates. | * Forward declaration for opaque JSRuntime.nativeIteratorStates. | |||
*/ | */ | |||
typedef struct JSNativeIteratorState JSNativeIteratorState; | typedef struct JSNativeIteratorState JSNativeIteratorState; | |||
typedef struct JSSetSlotRequest JSSetSlotRequest; | ||||
struct JSSetSlotRequest { | ||||
JSObject *obj; /* object containing slot to set */ | ||||
JSObject *pobj; /* new proto or parent reference */ | ||||
uint16 slot; /* which to set, proto or parent */ | ||||
uint16 errnum; /* JSMSG_NO_ERROR or error result * | ||||
/ | ||||
JSSetSlotRequest *next; /* next request in GC worklist */ | ||||
}; | ||||
struct JSRuntime { | struct JSRuntime { | |||
/* Runtime state, synchronized by the stateChange/gcLock condvar/lock. */ | /* Runtime state, synchronized by the stateChange/gcLock condvar/lock. */ | |||
JSRuntimeState state; | JSRuntimeState state; | |||
/* Context create/destroy callback. */ | /* Context create/destroy callback. */ | |||
JSContextCallback cxCallback; | JSContextCallback cxCallback; | |||
/* Garbage collector state, used by jsgc.c. */ | /* Garbage collector state, used by jsgc.c. */ | |||
JSGCChunkInfo *gcChunkList; | ||||
JSGCArenaList gcArenaList[GC_NUM_FREELISTS]; | JSGCArenaList gcArenaList[GC_NUM_FREELISTS]; | |||
JSGCDoubleArenaList gcDoubleArenaList; | ||||
JSDHashTable gcRootsHash; | JSDHashTable gcRootsHash; | |||
JSDHashTable *gcLocksHash; | JSDHashTable *gcLocksHash; | |||
jsrefcount gcKeepAtoms; | jsrefcount gcKeepAtoms; | |||
uint32 gcBytes; | uint32 gcBytes; | |||
uint32 gcLastBytes; | uint32 gcLastBytes; | |||
uint32 gcMaxBytes; | uint32 gcMaxBytes; | |||
uint32 gcMaxMallocBytes; | uint32 gcMaxMallocBytes; | |||
uint32 gcStackPoolLifespan; | ||||
uint32 gcLevel; | uint32 gcLevel; | |||
uint32 gcNumber; | uint32 gcNumber; | |||
JSTracer *gcMarkingTracer; | ||||
/* | /* | |||
* NB: do not pack another flag here by claiming gcPadding unless the n ew | * NB: do not pack another flag here by claiming gcPadding unless the n ew | |||
* flag is written only by the GC thread. Atomic updates to packed byt es | * flag is written only by the GC thread. Atomic updates to packed byt es | |||
* are not guaranteed, so stores issued by one thread may be lost due t o | * are not guaranteed, so stores issued by one thread may be lost due t o | |||
* unsynchronized read-modify-write cycles on other threads. | * unsynchronized read-modify-write cycles on other threads. | |||
*/ | */ | |||
JSPackedBool gcPoke; | JSPackedBool gcPoke; | |||
JSPackedBool gcRunning; | JSPackedBool gcRunning; | |||
uint16 gcPadding; | uint16 gcPadding; | |||
#ifdef JS_GC_ZEAL | ||||
jsrefcount gcZeal; | ||||
#endif | ||||
JSGCCallback gcCallback; | JSGCCallback gcCallback; | |||
uint32 gcMallocBytes; | uint32 gcMallocBytes; | |||
JSGCArena *gcUnscannedArenaStackTop; | JSGCArenaInfo *gcUntracedArenaStackTop; | |||
#ifdef DEBUG | #ifdef DEBUG | |||
size_t gcUnscannedBagSize; | size_t gcTraceLaterCount; | |||
#endif | #endif | |||
/* | /* | |||
* API compatibility requires keeping GCX_PRIVATE bytes separate from t | ||||
he | ||||
* original GC types' byte tally. Otherwise embeddings that configure | ||||
a | ||||
* good limit for pre-GCX_PRIVATE versions of the engine will see memor | ||||
y | ||||
* over-pressure too often, possibly leading to failed last-ditch GCs. | ||||
* | ||||
* The new XML GC-thing types do add to gcBytes, and they're larger tha | ||||
n | ||||
* the original GC-thing type size (8 bytes on most architectures). So | ||||
a | ||||
* user who enables E4X may want to increase the maxbytes value passed | ||||
to | ||||
* JS_NewRuntime. TODO: Note this in the API docs. | ||||
*/ | ||||
uint32 gcPrivateBytes; | ||||
/* | ||||
* Table for tracking iterators to ensure that we close iterator's stat e | * Table for tracking iterators to ensure that we close iterator's stat e | |||
* before finalizing the iterable object. | * before finalizing the iterable object. | |||
*/ | */ | |||
JSPtrTable gcIteratorTable; | JSPtrTable gcIteratorTable; | |||
#if JS_HAS_GENERATORS | /* | |||
/* Runtime state to support close hooks. */ | * The trace operation and its data argument to trace embedding-specifi | |||
JSGCCloseState gcCloseState; | c | |||
#endif | * GC roots. | |||
*/ | ||||
#ifdef JS_GCMETER | JSTraceDataOp gcExtraRootsTraceOp; | |||
JSGCStats gcStats; | void *gcExtraRootsData; | |||
#endif | ||||
/* Literal table maintained by jsatom.c functions. */ | /* | |||
JSAtomState atomState; | * Used to serialize cycle checks when setting __proto__ or __parent__ | |||
by | ||||
* requesting the GC handle the required cycle detection. If the GC has | ||||
n't | ||||
* been poked, it won't scan for garbage. This member is protected by | ||||
* rt->gcLock. | ||||
*/ | ||||
JSSetSlotRequest *setSlotRequests; | ||||
/* Random number generator state, used by jsmath.c. */ | /* Random number generator state, used by jsmath.c. */ | |||
JSBool rngInitialized; | JSBool rngInitialized; | |||
int64 rngMultiplier; | int64 rngMultiplier; | |||
int64 rngAddend; | int64 rngAddend; | |||
int64 rngMask; | int64 rngMask; | |||
int64 rngSeed; | int64 rngSeed; | |||
jsdouble rngDscale; | jsdouble rngDscale; | |||
/* Well-known numbers held for use by this runtime's contexts. */ | /* Well-known numbers held for use by this runtime's contexts. */ | |||
skipping to change at line 259 | skipping to change at line 267 | |||
jsdouble *jsPositiveInfinity; | jsdouble *jsPositiveInfinity; | |||
#ifdef JS_THREADSAFE | #ifdef JS_THREADSAFE | |||
JSLock *deflatedStringCacheLock; | JSLock *deflatedStringCacheLock; | |||
#endif | #endif | |||
JSHashTable *deflatedStringCache; | JSHashTable *deflatedStringCache; | |||
#ifdef DEBUG | #ifdef DEBUG | |||
uint32 deflatedStringCacheBytes; | uint32 deflatedStringCacheBytes; | |||
#endif | #endif | |||
/* Empty string held for use by this runtime's contexts. */ | /* | |||
* Empty and unit-length strings held for use by this runtime's context | ||||
s. | ||||
* The unitStrings array and its elements are created on demand. | ||||
*/ | ||||
JSString *emptyString; | JSString *emptyString; | |||
JSString **unitStrings; | ||||
/* List of active contexts sharing this runtime; protected by gcLock. * / | /* List of active contexts sharing this runtime; protected by gcLock. * / | |||
JSCList contextList; | JSCList contextList; | |||
/* These are used for debugging -- see jsprvtd.h and jsdbgapi.h. */ | /* Per runtime debug hooks -- see jsprvtd.h and jsdbgapi.h. */ | |||
JSTrapHandler interruptHandler; | JSDebugHooks globalDebugHooks; | |||
void *interruptHandlerData; | ||||
JSNewScriptHook newScriptHook; | ||||
void *newScriptHookData; | ||||
JSDestroyScriptHook destroyScriptHook; | ||||
void *destroyScriptHookData; | ||||
JSTrapHandler debuggerHandler; | ||||
void *debuggerHandlerData; | ||||
JSSourceHandler sourceHandler; | ||||
void *sourceHandlerData; | ||||
JSInterpreterHook executeHook; | ||||
void *executeHookData; | ||||
JSInterpreterHook callHook; | ||||
void *callHookData; | ||||
JSObjectHook objectHook; | ||||
void *objectHookData; | ||||
JSTrapHandler throwHook; | ||||
void *throwHookData; | ||||
JSDebugErrorHook debugErrorHook; | ||||
void *debugErrorHookData; | ||||
/* More debugging state, see jsdbgapi.c. */ | /* More debugging state, see jsdbgapi.c. */ | |||
JSCList trapList; | JSCList trapList; | |||
JSCList watchPointList; | JSCList watchPointList; | |||
/* Weak links to properties, indexed by quickened get/set opcodes. */ | ||||
/* XXX must come after JSCLists or MSVC alignment bug bites empty lists | ||||
*/ | ||||
JSPropertyCache propertyCache; | ||||
/* Client opaque pointer */ | /* Client opaque pointer */ | |||
void *data; | void *data; | |||
#ifdef JS_THREADSAFE | #ifdef JS_THREADSAFE | |||
/* These combine to interlock the GC and new requests. */ | /* These combine to interlock the GC and new requests. */ | |||
PRLock *gcLock; | PRLock *gcLock; | |||
PRCondVar *gcDone; | PRCondVar *gcDone; | |||
PRCondVar *requestDone; | PRCondVar *requestDone; | |||
uint32 requestCount; | uint32 requestCount; | |||
JSThread *gcThread; | JSThread *gcThread; | |||
/* Lock and owning thread pointer for JS_LOCK_RUNTIME. */ | /* Lock and owning thread pointer for JS_LOCK_RUNTIME. */ | |||
PRLock *rtLock; | PRLock *rtLock; | |||
#ifdef DEBUG | #ifdef DEBUG | |||
jsword rtLockOwner; | jsword rtLockOwner; | |||
#endif | #endif | |||
/* Used to synchronize down/up state change; protected by gcLock. */ | /* Used to synchronize down/up state change; protected by gcLock. */ | |||
PRCondVar *stateChange; | PRCondVar *stateChange; | |||
/* Used to serialize cycle checks when setting __proto__ or __parent__. | ||||
*/ | ||||
PRLock *setSlotLock; | ||||
PRCondVar *setSlotDone; | ||||
JSBool setSlotBusy; | ||||
JSScope *setSlotScope; /* deadlock avoidance, see jslock.c | ||||
*/ | ||||
/* | /* | |||
* State for sharing single-threaded scopes, once a second thread tries | * State for sharing single-threaded titles, once a second thread tries | |||
to | to | |||
* lock a scope. The scopeSharingDone condvar is protected by rt->gcLo | * lock a title. The titleSharingDone condvar is protected by rt->gcLo | |||
ck, | ck | |||
* to minimize number of locks taken in JS_EndRequest. | * to minimize number of locks taken in JS_EndRequest. | |||
* | * | |||
* The scopeSharingTodo linked list is likewise "global" per runtime, n ot | * The titleSharingTodo linked list is likewise "global" per runtime, n ot | |||
* one-list-per-context, to conserve space over all contexts, optimizin g | * one-list-per-context, to conserve space over all contexts, optimizin g | |||
* for the likely case that scopes become shared rarely, and among a ve ry | * for the likely case that titles become shared rarely, and among a ve ry | |||
* small set of threads (contexts). | * small set of threads (contexts). | |||
*/ | */ | |||
PRCondVar *scopeSharingDone; | PRCondVar *titleSharingDone; | |||
JSScope *scopeSharingTodo; | JSTitle *titleSharingTodo; | |||
/* | /* | |||
* Magic terminator for the rt->scopeSharingTodo linked list, threaded thro | * Magic terminator for the rt->titleSharingTodo linked list, threaded thro | |||
ugh | ugh | |||
* scope->u.link. This hack allows us to test whether a scope is on the li | * title->u.link. This hack allows us to test whether a title is on the li | |||
st | st | |||
* by asking whether scope->u.link is non-null. We use a large, likely bog | * by asking whether title->u.link is non-null. We use a large, likely bog | |||
us | us | |||
* pointer here to distinguish this value from any valid u.count (small int ) | * pointer here to distinguish this value from any valid u.count (small int ) | |||
* value. | * value. | |||
*/ | */ | |||
#define NO_SCOPE_SHARING_TODO ((JSScope *) 0xfeedbeef) | #define NO_TITLE_SHARING_TODO ((JSTitle *) 0xfeedbeef) | |||
/* | /* | |||
* The index for JSThread info, returned by PR_NewThreadPrivateIndex. | * Lock serializing trapList and watchPointList accesses, and count of | |||
* The value is visible and shared by all threads, but the data is | all | |||
* private to each thread. | * mutations to trapList and watchPointList made by debugger threads. | |||
To | ||||
* keep the code simple, we define debuggerMutations for the thread-uns | ||||
afe | ||||
* case too. | ||||
*/ | */ | |||
PRUintn threadTPIndex; | PRLock *debuggerLock; | |||
#endif /* JS_THREADSAFE */ | #endif /* JS_THREADSAFE */ | |||
uint32 debuggerMutations; | ||||
/* | /* | |||
* Check property accessibility for objects of arbitrary class. Used a t | * Check property accessibility for objects of arbitrary class. Used a t | |||
* present to check f.caller accessibility for any function object f. | * present to check f.caller accessibility for any function object f. | |||
*/ | */ | |||
JSCheckAccessOp checkObjectAccess; | JSCheckAccessOp checkObjectAccess; | |||
/* Security principals serialization support. */ | /* Security principals serialization support. */ | |||
JSPrincipalsTranscoder principalsTranscoder; | JSPrincipalsTranscoder principalsTranscoder; | |||
skipping to change at line 398 | skipping to change at line 383 | |||
* | * | |||
* NB: Singleton objects must be carefully disconnected from the rest o f | * NB: Singleton objects must be carefully disconnected from the rest o f | |||
* the object graph usually associated with a JSContext's global object , | * the object graph usually associated with a JSContext's global object , | |||
* including the set of standard class objects. See jsxml.c for detail s. | * including the set of standard class objects. See jsxml.c for detail s. | |||
*/ | */ | |||
JSObject *anynameObject; | JSObject *anynameObject; | |||
JSObject *functionNamespaceObject; | JSObject *functionNamespaceObject; | |||
/* | /* | |||
* A helper list for the GC, so it can mark native iterator states. See | * A helper list for the GC, so it can mark native iterator states. See | |||
* js_MarkNativeIteratorStates for details. | * js_TraceNativeIteratorStates for details. | |||
*/ | */ | |||
JSNativeIteratorState *nativeIteratorStates; | JSNativeIteratorState *nativeIteratorStates; | |||
#ifndef JS_THREADSAFE | #ifndef JS_THREADSAFE | |||
/* | /* | |||
* For thread-unsafe embeddings, the GSN cache lives in the runtime and | * For thread-unsafe embeddings, the GSN cache lives in the runtime and | |||
* not each context, since we expect it to be filled once when decompil ing | * not each context, since we expect it to be filled once when decompil ing | |||
* a longer script, then hit repeatedly as js_GetSrcNote is called duri ng | * a longer script, then hit repeatedly as js_GetSrcNote is called duri ng | |||
* the decompiler activation that filled it. | * the decompiler activation that filled it. | |||
*/ | */ | |||
JSGSNCache gsnCache; | JSGSNCache gsnCache; | |||
#define JS_GSN_CACHE(cx) ((cx)->runtime->gsnCache) | /* Property cache for faster call/get/set invocation. */ | |||
JSPropertyCache propertyCache; | ||||
#define JS_GSN_CACHE(cx) ((cx)->runtime->gsnCache) | ||||
#define JS_PROPERTY_CACHE(cx) ((cx)->runtime->propertyCache) | ||||
#endif | #endif | |||
#ifdef DEBUG | /* | |||
* Object shape (property cache structural type) identifier generator. | ||||
* | ||||
* Type 0 stands for the empty scope, and must not be regenerated due t | ||||
o | ||||
* uint32 wrap-around. Since we use atomic pre-increment, the initial | ||||
* value for the first typed non-empty scope will be 1. | ||||
* | ||||
* The GC compresses live types, minimizing rt->shapeGen in the process | ||||
. | ||||
* If this counter overflows into SHAPE_OVERFLOW_BIT (in jsinterp.h), t | ||||
he | ||||
* GC will disable property caches for all threads, to avoid aliasing t | ||||
wo | ||||
* different types. Updated by js_GenerateShape (in jsinterp.c). | ||||
*/ | ||||
uint32 shapeGen; | ||||
/* Literal table maintained by jsatom.c functions. */ | ||||
JSAtomState atomState; | ||||
/* | ||||
* Various metering fields are defined at the end of JSRuntime. In this | ||||
* way there is no need to recompile all the code that refers to other | ||||
* fields of JSRuntime after enabling the corresponding metering macro. | ||||
*/ | ||||
#if defined DEBUG || defined JS_DUMP_PROPTREE_STATS | ||||
/* Function invocation metering. */ | /* Function invocation metering. */ | |||
jsrefcount inlineCalls; | jsrefcount inlineCalls; | |||
jsrefcount nativeCalls; | jsrefcount nativeCalls; | |||
jsrefcount nonInlineCalls; | jsrefcount nonInlineCalls; | |||
jsrefcount constructs; | jsrefcount constructs; | |||
/* Scope lock and property metering. */ | /* Title lock and scope property metering. */ | |||
jsrefcount claimAttempts; | jsrefcount claimAttempts; | |||
jsrefcount claimedScopes; | jsrefcount claimedTitles; | |||
jsrefcount deadContexts; | jsrefcount deadContexts; | |||
jsrefcount deadlocksAvoided; | jsrefcount deadlocksAvoided; | |||
jsrefcount liveScopes; | jsrefcount liveScopes; | |||
jsrefcount sharedScopes; | jsrefcount sharedTitles; | |||
jsrefcount totalScopes; | jsrefcount totalScopes; | |||
jsrefcount badUndependStrings; | ||||
jsrefcount liveScopeProps; | jsrefcount liveScopeProps; | |||
jsrefcount liveScopePropsPreSweep; | ||||
jsrefcount totalScopeProps; | jsrefcount totalScopeProps; | |||
jsrefcount livePropTreeNodes; | jsrefcount livePropTreeNodes; | |||
jsrefcount duplicatePropTreeNodes; | jsrefcount duplicatePropTreeNodes; | |||
jsrefcount totalPropTreeNodes; | jsrefcount totalPropTreeNodes; | |||
jsrefcount propTreeKidsChunks; | jsrefcount propTreeKidsChunks; | |||
jsrefcount middleDeleteFixups; | jsrefcount middleDeleteFixups; | |||
/* String instrumentation. */ | /* String instrumentation. */ | |||
jsrefcount liveStrings; | jsrefcount liveStrings; | |||
jsrefcount totalStrings; | jsrefcount totalStrings; | |||
jsrefcount liveDependentStrings; | jsrefcount liveDependentStrings; | |||
jsrefcount totalDependentStrings; | jsrefcount totalDependentStrings; | |||
jsrefcount badUndependStrings; | ||||
double lengthSum; | double lengthSum; | |||
double lengthSquaredSum; | double lengthSquaredSum; | |||
double strdepLengthSum; | double strdepLengthSum; | |||
double strdepLengthSquaredSum; | double strdepLengthSquaredSum; | |||
#endif /* DEBUG || JS_DUMP_PROPTREE_STATS */ | ||||
#ifdef JS_SCOPE_DEPTH_METER | ||||
/* | ||||
* Stats on runtime prototype chain lookups and scope chain depths, i.e | ||||
., | ||||
* counts of objects traversed on a chain until the wanted id is found. | ||||
*/ | ||||
JSBasicStats protoLookupDepthStats; | ||||
JSBasicStats scopeSearchDepthStats; | ||||
/* | ||||
* Stats on compile-time host environment and lexical scope chain lengt | ||||
hs | ||||
* (maximum depths). | ||||
*/ | ||||
JSBasicStats hostenvScopeDepthStats; | ||||
JSBasicStats lexicalScopeDepthStats; | ||||
#endif | ||||
#ifdef JS_GCMETER | ||||
JSGCStats gcStats; | ||||
#endif | #endif | |||
}; | }; | |||
#ifdef DEBUG | #ifdef DEBUG | |||
# define JS_RUNTIME_METER(rt, which) JS_ATOMIC_INCREMENT(&(rt)->which) | # define JS_RUNTIME_METER(rt, which) JS_ATOMIC_INCREMENT(&(rt)->which) | |||
# define JS_RUNTIME_UNMETER(rt, which) JS_ATOMIC_DECREMENT(&(rt)->which) | # define JS_RUNTIME_UNMETER(rt, which) JS_ATOMIC_DECREMENT(&(rt)->which) | |||
#else | #else | |||
# define JS_RUNTIME_METER(rt, which) /* nothing */ | # define JS_RUNTIME_METER(rt, which) /* nothing */ | |||
# define JS_RUNTIME_UNMETER(rt, which) /* nothing */ | # define JS_RUNTIME_UNMETER(rt, which) /* nothing */ | |||
#endif | #endif | |||
skipping to change at line 522 | skipping to change at line 555 | |||
typedef struct JSLocalRootStack { | typedef struct JSLocalRootStack { | |||
uint32 scopeMark; | uint32 scopeMark; | |||
uint32 rootCount; | uint32 rootCount; | |||
JSLocalRootChunk *topChunk; | JSLocalRootChunk *topChunk; | |||
JSLocalRootChunk firstChunk; | JSLocalRootChunk firstChunk; | |||
} JSLocalRootStack; | } JSLocalRootStack; | |||
#define JSLRS_NULL_MARK ((uint32) -1) | #define JSLRS_NULL_MARK ((uint32) -1) | |||
typedef struct JSTempValueRooter JSTempValueRooter; | ||||
typedef void | ||||
(* JS_DLL_CALLBACK JSTempValueMarker)(JSContext *cx, JSTempValueRooter *tvr | ||||
); | ||||
typedef union JSTempValueUnion { | ||||
jsval value; | ||||
JSObject *object; | ||||
JSString *string; | ||||
void *gcthing; | ||||
JSTempValueMarker marker; | ||||
JSScopeProperty *sprop; | ||||
JSWeakRoots *weakRoots; | ||||
jsval *array; | ||||
} JSTempValueUnion; | ||||
/* | /* | |||
* The following allows to reinterpret JSTempValueUnion.object as jsval usi | * Macros to push/pop JSTempValueRooter instances to context-linked stack o | |||
ng | f | |||
* the tagging property of a generic jsval described below. | * temporary GC roots. If you need to protect a result value that flows out | |||
of | ||||
* a C function across several layers of other functions, use the | ||||
* js_LeaveLocalRootScopeWithResult internal API (see further below) instea | ||||
d. | ||||
* | ||||
* The macros also provide a simple way to get a single rooted pointer via | ||||
* JS_PUSH_TEMP_ROOT_<KIND>(cx, NULL, &tvr). Then &tvr.u.<kind> gives the | ||||
* necessary pointer. | ||||
* | ||||
* JSTempValueRooter.count defines the type of the rooted value referenced | ||||
by | ||||
* JSTempValueRooter.u union of type JSTempValueUnion. When count is positi | ||||
ve | ||||
* or zero, u.array points to a vector of jsvals. Otherwise it must be one | ||||
of | ||||
* the following constants: | ||||
*/ | */ | |||
JS_STATIC_ASSERT(sizeof(JSTempValueUnion) == sizeof(jsval)); | #define JSTVU_SINGLE (-1) /* u.value or u.<gcthing> is single jsv | |||
JS_STATIC_ASSERT(sizeof(JSTempValueUnion) == sizeof(JSObject *)); | al | |||
or GC-thing */ | ||||
#define JSTVU_TRACE (-2) /* u.trace is a hook to trace a custom | ||||
* structure */ | ||||
#define JSTVU_SPROP (-3) /* u.sprop roots property tree node */ | ||||
#define JSTVU_WEAK_ROOTS (-4) /* u.weakRoots points to saved weak roo | ||||
ts */ | ||||
#define JSTVU_PARSE_CONTEXT (-5) /* u.parseContext roots JSParseContext* | ||||
*/ | ||||
#define JSTVU_SCRIPT (-6) /* u.script roots JSScript* */ | ||||
/* | /* | |||
* Context-linked stack of temporary GC roots. | * Here single JSTVU_SINGLE covers both jsval and pointers to any GC-thing | |||
* | via | |||
* If count is -1, then u.value contains the single value or GC-thing to ro | * reinterpreting the thing as JSVAL_OBJECT. It works because the GC-thing | |||
ot. | is | |||
* If count is -2, then u.marker holds a mark hook called to mark the value | * aligned on a 0 mod 8 boundary, and object has the 0 jsval tag. So any | |||
s. | * GC-thing may be tagged as if it were an object and untagged, if it's the | |||
* If count is -3, then u.sprop points to the property tree node to mark. | n | |||
* If count is -4, then u.weakRoots points to saved weak roots. | * used only as an opaque pointer until discriminated by other means than t | |||
* If count >= 0, then u.array points to a stack-allocated vector of jsvals | ag | |||
. | * bits. This is how, for example, js_GetGCThingTraceKind uses its |thing| | |||
* | * parameter -- it consults GC-thing flags stored separately from the thing | |||
* To root a single GC-thing pointer, which need not be tagged and stored a | to | |||
s a | * decide the kind of thing. | |||
* jsval, use JS_PUSH_TEMP_ROOT_GCTHING. The macro reinterprets an arbitrar | ||||
y | ||||
* GC-thing as jsval. It works because a GC-thing is aligned on a 0 mod 8 | ||||
* boundary, and object has the 0 jsval tag. So any GC-thing may be tagged | ||||
as | ||||
* if it were an object and untagged, if it's then used only as an opaque | ||||
* pointer until discriminated by other means than tag bits (this is how th | ||||
e | ||||
* GC mark function uses its |thing| parameter -- it consults GC-thing flag | ||||
s | ||||
* stored separately from the thing to decide the type of thing). | ||||
* | ||||
* JS_PUSH_TEMP_ROOT_OBJECT and JS_PUSH_TEMP_ROOT_STRING are type-safe | ||||
* alternatives to JS_PUSH_TEMP_ROOT_GCTHING for JSObject and JSString. The | ||||
y | ||||
* also provide a simple way to get a single pointer to rooted JSObject or | ||||
* JSString via JS_PUSH_TEMP_ROOT_(OBJECT|STRTING)(cx, NULL, &tvr). Then | ||||
* &tvr.u.object or tvr.u.string gives the necessary pointer, which puns | ||||
* tvr.u.value safely because JSObject * and JSString * are GC-things and, | ||||
as | ||||
* such, their tag bits are all zeroes. | ||||
* | * | |||
* If you need to protect a result value that flows out of a C function acr | * The following checks that this type-punning is possible. | |||
oss | ||||
* several layers of other functions, use the js_LeaveLocalRootScopeWithRes | ||||
ult | ||||
* internal API (see further below) instead. | ||||
*/ | */ | |||
struct JSTempValueRooter { | JS_STATIC_ASSERT(sizeof(JSTempValueUnion) == sizeof(jsval)); | |||
JSTempValueRooter *down; | JS_STATIC_ASSERT(sizeof(JSTempValueUnion) == sizeof(void *)); | |||
ptrdiff_t count; | ||||
JSTempValueUnion u; | ||||
}; | ||||
#define JSTVU_SINGLE (-1) | ||||
#define JSTVU_MARKER (-2) | ||||
#define JSTVU_SPROP (-3) | ||||
#define JSTVU_WEAK_ROOTS (-4) | ||||
#define JS_PUSH_TEMP_ROOT_COMMON(cx,tvr) \ | #define JS_PUSH_TEMP_ROOT_COMMON(cx,x,tvr,cnt,kind) \ | |||
JS_BEGIN_MACRO \ | JS_BEGIN_MACRO \ | |||
JS_ASSERT((cx)->tempValueRooters != (tvr)); \ | JS_ASSERT((cx)->tempValueRooters != (tvr)); \ | |||
(tvr)->count = (cnt); | ||||
\ | ||||
(tvr)->u.kind = (x); | ||||
\ | ||||
(tvr)->down = (cx)->tempValueRooters; \ | (tvr)->down = (cx)->tempValueRooters; \ | |||
(cx)->tempValueRooters = (tvr); \ | (cx)->tempValueRooters = (tvr); \ | |||
JS_END_MACRO | JS_END_MACRO | |||
#define JS_PUSH_SINGLE_TEMP_ROOT(cx,val,tvr) \ | #define JS_POP_TEMP_ROOT(cx,tvr) \ | |||
JS_BEGIN_MACRO \ | JS_BEGIN_MACRO \ | |||
(tvr)->count = JSTVU_SINGLE; | JS_ASSERT((cx)->tempValueRooters == (tvr)); | |||
\ | \ | |||
(tvr)->u.value = val; | (cx)->tempValueRooters = (tvr)->down; | |||
\ | \ | |||
JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); | ||||
\ | ||||
JS_END_MACRO | JS_END_MACRO | |||
#define JS_PUSH_TEMP_ROOT(cx,cnt,arr,tvr) \ | #define JS_PUSH_TEMP_ROOT(cx,cnt,arr,tvr) \ | |||
JS_BEGIN_MACRO \ | JS_BEGIN_MACRO \ | |||
JS_ASSERT((ptrdiff_t)(cnt) >= 0); | JS_ASSERT((int)(cnt) >= 0); | |||
\ | \ | |||
(tvr)->count = (ptrdiff_t)(cnt); | JS_PUSH_TEMP_ROOT_COMMON(cx, arr, tvr, (ptrdiff_t) (cnt), array); | |||
\ | \ | |||
(tvr)->u.array = (arr); | ||||
\ | ||||
JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); | ||||
\ | ||||
JS_END_MACRO | JS_END_MACRO | |||
#define JS_PUSH_TEMP_ROOT_MARKER(cx,marker_,tvr) | #define JS_PUSH_SINGLE_TEMP_ROOT(cx,val,tvr) | |||
\ | \ | |||
JS_BEGIN_MACRO | JS_PUSH_TEMP_ROOT_COMMON(cx, val, tvr, JSTVU_SINGLE, value) | |||
\ | ||||
(tvr)->count = JSTVU_MARKER; | ||||
\ | ||||
(tvr)->u.marker = (marker_); | ||||
\ | ||||
JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); | ||||
\ | ||||
JS_END_MACRO | ||||
#define JS_PUSH_TEMP_ROOT_OBJECT(cx,obj,tvr) \ | #define JS_PUSH_TEMP_ROOT_OBJECT(cx,obj,tvr) \ | |||
JS_BEGIN_MACRO | JS_PUSH_TEMP_ROOT_COMMON(cx, obj, tvr, JSTVU_SINGLE, object) | |||
\ | ||||
(tvr)->count = JSTVU_SINGLE; | ||||
\ | ||||
(tvr)->u.object = (obj); | ||||
\ | ||||
JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); | ||||
\ | ||||
JS_END_MACRO | ||||
#define JS_PUSH_TEMP_ROOT_STRING(cx,str,tvr) \ | #define JS_PUSH_TEMP_ROOT_STRING(cx,str,tvr) \ | |||
JS_BEGIN_MACRO | JS_PUSH_TEMP_ROOT_COMMON(cx, str, tvr, JSTVU_SINGLE, string) | |||
\ | ||||
(tvr)->count = JSTVU_SINGLE; | ||||
\ | ||||
(tvr)->u.string = (str); | ||||
\ | ||||
JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); | ||||
\ | ||||
JS_END_MACRO | ||||
#define JS_PUSH_TEMP_ROOT_GCTHING(cx,thing,tvr) | #define JS_PUSH_TEMP_ROOT_QNAME(cx,qn,tvr) | |||
\ | \ | |||
JS_BEGIN_MACRO | JS_PUSH_TEMP_ROOT_COMMON(cx, qn, tvr, JSTVU_SINGLE, qname) | |||
\ | ||||
JS_ASSERT(JSVAL_IS_OBJECT((jsval)thing)); | ||||
\ | ||||
(tvr)->count = JSTVU_SINGLE; | ||||
\ | ||||
(tvr)->u.gcthing = (thing); | ||||
\ | ||||
JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); | ||||
\ | ||||
JS_END_MACRO | ||||
#define JS_POP_TEMP_ROOT(cx,tvr) | #define JS_PUSH_TEMP_ROOT_NAMESPACE(cx,ns,tvr) | |||
\ | \ | |||
JS_BEGIN_MACRO | JS_PUSH_TEMP_ROOT_COMMON(cx, ns, tvr, JSTVU_SINGLE, nspace) | |||
\ | ||||
JS_ASSERT((cx)->tempValueRooters == (tvr)); | ||||
\ | ||||
(cx)->tempValueRooters = (tvr)->down; | ||||
\ | ||||
JS_END_MACRO | ||||
#define JS_TEMP_ROOT_EVAL(cx,cnt,val,expr) | #define JS_PUSH_TEMP_ROOT_XML(cx,xml_,tvr) | |||
\ | \ | |||
JS_BEGIN_MACRO | JS_PUSH_TEMP_ROOT_COMMON(cx, xml_, tvr, JSTVU_SINGLE, xml) | |||
\ | ||||
JSTempValueRooter tvr; | #define JS_PUSH_TEMP_ROOT_TRACE(cx,trace_,tvr) | |||
\ | \ | |||
JS_PUSH_TEMP_ROOT(cx, cnt, val, &tvr); | JS_PUSH_TEMP_ROOT_COMMON(cx, trace_, tvr, JSTVU_TRACE, trace) | |||
\ | ||||
(expr); | ||||
\ | ||||
JS_POP_TEMP_ROOT(cx, &tvr); | ||||
\ | ||||
JS_END_MACRO | ||||
#define JS_PUSH_TEMP_ROOT_SPROP(cx,sprop_,tvr) \ | #define JS_PUSH_TEMP_ROOT_SPROP(cx,sprop_,tvr) \ | |||
JS_BEGIN_MACRO | JS_PUSH_TEMP_ROOT_COMMON(cx, sprop_, tvr, JSTVU_SPROP, sprop) | |||
\ | ||||
(tvr)->count = JSTVU_SPROP; | ||||
\ | ||||
(tvr)->u.sprop = (sprop_); | ||||
\ | ||||
JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); | ||||
\ | ||||
JS_END_MACRO | ||||
#define JS_PUSH_TEMP_ROOT_WEAK_COPY(cx,weakRoots_,tvr) \ | #define JS_PUSH_TEMP_ROOT_WEAK_COPY(cx,weakRoots_,tvr) \ | |||
JS_BEGIN_MACRO | JS_PUSH_TEMP_ROOT_COMMON(cx, weakRoots_, tvr, JSTVU_WEAK_ROOTS, weakRoo | |||
\ | ts) | |||
(tvr)->count = JSTVU_WEAK_ROOTS; | ||||
\ | #define JS_PUSH_TEMP_ROOT_PARSE_CONTEXT(cx,pc,tvr) | |||
(tvr)->u.weakRoots = (weakRoots_); | \ | |||
\ | JS_PUSH_TEMP_ROOT_COMMON(cx, pc, tvr, JSTVU_PARSE_CONTEXT, parseContext | |||
JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); | ) | |||
\ | ||||
JS_END_MACRO | #define JS_PUSH_TEMP_ROOT_SCRIPT(cx,script_,tvr) | |||
\ | ||||
JS_PUSH_TEMP_ROOT_COMMON(cx, script_, tvr, JSTVU_SCRIPT, script) | ||||
struct JSContext { | struct JSContext { | |||
/* JSRuntime contextList linkage. */ | /* JSRuntime contextList linkage. */ | |||
JSCList links; | JSCList links; | |||
/* Interpreter activation count. */ | /* | |||
uintN interpLevel; | * Operation count. It is declared early in the structure as a frequent | |||
ly | ||||
* accessed field. | ||||
*/ | ||||
int32 operationCount; | ||||
/* Limit pointer for checking stack consumption during recursion. */ | #if JS_HAS_XML_SUPPORT | |||
jsuword stackLimit; | /* | |||
* Bit-set formed from binary exponentials of the XML_* tiny-ids define | ||||
d | ||||
* for boolean settings in jsxml.c, plus an XSF_CACHE_VALID bit. Toget | ||||
her | ||||
* these act as a cache of the boolean XML.ignore* and XML.prettyPrinti | ||||
ng | ||||
* property values associated with this context's global object. | ||||
*/ | ||||
uint8 xmlSettingFlags; | ||||
uint8 padding; | ||||
#else | ||||
uint16 padding; | ||||
#endif | ||||
/* Runtime version control identifier and equality operators. */ | /* Runtime version control identifier. */ | |||
uint16 version; | uint16 version; | |||
jsbytecode jsop_eq; | ||||
jsbytecode jsop_ne; | /* Per-context options. */ | |||
uint32 options; /* see jsapi.h for JSOPTION_* * | ||||
/ | ||||
/* Locale specific callbacks for string conversion. */ | ||||
JSLocaleCallbacks *localeCallbacks; | ||||
/* | ||||
* cx->resolvingTable is non-null and non-empty if we are initializing | ||||
* standard classes lazily, or if we are otherwise recursing indirectly | ||||
* from js_LookupProperty through a JSClass.resolve hook. It is used t | ||||
o | ||||
* limit runaway recursion (see jsapi.c and jsobj.c). | ||||
*/ | ||||
JSDHashTable *resolvingTable; | ||||
#if JS_HAS_LVALUE_RETURN | ||||
/* | ||||
* Secondary return value from native method called on the left-hand si | ||||
de | ||||
* of an assignment operator. The native should store the object in wh | ||||
ich | ||||
* to set a property in *rval, and return the property's id expressed a | ||||
s a | ||||
* jsval by calling JS_SetCallReturnValue2(cx, idval). | ||||
*/ | ||||
jsval rval2; | ||||
JSPackedBool rval2set; | ||||
#endif | ||||
/* | ||||
* True if generating an error, to prevent runaway recursion. | ||||
* NB: generatingError packs with rval2set, #if JS_HAS_LVALUE_RETURN; | ||||
* with insideGCMarkCallback and with throwing below. | ||||
*/ | ||||
JSPackedBool generatingError; | ||||
/* Flag to indicate that we run inside gcCallback(cx, JSGC_MARK_END). * | ||||
/ | ||||
JSPackedBool insideGCMarkCallback; | ||||
/* Exception state -- the exception member is a GC root by definition. | ||||
*/ | ||||
JSPackedBool throwing; /* is there a pending exception | ||||
? */ | ||||
jsval exception; /* most-recently-thrown excepti | ||||
on */ | ||||
/* Limit pointer for checking native stack consumption during recursion | ||||
. */ | ||||
jsuword stackLimit; | ||||
/* Quota on the size of arenas used to compile and execute scripts. */ | ||||
size_t scriptStackQuota; | ||||
/* Data shared by threads in an address space. */ | /* Data shared by threads in an address space. */ | |||
JSRuntime *runtime; | JSRuntime *runtime; | |||
/* Stack arena pool and frame pointer register. */ | /* Stack arena pool and frame pointer register. */ | |||
JSArenaPool stackPool; | JSArenaPool stackPool; | |||
JSStackFrame *fp; | JSStackFrame *fp; | |||
/* Temporary arena pool used while compiling and decompiling. */ | /* Temporary arena pool used while compiling and decompiling. */ | |||
JSArenaPool tempPool; | JSArenaPool tempPool; | |||
skipping to change at line 710 | skipping to change at line 750 | |||
/* Argument formatter support for JS_{Convert,Push}Arguments{,VA}. */ | /* Argument formatter support for JS_{Convert,Push}Arguments{,VA}. */ | |||
JSArgumentFormatMap *argumentFormatMap; | JSArgumentFormatMap *argumentFormatMap; | |||
/* Last message string and trace file for debugging. */ | /* Last message string and trace file for debugging. */ | |||
char *lastMessage; | char *lastMessage; | |||
#ifdef DEBUG | #ifdef DEBUG | |||
void *tracefp; | void *tracefp; | |||
#endif | #endif | |||
/* Per-context optional user callbacks. */ | /* Per-context optional error reporter. */ | |||
JSBranchCallback branchCallback; | ||||
JSErrorReporter errorReporter; | JSErrorReporter errorReporter; | |||
/* | ||||
* Flag indicating that the operation callback is set. When the flag is | ||||
0 | ||||
* but operationCallback is not null, operationCallback stores the bran | ||||
ch | ||||
* callback. | ||||
*/ | ||||
uint32 operationCallbackIsSet : 1; | ||||
uint32 operationLimit : 31; | ||||
JSOperationCallback operationCallback; | ||||
/* Interpreter activation count. */ | ||||
uintN interpLevel; | ||||
/* Client opaque pointer */ | /* Client opaque pointer */ | |||
void *data; | void *data; | |||
/* GC and thread-safe state. */ | /* GC and thread-safe state. */ | |||
JSStackFrame *dormantFrameChain; /* dormant stack frame to scan */ | JSStackFrame *dormantFrameChain; /* dormant stack frame to scan */ | |||
#ifdef JS_THREADSAFE | #ifdef JS_THREADSAFE | |||
JSThread *thread; | JSThread *thread; | |||
jsrefcount requestDepth; | jsrefcount requestDepth; | |||
JSScope *scopeToShare; /* weak reference, see jslock.c | /* Same as requestDepth but ignoring JS_SuspendRequest/JS_ResumeRequest | |||
*/ | */ | |||
JSScope *lockedSealedScope; /* weak ref, for low-cost seale | jsrefcount outstandingRequests; | |||
d | JSTitle *titleToShare; /* weak reference, see jslock.c | |||
scope locking */ | */ | |||
JSTitle *lockedSealedTitle; /* weak ref, for low-cost seale | ||||
d | ||||
title locking */ | ||||
JSCList threadLinks; /* JSThread contextList linkage */ | JSCList threadLinks; /* JSThread contextList linkage */ | |||
#define CX_FROM_THREAD_LINKS(tl) \ | #define CX_FROM_THREAD_LINKS(tl) \ | |||
((JSContext *)((char *)(tl) - offsetof(JSContext, threadLinks))) | ((JSContext *)((char *)(tl) - offsetof(JSContext, threadLinks))) | |||
#endif | #endif | |||
#if JS_HAS_LVALUE_RETURN | ||||
/* | ||||
* Secondary return value from native method called on the left-hand si | ||||
de | ||||
* of an assignment operator. The native should store the object in wh | ||||
ich | ||||
* to set a property in *rval, and return the property's id expressed a | ||||
s a | ||||
* jsval by calling JS_SetCallReturnValue2(cx, idval). | ||||
*/ | ||||
jsval rval2; | ||||
JSPackedBool rval2set; | ||||
#endif | ||||
#if JS_HAS_XML_SUPPORT | ||||
/* | ||||
* Bit-set formed from binary exponentials of the XML_* tiny-ids define | ||||
d | ||||
* for boolean settings in jsxml.c, plus an XSF_CACHE_VALID bit. Toget | ||||
her | ||||
* these act as a cache of the boolean XML.ignore* and XML.prettyPrinti | ||||
ng | ||||
* property values associated with this context's global object. | ||||
*/ | ||||
uint8 xmlSettingFlags; | ||||
#endif | ||||
/* | ||||
* True if creating an exception object, to prevent runaway recursion. | ||||
* NB: creatingException packs with rval2set, #if JS_HAS_LVALUE_RETURN; | ||||
* with xmlSettingFlags, #if JS_HAS_XML_SUPPORT; and with throwing belo | ||||
w. | ||||
*/ | ||||
JSPackedBool creatingException; | ||||
/* | ||||
* Exception state -- the exception member is a GC root by definition. | ||||
* NB: throwing packs with creatingException and rval2set, above. | ||||
*/ | ||||
JSPackedBool throwing; /* is there a pending exception | ||||
? */ | ||||
jsval exception; /* most-recently-thrown excepti | ||||
on */ | ||||
/* Flag to indicate that we run inside gcCallback(cx, JSGC_MARK_END). * | ||||
/ | ||||
JSPackedBool insideGCMarkCallback; | ||||
/* Per-context options. */ | ||||
uint32 options; /* see jsapi.h for JSOPTION_* * | ||||
/ | ||||
/* Locale specific callbacks for string conversion. */ | ||||
JSLocaleCallbacks *localeCallbacks; | ||||
/* | ||||
* cx->resolvingTable is non-null and non-empty if we are initializing | ||||
* standard classes lazily, or if we are otherwise recursing indirectly | ||||
* from js_LookupProperty through a JSClass.resolve hook. It is used t | ||||
o | ||||
* limit runaway recursion (see jsapi.c and jsobj.c). | ||||
*/ | ||||
JSDHashTable *resolvingTable; | ||||
/* PDL of stack headers describing stack slots not rooted by argv, etc. */ | /* PDL of stack headers describing stack slots not rooted by argv, etc. */ | |||
JSStackHeader *stackHeaders; | JSStackHeader *stackHeaders; | |||
/* Optional stack of heap-allocated scoped local GC roots. */ | /* Optional stack of heap-allocated scoped local GC roots. */ | |||
JSLocalRootStack *localRootStack; | JSLocalRootStack *localRootStack; | |||
/* Stack of thread-stack-allocated temporary GC roots. */ | /* Stack of thread-stack-allocated temporary GC roots. */ | |||
JSTempValueRooter *tempValueRooters; | JSTempValueRooter *tempValueRooters; | |||
#ifdef GC_MARK_DEBUG | /* List of pre-allocated doubles. */ | |||
/* Top of the GC mark stack. */ | JSGCDoubleCell *doubleFreeList; | |||
void *gcCurrentMarkNode; | ||||
#endif | /* Debug hooks associated with the current context. */ | |||
JSDebugHooks *debugHooks; | ||||
}; | }; | |||
#ifdef JS_THREADSAFE | #ifdef JS_THREADSAFE | |||
# define JS_THREAD_ID(cx) ((cx)->thread ? (cx)->thread->id : 0) | # define JS_THREAD_ID(cx) ((cx)->thread ? (cx)->thread->id : 0) | |||
#endif | #endif | |||
#ifdef __cplusplus | #ifdef __cplusplus | |||
/* FIXME(bug 332648): Move this into a public header. */ | /* FIXME(bug 332648): Move this into a public header. */ | |||
class JSAutoTempValueRooter | class JSAutoTempValueRooter | |||
{ | { | |||
skipping to change at line 820 | skipping to change at line 823 | |||
JSAutoTempValueRooter(JSContext *cx, jsval v) | JSAutoTempValueRooter(JSContext *cx, jsval v) | |||
: mContext(cx) { | : mContext(cx) { | |||
JS_PUSH_SINGLE_TEMP_ROOT(mContext, v, &mTvr); | JS_PUSH_SINGLE_TEMP_ROOT(mContext, v, &mTvr); | |||
} | } | |||
~JSAutoTempValueRooter() { | ~JSAutoTempValueRooter() { | |||
JS_POP_TEMP_ROOT(mContext, &mTvr); | JS_POP_TEMP_ROOT(mContext, &mTvr); | |||
} | } | |||
private: | private: | |||
#ifndef AIX | ||||
static void *operator new(size_t); | static void *operator new(size_t); | |||
static void operator delete(void *, size_t); | static void operator delete(void *, size_t); | |||
#endif | ||||
JSContext *mContext; | JSContext *mContext; | |||
JSTempValueRooter mTvr; | JSTempValueRooter mTvr; | |||
}; | }; | |||
#endif | #endif | |||
/* | /* | |||
* Slightly more readable macros for testing per-context option settings (a lso | * Slightly more readable macros for testing per-context option settings (a lso | |||
* to hide bitset implementation detail). | * to hide bitset implementation detail). | |||
* | * | |||
skipping to change at line 864 | skipping to change at line 869 | |||
*/ | */ | |||
#define JS_HAS_OPTION(cx,option) (((cx)->options & (option)) != 0) | #define JS_HAS_OPTION(cx,option) (((cx)->options & (option)) != 0) | |||
#define JS_HAS_STRICT_OPTION(cx) JS_HAS_OPTION(cx, JSOPTION_STRICT) | #define JS_HAS_STRICT_OPTION(cx) JS_HAS_OPTION(cx, JSOPTION_STRICT) | |||
#define JS_HAS_WERROR_OPTION(cx) JS_HAS_OPTION(cx, JSOPTION_WERROR) | #define JS_HAS_WERROR_OPTION(cx) JS_HAS_OPTION(cx, JSOPTION_WERROR) | |||
#define JS_HAS_COMPILE_N_GO_OPTION(cx) JS_HAS_OPTION(cx, JSOPTION_COMPILE_ N_GO) | #define JS_HAS_COMPILE_N_GO_OPTION(cx) JS_HAS_OPTION(cx, JSOPTION_COMPILE_ N_GO) | |||
#define JS_HAS_ATLINE_OPTION(cx) JS_HAS_OPTION(cx, JSOPTION_ATLINE) | #define JS_HAS_ATLINE_OPTION(cx) JS_HAS_OPTION(cx, JSOPTION_ATLINE) | |||
#define JSVERSION_MASK 0x0FFF /* see JSVersion in jspubtd .h */ | #define JSVERSION_MASK 0x0FFF /* see JSVersion in jspubtd .h */ | |||
#define JSVERSION_HAS_XML 0x1000 /* flag induced by XML opti on */ | #define JSVERSION_HAS_XML 0x1000 /* flag induced by XML opti on */ | |||
#define JSVERSION_NUMBER(cx) ((cx)->version & JSVERSION_MASK) | #define JSVERSION_NUMBER(cx) ((JSVersion)((cx)->version & | |||
\ | ||||
JSVERSION_MASK)) | ||||
#define JS_HAS_XML_OPTION(cx) ((cx)->version & JSVERSION_HAS_XML || \ | #define JS_HAS_XML_OPTION(cx) ((cx)->version & JSVERSION_HAS_XML || \ | |||
JSVERSION_NUMBER(cx) >= JSVERSION_ 1_6) | JSVERSION_NUMBER(cx) >= JSVERSION_ 1_6) | |||
#define JS_HAS_NATIVE_BRANCH_CALLBACK_OPTION(cx) | ||||
\ | ||||
JS_HAS_OPTION(cx, JSOPTION_NATIVE_BRANCH_CALLBACK) | ||||
/* | /* | |||
* Wrappers for the JSVERSION_IS_* macros from jspubtd.h taking JSContext * | * Initialize a library-wide thread private data index, and remember that i | |||
cx | t | |||
* and masking off the XML flag and any other high order bits. | * has already been done, so that it happens only once ever. Returns true | |||
on | ||||
* success. | ||||
*/ | */ | |||
#define JS_VERSION_IS_ECMA(cx) JSVERSION_IS_ECMA(JSVERSION_NUMBER( | extern JSBool | |||
cx)) | js_InitThreadPrivateIndex(void (JS_DLL_CALLBACK *ptr)(void *)); | |||
/* | /* | |||
* Common subroutine of JS_SetVersion and js_SetVersion, to update per-cont ext | * Common subroutine of JS_SetVersion and js_SetVersion, to update per-cont ext | |||
* data that depends on version. | * data that depends on version. | |||
*/ | */ | |||
extern void | extern void | |||
js_OnVersionChange(JSContext *cx); | js_OnVersionChange(JSContext *cx); | |||
/* | /* | |||
* Unlike the JS_SetVersion API, this function stores JSVERSION_HAS_XML and | * Unlike the JS_SetVersion API, this function stores JSVERSION_HAS_XML and | |||
skipping to change at line 903 | skipping to change at line 908 | |||
* and exclusively owned. | * and exclusively owned. | |||
*/ | */ | |||
extern JSContext * | extern JSContext * | |||
js_NewContext(JSRuntime *rt, size_t stackChunkSize); | js_NewContext(JSRuntime *rt, size_t stackChunkSize); | |||
extern void | extern void | |||
js_DestroyContext(JSContext *cx, JSDestroyContextMode mode); | js_DestroyContext(JSContext *cx, JSDestroyContextMode mode); | |||
/* | /* | |||
* Return true if cx points to a context in rt->contextList, else return fa lse. | * Return true if cx points to a context in rt->contextList, else return fa lse. | |||
* NB: the caller (see jslock.c:ClaimScope) must hold rt->gcLock. | * NB: the caller (see jslock.c:ClaimTitle) must hold rt->gcLock. | |||
*/ | */ | |||
extern JSBool | extern JSBool | |||
js_ValidContextPointer(JSRuntime *rt, JSContext *cx); | js_ValidContextPointer(JSRuntime *rt, JSContext *cx); | |||
/* | /* | |||
* If unlocked, acquire and release rt->gcLock around *iterp update; otherw ise | * If unlocked, acquire and release rt->gcLock around *iterp update; otherw ise | |||
* the caller must be holding rt->gcLock. | * the caller must be holding rt->gcLock. | |||
*/ | */ | |||
extern JSContext * | extern JSContext * | |||
js_ContextIterator(JSRuntime *rt, JSBool unlocked, JSContext **iterp); | js_ContextIterator(JSRuntime *rt, JSBool unlocked, JSContext **iterp); | |||
skipping to change at line 950 | skipping to change at line 955 | |||
extern void | extern void | |||
js_LeaveLocalRootScopeWithResult(JSContext *cx, jsval rval); | js_LeaveLocalRootScopeWithResult(JSContext *cx, jsval rval); | |||
extern void | extern void | |||
js_ForgetLocalRoot(JSContext *cx, jsval v); | js_ForgetLocalRoot(JSContext *cx, jsval v); | |||
extern int | extern int | |||
js_PushLocalRoot(JSContext *cx, JSLocalRootStack *lrs, jsval v); | js_PushLocalRoot(JSContext *cx, JSLocalRootStack *lrs, jsval v); | |||
extern void | extern void | |||
js_MarkLocalRoots(JSContext *cx, JSLocalRootStack *lrs); | js_TraceLocalRoots(JSTracer *trc, JSLocalRootStack *lrs); | |||
/* | /* | |||
* Report an exception, which is currently realized as a printf-style forma t | * Report an exception, which is currently realized as a printf-style forma t | |||
* string and its arguments. | * string and its arguments. | |||
*/ | */ | |||
typedef enum JSErrNum { | typedef enum JSErrNum { | |||
#define MSG_DEF(name, number, count, exception, format) \ | #define MSG_DEF(name, number, count, exception, format) \ | |||
name = number, | name = number, | |||
#include "js.msg" | #include "js.msg" | |||
#undef MSG_DEF | #undef MSG_DEF | |||
skipping to change at line 987 | skipping to change at line 992 | |||
js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback, | js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback, | |||
void *userRef, const uintN errorNumber, | void *userRef, const uintN errorNumber, | |||
char **message, JSErrorReport *reportp, | char **message, JSErrorReport *reportp, | |||
JSBool *warningp, JSBool charArgs, va_list ap); | JSBool *warningp, JSBool charArgs, va_list ap); | |||
#endif | #endif | |||
extern void | extern void | |||
js_ReportOutOfMemory(JSContext *cx); | js_ReportOutOfMemory(JSContext *cx); | |||
/* | /* | |||
* Report that cx->scriptStackQuota is exhausted. | ||||
*/ | ||||
extern void | ||||
js_ReportOutOfScriptQuota(JSContext *cx); | ||||
extern void | ||||
js_ReportOverRecursed(JSContext *cx); | ||||
extern void | ||||
js_ReportAllocationOverflow(JSContext *cx); | ||||
#define JS_CHECK_RECURSION(cx, onerror) | ||||
\ | ||||
JS_BEGIN_MACRO | ||||
\ | ||||
int stackDummy_; | ||||
\ | ||||
\ | ||||
if (!JS_CHECK_STACK_SIZE(cx, stackDummy_)) { | ||||
\ | ||||
js_ReportOverRecursed(cx); | ||||
\ | ||||
onerror; | ||||
\ | ||||
} | ||||
\ | ||||
JS_END_MACRO | ||||
/* | ||||
* Report an exception using a previously composed JSErrorReport. | * Report an exception using a previously composed JSErrorReport. | |||
* XXXbe remove from "friend" API | * XXXbe remove from "friend" API | |||
*/ | */ | |||
extern JS_FRIEND_API(void) | extern JS_FRIEND_API(void) | |||
js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *repo rt); | js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *repo rt); | |||
extern void | extern void | |||
js_ReportIsNotDefined(JSContext *cx, const char *name); | js_ReportIsNotDefined(JSContext *cx, const char *name); | |||
/* | ||||
* Report an attempt to access the property of a null or undefined value (v | ||||
). | ||||
*/ | ||||
extern JSBool | ||||
js_ReportIsNullOrUndefined(JSContext *cx, intN spindex, jsval v, | ||||
JSString *fallback); | ||||
/* | ||||
* Report error using js_DecompileValueGenerator(cx, spindex, v, fallback) | ||||
as | ||||
* the first argument for the error message. If the error message has less | ||||
* then 3 arguments, use null for arg1 or arg2. | ||||
*/ | ||||
extern JSBool | ||||
js_ReportValueErrorFlags(JSContext *cx, uintN flags, const uintN errorNumbe | ||||
r, | ||||
intN spindex, jsval v, JSString *fallback, | ||||
const char *arg1, const char *arg2); | ||||
#define js_ReportValueError(cx,errorNumber,spindex,v,fallback) | ||||
\ | ||||
((void)js_ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber, | ||||
\ | ||||
spindex, v, fallback, NULL, NULL)) | ||||
#define js_ReportValueError2(cx,errorNumber,spindex,v,fallback,arg1) | ||||
\ | ||||
((void)js_ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber, | ||||
\ | ||||
spindex, v, fallback, arg1, NULL)) | ||||
#define js_ReportValueError3(cx,errorNumber,spindex,v,fallback,arg1,arg2) | ||||
\ | ||||
((void)js_ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber, | ||||
\ | ||||
spindex, v, fallback, arg1, arg2)) | ||||
extern JSErrorFormatString js_ErrorFormatString[JSErr_Limit]; | extern JSErrorFormatString js_ErrorFormatString[JSErr_Limit]; | |||
/* | /* | |||
* See JS_SetThreadStackLimit in jsapi.c, where we check that the stack gro ws | * See JS_SetThreadStackLimit in jsapi.c, where we check that the stack gro ws | |||
* in the expected direction. On Unix-y systems, JS_STACK_GROWTH_DIRECTION is | * in the expected direction. On Unix-y systems, JS_STACK_GROWTH_DIRECTION is | |||
* computed on the build host by jscpucfg.c and written into jsautocfg.h. The | * computed on the build host by jscpucfg.c and written into jsautocfg.h. The | |||
* macro is hardcoded in jscpucfg.h on Windows and Mac systems (for histori cal | * macro is hardcoded in jscpucfg.h on Windows and Mac systems (for histori cal | |||
* reasons pre-dating autoconf usage). | * reasons pre-dating autoconf usage). | |||
*/ | */ | |||
#if JS_STACK_GROWTH_DIRECTION > 0 | #if JS_STACK_GROWTH_DIRECTION > 0 | |||
# define JS_CHECK_STACK_SIZE(cx, lval) ((jsuword)&(lval) < (cx)->stackLimi t) | # define JS_CHECK_STACK_SIZE(cx, lval) ((jsuword)&(lval) < (cx)->stackLimi t) | |||
#else | #else | |||
# define JS_CHECK_STACK_SIZE(cx, lval) ((jsuword)&(lval) > (cx)->stackLimi t) | # define JS_CHECK_STACK_SIZE(cx, lval) ((jsuword)&(lval) > (cx)->stackLimi t) | |||
#endif | #endif | |||
/* | ||||
* Update the operation counter according to the given weight and call the | ||||
* operation callback when we reach the operation limit. To make this | ||||
* frequently executed macro faster we decrease the counter from | ||||
* JSContext.operationLimit and compare against zero to check the limit. | ||||
* | ||||
* This macro can run the full GC. Return true if it is OK to continue and | ||||
* false otherwise. | ||||
*/ | ||||
#define JS_CHECK_OPERATION_LIMIT(cx, weight) | ||||
\ | ||||
(JS_CHECK_OPERATION_WEIGHT(weight), | ||||
\ | ||||
(((cx)->operationCount -= (weight)) > 0 || js_ResetOperationCount(cx)) | ||||
) | ||||
/* | ||||
* A version of JS_CHECK_OPERATION_LIMIT that just updates the operation co | ||||
unt | ||||
* without calling the operation callback or any other API. This macro rese | ||||
ts | ||||
* the count to 0 when it becomes negative to prevent a wrap-around when th | ||||
e | ||||
* macro is called repeatably. | ||||
*/ | ||||
#define JS_COUNT_OPERATION(cx, weight) | ||||
\ | ||||
((void)(JS_CHECK_OPERATION_WEIGHT(weight), | ||||
\ | ||||
(cx)->operationCount = ((cx)->operationCount > 0) | ||||
\ | ||||
? (cx)->operationCount - (weight) | ||||
\ | ||||
: 0)) | ||||
/* | ||||
* The implementation of the above macros assumes that subtracting weights | ||||
* twice from a positive number does not wrap-around INT32_MIN. | ||||
*/ | ||||
#define JS_CHECK_OPERATION_WEIGHT(weight) | ||||
\ | ||||
(JS_ASSERT((uint32) (weight) > 0), | ||||
\ | ||||
JS_ASSERT((uint32) (weight) < JS_BIT(30))) | ||||
/* Relative operations weights. */ | ||||
#define JSOW_JUMP 1 | ||||
#define JSOW_ALLOCATION 100 | ||||
#define JSOW_LOOKUP_PROPERTY 5 | ||||
#define JSOW_GET_PROPERTY 10 | ||||
#define JSOW_SET_PROPERTY 20 | ||||
#define JSOW_NEW_PROPERTY 200 | ||||
#define JSOW_DELETE_PROPERTY 30 | ||||
#define JSOW_ENTER_SHARP JS_OPERATION_WEIGHT_BASE | ||||
#define JSOW_SCRIPT_JUMP JS_OPERATION_WEIGHT_BASE | ||||
/* | ||||
* Reset the operation count and call the operation callback assuming that | ||||
the | ||||
* operation limit is reached. | ||||
*/ | ||||
extern JSBool | ||||
js_ResetOperationCount(JSContext *cx); | ||||
JS_END_EXTERN_C | JS_END_EXTERN_C | |||
#endif /* jscntxt_h___ */ | #endif /* jscntxt_h___ */ | |||
End of changes. 81 change blocks. | ||||
364 lines changed or deleted | 483 lines changed or added | |||
jsconfig.h | jsconfig.h | |||
---|---|---|---|---|
skipping to change at line 44 | skipping to change at line 44 | |||
* and other provisions required by the GPL or the LGPL. If you do not dele te | * and other provisions required by the GPL or the LGPL. If you do not dele te | |||
* the provisions above, a recipient may use your version of this file unde r | * the provisions above, a recipient may use your version of this file unde r | |||
* the terms of any one of the MPL, the GPL or the LGPL. | * the terms of any one of the MPL, the GPL or the LGPL. | |||
* | * | |||
* ***** END LICENSE BLOCK ***** */ | * ***** END LICENSE BLOCK ***** */ | |||
/* | /* | |||
* JS configuration macros. | * JS configuration macros. | |||
*/ | */ | |||
#ifndef JS_VERSION | #ifndef JS_VERSION | |||
#define JS_VERSION 170 | #define JS_VERSION 180 | |||
#endif | #endif | |||
/* | /* | |||
* Compile-time JS version configuration. The JS version numbers lie on th e | * Compile-time JS version configuration. The JS version numbers lie on th e | |||
* number line like so: | * number line like so: | |||
* | * | |||
* 1.0 1.1 1.2 1.3 1.4 ECMAv3 1.5 1.6 | * 1.0 1.1 1.2 1.3 1.4 ECMAv3 1.5 1.6 1.7 | |||
* ^ ^ | 1.8 | |||
* | | | * ^ ^ | |||
* basis for ECMAv1 close to ECMAv2 | * | | | |||
* basis for ECMAv1 close to ECMAv2 | ||||
* | * | |||
* where ECMAv3 stands for ECMA-262 Edition 3. See the runtime version enu m | * where ECMAv3 stands for ECMA-262 Edition 3. See the runtime version enu m | |||
* JSVersion in jspubtd.h. Code in the engine can therefore count on versi on | * JSVersion in jspubtd.h. Code in the engine can therefore count on versi on | |||
* <= JSVERSION_1_4 to mean "before the Third Edition of ECMA-262" and vers ion | * <= JSVERSION_1_4 to mean "before the Third Edition of ECMA-262" and vers ion | |||
* > JSVERSION_1_4 to mean "at or after the Third Edition". | * > JSVERSION_1_4 to mean "at or after the Third Edition". | |||
* | * | |||
* In the (likely?) event that SpiderMonkey grows to implement JavaScript 2 .0, | * In the (likely?) event that SpiderMonkey grows to implement JavaScript 2 .0, | |||
* or ECMA-262 Edition 4 (JS2 without certain extensions), the version numb er | * or ECMA-262 Edition 4 (JS2 without certain extensions), the version numb er | |||
* to use would be near 200, or greater. | * to use would be near 200, or greater. | |||
* | * | |||
skipping to change at line 110 | skipping to change at line 110 | |||
#define JS_HAS_UNEVAL 0 /* has uneval() top-level function */ | #define JS_HAS_UNEVAL 0 /* has uneval() top-level function */ | |||
#define JS_HAS_CONST 0 /* has JS2 const as alternative var */ | #define JS_HAS_CONST 0 /* has JS2 const as alternative var */ | |||
#define JS_HAS_FUN_EXPR_STMT 0 /* has function expression statemen t */ | #define JS_HAS_FUN_EXPR_STMT 0 /* has function expression statemen t */ | |||
#define JS_HAS_LVALUE_RETURN 1 /* has o.item(i) = j; for native it em */ | #define JS_HAS_LVALUE_RETURN 1 /* has o.item(i) = j; for native it em */ | |||
#define JS_HAS_NO_SUCH_METHOD 0 /* has o.__noSuchMethod__ handler * / | #define JS_HAS_NO_SUCH_METHOD 0 /* has o.__noSuchMethod__ handler * / | |||
#define JS_HAS_XML_SUPPORT 0 /* has ECMAScript for XML support * / | #define JS_HAS_XML_SUPPORT 0 /* has ECMAScript for XML support * / | |||
#define JS_HAS_ARRAY_EXTRAS 0 /* has indexOf and Lispy extras */ | #define JS_HAS_ARRAY_EXTRAS 0 /* has indexOf and Lispy extras */ | |||
#define JS_HAS_GENERATORS 0 /* has yield in generator function */ | #define JS_HAS_GENERATORS 0 /* has yield in generator function */ | |||
#define JS_HAS_BLOCK_SCOPE 0 /* has block scope via let/arraycom p */ | #define JS_HAS_BLOCK_SCOPE 0 /* has block scope via let/arraycom p */ | |||
#define JS_HAS_DESTRUCTURING 0 /* has [a,b] = ... or {p:a,q:b} = . .. */ | #define JS_HAS_DESTRUCTURING 0 /* has [a,b] = ... or {p:a,q:b} = . .. */ | |||
#define JS_HAS_GENERATOR_EXPRS 0 /* has (expr for (lhs in iterable)) | ||||
*/ | ||||
#define JS_HAS_EXPR_CLOSURES 0 /* has function (formals) listexpr | ||||
*/ | ||||
#elif JS_VERSION < 150 | #elif JS_VERSION < 150 | |||
#error "unsupported JS_VERSION" | #error "unsupported JS_VERSION" | |||
#elif JS_VERSION == 150 | #elif JS_VERSION == 150 | |||
#define JS_HAS_STR_HTML_HELPERS 1 /* has str.anchor, str.bold, etc. * / | #define JS_HAS_STR_HTML_HELPERS 1 /* has str.anchor, str.bold, etc. * / | |||
#define JS_HAS_PERL_SUBSTR 1 /* has str.substr */ | #define JS_HAS_PERL_SUBSTR 1 /* has str.substr */ | |||
#define JS_HAS_OBJ_PROTO_PROP 1 /* has o.__proto__ etc. */ | #define JS_HAS_OBJ_PROTO_PROP 1 /* has o.__proto__ etc. */ | |||
skipping to change at line 142 | skipping to change at line 144 | |||
#define JS_HAS_UNEVAL 1 /* has uneval() top-level function */ | #define JS_HAS_UNEVAL 1 /* has uneval() top-level function */ | |||
#define JS_HAS_CONST 1 /* has JS2 const as alternative var */ | #define JS_HAS_CONST 1 /* has JS2 const as alternative var */ | |||
#define JS_HAS_FUN_EXPR_STMT 1 /* has function expression statemen t */ | #define JS_HAS_FUN_EXPR_STMT 1 /* has function expression statemen t */ | |||
#define JS_HAS_LVALUE_RETURN 1 /* has o.item(i) = j; for native it em */ | #define JS_HAS_LVALUE_RETURN 1 /* has o.item(i) = j; for native it em */ | |||
#define JS_HAS_NO_SUCH_METHOD 1 /* has o.__noSuchMethod__ handler * / | #define JS_HAS_NO_SUCH_METHOD 1 /* has o.__noSuchMethod__ handler * / | |||
#define JS_HAS_XML_SUPPORT 0 /* has ECMAScript for XML support * / | #define JS_HAS_XML_SUPPORT 0 /* has ECMAScript for XML support * / | |||
#define JS_HAS_ARRAY_EXTRAS 0 /* has indexOf and Lispy extras */ | #define JS_HAS_ARRAY_EXTRAS 0 /* has indexOf and Lispy extras */ | |||
#define JS_HAS_GENERATORS 0 /* has yield in generator function */ | #define JS_HAS_GENERATORS 0 /* has yield in generator function */ | |||
#define JS_HAS_BLOCK_SCOPE 0 /* has block scope via let/arraycom p */ | #define JS_HAS_BLOCK_SCOPE 0 /* has block scope via let/arraycom p */ | |||
#define JS_HAS_DESTRUCTURING 0 /* has [a,b] = ... or {p:a,q:b} = . .. */ | #define JS_HAS_DESTRUCTURING 0 /* has [a,b] = ... or {p:a,q:b} = . .. */ | |||
#define JS_HAS_GENERATOR_EXPRS 0 /* has (expr for (lhs in iterable)) | ||||
*/ | ||||
#define JS_HAS_EXPR_CLOSURES 0 /* has function (formals) listexpr | ||||
*/ | ||||
#elif JS_VERSION == 160 | #elif JS_VERSION == 160 | |||
#define JS_HAS_STR_HTML_HELPERS 1 /* has str.anchor, str.bold, etc. * / | #define JS_HAS_STR_HTML_HELPERS 1 /* has str.anchor, str.bold, etc. * / | |||
#define JS_HAS_PERL_SUBSTR 1 /* has str.substr */ | #define JS_HAS_PERL_SUBSTR 1 /* has str.substr */ | |||
#define JS_HAS_OBJ_PROTO_PROP 1 /* has o.__proto__ etc. */ | #define JS_HAS_OBJ_PROTO_PROP 1 /* has o.__proto__ etc. */ | |||
#define JS_HAS_OBJ_WATCHPOINT 1 /* has o.watch and o.unwatch */ | #define JS_HAS_OBJ_WATCHPOINT 1 /* has o.watch and o.unwatch */ | |||
#define JS_HAS_EXPORT_IMPORT 1 /* has export fun; import obj.fun * / | #define JS_HAS_EXPORT_IMPORT 1 /* has export fun; import obj.fun * / | |||
#define JS_HAS_EVAL_THIS_SCOPE 1 /* Math.eval is same as with (Math) */ | #define JS_HAS_EVAL_THIS_SCOPE 1 /* Math.eval is same as with (Math) */ | |||
#define JS_HAS_SHARP_VARS 1 /* has #n=, #n# for object literals */ | #define JS_HAS_SHARP_VARS 1 /* has #n=, #n# for object literals */ | |||
skipping to change at line 170 | skipping to change at line 174 | |||
#define JS_HAS_UNEVAL 1 /* has uneval() top-level function */ | #define JS_HAS_UNEVAL 1 /* has uneval() top-level function */ | |||
#define JS_HAS_CONST 1 /* has JS2 const as alternative var */ | #define JS_HAS_CONST 1 /* has JS2 const as alternative var */ | |||
#define JS_HAS_FUN_EXPR_STMT 1 /* has function expression statemen t */ | #define JS_HAS_FUN_EXPR_STMT 1 /* has function expression statemen t */ | |||
#define JS_HAS_LVALUE_RETURN 1 /* has o.item(i) = j; for native it em */ | #define JS_HAS_LVALUE_RETURN 1 /* has o.item(i) = j; for native it em */ | |||
#define JS_HAS_NO_SUCH_METHOD 1 /* has o.__noSuchMethod__ handler * / | #define JS_HAS_NO_SUCH_METHOD 1 /* has o.__noSuchMethod__ handler * / | |||
#define JS_HAS_XML_SUPPORT 1 /* has ECMAScript for XML support * / | #define JS_HAS_XML_SUPPORT 1 /* has ECMAScript for XML support * / | |||
#define JS_HAS_ARRAY_EXTRAS 1 /* has indexOf and Lispy extras */ | #define JS_HAS_ARRAY_EXTRAS 1 /* has indexOf and Lispy extras */ | |||
#define JS_HAS_GENERATORS 0 /* has yield in generator function */ | #define JS_HAS_GENERATORS 0 /* has yield in generator function */ | |||
#define JS_HAS_BLOCK_SCOPE 0 /* has block scope via let/arraycom p */ | #define JS_HAS_BLOCK_SCOPE 0 /* has block scope via let/arraycom p */ | |||
#define JS_HAS_DESTRUCTURING 0 /* has [a,b] = ... or {p:a,q:b} = . .. */ | #define JS_HAS_DESTRUCTURING 0 /* has [a,b] = ... or {p:a,q:b} = . .. */ | |||
#define JS_HAS_GENERATOR_EXPRS 0 /* has (expr for (lhs in iterable)) | ||||
*/ | ||||
#define JS_HAS_EXPR_CLOSURES 0 /* has function (formals) listexpr | ||||
*/ | ||||
#elif JS_VERSION == 170 | #elif JS_VERSION == 170 | |||
#define JS_HAS_STR_HTML_HELPERS 1 /* has str.anchor, str.bold, etc. * / | #define JS_HAS_STR_HTML_HELPERS 1 /* has str.anchor, str.bold, etc. * / | |||
#define JS_HAS_PERL_SUBSTR 1 /* has str.substr */ | #define JS_HAS_PERL_SUBSTR 1 /* has str.substr */ | |||
#define JS_HAS_OBJ_PROTO_PROP 1 /* has o.__proto__ etc. */ | #define JS_HAS_OBJ_PROTO_PROP 1 /* has o.__proto__ etc. */ | |||
#define JS_HAS_OBJ_WATCHPOINT 1 /* has o.watch and o.unwatch */ | #define JS_HAS_OBJ_WATCHPOINT 1 /* has o.watch and o.unwatch */ | |||
#define JS_HAS_EXPORT_IMPORT 1 /* has export fun; import obj.fun * / | #define JS_HAS_EXPORT_IMPORT 1 /* has export fun; import obj.fun * / | |||
#define JS_HAS_EVAL_THIS_SCOPE 1 /* Math.eval is same as with (Math) */ | #define JS_HAS_EVAL_THIS_SCOPE 1 /* Math.eval is same as with (Math) */ | |||
#define JS_HAS_SHARP_VARS 1 /* has #n=, #n# for object literals */ | #define JS_HAS_SHARP_VARS 1 /* has #n=, #n# for object literals */ | |||
#define JS_HAS_SCRIPT_OBJECT 1 /* has (new Script("x++")).exec() * / | #define JS_HAS_SCRIPT_OBJECT 0 /* has (new Script("x++")).exec() * / | |||
#define JS_HAS_XDR 1 /* has XDR API and internal support */ | #define JS_HAS_XDR 1 /* has XDR API and internal support */ | |||
#define JS_HAS_XDR_FREEZE_THAW 0 /* has XDR freeze/thaw script metho ds */ | #define JS_HAS_XDR_FREEZE_THAW 0 /* has XDR freeze/thaw script metho ds */ | |||
#define JS_HAS_TOSOURCE 1 /* has Object/Array toSource method */ | #define JS_HAS_TOSOURCE 1 /* has Object/Array toSource method */ | |||
#define JS_HAS_DEBUGGER_KEYWORD 1 /* has hook for debugger keyword */ | #define JS_HAS_DEBUGGER_KEYWORD 1 /* has hook for debugger keyword */ | |||
#define JS_HAS_CATCH_GUARD 1 /* has exception handling catch gua rd */ | #define JS_HAS_CATCH_GUARD 1 /* has exception handling catch gua rd */ | |||
#define JS_HAS_SPARSE_ARRAYS 0 /* array methods preserve empty ele ms */ | #define JS_HAS_SPARSE_ARRAYS 0 /* array methods preserve empty ele ms */ | |||
#define JS_HAS_GETTER_SETTER 1 /* has JS2 getter/setter functions */ | #define JS_HAS_GETTER_SETTER 1 /* has JS2 getter/setter functions */ | |||
#define JS_HAS_UNEVAL 1 /* has uneval() top-level function */ | #define JS_HAS_UNEVAL 1 /* has uneval() top-level function */ | |||
#define JS_HAS_CONST 1 /* has JS2 const as alternative var */ | #define JS_HAS_CONST 1 /* has JS2 const as alternative var */ | |||
#define JS_HAS_FUN_EXPR_STMT 1 /* has function expression statemen t */ | #define JS_HAS_FUN_EXPR_STMT 1 /* has function expression statemen t */ | |||
#define JS_HAS_LVALUE_RETURN 1 /* has o.item(i) = j; for native it em */ | #define JS_HAS_LVALUE_RETURN 1 /* has o.item(i) = j; for native it em */ | |||
#define JS_HAS_NO_SUCH_METHOD 1 /* has o.__noSuchMethod__ handler * / | #define JS_HAS_NO_SUCH_METHOD 1 /* has o.__noSuchMethod__ handler * / | |||
#define JS_HAS_XML_SUPPORT 1 /* has ECMAScript for XML support * / | #define JS_HAS_XML_SUPPORT 1 /* has ECMAScript for XML support * / | |||
#define JS_HAS_ARRAY_EXTRAS 1 /* has indexOf and Lispy extras */ | #define JS_HAS_ARRAY_EXTRAS 1 /* has indexOf and Lispy extras */ | |||
#define JS_HAS_GENERATORS 1 /* has yield in generator function */ | #define JS_HAS_GENERATORS 1 /* has yield in generator function */ | |||
#define JS_HAS_BLOCK_SCOPE 1 /* has block scope via let/arraycom p */ | #define JS_HAS_BLOCK_SCOPE 1 /* has block scope via let/arraycom p */ | |||
#define JS_HAS_DESTRUCTURING 1 /* has [a,b] = ... or {p:a,q:b} = . .. */ | #define JS_HAS_DESTRUCTURING 1 /* has [a,b] = ... or {p:a,q:b} = . .. */ | |||
#define JS_HAS_GENERATOR_EXPRS 0 /* has (expr for (lhs in iterable)) | ||||
*/ | ||||
#define JS_HAS_EXPR_CLOSURES 0 /* has function (formals) listexpr | ||||
*/ | ||||
#elif JS_VERSION == 180 | ||||
#define JS_HAS_STR_HTML_HELPERS 1 /* has str.anchor, str.bold, etc. * | ||||
/ | ||||
#define JS_HAS_PERL_SUBSTR 1 /* has str.substr */ | ||||
#define JS_HAS_OBJ_PROTO_PROP 1 /* has o.__proto__ etc. */ | ||||
#define JS_HAS_OBJ_WATCHPOINT 1 /* has o.watch and o.unwatch */ | ||||
#define JS_HAS_EXPORT_IMPORT 1 /* has export fun; import obj.fun * | ||||
/ | ||||
#define JS_HAS_EVAL_THIS_SCOPE 1 /* Math.eval is same as with (Math) | ||||
*/ | ||||
#define JS_HAS_SHARP_VARS 1 /* has #n=, #n# for object literals | ||||
*/ | ||||
#define JS_HAS_SCRIPT_OBJECT 0 /* has (new Script("x++")).exec() * | ||||
/ | ||||
#define JS_HAS_XDR 1 /* has XDR API and internal support | ||||
*/ | ||||
#define JS_HAS_XDR_FREEZE_THAW 0 /* has XDR freeze/thaw script metho | ||||
ds */ | ||||
#define JS_HAS_TOSOURCE 1 /* has Object/Array toSource method | ||||
*/ | ||||
#define JS_HAS_DEBUGGER_KEYWORD 1 /* has hook for debugger keyword */ | ||||
#define JS_HAS_CATCH_GUARD 1 /* has exception handling catch gua | ||||
rd */ | ||||
#define JS_HAS_SPARSE_ARRAYS 0 /* array methods preserve empty ele | ||||
ms */ | ||||
#define JS_HAS_GETTER_SETTER 1 /* has JS2 getter/setter functions | ||||
*/ | ||||
#define JS_HAS_UNEVAL 1 /* has uneval() top-level function | ||||
*/ | ||||
#define JS_HAS_CONST 1 /* has JS2 const as alternative var | ||||
*/ | ||||
#define JS_HAS_FUN_EXPR_STMT 1 /* has function expression statemen | ||||
t */ | ||||
#define JS_HAS_LVALUE_RETURN 1 /* has o.item(i) = j; for native it | ||||
em */ | ||||
#define JS_HAS_NO_SUCH_METHOD 1 /* has o.__noSuchMethod__ handler * | ||||
/ | ||||
#define JS_HAS_XML_SUPPORT 1 /* has ECMAScript for XML support * | ||||
/ | ||||
#define JS_HAS_ARRAY_EXTRAS 1 /* has indexOf and Lispy extras */ | ||||
#define JS_HAS_GENERATORS 1 /* has yield in generator function | ||||
*/ | ||||
#define JS_HAS_BLOCK_SCOPE 1 /* has block scope via let/arraycom | ||||
p */ | ||||
#define JS_HAS_DESTRUCTURING 2 /* has [a,b] = ... or {p:a,q:b} = . | ||||
.. */ | ||||
#define JS_HAS_GENERATOR_EXPRS 1 /* has (expr for (lhs in iterable)) | ||||
*/ | ||||
#define JS_HAS_EXPR_CLOSURES 1 /* has function (formals) listexpr | ||||
*/ | ||||
#else | #else | |||
#error "unknown JS_VERSION" | #error "unknown JS_VERSION" | |||
#endif | #endif | |||
/* Features that are present in all versions. */ | /* Features that are present in all versions. */ | |||
#define JS_HAS_RESERVED_JAVA_KEYWORDS 1 | #define JS_HAS_RESERVED_JAVA_KEYWORDS 1 | |||
#define JS_HAS_RESERVED_ECMA_KEYWORDS 1 | #define JS_HAS_RESERVED_ECMA_KEYWORDS 1 | |||
/* Feature-test macro for evolving destructuring support. */ | ||||
#define JS_HAS_DESTRUCTURING_SHORTHAND (JS_HAS_DESTRUCTURING == 2) | ||||
End of changes. 8 change blocks. | ||||
6 lines changed or deleted | 75 lines changed or added | |||
jscpucfg.h | jscpucfg.h | |||
---|---|---|---|---|
skipping to change at line 43 | skipping to change at line 43 | |||
* decision by deleting the provisions above and replace them with the noti ce | * decision by deleting the provisions above and replace them with the noti ce | |||
* and other provisions required by the GPL or the LGPL. If you do not dele te | * and other provisions required by the GPL or the LGPL. If you do not dele te | |||
* the provisions above, a recipient may use your version of this file unde r | * the provisions above, a recipient may use your version of this file unde r | |||
* the terms of any one of the MPL, the GPL or the LGPL. | * the terms of any one of the MPL, the GPL or the LGPL. | |||
* | * | |||
* ***** END LICENSE BLOCK ***** */ | * ***** END LICENSE BLOCK ***** */ | |||
#ifndef js_cpucfg___ | #ifndef js_cpucfg___ | |||
#define js_cpucfg___ | #define js_cpucfg___ | |||
#include "jsosdep.h" | #define JS_HAVE_LONG_LONG | |||
#if defined(XP_WIN) || defined(XP_OS2) || defined(WINCE) | #if defined(XP_WIN) || defined(XP_OS2) || defined(WINCE) | |||
#if defined(_WIN64) | #if defined(_WIN64) | |||
#if defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_) | #if defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_) | |||
#define IS_LITTLE_ENDIAN 1 | #define IS_LITTLE_ENDIAN 1 | |||
#undef IS_BIG_ENDIAN | #undef IS_BIG_ENDIAN | |||
#define JS_BYTES_PER_BYTE 1L | #define JS_BYTES_PER_BYTE 1L | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
jsdate.h | jsdate.h | |||
---|---|---|---|---|
skipping to change at line 67 | skipping to change at line 67 | |||
/* | /* | |||
* Construct a new Date Object from a time value given in milliseconds UTC | * Construct a new Date Object from a time value given in milliseconds UTC | |||
* since the epoch. | * since the epoch. | |||
*/ | */ | |||
extern JS_FRIEND_API(JSObject*) | extern JS_FRIEND_API(JSObject*) | |||
js_NewDateObjectMsec(JSContext* cx, jsdouble msec_time); | js_NewDateObjectMsec(JSContext* cx, jsdouble msec_time); | |||
/* | /* | |||
* Construct a new Date Object from an exploded local time value. | * Construct a new Date Object from an exploded local time value. | |||
* | ||||
* Assert that mon < 12 to help catch off-by-one user errors, which are com | ||||
mon | ||||
* due to the 0-based month numbering copied into JS from Java (java.util.D | ||||
ate | ||||
* in 1995). js_DateSetMonth (below) likewise asserts month < 12. | ||||
*/ | */ | |||
extern JS_FRIEND_API(JSObject*) | extern JS_FRIEND_API(JSObject*) | |||
js_NewDateObject(JSContext* cx, int year, int mon, int mday, | js_NewDateObject(JSContext* cx, int year, int mon, int mday, | |||
int hour, int min, int sec); | int hour, int min, int sec); | |||
/* | /* | |||
* Detect whether the internal date value is NaN. (Because failure is | * Detect whether the internal date value is NaN. (Because failure is | |||
* out-of-band for js_DateGet*) | * out-of-band for js_DateGet*) | |||
*/ | */ | |||
extern JS_FRIEND_API(JSBool) | extern JS_FRIEND_API(JSBool) | |||
skipping to change at line 101 | skipping to change at line 105 | |||
extern JS_FRIEND_API(int) | extern JS_FRIEND_API(int) | |||
js_DateGetMinutes(JSContext *cx, JSObject* obj); | js_DateGetMinutes(JSContext *cx, JSObject* obj); | |||
extern JS_FRIEND_API(int) | extern JS_FRIEND_API(int) | |||
js_DateGetSeconds(JSContext *cx, JSObject* obj); | js_DateGetSeconds(JSContext *cx, JSObject* obj); | |||
extern JS_FRIEND_API(void) | extern JS_FRIEND_API(void) | |||
js_DateSetYear(JSContext *cx, JSObject *obj, int year); | js_DateSetYear(JSContext *cx, JSObject *obj, int year); | |||
extern JS_FRIEND_API(void) | extern JS_FRIEND_API(void) | |||
js_DateSetMonth(JSContext *cx, JSObject *obj, int year); | js_DateSetMonth(JSContext *cx, JSObject *obj, int month); | |||
extern JS_FRIEND_API(void) | extern JS_FRIEND_API(void) | |||
js_DateSetDate(JSContext *cx, JSObject *obj, int date); | js_DateSetDate(JSContext *cx, JSObject *obj, int date); | |||
extern JS_FRIEND_API(void) | extern JS_FRIEND_API(void) | |||
js_DateSetHours(JSContext *cx, JSObject *obj, int hours); | js_DateSetHours(JSContext *cx, JSObject *obj, int hours); | |||
extern JS_FRIEND_API(void) | extern JS_FRIEND_API(void) | |||
js_DateSetMinutes(JSContext *cx, JSObject *obj, int minutes); | js_DateSetMinutes(JSContext *cx, JSObject *obj, int minutes); | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 7 lines changed or added | |||
jsdbgapi.h | jsdbgapi.h | |||
---|---|---|---|---|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- | |||
* vim: set ts=8 sw=4 et tw=78: | ||||
* | * | |||
* ***** BEGIN LICENSE BLOCK ***** | * ***** BEGIN LICENSE BLOCK ***** | |||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | |||
* | * | |||
* The contents of this file are subject to the Mozilla Public License Vers ion | * The contents of this file are subject to the Mozilla Public License Vers ion | |||
* 1.1 (the "License"); you may not use this file except in compliance with | * 1.1 (the "License"); you may not use this file except in compliance with | |||
* the License. You may obtain a copy of the License at | * the License. You may obtain a copy of the License at | |||
* http://www.mozilla.org/MPL/ | * http://www.mozilla.org/MPL/ | |||
* | * | |||
* Software distributed under the License is distributed on an "AS IS" basi s, | * Software distributed under the License is distributed on an "AS IS" basi s, | |||
skipping to change at line 51 | skipping to change at line 52 | |||
#define jsdbgapi_h___ | #define jsdbgapi_h___ | |||
/* | /* | |||
* JS debugger API. | * JS debugger API. | |||
*/ | */ | |||
#include "jsapi.h" | #include "jsapi.h" | |||
#include "jsopcode.h" | #include "jsopcode.h" | |||
#include "jsprvtd.h" | #include "jsprvtd.h" | |||
JS_BEGIN_EXTERN_C | JS_BEGIN_EXTERN_C | |||
extern void | /* | |||
js_PatchOpcode(JSContext *cx, JSScript *script, jsbytecode *pc, JSOp op); | * Unexported library-private helper used to unpatch all traps in a script. | |||
* Returns script->code if script has no traps, else a JS_malloc'ed copy of | ||||
* script->code which the caller must JS_free, or null on JS_malloc OOM. | ||||
*/ | ||||
extern jsbytecode * | ||||
js_UntrapScriptCode(JSContext *cx, JSScript *script); | ||||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_SetTrap(JSContext *cx, JSScript *script, jsbytecode *pc, | JS_SetTrap(JSContext *cx, JSScript *script, jsbytecode *pc, | |||
JSTrapHandler handler, void *closure); | JSTrapHandler handler, void *closure); | |||
extern JS_PUBLIC_API(JSOp) | extern JS_PUBLIC_API(JSOp) | |||
JS_GetTrapOpcode(JSContext *cx, JSScript *script, jsbytecode *pc); | JS_GetTrapOpcode(JSContext *cx, JSScript *script, jsbytecode *pc); | |||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(void) | |||
JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc, | JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc, | |||
skipping to change at line 102 | skipping to change at line 108 | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_ClearAllWatchPoints(JSContext *cx); | JS_ClearAllWatchPoints(JSContext *cx); | |||
#ifdef JS_HAS_OBJ_WATCHPOINT | #ifdef JS_HAS_OBJ_WATCHPOINT | |||
/* | /* | |||
* Hide these non-API function prototypes by testing whether the internal | * Hide these non-API function prototypes by testing whether the internal | |||
* header file "jsconfig.h" has been included. | * header file "jsconfig.h" has been included. | |||
*/ | */ | |||
extern void | extern void | |||
js_MarkWatchPoints(JSContext *cx); | js_TraceWatchPoints(JSTracer *trc, JSObject *obj); | |||
extern void | ||||
js_SweepWatchPoints(JSContext *cx); | ||||
extern JSScopeProperty * | extern JSScopeProperty * | |||
js_FindWatchPoint(JSRuntime *rt, JSScope *scope, jsid id); | js_FindWatchPoint(JSRuntime *rt, JSScope *scope, jsid id); | |||
/* | ||||
* NB: callers outside of jsdbgapi.c must pass non-null scope. | ||||
*/ | ||||
extern JSPropertyOp | extern JSPropertyOp | |||
js_GetWatchedSetter(JSRuntime *rt, JSScope *scope, | js_GetWatchedSetter(JSRuntime *rt, JSScope *scope, | |||
const JSScopeProperty *sprop); | const JSScopeProperty *sprop); | |||
extern JSBool JS_DLL_CALLBACK | extern JSBool JS_DLL_CALLBACK | |||
js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp); | js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp); | |||
extern JSBool JS_DLL_CALLBACK | extern JSBool JS_DLL_CALLBACK | |||
js_watch_set_wrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, | js_watch_set_wrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, | |||
jsval *rval); | jsval *rval); | |||
skipping to change at line 137 | skipping to change at line 149 | |||
extern JS_PUBLIC_API(jsbytecode *) | extern JS_PUBLIC_API(jsbytecode *) | |||
JS_LineNumberToPC(JSContext *cx, JSScript *script, uintN lineno); | JS_LineNumberToPC(JSContext *cx, JSScript *script, uintN lineno); | |||
extern JS_PUBLIC_API(JSScript *) | extern JS_PUBLIC_API(JSScript *) | |||
JS_GetFunctionScript(JSContext *cx, JSFunction *fun); | JS_GetFunctionScript(JSContext *cx, JSFunction *fun); | |||
extern JS_PUBLIC_API(JSNative) | extern JS_PUBLIC_API(JSNative) | |||
JS_GetFunctionNative(JSContext *cx, JSFunction *fun); | JS_GetFunctionNative(JSContext *cx, JSFunction *fun); | |||
extern JS_PUBLIC_API(JSFastNative) | ||||
JS_GetFunctionFastNative(JSContext *cx, JSFunction *fun); | ||||
extern JS_PUBLIC_API(JSPrincipals *) | extern JS_PUBLIC_API(JSPrincipals *) | |||
JS_GetScriptPrincipals(JSContext *cx, JSScript *script); | JS_GetScriptPrincipals(JSContext *cx, JSScript *script); | |||
/* | /* | |||
* Stack Frame Iterator | * Stack Frame Iterator | |||
* | * | |||
* Used to iterate through the JS stack frames to extract | * Used to iterate through the JS stack frames to extract | |||
* information from the frames. | * information from the frames. | |||
*/ | */ | |||
skipping to change at line 229 | skipping to change at line 244 | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_IsDebuggerFrame(JSContext *cx, JSStackFrame *fp); | JS_IsDebuggerFrame(JSContext *cx, JSStackFrame *fp); | |||
extern JS_PUBLIC_API(jsval) | extern JS_PUBLIC_API(jsval) | |||
JS_GetFrameReturnValue(JSContext *cx, JSStackFrame *fp); | JS_GetFrameReturnValue(JSContext *cx, JSStackFrame *fp); | |||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(void) | |||
JS_SetFrameReturnValue(JSContext *cx, JSStackFrame *fp, jsval rval); | JS_SetFrameReturnValue(JSContext *cx, JSStackFrame *fp, jsval rval); | |||
/** | /** | |||
* Return fp's callee function object (fp->argv[-2]) if it has one. | * Return fp's callee function object (fp->callee) if it has one. | |||
*/ | */ | |||
extern JS_PUBLIC_API(JSObject *) | extern JS_PUBLIC_API(JSObject *) | |||
JS_GetFrameCalleeObject(JSContext *cx, JSStackFrame *fp); | JS_GetFrameCalleeObject(JSContext *cx, JSStackFrame *fp); | |||
/************************************************************************/ | /************************************************************************/ | |||
extern JS_PUBLIC_API(const char *) | extern JS_PUBLIC_API(const char *) | |||
JS_GetScriptFilename(JSContext *cx, JSScript *script); | JS_GetScriptFilename(JSContext *cx, JSScript *script); | |||
extern JS_PUBLIC_API(uintN) | extern JS_PUBLIC_API(uintN) | |||
skipping to change at line 385 | skipping to change at line 400 | |||
* be a legal combination, however, in order to preserve JSFILENAME_NULL as a | * be a legal combination, however, in order to preserve JSFILENAME_NULL as a | |||
* unique value. API clients may depend on JSFILENAME_SYSTEM being a set b it | * unique value. API clients may depend on JSFILENAME_SYSTEM being a set b it | |||
* in JSFILENAME_NULL -- a script with a null filename member is presumed t o | * in JSFILENAME_NULL -- a script with a null filename member is presumed t o | |||
* be a "system" script. | * be a "system" script. | |||
*/ | */ | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_FlagScriptFilenamePrefix(JSRuntime *rt, const char *prefix, uint32 flags ); | JS_FlagScriptFilenamePrefix(JSRuntime *rt, const char *prefix, uint32 flags ); | |||
#define JSFILENAME_NULL 0xffffffff /* null script filename */ | #define JSFILENAME_NULL 0xffffffff /* null script filename */ | |||
#define JSFILENAME_SYSTEM 0x00000001 /* "system" script, see bel ow */ | #define JSFILENAME_SYSTEM 0x00000001 /* "system" script, see bel ow */ | |||
#define JSFILENAME_PROTECTED 0x00000002 /* scripts need protection */ | ||||
/* | /* | |||
* Return true if obj is a "system" object, that is, one flagged by a prior | * Return true if obj is a "system" object, that is, one created by | |||
* call to JS_FlagSystemObject(cx, obj). What "system" means is up to the | * JS_NewSystemObject with the system flag set and not JS_NewObject. | |||
API | * | |||
* client, but it can be used to coordinate access control policies based o | * What "system" means is up to the API client, but it can be used to imple | |||
n | ment | |||
* script filenames and their prefixes, using JS_FlagScriptFilenamePrefix a | * access control policies based on script filenames and their prefixes, us | |||
nd | ing | |||
* JS_GetTopScriptFilenameFlags. | * JS_FlagScriptFilenamePrefix and JS_GetTopScriptFilenameFlags. | |||
*/ | */ | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_IsSystemObject(JSContext *cx, JSObject *obj); | JS_IsSystemObject(JSContext *cx, JSObject *obj); | |||
/* | /* | |||
* Flag obj as a "system" object. The API client can flag system objects t | * Call JS_NewObject(cx, clasp, proto, parent) and, if system is true, mark | |||
o | the | |||
* optimize access control checks. The engine stores but does not interpre | * result as a system object, that is an object for which JS_IsSystemObject | |||
t | * returns true. | |||
* the per-object flag set by this call. | ||||
*/ | */ | |||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(JSObject *) | |||
JS_FlagSystemObject(JSContext *cx, JSObject *obj); | JS_NewSystemObject(JSContext *cx, JSClass *clasp, JSObject *proto, | |||
JSObject *parent, JSBool system); | ||||
/************************************************************************/ | ||||
extern JS_PUBLIC_API(JSDebugHooks *) | ||||
JS_GetGlobalDebugHooks(JSRuntime *rt); | ||||
extern JS_PUBLIC_API(JSDebugHooks *) | ||||
JS_SetContextDebugHooks(JSContext *cx, JSDebugHooks *hooks); | ||||
#ifdef MOZ_SHARK | ||||
extern JS_PUBLIC_API(JSBool) | ||||
JS_StartChudRemote(); | ||||
extern JS_PUBLIC_API(JSBool) | ||||
JS_StopChudRemote(); | ||||
extern JS_PUBLIC_API(JSBool) | ||||
JS_ConnectShark(); | ||||
extern JS_PUBLIC_API(JSBool) | ||||
JS_DisconnectShark(); | ||||
extern JS_FRIEND_API(JSBool) | ||||
js_StopShark(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, | ||||
jsval *rval); | ||||
extern JS_FRIEND_API(JSBool) | ||||
js_StartShark(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, | ||||
jsval *rval); | ||||
extern JS_FRIEND_API(JSBool) | ||||
js_ConnectShark(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, | ||||
jsval *rval); | ||||
extern JS_FRIEND_API(JSBool) | ||||
js_DisconnectShark(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, | ||||
jsval *rval); | ||||
#endif /* MOZ_SHARK */ | ||||
JS_END_EXTERN_C | JS_END_EXTERN_C | |||
#endif /* jsdbgapi_h___ */ | #endif /* jsdbgapi_h___ */ | |||
End of changes. 10 change blocks. | ||||
19 lines changed or deleted | 75 lines changed or added | |||
jsdhash.h | jsdhash.h | |||
---|---|---|---|---|
skipping to change at line 89 | skipping to change at line 89 | |||
typedef uint32 JSDHashNumber; | typedef uint32 JSDHashNumber; | |||
typedef struct JSDHashEntryHdr JSDHashEntryHdr; | typedef struct JSDHashEntryHdr JSDHashEntryHdr; | |||
typedef struct JSDHashEntryStub JSDHashEntryStub; | typedef struct JSDHashEntryStub JSDHashEntryStub; | |||
typedef struct JSDHashTable JSDHashTable; | typedef struct JSDHashTable JSDHashTable; | |||
typedef struct JSDHashTableOps JSDHashTableOps; | typedef struct JSDHashTableOps JSDHashTableOps; | |||
/* | /* | |||
* Table entry header structure. | * Table entry header structure. | |||
* | * | |||
* In order to allow in-line allocation of key and value, we do not declare | * In order to allow in-line allocation of key and value, we do not declare | |||
* either here. Instead, the API uses const void *key as a formal paramete | * either here. Instead, the API uses const void *key as a formal paramete | |||
r, | r. | |||
* and asks each entry for its key when necessary via a getKey callback, us | * The key need not be stored in the entry; it may be part of the value, bu | |||
ed | t | |||
* when growing or shrinking the table. Other callback types are defined | * need not be stored at all. | |||
* below and grouped into the JSDHashTableOps structure, for single static | * | |||
* initialization per hash table sub-type. | * Callback types are defined below and grouped into the JSDHashTableOps | |||
* structure, for single static initialization per hash table sub-type. | ||||
* | * | |||
* Each hash table sub-type should nest the JSDHashEntryHdr structure at th e | * Each hash table sub-type should nest the JSDHashEntryHdr structure at th e | |||
* front of its particular entry type. The keyHash member contains the res ult | * front of its particular entry type. The keyHash member contains the res ult | |||
* of multiplying the hash code returned from the hashKey callback (see bel ow) | * of multiplying the hash code returned from the hashKey callback (see bel ow) | |||
* by JS_DHASH_GOLDEN_RATIO, then constraining the result to avoid the magi c 0 | * by JS_DHASH_GOLDEN_RATIO, then constraining the result to avoid the magi c 0 | |||
* and 1 values. The stored keyHash value is table size invariant, and it is | * and 1 values. The stored keyHash value is table size invariant, and it is | |||
* maintained automatically by JS_DHashTableOperate -- users should never s et | * maintained automatically by JS_DHashTableOperate -- users should never s et | |||
* it, and its only uses should be via the entry macros below. | * it, and its only uses should be via the entry macros below. | |||
* | * | |||
* The JS_DHASH_ENTRY_IS_LIVE macro tests whether entry is neither free nor | * The JS_DHASH_ENTRY_IS_LIVE macro tests whether entry is neither free nor | |||
skipping to change at line 246 | skipping to change at line 247 | |||
* The allocator should return null on error only (not if called with nbyte s | * The allocator should return null on error only (not if called with nbyte s | |||
* equal to 0; but note that jsdhash.c code will never call with 0 nbytes). | * equal to 0; but note that jsdhash.c code will never call with 0 nbytes). | |||
*/ | */ | |||
typedef void * | typedef void * | |||
(* JS_DLL_CALLBACK JSDHashAllocTable)(JSDHashTable *table, uint32 nbytes); | (* JS_DLL_CALLBACK JSDHashAllocTable)(JSDHashTable *table, uint32 nbytes); | |||
typedef void | typedef void | |||
(* JS_DLL_CALLBACK JSDHashFreeTable) (JSDHashTable *table, void *ptr); | (* JS_DLL_CALLBACK JSDHashFreeTable) (JSDHashTable *table, void *ptr); | |||
/* | /* | |||
* When a table grows or shrinks, each entry is queried for its key using t | ||||
his | ||||
* callback. NB: in that event, entry is not in table any longer; it's in | ||||
the | ||||
* old entryStore vector, which is due to be freed once all entries have be | ||||
en | ||||
* moved via moveEntry callbacks. | ||||
*/ | ||||
typedef const void * | ||||
(* JS_DLL_CALLBACK JSDHashGetKey) (JSDHashTable *table, | ||||
JSDHashEntryHdr *entry); | ||||
/* | ||||
* Compute the hash code for a given key to be looked up, added, or removed | * Compute the hash code for a given key to be looked up, added, or removed | |||
* from table. A hash code may have any JSDHashNumber value. | * from table. A hash code may have any JSDHashNumber value. | |||
*/ | */ | |||
typedef JSDHashNumber | typedef JSDHashNumber | |||
(* JS_DLL_CALLBACK JSDHashHashKey) (JSDHashTable *table, const void *key) ; | (* JS_DLL_CALLBACK JSDHashHashKey) (JSDHashTable *table, const void *key) ; | |||
/* | /* | |||
* Compare the key identifying entry in table with the provided key paramet er. | * Compare the key identifying entry in table with the provided key paramet er. | |||
* Return JS_TRUE if keys match, JS_FALSE otherwise. | * Return JS_TRUE if keys match, JS_FALSE otherwise. | |||
*/ | */ | |||
skipping to change at line 342 | skipping to change at line 333 | |||
* newly created by the JS_DHASH_ADD call that just succeeded. If placemen t | * newly created by the JS_DHASH_ADD call that just succeeded. If placemen t | |||
* new or similar initialization is required, define an initEntry hook. Of | * new or similar initialization is required, define an initEntry hook. Of | |||
* course, the clearEntry hook must zero or null appropriately. | * course, the clearEntry hook must zero or null appropriately. | |||
* | * | |||
* XXX assumes 0 is null for pointer types. | * XXX assumes 0 is null for pointer types. | |||
*/ | */ | |||
struct JSDHashTableOps { | struct JSDHashTableOps { | |||
/* Mandatory hooks. All implementations must provide these. */ | /* Mandatory hooks. All implementations must provide these. */ | |||
JSDHashAllocTable allocTable; | JSDHashAllocTable allocTable; | |||
JSDHashFreeTable freeTable; | JSDHashFreeTable freeTable; | |||
JSDHashGetKey getKey; | ||||
JSDHashHashKey hashKey; | JSDHashHashKey hashKey; | |||
JSDHashMatchEntry matchEntry; | JSDHashMatchEntry matchEntry; | |||
JSDHashMoveEntry moveEntry; | JSDHashMoveEntry moveEntry; | |||
JSDHashClearEntry clearEntry; | JSDHashClearEntry clearEntry; | |||
JSDHashFinalize finalize; | JSDHashFinalize finalize; | |||
/* Optional hooks start here. If null, these are not called. */ | /* Optional hooks start here. If null, these are not called. */ | |||
JSDHashInitEntry initEntry; | JSDHashInitEntry initEntry; | |||
}; | }; | |||
skipping to change at line 371 | skipping to change at line 361 | |||
extern JS_PUBLIC_API(JSDHashNumber) | extern JS_PUBLIC_API(JSDHashNumber) | |||
JS_DHashStringKey(JSDHashTable *table, const void *key); | JS_DHashStringKey(JSDHashTable *table, const void *key); | |||
/* A minimal entry contains a keyHash header and a void key pointer. */ | /* A minimal entry contains a keyHash header and a void key pointer. */ | |||
struct JSDHashEntryStub { | struct JSDHashEntryStub { | |||
JSDHashEntryHdr hdr; | JSDHashEntryHdr hdr; | |||
const void *key; | const void *key; | |||
}; | }; | |||
extern JS_PUBLIC_API(const void *) | ||||
JS_DHashGetKeyStub(JSDHashTable *table, JSDHashEntryHdr *entry); | ||||
extern JS_PUBLIC_API(JSDHashNumber) | extern JS_PUBLIC_API(JSDHashNumber) | |||
JS_DHashVoidPtrKeyStub(JSDHashTable *table, const void *key); | JS_DHashVoidPtrKeyStub(JSDHashTable *table, const void *key); | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_DHashMatchEntryStub(JSDHashTable *table, | JS_DHashMatchEntryStub(JSDHashTable *table, | |||
const JSDHashEntryHdr *entry, | const JSDHashEntryHdr *entry, | |||
const void *key); | const void *key); | |||
extern JS_PUBLIC_API(JSBool) | extern JS_PUBLIC_API(JSBool) | |||
JS_DHashMatchStringKey(JSDHashTable *table, | JS_DHashMatchStringKey(JSDHashTable *table, | |||
skipping to change at line 459 | skipping to change at line 446 | |||
/* | /* | |||
* Call this macro with k, the number of pointer-sized words wasted per ent ry | * Call this macro with k, the number of pointer-sized words wasted per ent ry | |||
* under chaining, to compute the minimum alpha at which double hashing sti ll | * under chaining, to compute the minimum alpha at which double hashing sti ll | |||
* beats chaining. | * beats chaining. | |||
*/ | */ | |||
#define JS_DHASH_MIN_ALPHA(table, k) \ | #define JS_DHASH_MIN_ALPHA(table, k) \ | |||
((float)((table)->entrySize / sizeof(void *) - 1) \ | ((float)((table)->entrySize / sizeof(void *) - 1) \ | |||
/ ((table)->entrySize / sizeof(void *) + (k))) | / ((table)->entrySize / sizeof(void *) + (k))) | |||
/* | /* | |||
* Default max/min alpha, and macros to compute the value for the |capacity | ||||
| | ||||
* parameter to JS_NewDHashTable and JS_DHashTableInit, given default or an | ||||
y | ||||
* max alpha, such that adding entryCount entries right after initializing | ||||
the | ||||
* table will not require a reallocation (so JS_DHASH_ADD can't fail for th | ||||
ose | ||||
* JS_DHashTableOperate calls). | ||||
* | ||||
* NB: JS_DHASH_CAP is a helper macro meant for use only in JS_DHASH_CAPACI | ||||
TY. | ||||
* Don't use it directly! | ||||
*/ | ||||
#define JS_DHASH_DEFAULT_MAX_ALPHA 0.75 | ||||
#define JS_DHASH_DEFAULT_MIN_ALPHA 0.25 | ||||
#define JS_DHASH_CAP(entryCount, maxAlpha) | ||||
\ | ||||
((uint32)((double)(entryCount) / (maxAlpha))) | ||||
#define JS_DHASH_CAPACITY(entryCount, maxAlpha) | ||||
\ | ||||
(JS_DHASH_CAP(entryCount, maxAlpha) + | ||||
\ | ||||
(((JS_DHASH_CAP(entryCount, maxAlpha) * (uint8)(0x100 * (maxAlpha))) | ||||
\ | ||||
>> 8) < (entryCount))) | ||||
#define JS_DHASH_DEFAULT_CAPACITY(entryCount) | ||||
\ | ||||
JS_DHASH_CAPACITY(entryCount, JS_DHASH_DEFAULT_MAX_ALPHA) | ||||
/* | ||||
* Finalize table's data, free its entry storage using table->ops->freeTabl e, | * Finalize table's data, free its entry storage using table->ops->freeTabl e, | |||
* and leave its members unchanged from their last live values (which leave s | * and leave its members unchanged from their last live values (which leave s | |||
* pointers dangling). If you want to burn cycles clearing table, it's up to | * pointers dangling). If you want to burn cycles clearing table, it's up to | |||
* your code to call memset. | * your code to call memset. | |||
*/ | */ | |||
extern JS_PUBLIC_API(void) | extern JS_PUBLIC_API(void) | |||
JS_DHashTableFinish(JSDHashTable *table); | JS_DHashTableFinish(JSDHashTable *table); | |||
/* | /* | |||
* To consolidate keyHash computation and table grow/shrink code, we use a | * To consolidate keyHash computation and table grow/shrink code, we use a | |||
End of changes. 5 change blocks. | ||||
24 lines changed or deleted | 42 lines changed or added | |||
jsemit.h | jsemit.h | |||
---|---|---|---|---|
skipping to change at line 51 | skipping to change at line 51 | |||
#ifndef jsemit_h___ | #ifndef jsemit_h___ | |||
#define jsemit_h___ | #define jsemit_h___ | |||
/* | /* | |||
* JS bytecode generation. | * JS bytecode generation. | |||
*/ | */ | |||
#include "jsstddef.h" | #include "jsstddef.h" | |||
#include "jstypes.h" | #include "jstypes.h" | |||
#include "jsatom.h" | #include "jsatom.h" | |||
#include "jsopcode.h" | #include "jsopcode.h" | |||
#include "jsscript.h" | ||||
#include "jsprvtd.h" | #include "jsprvtd.h" | |||
#include "jspubtd.h" | #include "jspubtd.h" | |||
JS_BEGIN_EXTERN_C | JS_BEGIN_EXTERN_C | |||
/* | /* | |||
* NB: If you add enumerators for scope statements, add them between STMT_W ITH | * NB: If you add enumerators for scope statements, add them between STMT_W ITH | |||
* and STMT_CATCH, or you will break the STMT_TYPE_IS_SCOPE macro. If you add | * and STMT_CATCH, or you will break the STMT_TYPE_IS_SCOPE macro. If you a dd | |||
* non-looping statement enumerators, add them before STMT_DO_LOOP or you w ill | * non-looping statement enumerators, add them before STMT_DO_LOOP or you w ill | |||
* break the STMT_TYPE_IS_LOOP macro. | * break the STMT_TYPE_IS_LOOP macro. | |||
* | * | |||
* Also remember to keep the statementName array in jsemit.c in sync. | * Also remember to keep the statementName array in jsemit.c in sync. | |||
*/ | */ | |||
typedef enum JSStmtType { | typedef enum JSStmtType { | |||
STMT_LABEL, /* labeled statement: L: s */ | STMT_LABEL, /* labeled statement: L: s */ | |||
STMT_IF, /* if (then) statement */ | STMT_IF, /* if (then) statement */ | |||
STMT_ELSE, /* else clause of if statement */ | STMT_ELSE, /* else clause of if statement */ | |||
STMT_BODY, /* synthetic body of function with | STMT_BODY, /* synthetic body of function with | |||
skipping to change at line 80 | skipping to change at line 81 | |||
STMT_BLOCK, /* compound statement: { s1[;... sN] } */ | STMT_BLOCK, /* compound statement: { s1[;... sN] } */ | |||
STMT_SWITCH, /* switch statement */ | STMT_SWITCH, /* switch statement */ | |||
STMT_WITH, /* with statement */ | STMT_WITH, /* with statement */ | |||
STMT_CATCH, /* catch block */ | STMT_CATCH, /* catch block */ | |||
STMT_TRY, /* try block */ | STMT_TRY, /* try block */ | |||
STMT_FINALLY, /* finally block */ | STMT_FINALLY, /* finally block */ | |||
STMT_SUBROUTINE, /* gosub-target subroutine body */ | STMT_SUBROUTINE, /* gosub-target subroutine body */ | |||
STMT_DO_LOOP, /* do/while loop statement */ | STMT_DO_LOOP, /* do/while loop statement */ | |||
STMT_FOR_LOOP, /* for loop statement */ | STMT_FOR_LOOP, /* for loop statement */ | |||
STMT_FOR_IN_LOOP, /* for/in loop statement */ | STMT_FOR_IN_LOOP, /* for/in loop statement */ | |||
STMT_WHILE_LOOP /* while loop statement */ | STMT_WHILE_LOOP, /* while loop statement */ | |||
STMT_LIMIT | ||||
} JSStmtType; | } JSStmtType; | |||
#define STMT_TYPE_IN_RANGE(t,b,e) ((uint)((t) - (b)) <= (uintN)((e) - (b))) | #define STMT_TYPE_IN_RANGE(t,b,e) ((uint)((t) - (b)) <= (uintN)((e) - (b))) | |||
/* | /* | |||
* A comment on the encoding of the JSStmtType enum and type-testing macros : | * A comment on the encoding of the JSStmtType enum and type-testing macros : | |||
* | * | |||
* STMT_TYPE_MAYBE_SCOPE tells whether a statement type is always, or may | * STMT_TYPE_MAYBE_SCOPE tells whether a statement type is always, or may | |||
* become, a lexical scope. It therefore includes block and switch (the tw o | * become, a lexical scope. It therefore includes block and switch (the tw o | |||
* low-numbered "maybe" scope types) and excludes with (with has dynamic sc ope | * low-numbered "maybe" scope types) and excludes with (with has dynamic sc ope | |||
* pending the "reformed with" in ES4/JS2). It includes all try-catch-fina lly | * pending the "reformed with" in ES4/JS2). It includes all try-catch-fina lly | |||
* types, which are high-numbered maybe-scope types. | * types, which are high-numbered maybe-scope types. | |||
* | * | |||
* STMT_TYPE_LINKS_SCOPE tells whether a JSStmtInfo of the given type eager ly | * STMT_TYPE_LINKS_SCOPE tells whether a JSStmtInfo of the given type eager ly | |||
* links to other scoping statement info records. It excludes the two earl y | * links to other scoping statement info records. It excludes the two earl y | |||
* "maybe" types, block and switch, as well as the try and both finally typ es, | * "maybe" types, block and switch, as well as the try and both finally typ es, | |||
* since try and the other trailing maybe-scope types don't need block scop e | * since try and the other trailing maybe-scope types don't need block scop e | |||
* unless they contain let declarations. | * unless they contain let declarations. | |||
* | * | |||
* We treat with as a static scope because it prevents lexical binding from | * We treat WITH as a static scope because it prevents lexical binding from | |||
* continuing further up the static scope chain. With the "reformed with" | * continuing further up the static scope chain. With the "reformed with" | |||
* proposal for JS2, we'll be able to model it statically, too. | * proposal for JS2, we'll be able to model it statically, too. | |||
*/ | */ | |||
#define STMT_TYPE_MAYBE_SCOPE(type) \ | #define STMT_TYPE_MAYBE_SCOPE(type) \ | |||
(type != STMT_WITH && \ | (type != STMT_WITH && \ | |||
STMT_TYPE_IN_RANGE(type, STMT_BLOCK, STMT_SUBROUTINE)) | STMT_TYPE_IN_RANGE(type, STMT_BLOCK, STMT_SUBROUTINE)) | |||
#define STMT_TYPE_LINKS_SCOPE(type) \ | #define STMT_TYPE_LINKS_SCOPE(type) \ | |||
STMT_TYPE_IN_RANGE(type, STMT_WITH, STMT_CATCH) | STMT_TYPE_IN_RANGE(type, STMT_WITH, STMT_CATCH) | |||
#define STMT_TYPE_IS_TRYING(type) \ | #define STMT_TYPE_IS_TRYING(type) \ | |||
skipping to change at line 130 | skipping to change at line 132 | |||
#define STMT_IS_LOOP(stmt) STMT_TYPE_IS_LOOP((stmt)->type) | #define STMT_IS_LOOP(stmt) STMT_TYPE_IS_LOOP((stmt)->type) | |||
typedef struct JSStmtInfo JSStmtInfo; | typedef struct JSStmtInfo JSStmtInfo; | |||
struct JSStmtInfo { | struct JSStmtInfo { | |||
uint16 type; /* statement type */ | uint16 type; /* statement type */ | |||
uint16 flags; /* flags, see below */ | uint16 flags; /* flags, see below */ | |||
ptrdiff_t update; /* loop update offset (top if none) */ | ptrdiff_t update; /* loop update offset (top if none) */ | |||
ptrdiff_t breaks; /* offset of last break in loop */ | ptrdiff_t breaks; /* offset of last break in loop */ | |||
ptrdiff_t continues; /* offset of last continue in loop */ | ptrdiff_t continues; /* offset of last continue in loop */ | |||
JSAtom *atom; /* name of LABEL, or block scope object | union { | |||
*/ | JSAtom *label; /* name of LABEL */ | |||
JSObject *blockObj; /* block scope object */ | ||||
} u; | ||||
JSStmtInfo *down; /* info for enclosing statement */ | JSStmtInfo *down; /* info for enclosing statement */ | |||
JSStmtInfo *downScope; /* next enclosing lexical scope */ | JSStmtInfo *downScope; /* next enclosing lexical scope */ | |||
}; | }; | |||
#define SIF_SCOPE 0x0001 /* statement has its own lexical scope */ | #define SIF_SCOPE 0x0001 /* statement has its own lexical scope */ | |||
#define SIF_BODY_BLOCK 0x0002 /* STMT_BLOCK type is a function body * / | #define SIF_BODY_BLOCK 0x0002 /* STMT_BLOCK type is a function body * / | |||
#define SIF_FOR_BLOCK 0x0004 /* for (let ...) induced block scope */ | ||||
/* | /* | |||
* To reuse space in JSStmtInfo, rename breaks and continues for use during | * To reuse space in JSStmtInfo, rename breaks and continues for use during | |||
* try/catch/finally code generation and backpatching. To match most commo | * try/catch/finally code generation and backpatching. To match most common | |||
n | * use cases, the macro argument is a struct, not a struct pointer. Only a | |||
* use cases, the macro argument is a struct, not a struct pointer. Only a | ||||
* loop, switch, or label statement info record can have breaks and continu es, | * loop, switch, or label statement info record can have breaks and continu es, | |||
* and only a for loop has an update backpatch chain, so it's safe to overl ay | * and only a for loop has an update backpatch chain, so it's safe to overl ay | |||
* these for the "trying" JSStmtTypes. | * these for the "trying" JSStmtTypes. | |||
*/ | */ | |||
#define CATCHNOTE(stmt) ((stmt).update) | #define CATCHNOTE(stmt) ((stmt).update) | |||
#define GOSUBS(stmt) ((stmt).breaks) | #define GOSUBS(stmt) ((stmt).breaks) | |||
#define GUARDJUMP(stmt) ((stmt).continues) | #define GUARDJUMP(stmt) ((stmt).continues) | |||
#define AT_TOP_LEVEL(tc) \ | #define AT_TOP_LEVEL(tc) \ | |||
(!(tc)->topStmt || ((tc)->topStmt->flags & SIF_BODY_BLOCK)) | (!(tc)->topStmt || ((tc)->topStmt->flags & SIF_BODY_BLOCK)) | |||
#define SET_STATEMENT_TOP(stmt, top) \ | #define SET_STATEMENT_TOP(stmt, top) \ | |||
((stmt)->update = (top), (stmt)->breaks = (stmt)->continues = (-1)) | ((stmt)->update = (top), (stmt)->breaks = (stmt)->continues = (-1)) | |||
struct JSTreeContext { /* tree context for semantic checks */ | struct JSTreeContext { /* tree context for semantic checks */ | |||
uint16 flags; /* statement state flags, see below */ | uint16 flags; /* statement state flags, see below */ | |||
uint16 numGlobalVars; /* max. no. of global variables/regexps | uint16 ngvars; /* max. no. of global variables/regexps | |||
*/ | */ | |||
uint32 tryCount; /* total count of try statements parsed | ||||
*/ | ||||
uint32 globalUses; /* optimizable global var uses in total */ | uint32 globalUses; /* optimizable global var uses in total */ | |||
uint32 loopyGlobalUses;/* optimizable global var uses in loops */ | uint32 loopyGlobalUses;/* optimizable global var uses in loops */ | |||
uint16 scopeDepth; /* current lexical scope chain depth */ | ||||
uint16 maxScopeDepth; /* maximum lexical scope chain depth */ | ||||
JSStmtInfo *topStmt; /* top of statement info stack */ | JSStmtInfo *topStmt; /* top of statement info stack */ | |||
JSStmtInfo *topScopeStmt; /* top lexical scope statement */ | JSStmtInfo *topScopeStmt; /* top lexical scope statement */ | |||
JSObject *blockChain; /* compile time block scope chain (NB: one | JSObject *blockChain; /* compile time block scope chain (NB: one | |||
deeper than the topScopeStmt/downSco pe | deeper than the topScopeStmt/downSco pe | |||
chain when in head of let block/expr ) */ | chain when in head of let block/expr ) */ | |||
JSParseNode *blockNode; /* parse node for a lexical scope. | JSParseNode *blockNode; /* parse node for a lexical scope. | |||
XXX combine with blockChain? */ | XXX combine with blockChain? */ | |||
JSAtomList decls; /* function, const, and var declaration s */ | JSAtomList decls; /* function, const, and var declaration s */ | |||
JSParseNode *nodeList; /* list of recyclable parse-node struct | JSParseContext *parseContext; | |||
s */ | JSFunction *fun; /* function to store argument and varia | |||
ble | ||||
names when flags & TCF_IN_FUNCTION * | ||||
/ | ||||
}; | }; | |||
#define TCF_COMPILING 0x01 /* generating bytecode; this tc is a cg | #define TCF_IN_FUNCTION 0x01 /* parsing inside function body */ | |||
*/ | #define TCF_RETURN_EXPR 0x02 /* function has 'return expr;' */ | |||
#define TCF_IN_FUNCTION 0x02 /* parsing inside function body */ | #define TCF_RETURN_VOID 0x04 /* function has 'return;' */ | |||
#define TCF_RETURN_EXPR 0x04 /* function has 'return expr;' */ | #define TCF_IN_FOR_INIT 0x08 /* parsing init expr of for; exclude 'i | |||
#define TCF_RETURN_VOID 0x08 /* function has 'return;' */ | n' */ | |||
#define TCF_RETURN_FLAGS 0x0C /* propagate these out of blocks */ | #define TCF_FUN_CLOSURE_VS_VAR 0x10 /* function and var with same name */ | |||
#define TCF_IN_FOR_INIT 0x10 /* parsing init expr of for; exclude 'i | #define TCF_FUN_USES_NONLOCALS 0x20 /* function refers to non-local names * | |||
n' */ | / | |||
#define TCF_FUN_CLOSURE_VS_VAR 0x20 /* function and var with same name */ | #define TCF_FUN_HEAVYWEIGHT 0x40 /* function needs Call object per call | |||
#define TCF_FUN_USES_NONLOCALS 0x40 /* function refers to non-local names * | */ | |||
/ | #define TCF_FUN_IS_GENERATOR 0x80 /* parsed yield statement in function * | |||
#define TCF_FUN_HEAVYWEIGHT 0x80 /* function needs Call object per call | / | |||
*/ | #define TCF_HAS_DEFXMLNS 0x100 /* default xml namespace = ...; parsed | |||
#define TCF_FUN_IS_GENERATOR 0x100 /* parsed yield statement in function * | */ | |||
/ | #define TCF_HAS_FUNCTION_STMT 0x200 /* block contains a function statement | |||
#define TCF_FUN_FLAGS 0x1E0 /* flags to propagate from FunctionBody | */ | |||
*/ | #define TCF_GENEXP_LAMBDA 0x400 /* flag lambda from generator expressio | |||
#define TCF_HAS_DEFXMLNS 0x200 /* default xml namespace = ...; parsed | n */ | |||
*/ | #define TCF_COMPILE_N_GO 0x800 /* compiler-and-go mode of script, can | |||
#define TCF_HAS_FUNCTION_STMT 0x400 /* block contains a function statement | optimize name references based on sc | |||
*/ | ope | |||
chain */ | ||||
#define TREE_CONTEXT_INIT(tc) | /* | |||
\ | * Flags to propagate out of the blocks. | |||
((tc)->flags = (tc)->numGlobalVars = 0, | */ | |||
\ | #define TCF_RETURN_FLAGS (TCF_RETURN_EXPR | TCF_RETURN_VOID) | |||
(tc)->tryCount = (tc)->globalUses = (tc)->loopyGlobalUses = 0, | ||||
\ | /* | |||
* Flags to propagate from FunctionBody. | ||||
*/ | ||||
#define TCF_FUN_FLAGS (TCF_FUN_IS_GENERATOR | | ||||
\ | ||||
TCF_FUN_HEAVYWEIGHT | | ||||
\ | ||||
TCF_FUN_USES_NONLOCALS | | ||||
\ | ||||
TCF_FUN_CLOSURE_VS_VAR) | ||||
#define TREE_CONTEXT_INIT(tc, pc) | ||||
\ | ||||
((tc)->flags = (tc)->ngvars = 0, | ||||
\ | ||||
(tc)->globalUses = (tc)->loopyGlobalUses = 0, | ||||
\ | ||||
(tc)->scopeDepth = (tc)->maxScopeDepth = 0, | ||||
\ | ||||
(tc)->topStmt = (tc)->topScopeStmt = NULL, \ | (tc)->topStmt = (tc)->topScopeStmt = NULL, \ | |||
(tc)->blockChain = NULL, \ | (tc)->blockChain = NULL, \ | |||
ATOM_LIST_INIT(&(tc)->decls), \ | ATOM_LIST_INIT(&(tc)->decls), \ | |||
(tc)->nodeList = NULL, (tc)->blockNode = NULL) | (tc)->blockNode = NULL, | |||
\ | ||||
(tc)->parseContext = (pc), | ||||
\ | ||||
(tc)->fun = NULL) | ||||
#define TREE_CONTEXT_FINISH(tc) \ | #define TREE_CONTEXT_FINISH(tc) \ | |||
((void)0) | ((void)0) | |||
/* | /* | |||
* Span-dependent instructions are jumps whose span (from the jump bytecode to | * Span-dependent instructions are jumps whose span (from the jump bytecode to | |||
* the jump target) may require 2 or 4 bytes of immediate operand. | * the jump target) may require 2 or 4 bytes of immediate operand. | |||
*/ | */ | |||
typedef struct JSSpanDep JSSpanDep; | typedef struct JSSpanDep JSSpanDep; | |||
typedef struct JSJumpTarget JSJumpTarget; | typedef struct JSJumpTarget JSJumpTarget; | |||
skipping to change at line 259 | skipping to change at line 285 | |||
JT_CLR_TAG((sd)->target)) | JT_CLR_TAG((sd)->target)) | |||
#define SD_SET_BPDELTA(sd,bp) ((sd)->target = BPDELTA_TO_JT(bp)) | #define SD_SET_BPDELTA(sd,bp) ((sd)->target = BPDELTA_TO_JT(bp)) | |||
#define SD_GET_BPDELTA(sd) (JS_ASSERT(!JT_HAS_TAG((sd)->target)), \ | #define SD_GET_BPDELTA(sd) (JS_ASSERT(!JT_HAS_TAG((sd)->target)), \ | |||
JT_TO_BPDELTA((sd)->target)) | JT_TO_BPDELTA((sd)->target)) | |||
/* Avoid asserting twice by expanding SD_GET_TARGET in the "then" clause. * / | /* Avoid asserting twice by expanding SD_GET_TARGET in the "then" clause. * / | |||
#define SD_SPAN(sd,pivot) (SD_GET_TARGET(sd) \ | #define SD_SPAN(sd,pivot) (SD_GET_TARGET(sd) \ | |||
? JT_CLR_TAG((sd)->target)->offset - (pivo t) \ | ? JT_CLR_TAG((sd)->target)->offset - (pivo t) \ | |||
: 0) | : 0) | |||
typedef struct JSTryNode JSTryNode; | ||||
struct JSTryNode { | ||||
JSTryNote note; | ||||
JSTryNode *prev; | ||||
}; | ||||
typedef struct JSEmittedObjectList { | ||||
uint32 length; /* number of emitted so far objects */ | ||||
JSParsedObjectBox *lastPob; /* last emitted object */ | ||||
} JSEmittedObjectList; | ||||
extern void | ||||
FinishParsedObjects(JSEmittedObjectList *emittedList, JSObjectArray *object | ||||
Map); | ||||
struct JSCodeGenerator { | struct JSCodeGenerator { | |||
JSTreeContext treeContext; /* base state: statement info stack, et c. */ | JSTreeContext treeContext; /* base state: statement info stack, et c. */ | |||
JSArenaPool *codePool; /* pointer to thread code arena pool */ | JSArenaPool *codePool; /* pointer to thread code arena pool */ | |||
JSArenaPool *notePool; /* pointer to thread srcnote arena pool */ | JSArenaPool *notePool; /* pointer to thread srcnote arena pool */ | |||
void *codeMark; /* low watermark in cg->codePool */ | void *codeMark; /* low watermark in cg->codePool */ | |||
void *noteMark; /* low watermark in cg->notePool */ | void *noteMark; /* low watermark in cg->notePool */ | |||
void *tempMark; /* low watermark in cx->tempPool */ | ||||
struct { | struct { | |||
jsbytecode *base; /* base of JS bytecode vector */ | jsbytecode *base; /* base of JS bytecode vector */ | |||
jsbytecode *limit; /* one byte beyond end of bytecode */ | jsbytecode *limit; /* one byte beyond end of bytecode */ | |||
jsbytecode *next; /* pointer to next free bytecode */ | jsbytecode *next; /* pointer to next free bytecode */ | |||
jssrcnote *notes; /* source notes, see below */ | jssrcnote *notes; /* source notes, see below */ | |||
uintN noteCount; /* number of source notes so far */ | uintN noteCount; /* number of source notes so far */ | |||
uintN noteMask; /* growth increment for notes */ | uintN noteMask; /* growth increment for notes */ | |||
ptrdiff_t lastNoteOffset; /* code offset for last source note */ | ptrdiff_t lastNoteOffset; /* code offset for last source note */ | |||
uintN currentLine; /* line number for tree-based srcnote g en */ | uintN currentLine; /* line number for tree-based srcnote g en */ | |||
} prolog, main, *current; | } prolog, main, *current; | |||
const char *filename; /* null or weak link to source filename */ | ||||
uintN firstLine; /* first line, for js_NewScriptFromCG * / | uintN firstLine; /* first line, for js_NewScriptFromCG * / | |||
JSPrincipals *principals; /* principals for constant folding eval */ | ||||
JSAtomList atomList; /* literals indexed for mapping */ | JSAtomList atomList; /* literals indexed for mapping */ | |||
intN stackDepth; /* current stack depth in script frame */ | intN stackDepth; /* current stack depth in script frame */ | |||
uintN maxStackDepth; /* maximum stack depth so far */ | uintN maxStackDepth; /* maximum stack depth so far */ | |||
JSTryNote *tryBase; /* first exception handling note */ | uintN ntrynotes; /* number of allocated so far try notes | |||
JSTryNote *tryNext; /* next available note */ | */ | |||
size_t tryNoteSpace; /* # of bytes allocated at tryBase */ | JSTryNode *lastTryNode; /* the last allocated try node */ | |||
JSSpanDep *spanDeps; /* span dependent instruction records * / | JSSpanDep *spanDeps; /* span dependent instruction records * / | |||
JSJumpTarget *jumpTargets; /* AVL tree of jump target offsets */ | JSJumpTarget *jumpTargets; /* AVL tree of jump target offsets */ | |||
JSJumpTarget *jtFreeList; /* JT_LEFT-linked list of free structs */ | JSJumpTarget *jtFreeList; /* JT_LEFT-linked list of free structs */ | |||
uintN numSpanDeps; /* number of span dependencies */ | uintN numSpanDeps; /* number of span dependencies */ | |||
uintN numJumpTargets; /* number of jump targets */ | uintN numJumpTargets; /* number of jump targets */ | |||
ptrdiff_t spanDepTodo; /* offset from main.base of potentially | ptrdiff_t spanDepTodo; /* offset from main.base of potentially | |||
unoptimized spandeps */ | unoptimized spandeps */ | |||
uintN arrayCompSlot; /* stack slot of array in comprehension */ | uintN arrayCompSlot; /* stack slot of array in comprehension */ | |||
uintN emitLevel; /* js_EmitTree recursion level */ | uintN emitLevel; /* js_EmitTree recursion level */ | |||
JSAtomList constList; /* compile time constants */ | JSAtomList constList; /* compile time constants */ | |||
JSCodeGenerator *parent; /* Enclosing function or global context | ||||
*/ | JSEmittedObjectList objectList; /* list of emitted so far objects */ | |||
JSEmittedObjectList regexpList; /* list of emitted so far regexp | ||||
that will be cloned during execution | ||||
*/ | ||||
JSCodeGenerator *parent; /* enclosing function or global context | ||||
*/ | ||||
}; | }; | |||
#define CG_BASE(cg) ((cg)->current->base) | #define CG_BASE(cg) ((cg)->current->base) | |||
#define CG_LIMIT(cg) ((cg)->current->limit) | #define CG_LIMIT(cg) ((cg)->current->limit) | |||
#define CG_NEXT(cg) ((cg)->current->next) | #define CG_NEXT(cg) ((cg)->current->next) | |||
#define CG_CODE(cg,offset) (CG_BASE(cg) + (offset)) | #define CG_CODE(cg,offset) (CG_BASE(cg) + (offset)) | |||
#define CG_OFFSET(cg) PTRDIFF(CG_NEXT(cg), CG_BASE(cg), jsbytecod e) | #define CG_OFFSET(cg) PTRDIFF(CG_NEXT(cg), CG_BASE(cg), jsbytecod e) | |||
#define CG_NOTES(cg) ((cg)->current->notes) | #define CG_NOTES(cg) ((cg)->current->notes) | |||
#define CG_NOTE_COUNT(cg) ((cg)->current->noteCount) | #define CG_NOTE_COUNT(cg) ((cg)->current->noteCount) | |||
skipping to change at line 331 | skipping to change at line 373 | |||
#define CG_PROLOG_CODE(cg,poff) (CG_PROLOG_BASE(cg) + (poff)) | #define CG_PROLOG_CODE(cg,poff) (CG_PROLOG_BASE(cg) + (poff)) | |||
#define CG_PROLOG_OFFSET(cg) PTRDIFF(CG_PROLOG_NEXT(cg), CG_PROLOG_BASE( cg),\ | #define CG_PROLOG_OFFSET(cg) PTRDIFF(CG_PROLOG_NEXT(cg), CG_PROLOG_BASE( cg),\ | |||
jsbytecode) | jsbytecode) | |||
#define CG_SWITCH_TO_MAIN(cg) ((cg)->current = &(cg)->main) | #define CG_SWITCH_TO_MAIN(cg) ((cg)->current = &(cg)->main) | |||
#define CG_SWITCH_TO_PROLOG(cg) ((cg)->current = &(cg)->prolog) | #define CG_SWITCH_TO_PROLOG(cg) ((cg)->current = &(cg)->prolog) | |||
/* | /* | |||
* Initialize cg to allocate bytecode space from codePool, source note spac e | * Initialize cg to allocate bytecode space from codePool, source note spac e | |||
* from notePool, and all other arena-allocated temporaries from cx->tempPo ol. | * from notePool, and all other arena-allocated temporaries from cx->tempPo ol. | |||
* Return true on success. Report an error and return false if the initial | ||||
* code segment can't be allocated. | ||||
*/ | */ | |||
extern JS_FRIEND_API(JSBool) | extern JS_FRIEND_API(void) | |||
js_InitCodeGenerator(JSContext *cx, JSCodeGenerator *cg, | js_InitCodeGenerator(JSContext *cx, JSCodeGenerator *cg, JSParseContext *pc | |||
, | ||||
JSArenaPool *codePool, JSArenaPool *notePool, | JSArenaPool *codePool, JSArenaPool *notePool, | |||
const char *filename, uintN lineno, | uintN lineno); | |||
JSPrincipals *principals); | ||||
/* | /* | |||
* Release cg->codePool, cg->notePool, and cx->tempPool to marks set by | * Release cg->codePool, cg->notePool, and cx->tempPool to marks set by | |||
* js_InitCodeGenerator. Note that cgs are magic: they own the arena pool | * js_InitCodeGenerator. Note that cgs are magic: they own the arena pool | |||
* "tops-of-stack" space above their codeMark, noteMark, and tempMark point s. | * "tops-of-stack" space above their codeMark, noteMark, and tempMark point s. | |||
* This means you cannot alloc from tempPool and save the pointer beyond th e | * This means you cannot alloc from tempPool and save the pointer beyond th e | |||
* next JS_FinishCodeGenerator. | * next JS_FinishCodeGenerator. | |||
*/ | */ | |||
extern JS_FRIEND_API(void) | extern JS_FRIEND_API(void) | |||
js_FinishCodeGenerator(JSContext *cx, JSCodeGenerator *cg); | js_FinishCodeGenerator(JSContext *cx, JSCodeGenerator *cg); | |||
/* | /* | |||
* Emit one bytecode. | * Emit one bytecode. | |||
*/ | */ | |||
skipping to change at line 414 | skipping to change at line 453 | |||
js_IsGlobalReference(JSTreeContext *tc, JSAtom *atom, JSBool *loopyp); | js_IsGlobalReference(JSTreeContext *tc, JSAtom *atom, JSBool *loopyp); | |||
/* | /* | |||
* Push the C-stack-allocated struct at stmt onto the stmtInfo stack. | * Push the C-stack-allocated struct at stmt onto the stmtInfo stack. | |||
*/ | */ | |||
extern void | extern void | |||
js_PushStatement(JSTreeContext *tc, JSStmtInfo *stmt, JSStmtType type, | js_PushStatement(JSTreeContext *tc, JSStmtInfo *stmt, JSStmtType type, | |||
ptrdiff_t top); | ptrdiff_t top); | |||
/* | /* | |||
* Push a block scope statement and link blockAtom's object-valued key into | * Push a block scope statement and link blockObj into tc->blockChain. To p | |||
* tc->blockChain. To pop this statement info record, use js_PopStatement | op | |||
as | * this statement info record, use js_PopStatement as usual, or if appropri | |||
* usual, or if appropriate (if generating code), js_PopStatementCG. | ate | |||
* (if generating code), js_PopStatementCG. | ||||
*/ | */ | |||
extern void | extern void | |||
js_PushBlockScope(JSTreeContext *tc, JSStmtInfo *stmt, JSAtom *blockAtom, | js_PushBlockScope(JSTreeContext *tc, JSStmtInfo *stmt, JSObject *blockObj, | |||
ptrdiff_t top); | ptrdiff_t top); | |||
/* | /* | |||
* Pop tc->topStmt. If the top JSStmtInfo struct is not stack-allocated, i t | * Pop tc->topStmt. If the top JSStmtInfo struct is not stack-allocated, it | |||
* is up to the caller to free it. | * is up to the caller to free it. | |||
*/ | */ | |||
extern void | extern void | |||
js_PopStatement(JSTreeContext *tc); | js_PopStatement(JSTreeContext *tc); | |||
/* | /* | |||
* Like js_PopStatement(&cg->treeContext), also patch breaks and continues | * Like js_PopStatement(&cg->treeContext), also patch breaks and continues | |||
* unless the top statement info record represents a try-catch-finally suit e. | * unless the top statement info record represents a try-catch-finally suit e. | |||
* May fail if a jump offset overflows. | * May fail if a jump offset overflows. | |||
*/ | */ | |||
extern JSBool | extern JSBool | |||
js_PopStatementCG(JSContext *cx, JSCodeGenerator *cg); | js_PopStatementCG(JSContext *cx, JSCodeGenerator *cg); | |||
/* | /* | |||
* Define and lookup a primitive jsval associated with the const named by a tom. | * Define and lookup a primitive jsval associated with the const named by a tom. | |||
* js_DefineCompileTimeConstant analyzes the constant-folded initializer at pn | * js_DefineCompileTimeConstant analyzes the constant-folded initializer at pn | |||
* and saves the const's value in cg->constList, if it can be used at compi le | * and saves the const's value in cg->constList, if it can be used at compi le | |||
* time. It returns true unless an error occurred. | * time. It returns true unless an error occurred. | |||
* | * | |||
* If the initializer's value could not be saved, js_LookupCompileTimeConst | * If the initializer's value could not be saved, js_DefineCompileTimeConst | |||
ant | ant | |||
* calls will return the undefined value. js_LookupCompileTimeConstant tri | * calls will return the undefined value. js_DefineCompileTimeConstant trie | |||
es | s | |||
* to find a const value memorized for atom, returning true with *vp set to a | * to find a const value memorized for atom, returning true with *vp set to a | |||
* value other than undefined if the constant was found, true with *vp set to | * value other than undefined if the constant was found, true with *vp set to | |||
* JSVAL_VOID if not found, and false on error. | * JSVAL_VOID if not found, and false on error. | |||
*/ | */ | |||
extern JSBool | extern JSBool | |||
js_DefineCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *at om, | js_DefineCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *at om, | |||
JSParseNode *pn); | JSParseNode *pn); | |||
extern JSBool | ||||
js_LookupCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *at | ||||
om, | ||||
jsval *vp); | ||||
/* | /* | |||
* Find a lexically scoped variable (one declared by let, catch, or an arra y | * Find a lexically scoped variable (one declared by let, catch, or an arra y | |||
* comprehension) named by atom, looking in tc's compile-time scopes. | * comprehension) named by atom, looking in tc's compile-time scopes. | |||
* | * | |||
* If a WITH statement is reached along the scope stack, return its stateme nt | * If a WITH statement is reached along the scope stack, return its stateme nt | |||
* info record, so callers can tell that atom is ambiguous. If slotp is no t | * info record, so callers can tell that atom is ambiguous. If slotp is not | |||
* null, then if atom is found, set *slotp to its stack slot, otherwise to -1. | * null, then if atom is found, set *slotp to its stack slot, otherwise to -1. | |||
* This means that if slotp is not null, all the block objects on the lexic al | * This means that if slotp is not null, all the block objects on the lexic al | |||
* scope chain must have had their depth slots computed by the code generat or, | * scope chain must have had their depth slots computed by the code generat or, | |||
* so the caller must be under js_EmitTree. | * so the caller must be under js_EmitTree. | |||
* | * | |||
* In any event, directly return the statement info record in which atom wa s | * In any event, directly return the statement info record in which atom wa s | |||
* found. Otherwise return null. | * found. Otherwise return null. | |||
*/ | */ | |||
extern JSStmtInfo * | extern JSStmtInfo * | |||
js_LexicalLookup(JSTreeContext *tc, JSAtom *atom, jsint *slotp, | js_LexicalLookup(JSTreeContext *tc, JSAtom *atom, jsint *slotp, | |||
JSBool letdecl); | uintN decltype); | |||
/* | /* | |||
* Emit code into cg for the tree rooted at pn. | * Emit code into cg for the tree rooted at pn. | |||
*/ | */ | |||
extern JSBool | extern JSBool | |||
js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn); | js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn); | |||
/* | /* | |||
* Emit function code into cg for the tree rooted at body. | * Emit function code using cg for the tree rooted at body. | |||
*/ | ||||
extern JSBool | ||||
js_EmitFunctionBytecode(JSContext *cx, JSCodeGenerator *cg, JSParseNode *bo | ||||
dy); | ||||
/* | ||||
* Emit code into cg for the tree rooted at body, then create a persistent | ||||
* script for fun from cg. | ||||
*/ | */ | |||
extern JSBool | extern JSBool | |||
js_EmitFunctionBody(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body, | js_EmitFunctionScript(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body | |||
JSFunction *fun); | ); | |||
/* | /* | |||
* Source notes generated along with bytecode for decompiling and debugging . | * Source notes generated along with bytecode for decompiling and debugging . | |||
* A source note is a uint8 with 5 bits of type and 3 of offset from the pc of | * A source note is a uint8 with 5 bits of type and 3 of offset from the pc of | |||
* the previous note. If 3 bits of offset aren't enough, extended delta no tes | * the previous note. If 3 bits of offset aren't enough, extended delta not es | |||
* (SRC_XDELTA) consisting of 2 set high order bits followed by 6 offset bi ts | * (SRC_XDELTA) consisting of 2 set high order bits followed by 6 offset bi ts | |||
* are emitted before the next note. Some notes have operand offsets encod ed | * are emitted before the next note. Some notes have operand offsets encode d | |||
* immediately after them, in note bytes or byte-triples. | * immediately after them, in note bytes or byte-triples. | |||
* | * | |||
* Source Note Extended Delta | * Source Note Extended Delta | |||
* +7-6-5-4-3+2-1-0+ +7-6-5+4-3-2-1-0+ | * +7-6-5-4-3+2-1-0+ +7-6-5+4-3-2-1-0+ | |||
* |note-type|delta| |1 1| ext-delta | | * |note-type|delta| |1 1| ext-delta | | |||
* +---------+-----+ +---+-----------+ | * +---------+-----+ +---+-----------+ | |||
* | * | |||
* At most one "gettable" note (i.e., a note of type other than SRC_NEWLINE , | * At most one "gettable" note (i.e., a note of type other than SRC_NEWLINE , | |||
* SRC_SETLINE, and SRC_XDELTA) applies to a given bytecode. | * SRC_SETLINE, and SRC_XDELTA) applies to a given bytecode. | |||
* | * | |||
* NB: the js_SrcNoteSpec array in jsemit.c is indexed by this enum, so its | * NB: the js_SrcNoteSpec array in jsemit.c is indexed by this enum, so its | |||
* initializers need to match the order here. | * initializers need to match the order here. | |||
* | * | |||
* Note on adding new source notes: every pair of bytecodes (A, B) where A and | * Note on adding new source notes: every pair of bytecodes (A, B) where A and | |||
* B have disjoint sets of source notes that could apply to each bytecode m ay | * B have disjoint sets of source notes that could apply to each bytecode m ay | |||
* reuse the same note type value for two notes (snA, snB) that have the sa me | * reuse the same note type value for two notes (snA, snB) that have the sa me | |||
* arity, offsetBias, and isSpanDep initializers in js_SrcNoteSpec. This i | * arity, offsetBias, and isSpanDep initializers in js_SrcNoteSpec. This is | |||
s | * why SRC_IF and SRC_INITPROP have the same value below. For bad historica | |||
* why SRC_IF and SRC_INITPROP have the same value below. For bad historic | l | |||
al | ||||
* reasons, some bytecodes below that could be overlayed have not been, but | * reasons, some bytecodes below that could be overlayed have not been, but | |||
* before using SRC_EXTENDED, consider compressing the existing note types. | * before using SRC_EXTENDED, consider compressing the existing note types. | |||
* | * | |||
* Don't forget to update JSXDR_BYTECODE_VERSION in jsxdrapi.h for all such | * Don't forget to update JSXDR_BYTECODE_VERSION in jsxdrapi.h for all such | |||
* incompatible source note or other bytecode changes. | * incompatible source note or other bytecode changes. | |||
*/ | */ | |||
typedef enum JSSrcNoteType { | typedef enum JSSrcNoteType { | |||
SRC_NULL = 0, /* terminates a note vector */ | SRC_NULL = 0, /* terminates a note vector */ | |||
SRC_IF = 1, /* JSOP_IFEQ bytecode is from an if-then */ | SRC_IF = 1, /* JSOP_IFEQ bytecode is from an if-then */ | |||
SRC_INITPROP = 1, /* disjoint meaning applied to JSOP_INITELE M or | SRC_INITPROP = 1, /* disjoint meaning applied to JSOP_INITELE M or | |||
to an index label in a regular (structur ing) | to an index label in a regular (structur ing) | |||
or a destructuring object initialiser */ | or a destructuring object initialiser */ | |||
SRC_GENEXP = 1, /* JSOP_ANONFUNOBJ from generator expressio n */ | ||||
SRC_IF_ELSE = 2, /* JSOP_IFEQ bytecode is from an if-then-el se */ | SRC_IF_ELSE = 2, /* JSOP_IFEQ bytecode is from an if-then-el se */ | |||
SRC_WHILE = 3, /* JSOP_IFEQ is from a while loop */ | SRC_WHILE = 3, /* JSOP_IFEQ is from a while loop */ | |||
SRC_FOR = 4, /* JSOP_NOP or JSOP_POP in for loop head */ | SRC_FOR = 4, /* JSOP_NOP or JSOP_POP in for loop head */ | |||
SRC_CONTINUE = 5, /* JSOP_GOTO is a continue, not a break; | SRC_CONTINUE = 5, /* JSOP_GOTO is a continue, not a break; | |||
also used on JSOP_ENDINIT if extra comma | also used on JSOP_ENDINIT if extra comma | |||
at end of array literal: [1,2,,] */ | at end of array literal: [1,2,,] */ | |||
SRC_DECL = 6, /* type of a declaration (var, const, let*) */ | SRC_DECL = 6, /* type of a declaration (var, const, let*) */ | |||
SRC_DESTRUCT = 6, /* JSOP_DUP starting a destructuring assign ment | SRC_DESTRUCT = 6, /* JSOP_DUP starting a destructuring assign ment | |||
operation, with SRC_DECL_* offset operan d */ | operation, with SRC_DECL_* offset operan d */ | |||
SRC_PCDELTA = 7, /* distance forward from comma-operator to | SRC_PCDELTA = 7, /* distance forward from comma-operator to | |||
skipping to change at line 552 | skipping to change at line 580 | |||
opcode, etc. -- always a forward delta * / | opcode, etc. -- always a forward delta * / | |||
SRC_GROUPASSIGN = 7, /* SRC_DESTRUCT variant for [a, b] = [c, d] */ | SRC_GROUPASSIGN = 7, /* SRC_DESTRUCT variant for [a, b] = [c, d] */ | |||
SRC_ASSIGNOP = 8, /* += or another assign-op follows */ | SRC_ASSIGNOP = 8, /* += or another assign-op follows */ | |||
SRC_COND = 9, /* JSOP_IFEQ is from conditional ?: operato r */ | SRC_COND = 9, /* JSOP_IFEQ is from conditional ?: operato r */ | |||
SRC_BRACE = 10, /* mandatory brace, for scope or to avoid | SRC_BRACE = 10, /* mandatory brace, for scope or to avoid | |||
dangling else */ | dangling else */ | |||
SRC_HIDDEN = 11, /* opcode shouldn't be decompiled */ | SRC_HIDDEN = 11, /* opcode shouldn't be decompiled */ | |||
SRC_PCBASE = 12, /* distance back from annotated getprop or | SRC_PCBASE = 12, /* distance back from annotated getprop or | |||
setprop op to left-most obj.prop.subprop | setprop op to left-most obj.prop.subprop | |||
bytecode -- always a backward delta */ | bytecode -- always a backward delta */ | |||
SRC_METHODBASE = 13, /* SRC_PCBASE variant for obj.function::foo | ||||
gets and sets; disjoint from SRC_LABEL b | ||||
y | ||||
bytecode to which it applies */ | ||||
SRC_LABEL = 13, /* JSOP_NOP for label: with atomid immediat e */ | SRC_LABEL = 13, /* JSOP_NOP for label: with atomid immediat e */ | |||
SRC_LABELBRACE = 14, /* JSOP_NOP for label: {...} begin brace */ | SRC_LABELBRACE = 14, /* JSOP_NOP for label: {...} begin brace */ | |||
SRC_ENDBRACE = 15, /* JSOP_NOP for label: {...} end brace */ | SRC_ENDBRACE = 15, /* JSOP_NOP for label: {...} end brace */ | |||
SRC_BREAK2LABEL = 16, /* JSOP_GOTO for 'break label' with atomid */ | SRC_BREAK2LABEL = 16, /* JSOP_GOTO for 'break label' with atomid */ | |||
SRC_CONT2LABEL = 17, /* JSOP_GOTO for 'continue label' with atom id */ | SRC_CONT2LABEL = 17, /* JSOP_GOTO for 'continue label' with atom id */ | |||
SRC_SWITCH = 18, /* JSOP_*SWITCH with offset to end of switc h, | SRC_SWITCH = 18, /* JSOP_*SWITCH with offset to end of switc h, | |||
2nd off to first JSOP_CASE if condswitch */ | 2nd off to first JSOP_CASE if condswitch */ | |||
SRC_FUNCDEF = 19, /* JSOP_NOP for function f() with atomid */ | SRC_FUNCDEF = 19, /* JSOP_NOP for function f() with atomid */ | |||
SRC_CATCH = 20, /* catch block has guard */ | SRC_CATCH = 20, /* catch block has guard */ | |||
SRC_EXTENDED = 21, /* extended source note, 32-159, in next by te */ | SRC_EXTENDED = 21, /* extended source note, 32-159, in next by te */ | |||
SRC_NEWLINE = 22, /* bytecode follows a source newline */ | SRC_NEWLINE = 22, /* bytecode follows a source newline */ | |||
SRC_SETLINE = 23, /* a file-absolute source line number note */ | SRC_SETLINE = 23, /* a file-absolute source line number note */ | |||
SRC_XDELTA = 24 /* 24-31 are for extended delta notes */ | SRC_XDELTA = 24 /* 24-31 are for extended delta notes */ | |||
} JSSrcNoteType; | } JSSrcNoteType; | |||
/* | /* | |||
* Constants for the SRC_DECL source note. Note that span-dependent byteco de | * Constants for the SRC_DECL source note. Note that span-dependent bytecod e | |||
* selection means that any SRC_DECL offset greater than SRC_DECL_LET may n eed | * selection means that any SRC_DECL offset greater than SRC_DECL_LET may n eed | |||
* to be adjusted, but these "offsets" are too small to span a span-depende nt | * to be adjusted, but these "offsets" are too small to span a span-depende nt | |||
* instruction, so can be used to denote distinct declaration syntaxes to t he | * instruction, so can be used to denote distinct declaration syntaxes to t he | |||
* decompiler. | * decompiler. | |||
* | * | |||
* NB: the var_prefix array in jsopcode.c depends on these dense indexes fr om | * NB: the var_prefix array in jsopcode.c depends on these dense indexes fr om | |||
* SRC_DECL_VAR through SRC_DECL_LET. | * SRC_DECL_VAR through SRC_DECL_LET. | |||
*/ | */ | |||
#define SRC_DECL_VAR 0 | #define SRC_DECL_VAR 0 | |||
#define SRC_DECL_CONST 1 | #define SRC_DECL_CONST 1 | |||
skipping to change at line 600 | skipping to change at line 625 | |||
#define SN_XDELTA_MASK ((ptrdiff_t)JS_BITMASK(SN_XDELTA_BITS)) | #define SN_XDELTA_MASK ((ptrdiff_t)JS_BITMASK(SN_XDELTA_BITS)) | |||
#define SN_MAKE_NOTE(sn,t,d) (*(sn) = (jssrcnote) \ | #define SN_MAKE_NOTE(sn,t,d) (*(sn) = (jssrcnote) \ | |||
(((t) << SN_DELTA_BITS) \ | (((t) << SN_DELTA_BITS) \ | |||
| ((d) & SN_DELTA_MASK))) | | ((d) & SN_DELTA_MASK))) | |||
#define SN_MAKE_XDELTA(sn,d) (*(sn) = (jssrcnote) \ | #define SN_MAKE_XDELTA(sn,d) (*(sn) = (jssrcnote) \ | |||
((SRC_XDELTA << SN_DELTA_BITS) \ | ((SRC_XDELTA << SN_DELTA_BITS) \ | |||
| ((d) & SN_XDELTA_MASK))) | | ((d) & SN_XDELTA_MASK))) | |||
#define SN_IS_XDELTA(sn) ((*(sn) >> SN_DELTA_BITS) >= SRC_XDELTA) | #define SN_IS_XDELTA(sn) ((*(sn) >> SN_DELTA_BITS) >= SRC_XDELTA) | |||
#define SN_TYPE(sn) (SN_IS_XDELTA(sn) ? SRC_XDELTA | #define SN_TYPE(sn) ((JSSrcNoteType)(SN_IS_XDELTA(sn) | |||
\ | \ | |||
: *(sn) >> SN_DELTA_BITS) | ? SRC_XDELTA | |||
\ | ||||
: *(sn) >> SN_DELTA_BITS)) | ||||
#define SN_SET_TYPE(sn,type) SN_MAKE_NOTE(sn, type, SN_DELTA(sn)) | #define SN_SET_TYPE(sn,type) SN_MAKE_NOTE(sn, type, SN_DELTA(sn)) | |||
#define SN_IS_GETTABLE(sn) (SN_TYPE(sn) < SRC_NEWLINE) | #define SN_IS_GETTABLE(sn) (SN_TYPE(sn) < SRC_NEWLINE) | |||
#define SN_DELTA(sn) ((ptrdiff_t)(SN_IS_XDELTA(sn) \ | #define SN_DELTA(sn) ((ptrdiff_t)(SN_IS_XDELTA(sn) \ | |||
? *(sn) & SN_XDELTA_MASK \ | ? *(sn) & SN_XDELTA_MASK \ | |||
: *(sn) & SN_DELTA_MASK)) | : *(sn) & SN_DELTA_MASK)) | |||
#define SN_SET_DELTA(sn,delta) (SN_IS_XDELTA(sn) \ | #define SN_SET_DELTA(sn,delta) (SN_IS_XDELTA(sn) \ | |||
? SN_MAKE_XDELTA(sn, delta) \ | ? SN_MAKE_XDELTA(sn, delta) \ | |||
: SN_MAKE_NOTE(sn, SN_TYPE(sn), delta)) | : SN_MAKE_NOTE(sn, SN_TYPE(sn), delta)) | |||
skipping to change at line 644 | skipping to change at line 670 | |||
#define SN_LENGTH(sn) ((js_SrcNoteSpec[SN_TYPE(sn)].arity == 0) ? 1 \ | #define SN_LENGTH(sn) ((js_SrcNoteSpec[SN_TYPE(sn)].arity == 0) ? 1 \ | |||
: js_SrcNoteLength(sn)) | : js_SrcNoteLength(sn)) | |||
#define SN_NEXT(sn) ((sn) + SN_LENGTH(sn)) | #define SN_NEXT(sn) ((sn) + SN_LENGTH(sn)) | |||
/* A source note array is terminated by an all-zero element. */ | /* A source note array is terminated by an all-zero element. */ | |||
#define SN_MAKE_TERMINATOR(sn) (*(sn) = SRC_NULL) | #define SN_MAKE_TERMINATOR(sn) (*(sn) = SRC_NULL) | |||
#define SN_IS_TERMINATOR(sn) (*(sn) == SRC_NULL) | #define SN_IS_TERMINATOR(sn) (*(sn) == SRC_NULL) | |||
/* | /* | |||
* Append a new source note of the given type (and therefore size) to cg's | * Append a new source note of the given type (and therefore size) to cg's | |||
* notes dynamic array, updating cg->noteCount. Return the new note's inde | * notes dynamic array, updating cg->noteCount. Return the new note's index | |||
x | * within the array pointed at by cg->current->notes. Return -1 if out of | |||
* within the array pointed at by cg->current->notes. Return -1 if out of | ||||
* memory. | * memory. | |||
*/ | */ | |||
extern intN | extern intN | |||
js_NewSrcNote(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type); | js_NewSrcNote(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type); | |||
extern intN | extern intN | |||
js_NewSrcNote2(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type, | js_NewSrcNote2(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type, | |||
ptrdiff_t offset); | ptrdiff_t offset); | |||
extern intN | extern intN | |||
skipping to change at line 678 | skipping to change at line 704 | |||
*/ | */ | |||
extern JS_FRIEND_API(ptrdiff_t) | extern JS_FRIEND_API(ptrdiff_t) | |||
js_GetSrcNoteOffset(jssrcnote *sn, uintN which); | js_GetSrcNoteOffset(jssrcnote *sn, uintN which); | |||
extern JSBool | extern JSBool | |||
js_SetSrcNoteOffset(JSContext *cx, JSCodeGenerator *cg, uintN index, | js_SetSrcNoteOffset(JSContext *cx, JSCodeGenerator *cg, uintN index, | |||
uintN which, ptrdiff_t offset); | uintN which, ptrdiff_t offset); | |||
/* | /* | |||
* Finish taking source notes in cx's notePool, copying final notes to the new | * Finish taking source notes in cx's notePool, copying final notes to the new | |||
* stable store allocated by the caller and passed in via notes. Return fa lse | * stable store allocated by the caller and passed in via notes. Return fal se | |||
* on malloc failure, which means this function reported an error. | * on malloc failure, which means this function reported an error. | |||
* | * | |||
* To compute the number of jssrcnotes to allocate and pass in via notes, u se | * To compute the number of jssrcnotes to allocate and pass in via notes, u se | |||
* the CG_COUNT_FINAL_SRCNOTES macro. This macro knows a lot about details of | * the CG_COUNT_FINAL_SRCNOTES macro. This macro knows a lot about details of | |||
* js_FinishTakingSrcNotes, SO DON'T CHANGE jsemit.c's js_FinishTakingSrcNo tes | * js_FinishTakingSrcNotes, SO DON'T CHANGE jsemit.c's js_FinishTakingSrcNo tes | |||
* FUNCTION WITHOUT CHECKING WHETHER THIS MACRO NEEDS CORRESPONDING CHANGES ! | * FUNCTION WITHOUT CHECKING WHETHER THIS MACRO NEEDS CORRESPONDING CHANGES ! | |||
*/ | */ | |||
#define CG_COUNT_FINAL_SRCNOTES(cg, cnt) \ | #define CG_COUNT_FINAL_SRCNOTES(cg, cnt) \ | |||
JS_BEGIN_MACRO \ | JS_BEGIN_MACRO \ | |||
ptrdiff_t diff_ = CG_PROLOG_OFFSET(cg) - (cg)->prolog.lastNoteOffse t; \ | ptrdiff_t diff_ = CG_PROLOG_OFFSET(cg) - (cg)->prolog.lastNoteOffse t; \ | |||
cnt = (cg)->prolog.noteCount + (cg)->main.noteCount + 1; \ | cnt = (cg)->prolog.noteCount + (cg)->main.noteCount + 1; \ | |||
if ((cg)->prolog.noteCount && \ | if ((cg)->prolog.noteCount && \ | |||
(cg)->prolog.currentLine != (cg)->firstLine) { \ | (cg)->prolog.currentLine != (cg)->firstLine) { \ | |||
if (diff_ > SN_DELTA_MASK) \ | if (diff_ > SN_DELTA_MASK) \ | |||
skipping to change at line 710 | skipping to change at line 736 | |||
: SN_DELTA_MASK - (*sn_ & SN_DELTA_MASK); \ | : SN_DELTA_MASK - (*sn_ & SN_DELTA_MASK); \ | |||
} \ | } \ | |||
if (diff_ > 0) \ | if (diff_ > 0) \ | |||
cnt += JS_HOWMANY(diff_, SN_XDELTA_MASK); \ | cnt += JS_HOWMANY(diff_, SN_XDELTA_MASK); \ | |||
} \ | } \ | |||
JS_END_MACRO | JS_END_MACRO | |||
extern JSBool | extern JSBool | |||
js_FinishTakingSrcNotes(JSContext *cx, JSCodeGenerator *cg, jssrcnote *note s); | js_FinishTakingSrcNotes(JSContext *cx, JSCodeGenerator *cg, jssrcnote *note s); | |||
/* | ||||
* Allocate cg->treeContext.tryCount notes (plus one for the end sentinel) | ||||
* from cx->tempPool and set up cg->tryBase/tryNext for exactly tryCount | ||||
* js_NewTryNote calls. The storage is freed by js_FinishCodeGenerator. | ||||
*/ | ||||
extern JSBool | ||||
js_AllocTryNotes(JSContext *cx, JSCodeGenerator *cg); | ||||
/* | ||||
* Grab the next trynote slot in cg, filling it in appropriately. | ||||
*/ | ||||
extern JSTryNote * | ||||
js_NewTryNote(JSContext *cx, JSCodeGenerator *cg, ptrdiff_t start, | ||||
ptrdiff_t end, ptrdiff_t catchStart); | ||||
/* | ||||
* Finish generating exception information into the space at notes. As wit | ||||
h | ||||
* js_FinishTakingSrcNotes, the caller must use CG_COUNT_FINAL_TRYNOTES(cg) | ||||
to | ||||
* preallocate enough space in a JSTryNote[] to pass as the notes parameter | ||||
of | ||||
* js_FinishTakingTryNotes. | ||||
*/ | ||||
#define CG_COUNT_FINAL_TRYNOTES(cg, cnt) | ||||
\ | ||||
JS_BEGIN_MACRO | ||||
\ | ||||
cnt = ((cg)->tryNext > (cg)->tryBase) | ||||
\ | ||||
? PTRDIFF(cg->tryNext, cg->tryBase, JSTryNote) + 1 | ||||
\ | ||||
: 0; | ||||
\ | ||||
JS_END_MACRO | ||||
extern void | extern void | |||
js_FinishTakingTryNotes(JSContext *cx, JSCodeGenerator *cg, JSTryNote *note s); | js_FinishTakingTryNotes(JSCodeGenerator *cg, JSTryNoteArray *array); | |||
JS_END_EXTERN_C | JS_END_EXTERN_C | |||
#endif /* jsemit_h___ */ | #endif /* jsemit_h___ */ | |||
End of changes. 46 change blocks. | ||||
144 lines changed or deleted | 140 lines changed or added | |||
jsfun.h | jsfun.h | |||
---|---|---|---|---|
skipping to change at line 47 | skipping to change at line 47 | |||
* | * | |||
* ***** END LICENSE BLOCK ***** */ | * ***** END LICENSE BLOCK ***** */ | |||
#ifndef jsfun_h___ | #ifndef jsfun_h___ | |||
#define jsfun_h___ | #define jsfun_h___ | |||
/* | /* | |||
* JS function definitions. | * JS function definitions. | |||
*/ | */ | |||
#include "jsprvtd.h" | #include "jsprvtd.h" | |||
#include "jspubtd.h" | #include "jspubtd.h" | |||
#include "jsobj.h" | ||||
JS_BEGIN_EXTERN_C | JS_BEGIN_EXTERN_C | |||
typedef struct JSLocalNameMap JSLocalNameMap; | ||||
/* | ||||
* Depending on the number of arguments and variables in the function their | ||||
* names and attributes are stored either as a single atom or as an array o | ||||
f | ||||
* tagged atoms (when there are few locals) or as a hash-based map (when th | ||||
ere | ||||
* are many locals). In the first 2 cases the lowest bit of the atom is use | ||||
d | ||||
* as a tag to distinguish const from var. See jsfun.c for details. | ||||
*/ | ||||
typedef union JSLocalNames { | ||||
jsuword taggedAtom; | ||||
jsuword *array; | ||||
JSLocalNameMap *map; | ||||
} JSLocalNames; | ||||
struct JSFunction { | struct JSFunction { | |||
JSObject *object; /* back-pointer to GC'ed object header */ | JSObject object; /* GC'ed object header */ | |||
uint16 nargs; /* minimum number of actual arguments */ | uint16 nargs; /* maximum number of specified arguments, | |||
uint16 flags; /* bound method and other flags, see jsapi. | reflected as f.length/f.arity */ | |||
h */ | uint16 flags; /* bound method and other flags, see jsapi. | |||
h */ | ||||
union { | union { | |||
struct { | struct { | |||
uint16 extra; /* number of arg slots for local GC roots * | uint16 extra; /* number of arg slots for local GC roots * | |||
/ | / | |||
uint16 spare; /* reserved for future use */ | uint16 minargs;/* minimum number of specified arguments, u | |||
JSNative native; /* native method pointer or null */ | sed | |||
only when calling fast native */ | ||||
JSNative native; /* native method pointer or null */ | ||||
JSClass *clasp; /* if non-null, constructor for this class | ||||
*/ | ||||
} n; | } n; | |||
struct { | struct { | |||
uint16 nvars; /* number of local variables */ | uint16 nvars; /* number of local variables */ | |||
uint16 nregexps; /* number of regular expressions literals * | uint16 spare; /* reserved for future use */ | |||
/ | JSScript *script;/* interpreted bytecode descriptor or null | |||
JSScript *script; /* interpreted bytecode descriptor or null | */ | |||
*/ | JSLocalNames names; /* argument and variable names */ | |||
} i; | } i; | |||
} u; | } u; | |||
JSAtom *atom; /* name for diagnostics and decompiling */ | JSAtom *atom; /* name for diagnostics and decompiling */ | |||
JSClass *clasp; /* if non-null, constructor for this class | ||||
*/ | ||||
}; | }; | |||
#define JSFUN_EXPR_CLOSURE 0x4000 /* expression closure: function(x)x*x * / | ||||
#define JSFUN_INTERPRETED 0x8000 /* use u.i if set, u.n if unset */ | #define JSFUN_INTERPRETED 0x8000 /* use u.i if set, u.n if unset */ | |||
#define JSFUN_SCRIPT_OR_FAST_NATIVE (JSFUN_INTERPRETED | JSFUN_FAST_NATIVE) | ||||
#define FUN_OBJECT(fun) (&(fun)->object) | ||||
#define FUN_INTERPRETED(fun) ((fun)->flags & JSFUN_INTERPRETED) | #define FUN_INTERPRETED(fun) ((fun)->flags & JSFUN_INTERPRETED) | |||
#define FUN_NATIVE(fun) (FUN_INTERPRETED(fun) ? NULL : (fun)->u.n.nati ve) | #define FUN_SLOW_NATIVE(fun) (!((fun)->flags & JSFUN_SCRIPT_OR_FAST_NATIVE) ) | |||
#define FUN_SCRIPT(fun) (FUN_INTERPRETED(fun) ? (fun)->u.i.script : NU LL) | #define FUN_SCRIPT(fun) (FUN_INTERPRETED(fun) ? (fun)->u.i.script : NU LL) | |||
#define FUN_NATIVE(fun) (FUN_SLOW_NATIVE(fun) ? (fun)->u.n.native : NU | ||||
LL) | ||||
#define FUN_FAST_NATIVE(fun) (((fun)->flags & JSFUN_FAST_NATIVE) | ||||
\ | ||||
? (JSFastNative) (fun)->u.n.native | ||||
\ | ||||
: NULL) | ||||
#define FUN_MINARGS(fun) (((fun)->flags & JSFUN_FAST_NATIVE) | ||||
\ | ||||
? (fun)->u.n.minargs | ||||
\ | ||||
: (fun)->nargs) | ||||
extern JSClass js_ArgumentsClass; | extern JSClass js_ArgumentsClass; | |||
extern JSClass js_CallClass; | extern JS_FRIEND_DATA(JSClass) js_CallClass; | |||
/* JS_FRIEND_DATA so that VALUE_IS_FUNCTION is callable from the shell. */ | /* JS_FRIEND_DATA so that VALUE_IS_FUNCTION is callable from the shell. */ | |||
extern JS_FRIEND_DATA(JSClass) js_FunctionClass; | extern JS_FRIEND_DATA(JSClass) js_FunctionClass; | |||
#define HAS_FUNCTION_CLASS(obj) (STOBJ_GET_CLASS(obj) == &js_FunctionClass) | ||||
/* | /* | |||
* NB: jsapi.h and jsobj.h must be included before any call to this macro. | * NB: jsapi.h and jsobj.h must be included before any call to this macro. | |||
*/ | */ | |||
#define VALUE_IS_FUNCTION(cx, v) \ | #define VALUE_IS_FUNCTION(cx, v) \ | |||
(!JSVAL_IS_PRIMITIVE(v) && | (!JSVAL_IS_PRIMITIVE(v) && HAS_FUNCTION_CLASS(JSVAL_TO_OBJECT(v))) | |||
\ | ||||
OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_FunctionClass) | ||||
extern JSBool | ||||
js_fun_toString(JSContext *cx, JSObject *obj, uint32 indent, | ||||
uintN argc, jsval *argv, jsval *rval); | ||||
extern JSBool | /* | |||
js_IsIdentifier(JSString *str); | * Macro to access the private slot of the function object after the slot i | |||
s | ||||
* initialized. | ||||
*/ | ||||
#define GET_FUNCTION_PRIVATE(cx, funobj) | ||||
\ | ||||
(JS_ASSERT(HAS_FUNCTION_CLASS(funobj)), | ||||
\ | ||||
(JSFunction *) OBJ_GET_PRIVATE(cx, funobj)) | ||||
extern JSObject * | extern JSObject * | |||
js_InitFunctionClass(JSContext *cx, JSObject *obj); | js_InitFunctionClass(JSContext *cx, JSObject *obj); | |||
extern JSObject * | extern JSObject * | |||
js_InitArgumentsClass(JSContext *cx, JSObject *obj); | js_InitArgumentsClass(JSContext *cx, JSObject *obj); | |||
extern JSObject * | extern JSObject * | |||
js_InitCallClass(JSContext *cx, JSObject *obj); | js_InitCallClass(JSContext *cx, JSObject *obj); | |||
extern JSFunction * | extern JSFunction * | |||
js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, uintN narg s, | js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, uintN narg s, | |||
uintN flags, JSObject *parent, JSAtom *atom); | uintN flags, JSObject *parent, JSAtom *atom); | |||
extern void | ||||
js_TraceFunction(JSTracer *trc, JSFunction *fun); | ||||
extern void | ||||
js_FinalizeFunction(JSContext *cx, JSFunction *fun); | ||||
extern JSObject * | extern JSObject * | |||
js_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent); | js_CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent); | |||
extern JSBool | extern JSBool | |||
js_LinkFunctionObject(JSContext *cx, JSFunction *fun, JSObject *object); | js_LinkFunctionObject(JSContext *cx, JSFunction *fun, JSObject *object); | |||
extern JSFunction * | extern JSFunction * | |||
js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, JSNative nati ve, | js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, JSNative nati ve, | |||
uintN nargs, uintN flags); | uintN nargs, uintN flags); | |||
/* | /* | |||
* Flags for js_ValueToFunction and js_ReportIsNotFunction. We depend on t he | * Flags for js_ValueToFunction and js_ReportIsNotFunction. We depend on t he | |||
skipping to change at line 143 | skipping to change at line 181 | |||
extern JSObject * | extern JSObject * | |||
js_ValueToCallableObject(JSContext *cx, jsval *vp, uintN flags); | js_ValueToCallableObject(JSContext *cx, jsval *vp, uintN flags); | |||
extern void | extern void | |||
js_ReportIsNotFunction(JSContext *cx, jsval *vp, uintN flags); | js_ReportIsNotFunction(JSContext *cx, jsval *vp, uintN flags); | |||
extern JSObject * | extern JSObject * | |||
js_GetCallObject(JSContext *cx, JSStackFrame *fp, JSObject *parent); | js_GetCallObject(JSContext *cx, JSStackFrame *fp, JSObject *parent); | |||
extern JSBool | extern JS_FRIEND_API(JSBool) | |||
js_PutCallObject(JSContext *cx, JSStackFrame *fp); | js_PutCallObject(JSContext *cx, JSStackFrame *fp); | |||
extern JSBool | extern JSBool | |||
js_GetCallVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp); | js_GetCallArg(JSContext *cx, JSObject *obj, jsid id, jsval *vp); | |||
extern JSBool | extern JSBool | |||
js_SetCallVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp); | js_GetCallVar(JSContext *cx, JSObject *obj, jsval id, jsval *vp); | |||
extern JSBool | extern JSBool | |||
js_GetArgsValue(JSContext *cx, JSStackFrame *fp, jsval *vp); | js_GetArgsValue(JSContext *cx, JSStackFrame *fp, jsval *vp); | |||
extern JSBool | extern JSBool | |||
js_GetArgsProperty(JSContext *cx, JSStackFrame *fp, jsid id, | js_GetArgsProperty(JSContext *cx, JSStackFrame *fp, jsid id, jsval *vp); | |||
JSObject **objp, jsval *vp); | ||||
extern JSObject * | extern JSObject * | |||
js_GetArgsObject(JSContext *cx, JSStackFrame *fp); | js_GetArgsObject(JSContext *cx, JSStackFrame *fp); | |||
extern JSBool | extern JS_FRIEND_API(JSBool) | |||
js_PutArgsObject(JSContext *cx, JSStackFrame *fp); | js_PutArgsObject(JSContext *cx, JSStackFrame *fp); | |||
extern JSBool | extern JSBool | |||
js_XDRFunction(JSXDRState *xdr, JSObject **objp); | js_XDRFunction(JSXDRState *xdr, JSObject **objp); | |||
typedef enum JSLocalKind { | ||||
JSLOCAL_NONE, | ||||
JSLOCAL_ARG, | ||||
JSLOCAL_VAR, | ||||
JSLOCAL_CONST | ||||
} JSLocalKind; | ||||
#define JS_GET_LOCAL_NAME_COUNT(fun) ((fun)->nargs + (fun)->u.i.nvars) | ||||
extern JSBool | ||||
js_AddLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, JSLocalKind kind) | ||||
; | ||||
/* | ||||
* Look up an argument or variable name returning its kind when found or | ||||
* JSLOCAL_NONE when no such name exists. When indexp is not null and the n | ||||
ame | ||||
* exists, *indexp will receive the index of the corresponding argument or | ||||
* variable. | ||||
*/ | ||||
extern JSLocalKind | ||||
js_LookupLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, uintN *indexp) | ||||
; | ||||
/* | ||||
* Functions to work with local names as an array of words. | ||||
* | ||||
* js_GetLocalNameArray returns the array or null when it cannot be allocat | ||||
ed | ||||
* The function must be called only when JS_GET_LOCAL_NAME_COUNT(fun) is no | ||||
t | ||||
* zero. The function use the supplied pool to allocate the array. | ||||
* | ||||
* The elements of the array with index below fun->nargs correspond to the | ||||
* names of function arguments and of function variables otherwise. Use | ||||
* JS_LOCAL_NAME_TO_ATOM to convert array's element into an atom. It can be | ||||
* null when the element is an argument corresponding to a destructuring | ||||
* pattern. For a variable use JS_LOCAL_NAME_IS_CONST to check if it | ||||
* corresponds to the const declaration. | ||||
*/ | ||||
extern jsuword * | ||||
js_GetLocalNameArray(JSContext *cx, JSFunction *fun, struct JSArenaPool *po | ||||
ol); | ||||
#define JS_LOCAL_NAME_TO_ATOM(nameWord) | ||||
\ | ||||
((JSAtom *) ((nameWord) & ~(jsuword) 1)) | ||||
#define JS_LOCAL_NAME_IS_CONST(nameWord) | ||||
\ | ||||
((((nameWord) & (jsuword) 1)) != 0) | ||||
extern void | ||||
js_FreezeLocalNames(JSContext *cx, JSFunction *fun); | ||||
JS_END_EXTERN_C | JS_END_EXTERN_C | |||
#endif /* jsfun_h___ */ | #endif /* jsfun_h___ */ | |||
End of changes. 22 change blocks. | ||||
34 lines changed or deleted | 136 lines changed or added | |||
jsgc.h | jsgc.h | |||
---|---|---|---|---|
skipping to change at line 48 | skipping to change at line 48 | |||
* ***** END LICENSE BLOCK ***** */ | * ***** END LICENSE BLOCK ***** */ | |||
#ifndef jsgc_h___ | #ifndef jsgc_h___ | |||
#define jsgc_h___ | #define jsgc_h___ | |||
/* | /* | |||
* JS Garbage Collector. | * JS Garbage Collector. | |||
*/ | */ | |||
#include "jsprvtd.h" | #include "jsprvtd.h" | |||
#include "jspubtd.h" | #include "jspubtd.h" | |||
#include "jsdhash.h" | #include "jsdhash.h" | |||
#include "jsbit.h" | ||||
#include "jsutil.h" | #include "jsutil.h" | |||
JS_BEGIN_EXTERN_C | JS_BEGIN_EXTERN_C | |||
/* GC thing type indexes. */ | JS_STATIC_ASSERT(JSTRACE_STRING == 2); | |||
#define GCX_OBJECT 0 /* JSObject */ | ||||
#define GCX_STRING 1 /* JSString */ | ||||
#define GCX_DOUBLE 2 /* jsdouble */ | ||||
#define GCX_MUTABLE_STRING 3 /* JSString that's mutable | ||||
-- | ||||
single-threaded only! */ | ||||
#define GCX_PRIVATE 4 /* private (unscanned) data | ||||
*/ | ||||
#define GCX_NAMESPACE 5 /* JSXMLNamespace */ | ||||
#define GCX_QNAME 6 /* JSXMLQName */ | ||||
#define GCX_XML 7 /* JSXML */ | ||||
#define GCX_EXTERNAL_STRING 8 /* JSString w/ external cha | ||||
rs */ | ||||
#define GCX_NTYPES_LOG2 4 /* type index bits */ | #define JSTRACE_NAMESPACE 3 | |||
#define GCX_NTYPES JS_BIT(GCX_NTYPES_LOG2) | #define JSTRACE_QNAME 4 | |||
#define JSTRACE_XML 5 | ||||
/* | ||||
* One past the maximum trace kind. | ||||
*/ | ||||
#define JSTRACE_LIMIT 6 | ||||
/* | ||||
* We use the trace kinds as the types for all GC things except external | ||||
* strings. | ||||
*/ | ||||
#define GCX_OBJECT JSTRACE_OBJECT /* JSObject */ | ||||
#define GCX_DOUBLE JSTRACE_DOUBLE /* jsdouble */ | ||||
#define GCX_STRING JSTRACE_STRING /* JSString */ | ||||
#define GCX_NAMESPACE JSTRACE_NAMESPACE /* JSXMLNamespace */ | ||||
#define GCX_QNAME JSTRACE_QNAME /* JSXMLQName */ | ||||
#define GCX_XML JSTRACE_XML /* JSXML */ | ||||
#define GCX_EXTERNAL_STRING JSTRACE_LIMIT /* JSString with extern | ||||
al | ||||
chars */ | ||||
/* | ||||
* The number of defined GC types. | ||||
*/ | ||||
#define GCX_NTYPES (GCX_EXTERNAL_STRING + 8) | ||||
/* | ||||
* The maximum limit for the number of GC types. | ||||
*/ | ||||
#define GCX_LIMIT_LOG2 4 /* type index bits */ | ||||
#define GCX_LIMIT JS_BIT(GCX_LIMIT_LOG2) | ||||
JS_STATIC_ASSERT(GCX_NTYPES <= GCX_LIMIT); | ||||
/* GC flag definitions, must fit in 8 bits (type index goes in the low bits ). */ | /* GC flag definitions, must fit in 8 bits (type index goes in the low bits ). */ | |||
#define GCF_TYPEMASK JS_BITMASK(GCX_NTYPES_LOG2) | #define GCF_TYPEMASK JS_BITMASK(GCX_LIMIT_LOG2) | |||
#define GCF_MARK JS_BIT(GCX_NTYPES_LOG2) | #define GCF_MARK JS_BIT(GCX_LIMIT_LOG2) | |||
#define GCF_FINAL JS_BIT(GCX_NTYPES_LOG2 + 1) | #define GCF_FINAL JS_BIT(GCX_LIMIT_LOG2 + 1) | |||
#define GCF_SYSTEM JS_BIT(GCX_NTYPES_LOG2 + 2) | #define GCF_LOCKSHIFT (GCX_LIMIT_LOG2 + 2) /* lock bit shift */ | |||
#define GCF_LOCKSHIFT (GCX_NTYPES_LOG2 + 3) /* lock bit shift */ | ||||
#define GCF_LOCK JS_BIT(GCF_LOCKSHIFT) /* lock request bit in API */ | #define GCF_LOCK JS_BIT(GCF_LOCKSHIFT) /* lock request bit in API */ | |||
/* Pseudo-flag that modifies GCX_STRING to make GCX_MUTABLE_STRING. */ | /* | |||
#define GCF_MUTABLE 2 | * Get the type of the external string or -1 if the string was not created | |||
* with JS_NewExternalString. | ||||
#if (GCX_STRING | GCF_MUTABLE) != GCX_MUTABLE_STRING | */ | |||
# error "mutable string type index botch!" | extern intN | |||
#endif | js_GetExternalStringGCType(JSString *str); | |||
extern uint8 * | extern JS_FRIEND_API(uint32) | |||
js_GetGCThingFlags(void *thing); | js_GetGCThingTraceKind(void *thing); | |||
/* | /* | |||
* The sole purpose of the function is to preserve public API compatibility | * The sole purpose of the function is to preserve public API compatibility | |||
* in JS_GetStringBytes which takes only single JSString* argument. | * in JS_GetStringBytes which takes only single JSString* argument. | |||
*/ | */ | |||
JSRuntime* | JSRuntime* | |||
js_GetGCStringRuntime(JSString *str); | js_GetGCStringRuntime(JSString *str); | |||
#if 1 | #if 1 | |||
/* | /* | |||
* Since we're forcing a GC from JS_GC anyway, don't bother wasting cycles | * Since we're forcing a GC from JS_GC anyway, don't bother wasting cycles | |||
* loading oldval. XXX remove implied force, fix jsinterp.c's "second arg | * loading oldval. XXX remove implied force, fix jsinterp.c's "second arg | |||
* ignored", etc. | * ignored", etc. | |||
*/ | */ | |||
#define GC_POKE(cx, oldval) ((cx)->runtime->gcPoke = JS_TRUE) | #define GC_POKE(cx, oldval) ((cx)->runtime->gcPoke = JS_TRUE) | |||
#else | #else | |||
#define GC_POKE(cx, oldval) ((cx)->runtime->gcPoke = JSVAL_IS_GCTHING(oldva l)) | #define GC_POKE(cx, oldval) ((cx)->runtime->gcPoke = JSVAL_IS_GCTHING(oldva l)) | |||
#endif | #endif | |||
extern intN | /* | |||
js_ChangeExternalStringFinalizer(JSStringFinalizeOp oldop, | * Write barrier macro monitoring property update from oldval to newval in | |||
JSStringFinalizeOp newop); | * scope->object. | |||
* | ||||
* Since oldval is used only for the branded scope case, and the oldval act | ||||
ual | ||||
* argument expression is typically not used otherwise by callers, performa | ||||
nce | ||||
* benefits if oldval is *not* evaluated into a callsite temporary variable | ||||
, | ||||
* and instead passed to GC_WRITE_BARRIER for conditional evaluation (we re | ||||
ly | ||||
* on modern compilers to do a good CSE job). Yay, C macros. | ||||
*/ | ||||
#define GC_WRITE_BARRIER(cx,scope,oldval,newval) | ||||
\ | ||||
JS_BEGIN_MACRO | ||||
\ | ||||
if (SCOPE_IS_BRANDED(scope) && | ||||
\ | ||||
(oldval) != (newval) && | ||||
\ | ||||
(VALUE_IS_FUNCTION(cx,oldval) || VALUE_IS_FUNCTION(cx,newval))) | ||||
{ \ | ||||
SCOPE_MAKE_UNIQUE_SHAPE(cx, scope); | ||||
\ | ||||
} | ||||
\ | ||||
GC_POKE(cx, oldval); | ||||
\ | ||||
JS_END_MACRO | ||||
extern JSBool | extern JSBool | |||
js_InitGC(JSRuntime *rt, uint32 maxbytes); | js_InitGC(JSRuntime *rt, uint32 maxbytes); | |||
extern void | extern void | |||
js_FinishGC(JSRuntime *rt); | js_FinishGC(JSRuntime *rt); | |||
extern intN | ||||
js_ChangeExternalStringFinalizer(JSStringFinalizeOp oldop, | ||||
JSStringFinalizeOp newop); | ||||
extern JSBool | extern JSBool | |||
js_AddRoot(JSContext *cx, void *rp, const char *name); | js_AddRoot(JSContext *cx, void *rp, const char *name); | |||
extern JSBool | extern JSBool | |||
js_AddRootRT(JSRuntime *rt, void *rp, const char *name); | js_AddRootRT(JSRuntime *rt, void *rp, const char *name); | |||
extern JSBool | extern JSBool | |||
js_RemoveRoot(JSRuntime *rt, void *rp); | js_RemoveRoot(JSRuntime *rt, void *rp); | |||
#ifdef DEBUG | #ifdef DEBUG | |||
skipping to change at line 141 | skipping to change at line 182 | |||
/* Table of pointers with count valid members. */ | /* Table of pointers with count valid members. */ | |||
typedef struct JSPtrTable { | typedef struct JSPtrTable { | |||
size_t count; | size_t count; | |||
void **array; | void **array; | |||
} JSPtrTable; | } JSPtrTable; | |||
extern JSBool | extern JSBool | |||
js_RegisterCloseableIterator(JSContext *cx, JSObject *obj); | js_RegisterCloseableIterator(JSContext *cx, JSObject *obj); | |||
#if JS_HAS_GENERATORS | ||||
/* | ||||
* Runtime state to support generators' close hooks. | ||||
*/ | ||||
typedef struct JSGCCloseState { | ||||
/* | ||||
* Singly linked list of generators that are reachable from GC roots or | ||||
* were created after the last GC. | ||||
*/ | ||||
JSGenerator *reachableList; | ||||
/* | ||||
* Head of the queue of generators that have already become unreachable | ||||
but | ||||
* whose close hooks are not yet run. | ||||
*/ | ||||
JSGenerator *todoQueue; | ||||
#ifndef JS_THREADSAFE | ||||
/* | ||||
* Flag indicating that the current thread is excuting a close hook for | ||||
* single thread case. | ||||
*/ | ||||
JSBool runningCloseHook; | ||||
#endif | ||||
} JSGCCloseState; | ||||
extern void | ||||
js_RegisterGenerator(JSContext *cx, JSGenerator *gen); | ||||
extern JSBool | ||||
js_RunCloseHooks(JSContext *cx); | ||||
#endif | ||||
/* | /* | |||
* The private JSGCThing struct, which describes a gcFreeList element. | * The private JSGCThing struct, which describes a gcFreeList element. | |||
*/ | */ | |||
struct JSGCThing { | struct JSGCThing { | |||
JSGCThing *next; | JSGCThing *next; | |||
uint8 *flagp; | uint8 *flagp; | |||
}; | }; | |||
#define GC_NBYTES_MAX (10 * sizeof(JSGCThing)) | #define GC_NBYTES_MAX (10 * sizeof(JSGCThing)) | |||
#define GC_NUM_FREELISTS (GC_NBYTES_MAX / sizeof(JSGCThing)) | #define GC_NUM_FREELISTS (GC_NBYTES_MAX / sizeof(JSGCThing)) | |||
#define GC_FREELIST_NBYTES(i) (((i) + 1) * sizeof(JSGCThing)) | #define GC_FREELIST_NBYTES(i) (((i) + 1) * sizeof(JSGCThing)) | |||
#define GC_FREELIST_INDEX(n) (((n) / sizeof(JSGCThing)) - 1) | #define GC_FREELIST_INDEX(n) (((n) / sizeof(JSGCThing)) - 1) | |||
/* | ||||
* Allocates a new GC thing of the given size. After a successful allocatio | ||||
n | ||||
* the caller must fully initialize the thing before calling any function t | ||||
hat | ||||
* can potentially trigger GC. This will ensure that GC tracing never sees | ||||
junk | ||||
* values stored in the partially initialized thing. | ||||
*/ | ||||
extern void * | extern void * | |||
js_NewGCThing(JSContext *cx, uintN flags, size_t nbytes); | js_NewGCThing(JSContext *cx, uintN flags, size_t nbytes); | |||
/* | ||||
* Allocate a new double jsval and store the result in *vp. vp must be a ro | ||||
ot. | ||||
* The function does not copy the result into any weak root. | ||||
*/ | ||||
extern JSBool | extern JSBool | |||
js_LockGCThing(JSContext *cx, void *thing); | js_NewDoubleInRootedValue(JSContext *cx, jsdouble d, jsval *vp); | |||
/* | ||||
* Return a pointer to a new GC-allocated and weakly-rooted jsdouble number | ||||
, | ||||
* or null when the allocation fails. | ||||
*/ | ||||
extern jsdouble * | ||||
js_NewWeaklyRootedDouble(JSContext *cx, jsdouble d); | ||||
extern JSBool | extern JSBool | |||
js_LockGCThingRT(JSRuntime *rt, void *thing); | js_LockGCThingRT(JSRuntime *rt, void *thing); | |||
extern JSBool | extern JSBool | |||
js_UnlockGCThingRT(JSRuntime *rt, void *thing); | js_UnlockGCThingRT(JSRuntime *rt, void *thing); | |||
extern JSBool | extern JSBool | |||
js_IsAboutToBeFinalized(JSContext *cx, void *thing); | js_IsAboutToBeFinalized(JSContext *cx, void *thing); | |||
extern void | ||||
js_MarkAtom(JSContext *cx, JSAtom *atom); | ||||
/* We avoid a large number of unnecessary calls by doing the flag check fir | ||||
st */ | ||||
#define GC_MARK_ATOM(cx, atom) | ||||
\ | ||||
JS_BEGIN_MACRO | ||||
\ | ||||
if (!((atom)->flags & ATOM_MARK)) | ||||
\ | ||||
js_MarkAtom(cx, atom); | ||||
\ | ||||
JS_END_MACRO | ||||
/* | /* | |||
* Always use GC_MARK macro and never call js_MarkGCThing directly so | * Macro to test if a traversal is the marking phase of GC to avoid exposin | |||
* when GC_MARK_DEBUG is defined the dump of live GC things does not miss | g | |||
* a thing. | * ScriptFilenameEntry to traversal implementations. | |||
*/ | */ | |||
extern void | #define IS_GC_MARKING_TRACER(trc) ((trc)->callback == NULL) | |||
js_MarkGCThing(JSContext *cx, void *thing); | ||||
#ifdef GC_MARK_DEBUG | #if JS_HAS_XML_SUPPORT | |||
# define JS_IS_VALID_TRACE_KIND(kind) ((uint32)(kind) <= JSTRACE_XML) | ||||
#else | ||||
# define JS_IS_VALID_TRACE_KIND(kind) ((uint32)(kind) <= JSTRACE_STRING) | ||||
#endif | ||||
# define GC_MARK(cx, thing, name) js_MarkNamedGCThing(cx, thing, name) | /* | |||
* JS_IS_VALID_TRACE_KIND assumes that JSTRACE_STRING is the last non-xml | ||||
* trace kind when JS_HAS_XML_SUPPORT is false. | ||||
*/ | ||||
JS_STATIC_ASSERT(JSTRACE_STRING + 1 == JSTRACE_NAMESPACE); | ||||
/* | ||||
* Trace jsval when JSVAL_IS_OBJECT(v) can be an arbitrary GC thing casted | ||||
as | ||||
* JSVAL_OBJECT and js_GetGCThingTraceKind has to be used to find the real | ||||
* type behind v. | ||||
*/ | ||||
extern void | extern void | |||
js_MarkNamedGCThing(JSContext *cx, void *thing, const char *name); | js_CallValueTracerIfGCThing(JSTracer *trc, jsval v); | |||
extern JS_FRIEND_DATA(FILE *) js_DumpGCHeap; | ||||
JS_EXTERN_DATA(void *) js_LiveThingToFind; | ||||
#else | ||||
# define GC_MARK(cx, thing, name) js_MarkGCThing(cx, thing) | ||||
#endif | extern void | |||
js_TraceStackFrame(JSTracer *trc, JSStackFrame *fp); | ||||
extern void | extern void | |||
js_MarkStackFrame(JSContext *cx, JSStackFrame *fp); | js_TraceRuntime(JSTracer *trc, JSBool allAtoms); | |||
extern JS_FRIEND_API(void) | ||||
js_TraceContext(JSTracer *trc, JSContext *acx); | ||||
/* | /* | |||
* Kinds of js_GC invocation. | * Kinds of js_GC invocation. | |||
*/ | */ | |||
typedef enum JSGCInvocationKind { | typedef enum JSGCInvocationKind { | |||
/* Normal invocation. */ | /* Normal invocation. */ | |||
GC_NORMAL, | GC_NORMAL = 0, | |||
/* | /* | |||
* Called from js_DestroyContext for last JSContext in a JSRuntime, whe n | * Called from js_DestroyContext for last JSContext in a JSRuntime, whe n | |||
* it is imperative that rt->gcPoke gets cleared early in js_GC. | * it is imperative that rt->gcPoke gets cleared early in js_GC. | |||
*/ | */ | |||
GC_LAST_CONTEXT, | GC_LAST_CONTEXT = 1, | |||
/* | ||||
* Flag bit telling js_GC that the caller has already acquired rt->gcLo | ||||
ck. | ||||
* Currently, this flag is set for the invocation kinds that also prese | ||||
rve | ||||
* atoms and weak roots, so we don't need another bit for GC_KEEP_ATOMS | ||||
. | ||||
*/ | ||||
GC_LOCK_HELD = 0x10, | ||||
GC_KEEP_ATOMS = GC_LOCK_HELD, | ||||
/* | ||||
* Called from js_SetProtoOrParent with a request to set an object's pr | ||||
oto | ||||
* or parent slot inserted on rt->setSlotRequests. | ||||
*/ | ||||
GC_SET_SLOT_REQUEST = GC_LOCK_HELD | 1, | ||||
/* | /* | |||
* Called from js_NewGCThing as a last-ditch GC attempt. See comments | * Called from js_NewGCThing as a last-ditch GC attempt. See comments | |||
* before js_GC definition for details. | * in jsgc.c just before js_GC's definition for details. | |||
*/ | */ | |||
GC_LAST_DITCH | GC_LAST_DITCH = GC_LOCK_HELD | 2 | |||
} JSGCInvocationKind; | } JSGCInvocationKind; | |||
extern void | extern void | |||
js_GC(JSContext *cx, JSGCInvocationKind gckind); | js_GC(JSContext *cx, JSGCInvocationKind gckind); | |||
/* Call this after succesful malloc of memory for GC-related things. */ | /* Call this after succesful malloc of memory for GC-related things. */ | |||
extern void | extern void | |||
js_UpdateMallocCounter(JSContext *cx, size_t nbytes); | js_UpdateMallocCounter(JSContext *cx, size_t nbytes); | |||
typedef struct JSGCArenaInfo JSGCArenaInfo; | ||||
typedef struct JSGCArenaList JSGCArenaList; | ||||
typedef struct JSGCChunkInfo JSGCChunkInfo; | ||||
struct JSGCArenaList { | ||||
JSGCArenaInfo *last; /* last allocated GC arena */ | ||||
uint16 lastCount; /* number of allocated things in the la | ||||
st | ||||
arena */ | ||||
uint16 thingSize; /* size of things to allocate on this l | ||||
ist | ||||
*/ | ||||
JSGCThing *freeList; /* list of free GC things */ | ||||
}; | ||||
typedef union JSGCDoubleCell JSGCDoubleCell; | ||||
union JSGCDoubleCell { | ||||
double number; | ||||
JSGCDoubleCell *link; | ||||
}; | ||||
JS_STATIC_ASSERT(sizeof(JSGCDoubleCell) == sizeof(double)); | ||||
typedef struct JSGCDoubleArenaList { | ||||
JSGCArenaInfo *first; /* first allocated GC arena */ | ||||
jsbitmap *nextDoubleFlags; /* bitmask with flags to check for | ||||
free | ||||
things */ | ||||
} JSGCDoubleArenaList; | ||||
struct JSWeakRoots { | ||||
/* Most recently created things by type, members of the GC's root set. | ||||
*/ | ||||
void *newborn[GCX_NTYPES]; | ||||
/* Atom root for the last-looked-up atom on this context. */ | ||||
jsval lastAtom; | ||||
/* Root for the result of the most recent js_InternalInvoke call. */ | ||||
jsval lastInternalResult; | ||||
}; | ||||
JS_STATIC_ASSERT(JSVAL_NULL == 0); | ||||
#define JS_CLEAR_WEAK_ROOTS(wr) (memset((wr), 0, sizeof(JSWeakRoots))) | ||||
#ifdef DEBUG_notme | #ifdef DEBUG_notme | |||
#define JS_GCMETER 1 | #define JS_GCMETER 1 | |||
#endif | #endif | |||
#ifdef JS_GCMETER | #ifdef JS_GCMETER | |||
typedef struct JSGCArenaStats { | ||||
uint32 alloc; /* allocation attempts */ | ||||
uint32 localalloc; /* allocations from local lists */ | ||||
uint32 retry; /* allocation retries after running the GC */ | ||||
uint32 fail; /* allocation failures */ | ||||
uint32 nthings; /* live GC things */ | ||||
uint32 maxthings; /* maximum of live GC cells */ | ||||
double totalthings; /* live GC things the GC scanned so far */ | ||||
uint32 narenas; /* number of arena in list before the GC */ | ||||
uint32 newarenas; /* new arenas allocated before the last GC */ | ||||
uint32 livearenas; /* number of live arenas after the last GC */ | ||||
uint32 maxarenas; /* maximum of allocated arenas */ | ||||
uint32 totalarenas; /* total number of arenas with live things that | ||||
GC scanned so far */ | ||||
} JSGCArenaStats; | ||||
typedef struct JSGCStats { | typedef struct JSGCStats { | |||
#ifdef JS_THREADSAFE | ||||
uint32 localalloc; /* number of succeeded allocations from local lists | ||||
*/ | ||||
#endif | ||||
uint32 alloc; /* number of allocation attempts */ | ||||
uint32 retry; /* allocation attempt retries after running the GC | ||||
*/ | ||||
uint32 retryhalt; /* allocation retries halted by the branch callback | ||||
*/ | ||||
uint32 fail; /* allocation failures */ | ||||
uint32 finalfail; /* finalizer calls allocator failures */ | uint32 finalfail; /* finalizer calls allocator failures */ | |||
uint32 lockborn; /* things born locked */ | uint32 lockborn; /* things born locked */ | |||
uint32 lock; /* valid lock calls */ | uint32 lock; /* valid lock calls */ | |||
uint32 unlock; /* valid unlock calls */ | uint32 unlock; /* valid unlock calls */ | |||
uint32 depth; /* mark tail recursion depth */ | uint32 depth; /* mark tail recursion depth */ | |||
uint32 maxdepth; /* maximum mark tail recursion depth */ | uint32 maxdepth; /* maximum mark tail recursion depth */ | |||
uint32 cdepth; /* mark recursion depth of C functions */ | uint32 cdepth; /* mark recursion depth of C functions */ | |||
uint32 maxcdepth; /* maximum mark recursion depth of C functions */ | uint32 maxcdepth; /* maximum mark recursion depth of C functions */ | |||
uint32 unscanned; /* mark C stack overflows or number of times | uint32 untraced; /* number of times tracing of GC thing's children w | |||
GC things were put in unscanned bag */ | ere | |||
delayed due to a low C stack */ | ||||
#ifdef DEBUG | #ifdef DEBUG | |||
uint32 maxunscanned; /* maximum size of unscanned bag */ | uint32 maxuntraced;/* maximum number of things with children to trace | |||
later */ | ||||
#endif | #endif | |||
uint32 maxlevel; /* maximum GC nesting (indirect recursion) level */ | uint32 maxlevel; /* maximum GC nesting (indirect recursion) level */ | |||
uint32 poke; /* number of potentially useful GC calls */ | uint32 poke; /* number of potentially useful GC calls */ | |||
uint32 nopoke; /* useless GC calls where js_PokeGC was not set */ | ||||
uint32 afree; /* thing arenas freed so far */ | uint32 afree; /* thing arenas freed so far */ | |||
uint32 stackseg; /* total extraordinary stack segments scanned */ | uint32 stackseg; /* total extraordinary stack segments scanned */ | |||
uint32 segslots; /* total stack segment jsval slots scanned */ | uint32 segslots; /* total stack segment jsval slots scanned */ | |||
uint32 nclose; /* number of objects with close hooks */ | uint32 nclose; /* number of objects with close hooks */ | |||
uint32 maxnclose; /* max number of objects with close hooks */ | uint32 maxnclose; /* max number of objects with close hooks */ | |||
uint32 closelater; /* number of close hooks scheduled to run */ | uint32 closelater; /* number of close hooks scheduled to run */ | |||
uint32 maxcloselater; /* max number of close hooks scheduled to run */ | uint32 maxcloselater; /* max number of close hooks scheduled to run */ | |||
JSGCArenaStats arenaStats[GC_NUM_FREELISTS]; | ||||
JSGCArenaStats doubleArenaStats; | ||||
} JSGCStats; | } JSGCStats; | |||
extern JS_FRIEND_API(void) | extern JS_FRIEND_API(void) | |||
js_DumpGCStats(JSRuntime *rt, FILE *fp); | js_DumpGCStats(JSRuntime *rt, FILE *fp); | |||
#endif /* JS_GCMETER */ | #endif /* JS_GCMETER */ | |||
typedef struct JSGCArena JSGCArena; | ||||
typedef struct JSGCArenaList JSGCArenaList; | ||||
#ifdef JS_GCMETER | ||||
typedef struct JSGCArenaStats JSGCArenaStats; | ||||
struct JSGCArenaStats { | ||||
uint32 narenas; /* number of arena in list */ | ||||
uint32 maxarenas; /* maximun number of allocated arenas */ | ||||
uint32 nthings; /* number of allocates JSGCThing */ | ||||
uint32 maxthings; /* maximum number number of allocates JSGCThing | ||||
*/ | ||||
uint32 totalnew; /* number of succeeded calls to js_NewGCThing * | ||||
/ | ||||
uint32 freelen; /* freeList lengths */ | ||||
uint32 recycle; /* number of things recycled through freeList * | ||||
/ | ||||
uint32 totalarenas; /* total number of arenas with live things that | ||||
GC scanned so far */ | ||||
uint32 totalfreelen; /* total number of things that GC put to free | ||||
list so far */ | ||||
}; | ||||
#endif | ||||
struct JSGCArenaList { | ||||
JSGCArena *last; /* last allocated GC arena */ | ||||
uint16 lastLimit; /* end offset of allocated so far things in | ||||
the last arena */ | ||||
uint16 thingSize; /* size of things to allocate on this list | ||||
*/ | ||||
JSGCThing *freeList; /* list of free GC things */ | ||||
#ifdef JS_GCMETER | ||||
JSGCArenaStats stats; | ||||
#endif | ||||
}; | ||||
typedef struct JSWeakRoots { | ||||
/* Most recently created things by type, members of the GC's root set. | ||||
*/ | ||||
JSGCThing *newborn[GCX_NTYPES]; | ||||
/* Atom root for the last-looked-up atom on this context. */ | ||||
JSAtom *lastAtom; | ||||
/* Root for the result of the most recent js_InternalInvoke call. */ | ||||
jsval lastInternalResult; | ||||
} JSWeakRoots; | ||||
JS_STATIC_ASSERT(JSVAL_NULL == 0); | ||||
#define JS_CLEAR_WEAK_ROOTS(wr) (memset((wr), 0, sizeof(JSWeakRoots))) | ||||
#ifdef DEBUG_notme | ||||
#define TOO_MUCH_GC 1 | ||||
#endif | ||||
#ifdef WAY_TOO_MUCH_GC | ||||
#define TOO_MUCH_GC 1 | ||||
#endif | ||||
JS_END_EXTERN_C | JS_END_EXTERN_C | |||
#endif /* jsgc_h___ */ | #endif /* jsgc_h___ */ | |||
End of changes. 33 change blocks. | ||||
178 lines changed or deleted | 225 lines changed or added | |||
jshash.h | jshash.h | |||
---|---|---|---|---|
skipping to change at line 94 | skipping to change at line 94 | |||
struct JSHashTable { | struct JSHashTable { | |||
JSHashEntry **buckets; /* vector of hash buckets */ | JSHashEntry **buckets; /* vector of hash buckets */ | |||
uint32 nentries; /* number of entries in table */ | uint32 nentries; /* number of entries in table */ | |||
uint32 shift; /* multiplicative hash shift */ | uint32 shift; /* multiplicative hash shift */ | |||
JSHashFunction keyHash; /* key hash function */ | JSHashFunction keyHash; /* key hash function */ | |||
JSHashComparator keyCompare; /* key comparison function */ | JSHashComparator keyCompare; /* key comparison function */ | |||
JSHashComparator valueCompare; /* value comparison function */ | JSHashComparator valueCompare; /* value comparison function */ | |||
JSHashAllocOps *allocOps; /* allocation operations */ | JSHashAllocOps *allocOps; /* allocation operations */ | |||
void *allocPriv; /* allocation private data */ | void *allocPriv; /* allocation private data */ | |||
#ifdef HASHMETER | #ifdef JS_HASHMETER | |||
uint32 nlookups; /* total number of lookups */ | uint32 nlookups; /* total number of lookups */ | |||
uint32 nsteps; /* number of hash chains traversed */ | uint32 nsteps; /* number of hash chains traversed */ | |||
uint32 ngrows; /* number of table expansions */ | uint32 ngrows; /* number of table expansions */ | |||
uint32 nshrinks; /* number of table contractions */ | uint32 nshrinks; /* number of table contractions */ | |||
#endif | #endif | |||
}; | }; | |||
/* | /* | |||
* Create a new hash table. | * Create a new hash table. | |||
* If allocOps is null, use default allocator ops built on top of malloc(). | * If allocOps is null, use default allocator ops built on top of malloc(). | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
jsinterp.h | jsinterp.h | |||
---|---|---|---|---|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- | |||
* vim: set ts=8 sw=4 et tw=78: | ||||
* | * | |||
* ***** BEGIN LICENSE BLOCK ***** | * ***** BEGIN LICENSE BLOCK ***** | |||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | |||
* | * | |||
* The contents of this file are subject to the Mozilla Public License Vers ion | * The contents of this file are subject to the Mozilla Public License Vers ion | |||
* 1.1 (the "License"); you may not use this file except in compliance with | * 1.1 (the "License"); you may not use this file except in compliance with | |||
* the License. You may obtain a copy of the License at | * the License. You may obtain a copy of the License at | |||
* http://www.mozilla.org/MPL/ | * http://www.mozilla.org/MPL/ | |||
* | * | |||
* Software distributed under the License is distributed on an "AS IS" basi s, | * Software distributed under the License is distributed on an "AS IS" basi s, | |||
skipping to change at line 47 | skipping to change at line 48 | |||
* | * | |||
* ***** END LICENSE BLOCK ***** */ | * ***** END LICENSE BLOCK ***** */ | |||
#ifndef jsinterp_h___ | #ifndef jsinterp_h___ | |||
#define jsinterp_h___ | #define jsinterp_h___ | |||
/* | /* | |||
* JS interpreter interface. | * JS interpreter interface. | |||
*/ | */ | |||
#include "jsprvtd.h" | #include "jsprvtd.h" | |||
#include "jspubtd.h" | #include "jspubtd.h" | |||
#include "jsopcode.h" | ||||
JS_BEGIN_EXTERN_C | JS_BEGIN_EXTERN_C | |||
typedef struct JSFrameRegs { | ||||
jsbytecode *pc; /* program counter */ | ||||
jsval *sp; /* stack pointer */ | ||||
} JSFrameRegs; | ||||
/* | /* | |||
* JS stack frame, may be allocated on the C stack by native callers. Alwa ys | * JS stack frame, may be allocated on the C stack by native callers. Alwa ys | |||
* allocated on cx->stackPool for calls from the interpreter to an interpre ted | * allocated on cx->stackPool for calls from the interpreter to an interpre ted | |||
* function. | * function. | |||
* | * | |||
* NB: This struct is manually initialized in jsinterp.c and jsiter.c. If you | * NB: This struct is manually initialized in jsinterp.c and jsiter.c. If you | |||
* add new members, update both files. But first, try to remove members. The | * add new members, update both files. But first, try to remove members. The | |||
* sharp* and xml* members should be moved onto the stack as local variable s | * sharp* and xml* members should be moved onto the stack as local variable s | |||
* with well-known slots, if possible. | * with well-known slots, if possible. | |||
*/ | */ | |||
struct JSStackFrame { | struct JSStackFrame { | |||
JSFrameRegs *regs; | ||||
jsval *spbase; /* operand stack base */ | ||||
JSObject *callobj; /* lazily created Call object */ | JSObject *callobj; /* lazily created Call object */ | |||
JSObject *argsobj; /* lazily created arguments object */ | JSObject *argsobj; /* lazily created arguments object */ | |||
JSObject *varobj; /* variables object, where vars go */ | JSObject *varobj; /* variables object, where vars go */ | |||
JSObject *callee; /* function or script object */ | ||||
JSScript *script; /* script being interpreted */ | JSScript *script; /* script being interpreted */ | |||
JSFunction *fun; /* function being called or null */ | JSFunction *fun; /* function being called or null */ | |||
JSObject *thisp; /* "this" pointer if in method */ | JSObject *thisp; /* "this" pointer if in method */ | |||
uintN argc; /* actual argument count */ | uintN argc; /* actual argument count */ | |||
jsval *argv; /* base of argument stack slots */ | jsval *argv; /* base of argument stack slots */ | |||
jsval rval; /* function return value */ | jsval rval; /* function return value */ | |||
uintN nvars; /* local variable count */ | uintN nvars; /* local variable count */ | |||
jsval *vars; /* base of variable stack slots */ | jsval *vars; /* base of variable stack slots */ | |||
JSStackFrame *down; /* previous frame */ | JSStackFrame *down; /* previous frame */ | |||
void *annotation; /* used by Java security */ | void *annotation; /* used by Java security */ | |||
JSObject *scopeChain; /* scope chain */ | JSObject *scopeChain; /* scope chain */ | |||
jsbytecode *pc; /* program counter */ | ||||
jsval *sp; /* stack pointer */ | ||||
jsval *spbase; /* operand stack base */ | ||||
uintN sharpDepth; /* array/object initializer depth */ | uintN sharpDepth; /* array/object initializer depth */ | |||
JSObject *sharpArray; /* scope for #n= initializer vars */ | JSObject *sharpArray; /* scope for #n= initializer vars */ | |||
uint32 flags; /* frame flags -- see below */ | uint32 flags; /* frame flags -- see below */ | |||
JSStackFrame *dormantNext; /* next dormant frame chain */ | JSStackFrame *dormantNext; /* next dormant frame chain */ | |||
JSObject *xmlNamespace; /* null or default xml namespace in E4X */ | JSObject *xmlNamespace; /* null or default xml namespace in E4X */ | |||
JSObject *blockChain; /* active compile-time block scopes */ | JSObject *blockChain; /* active compile-time block scopes */ | |||
#ifdef DEBUG | ||||
jsrefcount pcDisabledSave; /* for balanced property cache control | ||||
*/ | ||||
#endif | ||||
}; | }; | |||
typedef struct JSInlineFrame { | typedef struct JSInlineFrame { | |||
JSStackFrame frame; /* base struct */ | JSStackFrame frame; /* base struct */ | |||
jsval *rvp; /* ptr to caller's return value slot */ | JSFrameRegs callerRegs; /* parent's frame registers */ | |||
void *mark; /* mark before inline frame */ | void *mark; /* mark before inline frame */ | |||
void *hookData; /* debugger call hook data */ | void *hookData; /* debugger call hook data */ | |||
JSVersion callerVersion; /* dynamic version of calling script */ | JSVersion callerVersion; /* dynamic version of calling script */ | |||
} JSInlineFrame; | } JSInlineFrame; | |||
/* JS stack frame flags. */ | /* JS stack frame flags. */ | |||
#define JSFRAME_CONSTRUCTING 0x01 /* frame is for a constructor invocatio | #define JSFRAME_CONSTRUCTING 0x01 /* frame is for a constructor invocatio | |||
n */ | n */ | |||
#define JSFRAME_INTERNAL 0x02 /* internal call, not invoked by a scri | #define JSFRAME_COMPUTED_THIS 0x02 /* frame.thisp was computed already */ | |||
pt */ | #define JSFRAME_ASSIGNING 0x04 /* a complex (not simplex JOF_ASSIGNING | |||
#define JSFRAME_SKIP_CALLER 0x04 /* skip one link when evaluating f.call | ) op | |||
er | ||||
for this invocation of f */ | ||||
#define JSFRAME_ASSIGNING 0x08 /* a complex (not simplex JOF_ASSIGNING | ||||
) op | ||||
is currently assigning to a property */ | is currently assigning to a property */ | |||
#define JSFRAME_DEBUGGER 0x10 /* frame for JS_EvaluateInStackFrame */ | #define JSFRAME_DEBUGGER 0x08 /* frame for JS_EvaluateInStackFrame */ | |||
#define JSFRAME_EVAL 0x20 /* frame for obj_eval */ | #define JSFRAME_EVAL 0x10 /* frame for obj_eval */ | |||
#define JSFRAME_SPECIAL 0x30 /* special evaluation frame flags */ | #define JSFRAME_SCRIPT_OBJECT 0x20 /* compiling source for a Script object | |||
#define JSFRAME_COMPILING 0x40 /* frame is being used by compiler */ | */ | |||
#define JSFRAME_COMPILE_N_GO 0x80 /* compiler-and-go mode, can optimize n | #define JSFRAME_YIELDING 0x40 /* js_Interpret dispatched JSOP_YIELD * | |||
ame | / | |||
references based on scope chain */ | #define JSFRAME_ITERATOR 0x80 /* trying to get an iterator for for-in | |||
#define JSFRAME_SCRIPT_OBJECT 0x100 /* compiling source for a Script object | */ | |||
*/ | #define JSFRAME_POP_BLOCKS 0x100 /* scope chain contains blocks to pop * | |||
#define JSFRAME_YIELDING 0x200 /* js_Interpret dispatched JSOP_YIELD * | / | |||
/ | #define JSFRAME_GENERATOR 0x200 /* frame belongs to generator-iterator | |||
#define JSFRAME_FILTERING 0x400 /* XML filtering predicate expression * | */ | |||
/ | #define JSFRAME_ROOTED_ARGV 0x400 /* frame.argv is rooted by the caller * | |||
#define JSFRAME_ITERATOR 0x800 /* trying to get an iterator for for-in | / | |||
*/ | ||||
#define JSFRAME_POP_BLOCKS 0x1000 /* scope chain contains blocks to pop * | ||||
/ | ||||
#define JSFRAME_GENERATOR 0x2000 /* frame belongs to generator-iterator | ||||
*/ | ||||
#define JSFRAME_OVERRIDE_SHIFT 24 /* override bit-set params; see jsfun.c */ | #define JSFRAME_OVERRIDE_SHIFT 24 /* override bit-set params; see jsfun.c */ | |||
#define JSFRAME_OVERRIDE_BITS 8 | #define JSFRAME_OVERRIDE_BITS 8 | |||
#define JSFRAME_SPECIAL (JSFRAME_DEBUGGER | JSFRAME_EVAL) | ||||
/* | /* | |||
* Property cache for quickened get/set property opcodes. | * Property cache with structurally typed capabilities for invalidation, fo | |||
r | ||||
* polymorphic callsite method/get/set speedups. | ||||
* | ||||
* See bug https://bugzilla.mozilla.org/show_bug.cgi?id=365851. | ||||
*/ | */ | |||
#define PROPERTY_CACHE_LOG2 10 | #define PROPERTY_CACHE_LOG2 12 | |||
#define PROPERTY_CACHE_SIZE JS_BIT(PROPERTY_CACHE_LOG2) | #define PROPERTY_CACHE_SIZE JS_BIT(PROPERTY_CACHE_LOG2) | |||
#define PROPERTY_CACHE_MASK JS_BITMASK(PROPERTY_CACHE_LOG2) | #define PROPERTY_CACHE_MASK JS_BITMASK(PROPERTY_CACHE_LOG2) | |||
#define PROPERTY_CACHE_HASH(obj, id) \ | #define PROPERTY_CACHE_HASH(pc,kshape) | |||
((((jsuword)(obj) >> JSVAL_TAGBITS) ^ (jsuword)(id)) & PROPERTY_CACHE_M | \ | |||
ASK) | ((((jsuword)(pc) >> PROPERTY_CACHE_LOG2) ^ (jsuword)(pc) ^ (kshape)) & | |||
\ | ||||
#ifdef JS_THREADSAFE | PROPERTY_CACHE_MASK) | |||
#if HAVE_ATOMIC_DWORD_ACCESS | ||||
#define PCE_LOAD(cache, pce, entry) JS_ATOMIC_DWORD_LOAD(pce, entry) | #define PROPERTY_CACHE_HASH_PC(pc,kshape) | |||
#define PCE_STORE(cache, pce, entry) JS_ATOMIC_DWORD_STORE(pce, entry) | \ | |||
PROPERTY_CACHE_HASH(pc, kshape) | ||||
#else /* !HAVE_ATOMIC_DWORD_ACCESS */ | #define PROPERTY_CACHE_HASH_ATOM(atom,obj,pobj) | |||
\ | ||||
PROPERTY_CACHE_HASH((jsuword)(atom) >> 2, OBJ_SCOPE(obj)->shape) | ||||
#define JS_PROPERTY_CACHE_METERING 1 | /* | |||
* Property cache value capability macros. | ||||
*/ | ||||
#define PCVCAP_PROTOBITS 4 | ||||
#define PCVCAP_PROTOSIZE JS_BIT(PCVCAP_PROTOBITS) | ||||
#define PCVCAP_PROTOMASK JS_BITMASK(PCVCAP_PROTOBITS) | ||||
#define PCE_LOAD(cache, pce, entry) | #define PCVCAP_SCOPEBITS 4 | |||
\ | #define PCVCAP_SCOPESIZE JS_BIT(PCVCAP_SCOPEBITS) | |||
JS_BEGIN_MACRO | #define PCVCAP_SCOPEMASK JS_BITMASK(PCVCAP_SCOPEBITS) | |||
\ | ||||
uint32 prefills_; | ||||
\ | ||||
uint32 fills_ = (cache)->fills; | ||||
\ | ||||
do { | ||||
\ | ||||
/* Load until cache->fills is stable (see FILL macro below). */ | ||||
\ | ||||
prefills_ = fills_; | ||||
\ | ||||
(entry) = *(pce); | ||||
\ | ||||
} while ((fills_ = (cache)->fills) != prefills_); | ||||
\ | ||||
JS_END_MACRO | ||||
#define PCE_STORE(cache, pce, entry) | #define PCVCAP_TAGBITS (PCVCAP_PROTOBITS + PCVCAP_SCOPEBITS) | |||
\ | #define PCVCAP_TAGMASK JS_BITMASK(PCVCAP_TAGBITS) | |||
JS_BEGIN_MACRO | #define PCVCAP_TAG(t) ((t) & PCVCAP_TAGMASK) | |||
\ | ||||
do { | ||||
\ | ||||
/* Store until no racing collider stores half or all of pce. */ | ||||
\ | ||||
*(pce) = (entry); | ||||
\ | ||||
} while (PCE_OBJECT(*pce) != PCE_OBJECT(entry) || | ||||
\ | ||||
PCE_PROPERTY(*pce) != PCE_PROPERTY(entry)); | ||||
\ | ||||
JS_END_MACRO | ||||
#endif /* !HAVE_ATOMIC_DWORD_ACCESS */ | #define PCVCAP_MAKE(t,s,p) (((t) << PCVCAP_TAGBITS) | | |||
\ | ||||
((s) << PCVCAP_PROTOBITS) | | ||||
\ | ||||
(p)) | ||||
#define PCVCAP_SHAPE(t) ((t) >> PCVCAP_TAGBITS) | ||||
#else /* !JS_THREADSAFE */ | #define SHAPE_OVERFLOW_BIT JS_BIT(32 - PCVCAP_TAGBITS) | |||
#define PCE_LOAD(cache, pce, entry) ((entry) = *(pce)) | /* | |||
#define PCE_STORE(cache, pce, entry) (*(pce) = (entry)) | * When sprop is not null and the shape generation triggers the GC due to a | |||
* shape overflow, the functions roots sprop. | ||||
*/ | ||||
extern uint32 | ||||
js_GenerateShape(JSContext *cx, JSBool gcLocked, JSScopeProperty *sprop); | ||||
#endif /* !JS_THREADSAFE */ | struct JSPropCacheEntry { | |||
jsbytecode *kpc; /* pc if vcap tag is <= 1, else ato | ||||
m */ | ||||
jsuword kshape; /* key shape if pc, else obj for at | ||||
om */ | ||||
jsuword vcap; /* value capability, see above */ | ||||
jsuword vword; /* value word, see PCVAL_* below */ | ||||
}; | ||||
typedef union JSPropertyCacheEntry { | #if defined DEBUG_brendan || defined DEBUG_brendaneich | |||
struct { | #define JS_PROPERTY_CACHE_METERING 1 | |||
JSObject *object; /* weak link to object */ | ||||
JSScopeProperty *property; /* weak link to property */ | ||||
} s; | ||||
#ifdef HAVE_ATOMIC_DWORD_ACCESS | ||||
prdword align; | ||||
#endif | #endif | |||
} JSPropertyCacheEntry; | ||||
/* These may be called in lvalue or rvalue position. */ | ||||
#define PCE_OBJECT(entry) ((entry).s.object) | ||||
#define PCE_PROPERTY(entry) ((entry).s.property) | ||||
typedef struct JSPropertyCache { | typedef struct JSPropertyCache { | |||
JSPropertyCacheEntry table[PROPERTY_CACHE_SIZE]; | JSPropCacheEntry table[PROPERTY_CACHE_SIZE]; | |||
JSBool empty; | JSBool empty; | |||
JSBool disabled; | jsrefcount disabled; /* signed for anti-underflow assert | |||
s */ | ||||
#ifdef JS_PROPERTY_CACHE_METERING | #ifdef JS_PROPERTY_CACHE_METERING | |||
uint32 fills; | uint32 fills; /* number of cache entry fills */ | |||
uint32 recycles; | uint32 nofills; /* couldn't fill (e.g. default get) | |||
uint32 tests; | */ | |||
uint32 misses; | uint32 rofills; /* set on read-only prop can't fill | |||
uint32 flushes; | */ | |||
# define PCMETER(x) x | uint32 disfills; /* fill attempts on disabled cache | |||
*/ | ||||
uint32 oddfills; /* fill attempt after setter delete | ||||
d */ | ||||
uint32 modfills; /* fill that rehashed to a new entr | ||||
y */ | ||||
uint32 brandfills; /* scope brandings to type structur | ||||
al | ||||
method fills */ | ||||
uint32 noprotos; /* resolve-returned non-proto pobj | ||||
*/ | ||||
uint32 longchains; /* overlong scope and/or proto chai | ||||
n */ | ||||
uint32 recycles; /* cache entries recycled by fills | ||||
*/ | ||||
uint32 pcrecycles; /* pc-keyed entries recycled by ato | ||||
m- | ||||
keyed fills */ | ||||
uint32 tests; /* cache probes */ | ||||
uint32 pchits; /* fast-path polymorphic op hits */ | ||||
uint32 protopchits; /* pchits hitting immediate prototy | ||||
pe */ | ||||
uint32 initests; /* cache probes from JSOP_INITPROP | ||||
*/ | ||||
uint32 inipchits; /* init'ing next property pchit cas | ||||
e */ | ||||
uint32 inipcmisses; /* init'ing next property pc misses | ||||
*/ | ||||
uint32 settests; /* cache probes from JOF_SET opcode | ||||
s */ | ||||
uint32 addpchits; /* adding next property pchit case | ||||
*/ | ||||
uint32 setpchits; /* setting existing property pchit | ||||
*/ | ||||
uint32 setpcmisses; /* setting/adding property pc misse | ||||
s */ | ||||
uint32 slotchanges; /* clasp->reserveSlots result varia | ||||
nce- | ||||
induced slot changes */ | ||||
uint32 setmisses; /* JSOP_SET{NAME,PROP} total misses | ||||
*/ | ||||
uint32 idmisses; /* slow-path key id == atom misses | ||||
*/ | ||||
uint32 komisses; /* slow-path key object misses */ | ||||
uint32 vcmisses; /* value capability misses */ | ||||
uint32 misses; /* cache misses */ | ||||
uint32 flushes; /* cache flushes */ | ||||
# define PCMETER(x) x | ||||
#else | #else | |||
# define PCMETER(x) /* nothing */ | # define PCMETER(x) ((void)0) | |||
#endif | #endif | |||
} JSPropertyCache; | } JSPropertyCache; | |||
#define PROPERTY_CACHE_FILL(cache, obj, id, sprop) | /* | |||
\ | * Property cache value tagging/untagging macros. | |||
JS_BEGIN_MACRO | */ | |||
\ | #define PCVAL_OBJECT 0 | |||
JSPropertyCache *cache_ = (cache); | #define PCVAL_SLOT 1 | |||
\ | #define PCVAL_SPROP 2 | |||
if (!cache_->disabled) { | ||||
\ | ||||
uintN hashIndex_ = (uintN) PROPERTY_CACHE_HASH(obj, id); | ||||
\ | ||||
JSPropertyCacheEntry *pce_ = &cache_->table[hashIndex_]; | ||||
\ | ||||
JSPropertyCacheEntry entry_; | ||||
\ | ||||
JSScopeProperty *pce_sprop_; | ||||
\ | ||||
PCE_LOAD(cache_, pce_, entry_); | ||||
\ | ||||
pce_sprop_ = PCE_PROPERTY(entry_); | ||||
\ | ||||
PCMETER(if (pce_sprop_ && pce_sprop_ != sprop) | ||||
\ | ||||
cache_->recycles++); | ||||
\ | ||||
PCE_OBJECT(entry_) = obj; | ||||
\ | ||||
PCE_PROPERTY(entry_) = sprop; | ||||
\ | ||||
cache_->empty = JS_FALSE; | ||||
\ | ||||
PCMETER(cache_->fills++); | ||||
\ | ||||
PCE_STORE(cache_, pce_, entry_); | ||||
\ | ||||
} | ||||
\ | ||||
JS_END_MACRO | ||||
#define PROPERTY_CACHE_TEST(cache, obj, id, sprop) | #define PCVAL_TAGBITS 2 | |||
\ | #define PCVAL_TAGMASK JS_BITMASK(PCVAL_TAGBITS) | |||
JS_BEGIN_MACRO | #define PCVAL_TAG(v) ((v) & PCVAL_TAGMASK) | |||
\ | #define PCVAL_CLRTAG(v) ((v) & ~(jsuword)PCVAL_TAGMASK) | |||
uintN hashIndex_ = (uintN) PROPERTY_CACHE_HASH(obj, id); | #define PCVAL_SETTAG(v,t) ((jsuword)(v) | (t)) | |||
\ | ||||
JSPropertyCache *cache_ = (cache); | #define PCVAL_NULL 0 | |||
\ | #define PCVAL_IS_NULL(v) ((v) == PCVAL_NULL) | |||
JSPropertyCacheEntry *pce_ = &cache_->table[hashIndex_]; | ||||
\ | #define PCVAL_IS_OBJECT(v) (PCVAL_TAG(v) == PCVAL_OBJECT) | |||
JSPropertyCacheEntry entry_; | #define PCVAL_TO_OBJECT(v) ((JSObject *) (v)) | |||
\ | #define OBJECT_TO_PCVAL(obj) ((jsuword) (obj)) | |||
JSScopeProperty *pce_sprop_; | ||||
\ | #define PCVAL_OBJECT_TO_JSVAL(v) OBJECT_TO_JSVAL(PCVAL_TO_OBJECT(v)) | |||
PCE_LOAD(cache_, pce_, entry_); | #define JSVAL_OBJECT_TO_PCVAL(v) OBJECT_TO_PCVAL(JSVAL_TO_OBJECT(v)) | |||
\ | ||||
pce_sprop_ = PCE_PROPERTY(entry_); | #define PCVAL_IS_SLOT(v) ((v) & PCVAL_SLOT) | |||
\ | #define PCVAL_TO_SLOT(v) ((jsuint)(v) >> 1) | |||
#define SLOT_TO_PCVAL(i) (((jsuword)(i) << 1) | PCVAL_SLOT) | ||||
#define PCVAL_IS_SPROP(v) (PCVAL_TAG(v) == PCVAL_SPROP) | ||||
#define PCVAL_TO_SPROP(v) ((JSScopeProperty *) PCVAL_CLRTAG(v)) | ||||
#define SPROP_TO_PCVAL(sprop) PCVAL_SETTAG(sprop, PCVAL_SPROP) | ||||
/* | ||||
* Fill property cache entry for key cx->fp->pc, optimized value word compu | ||||
ted | ||||
* from obj and sprop, and entry capability forged from OBJ_SCOPE(obj)->sha | ||||
pe, | ||||
* scopeIndex, and protoIndex. | ||||
*/ | ||||
extern void | ||||
js_FillPropertyCache(JSContext *cx, JSObject *obj, jsuword kshape, | ||||
uintN scopeIndex, uintN protoIndex, | ||||
JSObject *pobj, JSScopeProperty *sprop, | ||||
JSPropCacheEntry **entryp); | ||||
/* | ||||
* Property cache lookup macros. PROPERTY_CACHE_TEST is designed to inline | ||||
the | ||||
* fast path in js_Interpret, so it makes "just-so" restrictions on paramet | ||||
ers, | ||||
* e.g. pobj and obj should not be the same variable, since for JOF_PROP-mo | ||||
de | ||||
* opcodes, obj must not be changed because of a cache miss. | ||||
* | ||||
* On return from PROPERTY_CACHE_TEST, if atom is null then obj points to t | ||||
he | ||||
* scope chain element in which the property was found, pobj is locked, and | ||||
* entry is valid. If atom is non-null then no object is locked but entry i | ||||
s | ||||
* still set correctly for use, e.g., by js_FillPropertyCache and atom shou | ||||
ld | ||||
* be used as the id to find. | ||||
* | ||||
* We must lock pobj on a hit in order to close races with threads that mig | ||||
ht | ||||
* be deleting a property from its scope, or otherwise invalidating propert | ||||
y | ||||
* caches (on all threads) by re-generating scope->shape. | ||||
*/ | ||||
#define PROPERTY_CACHE_TEST(cx, pc, obj, pobj, entry, atom) | ||||
\ | ||||
do { | ||||
\ | ||||
JSPropertyCache *cache_ = &JS_PROPERTY_CACHE(cx); | ||||
\ | ||||
uint32 kshape_ = (JS_ASSERT(OBJ_IS_NATIVE(obj)), | ||||
\ | ||||
OBJ_SCOPE(obj)->shape); | ||||
\ | ||||
entry = &cache_->table[PROPERTY_CACHE_HASH_PC(pc, kshape_)]; | ||||
\ | ||||
PCMETER(cache_->tests++); \ | PCMETER(cache_->tests++); \ | |||
if (pce_sprop_ && | JS_ASSERT(&obj != &pobj); | |||
\ | \ | |||
PCE_OBJECT(entry_) == obj && | if (entry->kpc == pc && entry->kshape == kshape_) { | |||
\ | \ | |||
pce_sprop_->id == id) { | JSObject *tmp_; | |||
\ | \ | |||
sprop = pce_sprop_; | pobj = obj; | |||
\ | \ | |||
} else { | JS_LOCK_OBJ(cx, pobj); | |||
\ | \ | |||
PCMETER(cache_->misses++); | JS_ASSERT(PCVCAP_TAG(entry->vcap) <= 1); | |||
\ | \ | |||
sprop = NULL; | if (PCVCAP_TAG(entry->vcap) == 1 && | |||
\ | \ | |||
(tmp_ = LOCKED_OBJ_GET_PROTO(pobj)) != NULL && | ||||
\ | ||||
OBJ_IS_NATIVE(tmp_)) { | ||||
\ | ||||
JS_UNLOCK_OBJ(cx, pobj); | ||||
\ | ||||
pobj = tmp_; | ||||
\ | ||||
JS_LOCK_OBJ(cx, pobj); | ||||
\ | ||||
} | ||||
\ | ||||
if (PCVCAP_SHAPE(entry->vcap) == OBJ_SCOPE(pobj)->shape) { | ||||
\ | ||||
PCMETER(cache_->pchits++); | ||||
\ | ||||
PCMETER(!PCVCAP_TAG(entry->vcap) || cache_->protopchits++); | ||||
\ | ||||
pobj = OBJ_SCOPE(pobj)->object; | ||||
\ | ||||
atom = NULL; | ||||
\ | ||||
break; | ||||
\ | ||||
} | ||||
\ | ||||
JS_UNLOCK_OBJ(cx, pobj); | ||||
\ | ||||
} \ | } \ | |||
JS_END_MACRO | atom = js_FullTestPropertyCache(cx, pc, &obj, &pobj, &entry); | |||
\ | ||||
if (atom) | ||||
\ | ||||
PCMETER(cache_->misses++); | ||||
\ | ||||
} while (0) | ||||
extern JSAtom * | ||||
js_FullTestPropertyCache(JSContext *cx, jsbytecode *pc, | ||||
JSObject **objp, JSObject **pobjp, | ||||
JSPropCacheEntry **entryp); | ||||
extern void | extern void | |||
js_FlushPropertyCache(JSContext *cx); | js_FlushPropertyCache(JSContext *cx); | |||
extern void | extern void | |||
js_FlushPropertyCacheForScript(JSContext *cx, JSScript *script); | ||||
extern void | ||||
js_DisablePropertyCache(JSContext *cx); | js_DisablePropertyCache(JSContext *cx); | |||
extern void | extern void | |||
js_EnablePropertyCache(JSContext *cx); | js_EnablePropertyCache(JSContext *cx); | |||
/* | ||||
* Interpreter stack arena-pool alloc and free functions. | ||||
*/ | ||||
extern JS_FRIEND_API(jsval *) | extern JS_FRIEND_API(jsval *) | |||
js_AllocStack(JSContext *cx, uintN nslots, void **markp); | js_AllocStack(JSContext *cx, uintN nslots, void **markp); | |||
extern JS_FRIEND_API(void) | extern JS_FRIEND_API(void) | |||
js_FreeStack(JSContext *cx, void *mark); | js_FreeStack(JSContext *cx, void *mark); | |||
extern JSBool | extern jsval * | |||
js_GetArgument(JSContext *cx, JSObject *obj, jsval id, jsval *vp); | js_AllocRawStack(JSContext *cx, uintN nslots, void **markp); | |||
extern JSBool | ||||
js_SetArgument(JSContext *cx, JSObject *obj, jsval id, jsval *vp); | ||||
extern JSBool | ||||
js_GetLocalVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp); | ||||
extern JSBool | ||||
js_SetLocalVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp); | ||||
#ifdef DUMP_CALL_TABLE | ||||
# define JSOPTION_LOGCALL_TOSOURCE JS_BIT(15) | ||||
extern JSHashTable *js_CallTable; | ||||
extern size_t js_LogCallToSourceLimit; | ||||
extern void js_DumpCallTable(JSContext *cx); | extern void | |||
#endif | js_FreeRawStack(JSContext *cx, void *mark); | |||
/* | /* | |||
* Refresh and return fp->scopeChain. It may be stale if block scopes are | * Refresh and return fp->scopeChain. It may be stale if block scopes are | |||
* active but not yet reflected by objects in the scope chain. If a block | * active but not yet reflected by objects in the scope chain. If a block | |||
* scope contains a with, eval, XML filtering predicate, or similar such | * scope contains a with, eval, XML filtering predicate, or similar such | |||
* dynamically scoped construct, then compile-time block scope at fp->block s | * dynamically scoped construct, then compile-time block scope at fp->block s | |||
* must reflect at runtime. | * must reflect at runtime. | |||
*/ | */ | |||
extern JSObject * | extern JSObject * | |||
js_GetScopeChain(JSContext *cx, JSStackFrame *fp); | js_GetScopeChain(JSContext *cx, JSStackFrame *fp); | |||
/* | /* | |||
* Compute the 'this' parameter for a call with nominal 'this' given by thi | * Given a context and a vector of [callee, this, args...] for a function t | |||
sp | hat | |||
* and arguments including argv[-1] (nominal 'this') and argv[-2] (callee). | * was specified with a JSFUN_THISP_PRIMITIVE flag, get the primitive value | |||
* Activation objects ("Call" objects not created with "new Call()", i.e., | of | |||
* "Call" objects that have private data) may not be referred to by 'this', | * |this| into *thisvp. In doing so, if |this| is an object, insist it is a | |||
* per ECMA-262, so js_ComputeThis censors them. | n | |||
* instance of clasp and extract its private slot value to return via *this | ||||
vp. | ||||
* | ||||
* NB: this function loads and uses *vp before storing *thisvp, so the two | ||||
may | ||||
* alias the same jsval. | ||||
*/ | ||||
extern JSBool | ||||
js_GetPrimitiveThis(JSContext *cx, jsval *vp, JSClass *clasp, jsval *thisvp | ||||
); | ||||
/* | ||||
* For a call with arguments argv including argv[-1] (nominal |this|) and | ||||
* argv[-2] (callee) replace null |this| with callee's parent, replace | ||||
* primitive values with the equivalent wrapper objects and censor activati | ||||
on | ||||
* objects as, per ECMA-262, they may not be referred to by |this|. argv[-1 | ||||
] | ||||
* must not be a JSVAL_VOID. | ||||
*/ | */ | |||
extern JSObject * | extern JSObject * | |||
js_ComputeThis(JSContext *cx, JSObject *thisp, jsval *argv); | js_ComputeThis(JSContext *cx, JSBool lazy, jsval *argv); | |||
/* | ||||
* ECMA requires "the global object", but in embeddings such as the browser | ||||
, | ||||
* which have multiple top-level objects (windows, frames, etc. in the DOM) | ||||
, | ||||
* we prefer fun's parent. An example that causes this code to run: | ||||
* | ||||
* // in window w1 | ||||
* function f() { return this } | ||||
* function g() { return f } | ||||
* | ||||
* // in window w2 | ||||
* var h = w1.g() | ||||
* alert(h() == w1) | ||||
* | ||||
* The alert should display "true". | ||||
*/ | ||||
JSObject * | ||||
js_ComputeGlobalThis(JSContext *cx, JSBool lazy, jsval *argv); | ||||
extern const uint16 js_PrimitiveTestFlags[]; | ||||
#define PRIMITIVE_THIS_TEST(fun,thisv) | ||||
\ | ||||
(JS_ASSERT(thisv != JSVAL_VOID), | ||||
\ | ||||
JSFUN_THISP_TEST(JSFUN_THISP_FLAGS((fun)->flags), | ||||
\ | ||||
js_PrimitiveTestFlags[JSVAL_TAG(thisv) - 1])) | ||||
/* | /* | |||
* NB: js_Invoke requires that cx is currently running JS (i.e., that cx->f p | * NB: js_Invoke requires that cx is currently running JS (i.e., that cx->f p | |||
* is non-null), and that the callee, |this| parameter, and actual argument | * is non-null), and that vp points to the callee, |this| parameter, and | |||
s | * actual arguments of the call. [vp .. vp + 2 + argc) must belong to the l | |||
* are already pushed on the stack under cx->fp->sp. | ast | |||
* JS stack segment that js_AllocStack allocated. The function may use the | ||||
* space available after vp + 2 + argc in the stack segment for temporaries | ||||
, | ||||
* so the caller should not use that space for values that must be preserve | ||||
d | ||||
* across the call. | ||||
*/ | */ | |||
extern JS_FRIEND_API(JSBool) | extern JS_FRIEND_API(JSBool) | |||
js_Invoke(JSContext *cx, uintN argc, uintN flags); | js_Invoke(JSContext *cx, uintN argc, jsval *vp, uintN flags); | |||
/* | /* | |||
* Consolidated js_Invoke flags simply rename certain JSFRAME_* flags, so t hat | * Consolidated js_Invoke flags simply rename certain JSFRAME_* flags, so t hat | |||
* we can share bits stored in JSStackFrame.flags and passed to: | * we can share bits stored in JSStackFrame.flags and passed to: | |||
* | * | |||
* js_Invoke | * js_Invoke | |||
* js_InternalInvoke | * js_InternalInvoke | |||
* js_ValueToFunction | * js_ValueToFunction | |||
* js_ValueToFunctionObject | * js_ValueToFunctionObject | |||
* js_ValueToCallableObject | * js_ValueToCallableObject | |||
* js_ReportIsNotFunction | * js_ReportIsNotFunction | |||
* | * | |||
* See jsfun.h for the latter four and flag renaming macros. | * See jsfun.h for the latter four and flag renaming macros. | |||
*/ | */ | |||
#define JSINVOKE_CONSTRUCT JSFRAME_CONSTRUCTING | #define JSINVOKE_CONSTRUCT JSFRAME_CONSTRUCTING | |||
#define JSINVOKE_INTERNAL JSFRAME_INTERNAL | ||||
#define JSINVOKE_SKIP_CALLER JSFRAME_SKIP_CALLER | ||||
#define JSINVOKE_ITERATOR JSFRAME_ITERATOR | #define JSINVOKE_ITERATOR JSFRAME_ITERATOR | |||
/* | /* | |||
* Mask to isolate construct and iterator flags for use with jsfun.h functi ons. | * Mask to isolate construct and iterator flags for use with jsfun.h functi ons. | |||
*/ | */ | |||
#define JSINVOKE_FUNFLAGS (JSINVOKE_CONSTRUCT | JSINVOKE_ITERATOR) | #define JSINVOKE_FUNFLAGS (JSINVOKE_CONSTRUCT | JSINVOKE_ITERATOR) | |||
/* | /* | |||
* "Internal" calls may come from C or C++ code using a JSContext on which no | * "Internal" calls may come from C or C++ code using a JSContext on which no | |||
* JS is running (!cx->fp), so they may need to push a dummy JSStackFrame. | * JS is running (!cx->fp), so they may need to push a dummy JSStackFrame. | |||
skipping to change at line 347 | skipping to change at line 462 | |||
extern JSBool | extern JSBool | |||
js_InternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, jsval fval, | js_InternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, jsval fval, | |||
JSAccessMode mode, uintN argc, jsval *argv, jsval *rval ); | JSAccessMode mode, uintN argc, jsval *argv, jsval *rval ); | |||
extern JSBool | extern JSBool | |||
js_Execute(JSContext *cx, JSObject *chain, JSScript *script, | js_Execute(JSContext *cx, JSObject *chain, JSScript *script, | |||
JSStackFrame *down, uintN flags, jsval *result); | JSStackFrame *down, uintN flags, jsval *result); | |||
extern JSBool | extern JSBool | |||
js_InvokeConstructor(JSContext *cx, uintN argc, jsval *vp); | ||||
extern JSBool | ||||
js_Interpret(JSContext *cx); | ||||
#define JSPROP_INITIALIZER 0x100 /* NB: Not a valid property attribute. * | ||||
/ | ||||
extern JSBool | ||||
js_CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs, | js_CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs, | |||
JSObject **objp, JSProperty **propp); | JSObject **objp, JSProperty **propp); | |||
extern JSBool | extern JSBool | |||
js_StrictlyEqual(jsval lval, jsval rval); | js_StrictlyEqual(JSContext *cx, jsval lval, jsval rval); | |||
extern JSBool | extern JSBool | |||
js_InvokeConstructor(JSContext *cx, jsval *vp, uintN argc); | js_EnterWith(JSContext *cx, jsint stackIndex); | |||
extern void | ||||
js_LeaveWith(JSContext *cx); | ||||
extern JSClass * | ||||
js_IsActiveWithOrBlock(JSContext *cx, JSObject *obj, int stackDepth); | ||||
extern jsint | ||||
js_CountWithBlocks(JSContext *cx, JSStackFrame *fp); | ||||
/* | ||||
* Unwind block and scope chains to match the given depth. The function set | ||||
s | ||||
* fp->sp on return to stackDepth. | ||||
*/ | ||||
extern JSBool | extern JSBool | |||
js_Interpret(JSContext *cx, jsbytecode *pc, jsval *result); | js_UnwindScope(JSContext *cx, JSStackFrame *fp, jsint stackDepth, | |||
JSBool normalUnwind); | ||||
extern JSBool | ||||
js_InternNonIntElementId(JSContext *cx, JSObject *obj, jsval idval, jsid *i | ||||
dp); | ||||
extern JSBool | ||||
js_ImportProperty(JSContext *cx, JSObject *obj, jsid id); | ||||
extern JSBool | ||||
js_OnUnknownMethod(JSContext *cx, jsval *vp); | ||||
/* | ||||
* Find the results of incrementing or decrementing *vp. For pre-increments | ||||
, | ||||
* both *vp and *vp2 will contain the result on return. For post-increments | ||||
, | ||||
* vp will contain the original value converted to a number and vp2 will ge | ||||
t | ||||
* the result. Both vp and vp2 must be roots. | ||||
*/ | ||||
extern JSBool | ||||
js_DoIncDec(JSContext *cx, const JSCodeSpec *cs, jsval *vp, jsval *vp2); | ||||
/* | ||||
* JS_OPMETER helper functions. | ||||
*/ | ||||
extern void | ||||
js_MeterOpcodePair(JSOp op1, JSOp op2); | ||||
extern void | ||||
js_MeterSlotOpcode(JSOp op, uint32 slot); | ||||
JS_END_EXTERN_C | JS_END_EXTERN_C | |||
#endif /* jsinterp_h___ */ | #endif /* jsinterp_h___ */ | |||
End of changes. 46 change blocks. | ||||
211 lines changed or deleted | 413 lines changed or added | |||
jsiter.h | jsiter.h | |||
---|---|---|---|---|
skipping to change at line 42 | skipping to change at line 42 | |||
* use your version of this file under the terms of the MPL, indicate your | * use your version of this file under the terms of the MPL, indicate your | |||
* decision by deleting the provisions above and replace them with the noti ce | * decision by deleting the provisions above and replace them with the noti ce | |||
* and other provisions required by the GPL or the LGPL. If you do not dele te | * and other provisions required by the GPL or the LGPL. If you do not dele te | |||
* the provisions above, a recipient may use your version of this file unde r | * the provisions above, a recipient may use your version of this file unde r | |||
* the terms of any one of the MPL, the GPL or the LGPL. | * the terms of any one of the MPL, the GPL or the LGPL. | |||
* | * | |||
* ***** END LICENSE BLOCK ***** */ | * ***** END LICENSE BLOCK ***** */ | |||
#ifndef jsiter_h___ | #ifndef jsiter_h___ | |||
#define jsiter_h___ | #define jsiter_h___ | |||
/* | /* | |||
* JavaScript iterators. | * JavaScript iterators. | |||
*/ | */ | |||
#include "jsprvtd.h" | #include "jsprvtd.h" | |||
#include "jspubtd.h" | #include "jspubtd.h" | |||
JS_BEGIN_EXTERN_C | ||||
#define JSITER_ENUMERATE 0x1 /* for-in compatible hidden default iterato r */ | #define JSITER_ENUMERATE 0x1 /* for-in compatible hidden default iterato r */ | |||
#define JSITER_FOREACH 0x2 /* return [key, value] pair rather than key */ | #define JSITER_FOREACH 0x2 /* return [key, value] pair rather than key */ | |||
#define JSITER_KEYVALUE 0x4 /* destructuring for-in wants [key, value] */ | #define JSITER_KEYVALUE 0x4 /* destructuring for-in wants [key, value] */ | |||
extern void | ||||
js_CloseNativeIterator(JSContext *cx, JSObject *iterobj); | ||||
extern void | ||||
js_CloseIteratorState(JSContext *cx, JSObject *iterobj); | ||||
/* | /* | |||
* Convert the value stored in *vp to its iteration object. The flags shoul d | * Convert the value stored in *vp to its iteration object. The flags shoul d | |||
* contain JSITER_ENUMERATE if js_ValueToIterator is called when enumeratin g | * contain JSITER_ENUMERATE if js_ValueToIterator is called when enumeratin g | |||
* for-in semantics are required, and when the caller can guarantee that th e | * for-in semantics are required, and when the caller can guarantee that th e | |||
* iterator will never be exposed to scripts. | * iterator will never be exposed to scripts. | |||
*/ | */ | |||
extern JSBool | extern JS_FRIEND_API(JSBool) | |||
js_ValueToIterator(JSContext *cx, uintN flags, jsval *vp); | js_ValueToIterator(JSContext *cx, uintN flags, jsval *vp); | |||
extern JS_FRIEND_API(JSBool) | ||||
js_CloseIterator(JSContext *cx, jsval v); | ||||
/* | /* | |||
* Given iterobj, call iterobj.next(). If the iterator stopped, set *rval to | * Given iterobj, call iterobj.next(). If the iterator stopped, set *rval to | |||
* JSVAL_HOLE. Otherwise set it to the result of the next call. | * JSVAL_HOLE. Otherwise set it to the result of the next call. | |||
*/ | */ | |||
extern JSBool | extern JS_FRIEND_API(JSBool) | |||
js_CallIteratorNext(JSContext *cx, JSObject *iterobj, jsval *rval); | js_CallIteratorNext(JSContext *cx, JSObject *iterobj, jsval *rval); | |||
/* | ||||
* Close iterobj, whose class must be js_IteratorClass. | ||||
*/ | ||||
extern void | ||||
js_CloseNativeIterator(JSContext *cx, JSObject *iterobj); | ||||
extern JSBool | ||||
js_ThrowStopIteration(JSContext *cx); | ||||
#if JS_HAS_GENERATORS | #if JS_HAS_GENERATORS | |||
/* | /* | |||
* Generator state codes. | * Generator state codes. | |||
*/ | */ | |||
typedef enum JSGeneratorState { | typedef enum JSGeneratorState { | |||
JSGEN_NEWBORN, /* not yet started */ | JSGEN_NEWBORN, /* not yet started */ | |||
JSGEN_OPEN, /* started by a .next() or .send(undefined) call */ | JSGEN_OPEN, /* started by a .next() or .send(undefined) call */ | |||
JSGEN_RUNNING, /* currently executing via .next(), etc., call */ | JSGEN_RUNNING, /* currently executing via .next(), etc., call */ | |||
JSGEN_CLOSING, /* close method is doing asynchronous return */ | JSGEN_CLOSING, /* close method is doing asynchronous return */ | |||
JSGEN_CLOSED /* closed, cannot be started or closed again */ | JSGEN_CLOSED /* closed, cannot be started or closed again */ | |||
} JSGeneratorState; | } JSGeneratorState; | |||
struct JSGenerator { | struct JSGenerator { | |||
JSGenerator *next; | ||||
JSObject *obj; | JSObject *obj; | |||
JSGeneratorState state; | JSGeneratorState state; | |||
JSStackFrame frame; | JSStackFrame frame; | |||
JSFrameRegs savedRegs; | ||||
JSArena arena; | JSArena arena; | |||
jsval stack[1]; | jsval stack[1]; | |||
}; | }; | |||
#define FRAME_TO_GENERATOR(fp) \ | #define FRAME_TO_GENERATOR(fp) \ | |||
((JSGenerator *) ((uint8 *)(fp) - offsetof(JSGenerator, frame))) | ((JSGenerator *) ((uint8 *)(fp) - offsetof(JSGenerator, frame))) | |||
extern JSObject * | extern JSObject * | |||
js_NewGenerator(JSContext *cx, JSStackFrame *fp); | js_NewGenerator(JSContext *cx, JSStackFrame *fp); | |||
extern JSBool | ||||
js_CloseGeneratorObject(JSContext *cx, JSGenerator *gen); | ||||
#endif | #endif | |||
extern JSClass js_GeneratorClass; | extern JSClass js_GeneratorClass; | |||
extern JSClass js_IteratorClass; | extern JSClass js_IteratorClass; | |||
extern JSClass js_StopIterationClass; | extern JSClass js_StopIterationClass; | |||
extern JSObject * | extern JSObject * | |||
js_InitIteratorClasses(JSContext *cx, JSObject *obj); | js_InitIteratorClasses(JSContext *cx, JSObject *obj); | |||
JS_END_EXTERN_C | ||||
#endif /* jsiter_h___ */ | #endif /* jsiter_h___ */ | |||
End of changes. 11 change blocks. | ||||
12 lines changed or deleted | 20 lines changed or added | |||
jslibmath.h | jslibmath.h | |||
---|---|---|---|---|
skipping to change at line 118 | skipping to change at line 118 | |||
* Use math routines in fdlibm. | * Use math routines in fdlibm. | |||
*/ | */ | |||
#undef __P | #undef __P | |||
#ifdef __STDC__ | #ifdef __STDC__ | |||
#define __P(p) p | #define __P(p) p | |||
#else | #else | |||
#define __P(p) () | #define __P(p) () | |||
#endif | #endif | |||
#if (defined _WIN32 && !defined WINCE) || defined SUNOS4 | #if defined _WIN32 && !defined WINCE | |||
#define fd_acos acos | #define fd_acos acos | |||
#define fd_asin asin | #define fd_asin asin | |||
#define fd_atan atan | #define fd_atan atan | |||
#define fd_cos cos | #define fd_cos cos | |||
#define fd_sin sin | #define fd_sin sin | |||
#define fd_tan tan | #define fd_tan tan | |||
#define fd_exp exp | #define fd_exp exp | |||
#define fd_log log | #define fd_log log | |||
#define fd_sqrt sqrt | #define fd_sqrt sqrt | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
jslock.h | jslock.h | |||
---|---|---|---|---|
skipping to change at line 53 | skipping to change at line 53 | |||
#include "jstypes.h" | #include "jstypes.h" | |||
#include "pratom.h" | #include "pratom.h" | |||
#include "prlock.h" | #include "prlock.h" | |||
#include "prcvar.h" | #include "prcvar.h" | |||
#include "prthread.h" | #include "prthread.h" | |||
#include "jsprvtd.h" /* for JSScope, etc. */ | #include "jsprvtd.h" /* for JSScope, etc. */ | |||
#include "jspubtd.h" /* for JSRuntime, etc. */ | #include "jspubtd.h" /* for JSRuntime, etc. */ | |||
JS_BEGIN_EXTERN_C | ||||
#define Thin_GetWait(W) ((jsword)(W) & 0x1) | #define Thin_GetWait(W) ((jsword)(W) & 0x1) | |||
#define Thin_SetWait(W) ((jsword)(W) | 0x1) | #define Thin_SetWait(W) ((jsword)(W) | 0x1) | |||
#define Thin_RemoveWait(W) ((jsword)(W) & ~0x1) | #define Thin_RemoveWait(W) ((jsword)(W) & ~0x1) | |||
typedef struct JSFatLock JSFatLock; | typedef struct JSFatLock JSFatLock; | |||
struct JSFatLock { | struct JSFatLock { | |||
int susp; | int susp; | |||
PRLock *slock; | PRLock *slock; | |||
PRCondVar *svar; | PRCondVar *svar; | |||
skipping to change at line 82 | skipping to change at line 84 | |||
#define CX_THINLOCK_ID(cx) ((jsword)(cx)->thread) | #define CX_THINLOCK_ID(cx) ((jsword)(cx)->thread) | |||
#define CURRENT_THREAD_IS_ME(me) (((JSThread *)me)->id == js_CurrentThreadI d()) | #define CURRENT_THREAD_IS_ME(me) (((JSThread *)me)->id == js_CurrentThreadI d()) | |||
typedef PRLock JSLock; | typedef PRLock JSLock; | |||
typedef struct JSFatLockTable { | typedef struct JSFatLockTable { | |||
JSFatLock *free; | JSFatLock *free; | |||
JSFatLock *taken; | JSFatLock *taken; | |||
} JSFatLockTable; | } JSFatLockTable; | |||
typedef struct JSTitle JSTitle; | ||||
struct JSTitle { | ||||
JSContext *ownercx; /* creating context, NULL if shared | ||||
*/ | ||||
JSThinLock lock; /* binary semaphore protecting titl | ||||
e */ | ||||
union { /* union lockful and lock-free stat | ||||
e: */ | ||||
jsrefcount count; /* lock entry count for reentrancy | ||||
*/ | ||||
JSTitle *link; /* next link in rt->titleSharingTod | ||||
o */ | ||||
} u; | ||||
#ifdef JS_DEBUG_TITLE_LOCKS | ||||
const char *file[4]; /* file where lock was (re-)taken * | ||||
/ | ||||
unsigned int line[4]; /* line where lock was (re-)taken * | ||||
/ | ||||
#endif | ||||
}; | ||||
/* | ||||
* Title structures must be immediately preceded by JSObjectMap structures | ||||
for | ||||
* maps that use titles for threadsafety. This is enforced by assertion in | ||||
* jsscope.h; see bug 408416 for future remedies to this somewhat fragile | ||||
* architecture. | ||||
*/ | ||||
#define TITLE_TO_MAP(title) | ||||
\ | ||||
((JSObjectMap *)((char *)(title) - sizeof(JSObjectMap))) | ||||
/* | /* | |||
* Atomic increment and decrement for a reference counter, given jsrefcount *p. | * Atomic increment and decrement for a reference counter, given jsrefcount *p. | |||
* NB: jsrefcount is int32, aka PRInt32, so that pratom.h functions work. | * NB: jsrefcount is int32, aka PRInt32, so that pratom.h functions work. | |||
*/ | */ | |||
#define JS_ATOMIC_INCREMENT(p) PR_AtomicIncrement((PRInt32 *)(p)) | #define JS_ATOMIC_INCREMENT(p) PR_AtomicIncrement((PRInt32 *)(p)) | |||
#define JS_ATOMIC_DECREMENT(p) PR_AtomicDecrement((PRInt32 *)(p)) | #define JS_ATOMIC_DECREMENT(p) PR_AtomicDecrement((PRInt32 *)(p)) | |||
#define JS_ATOMIC_ADD(p,v) PR_AtomicAdd((PRInt32 *)(p), (PRInt32)( v)) | #define JS_ATOMIC_ADD(p,v) PR_AtomicAdd((PRInt32 *)(p), (PRInt32)( v)) | |||
#define js_CurrentThreadId() (jsword)PR_GetCurrentThread() | #define js_CurrentThreadId() (jsword)PR_GetCurrentThread() | |||
#define JS_NEW_LOCK() PR_NewLock() | #define JS_NEW_LOCK() PR_NewLock() | |||
skipping to change at line 105 | skipping to change at line 132 | |||
#define JS_LOCK0(P,M) js_Lock(P,M) | #define JS_LOCK0(P,M) js_Lock(P,M) | |||
#define JS_UNLOCK0(P,M) js_Unlock(P,M) | #define JS_UNLOCK0(P,M) js_Unlock(P,M) | |||
#define JS_NEW_CONDVAR(l) PR_NewCondVar(l) | #define JS_NEW_CONDVAR(l) PR_NewCondVar(l) | |||
#define JS_DESTROY_CONDVAR(cv) PR_DestroyCondVar(cv) | #define JS_DESTROY_CONDVAR(cv) PR_DestroyCondVar(cv) | |||
#define JS_WAIT_CONDVAR(cv,to) PR_WaitCondVar(cv,to) | #define JS_WAIT_CONDVAR(cv,to) PR_WaitCondVar(cv,to) | |||
#define JS_NO_TIMEOUT PR_INTERVAL_NO_TIMEOUT | #define JS_NO_TIMEOUT PR_INTERVAL_NO_TIMEOUT | |||
#define JS_NOTIFY_CONDVAR(cv) PR_NotifyCondVar(cv) | #define JS_NOTIFY_CONDVAR(cv) PR_NotifyCondVar(cv) | |||
#define JS_NOTIFY_ALL_CONDVAR(cv) PR_NotifyAllCondVar(cv) | #define JS_NOTIFY_ALL_CONDVAR(cv) PR_NotifyAllCondVar(cv) | |||
/* | #ifdef JS_DEBUG_TITLE_LOCKS | |||
* Include jsscope.h so JS_LOCK_OBJ macro callers don't have to include it. | ||||
* Since there is a JSThinLock member in JSScope, we can't nest this includ | #define SET_OBJ_INFO(obj_, file_, line_) | |||
e | \ | |||
* much earlier (see JSThinLock's typedef, above). Yes, that means there i | SET_SCOPE_INFO(OBJ_SCOPE(obj_), file_, line_) | |||
s | ||||
* an #include cycle between jslock.h and jsscope.h: moderate-sized XXX her | #define SET_SCOPE_INFO(scope_, file_, line_) | |||
e, | \ | |||
* to be fixed by moving JS_LOCK_SCOPE to jsscope.h, JS_LOCK_OBJ to jsobj.h | js_SetScopeInfo(scope_, file_, line_) | |||
, | ||||
* and so on. | #endif | |||
*/ | ||||
#include "jsscope.h" | ||||
#define JS_LOCK_RUNTIME(rt) js_LockRuntime(rt) | #define JS_LOCK_RUNTIME(rt) js_LockRuntime(rt) | |||
#define JS_UNLOCK_RUNTIME(rt) js_UnlockRuntime(rt) | #define JS_UNLOCK_RUNTIME(rt) js_UnlockRuntime(rt) | |||
/* | /* | |||
* NB: The JS_LOCK_OBJ and JS_UNLOCK_OBJ macros work *only* on native objec ts | * NB: The JS_LOCK_OBJ and JS_UNLOCK_OBJ macros work *only* on native objec ts | |||
* (objects for which OBJ_IS_NATIVE returns true). All uses of these macro s in | * (objects for which OBJ_IS_NATIVE returns true). All uses of these macro s in | |||
* the engine are predicated on OBJ_IS_NATIVE or equivalent checks. These uses | * the engine are predicated on OBJ_IS_NATIVE or equivalent checks. These uses | |||
* are for optimizations above the JSObjectOps layer, under which object lo cks | * are for optimizations above the JSObjectOps layer, under which object lo cks | |||
* normally hide. | * normally hide. | |||
*/ | */ | |||
#define JS_LOCK_OBJ(cx,obj) ((OBJ_SCOPE(obj)->ownercx == (cx)) | #define JS_LOCK_OBJ(cx,obj) ((OBJ_SCOPE(obj)->title.ownercx == (cx)) | |||
\ | \ | |||
? (void)0 | ? (void)0 | |||
\ | \ | |||
: (js_LockObj(cx, obj))) | : (js_LockObj(cx, obj), | |||
#define JS_UNLOCK_OBJ(cx,obj) ((OBJ_SCOPE(obj)->ownercx == (cx)) | \ | |||
\ | SET_OBJ_INFO(obj,__FILE__,__LINE__))) | |||
? (void)0 : js_UnlockObj(cx, obj)) | #define JS_UNLOCK_OBJ(cx,obj) ((OBJ_SCOPE(obj)->title.ownercx == (cx)) | |||
\ | ||||
? (void)0 : js_UnlockObj(cx, obj)) | ||||
#define JS_LOCK_SCOPE(cx,scope) ((scope)->ownercx == (cx) ? (void)0 | #define JS_LOCK_TITLE(cx,title) | |||
\ | \ | |||
: js_LockScope(cx, scope)) | ((title)->ownercx == (cx) ? (void)0 | |||
#define JS_UNLOCK_SCOPE(cx,scope) ((scope)->ownercx == (cx) ? (void)0 | \ | |||
\ | : (js_LockTitle(cx, (title)), | |||
: js_UnlockScope(cx, scope)) | \ | |||
#define JS_TRANSFER_SCOPE_LOCK(cx, scope, newscope) | SET_TITLE_INFO(title,__FILE__,__LINE__))) | |||
\ | ||||
js_TransferScopeLock(cx, scope, newscop | #define JS_UNLOCK_TITLE(cx,title) ((title)->ownercx == (cx) ? (void)0 | |||
e) | \ | |||
: js_UnlockTitle(cx, title)) | ||||
#define JS_LOCK_SCOPE(cx,scope) JS_LOCK_TITLE(cx,&(scope)->title) | ||||
#define JS_UNLOCK_SCOPE(cx,scope) JS_UNLOCK_TITLE(cx,&(scope)->title) | ||||
#define JS_TRANSFER_SCOPE_LOCK(cx, scope, newscope) | ||||
\ | ||||
js_TransferTitle(cx, &scope->title, &newscope->title) | ||||
extern void js_LockRuntime(JSRuntime *rt); | extern void js_LockRuntime(JSRuntime *rt); | |||
extern void js_UnlockRuntime(JSRuntime *rt); | extern void js_UnlockRuntime(JSRuntime *rt); | |||
extern void js_LockObj(JSContext *cx, JSObject *obj); | extern void js_LockObj(JSContext *cx, JSObject *obj); | |||
extern void js_UnlockObj(JSContext *cx, JSObject *obj); | extern void js_UnlockObj(JSContext *cx, JSObject *obj); | |||
extern void js_LockScope(JSContext *cx, JSScope *scope); | extern void js_InitTitle(JSContext *cx, JSTitle *title); | |||
extern void js_UnlockScope(JSContext *cx, JSScope *scope); | extern void js_FinishTitle(JSContext *cx, JSTitle *title); | |||
extern void js_LockTitle(JSContext *cx, JSTitle *title); | ||||
extern void js_UnlockTitle(JSContext *cx, JSTitle *title); | ||||
extern int js_SetupLocks(int,int); | extern int js_SetupLocks(int,int); | |||
extern void js_CleanupLocks(); | extern void js_CleanupLocks(); | |||
extern void js_TransferScopeLock(JSContext *, JSScope *, JSScope *); | extern void js_TransferTitle(JSContext *, JSTitle *, JSTitle *); | |||
extern JS_FRIEND_API(jsval) | extern JS_FRIEND_API(jsval) | |||
js_GetSlotThreadSafe(JSContext *, JSObject *, uint32); | js_GetSlotThreadSafe(JSContext *, JSObject *, uint32); | |||
extern void js_SetSlotThreadSafe(JSContext *, JSObject *, uint32, jsval); | extern void js_SetSlotThreadSafe(JSContext *, JSObject *, uint32, jsval); | |||
extern void js_InitLock(JSThinLock *); | extern void js_InitLock(JSThinLock *); | |||
extern void js_FinishLock(JSThinLock *); | extern void js_FinishLock(JSThinLock *); | |||
extern void js_FinishSharingScope(JSRuntime *rt, JSScope *scope); | extern void js_FinishSharingTitle(JSContext *cx, JSTitle *title); | |||
#ifdef DEBUG | #ifdef DEBUG | |||
#define JS_IS_RUNTIME_LOCKED(rt) js_IsRuntimeLocked(rt) | #define JS_IS_RUNTIME_LOCKED(rt) js_IsRuntimeLocked(rt) | |||
#define JS_IS_OBJ_LOCKED(cx,obj) js_IsObjLocked(cx,obj) | #define JS_IS_OBJ_LOCKED(cx,obj) js_IsObjLocked(cx,obj) | |||
#define JS_IS_SCOPE_LOCKED(cx,scope) js_IsScopeLocked(cx,scope) | #define JS_IS_TITLE_LOCKED(cx,title) js_IsTitleLocked(cx,title) | |||
extern JSBool js_IsRuntimeLocked(JSRuntime *rt); | extern JSBool js_IsRuntimeLocked(JSRuntime *rt); | |||
extern JSBool js_IsObjLocked(JSContext *cx, JSObject *obj); | extern JSBool js_IsObjLocked(JSContext *cx, JSObject *obj); | |||
extern JSBool js_IsScopeLocked(JSContext *cx, JSScope *scope); | extern JSBool js_IsTitleLocked(JSContext *cx, JSTitle *title); | |||
#ifdef JS_DEBUG_TITLE_LOCKS | ||||
extern void js_SetScopeInfo(JSScope *scope, const char *file, int line); | ||||
#endif | ||||
#else | #else | |||
#define JS_IS_RUNTIME_LOCKED(rt) 0 | #define JS_IS_RUNTIME_LOCKED(rt) 0 | |||
#define JS_IS_OBJ_LOCKED(cx,obj) 1 | #define JS_IS_OBJ_LOCKED(cx,obj) 1 | |||
#define JS_IS_SCOPE_LOCKED(cx,scope) 1 | #define JS_IS_TITLE_LOCKED(cx,title) 1 | |||
#endif /* DEBUG */ | #endif /* DEBUG */ | |||
#define JS_LOCK_OBJ_VOID(cx, obj, e) \ | #define JS_LOCK_OBJ_VOID(cx, obj, e) \ | |||
JS_BEGIN_MACRO \ | JS_BEGIN_MACRO \ | |||
JS_LOCK_OBJ(cx, obj); \ | JS_LOCK_OBJ(cx, obj); \ | |||
e; \ | e; \ | |||
JS_UNLOCK_OBJ(cx, obj); \ | JS_UNLOCK_OBJ(cx, obj); \ | |||
JS_END_MACRO | JS_END_MACRO | |||
#define JS_LOCK_VOID(cx, e) \ | #define JS_LOCK_VOID(cx, e) \ | |||
JS_BEGIN_MACRO \ | JS_BEGIN_MACRO \ | |||
JSRuntime *_rt = (cx)->runtime; \ | JSRuntime *_rt = (cx)->runtime; \ | |||
JS_LOCK_RUNTIME_VOID(_rt, e); \ | JS_LOCK_RUNTIME_VOID(_rt, e); \ | |||
JS_END_MACRO | JS_END_MACRO | |||
/* FIXME: bug 353962 hackaround */ | ||||
#define JS_USE_ONLY_NSPR_LOCKS 1 | ||||
#if defined(JS_USE_ONLY_NSPR_LOCKS) || \ | #if defined(JS_USE_ONLY_NSPR_LOCKS) || \ | |||
!( (defined(_WIN32) && defined(_M_IX86)) || \ | !( (defined(_WIN32) && defined(_M_IX86)) || \ | |||
(defined(__GNUC__) && defined(__i386__)) || \ | (defined(__GNUC__) && defined(__i386__)) || \ | |||
((defined(__USLC__) || defined(_SCO_DS)) && defined(i386)) || \ | ||||
(defined(SOLARIS) && defined(sparc) && defined(ULTRA_SPARC)) || \ | (defined(SOLARIS) && defined(sparc) && defined(ULTRA_SPARC)) || \ | |||
defined(AIX) ) | defined(AIX) ) | |||
#define NSPR_LOCK 1 | #define NSPR_LOCK 1 | |||
#undef JS_LOCK0 | #undef JS_LOCK0 | |||
#undef JS_UNLOCK0 | #undef JS_UNLOCK0 | |||
#define JS_LOCK0(P,M) (JS_ACQUIRE_LOCK(((JSLock*)(P)->fat)), (P)->owner = (M)) | #define JS_LOCK0(P,M) (JS_ACQUIRE_LOCK(((JSLock*)(P)->fat)), (P)->owner = (M)) | |||
#define JS_UNLOCK0(P,M) ((P)->owner = 0, JS_RELEASE_LOCK(((JSLock*)(P)->fat ))) | #define JS_UNLOCK0(P,M) ((P)->owner = 0, JS_RELEASE_LOCK(((JSLock*)(P)->fat ))) | |||
#else /* arch-tests */ | #else /* arch-tests */ | |||
#undef NSPR_LOCK | #undef NSPR_LOCK | |||
extern JS_INLINE void js_Lock(JSThinLock *tl, jsword me); | extern void js_Lock(JSThinLock *tl, jsword me); | |||
extern JS_INLINE void js_Unlock(JSThinLock *tl, jsword me); | extern void js_Unlock(JSThinLock *tl, jsword me); | |||
#endif /* arch-tests */ | #endif /* arch-tests */ | |||
#else /* !JS_THREADSAFE */ | #else /* !JS_THREADSAFE */ | |||
JS_BEGIN_EXTERN_C | ||||
#define JS_ATOMIC_INCREMENT(p) (++*(p)) | #define JS_ATOMIC_INCREMENT(p) (++*(p)) | |||
#define JS_ATOMIC_DECREMENT(p) (--*(p)) | #define JS_ATOMIC_DECREMENT(p) (--*(p)) | |||
#define JS_ATOMIC_ADD(p,v) (*(p) += (v)) | #define JS_ATOMIC_ADD(p,v) (*(p) += (v)) | |||
#define JS_CurrentThreadId() 0 | #define JS_CurrentThreadId() 0 | |||
#define JS_NEW_LOCK() NULL | #define JS_NEW_LOCK() NULL | |||
#define JS_DESTROY_LOCK(l) ((void)0) | #define JS_DESTROY_LOCK(l) ((void)0) | |||
#define JS_ACQUIRE_LOCK(l) ((void)0) | #define JS_ACQUIRE_LOCK(l) ((void)0) | |||
#define JS_RELEASE_LOCK(l) ((void)0) | #define JS_RELEASE_LOCK(l) ((void)0) | |||
#define JS_LOCK0(P,M) ((void)0) | #define JS_LOCK0(P,M) ((void)0) | |||
skipping to change at line 242 | skipping to change at line 280 | |||
#define JS_UNLOCK_RUNTIME(rt) ((void)0) | #define JS_UNLOCK_RUNTIME(rt) ((void)0) | |||
#define JS_LOCK_OBJ(cx,obj) ((void)0) | #define JS_LOCK_OBJ(cx,obj) ((void)0) | |||
#define JS_UNLOCK_OBJ(cx,obj) ((void)0) | #define JS_UNLOCK_OBJ(cx,obj) ((void)0) | |||
#define JS_LOCK_OBJ_VOID(cx,obj,e) (e) | #define JS_LOCK_OBJ_VOID(cx,obj,e) (e) | |||
#define JS_LOCK_SCOPE(cx,scope) ((void)0) | #define JS_LOCK_SCOPE(cx,scope) ((void)0) | |||
#define JS_UNLOCK_SCOPE(cx,scope) ((void)0) | #define JS_UNLOCK_SCOPE(cx,scope) ((void)0) | |||
#define JS_TRANSFER_SCOPE_LOCK(c,o,n) ((void)0) | #define JS_TRANSFER_SCOPE_LOCK(c,o,n) ((void)0) | |||
#define JS_IS_RUNTIME_LOCKED(rt) 1 | #define JS_IS_RUNTIME_LOCKED(rt) 1 | |||
#define JS_IS_OBJ_LOCKED(cx,obj) 1 | #define JS_IS_OBJ_LOCKED(cx,obj) 1 | |||
#define JS_IS_SCOPE_LOCKED(cx,scope) 1 | #define JS_IS_TITLE_LOCKED(cx,title) 1 | |||
#define JS_LOCK_VOID(cx, e) JS_LOCK_RUNTIME_VOID((cx)->runtime, e) | #define JS_LOCK_VOID(cx, e) JS_LOCK_RUNTIME_VOID((cx)->runtime, e) | |||
#endif /* !JS_THREADSAFE */ | #endif /* !JS_THREADSAFE */ | |||
#define JS_LOCK_RUNTIME_VOID(rt,e) \ | #define JS_LOCK_RUNTIME_VOID(rt,e) \ | |||
JS_BEGIN_MACRO \ | JS_BEGIN_MACRO \ | |||
JS_LOCK_RUNTIME(rt); \ | JS_LOCK_RUNTIME(rt); \ | |||
e; \ | e; \ | |||
JS_UNLOCK_RUNTIME(rt); \ | JS_UNLOCK_RUNTIME(rt); \ | |||
JS_END_MACRO | JS_END_MACRO | |||
skipping to change at line 266 | skipping to change at line 304 | |||
#define JS_LOCK_GC_VOID(rt,e) (JS_LOCK_GC(rt), (e), JS_UNLOCK_GC(rt)) | #define JS_LOCK_GC_VOID(rt,e) (JS_LOCK_GC(rt), (e), JS_UNLOCK_GC(rt)) | |||
#define JS_AWAIT_GC_DONE(rt) JS_WAIT_CONDVAR((rt)->gcDone, JS_NO_TIM EOUT) | #define JS_AWAIT_GC_DONE(rt) JS_WAIT_CONDVAR((rt)->gcDone, JS_NO_TIM EOUT) | |||
#define JS_NOTIFY_GC_DONE(rt) JS_NOTIFY_ALL_CONDVAR((rt)->gcDone) | #define JS_NOTIFY_GC_DONE(rt) JS_NOTIFY_ALL_CONDVAR((rt)->gcDone) | |||
#define JS_AWAIT_REQUEST_DONE(rt) JS_WAIT_CONDVAR((rt)->requestDone, \ | #define JS_AWAIT_REQUEST_DONE(rt) JS_WAIT_CONDVAR((rt)->requestDone, \ | |||
JS_NO_TIMEOUT) | JS_NO_TIMEOUT) | |||
#define JS_NOTIFY_REQUEST_DONE(rt) JS_NOTIFY_CONDVAR((rt)->requestDone) | #define JS_NOTIFY_REQUEST_DONE(rt) JS_NOTIFY_CONDVAR((rt)->requestDone) | |||
#define JS_LOCK(P,CX) JS_LOCK0(P, CX_THINLOCK_ID(CX)) | #define JS_LOCK(P,CX) JS_LOCK0(P, CX_THINLOCK_ID(CX)) | |||
#define JS_UNLOCK(P,CX) JS_UNLOCK0(P, CX_THINLOCK_ID(CX)) | #define JS_UNLOCK(P,CX) JS_UNLOCK0(P, CX_THINLOCK_ID(CX)) | |||
#ifndef SET_OBJ_INFO | ||||
#define SET_OBJ_INFO(obj,f,l) ((void)0) | ||||
#endif | ||||
#ifndef SET_TITLE_INFO | ||||
#define SET_TITLE_INFO(title,f,l) ((void)0) | ||||
#endif | ||||
JS_END_EXTERN_C | ||||
#endif /* jslock_h___ */ | #endif /* jslock_h___ */ | |||
End of changes. 17 change blocks. | ||||
45 lines changed or deleted | 101 lines changed or added | |||
jslong.h | jslong.h | |||
---|---|---|---|---|
skipping to change at line 54 | skipping to change at line 54 | |||
** don't support 64 bit integers yet, so we use these macros to | ** don't support 64 bit integers yet, so we use these macros to | |||
** support both machines that do and don't. | ** support both machines that do and don't. | |||
**/ | **/ | |||
#ifndef jslong_h___ | #ifndef jslong_h___ | |||
#define jslong_h___ | #define jslong_h___ | |||
#include "jstypes.h" | #include "jstypes.h" | |||
JS_BEGIN_EXTERN_C | JS_BEGIN_EXTERN_C | |||
/*********************************************************************** | ||||
** DEFINES: JSLL_MaxInt | ||||
** JSLL_MinInt | ||||
** JSLL_Zero | ||||
** DESCRIPTION: | ||||
** Various interesting constants and static variable | ||||
** initializer | ||||
***********************************************************************/ | ||||
#ifdef HAVE_WATCOM_BUG_2 | ||||
JSInt64 __pascal __loadds __export | ||||
JSLL_MaxInt(void); | ||||
JSInt64 __pascal __loadds __export | ||||
JSLL_MinInt(void); | ||||
JSInt64 __pascal __loadds __export | ||||
JSLL_Zero(void); | ||||
#else | ||||
extern JS_PUBLIC_API(JSInt64) JSLL_MaxInt(void); | ||||
extern JS_PUBLIC_API(JSInt64) JSLL_MinInt(void); | ||||
extern JS_PUBLIC_API(JSInt64) JSLL_Zero(void); | ||||
#endif | ||||
#define JSLL_MAXINT JSLL_MaxInt() | ||||
#define JSLL_MININT JSLL_MinInt() | ||||
#define JSLL_ZERO JSLL_Zero() | ||||
#ifdef JS_HAVE_LONG_LONG | #ifdef JS_HAVE_LONG_LONG | |||
#if JS_BYTES_PER_LONG == 8 | #if JS_BYTES_PER_LONG == 8 | |||
#define JSLL_INIT(hi, lo) ((hi ## L << 32) + lo ## L) | #define JSLL_INIT(hi, lo) ((hi ## L << 32) + lo ## L) | |||
#elif (defined(WIN32) || defined(WIN16)) && !defined(__GNUC__) | #elif (defined(WIN32) || defined(WIN16)) && !defined(__GNUC__) | |||
#define JSLL_INIT(hi, lo) ((hi ## i64 << 32) + lo ## i64) | #define JSLL_INIT(hi, lo) ((hi ## i64 << 32) + lo ## i64) | |||
#else | #else | |||
#define JSLL_INIT(hi, lo) ((hi ## LL << 32) + lo ## LL) | #define JSLL_INIT(hi, lo) ((hi ## LL << 32) + lo ## LL) | |||
#endif | #endif | |||
End of changes. 1 change blocks. | ||||
25 lines changed or deleted | 0 lines changed or added | |||
jsnum.h | jsnum.h | |||
---|---|---|---|---|
skipping to change at line 49 | skipping to change at line 49 | |||
#ifndef jsnum_h___ | #ifndef jsnum_h___ | |||
#define jsnum_h___ | #define jsnum_h___ | |||
/* | /* | |||
* JS number (IEEE double) interface. | * JS number (IEEE double) interface. | |||
* | * | |||
* JS numbers are optimistically stored in the top 31 bits of 32-bit intege rs, | * JS numbers are optimistically stored in the top 31 bits of 32-bit intege rs, | |||
* but floating point literals, results that overflow 31 bits, and division and | * but floating point literals, results that overflow 31 bits, and division and | |||
* modulus operands and results require a 64-bit IEEE double. These are GC 'ed | * modulus operands and results require a 64-bit IEEE double. These are GC 'ed | |||
* and pointed to by 32-bit jsvals on the stack and in object properties. | * and pointed to by 32-bit jsvals on the stack and in object properties. | |||
* | ||||
* When a JS number is treated as an object (followed by . or []), the runt | ||||
ime | ||||
* wraps it with a JSObject whose valueOf method returns the unwrapped numb | ||||
er. | ||||
*/ | */ | |||
JS_BEGIN_EXTERN_C | JS_BEGIN_EXTERN_C | |||
/* | /* | |||
* Stefan Hanske <sh990154@mail.uni-greifswald.de> reports: | * The ARM architecture supports two floating point models: VFP and FPA. Wh | |||
* ARM is a little endian architecture but 64 bit double words are stored | en | |||
* differently: the 32 bit words are in little endian byte order, the two w | * targetting FPA, doubles are mixed-endian on little endian ARMs (meaning | |||
ords | that | |||
* are stored in big endian`s way. | * the high and low words are in big endian order). | |||
*/ | */ | |||
#if defined(__arm) || defined(__arm32__) || defined(__arm26__) || defined(_ _arm__) | #if defined(__arm) || defined(__arm32__) || defined(__arm26__) || defined(_ _arm__) | |||
#define CPU_IS_ARM | #if !defined(__VFP_FP__) | |||
#define FPU_IS_ARM_FPA | ||||
#endif | ||||
#endif | #endif | |||
typedef union jsdpun { | typedef union jsdpun { | |||
struct { | struct { | |||
#if defined(IS_LITTLE_ENDIAN) && !defined(CPU_IS_ARM) | #if defined(IS_LITTLE_ENDIAN) && !defined(FPU_IS_ARM_FPA) | |||
uint32 lo, hi; | uint32 lo, hi; | |||
#else | #else | |||
uint32 hi, lo; | uint32 hi, lo; | |||
#endif | #endif | |||
} s; | } s; | |||
jsdouble d; | jsdouble d; | |||
} jsdpun; | } jsdpun; | |||
#if (__GNUC__ == 2 && __GNUC_MINOR__ > 95) || __GNUC__ > 2 | #if (__GNUC__ == 2 && __GNUC_MINOR__ > 95) || __GNUC__ > 2 | |||
/* | /* | |||
skipping to change at line 98 | skipping to change at line 95 | |||
#define JSDOUBLE_SET_LO32(x, y) \ | #define JSDOUBLE_SET_LO32(x, y) \ | |||
(__extension__ ({ jsdpun u; u.d = (x); u.s.lo = (y); (x) = u.d; })) | (__extension__ ({ jsdpun u; u.d = (x); u.s.lo = (y); (x) = u.d; })) | |||
#else /* not or old GNUC */ | #else /* not or old GNUC */ | |||
/* | /* | |||
* We don't know of any non-gcc compilers that perform alias optimization, | * We don't know of any non-gcc compilers that perform alias optimization, | |||
* so this code should work. | * so this code should work. | |||
*/ | */ | |||
#if defined(IS_LITTLE_ENDIAN) && !defined(CPU_IS_ARM) | #if defined(IS_LITTLE_ENDIAN) && !defined(FPU_IS_ARM_FPA) | |||
#define JSDOUBLE_HI32(x) (((uint32 *)&(x))[1]) | #define JSDOUBLE_HI32(x) (((uint32 *)&(x))[1]) | |||
#define JSDOUBLE_LO32(x) (((uint32 *)&(x))[0]) | #define JSDOUBLE_LO32(x) (((uint32 *)&(x))[0]) | |||
#else | #else | |||
#define JSDOUBLE_HI32(x) (((uint32 *)&(x))[0]) | #define JSDOUBLE_HI32(x) (((uint32 *)&(x))[0]) | |||
#define JSDOUBLE_LO32(x) (((uint32 *)&(x))[1]) | #define JSDOUBLE_LO32(x) (((uint32 *)&(x))[1]) | |||
#endif | #endif | |||
#define JSDOUBLE_SET_HI32(x, y) (JSDOUBLE_HI32(x)=(y)) | #define JSDOUBLE_SET_HI32(x, y) (JSDOUBLE_HI32(x)=(y)) | |||
#define JSDOUBLE_SET_LO32(x, y) (JSDOUBLE_LO32(x)=(y)) | #define JSDOUBLE_SET_LO32(x, y) (JSDOUBLE_LO32(x)=(y)) | |||
skipping to change at line 153 | skipping to change at line 150 | |||
: (LVAL) OP (RVAL)) | : (LVAL) OP (RVAL)) | |||
#else | #else | |||
#define JSDOUBLE_COMPARE(LVAL, OP, RVAL, IFNAN) ((LVAL) OP (RVAL)) | #define JSDOUBLE_COMPARE(LVAL, OP, RVAL, IFNAN) ((LVAL) OP (RVAL)) | |||
#endif | #endif | |||
/* Initialize number constants and runtime state for the first context. */ | /* Initialize number constants and runtime state for the first context. */ | |||
extern JSBool | extern JSBool | |||
js_InitRuntimeNumberState(JSContext *cx); | js_InitRuntimeNumberState(JSContext *cx); | |||
extern void | extern void | |||
js_TraceRuntimeNumberState(JSTracer *trc); | ||||
extern void | ||||
js_FinishRuntimeNumberState(JSContext *cx); | js_FinishRuntimeNumberState(JSContext *cx); | |||
/* Initialize the Number class, returning its prototype object. */ | /* Initialize the Number class, returning its prototype object. */ | |||
extern JSClass js_NumberClass; | extern JSClass js_NumberClass; | |||
extern JSObject * | extern JSObject * | |||
js_InitNumberClass(JSContext *cx, JSObject *obj); | js_InitNumberClass(JSContext *cx, JSObject *obj); | |||
/* | /* | |||
* String constants for global function names, used in jsapi.c and jsnum.c. | * String constants for global function names, used in jsapi.c and jsnum.c. | |||
*/ | */ | |||
extern const char js_Infinity_str[]; | extern const char js_Infinity_str[]; | |||
extern const char js_NaN_str[]; | extern const char js_NaN_str[]; | |||
extern const char js_isNaN_str[]; | extern const char js_isNaN_str[]; | |||
extern const char js_isFinite_str[]; | extern const char js_isFinite_str[]; | |||
extern const char js_parseFloat_str[]; | extern const char js_parseFloat_str[]; | |||
extern const char js_parseInt_str[]; | extern const char js_parseInt_str[]; | |||
/* GC-allocate a new JS number. */ | /* | |||
extern jsdouble * | * vp must be a root. | |||
js_NewDouble(JSContext *cx, jsdouble d, uintN gcflag); | */ | |||
extern void | ||||
js_FinalizeDouble(JSContext *cx, jsdouble *dp); | ||||
extern JSBool | ||||
js_NewDoubleValue(JSContext *cx, jsdouble d, jsval *rval); | ||||
extern JSBool | extern JSBool | |||
js_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval); | js_NewNumberInRootedValue(JSContext *cx, jsdouble d, jsval *vp); | |||
/* Construct a Number instance that wraps around d. */ | ||||
extern JSObject * | ||||
js_NumberToObject(JSContext *cx, jsdouble d); | ||||
/* Convert a number to a GC'ed string. */ | /* Convert a number to a GC'ed string. */ | |||
extern JSString * | extern JSString * | |||
js_NumberToString(JSContext *cx, jsdouble d); | js_NumberToString(JSContext *cx, jsdouble d); | |||
/* | /* | |||
* Convert a value to a number, returning false after reporting any error, | * Convert int to C string. The buf must be big enough for MIN_INT to fit | |||
* otherwise returning true with *dp set. | * including '-' and '\0'. | |||
*/ | */ | |||
extern JSBool | char * | |||
js_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp); | js_IntToCString(jsint i, char *buf, size_t bufSize); | |||
/* | /* | |||
* Convert a value or a double to an int32, according to the ECMA rules | * Convert a number to C string. The buf must be at least | |||
* for ToInt32. | * DTOSTR_STANDARD_BUFFER_SIZE. | |||
*/ | */ | |||
extern JSBool | char * | |||
js_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip); | js_NumberToCString(JSContext *cx, jsdouble d, char *buf, size_t bufSize); | |||
extern JSBool | /* | |||
js_DoubleToECMAInt32(JSContext *cx, jsdouble d, int32 *ip); | * Convert a value to a number. On exit JSVAL_IS_NULL(*vp) iff there was an | |||
* error. If on exit JSVAL_IS_NUMBER(*vp), then *vp holds the jsval that | ||||
* matches the result. Otherwise *vp is JSVAL_TRUE indicating that the jsva | ||||
l | ||||
* for result has to be created explicitly using, for example, the | ||||
* js_NewNumberInRootedValue function. | ||||
*/ | ||||
extern jsdouble | ||||
js_ValueToNumber(JSContext *cx, jsval* vp); | ||||
/* | /* | |||
* Convert a value or a double to a uint32, according to the ECMA rules | * Convert a value to an int32 or uint32, according to the ECMA rules for | |||
* for ToUint32. | * ToInt32 and ToUint32. On exit JSVAL_IS_NULL(*vp) iff there was an error. | |||
If | ||||
* on exit JSVAL_IS_INT(*vp), then *vp holds the jsval matching the result. | ||||
* Otherwise *vp is JSVAL_TRUE indicating that the jsval for result has to | ||||
be | ||||
* created explicitly using, for example, the js_NewNumberInRootedValue | ||||
* function. | ||||
*/ | */ | |||
extern JSBool | extern int32 | |||
js_ValueToECMAUint32(JSContext *cx, jsval v, uint32 *ip); | js_ValueToECMAInt32(JSContext *cx, jsval *vp); | |||
extern JSBool | extern uint32 | |||
js_DoubleToECMAUint32(JSContext *cx, jsdouble d, uint32 *ip); | js_ValueToECMAUint32(JSContext *cx, jsval *vp); | |||
/* | ||||
* Specialized ToInt32 and ToUint32 converters for doubles. | ||||
*/ | ||||
extern int32 | ||||
js_DoubleToECMAInt32(jsdouble d); | ||||
extern uint32 | ||||
js_DoubleToECMAUint32(jsdouble d); | ||||
/* | /* | |||
* Convert a value to a number, then to an int32 if it fits by rounding to | * Convert a value to a number, then to an int32 if it fits by rounding to | |||
* nearest; but failing with an error report if the double is out of range | * nearest; but failing with an error report if the double is out of range | |||
* or unordered. | * or unordered. On exit JSVAL_IS_NULL(*vp) iff there was an error. If on e | |||
xit | ||||
* JSVAL_IS_INT(*vp), then *vp holds the jsval matching the result. Otherwi | ||||
se | ||||
* *vp is JSVAL_TRUE indicating that the jsval for result has to be created | ||||
* explicitly using, for example, the js_NewNumberInRootedValue function. | ||||
*/ | */ | |||
extern JSBool | extern int32 | |||
js_ValueToInt32(JSContext *cx, jsval v, int32 *ip); | js_ValueToInt32(JSContext *cx, jsval *vp); | |||
/* | /* | |||
* Convert a value to a number, then to a uint16 according to the ECMA rule s | * Convert a value to a number, then to a uint16 according to the ECMA rule s | |||
* for ToUint16. | * for ToUint16. On exit JSVAL_IS_NULL(*vp) iff there was an error, otherwi | |||
se | ||||
* vp is jsval matching the result. | ||||
*/ | */ | |||
extern JSBool | extern uint16 | |||
js_ValueToUint16(JSContext *cx, jsval v, uint16 *ip); | js_ValueToUint16(JSContext *cx, jsval *vp); | |||
/* | /* | |||
* Convert a jsdouble to an integral number, stored in a jsdouble. | * Convert a jsdouble to an integral number, stored in a jsdouble. | |||
* If d is NaN, return 0. If d is an infinity, return it without conversio n. | * If d is NaN, return 0. If d is an infinity, return it without conversio n. | |||
*/ | */ | |||
extern jsdouble | extern jsdouble | |||
js_DoubleToInteger(jsdouble d); | js_DoubleToInteger(jsdouble d); | |||
/* | /* | |||
* Similar to strtod except that it replaces overflows with infinities of t he | * Similar to strtod except that it replaces overflows with infinities of t he | |||
* correct sign, and underflows with zeros of the correct sign. Guaranteed to | * correct sign, and underflows with zeros of the correct sign. Guaranteed to | |||
* return the closest double number to the given input in dp. | * return the closest double number to the given input in dp. | |||
* | * | |||
* Also allows inputs of the form [+|-]Infinity, which produce an infinity of | * Also allows inputs of the form [+|-]Infinity, which produce an infinity of | |||
* the appropriate sign. The case of the "Infinity" string must match exac tly. | * the appropriate sign. The case of the "Infinity" string must match exac tly. | |||
* If the string does not contain a number, set *ep to s and return 0.0 in dp. | * If the string does not contain a number, set *ep to s and return 0.0 in dp. | |||
* Return false if out of memory. | * Return false if out of memory. | |||
*/ | */ | |||
extern JSBool | extern JSBool | |||
js_strtod(JSContext *cx, const jschar *s, const jschar **ep, jsdouble *dp); | js_strtod(JSContext *cx, const jschar *s, const jschar *send, | |||
const jschar **ep, jsdouble *dp); | ||||
/* | /* | |||
* Similar to strtol except that it handles integers of arbitrary size. | * Similar to strtol except that it handles integers of arbitrary size. | |||
* Guaranteed to return the closest double number to the given input when r adix | * Guaranteed to return the closest double number to the given input when r adix | |||
* is 10 or a power of 2. Callers may see round-off errors for very large | * is 10 or a power of 2. Callers may see round-off errors for very large | |||
* numbers of a different radix than 10 or a power of 2. | * numbers of a different radix than 10 or a power of 2. | |||
* | * | |||
* If the string does not contain a number, set *ep to s and return 0.0 in dp. | * If the string does not contain a number, set *ep to s and return 0.0 in dp. | |||
* Return false if out of memory. | * Return false if out of memory. | |||
*/ | */ | |||
extern JSBool | extern JSBool | |||
js_strtointeger(JSContext *cx, const jschar *s, const jschar **ep, jsint ra | js_strtointeger(JSContext *cx, const jschar *s, const jschar *send, | |||
dix, jsdouble *dp); | const jschar **ep, jsint radix, jsdouble *dp); | |||
JS_END_EXTERN_C | JS_END_EXTERN_C | |||
#endif /* jsnum_h___ */ | #endif /* jsnum_h___ */ | |||
End of changes. 23 change blocks. | ||||
54 lines changed or deleted | 73 lines changed or added | |||
jsobj.h | jsobj.h | |||
---|---|---|---|---|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- | |||
* vim: set ts=8 sw=4 et tw=80: | * vim: set ts=8 sw=4 et tw=78: | |||
* | * | |||
* ***** BEGIN LICENSE BLOCK ***** | * ***** BEGIN LICENSE BLOCK ***** | |||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | |||
* | * | |||
* The contents of this file are subject to the Mozilla Public License Vers ion | * The contents of this file are subject to the Mozilla Public License Vers ion | |||
* 1.1 (the "License"); you may not use this file except in compliance with | * 1.1 (the "License"); you may not use this file except in compliance with | |||
* the License. You may obtain a copy of the License at | * the License. You may obtain a copy of the License at | |||
* http://www.mozilla.org/MPL/ | * http://www.mozilla.org/MPL/ | |||
* | * | |||
* Software distributed under the License is distributed on an "AS IS" basi s, | * Software distributed under the License is distributed on an "AS IS" basi s, | |||
skipping to change at line 60 | skipping to change at line 60 | |||
*/ | */ | |||
#include "jshash.h" /* Added by JSIFY */ | #include "jshash.h" /* Added by JSIFY */ | |||
#include "jsprvtd.h" | #include "jsprvtd.h" | |||
#include "jspubtd.h" | #include "jspubtd.h" | |||
JS_BEGIN_EXTERN_C | JS_BEGIN_EXTERN_C | |||
struct JSObjectMap { | struct JSObjectMap { | |||
jsrefcount nrefs; /* count of all referencing objects */ | jsrefcount nrefs; /* count of all referencing objects */ | |||
JSObjectOps *ops; /* high level object operation vtable */ | JSObjectOps *ops; /* high level object operation vtable */ | |||
uint32 nslots; /* length of obj->slots vector */ | uint32 freeslot; /* index of next free slot in object */ | |||
uint32 freeslot; /* index of next free obj->slots element */ | ||||
}; | }; | |||
/* Shorthand macros for frequently-made calls. */ | /* Shorthand macros for frequently-made calls. */ | |||
#define OBJ_LOOKUP_PROPERTY(cx,obj,id,objp,propp) \ | #define OBJ_LOOKUP_PROPERTY(cx,obj,id,objp,propp) \ | |||
(obj)->map->ops->lookupProperty(cx,obj,id,objp,propp) | (obj)->map->ops->lookupProperty(cx,obj,id,objp,propp) | |||
#define OBJ_DEFINE_PROPERTY(cx,obj,id,value,getter,setter,attrs,propp) \ | #define OBJ_DEFINE_PROPERTY(cx,obj,id,value,getter,setter,attrs,propp) \ | |||
(obj)->map->ops->defineProperty(cx,obj,id,value,getter,setter,attrs,pro pp) | (obj)->map->ops->defineProperty(cx,obj,id,value,getter,setter,attrs,pro pp) | |||
#define OBJ_GET_PROPERTY(cx,obj,id,vp) \ | #define OBJ_GET_PROPERTY(cx,obj,id,vp) \ | |||
(obj)->map->ops->getProperty(cx,obj,id,vp) | (obj)->map->ops->getProperty(cx,obj,id,vp) | |||
#define OBJ_SET_PROPERTY(cx,obj,id,vp) \ | #define OBJ_SET_PROPERTY(cx,obj,id,vp) \ | |||
skipping to change at line 114 | skipping to change at line 113 | |||
#define OBJ_TO_INNER_OBJECT(cx,obj) \ | #define OBJ_TO_INNER_OBJECT(cx,obj) \ | |||
JS_BEGIN_MACRO \ | JS_BEGIN_MACRO \ | |||
JSClass *clasp_ = OBJ_GET_CLASS(cx, obj); \ | JSClass *clasp_ = OBJ_GET_CLASS(cx, obj); \ | |||
if (clasp_->flags & JSCLASS_IS_EXTENDED) { \ | if (clasp_->flags & JSCLASS_IS_EXTENDED) { \ | |||
JSExtendedClass *xclasp_ = (JSExtendedClass*)clasp_; \ | JSExtendedClass *xclasp_ = (JSExtendedClass*)clasp_; \ | |||
if (xclasp_->innerObject) \ | if (xclasp_->innerObject) \ | |||
obj = xclasp_->innerObject(cx, obj); \ | obj = xclasp_->innerObject(cx, obj); \ | |||
} \ | } \ | |||
JS_END_MACRO | JS_END_MACRO | |||
#define OBJ_TO_OUTER_OBJECT(cx,obj) | ||||
\ | ||||
JS_BEGIN_MACRO | ||||
\ | ||||
JSClass *clasp_ = OBJ_GET_CLASS(cx, obj); | ||||
\ | ||||
if (clasp_->flags & JSCLASS_IS_EXTENDED) { | ||||
\ | ||||
JSExtendedClass *xclasp_ = (JSExtendedClass*)clasp_; | ||||
\ | ||||
if (xclasp_->outerObject) | ||||
\ | ||||
obj = xclasp_->outerObject(cx, obj); | ||||
\ | ||||
} | ||||
\ | ||||
JS_END_MACRO | ||||
#define JS_INITIAL_NSLOTS 6 | ||||
/* | /* | |||
* In the original JS engine design, obj->slots pointed to a vector of leng | * When JSObject.dslots is not null, JSObject.dslots[-1] records the number | |||
th | of | |||
* JS_INITIAL_NSLOTS words if obj->map was shared with a prototype object, | * available slots. | |||
* else of length obj->map->nslots. With the advent of JS_GetReservedSlot, | ||||
* JS_SetReservedSlot, and JSCLASS_HAS_RESERVED_SLOTS (see jsapi.h), the si | ||||
ze | ||||
* of the minimum length slots vector in the case where map is shared canno | ||||
t | ||||
* be constant. This length starts at JS_INITIAL_NSLOTS, but may advance t | ||||
o | ||||
* include all the reserved slots. | ||||
* | ||||
* Therefore slots must be self-describing. Rather than tag its low order | ||||
bit | ||||
* (a bit is all we need) to distinguish initial length from reserved lengt | ||||
h, | ||||
* we do "the BSTR thing": over-allocate slots by one jsval, and store the | ||||
* *net* length (counting usable slots, which have non-negative obj->slots[ | ||||
] | ||||
* indices) in obj->slots[-1]. All code that sets obj->slots must be aware | ||||
of | ||||
* this hack -- you have been warned, and jsobj.c has been updated! | ||||
*/ | */ | |||
struct JSObject { | struct JSObject { | |||
JSObjectMap *map; | JSObjectMap *map; | |||
jsval *slots; | jsval fslots[JS_INITIAL_NSLOTS]; | |||
jsval *dslots; /* dynamically allocated slots */ | ||||
}; | }; | |||
#define JSSLOT_PROTO 0 | #define JSSLOT_PROTO 0 | |||
#define JSSLOT_PARENT 1 | #define JSSLOT_PARENT 1 | |||
#define JSSLOT_CLASS 2 | #define JSSLOT_CLASS 2 | |||
#define JSSLOT_PRIVATE 3 | #define JSSLOT_PRIVATE 3 | |||
#define JSSLOT_START(clasp) (((clasp)->flags & JSCLASS_HAS_PRIVATE) \ | #define JSSLOT_START(clasp) (((clasp)->flags & JSCLASS_HAS_PRIVATE) \ | |||
? JSSLOT_PRIVATE + 1 \ | ? JSSLOT_PRIVATE + 1 \ | |||
: JSSLOT_CLASS + 1) | : JSSLOT_CLASS + 1) | |||
#define JSSLOT_FREE(clasp) (JSSLOT_START(clasp) \ | #define JSSLOT_FREE(clasp) (JSSLOT_START(clasp) \ | |||
+ JSCLASS_RESERVED_SLOTS(clasp)) | + JSCLASS_RESERVED_SLOTS(clasp)) | |||
#define JS_INITIAL_NSLOTS 5 | /* | |||
* STOBJ prefix means Single Threaded Object. Use the following fast macros | ||||
to | ||||
* directly manipulate slots in obj when only one thread can access obj and | ||||
* when obj->map->freeslot can be inconsistent with slots. | ||||
*/ | ||||
#ifdef DEBUG | #define STOBJ_NSLOTS(obj) | |||
#define MAP_CHECK_SLOT(map,slot) \ | \ | |||
JS_ASSERT((uint32)slot < JS_MIN((map)->freeslot, (map)->nslots)) | ((obj)->dslots ? (uint32)(obj)->dslots[-1] : (uint32)JS_INITIAL_NSLOTS) | |||
#define OBJ_CHECK_SLOT(obj,slot) \ | ||||
MAP_CHECK_SLOT((obj)->map, slot) | #define STOBJ_GET_SLOT(obj,slot) | |||
#else | \ | |||
#define OBJ_CHECK_SLOT(obj,slot) ((void)0) | ((slot) < JS_INITIAL_NSLOTS | |||
#endif | \ | |||
? (obj)->fslots[(slot)] | ||||
\ | ||||
: (JS_ASSERT((slot) < (uint32)(obj)->dslots[-1]), | ||||
\ | ||||
(obj)->dslots[(slot) - JS_INITIAL_NSLOTS])) | ||||
#define STOBJ_SET_SLOT(obj,slot,value) | ||||
\ | ||||
((slot) < JS_INITIAL_NSLOTS | ||||
\ | ||||
? (obj)->fslots[(slot)] = (value) | ||||
\ | ||||
: (JS_ASSERT((slot) < (uint32)(obj)->dslots[-1]), | ||||
\ | ||||
(obj)->dslots[(slot) - JS_INITIAL_NSLOTS] = (value))) | ||||
#define STOBJ_GET_PROTO(obj) | ||||
\ | ||||
JSVAL_TO_OBJECT((obj)->fslots[JSSLOT_PROTO]) | ||||
#define STOBJ_SET_PROTO(obj,proto) | ||||
\ | ||||
((obj)->fslots[JSSLOT_PROTO] = OBJECT_TO_JSVAL(proto)) | ||||
#define STOBJ_GET_PARENT(obj) | ||||
\ | ||||
JSVAL_TO_OBJECT((obj)->fslots[JSSLOT_PARENT]) | ||||
#define STOBJ_SET_PARENT(obj,parent) | ||||
\ | ||||
((obj)->fslots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(parent)) | ||||
/* | ||||
* We use JSSLOT_CLASS to store both JSClass* and the system flag as an int | ||||
- | ||||
* tagged value (see jsapi.h for details) with the system flag stored in th | ||||
e | ||||
* second lowest bit. | ||||
*/ | ||||
#define STOBJ_GET_CLASS(obj) ((JSClass *)((obj)->fslots[JSSLOT_CLASS] & | ||||
~3)) | ||||
#define STOBJ_IS_SYSTEM(obj) (((obj)->fslots[JSSLOT_CLASS] & 2) != 0) | ||||
#define STOBJ_SET_SYSTEM(obj) ((void)((obj)->fslots[JSSLOT_CLASS] |= 2)) | ||||
#define STOBJ_GET_PRIVATE(obj) | ||||
\ | ||||
(JS_ASSERT(JSVAL_IS_INT(STOBJ_GET_SLOT(obj, JSSLOT_PRIVATE))), | ||||
\ | ||||
JSVAL_TO_PRIVATE(STOBJ_GET_SLOT(obj, JSSLOT_PRIVATE))) | ||||
#define OBJ_CHECK_SLOT(obj,slot) | ||||
\ | ||||
JS_ASSERT(slot < (obj)->map->freeslot) | ||||
#define LOCKED_OBJ_GET_SLOT(obj,slot) | ||||
\ | ||||
(OBJ_CHECK_SLOT(obj, slot), STOBJ_GET_SLOT(obj, slot)) | ||||
#define LOCKED_OBJ_SET_SLOT(obj,slot,value) | ||||
\ | ||||
(OBJ_CHECK_SLOT(obj, slot), STOBJ_SET_SLOT(obj, slot, value)) | ||||
/* | ||||
* NB: Don't call LOCKED_OBJ_SET_SLOT or STOBJ_SET_SLOT for a write to a sl | ||||
ot | ||||
* that may contain a function reference already, or where the new value is | ||||
a | ||||
* function ref, and the object's scope may be branded with a property cach | ||||
e | ||||
* structural type capability that distinguishes versions of the object wit | ||||
h | ||||
* and without the function property. Instead use LOCKED_OBJ_WRITE_BARRIER | ||||
or | ||||
* a fast inline equivalent (JSOP_SETNAME/JSOP_SETPROP cases in jsinterp.c) | ||||
. | ||||
*/ | ||||
#define LOCKED_OBJ_WRITE_BARRIER(cx,obj,slot,newval) | ||||
\ | ||||
JS_BEGIN_MACRO | ||||
\ | ||||
JSScope *scope_ = OBJ_SCOPE(obj); | ||||
\ | ||||
JS_ASSERT(scope_->object == (obj)); | ||||
\ | ||||
GC_WRITE_BARRIER(cx, scope_, LOCKED_OBJ_GET_SLOT(obj, slot), newval | ||||
); \ | ||||
LOCKED_OBJ_SET_SLOT(obj, slot, newval); | ||||
\ | ||||
JS_END_MACRO | ||||
/* Fast macros for accessing obj->slots while obj is locked (if thread-safe | ||||
). */ | ||||
#define LOCKED_OBJ_GET_SLOT(obj,slot) \ | ||||
(OBJ_CHECK_SLOT(obj, slot), (obj)->slots[slot]) | ||||
#define LOCKED_OBJ_SET_SLOT(obj,slot,value) \ | ||||
(OBJ_CHECK_SLOT(obj, slot), (obj)->slots[slot] = (value)) | ||||
#define LOCKED_OBJ_GET_PROTO(obj) \ | #define LOCKED_OBJ_GET_PROTO(obj) \ | |||
JSVAL_TO_OBJECT(LOCKED_OBJ_GET_SLOT(obj, JSSLOT_PROTO)) | (OBJ_CHECK_SLOT(obj, JSSLOT_PROTO), STOBJ_GET_PROTO(obj)) | |||
#define LOCKED_OBJ_SET_PROTO(obj,proto) \ | ||||
(OBJ_CHECK_SLOT(obj, JSSLOT_PROTO), STOBJ_SET_PROTO(obj, proto)) | ||||
#define LOCKED_OBJ_GET_PARENT(obj) \ | ||||
(OBJ_CHECK_SLOT(obj, JSSLOT_PARENT), STOBJ_GET_PARENT(obj)) | ||||
#define LOCKED_OBJ_SET_PARENT(obj,parent) \ | ||||
(OBJ_CHECK_SLOT(obj, JSSLOT_PARENT), STOBJ_SET_PARENT(obj, parent)) | ||||
#define LOCKED_OBJ_GET_CLASS(obj) \ | #define LOCKED_OBJ_GET_CLASS(obj) \ | |||
((JSClass *)JSVAL_TO_PRIVATE(LOCKED_OBJ_GET_SLOT(obj, JSSLOT_CLASS))) | (OBJ_CHECK_SLOT(obj, JSSLOT_CLASS), STOBJ_GET_CLASS(obj)) | |||
#define LOCKED_OBJ_GET_PRIVATE(obj) \ | ||||
(OBJ_CHECK_SLOT(obj, JSSLOT_PRIVATE), STOBJ_GET_PRIVATE(obj)) | ||||
#ifdef JS_THREADSAFE | #ifdef JS_THREADSAFE | |||
/* Thread-safe functions and wrapper macros for accessing obj->slots. */ | /* Thread-safe functions and wrapper macros for accessing slots in obj. */ | |||
#define OBJ_GET_SLOT(cx,obj,slot) \ | #define OBJ_GET_SLOT(cx,obj,slot) \ | |||
(OBJ_CHECK_SLOT(obj, slot), \ | (OBJ_CHECK_SLOT(obj, slot), \ | |||
(OBJ_IS_NATIVE(obj) && OBJ_SCOPE(obj)->ownercx == cx) \ | (OBJ_IS_NATIVE(obj) && OBJ_SCOPE(obj)->title.ownercx == cx) \ | |||
? LOCKED_OBJ_GET_SLOT(obj, slot) \ | ? LOCKED_OBJ_GET_SLOT(obj, slot) \ | |||
: js_GetSlotThreadSafe(cx, obj, slot)) | : js_GetSlotThreadSafe(cx, obj, slot)) | |||
#define OBJ_SET_SLOT(cx,obj,slot,value) \ | #define OBJ_SET_SLOT(cx,obj,slot,value) \ | |||
(OBJ_CHECK_SLOT(obj, slot), | JS_BEGIN_MACRO | |||
\ | \ | |||
(OBJ_IS_NATIVE(obj) && OBJ_SCOPE(obj)->ownercx == cx) | OBJ_CHECK_SLOT(obj, slot); | |||
\ | \ | |||
? (void) LOCKED_OBJ_SET_SLOT(obj, slot, value) | if (OBJ_IS_NATIVE(obj) && OBJ_SCOPE(obj)->title.ownercx == cx) | |||
\ | \ | |||
: js_SetSlotThreadSafe(cx, obj, slot, value)) | LOCKED_OBJ_WRITE_BARRIER(cx, obj, slot, value); | |||
\ | ||||
else | ||||
\ | ||||
js_SetSlotThreadSafe(cx, obj, slot, value); | ||||
\ | ||||
JS_END_MACRO | ||||
/* | /* | |||
* If thread-safe, define an OBJ_GET_SLOT wrapper that bypasses, for a nati ve | * If thread-safe, define an OBJ_GET_SLOT wrapper that bypasses, for a nati ve | |||
* object, the lock-free "fast path" test of (OBJ_SCOPE(obj)->ownercx == cx ), | * object, the lock-free "fast path" test of (OBJ_SCOPE(obj)->ownercx == cx ), | |||
* to avoid needlessly switching from lock-free to lock-full scope when doi ng | * to avoid needlessly switching from lock-free to lock-full scope when doi ng | |||
* GC on a different context from the last one to own the scope. The calle r | * GC on a different context from the last one to own the scope. The calle r | |||
* in this case is probably a JSClass.mark function, e.g., fun_mark, or may be | * in this case is probably a JSClass.mark function, e.g., fun_mark, or may be | |||
* a finalizer. | * a finalizer. | |||
* | * | |||
* The GC runs only when all threads except the one on which the GC is acti ve | * The GC runs only when all threads except the one on which the GC is acti ve | |||
* are suspended at GC-safe points, so there is no hazard in directly acces | * are suspended at GC-safe points, so calling STOBJ_GET_SLOT from the GC's | |||
sing | * thread is safe when rt->gcRunning is set. See jsgc.c for details. | |||
* obj->slots[slot] from the GC's thread, once rt->gcRunning has been set. | ||||
See | ||||
* jsgc.c for details. | ||||
*/ | */ | |||
#define THREAD_IS_RUNNING_GC(rt, thread) \ | #define THREAD_IS_RUNNING_GC(rt, thread) \ | |||
((rt)->gcRunning && (rt)->gcThread == (thread)) | ((rt)->gcRunning && (rt)->gcThread == (thread)) | |||
#define CX_THREAD_IS_RUNNING_GC(cx) \ | #define CX_THREAD_IS_RUNNING_GC(cx) \ | |||
THREAD_IS_RUNNING_GC((cx)->runtime, (cx)->thread) | THREAD_IS_RUNNING_GC((cx)->runtime, (cx)->thread) | |||
#define GC_AWARE_GET_SLOT(cx, obj, slot) | ||||
\ | ||||
((OBJ_IS_NATIVE(obj) && CX_THREAD_IS_RUNNING_GC(cx)) | ||||
\ | ||||
? (obj)->slots[slot] | ||||
\ | ||||
: OBJ_GET_SLOT(cx, obj, slot)) | ||||
#else /* !JS_THREADSAFE */ | #else /* !JS_THREADSAFE */ | |||
#define OBJ_GET_SLOT(cx,obj,slot) LOCKED_OBJ_GET_SLOT(obj,slot) | #define OBJ_GET_SLOT(cx,obj,slot) LOCKED_OBJ_GET_SLOT(obj,slot) | |||
#define OBJ_SET_SLOT(cx,obj,slot,value) LOCKED_OBJ_SET_SLOT(obj,slot,value) | #define OBJ_SET_SLOT(cx,obj,slot,value) LOCKED_OBJ_WRITE_BARRIER(cx,obj,slo | |||
#define GC_AWARE_GET_SLOT(cx,obj,slot) LOCKED_OBJ_GET_SLOT(obj,slot) | t, \ | |||
value) | ||||
#endif /* !JS_THREADSAFE */ | #endif /* !JS_THREADSAFE */ | |||
/* Thread-safe proto, parent, and class access macros. */ | /* Thread-safe proto, parent, and class access macros. */ | |||
#define OBJ_GET_PROTO(cx,obj) \ | #define OBJ_GET_PROTO(cx,obj) \ | |||
JSVAL_TO_OBJECT(OBJ_GET_SLOT(cx, obj, JSSLOT_PROTO)) | STOBJ_GET_PROTO(obj) | |||
#define OBJ_SET_PROTO(cx,obj,proto) \ | #define OBJ_SET_PROTO(cx,obj,proto) \ | |||
OBJ_SET_SLOT(cx, obj, JSSLOT_PROTO, OBJECT_TO_JSVAL(proto)) | STOBJ_SET_SLOT(obj, JSSLOT_PROTO, OBJECT_TO_JSVAL(proto)) | |||
#define OBJ_GET_PARENT(cx,obj) \ | #define OBJ_GET_PARENT(cx,obj) \ | |||
JSVAL_TO_OBJECT(OBJ_GET_SLOT(cx, obj, JSSLOT_PARENT)) | STOBJ_GET_PARENT(obj) | |||
#define OBJ_SET_PARENT(cx,obj,parent) \ | #define OBJ_SET_PARENT(cx,obj,parent) \ | |||
OBJ_SET_SLOT(cx, obj, JSSLOT_PARENT, OBJECT_TO_JSVAL(parent)) | STOBJ_SET_SLOT(obj, JSSLOT_PARENT, OBJECT_TO_JSVAL(parent)) | |||
#define OBJ_GET_CLASS(cx,obj) \ | /* | |||
((JSClass *)JSVAL_TO_PRIVATE(OBJ_GET_SLOT(cx, obj, JSSLOT_CLASS))) | * Class is invariant and comes from the fixed JSSLOT_CLASS. Thus no lockin | |||
g | ||||
* is necessary to read it. Same for the private slot. | ||||
*/ | ||||
#define OBJ_GET_CLASS(cx,obj) STOBJ_GET_CLASS(obj) | ||||
#define OBJ_GET_PRIVATE(cx,obj) STOBJ_GET_PRIVATE(obj) | ||||
/* Test whether a map or object is native. */ | /* Test whether a map or object is native. */ | |||
#define MAP_IS_NATIVE(map) \ | #define MAP_IS_NATIVE(map) \ | |||
((map)->ops == &js_ObjectOps || | JS_LIKELY((map)->ops == &js_ObjectOps || | |||
\ | \ | |||
((map)->ops && (map)->ops->newObjectMap == js_ObjectOps.newObjectMap)) | (map)->ops->newObjectMap == js_ObjectOps.newObjectMap) | |||
#define OBJ_IS_NATIVE(obj) MAP_IS_NATIVE((obj)->map) | #define OBJ_IS_NATIVE(obj) MAP_IS_NATIVE((obj)->map) | |||
extern JS_FRIEND_DATA(JSObjectOps) js_ObjectOps; | extern JS_FRIEND_DATA(JSObjectOps) js_ObjectOps; | |||
extern JS_FRIEND_DATA(JSObjectOps) js_WithObjectOps; | extern JS_FRIEND_DATA(JSObjectOps) js_WithObjectOps; | |||
extern JSClass js_ObjectClass; | extern JSClass js_ObjectClass; | |||
extern JSClass js_WithClass; | extern JSClass js_WithClass; | |||
extern JSClass js_BlockClass; | extern JSClass js_BlockClass; | |||
/* | /* | |||
* Block scope object macros. The slots reserved by js_BlockClass are: | * Block scope object macros. The slots reserved by js_BlockClass are: | |||
* | * | |||
* JSSLOT_PRIVATE JSStackFrame * active frame pointer or null | * JSSLOT_PRIVATE JSStackFrame * active frame pointer or null | |||
* JSSLOT_BLOCK_DEPTH int depth of block slots in frame | * JSSLOT_BLOCK_DEPTH int depth of block slots in frame | |||
* | * | |||
* After JSSLOT_BLOCK_DEPTH come one or more slots for the block locals. | * After JSSLOT_BLOCK_DEPTH come one or more slots for the block locals. | |||
* OBJ_BLOCK_COUNT depends on this arrangement. | ||||
* | * | |||
* A With object is like a Block object, in that both have one reserved slo t | * A With object is like a Block object, in that both have one reserved slo t | |||
* telling the stack depth of the relevant slots (the slot whose value is t he | * telling the stack depth of the relevant slots (the slot whose value is t he | |||
* object named in the with statement, the slots containing the block's loc al | * object named in the with statement, the slots containing the block's loc al | |||
* variables); and both have a private slot referring to the JSStackFrame i n | * variables); and both have a private slot referring to the JSStackFrame i n | |||
* whose activation they were created (or null if the with or block object | * whose activation they were created (or null if the with or block object | |||
* outlives the frame). | * outlives the frame). | |||
*/ | */ | |||
#define JSSLOT_BLOCK_DEPTH (JSSLOT_PRIVATE + 1) | #define JSSLOT_BLOCK_DEPTH (JSSLOT_PRIVATE + 1) | |||
#define OBJ_BLOCK_COUNT(cx,obj) \ | #define OBJ_IS_CLONED_BLOCK(obj) | |||
((obj)->map->freeslot - (JSSLOT_BLOCK_DEPTH + 1)) | \ | |||
#define OBJ_BLOCK_DEPTH(cx,obj) \ | (OBJ_SCOPE(obj)->object != (obj)) | |||
JSVAL_TO_INT(OBJ_GET_SLOT(cx, obj, JSSLOT_BLOCK_DEPTH)) | #define OBJ_BLOCK_COUNT(cx,obj) | |||
#define OBJ_SET_BLOCK_DEPTH(cx,obj,depth) \ | \ | |||
OBJ_SET_SLOT(cx, obj, JSSLOT_BLOCK_DEPTH, INT_TO_JSVAL(depth)) | (OBJ_SCOPE(obj)->entryCount) | |||
#define OBJ_BLOCK_DEPTH(cx,obj) | ||||
\ | ||||
JSVAL_TO_INT(STOBJ_GET_SLOT(obj, JSSLOT_BLOCK_DEPTH)) | ||||
#define OBJ_SET_BLOCK_DEPTH(cx,obj,depth) | ||||
\ | ||||
STOBJ_SET_SLOT(obj, JSSLOT_BLOCK_DEPTH, INT_TO_JSVAL(depth)) | ||||
/* | /* | |||
* To make sure this slot is well-defined, always call js_NewWithObject to | * To make sure this slot is well-defined, always call js_NewWithObject to | |||
* create a With object, don't call js_NewObject directly. When creating a | * create a With object, don't call js_NewObject directly. When creating a | |||
* With object that does not correspond to a stack slot, pass -1 for depth. | * With object that does not correspond to a stack slot, pass -1 for depth. | |||
* | * | |||
* When popping the stack across this object's "with" statement, client cod e | * When popping the stack across this object's "with" statement, client cod e | |||
* must call JS_SetPrivate(cx, withobj, NULL). | * must call JS_SetPrivate(cx, withobj, NULL). | |||
*/ | */ | |||
extern JSObject * | extern JSObject * | |||
skipping to change at line 291 | skipping to change at line 357 | |||
* into an active scope chain. | * into an active scope chain. | |||
*/ | */ | |||
extern JSObject * | extern JSObject * | |||
js_NewBlockObject(JSContext *cx); | js_NewBlockObject(JSContext *cx); | |||
extern JSObject * | extern JSObject * | |||
js_CloneBlockObject(JSContext *cx, JSObject *proto, JSObject *parent, | js_CloneBlockObject(JSContext *cx, JSObject *proto, JSObject *parent, | |||
JSStackFrame *fp); | JSStackFrame *fp); | |||
extern JSBool | extern JSBool | |||
js_PutBlockObject(JSContext *cx, JSObject *obj); | js_PutBlockObject(JSContext *cx, JSBool normalUnwind); | |||
struct JSSharpObjectMap { | struct JSSharpObjectMap { | |||
jsrefcount depth; | jsrefcount depth; | |||
jsatomid sharpgen; | jsatomid sharpgen; | |||
JSHashTable *table; | JSHashTable *table; | |||
}; | }; | |||
#define SHARP_BIT ((jsatomid) 1) | #define SHARP_BIT ((jsatomid) 1) | |||
#define BUSY_BIT ((jsatomid) 2) | #define BUSY_BIT ((jsatomid) 2) | |||
#define SHARP_ID_SHIFT 2 | #define SHARP_ID_SHIFT 2 | |||
skipping to change at line 320 | skipping to change at line 386 | |||
jschar **sp); | jschar **sp); | |||
extern void | extern void | |||
js_LeaveSharpObject(JSContext *cx, JSIdArray **idap); | js_LeaveSharpObject(JSContext *cx, JSIdArray **idap); | |||
/* | /* | |||
* Mark objects stored in map if GC happens between js_EnterSharpObject | * Mark objects stored in map if GC happens between js_EnterSharpObject | |||
* and js_LeaveSharpObject. GC calls this when map->depth > 0. | * and js_LeaveSharpObject. GC calls this when map->depth > 0. | |||
*/ | */ | |||
extern void | extern void | |||
js_GCMarkSharpMap(JSContext *cx, JSSharpObjectMap *map); | js_TraceSharpMap(JSTracer *trc, JSSharpObjectMap *map); | |||
extern JSBool | ||||
js_obj_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, | ||||
jsval *rval); | ||||
extern JSBool | ||||
js_obj_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, | ||||
jsval *rval); | ||||
extern JSBool | extern JSBool | |||
js_HasOwnPropertyHelper(JSContext *cx, JSObject *obj, JSLookupPropOp lookup | js_HasOwnPropertyHelper(JSContext *cx, JSLookupPropOp lookup, jsval *vp); | |||
, | ||||
uintN argc, jsval *argv, jsval *rval); | ||||
extern JSObject* | extern JSObject * | |||
js_InitBlockClass(JSContext *cx, JSObject* obj); | js_InitBlockClass(JSContext *cx, JSObject* obj); | |||
extern JSObject * | extern JSObject * | |||
js_InitEval(JSContext *cx, JSObject *obj); | ||||
extern JSObject * | ||||
js_InitObjectClass(JSContext *cx, JSObject *obj); | js_InitObjectClass(JSContext *cx, JSObject *obj); | |||
/* Select Object.prototype method names shared between jsapi.c and jsobj.c. */ | /* Select Object.prototype method names shared between jsapi.c and jsobj.c. */ | |||
extern const char js_watch_str[]; | extern const char js_watch_str[]; | |||
extern const char js_unwatch_str[]; | extern const char js_unwatch_str[]; | |||
extern const char js_hasOwnProperty_str[]; | extern const char js_hasOwnProperty_str[]; | |||
extern const char js_isPrototypeOf_str[]; | extern const char js_isPrototypeOf_str[]; | |||
extern const char js_propertyIsEnumerable_str[]; | extern const char js_propertyIsEnumerable_str[]; | |||
extern const char js_defineGetter_str[]; | extern const char js_defineGetter_str[]; | |||
extern const char js_defineSetter_str[]; | extern const char js_defineSetter_str[]; | |||
skipping to change at line 372 | skipping to change at line 432 | |||
extern JSObjectMap * | extern JSObjectMap * | |||
js_HoldObjectMap(JSContext *cx, JSObjectMap *map); | js_HoldObjectMap(JSContext *cx, JSObjectMap *map); | |||
extern JSObjectMap * | extern JSObjectMap * | |||
js_DropObjectMap(JSContext *cx, JSObjectMap *map, JSObject *obj); | js_DropObjectMap(JSContext *cx, JSObjectMap *map, JSObject *obj); | |||
extern JSBool | extern JSBool | |||
js_GetClassId(JSContext *cx, JSClass *clasp, jsid *idp); | js_GetClassId(JSContext *cx, JSClass *clasp, jsid *idp); | |||
extern JSObject * | extern JSObject * | |||
js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *pare | js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *pare | |||
nt); | nt, | |||
uintN objectSize); | ||||
/* | ||||
* See jsapi.h, JS_NewObjectWithGivenProto. | ||||
* | ||||
* objectSize is either the explicit size for the allocated object or 0 | ||||
* indicating to use the default size based on object's class. | ||||
*/ | ||||
extern JSObject * | ||||
js_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto, | ||||
JSObject *parent, uintN objectSize); | ||||
/* | /* | |||
* Fast access to immutable standard objects (constructors and prototypes). | * Fast access to immutable standard objects (constructors and prototypes). | |||
*/ | */ | |||
extern JSBool | extern JSBool | |||
js_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, | js_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, | |||
JSObject **objp); | JSObject **objp); | |||
extern JSBool | extern JSBool | |||
js_SetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, JSObject *c obj); | js_SetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, JSObject *c obj); | |||
skipping to change at line 400 | skipping to change at line 471 | |||
extern void | extern void | |||
js_FinalizeObject(JSContext *cx, JSObject *obj); | js_FinalizeObject(JSContext *cx, JSObject *obj); | |||
extern JSBool | extern JSBool | |||
js_AllocSlot(JSContext *cx, JSObject *obj, uint32 *slotp); | js_AllocSlot(JSContext *cx, JSObject *obj, uint32 *slotp); | |||
extern void | extern void | |||
js_FreeSlot(JSContext *cx, JSObject *obj, uint32 slot); | js_FreeSlot(JSContext *cx, JSObject *obj, uint32 slot); | |||
/* | /* JSVAL_INT_MAX as a string */ | |||
* Native property add and lookup variants that hide id in the hidden atom | #define JSVAL_INT_MAX_STRING "1073741823" | |||
* subspace, so as to avoid collisions between internal properties such as | ||||
* formal arguments and local variables in function objects, and externally | ||||
* set properties with the same ids. | ||||
*/ | ||||
extern JSScopeProperty * | ||||
js_AddHiddenProperty(JSContext *cx, JSObject *obj, jsid id, | ||||
JSPropertyOp getter, JSPropertyOp setter, uint32 slot, | ||||
uintN attrs, uintN flags, intN shortid); | ||||
extern JSBool | #define CHECK_FOR_STRING_INDEX(id) | |||
js_LookupHiddenProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **o | \ | |||
bjp, | JS_BEGIN_MACRO | |||
JSProperty **propp); | \ | |||
if (JSID_IS_ATOM(id)) { | ||||
\ | ||||
JSAtom *atom_ = JSID_TO_ATOM(id); | ||||
\ | ||||
JSString *str_ = ATOM_TO_STRING(atom_); | ||||
\ | ||||
const jschar *s_ = JSFLATSTR_CHARS(str_); | ||||
\ | ||||
JSBool negative_ = (*s_ == '-'); | ||||
\ | ||||
if (negative_) s_++; | ||||
\ | ||||
if (JS7_ISDEC(*s_)) { | ||||
\ | ||||
size_t n_ = JSFLATSTR_LENGTH(str_) - negative_; | ||||
\ | ||||
if (n_ <= sizeof(JSVAL_INT_MAX_STRING) - 1) | ||||
\ | ||||
id = js_CheckForStringIndex(id, s_, s_ + n_, negative_) | ||||
; \ | ||||
} | ||||
\ | ||||
} | ||||
\ | ||||
JS_END_MACRO | ||||
extern jsid | ||||
js_CheckForStringIndex(jsid id, const jschar *cp, const jschar *end, | ||||
JSBool negative); | ||||
/* | /* | |||
* Find or create a property named by id in obj's scope, with the given get ter | * Find or create a property named by id in obj's scope, with the given get ter | |||
* and setter, slot, attributes, and other members. | * and setter, slot, attributes, and other members. | |||
*/ | */ | |||
extern JSScopeProperty * | extern JSScopeProperty * | |||
js_AddNativeProperty(JSContext *cx, JSObject *obj, jsid id, | js_AddNativeProperty(JSContext *cx, JSObject *obj, jsid id, | |||
JSPropertyOp getter, JSPropertyOp setter, uint32 slot, | JSPropertyOp getter, JSPropertyOp setter, uint32 slot, | |||
uintN attrs, uintN flags, intN shortid); | uintN attrs, uintN flags, intN shortid); | |||
skipping to change at line 452 | skipping to change at line 531 | |||
js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value, | js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value, | |||
JSPropertyOp getter, JSPropertyOp setter, uintN attrs, | JSPropertyOp getter, JSPropertyOp setter, uintN attrs, | |||
JSProperty **propp); | JSProperty **propp); | |||
extern JSBool | extern JSBool | |||
js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, jsval value, | js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, jsval value, | |||
JSPropertyOp getter, JSPropertyOp setter, uintN att rs, | JSPropertyOp getter, JSPropertyOp setter, uintN att rs, | |||
uintN flags, intN shortid, JSProperty **propp); | uintN flags, intN shortid, JSProperty **propp); | |||
/* | /* | |||
* Unlike js_DefineProperty, propp must be non-null. On success, and if id was | * Unlike js_DefineProperty, propp must be non-null. On success, and if id was | |||
* found, return true with *objp non-null and locked, and with a held prope rty | * found, return true with *objp non-null and locked, and with a held prope rty | |||
* stored in *propp. If successful but id was not found, return true with | * stored in *propp. If successful but id was not found, return true with b | |||
both | oth | |||
* *objp and *propp null. Therefore all callers who receive a non-null *pr | * *objp and *propp null. Therefore all callers who receive a non-null *pro | |||
opp | pp | |||
* must later call OBJ_DROP_PROPERTY(cx, *objp, *propp). | * must later call OBJ_DROP_PROPERTY(cx, *objp, *propp). | |||
*/ | */ | |||
extern JS_FRIEND_API(JSBool) | extern JS_FRIEND_API(JSBool) | |||
js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, | js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, | |||
JSProperty **propp); | JSProperty **propp); | |||
/* | /* | |||
* Specialized subroutine that allows caller to preset JSRESOLVE_* flags. | * Specialized subroutine that allows caller to preset JSRESOLVE_* flags an | |||
* JSRESOLVE_HIDDEN flags hidden function param/local name lookups, just fo | d | |||
r | * returns the index along the prototype chain in which *propp was found, o | |||
* internal use by fun_resolve and similar built-ins. | r | |||
* the last index if not found, or -1 on error. | ||||
*/ | */ | |||
extern JSBool | extern int | |||
js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN fla gs, | js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN fla gs, | |||
JSObject **objp, JSProperty **propp); | JSObject **objp, JSProperty **propp); | |||
#define JSRESOLVE_HIDDEN 0x8000 | extern int | |||
js_FindPropertyHelper(JSContext *cx, jsid id, JSObject **objp, | ||||
JSObject **pobjp, JSProperty **propp, | ||||
JSPropCacheEntry **entryp); | ||||
/* | ||||
* Return the index along the scope chain in which id was found, or the las | ||||
t | ||||
* index if not found, or -1 on error. | ||||
*/ | ||||
extern JS_FRIEND_API(JSBool) | extern JS_FRIEND_API(JSBool) | |||
js_FindProperty(JSContext *cx, jsid id, JSObject **objp, JSObject **pobjp, | js_FindProperty(JSContext *cx, jsid id, JSObject **objp, JSObject **pobjp, | |||
JSProperty **propp); | JSProperty **propp); | |||
extern JSObject * | extern JSObject * | |||
js_FindIdentifierBase(JSContext *cx, jsid id); | js_FindIdentifierBase(JSContext *cx, jsid id, JSPropCacheEntry *entry); | |||
extern JSObject * | extern JSObject * | |||
js_FindVariableScope(JSContext *cx, JSFunction **funp); | js_FindVariableScope(JSContext *cx, JSFunction **funp); | |||
/* | /* | |||
* NB: js_NativeGet and js_NativeSet are called with the scope containing s prop | * NB: js_NativeGet and js_NativeSet are called with the scope containing s prop | |||
* (pobj's scope for Get, obj's for Set) locked, and on successful return, that | * (pobj's scope for Get, obj's for Set) locked, and on successful return, that | |||
* scope is again locked. But on failure, both functions return false with the | * scope is again locked. But on failure, both functions return false with the | |||
* scope containing sprop unlocked. | * scope containing sprop unlocked. | |||
*/ | */ | |||
extern JSBool | extern JSBool | |||
js_NativeGet(JSContext *cx, JSObject *obj, JSObject *pobj, | js_NativeGet(JSContext *cx, JSObject *obj, JSObject *pobj, | |||
JSScopeProperty *sprop, jsval *vp); | JSScopeProperty *sprop, jsval *vp); | |||
extern JSBool | extern JSBool | |||
js_NativeSet(JSContext *cx, JSObject *obj, JSScopeProperty *sprop, jsval *v p); | js_NativeSet(JSContext *cx, JSObject *obj, JSScopeProperty *sprop, jsval *v p); | |||
extern JSBool | extern JSBool | |||
js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp, | ||||
JSPropCacheEntry **entryp); | ||||
extern JSBool | ||||
js_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp); | js_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp); | |||
extern JSBool | extern JSBool | |||
js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp, | ||||
JSPropCacheEntry **entryp); | ||||
extern JSBool | ||||
js_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp); | js_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp); | |||
extern JSBool | extern JSBool | |||
js_GetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop, | js_GetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop, | |||
uintN *attrsp); | uintN *attrsp); | |||
extern JSBool | extern JSBool | |||
js_SetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop, | js_SetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop, | |||
uintN *attrsp); | uintN *attrsp); | |||
skipping to change at line 530 | skipping to change at line 624 | |||
* Unlike realloc(3), this function frees ida on failure. | * Unlike realloc(3), this function frees ida on failure. | |||
*/ | */ | |||
extern JSIdArray * | extern JSIdArray * | |||
js_SetIdArrayLength(JSContext *cx, JSIdArray *ida, jsint length); | js_SetIdArrayLength(JSContext *cx, JSIdArray *ida, jsint length); | |||
extern JSBool | extern JSBool | |||
js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, | js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, | |||
jsval *statep, jsid *idp); | jsval *statep, jsid *idp); | |||
extern void | extern void | |||
js_MarkNativeIteratorStates(JSContext *cx); | js_TraceNativeIteratorStates(JSTracer *trc); | |||
extern JSBool | extern JSBool | |||
js_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, | js_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, | |||
jsval *vp, uintN *attrsp); | jsval *vp, uintN *attrsp); | |||
extern JSBool | extern JSBool | |||
js_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ; | js_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ; | |||
extern JSBool | extern JSBool | |||
js_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, | js_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, | |||
skipping to change at line 560 | skipping to change at line 654 | |||
js_IsDelegate(JSContext *cx, JSObject *obj, jsval v, JSBool *bp); | js_IsDelegate(JSContext *cx, JSObject *obj, jsval v, JSBool *bp); | |||
extern JSBool | extern JSBool | |||
js_GetClassPrototype(JSContext *cx, JSObject *scope, jsid id, | js_GetClassPrototype(JSContext *cx, JSObject *scope, jsid id, | |||
JSObject **protop); | JSObject **protop); | |||
extern JSBool | extern JSBool | |||
js_SetClassPrototype(JSContext *cx, JSObject *ctor, JSObject *proto, | js_SetClassPrototype(JSContext *cx, JSObject *ctor, JSObject *proto, | |||
uintN attrs); | uintN attrs); | |||
/* | ||||
* Wrap boolean, number or string as Boolean, Number or String object. | ||||
* *vp must not be an object, null or undefined. | ||||
*/ | ||||
extern JSBool | ||||
js_PrimitiveToObject(JSContext *cx, jsval *vp); | ||||
extern JSBool | extern JSBool | |||
js_ValueToObject(JSContext *cx, jsval v, JSObject **objp); | js_ValueToObject(JSContext *cx, jsval v, JSObject **objp); | |||
extern JSObject * | extern JSObject * | |||
js_ValueToNonNullObject(JSContext *cx, jsval v); | js_ValueToNonNullObject(JSContext *cx, jsval v); | |||
extern JSBool | extern JSBool | |||
js_TryValueOf(JSContext *cx, JSObject *obj, JSType type, jsval *rval); | js_TryValueOf(JSContext *cx, JSObject *obj, JSType type, jsval *rval); | |||
extern JSBool | extern JSBool | |||
js_TryMethod(JSContext *cx, JSObject *obj, JSAtom *atom, | js_TryMethod(JSContext *cx, JSObject *obj, JSAtom *atom, | |||
uintN argc, jsval *argv, jsval *rval); | uintN argc, jsval *argv, jsval *rval); | |||
extern JSBool | extern JSBool | |||
js_XDRObject(JSXDRState *xdr, JSObject **objp); | js_XDRObject(JSXDRState *xdr, JSObject **objp); | |||
extern uint32 | extern void | |||
js_Mark(JSContext *cx, JSObject *obj, void *arg); | js_TraceObject(JSTracer *trc, JSObject *obj); | |||
extern void | ||||
js_PrintObjectSlotName(JSTracer *trc, char *buf, size_t bufsize); | ||||
extern void | extern void | |||
js_Clear(JSContext *cx, JSObject *obj); | js_Clear(JSContext *cx, JSObject *obj); | |||
extern jsval | extern jsval | |||
js_GetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot); | js_GetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot); | |||
extern JSBool | extern JSBool | |||
js_SetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot, jsval v); | js_SetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot, jsval v); | |||
extern JSObject * | extern JSObject * | |||
js_CheckScopeChainValidity(JSContext *cx, JSObject *scopeobj, const char *c aller); | js_CheckScopeChainValidity(JSContext *cx, JSObject *scopeobj, const char *c aller); | |||
extern JSBool | extern JSBool | |||
js_CheckPrincipalsAccess(JSContext *cx, JSObject *scopeobj, | js_CheckPrincipalsAccess(JSContext *cx, JSObject *scopeobj, | |||
JSPrincipals *principals, JSAtom *caller); | JSPrincipals *principals, JSAtom *caller); | |||
/* Infallible -- returns its argument if there is no wrapped object. */ | ||||
extern JSObject * | ||||
js_GetWrappedObject(JSContext *cx, JSObject *obj); | ||||
/* NB: Infallible. */ | ||||
extern const char * | ||||
js_ComputeFilename(JSContext *cx, JSStackFrame *caller, | ||||
JSPrincipals *principals, uintN *linenop); | ||||
JS_END_EXTERN_C | JS_END_EXTERN_C | |||
#endif /* jsobj_h___ */ | #endif /* jsobj_h___ */ | |||
End of changes. 45 change blocks. | ||||
128 lines changed or deleted | 293 lines changed or added | |||
jsopcode.h | jsopcode.h | |||
---|---|---|---|---|
skipping to change at line 76 | skipping to change at line 76 | |||
#include "jsopcode.tbl" | #include "jsopcode.tbl" | |||
#undef OPDEF | #undef OPDEF | |||
JSOP_LIMIT_LENGTH | JSOP_LIMIT_LENGTH | |||
} JSOpLength; | } JSOpLength; | |||
/* | /* | |||
* JS bytecode formats. | * JS bytecode formats. | |||
*/ | */ | |||
#define JOF_BYTE 0 /* single bytecode, no immediates */ | #define JOF_BYTE 0 /* single bytecode, no immediates */ | |||
#define JOF_JUMP 1 /* signed 16-bit jump offset immediate */ | #define JOF_JUMP 1 /* signed 16-bit jump offset immediate */ | |||
#define JOF_CONST 2 /* unsigned 16-bit constant pool index */ | #define JOF_ATOM 2 /* unsigned 16-bit constant pool index */ | |||
#define JOF_UINT16 3 /* unsigned 16-bit immediate operand */ | #define JOF_UINT16 3 /* unsigned 16-bit immediate operand */ | |||
#define JOF_TABLESWITCH 4 /* table switch */ | #define JOF_TABLESWITCH 4 /* table switch */ | |||
#define JOF_LOOKUPSWITCH 5 /* lookup switch */ | #define JOF_LOOKUPSWITCH 5 /* lookup switch */ | |||
#define JOF_QARG 6 /* quickened get/set function argument op s */ | #define JOF_QARG 6 /* quickened get/set function argument op s */ | |||
#define JOF_QVAR 7 /* quickened get/set local variable ops * / | #define JOF_QVAR 7 /* quickened get/set local variable ops * / | |||
#define JOF_INDEXCONST 8 /* uint16 slot index + constant pool inde x */ | #define JOF_SLOTATOM 8 /* uint16 slot index + constant pool inde x */ | |||
#define JOF_JUMPX 9 /* signed 32-bit jump offset immediate */ | #define JOF_JUMPX 9 /* signed 32-bit jump offset immediate */ | |||
#define JOF_TABLESWITCHX 10 /* extended (32-bit offset) table switch */ | #define JOF_TABLESWITCHX 10 /* extended (32-bit offset) table switch */ | |||
#define JOF_LOOKUPSWITCHX 11 /* extended (32-bit offset) lookup switch */ | #define JOF_LOOKUPSWITCHX 11 /* extended (32-bit offset) lookup switch */ | |||
#define JOF_UINT24 12 /* extended unsigned 24-bit literal (inde x) */ | #define JOF_UINT24 12 /* extended unsigned 24-bit literal (inde x) */ | |||
#define JOF_LITOPX 13 /* JOF_UINT24 followed by op being extend | #define JOF_2BYTE 13 /* 2-byte opcode, e.g., upper 8 bits of 2 | |||
ed, | 4-bit | |||
where op if JOF_CONST has no unsigned | atom index */ | |||
16- | ||||
bit immediate operand */ | ||||
#define JOF_LOCAL 14 /* block-local operand stack variable */ | #define JOF_LOCAL 14 /* block-local operand stack variable */ | |||
#define JOF_TYPEMASK 0x000f /* mask for above immediate types */ | #define JOF_OBJECT 15 /* unsigned 16-bit object pool index */ | |||
#define JOF_NAME 0x0010 /* name operation */ | #define JOF_SLOTOBJECT 16 /* uint16 slot index + object pool index | |||
#define JOF_PROP 0x0020 /* obj.prop operation */ | */ | |||
#define JOF_ELEM 0x0030 /* obj[index] operation */ | #define JOF_REGEXP 17 /* unsigned 16-bit regexp pool index */ | |||
#define JOF_MODEMASK 0x0030 /* mask for above addressing modes */ | #define JOF_INT8 18 /* int8 immediate operand */ | |||
#define JOF_SET 0x0040 /* set (i.e., assignment) operation */ | #define JOF_INT32 19 /* int32 immediate operand */ | |||
#define JOF_DEL 0x0080 /* delete operation */ | #define JOF_TYPEMASK 0x001f /* mask for above immediate types */ | |||
#define JOF_DEC 0x0100 /* decrement (--, not ++) opcode */ | ||||
#define JOF_INC 0x0200 /* increment (++, not --) opcode */ | #define JOF_NAME (1U<<5) /* name operation */ | |||
#define JOF_INCDEC 0x0300 /* increment or decrement opcode */ | #define JOF_PROP (2U<<5) /* obj.prop operation */ | |||
#define JOF_POST 0x0400 /* postorder increment or decrement */ | #define JOF_ELEM (3U<<5) /* obj[index] operation */ | |||
#define JOF_IMPORT 0x0800 /* import property op */ | #define JOF_XMLNAME (4U<<5) /* XML name: *, a::b, @a, @a::b, etc. */ | |||
#define JOF_FOR 0x1000 /* for-in property op */ | #define JOF_VARPROP (5U<<5) /* x.prop for this, arg, var, or local x | |||
*/ | ||||
#define JOF_MODEMASK (7U<<5) /* mask for above addressing modes */ | ||||
#define JOF_SET (1U<<8) /* set (i.e., assignment) operation */ | ||||
#define JOF_DEL (1U<<9) /* delete operation */ | ||||
#define JOF_DEC (1U<<10) /* decrement (--, not ++) opcode */ | ||||
#define JOF_INC (2U<<10) /* increment (++, not --) opcode */ | ||||
#define JOF_INCDEC (3U<<10) /* increment or decrement opcode */ | ||||
#define JOF_POST (1U<<12) /* postorder increment or decrement */ | ||||
#define JOF_IMPORT (1U<<13) /* import property op */ | ||||
#define JOF_FOR (1U<<14) /* for-in property op */ | ||||
#define JOF_ASSIGNING JOF_SET /* hint for JSClass.resolve, used for ops | #define JOF_ASSIGNING JOF_SET /* hint for JSClass.resolve, used for ops | |||
that do simplex assignment */ | that do simplex assignment */ | |||
#define JOF_DETECTING 0x2000 /* object detection flag for JSNewResolve | #define JOF_DETECTING (1U<<15) /* object detection for JSNewResolveOp */ | |||
Op */ | #define JOF_BACKPATCH (1U<<16) /* backpatch placeholder during codegen * | |||
#define JOF_BACKPATCH 0x4000 /* backpatch placeholder during codegen * | / | |||
/ | #define JOF_LEFTASSOC (1U<<17) /* left-associative operator */ | |||
#define JOF_LEFTASSOC 0x8000 /* left-associative operator */ | #define JOF_DECLARING (1U<<18) /* var, const, or function declaration op | |||
#define JOF_DECLARING 0x10000 /* var, const, or function declaration op | */ | |||
*/ | #define JOF_INDEXBASE (1U<<19) /* atom segment base setting prefix op */ | |||
#define JOF_XMLNAME 0x20000 /* XML name: *, a::b, @a, @a::b, etc. */ | #define JOF_CALLOP (1U<<20) /* call operation that pushes function an | |||
d | ||||
this */ | ||||
#define JOF_PARENHEAD (1U<<21) /* opcode consumes value of expression in | ||||
parenthesized statement head */ | ||||
#define JOF_INVOKE (1U<<22) /* JSOP_CALL, JSOP_NEW, JSOP_EVAL */ | ||||
#define JOF_TMPSLOT (1U<<23) /* interpreter uses extra temporary slot | ||||
to root intermediate objects besides | ||||
the slots opcode uses */ | ||||
#define JOF_TMPSLOT2 (2U<<23) /* interpreter uses extra 2 temporary slo | ||||
t | ||||
besides the slots opcode uses */ | ||||
#define JOF_TMPSLOT_SHIFT 23 | ||||
#define JOF_TMPSLOT_MASK (JS_BITMASK(2) << JOF_TMPSLOT_SHIFT) | ||||
/* Shorthands for type from format and type from opcode. */ | ||||
#define JOF_TYPE(fmt) ((fmt) & JOF_TYPEMASK) | ||||
#define JOF_OPTYPE(op) JOF_TYPE(js_CodeSpec[op].format) | ||||
/* Shorthands for mode from format and mode from opcode. */ | ||||
#define JOF_MODE(fmt) ((fmt) & JOF_MODEMASK) | ||||
#define JOF_OPMODE(op) JOF_MODE(js_CodeSpec[op].format) | ||||
#define JOF_TYPE_IS_EXTENDED_JUMP(t) \ | #define JOF_TYPE_IS_EXTENDED_JUMP(t) \ | |||
((unsigned)((t) - JOF_JUMPX) <= (unsigned)(JOF_LOOKUPSWITCHX - JOF_JUMP X)) | ((unsigned)((t) - JOF_JUMPX) <= (unsigned)(JOF_LOOKUPSWITCHX - JOF_JUMP X)) | |||
/* | /* | |||
* Immediate operand getters, setters, and bounds. | * Immediate operand getters, setters, and bounds. | |||
*/ | */ | |||
/* Common uint16 immediate format helpers. */ | ||||
#define UINT16_LEN 2 | ||||
#define UINT16_HI(i) ((jsbytecode)((i) >> 8)) | ||||
#define UINT16_LO(i) ((jsbytecode)(i)) | ||||
#define GET_UINT16(pc) ((uintN)(((pc)[1] << 8) | (pc)[2])) | ||||
#define SET_UINT16(pc,i) ((pc)[1] = UINT16_HI(i), (pc)[2] = UINT16_L | ||||
O(i)) | ||||
#define UINT16_LIMIT ((uintN)1 << 16) | ||||
/* Short (2-byte signed offset) relative jump macros. */ | /* Short (2-byte signed offset) relative jump macros. */ | |||
#define JUMP_OFFSET_LEN 2 | #define JUMP_OFFSET_LEN 2 | |||
#define JUMP_OFFSET_HI(off) ((jsbytecode)((off) >> 8)) | #define JUMP_OFFSET_HI(off) ((jsbytecode)((off) >> 8)) | |||
#define JUMP_OFFSET_LO(off) ((jsbytecode)(off)) | #define JUMP_OFFSET_LO(off) ((jsbytecode)(off)) | |||
#define GET_JUMP_OFFSET(pc) ((int16)(((pc)[1] << 8) | (pc)[2])) | #define GET_JUMP_OFFSET(pc) ((int16)GET_UINT16(pc)) | |||
#define SET_JUMP_OFFSET(pc,off) ((pc)[1] = JUMP_OFFSET_HI(off), \ | #define SET_JUMP_OFFSET(pc,off) ((pc)[1] = JUMP_OFFSET_HI(off), \ | |||
(pc)[2] = JUMP_OFFSET_LO(off)) | (pc)[2] = JUMP_OFFSET_LO(off)) | |||
#define JUMP_OFFSET_MIN ((int16)0x8000) | #define JUMP_OFFSET_MIN ((int16)0x8000) | |||
#define JUMP_OFFSET_MAX ((int16)0x7fff) | #define JUMP_OFFSET_MAX ((int16)0x7fff) | |||
/* | /* | |||
* When a short jump won't hold a relative offset, its 2-byte immediate off set | * When a short jump won't hold a relative offset, its 2-byte immediate off set | |||
* operand is an unsigned index of a span-dependency record, maintained unt il | * operand is an unsigned index of a span-dependency record, maintained unt il | |||
* code generation finishes -- after which some (but we hope not nearly all ) | * code generation finishes -- after which some (but we hope not nearly all ) | |||
* span-dependent jumps must be extended (see OptimizeSpanDeps in jsemit.c) . | * span-dependent jumps must be extended (see OptimizeSpanDeps in jsemit.c) . | |||
* | * | |||
* If the span-dependency record index overflows SPANDEP_INDEX_MAX, the jum p | * If the span-dependency record index overflows SPANDEP_INDEX_MAX, the jum p | |||
* offset will contain SPANDEP_INDEX_HUGE, indicating that the record must be | * offset will contain SPANDEP_INDEX_HUGE, indicating that the record must be | |||
* found (via binary search) by its "before span-dependency optimization" p c | * found (via binary search) by its "before span-dependency optimization" p c | |||
* offset (from script main entry point). | * offset (from script main entry point). | |||
*/ | */ | |||
#define GET_SPANDEP_INDEX(pc) ((uint16)(((pc)[1] << 8) | (pc)[2])) | #define GET_SPANDEP_INDEX(pc) ((uint16)GET_UINT16(pc)) | |||
#define SET_SPANDEP_INDEX(pc,i) ((pc)[1] = JUMP_OFFSET_HI(i), \ | #define SET_SPANDEP_INDEX(pc,i) ((pc)[1] = JUMP_OFFSET_HI(i), \ | |||
(pc)[2] = JUMP_OFFSET_LO(i)) | (pc)[2] = JUMP_OFFSET_LO(i)) | |||
#define SPANDEP_INDEX_MAX ((uint16)0xfffe) | #define SPANDEP_INDEX_MAX ((uint16)0xfffe) | |||
#define SPANDEP_INDEX_HUGE ((uint16)0xffff) | #define SPANDEP_INDEX_HUGE ((uint16)0xffff) | |||
/* Ultimately, if short jumps won't do, emit long (4-byte signed) offsets. */ | /* Ultimately, if short jumps won't do, emit long (4-byte signed) offsets. */ | |||
#define JUMPX_OFFSET_LEN 4 | #define JUMPX_OFFSET_LEN 4 | |||
#define JUMPX_OFFSET_B3(off) ((jsbytecode)((off) >> 24)) | #define JUMPX_OFFSET_B3(off) ((jsbytecode)((off) >> 24)) | |||
#define JUMPX_OFFSET_B2(off) ((jsbytecode)((off) >> 16)) | #define JUMPX_OFFSET_B2(off) ((jsbytecode)((off) >> 16)) | |||
#define JUMPX_OFFSET_B1(off) ((jsbytecode)((off) >> 8)) | #define JUMPX_OFFSET_B1(off) ((jsbytecode)((off) >> 8)) | |||
skipping to change at line 162 | skipping to change at line 197 | |||
#define GET_JUMPX_OFFSET(pc) ((int32)(((pc)[1] << 24) | ((pc)[2] << 16) \ | #define GET_JUMPX_OFFSET(pc) ((int32)(((pc)[1] << 24) | ((pc)[2] << 16) \ | |||
| ((pc)[3] << 8) | (pc)[4])) | | ((pc)[3] << 8) | (pc)[4])) | |||
#define SET_JUMPX_OFFSET(pc,off)((pc)[1] = JUMPX_OFFSET_B3(off), \ | #define SET_JUMPX_OFFSET(pc,off)((pc)[1] = JUMPX_OFFSET_B3(off), \ | |||
(pc)[2] = JUMPX_OFFSET_B2(off), \ | (pc)[2] = JUMPX_OFFSET_B2(off), \ | |||
(pc)[3] = JUMPX_OFFSET_B1(off), \ | (pc)[3] = JUMPX_OFFSET_B1(off), \ | |||
(pc)[4] = JUMPX_OFFSET_B0(off)) | (pc)[4] = JUMPX_OFFSET_B0(off)) | |||
#define JUMPX_OFFSET_MIN ((int32)0x80000000) | #define JUMPX_OFFSET_MIN ((int32)0x80000000) | |||
#define JUMPX_OFFSET_MAX ((int32)0x7fffffff) | #define JUMPX_OFFSET_MAX ((int32)0x7fffffff) | |||
/* | /* | |||
* A literal is indexed by a per-script atom map. Most scripts have relati | * A literal is indexed by a per-script atom or object maps. Most scripts | |||
vely | * have relatively few literals, so the standard JOF_ATOM, JOF_OBJECT and | |||
* few literals, so the standard JOF_CONST format specifies a fixed 16 bits | * JOF_REGEXP formats specifies a fixed 16 bits of immediate operand index. | |||
of | * A script with more than 64K literals must wrap the bytecode into | |||
* immediate operand index. A script with more than 64K literals must push | * JSOP_INDEXBASE and JSOP_RESETBASE pair. | |||
all | ||||
* high-indexed literals on the stack using JSOP_LITERAL, then use JOF_ELEM | ||||
ops | ||||
* instead of JOF_PROP, etc. | ||||
*/ | */ | |||
#define ATOM_INDEX_LEN 2 | #define INDEX_LEN 2 | |||
#define ATOM_INDEX_HI(i) ((jsbytecode)((i) >> 8)) | #define INDEX_HI(i) ((jsbytecode)((i) >> 8)) | |||
#define ATOM_INDEX_LO(i) ((jsbytecode)(i)) | #define INDEX_LO(i) ((jsbytecode)(i)) | |||
#define GET_ATOM_INDEX(pc) ((jsatomid)(((pc)[1] << 8) | (pc)[2])) | #define GET_INDEX(pc) GET_UINT16(pc) | |||
#define SET_ATOM_INDEX(pc,i) ((pc)[1] = ATOM_INDEX_HI(i), | #define SET_INDEX(pc,i) ((pc)[1] = INDEX_HI(i), (pc)[2] = INDEX_LO( | |||
\ | i)) | |||
(pc)[2] = ATOM_INDEX_LO(i)) | ||||
#define GET_ATOM(cx,script,pc) js_GetAtom((cx), &(script)->atomMap, | #define GET_INDEXBASE(pc) (JS_ASSERT(*(pc) == JSOP_INDEXBASE), | |||
\ | \ | |||
GET_ATOM_INDEX(pc)) | ((uintN)((pc)[1])) << 16) | |||
#define INDEXBASE_LEN 1 | ||||
/* A full atom index for JSOP_UINT24 uses 24 bits of immediate operand. */ | ||||
#define UINT24_HI(i) ((jsbytecode)((i) >> 16)) | #define UINT24_HI(i) ((jsbytecode)((i) >> 16)) | |||
#define UINT24_MID(i) ((jsbytecode)((i) >> 8)) | #define UINT24_MID(i) ((jsbytecode)((i) >> 8)) | |||
#define UINT24_LO(i) ((jsbytecode)(i)) | #define UINT24_LO(i) ((jsbytecode)(i)) | |||
#define GET_UINT24(pc) ((jsatomid)(((pc)[1] << 16) | \ | #define GET_UINT24(pc) ((jsatomid)(((pc)[1] << 16) | \ | |||
((pc)[2] << 8) | \ | ((pc)[2] << 8) | \ | |||
(pc)[3])) | (pc)[3])) | |||
#define SET_UINT24(pc,i) ((pc)[1] = UINT24_HI(i), \ | #define SET_UINT24(pc,i) ((pc)[1] = UINT24_HI(i), \ | |||
(pc)[2] = UINT24_MID(i), \ | (pc)[2] = UINT24_MID(i), \ | |||
(pc)[3] = UINT24_LO(i)) | (pc)[3] = UINT24_LO(i)) | |||
/* Same format for JSOP_LITERAL, etc., but future-proof with different name | #define GET_INT8(pc) ((jsint)(int8)(pc)[1]) | |||
s. */ | ||||
#define LITERAL_INDEX_LEN 3 | ||||
#define LITERAL_INDEX_HI(i) UINT24_HI(i) | ||||
#define LITERAL_INDEX_MID(i) UINT24_MID(i) | ||||
#define LITERAL_INDEX_LO(i) UINT24_LO(i) | ||||
#define GET_LITERAL_INDEX(pc) GET_UINT24(pc) | ||||
#define SET_LITERAL_INDEX(pc,i) SET_UINT24(pc,i) | ||||
/* Atom index limit is determined by SN_3BYTE_OFFSET_FLAG, see jsemit.h. */ | #define GET_INT32(pc) ((jsint)(((uint32)((pc)[1]) << 24) | | |||
#define ATOM_INDEX_LIMIT_LOG2 23 | \ | |||
#define ATOM_INDEX_LIMIT ((uint32)1 << ATOM_INDEX_LIMIT_LOG2) | ((uint32)((pc)[2]) << 16) | | |||
\ | ||||
((uint32)((pc)[3]) << 8) | | ||||
\ | ||||
(uint32)(pc)[4])) | ||||
#define SET_INT32(pc,i) ((pc)[1] = (jsbytecode)((uint32)(i) >> 24), | ||||
\ | ||||
(pc)[2] = (jsbytecode)((uint32)(i) >> 16), | ||||
\ | ||||
(pc)[3] = (jsbytecode)((uint32)(i) >> 8), | ||||
\ | ||||
(pc)[4] = (jsbytecode)(uint32)(i)) | ||||
JS_STATIC_ASSERT(sizeof(jsatomid) * JS_BITS_PER_BYTE >= | /* Index limit is determined by SN_3BYTE_OFFSET_FLAG, see jsemit.h. */ | |||
ATOM_INDEX_LIMIT_LOG2 + 1); | #define INDEX_LIMIT_LOG2 23 | |||
#define INDEX_LIMIT ((uint32)1 << INDEX_LIMIT_LOG2) | ||||
/* Common uint16 immediate format helpers. */ | JS_STATIC_ASSERT(sizeof(uint32) * JS_BITS_PER_BYTE >= INDEX_LIMIT_LOG2 + 1) | |||
#define UINT16_HI(i) ((jsbytecode)((i) >> 8)) | ; | |||
#define UINT16_LO(i) ((jsbytecode)(i)) | ||||
#define GET_UINT16(pc) ((uintN)(((pc)[1] << 8) | (pc)[2])) | ||||
#define SET_UINT16(pc,i) ((pc)[1] = UINT16_HI(i), (pc)[2] = UINT16_L | ||||
O(i)) | ||||
#define UINT16_LIMIT ((uintN)1 << 16) | ||||
/* Actual argument count operand format helpers. */ | /* Actual argument count operand format helpers. */ | |||
#define ARGC_HI(argc) UINT16_HI(argc) | #define ARGC_HI(argc) UINT16_HI(argc) | |||
#define ARGC_LO(argc) UINT16_LO(argc) | #define ARGC_LO(argc) UINT16_LO(argc) | |||
#define GET_ARGC(pc) GET_UINT16(pc) | #define GET_ARGC(pc) GET_UINT16(pc) | |||
#define ARGC_LIMIT UINT16_LIMIT | #define ARGC_LIMIT UINT16_LIMIT | |||
/* Synonyms for quick JOF_QARG and JOF_QVAR bytecodes. */ | /* Synonyms for quick JOF_QARG and JOF_QVAR bytecodes. */ | |||
#define GET_ARGNO(pc) GET_UINT16(pc) | #define GET_ARGNO(pc) GET_UINT16(pc) | |||
#define SET_ARGNO(pc,argno) SET_UINT16(pc,argno) | #define SET_ARGNO(pc,argno) SET_UINT16(pc,argno) | |||
#define ARGNO_LEN 2 | #define ARGNO_LEN 2 | |||
#define ARGNO_LIMIT UINT16_LIMIT | #define ARGNO_LIMIT UINT16_LIMIT | |||
#define GET_VARNO(pc) GET_UINT16(pc) | #define GET_VARNO(pc) GET_UINT16(pc) | |||
#define SET_VARNO(pc,varno) SET_UINT16(pc,varno) | #define SET_VARNO(pc,varno) SET_UINT16(pc,varno) | |||
#define VARNO_LEN 2 | #define VARNO_LEN 2 | |||
#define VARNO_LIMIT UINT16_LIMIT | #define VARNO_LIMIT UINT16_LIMIT | |||
struct JSCodeSpec { | struct JSCodeSpec { | |||
const char *name; /* JS bytecode name */ | ||||
const char *token; /* JS source literal or null */ | ||||
int8 length; /* length including opcode byte */ | int8 length; /* length including opcode byte */ | |||
int8 nuses; /* arity, -1 if variadic */ | int8 nuses; /* arity, -1 if variadic */ | |||
int8 ndefs; /* number of stack results */ | int8 ndefs; /* number of stack results */ | |||
uint8 prec; /* operator precedence */ | uint8 prec; /* operator precedence */ | |||
uint32 format; /* immediate operand format */ | uint32 format; /* immediate operand format */ | |||
}; | }; | |||
extern const JSCodeSpec js_CodeSpec[]; | extern const JSCodeSpec js_CodeSpec[]; | |||
extern uintN js_NumCodeSpecs; | extern uintN js_NumCodeSpecs; | |||
extern const jschar js_EscapeMap[]; | extern const char *js_CodeName[]; | |||
extern const char js_EscapeMap[]; | ||||
/* | /* | |||
* Return a GC'ed string containing the chars in str, with any non-printing | * Return a GC'ed string containing the chars in str, with any non-printing | |||
* chars or quotes (' or " as specified by the quote argument) escaped, and | * chars or quotes (' or " as specified by the quote argument) escaped, and | |||
* with the quote character at the beginning and end of the result string. | * with the quote character at the beginning and end of the result string. | |||
*/ | */ | |||
extern JSString * | extern JSString * | |||
js_QuoteString(JSContext *cx, JSString *str, jschar quote); | js_QuoteString(JSContext *cx, JSString *str, jschar quote); | |||
/* | /* | |||
* JSPrinter operations, for printf style message formatting. The return | * JSPrinter operations, for printf style message formatting. The return | |||
* value from js_GetPrinterOutput() is the printer's cumulative output, in | * value from js_GetPrinterOutput() is the printer's cumulative output, in | |||
* a GC'ed string. | * a GC'ed string. | |||
*/ | */ | |||
#ifdef JS_ARENAMETER | ||||
# define JS_NEW_PRINTER(cx, name, fun, indent, pretty) | ||||
\ | ||||
js_NewPrinter(cx, name, fun, indent, pretty) | ||||
#else | ||||
# define JS_NEW_PRINTER(cx, name, fun, indent, pretty) | ||||
\ | ||||
js_NewPrinter(cx, fun, indent, pretty) | ||||
#endif | ||||
extern JSPrinter * | extern JSPrinter * | |||
js_NewPrinter(JSContext *cx, const char *name, uintN indent, JSBool pretty) | JS_NEW_PRINTER(JSContext *cx, const char *name, JSFunction *fun, | |||
; | uintN indent, JSBool pretty); | |||
extern void | extern void | |||
js_DestroyPrinter(JSPrinter *jp); | js_DestroyPrinter(JSPrinter *jp); | |||
extern JSString * | extern JSString * | |||
js_GetPrinterOutput(JSPrinter *jp); | js_GetPrinterOutput(JSPrinter *jp); | |||
extern int | extern int | |||
js_printf(JSPrinter *jp, const char *format, ...); | js_printf(JSPrinter *jp, const char *format, ...); | |||
extern JSBool | extern JSBool | |||
js_puts(JSPrinter *jp, const char *s); | js_puts(JSPrinter *jp, const char *s); | |||
/* | ||||
* Get index operand from the bytecode using a bytecode analysis to deduce | ||||
the | ||||
* the index register. This function is infallible, in spite of taking cx a | ||||
s | ||||
* its first parameter; it uses only cx->runtime when calling JS_GetTrapOpc | ||||
ode. | ||||
* The GET_*_FROM_BYTECODE macros that call it pick up cx from their caller | ||||
's | ||||
* lexical environments. | ||||
*/ | ||||
uintN | ||||
js_GetIndexFromBytecode(JSContext *cx, JSScript *script, jsbytecode *pc, | ||||
ptrdiff_t pcoff); | ||||
/* | ||||
* A slower version of GET_ATOM when the caller does not want to maintain | ||||
* the index segment register itself. | ||||
*/ | ||||
#define GET_ATOM_FROM_BYTECODE(script, pc, pcoff, atom) | ||||
\ | ||||
JS_BEGIN_MACRO | ||||
\ | ||||
uintN index_ = js_GetIndexFromBytecode(cx, (script), (pc), (pcoff)) | ||||
; \ | ||||
JS_GET_SCRIPT_ATOM((script), index_, atom); | ||||
\ | ||||
JS_END_MACRO | ||||
#define GET_OBJECT_FROM_BYTECODE(script, pc, pcoff, obj) | ||||
\ | ||||
JS_BEGIN_MACRO | ||||
\ | ||||
uintN index_ = js_GetIndexFromBytecode(cx, (script), (pc), (pcoff)) | ||||
; \ | ||||
JS_GET_SCRIPT_OBJECT((script), index_, obj); | ||||
\ | ||||
JS_END_MACRO | ||||
#define GET_FUNCTION_FROM_BYTECODE(script, pc, pcoff, fun) | ||||
\ | ||||
JS_BEGIN_MACRO | ||||
\ | ||||
uintN index_ = js_GetIndexFromBytecode(cx, (script), (pc), (pcoff)) | ||||
; \ | ||||
JS_GET_SCRIPT_FUNCTION((script), index_, fun); | ||||
\ | ||||
JS_END_MACRO | ||||
#define GET_REGEXP_FROM_BYTECODE(script, pc, pcoff, obj) | ||||
\ | ||||
JS_BEGIN_MACRO | ||||
\ | ||||
uintN index_ = js_GetIndexFromBytecode(cx, (script), (pc), (pcoff)) | ||||
; \ | ||||
JS_GET_SCRIPT_REGEXP((script), index_, obj); | ||||
\ | ||||
JS_END_MACRO | ||||
#ifdef DEBUG | #ifdef DEBUG | |||
/* | /* | |||
* Disassemblers, for debugging only. | * Disassemblers, for debugging only. | |||
*/ | */ | |||
#include <stdio.h> | #include <stdio.h> | |||
extern JS_FRIEND_API(JSBool) | extern JS_FRIEND_API(JSBool) | |||
js_Disassemble(JSContext *cx, JSScript *script, JSBool lines, FILE *fp); | js_Disassemble(JSContext *cx, JSScript *script, JSBool lines, FILE *fp); | |||
extern JS_FRIEND_API(uintN) | extern JS_FRIEND_API(uintN) | |||
js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc, | js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc, | |||
JSBool lines, FILE *fp); | JSBool lines, FILE *fp); | |||
#endif /* DEBUG */ | #endif /* DEBUG */ | |||
/* | /* | |||
* Decompilers, for script, function, and expression pretty-printing. | * Decompilers, for script, function, and expression pretty-printing. | |||
*/ | */ | |||
extern JSBool | extern JSBool | |||
js_DecompileCode(JSPrinter *jp, JSScript *script, jsbytecode *pc, uintN len | ||||
, | ||||
uintN pcdepth); | ||||
extern JSBool | ||||
js_DecompileScript(JSPrinter *jp, JSScript *script); | js_DecompileScript(JSPrinter *jp, JSScript *script); | |||
extern JSBool | extern JSBool | |||
js_DecompileFunctionBody(JSPrinter *jp, JSFunction *fun); | js_DecompileFunctionBody(JSPrinter *jp); | |||
extern JSBool | extern JSBool | |||
js_DecompileFunction(JSPrinter *jp, JSFunction *fun); | js_DecompileFunction(JSPrinter *jp); | |||
/* | /* | |||
* Find the source expression that resulted in v, and return a new string | * Find the source expression that resulted in v, and return a newly alloca | |||
* containing it. Fall back on v's string conversion (fallback) if we can' | ted | |||
t | * C-string containing it. Fall back on v's string conversion (fallback) i | |||
* find the bytecode that generated and pushed v on the operand stack. | f we | |||
* can't find the bytecode that generated and pushed v on the operand stack | ||||
. | ||||
* | * | |||
* Search the current stack frame if spindex is JSDVG_SEARCH_STACK. Don't | * Search the current stack frame if spindex is JSDVG_SEARCH_STACK. Don't | |||
* look for v on the stack if spindex is JSDVG_IGNORE_STACK. Otherwise, | * look for v on the stack if spindex is JSDVG_IGNORE_STACK. Otherwise, | |||
* spindex is the negative index of v, measured from cx->fp->sp, or from a | * spindex is the negative index of v, measured from cx->fp->sp, or from a | |||
* lower frame's sp if cx->fp is native. | * lower frame's sp if cx->fp is native. | |||
* | ||||
* The caller must call JS_free on the result after a succsesful call. | ||||
*/ | */ | |||
extern JSString * | extern char * | |||
js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v, | js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v, | |||
JSString *fallback); | JSString *fallback); | |||
#define JSDVG_IGNORE_STACK 0 | #define JSDVG_IGNORE_STACK 0 | |||
#define JSDVG_SEARCH_STACK 1 | #define JSDVG_SEARCH_STACK 1 | |||
JS_END_EXTERN_C | JS_END_EXTERN_C | |||
#endif /* jsopcode_h___ */ | #endif /* jsopcode_h___ */ | |||
End of changes. 26 change blocks. | ||||
87 lines changed or deleted | 189 lines changed or added | |||
jsotypes.h | jsotypes.h | |||
---|---|---|---|---|
skipping to change at line 70 | skipping to change at line 70 | |||
#include <SupportDefs.h> | #include <SupportDefs.h> | |||
typedef JSUintn uintn; | typedef JSUintn uintn; | |||
#ifndef _XP_Core_ | #ifndef _XP_Core_ | |||
typedef JSIntn intn; | typedef JSIntn intn; | |||
#endif | #endif | |||
#else | #else | |||
/* SVR4 typedef of uint is commonly found on UNIX machines. */ | /* SVR4 typedef of uint is commonly found on UNIX machines. */ | |||
#if defined(XP_UNIX) && !defined(__QNXNTO__) | #ifdef XP_UNIX | |||
#include <sys/types.h> | #include <sys/types.h> | |||
#else | #else | |||
typedef JSUintn uint; | typedef JSUintn uint; | |||
#endif | #endif | |||
typedef JSUintn uintn; | typedef JSUintn uintn; | |||
typedef JSUint64 uint64; | typedef JSUint64 uint64; | |||
#if !defined(_WIN32) && !defined(XP_OS2) | #if !defined(_WIN32) && !defined(XP_OS2) | |||
typedef JSUint32 uint32; | typedef JSUint32 uint32; | |||
#else | #else | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
jsparse.h | jsparse.h | |||
---|---|---|---|---|
skipping to change at line 64 | skipping to change at line 64 | |||
* Parsing builds a tree of nodes that directs code generation. This tree is | * Parsing builds a tree of nodes that directs code generation. This tree is | |||
* not a concrete syntax tree in all respects (for example, || and && are l eft | * not a concrete syntax tree in all respects (for example, || and && are l eft | |||
* associative, but (A && B && C) translates into the right-associated tree | * associative, but (A && B && C) translates into the right-associated tree | |||
* <A && <B && C>> so that code generation can emit a left-associative bran ch | * <A && <B && C>> so that code generation can emit a left-associative bran ch | |||
* around <B && C> when A is false). Nodes are labeled by token type, with a | * around <B && C> when A is false). Nodes are labeled by token type, with a | |||
* JSOp secondary label when needed: | * JSOp secondary label when needed: | |||
* | * | |||
* Label Variant Members | * Label Variant Members | |||
* ----- ------- ------- | * ----- ------- ------- | |||
* <Definitions> | * <Definitions> | |||
* TOK_FUNCTION func pn_funAtom: atom holding function object contai | * TOK_FUNCTION func pn_funpob: JSParsedObjectBox holding function | |||
ning | * object containing arg and var properties. We | |||
* arg and var properties. We create the functi | * create the function object at parse (not emit | |||
on | ) | |||
* object at parse (not emit) time to specialize | * time to specialize arg and var bytecodes earl | |||
arg | y. | |||
* and var bytecodes early. | ||||
* pn_body: TOK_LC node for function body statemen ts | * pn_body: TOK_LC node for function body statemen ts | |||
* pn_flags: TCF_FUN_* flags (see jsemit.h) collec ted | * pn_flags: TCF_FUN_* flags (see jsemit.h) collec ted | |||
* while parsing the function's body | * while parsing the function's body | |||
* pn_tryCount: of try statements in function | * pn_sclen: maximum lexical scope chain length | |||
* | * | |||
* <Statements> | * <Statements> | |||
* TOK_LC list pn_head: list of pn_count statements | * TOK_LC list pn_head: list of pn_count statements | |||
* TOK_EXPORT list pn_head: list of pn_count TOK_NAMEs or one TOK_ STAR | * TOK_EXPORT list pn_head: list of pn_count TOK_NAMEs or one TOK_ STAR | |||
* (which is not a multiply node) | * (which is not a multiply node) | |||
* TOK_IMPORT list pn_head: list of pn_count sub-trees of the form | * TOK_IMPORT list pn_head: list of pn_count sub-trees of the form | |||
* a.b.*, a[b].*, a.*, a.b, or a[b] -- but never a. | * a.b.*, a[b].*, a.*, a.b, or a[b] -- but never a. | |||
* Each member is expressed with TOK_DOT or TOK_ LB. | * Each member is expressed with TOK_DOT or TOK_ LB. | |||
* Each sub-tree's root node has a pn_op in the set | * Each sub-tree's root node has a pn_op in the set | |||
* JSOP_IMPORT{ALL,PROP,ELEM} | * JSOP_IMPORT{ALL,PROP,ELEM} | |||
skipping to change at line 140 | skipping to change at line 140 | |||
* TOK_COMMA list pn_head: list of pn_count comma-separated exprs | * TOK_COMMA list pn_head: list of pn_count comma-separated exprs | |||
* TOK_ASSIGN binary pn_left: lvalue, pn_right: rvalue | * TOK_ASSIGN binary pn_left: lvalue, pn_right: rvalue | |||
* pn_op: JSOP_ADD for +=, etc. | * pn_op: JSOP_ADD for +=, etc. | |||
* TOK_HOOK ternary pn_kid1: cond, pn_kid2: then, pn_kid3: else | * TOK_HOOK ternary pn_kid1: cond, pn_kid2: then, pn_kid3: else | |||
* TOK_OR binary pn_left: first in || chain, pn_right: rest of c hain | * TOK_OR binary pn_left: first in || chain, pn_right: rest of c hain | |||
* TOK_AND binary pn_left: first in && chain, pn_right: rest of c hain | * TOK_AND binary pn_left: first in && chain, pn_right: rest of c hain | |||
* TOK_BITOR binary pn_left: left-assoc | expr, pn_right: ^ expr | * TOK_BITOR binary pn_left: left-assoc | expr, pn_right: ^ expr | |||
* TOK_BITXOR binary pn_left: left-assoc ^ expr, pn_right: & expr | * TOK_BITXOR binary pn_left: left-assoc ^ expr, pn_right: & expr | |||
* TOK_BITAND binary pn_left: left-assoc & expr, pn_right: EQ expr | * TOK_BITAND binary pn_left: left-assoc & expr, pn_right: EQ expr | |||
* TOK_EQOP binary pn_left: left-assoc EQ expr, pn_right: REL expr | * TOK_EQOP binary pn_left: left-assoc EQ expr, pn_right: REL expr | |||
* pn_op: JSOP_EQ, JSOP_NE, JSOP_NEW_EQ, JSOP_NEW_ | * pn_op: JSOP_EQ, JSOP_NE, | |||
NE | * JSOP_STRICTEQ, JSOP_STRICTNE | |||
* TOK_RELOP binary pn_left: left-assoc REL expr, pn_right: SH expr | * TOK_RELOP binary pn_left: left-assoc REL expr, pn_right: SH expr | |||
* pn_op: JSOP_LT, JSOP_LE, JSOP_GT, JSOP_GE | * pn_op: JSOP_LT, JSOP_LE, JSOP_GT, JSOP_GE | |||
* TOK_SHOP binary pn_left: left-assoc SH expr, pn_right: ADD expr | * TOK_SHOP binary pn_left: left-assoc SH expr, pn_right: ADD expr | |||
* pn_op: JSOP_LSH, JSOP_RSH, JSOP_URSH | * pn_op: JSOP_LSH, JSOP_RSH, JSOP_URSH | |||
* TOK_PLUS, binary pn_left: left-assoc ADD expr, pn_right: MUL exp r | * TOK_PLUS, binary pn_left: left-assoc ADD expr, pn_right: MUL exp r | |||
* pn_extra: if a left-associated binary TOK_PLUS | * pn_extra: if a left-associated binary TOK_PLUS | |||
* tree has been flattened into a list (see abov e | * tree has been flattened into a list (see abov e | |||
* under <Expressions>), pn_extra will contain | * under <Expressions>), pn_extra will contain | |||
* PNX_STRCAT if at least one list element is a | * PNX_STRCAT if at least one list element is a | |||
* string literal (TOK_STRING); if such a list h as | * string literal (TOK_STRING); if such a list h as | |||
skipping to change at line 179 | skipping to change at line 180 | |||
* TOK_LP list pn_head: list of call, arg1, arg2, ... argN | * TOK_LP list pn_head: list of call, arg1, arg2, ... argN | |||
* pn_count: 1 + N (where N is number of args) | * pn_count: 1 + N (where N is number of args) | |||
* call is a MEMBER expr naming a callable object | * call is a MEMBER expr naming a callable object | |||
* TOK_RB list pn_head: list of pn_count array element exprs | * TOK_RB list pn_head: list of pn_count array element exprs | |||
* [,,] holes are represented by TOK_COMMA nodes | * [,,] holes are represented by TOK_COMMA nodes | |||
* #n=[...] produces TOK_DEFSHARP at head of list | * #n=[...] produces TOK_DEFSHARP at head of list | |||
* pn_extra: PN_ENDCOMMA if extra comma at end | * pn_extra: PN_ENDCOMMA if extra comma at end | |||
* TOK_RC list pn_head: list of pn_count TOK_COLON nodes where | * TOK_RC list pn_head: list of pn_count TOK_COLON nodes where | |||
* each has pn_left: property id, pn_right: value | * each has pn_left: property id, pn_right: value | |||
* #n={...} produces TOK_DEFSHARP at head of list | * #n={...} produces TOK_DEFSHARP at head of list | |||
* var {x} = object destructuring shorthand shares | ||||
* PN_NAME node for x on left and right of TOK_COL | ||||
ON | ||||
* node in TOK_RC's list, has PNX_SHORTHAND flag | ||||
* TOK_DEFSHARP unary pn_num: jsint value of n in #n= | * TOK_DEFSHARP unary pn_num: jsint value of n in #n= | |||
* pn_kid: null for #n=[...] and #n={...}, primary | * pn_kid: null for #n=[...] and #n={...}, primary | |||
* if #n=primary for function, paren, name, object | * if #n=primary for function, paren, name, object | |||
* literal expressions | * literal expressions | |||
* TOK_USESHARP nullary pn_num: jsint value of n in #n# | * TOK_USESHARP nullary pn_num: jsint value of n in #n# | |||
* TOK_RP unary pn_kid: parenthesized expression | * TOK_RP unary pn_kid: parenthesized expression | |||
* TOK_NAME, name pn_atom: name, string, or object atom | * TOK_NAME, name pn_atom: name, string, or object atom | |||
* TOK_STRING, pn_op: JSOP_NAME, JSOP_STRING, or JSOP_OBJECT, or | * TOK_STRING, pn_op: JSOP_NAME, JSOP_STRING, or JSOP_OBJECT, or | |||
* JSOP_REGEXP | * JSOP_REGEXP | |||
* TOK_OBJECT If JSOP_NAME, pn_op may be JSOP_*ARG or JSOP_*V | * TOK_REGEXP If JSOP_NAME, pn_op may be JSOP_*ARG or JSOP_*V | |||
AR | AR | |||
* with pn_slot >= 0 and pn_attrs telling const-ne | * with pn_slot >= 0 and pn_const telling const-ne | |||
ss | ss | |||
* TOK_NUMBER dval pn_dval: double value of numeric literal | * TOK_NUMBER dval pn_dval: double value of numeric literal | |||
* TOK_PRIMARY nullary pn_op: JSOp bytecode | * TOK_PRIMARY nullary pn_op: JSOp bytecode | |||
* | * | |||
* <E4X node descriptions> | * <E4X node descriptions> | |||
* TOK_ANYNAME nullary pn_op: JSOP_ANYNAME | * TOK_ANYNAME nullary pn_op: JSOP_ANYNAME | |||
* pn_atom: cx->runtime->atomState.starAtom | * pn_atom: cx->runtime->atomState.starAtom | |||
* TOK_AT unary pn_op: JSOP_TOATTRNAME; pn_kid attribute id/exp r | * TOK_AT unary pn_op: JSOP_TOATTRNAME; pn_kid attribute id/exp r | |||
* TOK_DBLCOLON binary pn_op: JSOP_QNAME | * TOK_DBLCOLON binary pn_op: JSOP_QNAME | |||
* pn_left: TOK_ANYNAME or TOK_NAME node | * pn_left: TOK_ANYNAME or TOK_NAME node | |||
* pn_right: TOK_STRING "*" node, or expr within [ ] | * pn_right: TOK_STRING "*" node, or expr within [ ] | |||
skipping to change at line 252 | skipping to change at line 256 | |||
* | * | |||
* translates to: | * translates to: | |||
* | * | |||
* ((a x {x}) 'Hi there!' ((b y {y}) 'How are you?') ((answer) {x + y})) | * ((a x {x}) 'Hi there!' ((b y {y}) 'How are you?') ((answer) {x + y})) | |||
* | * | |||
* <Non-E4X node descriptions, continued> | * <Non-E4X node descriptions, continued> | |||
* | * | |||
* Label Variant Members | * Label Variant Members | |||
* ----- ------- ------- | * ----- ------- ------- | |||
* TOK_LEXICALSCOPE name pn_op: JSOP_LEAVEBLOCK or JSOP_LEAVEBLOCKEX PR | * TOK_LEXICALSCOPE name pn_op: JSOP_LEAVEBLOCK or JSOP_LEAVEBLOCKEX PR | |||
* pn_atom: block object | * pn_pob: block object | |||
* pn_expr: block body | * pn_expr: block body | |||
* TOK_ARRAYCOMP list pn_head: list of pn_count (1 or 2) elements | * TOK_ARRAYCOMP list pn_head: list of pn_count (1 or 2) elements | |||
* if pn_count is 2, first element is #n=[...] | * if pn_count is 2, first element is #n=[...] | |||
* last element is block enclosing for loop( s) | * last element is block enclosing for loop( s) | |||
* and optionally if-guarded TOK_ARRAYPUSH | * and optionally if-guarded TOK_ARRAYPUSH | |||
* pn_extra: stack slot, used during code gen | * pn_extra: stack slot, used during code gen | |||
* TOK_ARRAYPUSH unary pn_op: JSOP_ARRAYCOMP | * TOK_ARRAYPUSH unary pn_op: JSOP_ARRAYCOMP | |||
* pn_kid: array comprehension expression | * pn_kid: array comprehension expression | |||
*/ | */ | |||
typedef enum JSParseNodeArity { | typedef enum JSParseNodeArity { | |||
skipping to change at line 280 | skipping to change at line 284 | |||
} JSParseNodeArity; | } JSParseNodeArity; | |||
struct JSParseNode { | struct JSParseNode { | |||
uint16 pn_type; | uint16 pn_type; | |||
uint8 pn_op; | uint8 pn_op; | |||
int8 pn_arity; | int8 pn_arity; | |||
JSTokenPos pn_pos; | JSTokenPos pn_pos; | |||
ptrdiff_t pn_offset; /* first generated bytecode offset */ | ptrdiff_t pn_offset; /* first generated bytecode offset */ | |||
union { | union { | |||
struct { /* TOK_FUNCTION node */ | struct { /* TOK_FUNCTION node */ | |||
JSAtom *funAtom; /* atomized function object */ | JSParsedObjectBox *funpob; /* function object */ | |||
JSParseNode *body; /* TOK_LC list of statements */ | JSParseNode *body; /* TOK_LC list of statements */ | |||
uint32 flags; /* accumulated tree context flags * | uint16 flags; /* accumulated tree context flags * | |||
/ | / | |||
uint32 tryCount; /* count of try statements in body | uint16 sclen; /* maximum scope chain length */ | |||
*/ | uint32 index; /* emitter's index */ | |||
} func; | } func; | |||
struct { /* list of next-linked nodes */ | struct { /* list of next-linked nodes */ | |||
JSParseNode *head; /* first node in list */ | JSParseNode *head; /* first node in list */ | |||
JSParseNode **tail; /* ptr to ptr to last node in list */ | JSParseNode **tail; /* ptr to ptr to last node in list */ | |||
uint32 count; /* number of nodes in list */ | uint32 count; /* number of nodes in list */ | |||
uint32 extra; /* extra flags, see below */ | uint32 extra; /* extra flags, see below */ | |||
} list; | } list; | |||
struct { /* ternary: if, for(;;), ?: */ | struct { /* ternary: if, for(;;), ?: */ | |||
JSParseNode *kid1; /* condition, discriminant, etc. */ | JSParseNode *kid1; /* condition, discriminant, etc. */ | |||
JSParseNode *kid2; /* then-part, case list, etc. */ | JSParseNode *kid2; /* then-part, case list, etc. */ | |||
JSParseNode *kid3; /* else-part, default case, etc. */ | JSParseNode *kid3; /* else-part, default case, etc. */ | |||
} ternary; | } ternary; | |||
struct { /* two kids if binary */ | struct { /* two kids if binary */ | |||
JSParseNode *left; | JSParseNode *left; | |||
JSParseNode *right; | JSParseNode *right; | |||
jsval val; /* switch case value */ | jsval val; /* switch case value */ | |||
} binary; | } binary; | |||
struct { /* one kid if unary */ | struct { /* one kid if unary */ | |||
JSParseNode *kid; | JSParseNode *kid; | |||
jsint num; /* -1 or sharp variable number */ | jsint num; /* -1 or sharp variable number */ | |||
JSBool hidden; /* hidden genexp-induced JSOP_YIELD */ | ||||
} unary; | } unary; | |||
struct { /* name, labeled statement, etc. */ | struct { /* name, labeled statement, etc. */ | |||
JSAtom *atom; /* name or label atom, null if slot */ | JSAtom *atom; /* name or label atom, null if slot */ | |||
JSParseNode *expr; /* object or initializer */ | JSParseNode *expr; /* object or initializer */ | |||
jsint slot; /* -1 or arg or local var slot */ | jsint slot; /* -1 or arg or local var slot */ | |||
uintN attrs; /* attributes if local var or const */ | JSBool isconst; /* true for const names */ | |||
} name; | } name; | |||
struct { /* lexical scope. */ | ||||
JSParsedObjectBox *pob; /* block object */ | ||||
JSParseNode *expr; /* object or initializer */ | ||||
jsint slot; /* -1 or arg or local var slot */ | ||||
} lexical; | ||||
struct { | struct { | |||
JSAtom *atom; /* first atom in pair */ | JSAtom *atom; /* first atom in pair */ | |||
JSAtom *atom2; /* second atom in pair or null */ | JSAtom *atom2; /* second atom in pair or null */ | |||
} apair; | } apair; | |||
struct { /* object literal */ | ||||
JSParsedObjectBox *pob; | ||||
} object; | ||||
jsdouble dval; /* aligned numeric literal value */ | jsdouble dval; /* aligned numeric literal value */ | |||
} pn_u; | } pn_u; | |||
JSParseNode *pn_next; /* to align dval and pn_u on RISCs */ | JSParseNode *pn_next; /* to align dval and pn_u on RISCs */ | |||
JSTokenStream *pn_ts; /* token stream for error reports * | ||||
/ | ||||
JSAtom *pn_source; /* saved source for decompilation * | ||||
/ | ||||
}; | }; | |||
#define pn_funAtom pn_u.func.funAtom | #define pn_funpob pn_u.func.funpob | |||
#define pn_body pn_u.func.body | #define pn_body pn_u.func.body | |||
#define pn_flags pn_u.func.flags | #define pn_flags pn_u.func.flags | |||
#define pn_tryCount pn_u.func.tryCount | #define pn_sclen pn_u.func.sclen | |||
#define pn_index pn_u.func.index | ||||
#define pn_head pn_u.list.head | #define pn_head pn_u.list.head | |||
#define pn_tail pn_u.list.tail | #define pn_tail pn_u.list.tail | |||
#define pn_count pn_u.list.count | #define pn_count pn_u.list.count | |||
#define pn_extra pn_u.list.extra | #define pn_extra pn_u.list.extra | |||
#define pn_kid1 pn_u.ternary.kid1 | #define pn_kid1 pn_u.ternary.kid1 | |||
#define pn_kid2 pn_u.ternary.kid2 | #define pn_kid2 pn_u.ternary.kid2 | |||
#define pn_kid3 pn_u.ternary.kid3 | #define pn_kid3 pn_u.ternary.kid3 | |||
#define pn_left pn_u.binary.left | #define pn_left pn_u.binary.left | |||
#define pn_right pn_u.binary.right | #define pn_right pn_u.binary.right | |||
#define pn_val pn_u.binary.val | #define pn_val pn_u.binary.val | |||
#define pn_kid pn_u.unary.kid | #define pn_kid pn_u.unary.kid | |||
#define pn_num pn_u.unary.num | #define pn_num pn_u.unary.num | |||
#define pn_hidden pn_u.unary.hidden | ||||
#define pn_atom pn_u.name.atom | #define pn_atom pn_u.name.atom | |||
#define pn_expr pn_u.name.expr | #define pn_expr pn_u.name.expr | |||
#define pn_slot pn_u.name.slot | #define pn_slot pn_u.name.slot | |||
#define pn_attrs pn_u.name.attrs | #define pn_const pn_u.name.isconst | |||
#define pn_dval pn_u.dval | #define pn_dval pn_u.dval | |||
#define pn_atom2 pn_u.apair.atom2 | #define pn_atom2 pn_u.apair.atom2 | |||
#define pn_pob pn_u.object.pob | ||||
/* PN_LIST pn_extra flags. */ | /* PN_LIST pn_extra flags. */ | |||
#define PNX_STRCAT 0x01 /* TOK_PLUS list has string term */ | #define PNX_STRCAT 0x01 /* TOK_PLUS list has string term */ | |||
#define PNX_CANTFOLD 0x02 /* TOK_PLUS list has unfoldable ter m */ | #define PNX_CANTFOLD 0x02 /* TOK_PLUS list has unfoldable ter m */ | |||
#define PNX_POPVAR 0x04 /* TOK_VAR last result needs poppin g */ | #define PNX_POPVAR 0x04 /* TOK_VAR last result needs poppin g */ | |||
#define PNX_FORINVAR 0x08 /* TOK_VAR is left kid of TOK_IN no de, | #define PNX_FORINVAR 0x08 /* TOK_VAR is left kid of TOK_IN no de, | |||
which is left kid of TOK_FOR */ | which is left kid of TOK_FOR */ | |||
#define PNX_ENDCOMMA 0x10 /* array literal has comma at end * / | #define PNX_ENDCOMMA 0x10 /* array literal has comma at end * / | |||
#define PNX_XMLROOT 0x20 /* top-most node in XML literal tre e */ | #define PNX_XMLROOT 0x20 /* top-most node in XML literal tre e */ | |||
#define PNX_GROUPINIT 0x40 /* var [a, b] = [c, d]; unit list * / | #define PNX_GROUPINIT 0x40 /* var [a, b] = [c, d]; unit list * / | |||
#define PNX_NEEDBRACES 0x80 /* braces necessary due to closure */ | #define PNX_NEEDBRACES 0x80 /* braces necessary due to closure */ | |||
#define PNX_FUNCDEFS 0x100 /* contains top-level function | ||||
statements */ | ||||
#define PNX_SHORTHAND 0x200 /* shorthand syntax used, at presen | ||||
t | ||||
object destructuring ({x,y}) onl | ||||
y */ | ||||
/* | /* | |||
* Move pn2 into pn, preserving pn->pn_pos and pn->pn_offset and handing of f | * Move pn2 into pn, preserving pn->pn_pos and pn->pn_offset and handing of f | |||
* any kids in pn2->pn_u, by clearing pn2. | * any kids in pn2->pn_u, by clearing pn2. | |||
*/ | */ | |||
#define PN_MOVE_NODE(pn, pn2) \ | #define PN_MOVE_NODE(pn, pn2) \ | |||
JS_BEGIN_MACRO \ | JS_BEGIN_MACRO \ | |||
(pn)->pn_type = (pn2)->pn_type; \ | (pn)->pn_type = (pn2)->pn_type; \ | |||
(pn)->pn_op = (pn2)->pn_op; \ | (pn)->pn_op = (pn2)->pn_op; \ | |||
(pn)->pn_arity = (pn2)->pn_arity; \ | (pn)->pn_arity = (pn2)->pn_arity; \ | |||
skipping to change at line 382 | skipping to change at line 401 | |||
(pn)->pn_op = JSOP_NOP; \ | (pn)->pn_op = JSOP_NOP; \ | |||
(pn)->pn_arity = PN_NULLARY; \ | (pn)->pn_arity = PN_NULLARY; \ | |||
JS_END_MACRO | JS_END_MACRO | |||
/* True if pn is a parsenode representing a literal constant. */ | /* True if pn is a parsenode representing a literal constant. */ | |||
#define PN_IS_CONSTANT(pn) \ | #define PN_IS_CONSTANT(pn) \ | |||
((pn)->pn_type == TOK_NUMBER || \ | ((pn)->pn_type == TOK_NUMBER || \ | |||
(pn)->pn_type == TOK_STRING || \ | (pn)->pn_type == TOK_STRING || \ | |||
((pn)->pn_type == TOK_PRIMARY && (pn)->pn_op != JSOP_THIS)) | ((pn)->pn_type == TOK_PRIMARY && (pn)->pn_op != JSOP_THIS)) | |||
#define PN_OP(pn) ((JSOp)(pn)->pn_op) | ||||
#define PN_TYPE(pn) ((JSTokenType)(pn)->pn_type) | ||||
/* | /* | |||
* Compute a pointer to the last JSParseNode element in a singly-linked lis t. | * Compute a pointer to the last JSParseNode element in a singly-linked lis t. | |||
* NB: list must be non-empty for correct PN_LAST usage! | * NB: list must be non-empty for correct PN_LAST usage! | |||
*/ | */ | |||
#define PN_LAST(list) \ | #define PN_LAST(list) \ | |||
((JSParseNode *)((char *)(list)->pn_tail - offsetof(JSParseNode, pn_nex t))) | ((JSParseNode *)((char *)(list)->pn_tail - offsetof(JSParseNode, pn_nex t))) | |||
#define PN_INIT_LIST(list) \ | #define PN_INIT_LIST(list) \ | |||
JS_BEGIN_MACRO \ | JS_BEGIN_MACRO \ | |||
(list)->pn_head = NULL; \ | (list)->pn_head = NULL; \ | |||
skipping to change at line 411 | skipping to change at line 433 | |||
(list)->pn_extra = 0; \ | (list)->pn_extra = 0; \ | |||
JS_END_MACRO | JS_END_MACRO | |||
#define PN_APPEND(list, pn) \ | #define PN_APPEND(list, pn) \ | |||
JS_BEGIN_MACRO \ | JS_BEGIN_MACRO \ | |||
*(list)->pn_tail = (pn); \ | *(list)->pn_tail = (pn); \ | |||
(list)->pn_tail = &(pn)->pn_next; \ | (list)->pn_tail = &(pn)->pn_next; \ | |||
(list)->pn_count++; \ | (list)->pn_count++; \ | |||
JS_END_MACRO | JS_END_MACRO | |||
struct JSParsedObjectBox { | ||||
JSParsedObjectBox *traceLink; | ||||
JSParsedObjectBox *emitLink; | ||||
JSObject *object; | ||||
}; | ||||
struct JSParseContext { | ||||
JSTokenStream tokenStream; | ||||
void *tempPoolMark; /* initial JSContext.tempPool mark | ||||
*/ | ||||
JSPrincipals *principals; /* principals associated with sourc | ||||
e */ | ||||
JSParseNode *nodeList; /* list of recyclable parse-node | ||||
structs */ | ||||
JSParsedObjectBox *traceListHead; /* list of parsed object for GC | ||||
tracing */ | ||||
JSTempValueRooter tempRoot; /* root to trace traceListHead */ | ||||
}; | ||||
/* | ||||
* Convenience macro to access JSParseContext.tokenStream as a pointer. | ||||
*/ | ||||
#define TS(pc) (&(pc)->tokenStream) | ||||
/* | /* | |||
* Parse a top-level JS script. | * Parse a top-level JS script. | |||
* | ||||
* The caller must prevent the GC from running while this function is activ | ||||
e, | ||||
* because atoms and function newborns are not rooted yet. | ||||
*/ | */ | |||
extern JS_FRIEND_API(JSParseNode *) | extern JSParseNode * | |||
js_ParseTokenStream(JSContext *cx, JSObject *chain, JSTokenStream *ts); | js_ParseScript(JSContext *cx, JSObject *chain, JSParseContext *pc); | |||
extern JS_FRIEND_API(JSBool) | extern JSScript * | |||
js_CompileTokenStream(JSContext *cx, JSObject *chain, JSTokenStream *ts, | js_CompileScript(JSContext *cx, JSObject *obj, JSPrincipals *principals, | |||
JSCodeGenerator *cg); | uint32 tcflags, const jschar *chars, size_t length, | |||
FILE *file, const char *filename, uintN lineno); | ||||
extern JSBool | extern JSBool | |||
js_CompileFunctionBody(JSContext *cx, JSTokenStream *ts, JSFunction *fun); | js_CompileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipals *princi | |||
pals, | ||||
const jschar *chars, size_t length, | ||||
const char *filename, uintN lineno); | ||||
extern JSBool | extern JSBool | |||
js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc); | js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc); | |||
#if JS_HAS_XML_SUPPORT | #if JS_HAS_XML_SUPPORT | |||
JS_FRIEND_API(JSParseNode *) | JS_FRIEND_API(JSParseNode *) | |||
js_ParseXMLTokenStream(JSContext *cx, JSObject *chain, JSTokenStream *ts, | js_ParseXMLText(JSContext *cx, JSObject *chain, JSParseContext *pc, | |||
JSBool allowList); | JSBool allowList); | |||
#endif | #endif | |||
/* | ||||
* Initialize a parse context. All parameters after pc are passed to | ||||
* js_InitTokenStream. | ||||
* | ||||
* The parse context owns the arena pool "tops-of-stack" space above the | ||||
* current JSContext.tempPool mark. This means you cannot allocate from | ||||
* tempPool and save the pointer beyond the next js_FinishParseContext. | ||||
*/ | ||||
extern JSBool | ||||
js_InitParseContext(JSContext *cx, JSParseContext *pc, JSPrincipals *princi | ||||
pals, | ||||
const jschar *base, size_t length, FILE *fp, | ||||
const char *filename, uintN lineno); | ||||
extern void | ||||
js_FinishParseContext(JSContext *cx, JSParseContext *pc); | ||||
extern void | ||||
js_InitCompilePrincipals(JSContext *cx, JSParseContext *pc, | ||||
JSPrincipals *principals); | ||||
/* | ||||
* Allocate a new parseed object node from cx->tempPool. | ||||
*/ | ||||
extern JSParsedObjectBox * | ||||
js_NewParsedObjectBox(JSContext *cx, JSParseContext *pc, JSObject *obj); | ||||
extern void | ||||
js_TraceParseContext(JSTracer *trc, JSParseContext *pc); | ||||
JS_END_EXTERN_C | JS_END_EXTERN_C | |||
#endif /* jsparse_h___ */ | #endif /* jsparse_h___ */ | |||
End of changes. 27 change blocks. | ||||
40 lines changed or deleted | 114 lines changed or added | |||
jsprvtd.h | jsprvtd.h | |||
---|---|---|---|---|
skipping to change at line 60 | skipping to change at line 60 | |||
* declaring a pointer to struct type, or defining a member of struct type. | * declaring a pointer to struct type, or defining a member of struct type. | |||
* | * | |||
* A few fundamental scalar types are defined here too. Neither the scalar | * A few fundamental scalar types are defined here too. Neither the scalar | |||
* nor the struct typedefs should change much, therefore the nearly-global | * nor the struct typedefs should change much, therefore the nearly-global | |||
* make dependency induced by this file should not prove painful. | * make dependency induced by this file should not prove painful. | |||
*/ | */ | |||
#include "jspubtd.h" | #include "jspubtd.h" | |||
/* Internal identifier (jsid) macros. */ | /* Internal identifier (jsid) macros. */ | |||
#define JSID_ATOM 0x0 | ||||
#define JSID_INT 0x1 | ||||
#define JSID_OBJECT 0x2 | ||||
#define JSID_TAGMASK 0x3 | ||||
#define JSID_TAG(id) ((id) & JSID_TAGMASK) | ||||
#define JSID_SETTAG(id,t) ((id) | (t)) | ||||
#define JSID_CLRTAG(id) ((id) & ~(jsid)JSID_TAGMASK) | ||||
#define JSID_IS_ATOM(id) (JSID_TAG(id) == JSID_ATOM) | #define JSID_IS_ATOM(id) JSVAL_IS_STRING((jsval)(id)) | |||
#define JSID_TO_ATOM(id) ((JSAtom *)(id)) | #define JSID_TO_ATOM(id) ((JSAtom *)(id)) | |||
#define ATOM_TO_JSID(atom) ((jsid)(atom)) | #define ATOM_TO_JSID(atom) (JS_ASSERT(ATOM_IS_STRING(atom)), | |||
#define ATOM_JSID_TO_JSVAL(id) ATOM_KEY(JSID_TO_ATOM(id)) | \ | |||
(jsid)(atom)) | ||||
#define JSID_IS_INT(id) ((id) & JSID_INT) | #define JSID_IS_INT(id) JSVAL_IS_INT((jsval)(id)) | |||
#define JSID_TO_INT(id) ((jsint)(id) >> 1) | #define JSID_TO_INT(id) JSVAL_TO_INT((jsval)(id)) | |||
#define INT_TO_JSID(i) (((jsint)(i) << 1) | JSID_INT) | #define INT_TO_JSID(i) ((jsid)INT_TO_JSVAL(i)) | |||
#define INT_JSID_TO_JSVAL(id) (id) | #define INT_JSVAL_TO_JSID(v) ((jsid)(v)) | |||
#define INT_JSVAL_TO_JSID(v) (v) | #define INT_JSID_TO_JSVAL(id) ((jsval)(id)) | |||
#define JSID_IS_OBJECT(id) (JSID_TAG(id) == JSID_OBJECT) | #define JSID_IS_OBJECT(id) JSVAL_IS_OBJECT((jsval)(id)) | |||
#define JSID_TO_OBJECT(id) ((JSObject *) JSID_CLRTAG(id)) | #define JSID_TO_OBJECT(id) JSVAL_TO_OBJECT((jsval)(id)) | |||
#define OBJECT_TO_JSID(obj) ((jsid)(obj) | JSID_OBJECT) | #define OBJECT_TO_JSID(obj) ((jsid)OBJECT_TO_JSVAL(obj)) | |||
#define OBJECT_JSID_TO_JSVAL(id) OBJECT_TO_JSVAL(JSID_CLRTAG(id)) | #define OBJECT_JSVAL_TO_JSID(v) ((jsid)v) | |||
#define OBJECT_JSVAL_TO_JSID(v) OBJECT_TO_JSID(JSVAL_TO_OBJECT(v)) | ||||
#define ID_TO_VALUE(id) ((jsval)(id)) | ||||
/* | ||||
* Convenience constants. | ||||
*/ | ||||
#define JS_BITS_PER_UINT32_LOG2 5 | ||||
#define JS_BITS_PER_UINT32 32 | ||||
/* Scalar typedefs. */ | /* Scalar typedefs. */ | |||
typedef uint8 jsbytecode; | typedef uint8 jsbytecode; | |||
typedef uint8 jssrcnote; | typedef uint8 jssrcnote; | |||
typedef uint32 jsatomid; | typedef uint32 jsatomid; | |||
/* Struct typedefs. */ | /* Struct typedefs. */ | |||
typedef struct JSArgumentFormatMap JSArgumentFormatMap; | typedef struct JSArgumentFormatMap JSArgumentFormatMap; | |||
typedef struct JSCodeGenerator JSCodeGenerator; | typedef struct JSCodeGenerator JSCodeGenerator; | |||
typedef struct JSDependentString JSDependentString; | ||||
typedef struct JSGCThing JSGCThing; | typedef struct JSGCThing JSGCThing; | |||
typedef struct JSGenerator JSGenerator; | typedef struct JSGenerator JSGenerator; | |||
typedef struct JSParseContext JSParseContext; | ||||
typedef struct JSParsedObjectBox JSParsedObjectBox; | ||||
typedef struct JSParseNode JSParseNode; | typedef struct JSParseNode JSParseNode; | |||
typedef struct JSPropCacheEntry JSPropCacheEntry; | ||||
typedef struct JSSharpObjectMap JSSharpObjectMap; | typedef struct JSSharpObjectMap JSSharpObjectMap; | |||
typedef struct JSTempValueRooter JSTempValueRooter; | ||||
typedef struct JSThread JSThread; | typedef struct JSThread JSThread; | |||
typedef struct JSToken JSToken; | typedef struct JSToken JSToken; | |||
typedef struct JSTokenPos JSTokenPos; | typedef struct JSTokenPos JSTokenPos; | |||
typedef struct JSTokenPtr JSTokenPtr; | typedef struct JSTokenPtr JSTokenPtr; | |||
typedef struct JSTokenStream JSTokenStream; | typedef struct JSTokenStream JSTokenStream; | |||
typedef struct JSTreeContext JSTreeContext; | typedef struct JSTreeContext JSTreeContext; | |||
typedef struct JSTryNote JSTryNote; | typedef struct JSTryNote JSTryNote; | |||
typedef struct JSWeakRoots JSWeakRoots; | ||||
/* Friend "Advanced API" typedefs. */ | /* Friend "Advanced API" typedefs. */ | |||
typedef struct JSAtom JSAtom; | typedef struct JSAtom JSAtom; | |||
typedef struct JSAtomList JSAtomList; | typedef struct JSAtomList JSAtomList; | |||
typedef struct JSAtomListElement JSAtomListElement; | typedef struct JSAtomListElement JSAtomListElement; | |||
typedef struct JSAtomMap JSAtomMap; | typedef struct JSAtomMap JSAtomMap; | |||
typedef struct JSAtomState JSAtomState; | typedef struct JSAtomState JSAtomState; | |||
typedef struct JSCodeSpec JSCodeSpec; | typedef struct JSCodeSpec JSCodeSpec; | |||
typedef struct JSPrinter JSPrinter; | typedef struct JSPrinter JSPrinter; | |||
typedef struct JSRegExp JSRegExp; | typedef struct JSRegExp JSRegExp; | |||
skipping to change at line 202 | skipping to change at line 206 | |||
JSBool *ok, void *closure); | JSBool *ok, void *closure); | |||
typedef void | typedef void | |||
(* JS_DLL_CALLBACK JSObjectHook)(JSContext *cx, JSObject *obj, JSBool isNew , | (* JS_DLL_CALLBACK JSObjectHook)(JSContext *cx, JSObject *obj, JSBool isNew , | |||
void *closure); | void *closure); | |||
typedef JSBool | typedef JSBool | |||
(* JS_DLL_CALLBACK JSDebugErrorHook)(JSContext *cx, const char *message, | (* JS_DLL_CALLBACK JSDebugErrorHook)(JSContext *cx, const char *message, | |||
JSErrorReport *report, void *closure); | JSErrorReport *report, void *closure); | |||
typedef struct JSDebugHooks { | ||||
JSTrapHandler interruptHandler; | ||||
void *interruptHandlerData; | ||||
JSNewScriptHook newScriptHook; | ||||
void *newScriptHookData; | ||||
JSDestroyScriptHook destroyScriptHook; | ||||
void *destroyScriptHookData; | ||||
JSTrapHandler debuggerHandler; | ||||
void *debuggerHandlerData; | ||||
JSSourceHandler sourceHandler; | ||||
void *sourceHandlerData; | ||||
JSInterpreterHook executeHook; | ||||
void *executeHookData; | ||||
JSInterpreterHook callHook; | ||||
void *callHookData; | ||||
JSObjectHook objectHook; | ||||
void *objectHookData; | ||||
JSTrapHandler throwHook; | ||||
void *throwHookData; | ||||
JSDebugErrorHook debugErrorHook; | ||||
void *debugErrorHookData; | ||||
} JSDebugHooks; | ||||
/* | ||||
* Type definitions for temporary GC roots that register with GC local C | ||||
* variables. See jscntxt.h for details. | ||||
*/ | ||||
typedef void | ||||
(* JS_DLL_CALLBACK JSTempValueTrace)(JSTracer *trc, JSTempValueRooter *tvr) | ||||
; | ||||
typedef union JSTempValueUnion { | ||||
jsval value; | ||||
JSObject *object; | ||||
JSString *string; | ||||
JSXML *xml; | ||||
JSXMLQName *qname; | ||||
JSXMLNamespace *nspace; | ||||
JSTempValueTrace trace; | ||||
JSScopeProperty *sprop; | ||||
JSWeakRoots *weakRoots; | ||||
JSParseContext *parseContext; | ||||
JSScript *script; | ||||
jsval *array; | ||||
} JSTempValueUnion; | ||||
struct JSTempValueRooter { | ||||
JSTempValueRooter *down; | ||||
ptrdiff_t count; | ||||
JSTempValueUnion u; | ||||
}; | ||||
/* | ||||
* The following determines whether JS_EncodeCharacters and JS_DecodeBytes | ||||
* treat char[] as utf-8 or simply as bytes that need to be inflated/deflat | ||||
ed. | ||||
*/ | ||||
#ifdef JS_C_STRINGS_ARE_UTF8 | ||||
# define js_CStringsAreUTF8 JS_TRUE | ||||
#else | ||||
extern JSBool js_CStringsAreUTF8; | ||||
#endif | ||||
#endif /* jsprvtd_h___ */ | #endif /* jsprvtd_h___ */ | |||
End of changes. 11 change blocks. | ||||
21 lines changed or deleted | 89 lines changed or added | |||
jspubtd.h | jspubtd.h | |||
---|---|---|---|---|
skipping to change at line 74 | skipping to change at line 74 | |||
typedef enum JSVersion { | typedef enum JSVersion { | |||
JSVERSION_1_0 = 100, | JSVERSION_1_0 = 100, | |||
JSVERSION_1_1 = 110, | JSVERSION_1_1 = 110, | |||
JSVERSION_1_2 = 120, | JSVERSION_1_2 = 120, | |||
JSVERSION_1_3 = 130, | JSVERSION_1_3 = 130, | |||
JSVERSION_1_4 = 140, | JSVERSION_1_4 = 140, | |||
JSVERSION_ECMA_3 = 148, | JSVERSION_ECMA_3 = 148, | |||
JSVERSION_1_5 = 150, | JSVERSION_1_5 = 150, | |||
JSVERSION_1_6 = 160, | JSVERSION_1_6 = 160, | |||
JSVERSION_1_7 = 170, | JSVERSION_1_7 = 170, | |||
JSVERSION_1_8 = 180, | ||||
JSVERSION_DEFAULT = 0, | JSVERSION_DEFAULT = 0, | |||
JSVERSION_UNKNOWN = -1 | JSVERSION_UNKNOWN = -1, | |||
JSVERSION_LATEST = JSVERSION_1_8 | ||||
} JSVersion; | } JSVersion; | |||
#define JSVERSION_IS_ECMA(version) \ | #define JSVERSION_IS_ECMA(version) \ | |||
((version) == JSVERSION_DEFAULT || (version) >= JSVERSION_1_3) | ((version) == JSVERSION_DEFAULT || (version) >= JSVERSION_1_3) | |||
/* Result of typeof operator enumeration. */ | /* Result of typeof operator enumeration. */ | |||
typedef enum JSType { | typedef enum JSType { | |||
JSTYPE_VOID, /* undefined */ | JSTYPE_VOID, /* undefined */ | |||
JSTYPE_OBJECT, /* object */ | JSTYPE_OBJECT, /* object */ | |||
JSTYPE_FUNCTION, /* function */ | JSTYPE_FUNCTION, /* function */ | |||
skipping to change at line 133 | skipping to change at line 135 | |||
} JSIterateOp; | } JSIterateOp; | |||
/* Struct typedefs. */ | /* Struct typedefs. */ | |||
typedef struct JSClass JSClass; | typedef struct JSClass JSClass; | |||
typedef struct JSExtendedClass JSExtendedClass; | typedef struct JSExtendedClass JSExtendedClass; | |||
typedef struct JSConstDoubleSpec JSConstDoubleSpec; | typedef struct JSConstDoubleSpec JSConstDoubleSpec; | |||
typedef struct JSContext JSContext; | typedef struct JSContext JSContext; | |||
typedef struct JSErrorReport JSErrorReport; | typedef struct JSErrorReport JSErrorReport; | |||
typedef struct JSFunction JSFunction; | typedef struct JSFunction JSFunction; | |||
typedef struct JSFunctionSpec JSFunctionSpec; | typedef struct JSFunctionSpec JSFunctionSpec; | |||
typedef struct JSTracer JSTracer; | ||||
typedef struct JSIdArray JSIdArray; | typedef struct JSIdArray JSIdArray; | |||
typedef struct JSProperty JSProperty; | typedef struct JSProperty JSProperty; | |||
typedef struct JSPropertySpec JSPropertySpec; | typedef struct JSPropertySpec JSPropertySpec; | |||
typedef struct JSObject JSObject; | typedef struct JSObject JSObject; | |||
typedef struct JSObjectMap JSObjectMap; | typedef struct JSObjectMap JSObjectMap; | |||
typedef struct JSObjectOps JSObjectOps; | typedef struct JSObjectOps JSObjectOps; | |||
typedef struct JSXMLObjectOps JSXMLObjectOps; | typedef struct JSXMLObjectOps JSXMLObjectOps; | |||
typedef struct JSRuntime JSRuntime; | typedef struct JSRuntime JSRuntime; | |||
typedef struct JSRuntime JSTaskState; /* XXX deprecated name */ | typedef struct JSRuntime JSTaskState; /* XXX deprecated name */ | |||
typedef struct JSScript JSScript; | typedef struct JSScript JSScript; | |||
skipping to change at line 276 | skipping to change at line 279 | |||
* Used by JS_AddExternalStringFinalizer and JS_RemoveExternalStringFinaliz er | * Used by JS_AddExternalStringFinalizer and JS_RemoveExternalStringFinaliz er | |||
* to extend and reduce the set of string types finalized by the GC. | * to extend and reduce the set of string types finalized by the GC. | |||
*/ | */ | |||
typedef void | typedef void | |||
(* JS_DLL_CALLBACK JSStringFinalizeOp)(JSContext *cx, JSString *str); | (* JS_DLL_CALLBACK JSStringFinalizeOp)(JSContext *cx, JSString *str); | |||
/* | /* | |||
* The signature for JSClass.getObjectOps, used by JS_NewObject's internals | * The signature for JSClass.getObjectOps, used by JS_NewObject's internals | |||
* to discover the set of high-level object operations to use for new objec ts | * to discover the set of high-level object operations to use for new objec ts | |||
* of the given class. All native objects have a JSClass, which is stored as | * of the given class. All native objects have a JSClass, which is stored as | |||
* a private (int-tagged) pointer in obj->slots[JSSLOT_CLASS]. In contrast | * a private (int-tagged) pointer in obj slots. In contrast, all native and | |||
, | * host objects have a JSObjectMap at obj->map, which may be shared among a | |||
* all native and host objects have a JSObjectMap at obj->map, which may be | * number of objects, and which contains the JSObjectOps *ops pointer used | |||
* shared among a number of objects, and which contains the JSObjectOps *op | to | |||
s | * dispatch object operations from API calls. | |||
* pointer used to dispatch object operations from API calls. | ||||
* | * | |||
* Thus JSClass (which pre-dates JSObjectOps in the API) provides a low-lev el | * Thus JSClass (which pre-dates JSObjectOps in the API) provides a low-lev el | |||
* interface to class-specific code and data, while JSObjectOps allows for a | * interface to class-specific code and data, while JSObjectOps allows for a | |||
* higher level of operation, which does not use the object's class except to | * higher level of operation, which does not use the object's class except to | |||
* find the class's JSObjectOps struct, by calling clasp->getObjectOps, and to | * find the class's JSObjectOps struct, by calling clasp->getObjectOps, and to | |||
* finalize the object. | * finalize the object. | |||
* | * | |||
* If this seems backwards, that's because it is! API compatibility requir es | * If this seems backwards, that's because it is! API compatibility requir es | |||
* a JSClass *clasp parameter to JS_NewObject, etc. Most host objects do n ot | * a JSClass *clasp parameter to JS_NewObject, etc. Most host objects do n ot | |||
* need to implement the larger JSObjectOps, and can share the common JSSco pe | * need to implement the larger JSObjectOps, and can share the common JSSco pe | |||
skipping to change at line 332 | skipping to change at line 335 | |||
/* | /* | |||
* Check whether v is an instance of obj. Return false on error or excepti on, | * Check whether v is an instance of obj. Return false on error or excepti on, | |||
* true on success with JS_TRUE in *bp if v is an instance of obj, JS_FALSE in | * true on success with JS_TRUE in *bp if v is an instance of obj, JS_FALSE in | |||
* *bp otherwise. | * *bp otherwise. | |||
*/ | */ | |||
typedef JSBool | typedef JSBool | |||
(* JS_DLL_CALLBACK JSHasInstanceOp)(JSContext *cx, JSObject *obj, jsval v, | (* JS_DLL_CALLBACK JSHasInstanceOp)(JSContext *cx, JSObject *obj, jsval v, | |||
JSBool *bp); | JSBool *bp); | |||
/* | /* | |||
* Function type for JSClass.mark and JSObjectOps.mark, called from the GC | * Deprecated function type for JSClass.mark. All new code should define | |||
to | * JSTraceOp instead to ensure the traversal of traceable things stored in | |||
* scan live GC-things reachable from obj's private data structure. For ea | * the native structures. | |||
ch | */ | |||
* such thing, a mark implementation must call | typedef uint32 | |||
(* JS_DLL_CALLBACK JSMarkOp)(JSContext *cx, JSObject *obj, void *arg); | ||||
/* | ||||
* Function type for trace operation of the class called to enumerate all | ||||
* traceable things reachable from obj's private data structure. For each s | ||||
uch | ||||
* thing, a trace implementation must call | ||||
* | * | |||
* JS_MarkGCThing(cx, thing, name, arg); | * JS_CallTracer(trc, thing, kind); | |||
* | * | |||
* The trailing name and arg parameters are used for GC_MARK_DEBUG-mode hea | * or one of its convenience macros as described in jsapi.h. | |||
p | ||||
* dumping and ref-path tracing. The mark function should pass a (typicall | ||||
y | ||||
* literal) string naming the private data member for name, and it must pas | ||||
s | ||||
* the opaque arg parameter through from its caller. | ||||
* | * | |||
* For the JSObjectOps.mark hook, the return value is the number of slots a | * JSTraceOp implementation can assume that no other threads mutates object | |||
t | * state. It must not change state of the object or corresponding native | |||
* obj->slots to scan. For JSClass.mark, the return value is ignored. | * structures. The only exception for this rule is the case when the embedd | |||
ing | ||||
* needs a tight integration with GC. In that case the embedding can check | ||||
if | ||||
* the traversal is a part of the marking phase through calling | ||||
* JS_IsGCMarkingTracer and apply a special code like emptying caches or | ||||
* marking its native structures. | ||||
* | * | |||
* NB: JSMarkOp implementations cannot allocate new GC-things (JS_NewObject | * To define the tracer for a JSClass, the implementation must add | |||
* called from a mark function will fail silently, e.g.). | * JSCLASS_MARK_IS_TRACE to class flags and use JS_CLASS_TRACE(method) | |||
* macro below to convert JSTraceOp to JSMarkOp when initializing or | ||||
* assigning JSClass.mark field. | ||||
*/ | */ | |||
typedef uint32 | typedef void | |||
(* JS_DLL_CALLBACK JSMarkOp)(JSContext *cx, JSObject *obj, void *arg); | (* JS_DLL_CALLBACK JSTraceOp)(JSTracer *trc, JSObject *obj); | |||
#if defined __GNUC__ && __GNUC__ >= 4 && !defined __cplusplus | ||||
# define JS_CLASS_TRACE(method) | ||||
\ | ||||
(__builtin_types_compatible_p(JSTraceOp, __typeof(&(method))) | ||||
\ | ||||
? (JSMarkOp)(method) | ||||
\ | ||||
: js_WrongTypeForClassTracer) | ||||
extern JSMarkOp js_WrongTypeForClassTracer; | ||||
#else | ||||
# define JS_CLASS_TRACE(method) ((JSMarkOp)(method)) | ||||
#endif | ||||
/* | ||||
* Tracer callback, called for each traceable thing directly refrenced by a | ||||
* particular object or runtime structure. It is the callback responsibilit | ||||
y | ||||
* to ensure the traversal of the full object graph via calling eventually | ||||
* JS_TraceChildren on the passed thing. In this case the callback must be | ||||
* prepared to deal with cycles in the traversal graph. | ||||
* | ||||
* kind argument is one of JSTRACE_OBJECT, JSTRACE_DOUBLE, JSTRACE_STRING o | ||||
r | ||||
* a tag denoting internal implementation-specific traversal kind. In the | ||||
* latter case the only operations on thing that the callback can do is to | ||||
call | ||||
* JS_TraceChildren or DEBUG-only JS_PrintTraceThingInfo. | ||||
*/ | ||||
typedef void | ||||
(* JS_DLL_CALLBACK JSTraceCallback)(JSTracer *trc, void *thing, uint32 kind | ||||
); | ||||
/* | ||||
* DEBUG only callback that JSTraceOp implementation can provide to return | ||||
* a string describing the reference traced with JS_CallTracer. | ||||
*/ | ||||
#ifdef DEBUG | ||||
typedef void | ||||
(* JS_DLL_CALLBACK JSTraceNamePrinter)(JSTracer *trc, char *buf, | ||||
size_t bufsize); | ||||
#endif | ||||
/* | /* | |||
* The optional JSClass.reserveSlots hook allows a class to make computed | * The optional JSClass.reserveSlots hook allows a class to make computed | |||
* per-instance object slots reservations, in addition to or instead of usi ng | * per-instance object slots reservations, in addition to or instead of usi ng | |||
* JSCLASS_HAS_RESERVED_SLOTS(n) in the JSClass.flags initializer to reserv e | * JSCLASS_HAS_RESERVED_SLOTS(n) in the JSClass.flags initializer to reserv e | |||
* a constant-per-class number of slots. Implementations of this hook shou ld | * a constant-per-class number of slots. Implementations of this hook shou ld | |||
* return the number of slots to reserve, not including any reserved by usi ng | * return the number of slots to reserve, not including any reserved by usi ng | |||
* JSCLASS_HAS_RESERVED_SLOTS(n) in JSClass.flags. | * JSCLASS_HAS_RESERVED_SLOTS(n) in JSClass.flags. | |||
* | * | |||
* NB: called with obj locked by the JSObjectOps-specific mutual exclusion | * NB: called with obj locked by the JSObjectOps-specific mutual exclusion | |||
skipping to change at line 474 | skipping to change at line 526 | |||
/* | /* | |||
* A generic type for functions mapping an object to another object, or nul l | * A generic type for functions mapping an object to another object, or nul l | |||
* if an error or exception was thrown on cx. Used by JSObjectOps.thisObje ct | * if an error or exception was thrown on cx. Used by JSObjectOps.thisObje ct | |||
* at present. | * at present. | |||
*/ | */ | |||
typedef JSObject * | typedef JSObject * | |||
(* JS_DLL_CALLBACK JSObjectOp)(JSContext *cx, JSObject *obj); | (* JS_DLL_CALLBACK JSObjectOp)(JSContext *cx, JSObject *obj); | |||
/* | /* | |||
* Hook that creates an iterator object for a given object. Returns the | ||||
* iterator object or null if an error or exception was thrown on cx. | ||||
*/ | ||||
typedef JSObject * | ||||
(* JS_DLL_CALLBACK JSIteratorOp)(JSContext *cx, JSObject *obj, | ||||
JSBool keysonly); | ||||
/* | ||||
* A generic type for functions taking a context, object, and property, wit h | * A generic type for functions taking a context, object, and property, wit h | |||
* no return value. Used by JSObjectOps.dropProperty currently (see above, | * no return value. Used by JSObjectOps.dropProperty currently (see above, | |||
* JSDefinePropOp and JSLookupPropOp, for the object-locking protocol in wh ich | * JSDefinePropOp and JSLookupPropOp, for the object-locking protocol in wh ich | |||
* dropProperty participates). | * dropProperty participates). | |||
*/ | */ | |||
typedef void | typedef void | |||
(* JS_DLL_CALLBACK JSPropertyRefOp)(JSContext *cx, JSObject *obj, | (* JS_DLL_CALLBACK JSPropertyRefOp)(JSContext *cx, JSObject *obj, | |||
JSProperty *prop); | JSProperty *prop); | |||
/* | /* | |||
* Function type for JSObjectOps.setProto and JSObjectOps.setParent. These | * Function pointer type for JSObjectOps.setProto and JSObjectOps.setParent | |||
* hooks must check for cycles without deadlocking, and otherwise take spec | . | |||
ial | * These hooks must check for cycles without deadlocking, and otherwise tak | |||
* steps. See jsobj.c, js_SetProtoOrParent, for an example. | e | |||
* special steps. See jsobj.c and jsgc.c for details. | ||||
*/ | */ | |||
typedef JSBool | typedef JSBool | |||
(* JS_DLL_CALLBACK JSSetObjectSlotOp)(JSContext *cx, JSObject *obj, | (* JS_DLL_CALLBACK JSSetObjectSlotOp)(JSContext *cx, JSObject *obj, | |||
uint32 slot, JSObject *pobj); | uint32 slot, JSObject *pobj); | |||
/* | /* | |||
* Get and set a required slot, one that should already have been allocated . | * Get and set a required slot, one that should already have been allocated . | |||
* These operations are infallible, so required slots must be pre-allocated , | * These operations are infallible, so required slots must be pre-allocated , | |||
* or implementations must suppress out-of-memory errors. The native ops | * or implementations must suppress out-of-memory errors. The native ops | |||
* (js_ObjectOps, see jsobj.c) access slots reserved by including a call to | * (js_ObjectOps, see jsobj.c) access slots reserved by including a call to | |||
* the JSCLASS_HAS_RESERVED_SLOTS(n) macro in the JSClass.flags initializer . | * the JSCLASS_HAS_RESERVED_SLOTS(n) macro in the JSClass.flags initializer . | |||
* | * | |||
* NB: the slot parameter is a zero-based index into obj->slots[], unlike t he | * NB: the slot parameter is a zero-based index into obj slots, unlike the | |||
* index parameter to the JS_GetReservedSlot and JS_SetReservedSlot API ent ry | * index parameter to the JS_GetReservedSlot and JS_SetReservedSlot API ent ry | |||
* points, which is a zero-based index into the JSCLASS_RESERVED_SLOTS(clas p) | * points, which is a zero-based index into the JSCLASS_RESERVED_SLOTS(clas p) | |||
* reserved slots that come after the initial well-known slots: proto, pare nt, | * reserved slots that come after the initial well-known slots: proto, pare nt, | |||
* class, and optionally, the private data slot. | * class, and optionally, the private data slot. | |||
*/ | */ | |||
typedef jsval | typedef jsval | |||
(* JS_DLL_CALLBACK JSGetRequiredSlotOp)(JSContext *cx, JSObject *obj, | (* JS_DLL_CALLBACK JSGetRequiredSlotOp)(JSContext *cx, JSObject *obj, | |||
uint32 slot); | uint32 slot); | |||
typedef JSBool | typedef JSBool | |||
skipping to change at line 540 | skipping to change at line 600 | |||
typedef JSBool | typedef JSBool | |||
(* JS_DLL_CALLBACK JSConcatenateOp)(JSContext *cx, JSObject *obj, jsval v, | (* JS_DLL_CALLBACK JSConcatenateOp)(JSContext *cx, JSObject *obj, jsval v, | |||
jsval *vp); | jsval *vp); | |||
/* Typedef for native functions called by the JS VM. */ | /* Typedef for native functions called by the JS VM. */ | |||
typedef JSBool | typedef JSBool | |||
(* JS_DLL_CALLBACK JSNative)(JSContext *cx, JSObject *obj, uintN argc, | (* JS_DLL_CALLBACK JSNative)(JSContext *cx, JSObject *obj, uintN argc, | |||
jsval *argv, jsval *rval); | jsval *argv, jsval *rval); | |||
/* See jsapi.h, the JS_CALLEE, JS_THIS, etc. macros. */ | ||||
typedef JSBool | ||||
(* JS_DLL_CALLBACK JSFastNative)(JSContext *cx, uintN argc, jsval *vp); | ||||
/* Callbacks and their arguments. */ | /* Callbacks and their arguments. */ | |||
typedef enum JSContextOp { | typedef enum JSContextOp { | |||
JSCONTEXT_NEW, | JSCONTEXT_NEW, | |||
JSCONTEXT_DESTROY | JSCONTEXT_DESTROY | |||
} JSContextOp; | } JSContextOp; | |||
/* | /* | |||
* The possible values for contextOp when the runtime calls the callback ar e: | * The possible values for contextOp when the runtime calls the callback ar e: | |||
* JSCONTEXT_NEW JS_NewContext succesfully created a new JSContext | * JSCONTEXT_NEW JS_NewContext successfully created a new JSContext | |||
* instance. The callback can initialize the instance as | * instance. The callback can initialize the instance as | |||
* required. If the callback returns false, the instan ce | * required. If the callback returns false, the instan ce | |||
* will be destroyed and JS_NewContext returns null. I n | * will be destroyed and JS_NewContext returns null. I n | |||
* this case the callback is not called again. | * this case the callback is not called again. | |||
* JSCONTEXT_DESTROY One of JS_DestroyContext* methods is called. The | * JSCONTEXT_DESTROY One of JS_DestroyContext* methods is called. The | |||
* callback may perform its own cleanup and must alway s | * callback may perform its own cleanup and must alway s | |||
* return true. | * return true. | |||
* Any other value For future compatibility the callback must do nothi ng | * Any other value For future compatibility the callback must do nothi ng | |||
* and return true in this case. | * and return true in this case. | |||
*/ | */ | |||
skipping to change at line 573 | skipping to change at line 637 | |||
typedef enum JSGCStatus { | typedef enum JSGCStatus { | |||
JSGC_BEGIN, | JSGC_BEGIN, | |||
JSGC_END, | JSGC_END, | |||
JSGC_MARK_END, | JSGC_MARK_END, | |||
JSGC_FINALIZE_END | JSGC_FINALIZE_END | |||
} JSGCStatus; | } JSGCStatus; | |||
typedef JSBool | typedef JSBool | |||
(* JS_DLL_CALLBACK JSGCCallback)(JSContext *cx, JSGCStatus status); | (* JS_DLL_CALLBACK JSGCCallback)(JSContext *cx, JSGCStatus status); | |||
/* | ||||
* Generic trace operation that calls JS_CallTracer on each traceable thing | ||||
* stored in data. | ||||
*/ | ||||
typedef void | ||||
(* JS_DLL_CALLBACK JSTraceDataOp)(JSTracer *trc, void *data); | ||||
typedef JSBool | ||||
(* JS_DLL_CALLBACK JSOperationCallback)(JSContext *cx); | ||||
/* | ||||
* Deprecated form of JSOperationCallback. | ||||
*/ | ||||
typedef JSBool | typedef JSBool | |||
(* JS_DLL_CALLBACK JSBranchCallback)(JSContext *cx, JSScript *script); | (* JS_DLL_CALLBACK JSBranchCallback)(JSContext *cx, JSScript *script); | |||
typedef void | typedef void | |||
(* JS_DLL_CALLBACK JSErrorReporter)(JSContext *cx, const char *message, | (* JS_DLL_CALLBACK JSErrorReporter)(JSContext *cx, const char *message, | |||
JSErrorReport *report); | JSErrorReport *report); | |||
/* | /* | |||
* Possible exception types. These types are part of a JSErrorFormatString | * Possible exception types. These types are part of a JSErrorFormatString | |||
* structure. They define which error to throw in case of a runtime error. | * structure. They define which error to throw in case of a runtime error. | |||
skipping to change at line 599 | skipping to change at line 676 | |||
JSEXN_EVALERR, | JSEXN_EVALERR, | |||
JSEXN_RANGEERR, | JSEXN_RANGEERR, | |||
JSEXN_REFERENCEERR, | JSEXN_REFERENCEERR, | |||
JSEXN_SYNTAXERR, | JSEXN_SYNTAXERR, | |||
JSEXN_TYPEERR, | JSEXN_TYPEERR, | |||
JSEXN_URIERR, | JSEXN_URIERR, | |||
JSEXN_LIMIT | JSEXN_LIMIT | |||
} JSExnType; | } JSExnType; | |||
typedef struct JSErrorFormatString { | typedef struct JSErrorFormatString { | |||
/* The error format string (UTF-8 if JS_C_STRINGS_ARE_UTF8 is defined). */ | /* The error format string (UTF-8 if js_CStringsAreUTF8). */ | |||
const char *format; | const char *format; | |||
/* The number of arguments to expand in the formatted error message. */ | /* The number of arguments to expand in the formatted error message. */ | |||
uint16 argCount; | uint16 argCount; | |||
/* One of the JSExnType constants above. */ | /* One of the JSExnType constants above. */ | |||
int16 exnType; | int16 exnType; | |||
} JSErrorFormatString; | } JSErrorFormatString; | |||
typedef const JSErrorFormatString * | typedef const JSErrorFormatString * | |||
End of changes. 17 change blocks. | ||||
34 lines changed or deleted | 115 lines changed or added | |||
jsregexp.h | jsregexp.h | |||
---|---|---|---|---|
skipping to change at line 53 | skipping to change at line 53 | |||
* JS regular expression interface. | * JS regular expression interface. | |||
*/ | */ | |||
#include <stddef.h> | #include <stddef.h> | |||
#include "jspubtd.h" | #include "jspubtd.h" | |||
#include "jsstr.h" | #include "jsstr.h" | |||
#ifdef JS_THREADSAFE | #ifdef JS_THREADSAFE | |||
#include "jsdhash.h" | #include "jsdhash.h" | |||
#endif | #endif | |||
JS_BEGIN_EXTERN_C | ||||
struct JSRegExpStatics { | struct JSRegExpStatics { | |||
JSString *input; /* input string to match (perl $_, GC root) */ | JSString *input; /* input string to match (perl $_, GC root) */ | |||
JSBool multiline; /* whether input contains newlines (perl $* ) */ | JSBool multiline; /* whether input contains newlines (perl $* ) */ | |||
uint16 parenCount; /* number of valid elements in parens[] */ | uint16 parenCount; /* number of valid elements in parens[] */ | |||
uint16 moreLength; /* number of allocated elements in morePare ns */ | uint16 moreLength; /* number of allocated elements in morePare ns */ | |||
JSSubString parens[9]; /* last set of parens matched (perl $1, $2) */ | JSSubString parens[9]; /* last set of parens matched (perl $1, $2) */ | |||
JSSubString *moreParens; /* null or realloc'd vector for $10, etc. * / | JSSubString *moreParens; /* null or realloc'd vector for $10, etc. * / | |||
JSSubString lastMatch; /* last string matched (perl $&) */ | JSSubString lastMatch; /* last string matched (perl $&) */ | |||
JSSubString lastParen; /* last paren matched (perl $+) */ | JSSubString lastParen; /* last paren matched (perl $+) */ | |||
JSSubString leftContext; /* input to left of last match (perl $`) */ | JSSubString leftContext; /* input to left of last match (perl $`) */ | |||
skipping to change at line 103 | skipping to change at line 105 | |||
? ((jsuint)(num) < 9) \ | ? ((jsuint)(num) < 9) \ | |||
? &(res)->parens[num] \ | ? &(res)->parens[num] \ | |||
: &(res)->moreParens[(num) - 9] \ | : &(res)->moreParens[(num) - 9] \ | |||
: &js_EmptySubString) | : &js_EmptySubString) | |||
typedef struct RENode RENode; | typedef struct RENode RENode; | |||
struct JSRegExp { | struct JSRegExp { | |||
jsrefcount nrefs; /* reference count */ | jsrefcount nrefs; /* reference count */ | |||
uint16 flags; /* flags, see jsapi.h's JSREG_* defines */ | uint16 flags; /* flags, see jsapi.h's JSREG_* defines */ | |||
uint16 cloneIndex; /* index in fp->vars or funobj->slots of | ||||
cloned regexp object */ | ||||
size_t parenCount; /* number of parenthesized submatches */ | size_t parenCount; /* number of parenthesized submatches */ | |||
size_t classCount; /* count [...] bitmaps */ | size_t classCount; /* count [...] bitmaps */ | |||
RECharSet *classList; /* list of [...] bitmaps */ | RECharSet *classList; /* list of [...] bitmaps */ | |||
JSString *source; /* locked source string, sans // */ | JSString *source; /* locked source string, sans // */ | |||
jsbytecode program[1]; /* regular expression bytecode */ | jsbytecode program[1]; /* regular expression bytecode */ | |||
}; | }; | |||
extern JSRegExp * | extern JSRegExp * | |||
js_NewRegExp(JSContext *cx, JSTokenStream *ts, | js_NewRegExp(JSContext *cx, JSTokenStream *ts, | |||
JSString *str, uintN flags, JSBool flat); | JSString *str, uintN flags, JSBool flat); | |||
extern JSRegExp * | extern JSRegExp * | |||
js_NewRegExpOpt(JSContext *cx, JSTokenStream *ts, | js_NewRegExpOpt(JSContext *cx, JSString *str, JSString *opt, JSBool flat); | |||
JSString *str, JSString *opt, JSBool flat); | ||||
#define HOLD_REGEXP(cx, re) JS_ATOMIC_INCREMENT(&(re)->nrefs) | #define HOLD_REGEXP(cx, re) JS_ATOMIC_INCREMENT(&(re)->nrefs) | |||
#define DROP_REGEXP(cx, re) js_DestroyRegExp(cx, re) | #define DROP_REGEXP(cx, re) js_DestroyRegExp(cx, re) | |||
extern void | extern void | |||
js_DestroyRegExp(JSContext *cx, JSRegExp *re); | js_DestroyRegExp(JSContext *cx, JSRegExp *re); | |||
/* | /* | |||
* Execute re on input str at *indexp, returning null in *rval on mismatch. | * Execute re on input str at *indexp, returning null in *rval on mismatch. | |||
* On match, return true if test is true, otherwise return an array object. | * On match, return true if test is true, otherwise return an array object. | |||
skipping to change at line 158 | skipping to change at line 157 | |||
extern JSClass js_RegExpClass; | extern JSClass js_RegExpClass; | |||
extern JSObject * | extern JSObject * | |||
js_InitRegExpClass(JSContext *cx, JSObject *obj); | js_InitRegExpClass(JSContext *cx, JSObject *obj); | |||
/* | /* | |||
* Export js_regexp_toString to the decompiler. | * Export js_regexp_toString to the decompiler. | |||
*/ | */ | |||
extern JSBool | extern JSBool | |||
js_regexp_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, | js_regexp_toString(JSContext *cx, JSObject *obj, jsval *vp); | |||
jsval *rval); | ||||
/* | /* | |||
* Create, serialize/deserialize, or clone a RegExp object. | * Create, serialize/deserialize, or clone a RegExp object. | |||
*/ | */ | |||
extern JSObject * | extern JSObject * | |||
js_NewRegExpObject(JSContext *cx, JSTokenStream *ts, | js_NewRegExpObject(JSContext *cx, JSTokenStream *ts, | |||
jschar *chars, size_t length, uintN flags); | jschar *chars, size_t length, uintN flags); | |||
extern JSBool | extern JSBool | |||
js_XDRRegExp(JSXDRState *xdr, JSObject **objp); | js_XDRRegExp(JSXDRState *xdr, JSObject **objp); | |||
skipping to change at line 183 | skipping to change at line 181 | |||
/* | /* | |||
* Get and set the per-object (clone or clone-parent) lastIndex slot. | * Get and set the per-object (clone or clone-parent) lastIndex slot. | |||
*/ | */ | |||
extern JSBool | extern JSBool | |||
js_GetLastIndex(JSContext *cx, JSObject *obj, jsdouble *lastIndex); | js_GetLastIndex(JSContext *cx, JSObject *obj, jsdouble *lastIndex); | |||
extern JSBool | extern JSBool | |||
js_SetLastIndex(JSContext *cx, JSObject *obj, jsdouble lastIndex); | js_SetLastIndex(JSContext *cx, JSObject *obj, jsdouble lastIndex); | |||
JS_END_EXTERN_C | ||||
#endif /* jsregexp_h___ */ | #endif /* jsregexp_h___ */ | |||
End of changes. 5 change blocks. | ||||
6 lines changed or deleted | 6 lines changed or added | |||
jsscan.h | jsscan.h | |||
---|---|---|---|---|
skipping to change at line 87 | skipping to change at line 87 | |||
TOK_STAR = 17, TOK_DIVOP = 18, /* multiply/divide ops (* / %) */ | TOK_STAR = 17, TOK_DIVOP = 18, /* multiply/divide ops (* / %) */ | |||
TOK_UNARYOP = 19, /* unary prefix operator */ | TOK_UNARYOP = 19, /* unary prefix operator */ | |||
TOK_INC = 20, TOK_DEC = 21, /* increment/decrement (++ --) */ | TOK_INC = 20, TOK_DEC = 21, /* increment/decrement (++ --) */ | |||
TOK_DOT = 22, /* member operator (.) */ | TOK_DOT = 22, /* member operator (.) */ | |||
TOK_LB = 23, TOK_RB = 24, /* left and right brackets */ | TOK_LB = 23, TOK_RB = 24, /* left and right brackets */ | |||
TOK_LC = 25, TOK_RC = 26, /* left and right curlies (braces) */ | TOK_LC = 25, TOK_RC = 26, /* left and right curlies (braces) */ | |||
TOK_LP = 27, TOK_RP = 28, /* left and right parentheses */ | TOK_LP = 27, TOK_RP = 28, /* left and right parentheses */ | |||
TOK_NAME = 29, /* identifier */ | TOK_NAME = 29, /* identifier */ | |||
TOK_NUMBER = 30, /* numeric constant */ | TOK_NUMBER = 30, /* numeric constant */ | |||
TOK_STRING = 31, /* string constant */ | TOK_STRING = 31, /* string constant */ | |||
TOK_OBJECT = 32, /* RegExp or other object constant */ | TOK_REGEXP = 32, /* RegExp constant */ | |||
TOK_PRIMARY = 33, /* true, false, null, this, super * / | TOK_PRIMARY = 33, /* true, false, null, this, super * / | |||
TOK_FUNCTION = 34, /* function keyword */ | TOK_FUNCTION = 34, /* function keyword */ | |||
TOK_EXPORT = 35, /* export keyword */ | TOK_EXPORT = 35, /* export keyword */ | |||
TOK_IMPORT = 36, /* import keyword */ | TOK_IMPORT = 36, /* import keyword */ | |||
TOK_IF = 37, /* if keyword */ | TOK_IF = 37, /* if keyword */ | |||
TOK_ELSE = 38, /* else keyword */ | TOK_ELSE = 38, /* else keyword */ | |||
TOK_SWITCH = 39, /* switch keyword */ | TOK_SWITCH = 39, /* switch keyword */ | |||
TOK_CASE = 40, /* case keyword */ | TOK_CASE = 40, /* case keyword */ | |||
TOK_DEFAULT = 41, /* default keyword */ | TOK_DEFAULT = 41, /* default keyword */ | |||
TOK_WHILE = 42, /* while keyword */ | TOK_WHILE = 42, /* while keyword */ | |||
skipping to change at line 203 | skipping to change at line 203 | |||
struct JSTokenPos { | struct JSTokenPos { | |||
JSTokenPtr begin; /* first character and line of toke n */ | JSTokenPtr begin; /* first character and line of toke n */ | |||
JSTokenPtr end; /* index 1 past last char, last lin e */ | JSTokenPtr end; /* index 1 past last char, last lin e */ | |||
}; | }; | |||
struct JSToken { | struct JSToken { | |||
JSTokenType type; /* char value or above enumerator * / | JSTokenType type; /* char value or above enumerator * / | |||
JSTokenPos pos; /* token position in file */ | JSTokenPos pos; /* token position in file */ | |||
jschar *ptr; /* beginning of token in line buffe r */ | jschar *ptr; /* beginning of token in line buffe r */ | |||
union { | union { | |||
struct { /* non-numeric literal */ | struct { /* name or string literal */ | |||
JSOp op; /* operator, for minimal parser */ | JSOp op; /* operator, for minimal parser */ | |||
JSAtom *atom; /* atom table entry */ | JSAtom *atom; /* atom table entry */ | |||
} s; | } s; | |||
uintN reflags; /* regexp flags, use tokenbuf to ac | ||||
cess | ||||
regexp chars */ | ||||
struct { /* atom pair, for XML PIs */ | struct { /* atom pair, for XML PIs */ | |||
JSAtom *atom2; /* auxiliary atom table entry */ | JSAtom *atom2; /* auxiliary atom table entry */ | |||
JSAtom *atom; /* main atom table entry */ | JSAtom *atom; /* main atom table entry */ | |||
} p; | } p; | |||
jsdouble dval; /* floating point number */ | jsdouble dval; /* floating point number */ | |||
} u; | } u; | |||
}; | }; | |||
#define t_op u.s.op | #define t_op u.s.op | |||
#define t_reflags u.reflags | ||||
#define t_atom u.s.atom | #define t_atom u.s.atom | |||
#define t_atom2 u.p.atom2 | #define t_atom2 u.p.atom2 | |||
#define t_dval u.dval | #define t_dval u.dval | |||
typedef struct JSTokenBuf { | typedef struct JSTokenBuf { | |||
jschar *base; /* base of line or stream buffer */ | jschar *base; /* base of line or stream buffer */ | |||
jschar *limit; /* limit for quick bounds check */ | jschar *limit; /* limit for quick bounds check */ | |||
jschar *ptr; /* next char to get, or slot to use */ | jschar *ptr; /* next char to get, or slot to use */ | |||
} JSTokenBuf; | } JSTokenBuf; | |||
skipping to change at line 246 | skipping to change at line 249 | |||
uintN ungetpos; /* next free char slot in ungetbuf */ | uintN ungetpos; /* next free char slot in ungetbuf */ | |||
jschar ungetbuf[6]; /* at most 6, for \uXXXX lookahead */ | jschar ungetbuf[6]; /* at most 6, for \uXXXX lookahead */ | |||
uintN flags; /* flags -- see below */ | uintN flags; /* flags -- see below */ | |||
ptrdiff_t linelen; /* physical linebuf segment length */ | ptrdiff_t linelen; /* physical linebuf segment length */ | |||
ptrdiff_t linepos; /* linebuf offset in physical line */ | ptrdiff_t linepos; /* linebuf offset in physical line */ | |||
JSTokenBuf linebuf; /* line buffer for diagnostics */ | JSTokenBuf linebuf; /* line buffer for diagnostics */ | |||
JSTokenBuf userbuf; /* user input buffer if !file */ | JSTokenBuf userbuf; /* user input buffer if !file */ | |||
JSStringBuffer tokenbuf; /* current token string buffer */ | JSStringBuffer tokenbuf; /* current token string buffer */ | |||
const char *filename; /* input filename or null */ | const char *filename; /* input filename or null */ | |||
FILE *file; /* stdio stream if reading from fil e */ | FILE *file; /* stdio stream if reading from fil e */ | |||
JSPrincipals *principals; /* principals associated with sourc e */ | ||||
JSSourceHandler listener; /* callback for source; eg debugger */ | JSSourceHandler listener; /* callback for source; eg debugger */ | |||
void *listenerData; /* listener 'this' data */ | void *listenerData; /* listener 'this' data */ | |||
void *listenerTSData;/* listener data for this TokenStre am */ | void *listenerTSData;/* listener data for this TokenStre am */ | |||
jschar *saveEOL; /* save next end of line in userbuf , to | jschar *saveEOL; /* save next end of line in userbuf , to | |||
optimize for very long lines */ | optimize for very long lines */ | |||
}; | }; | |||
#define CURRENT_TOKEN(ts) ((ts)->tokens[(ts)->cursor]) | #define CURRENT_TOKEN(ts) ((ts)->tokens[(ts)->cursor]) | |||
#define ON_CURRENT_LINE(ts,pos) ((uint16)(ts)->lineno == (pos).end.lineno) | #define ON_CURRENT_LINE(ts,pos) ((uint16)(ts)->lineno == (pos).end.lineno) | |||
skipping to change at line 305 | skipping to change at line 307 | |||
#define TSF_KEYWORD_IS_NAME 0x4000 | #define TSF_KEYWORD_IS_NAME 0x4000 | |||
/* Unicode separators that are treated as line terminators, in addition to \n, \r */ | /* Unicode separators that are treated as line terminators, in addition to \n, \r */ | |||
#define LINE_SEPARATOR 0x2028 | #define LINE_SEPARATOR 0x2028 | |||
#define PARA_SEPARATOR 0x2029 | #define PARA_SEPARATOR 0x2029 | |||
/* | /* | |||
* Create a new token stream, either from an input buffer or from a file. | * Create a new token stream, either from an input buffer or from a file. | |||
* Return null on file-open or memory-allocation failure. | * Return null on file-open or memory-allocation failure. | |||
* | * | |||
* NB: All of js_New{,Buffer,File}TokenStream() return a pointer to transie | * The function uses JSContext.tempPool to allocate internal buffers. The | |||
nt | * caller should release them using JS_ARENA_RELEASE after it has finished | |||
* memory in the current context's temp pool. This memory is deallocated v | * with the token stream and has called js_CloseTokenStream. | |||
ia | ||||
* JS_ARENA_RELEASE() after parsing is finished. | ||||
*/ | */ | |||
extern JSTokenStream * | extern JSBool | |||
js_NewTokenStream(JSContext *cx, const jschar *base, size_t length, | js_InitTokenStream(JSContext *cx, JSTokenStream *ts, | |||
const char *filename, uintN lineno, JSPrincipals *princip | const jschar *base, size_t length, | |||
als); | FILE *fp, const char *filename, uintN lineno); | |||
extern JS_FRIEND_API(JSTokenStream *) | ||||
js_NewBufferTokenStream(JSContext *cx, const jschar *base, size_t length); | ||||
extern JS_FRIEND_API(JSTokenStream *) | ||||
js_NewFileTokenStream(JSContext *cx, const char *filename, FILE *defaultfp) | ||||
; | ||||
extern JS_FRIEND_API(JSBool) | extern void | |||
js_CloseTokenStream(JSContext *cx, JSTokenStream *ts); | js_CloseTokenStream(JSContext *cx, JSTokenStream *ts); | |||
extern JS_FRIEND_API(int) | extern JS_FRIEND_API(int) | |||
js_fgets(char *buf, int size, FILE *file); | js_fgets(char *buf, int size, FILE *file); | |||
/* | /* | |||
* If the given char array forms JavaScript keyword, return corresponding | * If the given char array forms JavaScript keyword, return corresponding | |||
* token. Otherwise return TOK_EOF. | * token. Otherwise return TOK_EOF. | |||
*/ | */ | |||
extern JSTokenType | extern JSTokenType | |||
js_CheckKeyword(const jschar *chars, size_t length); | js_CheckKeyword(const jschar *chars, size_t length); | |||
#define js_IsKeyword(chars, length) \ | ||||
(js_CheckKeyword(chars, length) != TOK_EOF) | ||||
/* | /* | |||
* Friend-exported API entry point to call a mapping function on each reser ved | * Friend-exported API entry point to call a mapping function on each reser ved | |||
* identifier in the scanner's keyword table. | * identifier in the scanner's keyword table. | |||
*/ | */ | |||
extern JS_FRIEND_API(void) | extern JS_FRIEND_API(void) | |||
js_MapKeywords(void (*mapfun)(const char *)); | js_MapKeywords(void (*mapfun)(const char *)); | |||
/* | /* | |||
* Report a compile-time error by its number, using ts or cg to show contex | * Check that str forms a valid JS identifier name. The function does not | |||
t. | * check if str is a JS keyword. | |||
* Return true for a warning, false for an error. | ||||
*/ | */ | |||
extern JSBool | extern JSBool | |||
js_ReportCompileErrorNumber(JSContext *cx, void *handle, uintN flags, | js_IsIdentifier(JSString *str); | |||
uintN errorNumber, ...); | ||||
extern JSBool | /* | |||
js_ReportCompileErrorNumberUC(JSContext *cx, void *handle, uintN flags, | * Report a compile-time error by its number. Return true for a warning, fa | |||
uintN errorNumber, ...); | lse | |||
* for an error. When pn is not null, use it to report error's location. | ||||
* Otherwise use ts, which must not be null. | ||||
*/ | ||||
JSBool | ||||
js_ReportCompileErrorNumber(JSContext *cx, JSTokenStream *ts, JSParseNode * | ||||
pn, | ||||
uintN flags, uintN errorNumber, ...); | ||||
/* Steal some JSREPORT_* bits (see jsapi.h) to tell handle's type. */ | /* | |||
#define JSREPORT_HANDLE 0x300 | * Steal one JSREPORT_* bit (see jsapi.h) to tell that arguments to the err | |||
#define JSREPORT_TS 0x000 | or | |||
#define JSREPORT_CG 0x100 | * message have const jschar* type, not const char*. | |||
#define JSREPORT_PN 0x200 | */ | |||
#define JSREPORT_UC 0x100 | ||||
/* | /* | |||
* Look ahead one token and return its type. | * Look ahead one token and return its type. | |||
*/ | */ | |||
extern JSTokenType | extern JSTokenType | |||
js_PeekToken(JSContext *cx, JSTokenStream *ts); | js_PeekToken(JSContext *cx, JSTokenStream *ts); | |||
extern JSTokenType | extern JSTokenType | |||
js_PeekTokenSameLine(JSContext *cx, JSTokenStream *ts); | js_PeekTokenSameLine(JSContext *cx, JSTokenStream *ts); | |||
End of changes. 13 change blocks. | ||||
36 lines changed or deleted | 33 lines changed or added | |||
jsscope.h | jsscope.h | |||
---|---|---|---|---|
skipping to change at line 47 | skipping to change at line 47 | |||
* the terms of any one of the MPL, the GPL or the LGPL. | * the terms of any one of the MPL, the GPL or the LGPL. | |||
* | * | |||
* ***** END LICENSE BLOCK ***** */ | * ***** END LICENSE BLOCK ***** */ | |||
#ifndef jsscope_h___ | #ifndef jsscope_h___ | |||
#define jsscope_h___ | #define jsscope_h___ | |||
/* | /* | |||
* JS symbol tables. | * JS symbol tables. | |||
*/ | */ | |||
#include "jstypes.h" | #include "jstypes.h" | |||
#include "jslock.h" | ||||
#include "jsobj.h" | #include "jsobj.h" | |||
#include "jsprvtd.h" | #include "jsprvtd.h" | |||
#include "jspubtd.h" | #include "jspubtd.h" | |||
#ifdef JS_THREADSAFE | JS_BEGIN_EXTERN_C | |||
# include "jslock.h" | ||||
#endif | ||||
/* | /* | |||
* Given P independent, non-unique properties each of size S words mapped b y | * Given P independent, non-unique properties each of size S words mapped b y | |||
* all scopes in a runtime, construct a property tree of N nodes each of si ze | * all scopes in a runtime, construct a property tree of N nodes each of si ze | |||
* S+L words (L for tree linkage). A nominal L value is 2 for leftmost-chi ld | * S+L words (L for tree linkage). A nominal L value is 2 for leftmost-chi ld | |||
* and right-sibling links. We hope that the N < P by enough that the spac e | * and right-sibling links. We hope that the N < P by enough that the spac e | |||
* overhead of L, and the overhead of scope entries pointing at property tr ee | * overhead of L, and the overhead of scope entries pointing at property tr ee | |||
* nodes, is worth it. | * nodes, is worth it. | |||
* | * | |||
* The tree construction goes as follows. If any empty scope in the runtim e | * The tree construction goes as follows. If any empty scope in the runtim e | |||
skipping to change at line 122 | skipping to change at line 121 | |||
* What if we add Y again? X->Y->Z->Y is wrong and we'll enumerate Y twice . | * What if we add Y again? X->Y->Z->Y is wrong and we'll enumerate Y twice . | |||
* Therefore we must fork in such a case, if not earlier. Because delete i s | * Therefore we must fork in such a case, if not earlier. Because delete i s | |||
* "bursty", we should not fork eagerly. Delaying a fork till we are at ri sk | * "bursty", we should not fork eagerly. Delaying a fork till we are at ri sk | |||
* of adding Y after it was deleted already requires a flag in the JSScope, to | * of adding Y after it was deleted already requires a flag in the JSScope, to | |||
* wit, SCOPE_MIDDLE_DELETE. | * wit, SCOPE_MIDDLE_DELETE. | |||
* | * | |||
* What about thread safety? If the property tree operations done by reque sts | * What about thread safety? If the property tree operations done by reque sts | |||
* are find-node and insert-node, then the only hazard is duplicate inserti on. | * are find-node and insert-node, then the only hazard is duplicate inserti on. | |||
* This is harmless except for minor bloat. When all requests have ended o r | * This is harmless except for minor bloat. When all requests have ended o r | |||
* been suspended, the GC is free to sweep the tree after marking all nodes | * been suspended, the GC is free to sweep the tree after marking all nodes | |||
* reachable from scopes, performing remove-node operations as needed. Not | * reachable from scopes, performing remove-node operations as needed. | |||
e | ||||
* also that the stable storage of the property nodes during active request | ||||
s | ||||
* permits the property cache (see jsinterp.h) to dereference JSScopeProper | ||||
ty | ||||
* weak references safely. | ||||
* | * | |||
* Is the property tree worth it compared to property storage in each table 's | * Is the property tree worth it compared to property storage in each table 's | |||
* entries? To decide, we must find the relation <> between the words used | * entries? To decide, we must find the relation <> between the words used | |||
* with a property tree and the words required without a tree. | * with a property tree and the words required without a tree. | |||
* | * | |||
* Model all scopes as one super-scope of capacity T entries (T a power of 2). | * Model all scopes as one super-scope of capacity T entries (T a power of 2). | |||
* Let alpha be the load factor of this double hash-table. With the proper ty | * Let alpha be the load factor of this double hash-table. With the proper ty | |||
* tree, each entry in the table is a word-sized pointer to a node that can be | * tree, each entry in the table is a word-sized pointer to a node that can be | |||
* shared by many scopes. But all such pointers are overhead compared to t he | * shared by many scopes. But all such pointers are overhead compared to t he | |||
* situation without the property tree, where the table stores property nod es | * situation without the property tree, where the table stores property nod es | |||
skipping to change at line 204 | skipping to change at line 200 | |||
* in Mozilla is < 5, with a large standard deviation (~8). Instead of alw ays | * in Mozilla is < 5, with a large standard deviation (~8). Instead of alw ays | |||
* allocating scope->table, we leave it null while initializing all the oth er | * allocating scope->table, we leave it null while initializing all the oth er | |||
* scope members as if it were non-null and minimal-length. Until a proper ty | * scope members as if it were non-null and minimal-length. Until a proper ty | |||
* is added that crosses the threshold of 6 or more entries for hashing, or | * is added that crosses the threshold of 6 or more entries for hashing, or | |||
* until a "middle delete" occurs, we use linear search from scope->lastPro p | * until a "middle delete" occurs, we use linear search from scope->lastPro p | |||
* to find a given id, and save on the space overhead of a hash table. | * to find a given id, and save on the space overhead of a hash table. | |||
*/ | */ | |||
struct JSScope { | struct JSScope { | |||
JSObjectMap map; /* base class state */ | JSObjectMap map; /* base class state */ | |||
#ifdef JS_THREADSAFE | ||||
JSTitle title; /* lock state */ | ||||
#endif | ||||
JSObject *object; /* object that owns this scope */ | JSObject *object; /* object that owns this scope */ | |||
uint32 shape; /* property cache shape identifier */ | ||||
uint8 flags; /* flags, see below */ | uint8 flags; /* flags, see below */ | |||
int8 hashShift; /* multiplicative hash shift */ | int8 hashShift; /* multiplicative hash shift */ | |||
uint16 spare; /* reserved */ | uint16 spare; /* reserved */ | |||
uint32 entryCount; /* number of entries in table */ | uint32 entryCount; /* number of entries in table */ | |||
uint32 removedCount; /* removed entry sentinels in table */ | uint32 removedCount; /* removed entry sentinels in table */ | |||
JSScopeProperty **table; /* table of ptrs to shared tree nod es */ | JSScopeProperty **table; /* table of ptrs to shared tree nod es */ | |||
JSScopeProperty *lastProp; /* pointer to last property added * / | JSScopeProperty *lastProp; /* pointer to last property added * / | |||
}; | ||||
#ifdef JS_THREADSAFE | #ifdef JS_THREADSAFE | |||
JSContext *ownercx; /* creating context, NULL if shared | JS_STATIC_ASSERT(offsetof(JSScope, title) == sizeof(JSObjectMap)); | |||
*/ | ||||
JSThinLock lock; /* binary semaphore protecting scop | ||||
e */ | ||||
union { /* union lockful and lock-free stat | ||||
e: */ | ||||
jsrefcount count; /* lock entry count for reentrancy | ||||
*/ | ||||
JSScope *link; /* next link in rt->scopeSharingTod | ||||
o */ | ||||
} u; | ||||
#ifdef DEBUG | ||||
const char *file[4]; /* file where lock was (re-)taken * | ||||
/ | ||||
unsigned int line[4]; /* line where lock was (re-)taken * | ||||
/ | ||||
#endif | ||||
#endif | #endif | |||
}; | ||||
#define JS_IS_SCOPE_LOCKED(cx, scope) JS_IS_TITLE_LOCKED(cx, &(scope)->ti | ||||
tle) | ||||
#define OBJ_SCOPE(obj) ((JSScope *)(obj)->map) | #define OBJ_SCOPE(obj) ((JSScope *)(obj)->map) | |||
#define SCOPE_MAKE_UNIQUE_SHAPE(cx,scope) | ||||
\ | ||||
((scope)->shape = js_GenerateShape((cx), JS_FALSE, NULL)) | ||||
#define SCOPE_EXTEND_SHAPE(cx,scope,sprop) | ||||
\ | ||||
JS_BEGIN_MACRO | ||||
\ | ||||
if (!(scope)->lastProp || | ||||
\ | ||||
(scope)->shape == (scope)->lastProp->shape) { | ||||
\ | ||||
(scope)->shape = (sprop)->shape; | ||||
\ | ||||
} else { | ||||
\ | ||||
(scope)->shape = js_GenerateShape((cx), JS_FALSE, sprop); | ||||
\ | ||||
} | ||||
\ | ||||
JS_END_MACRO | ||||
/* By definition, hashShift = JS_DHASH_BITS - log2(capacity). */ | /* By definition, hashShift = JS_DHASH_BITS - log2(capacity). */ | |||
#define SCOPE_CAPACITY(scope) JS_BIT(JS_DHASH_BITS-(scope)->hashS hift) | #define SCOPE_CAPACITY(scope) JS_BIT(JS_DHASH_BITS-(scope)->hashS hift) | |||
/* Scope flags and some macros to hide them from other files than jsscope.c . */ | /* Scope flags and some macros to hide them from other files than jsscope.c . */ | |||
#define SCOPE_MIDDLE_DELETE 0x0001 | #define SCOPE_MIDDLE_DELETE 0x0001 | |||
#define SCOPE_SEALED 0x0002 | #define SCOPE_SEALED 0x0002 | |||
#define SCOPE_BRANDED 0x0004 | ||||
#define SCOPE_HAD_MIDDLE_DELETE(scope) ((scope)->flags & SCOPE_MIDDLE_DELE TE) | #define SCOPE_HAD_MIDDLE_DELETE(scope) ((scope)->flags & SCOPE_MIDDLE_DELE TE) | |||
#define SCOPE_SET_MIDDLE_DELETE(scope) ((scope)->flags |= SCOPE_MIDDLE_DEL ETE) | #define SCOPE_SET_MIDDLE_DELETE(scope) ((scope)->flags |= SCOPE_MIDDLE_DEL ETE) | |||
#define SCOPE_CLR_MIDDLE_DELETE(scope) ((scope)->flags &= ~SCOPE_MIDDLE_DE LETE) | #define SCOPE_CLR_MIDDLE_DELETE(scope) ((scope)->flags &= ~SCOPE_MIDDLE_DE LETE) | |||
#define SCOPE_IS_SEALED(scope) ((scope)->flags & SCOPE_SEALED) | #define SCOPE_IS_SEALED(scope) ((scope)->flags & SCOPE_SEALED) | |||
#define SCOPE_SET_SEALED(scope) ((scope)->flags |= SCOPE_SEALED) | #define SCOPE_SET_SEALED(scope) ((scope)->flags |= SCOPE_SEALED) | |||
#if 0 | #if 0 | |||
/* | /* | |||
* Don't define this, it can't be done safely because JS_LOCK_OBJ will avoi d | * Don't define this, it can't be done safely because JS_LOCK_OBJ will avoi d | |||
* taking the lock if the object owns its scope and the scope is sealed. | * taking the lock if the object owns its scope and the scope is sealed. | |||
*/ | */ | |||
#define SCOPE_CLR_SEALED(scope) ((scope)->flags &= ~SCOPE_SEALED) | #undef SCOPE_CLR_SEALED(scope) ((scope)->flags &= ~SCOPE_SEALED) | |||
#endif | #endif | |||
/* | /* | |||
* A branded scope's object contains plain old methods (function-valued | ||||
* properties without magic getters and setters), and its scope->shape | ||||
* evolves whenever a function value changes. | ||||
*/ | ||||
#define SCOPE_IS_BRANDED(scope) ((scope)->flags & SCOPE_BRANDED) | ||||
#define SCOPE_SET_BRANDED(scope) ((scope)->flags |= SCOPE_BRANDED) | ||||
#define SCOPE_CLR_BRANDED(scope) ((scope)->flags &= ~SCOPE_BRANDED) | ||||
/* | ||||
* A little information hiding for scope->lastProp, in case it ever becomes | * A little information hiding for scope->lastProp, in case it ever becomes | |||
* a tagged pointer again. | * a tagged pointer again. | |||
*/ | */ | |||
#define SCOPE_LAST_PROP(scope) ((scope)->lastProp) | #define SCOPE_LAST_PROP(scope) ((scope)->lastProp) | |||
#define SCOPE_REMOVE_LAST_PROP(scope) ((scope)->lastProp = \ | #define SCOPE_REMOVE_LAST_PROP(scope) ((scope)->lastProp = \ | |||
(scope)->lastProp->parent) | (scope)->lastProp->parent) | |||
struct JSScopeProperty { | struct JSScopeProperty { | |||
jsid id; /* int-tagged jsval/untagged JSAtom * */ | jsid id; /* int-tagged jsval/untagged JSAtom * */ | |||
JSPropertyOp getter; /* getter and setter hooks or objec ts */ | JSPropertyOp getter; /* getter and setter hooks or objec ts */ | |||
JSPropertyOp setter; | JSPropertyOp setter; | |||
uint32 slot; /* index in obj->slots vector */ | uint32 slot; /* abstract index in object slots * / | |||
uint8 attrs; /* attributes, see jsapi.h JSPROP_* */ | uint8 attrs; /* attributes, see jsapi.h JSPROP_* */ | |||
uint8 flags; /* flags, see below for defines */ | uint8 flags; /* flags, see below for defines */ | |||
int16 shortid; /* tinyid, or local arg/var index * / | int16 shortid; /* tinyid, or local arg/var index * / | |||
JSScopeProperty *parent; /* parent node, reverse for..in ord er */ | JSScopeProperty *parent; /* parent node, reverse for..in ord er */ | |||
JSScopeProperty *kids; /* null, single child, or a tagged ptr | JSScopeProperty *kids; /* null, single child, or a tagged ptr | |||
to many-kids data structure */ | to many-kids data structure */ | |||
uint32 shape; /* property cache shape identifier */ | ||||
}; | }; | |||
/* JSScopeProperty pointer tag bit indicating a collision. */ | /* JSScopeProperty pointer tag bit indicating a collision. */ | |||
#define SPROP_COLLISION ((jsuword)1) | #define SPROP_COLLISION ((jsuword)1) | |||
#define SPROP_REMOVED ((JSScopeProperty *) SPROP_COLLISIO N) | #define SPROP_REMOVED ((JSScopeProperty *) SPROP_COLLISIO N) | |||
/* Macros to get and set sprop pointer values and collision flags. */ | /* Macros to get and set sprop pointer values and collision flags. */ | |||
#define SPROP_IS_FREE(sprop) ((sprop) == NULL) | #define SPROP_IS_FREE(sprop) ((sprop) == NULL) | |||
#define SPROP_IS_REMOVED(sprop) ((sprop) == SPROP_REMOVED) | #define SPROP_IS_REMOVED(sprop) ((sprop) == SPROP_REMOVED) | |||
#define SPROP_IS_LIVE(sprop) ((sprop) > SPROP_REMOVED) | #define SPROP_IS_LIVE(sprop) ((sprop) > SPROP_REMOVED) | |||
skipping to change at line 292 | skipping to change at line 310 | |||
#define SPROP_CLEAR_COLLISION(sprop) \ | #define SPROP_CLEAR_COLLISION(sprop) \ | |||
((JSScopeProperty *) ((jsuword)(sprop) & ~SPROP_COLLISION)) | ((JSScopeProperty *) ((jsuword)(sprop) & ~SPROP_COLLISION)) | |||
#define SPROP_STORE_PRESERVING_COLLISION(spp, sprop) \ | #define SPROP_STORE_PRESERVING_COLLISION(spp, sprop) \ | |||
(*(spp) = (JSScopeProperty *) ((jsuword)(sprop) \ | (*(spp) = (JSScopeProperty *) ((jsuword)(sprop) \ | |||
| SPROP_HAD_COLLISION(*(spp)))) | | SPROP_HAD_COLLISION(*(spp)))) | |||
/* Bits stored in sprop->flags. */ | /* Bits stored in sprop->flags. */ | |||
#define SPROP_MARK 0x01 | #define SPROP_MARK 0x01 | |||
#define SPROP_IS_DUPLICATE 0x02 | #define SPROP_IS_ALIAS 0x02 | |||
#define SPROP_IS_ALIAS 0x04 | #define SPROP_HAS_SHORTID 0x04 | |||
#define SPROP_HAS_SHORTID 0x08 | #define SPROP_FLAG_SHAPE_REGEN 0x08 | |||
#define SPROP_IS_HIDDEN 0x10 /* a normally-hidden proper | ||||
ty, | ||||
e.g., function arg or va | ||||
r */ | ||||
/* | /* | |||
* If SPROP_HAS_SHORTID is set in sprop->flags, we use sprop->shortid rathe r | * If SPROP_HAS_SHORTID is set in sprop->flags, we use sprop->shortid rathe r | |||
* than id when calling sprop's getter or setter. | * than id when calling sprop's getter or setter. | |||
*/ | */ | |||
#define SPROP_USERID(sprop) \ | #define SPROP_USERID(sprop) \ | |||
(((sprop)->flags & SPROP_HAS_SHORTID) ? INT_TO_JSVAL((sprop)->shortid) \ | (((sprop)->flags & SPROP_HAS_SHORTID) ? INT_TO_JSVAL((sprop)->shortid) \ | |||
: ID_TO_VALUE((sprop)->id)) | : ID_TO_VALUE((sprop)->id)) | |||
#define SPROP_INVALID_SLOT 0xffffffff | #define SPROP_INVALID_SLOT 0xffffffff | |||
skipping to change at line 352 | skipping to change at line 368 | |||
extern JSScope * | extern JSScope * | |||
js_GetMutableScope(JSContext *cx, JSObject *obj); | js_GetMutableScope(JSContext *cx, JSObject *obj); | |||
extern JSScope * | extern JSScope * | |||
js_NewScope(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops, JSClass *cla sp, | js_NewScope(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops, JSClass *cla sp, | |||
JSObject *obj); | JSObject *obj); | |||
extern void | extern void | |||
js_DestroyScope(JSContext *cx, JSScope *scope); | js_DestroyScope(JSContext *cx, JSScope *scope); | |||
#define ID_TO_VALUE(id) (JSID_IS_ATOM(id) ? ATOM_JSID_TO_JSVAL(id) : | ||||
\ | ||||
JSID_IS_OBJECT(id) ? OBJECT_JSID_TO_JSVAL(id) : | ||||
\ | ||||
(jsval)(id)) | ||||
#define HASH_ID(id) (JSID_IS_ATOM(id) ? JSID_TO_ATOM(id)->number : | ||||
\ | ||||
JSID_IS_OBJECT(id) ? (jsatomid) JSID_CLRTAG(id) : | ||||
\ | ||||
(jsatomid) JSID_TO_INT(id)) | ||||
extern JS_FRIEND_API(JSScopeProperty **) | extern JS_FRIEND_API(JSScopeProperty **) | |||
js_SearchScope(JSScope *scope, jsid id, JSBool adding); | js_SearchScope(JSScope *scope, jsid id, JSBool adding); | |||
#define SCOPE_GET_PROPERTY(scope, id) \ | #define SCOPE_GET_PROPERTY(scope, id) \ | |||
SPROP_FETCH(js_SearchScope(scope, id, JS_FALSE)) | SPROP_FETCH(js_SearchScope(scope, id, JS_FALSE)) | |||
#define SCOPE_HAS_PROPERTY(scope, sprop) \ | #define SCOPE_HAS_PROPERTY(scope, sprop) \ | |||
(SCOPE_GET_PROPERTY(scope, (sprop)->id) == (sprop)) | (SCOPE_GET_PROPERTY(scope, (sprop)->id) == (sprop)) | |||
extern JSScopeProperty * | extern JSScopeProperty * | |||
skipping to change at line 389 | skipping to change at line 398 | |||
js_RemoveScopeProperty(JSContext *cx, JSScope *scope, jsid id); | js_RemoveScopeProperty(JSContext *cx, JSScope *scope, jsid id); | |||
extern void | extern void | |||
js_ClearScope(JSContext *cx, JSScope *scope); | js_ClearScope(JSContext *cx, JSScope *scope); | |||
/* | /* | |||
* These macros used to inline short code sequences, but they grew over tim e. | * These macros used to inline short code sequences, but they grew over tim e. | |||
* We retain them for internal backward compatibility, and in case one or b oth | * We retain them for internal backward compatibility, and in case one or b oth | |||
* ever shrink to inline-able size. | * ever shrink to inline-able size. | |||
*/ | */ | |||
#define MARK_ID(cx,id) js_MarkId(cx, id) | #define TRACE_ID(trc, id) js_TraceId(trc, id) | |||
#define MARK_SCOPE_PROPERTY(cx,sprop) js_MarkScopeProperty(cx, sprop) | #define TRACE_SCOPE_PROPERTY(trc, sprop) js_TraceScopeProperty(trc, sprop) | |||
extern void | extern void | |||
js_MarkId(JSContext *cx, jsid id); | js_TraceId(JSTracer *trc, jsid id); | |||
extern void | extern void | |||
js_MarkScopeProperty(JSContext *cx, JSScopeProperty *sprop); | js_TraceScopeProperty(JSTracer *trc, JSScopeProperty *sprop); | |||
extern void | extern void | |||
js_SweepScopeProperties(JSRuntime *rt); | js_SweepScopeProperties(JSContext *cx); | |||
extern JSBool | extern JSBool | |||
js_InitPropertyTree(JSRuntime *rt); | js_InitPropertyTree(JSRuntime *rt); | |||
extern void | extern void | |||
js_FinishPropertyTree(JSRuntime *rt); | js_FinishPropertyTree(JSRuntime *rt); | |||
JS_END_EXTERN_C | ||||
#endif /* jsscope_h___ */ | #endif /* jsscope_h___ */ | |||
End of changes. 21 change blocks. | ||||
53 lines changed or deleted | 58 lines changed or added | |||
jsscript.h | jsscript.h | |||
---|---|---|---|---|
skipping to change at line 52 | skipping to change at line 52 | |||
#define jsscript_h___ | #define jsscript_h___ | |||
/* | /* | |||
* JS script descriptor. | * JS script descriptor. | |||
*/ | */ | |||
#include "jsatom.h" | #include "jsatom.h" | |||
#include "jsprvtd.h" | #include "jsprvtd.h" | |||
JS_BEGIN_EXTERN_C | JS_BEGIN_EXTERN_C | |||
/* | /* | |||
* Exception handling runtime information. | * Type of try note associated with each catch or finally block or with for | |||
* | -in | |||
* All fields except length are code offsets relative to the main entry poi | * loop. | |||
nt | */ | |||
* of the script. If script->trynotes is not null, it points to a vector o | typedef enum JSTryNoteKind { | |||
f | JSTN_CATCH, | |||
* these structs terminated by one with catchStart == 0. | JSTN_FINALLY, | |||
JSTN_ITER | ||||
} JSTryNoteKind; | ||||
/* | ||||
* Exception handling record. | ||||
*/ | */ | |||
struct JSTryNote { | struct JSTryNote { | |||
ptrdiff_t start; /* start of try statement */ | uint8 kind; /* one of JSTryNoteKind */ | |||
ptrdiff_t length; /* count of try statement bytecodes */ | uint8 padding; /* explicit padding on uint16 boundary */ | |||
ptrdiff_t catchStart; /* start of catch block (0 if end) */ | uint16 stackDepth; /* stack depth upon exception handler entry | |||
*/ | ||||
uint32 start; /* start of the try statement or for-in loo | ||||
p | ||||
relative to script->main */ | ||||
uint32 length; /* length of the try statement or for-in lo | ||||
op */ | ||||
}; | }; | |||
#define JSTRYNOTE_GRAIN sizeof(ptrdiff_t) | typedef struct JSTryNoteArray { | |||
#define JSTRYNOTE_ALIGNMASK (JSTRYNOTE_GRAIN - 1) | JSTryNote *vector; /* array of indexed try notes */ | |||
uint32 length; /* count of indexded try notes */ | ||||
} JSTryNoteArray; | ||||
typedef struct JSObjectArray { | ||||
JSObject **vector; /* array of indexed objects */ | ||||
uint32 length; /* count of indexded objects */ | ||||
} JSObjectArray; | ||||
#define JS_OBJECT_ARRAY_SIZE(length) | ||||
\ | ||||
(offsetof(JSObjectArray, vector) + sizeof(JSObject *) * (length)) | ||||
#if defined DEBUG && defined JS_THREADSAFE | ||||
# define CHECK_SCRIPT_OWNER 1 | ||||
#endif | ||||
struct JSScript { | struct JSScript { | |||
jsbytecode *code; /* bytecodes and their immediate operands * | jsbytecode *code; /* bytecodes and their immediate operands * | |||
/ | / | |||
uint32 length; /* length of code vector */ | uint32 length; /* length of code vector */ | |||
jsbytecode *main; /* main entry point, after predef'ing prolo | uint16 version; /* JS version under which script was compil | |||
g */ | ed */ | |||
uint16 version; /* JS version under which script was compil | uint16 ngvars; /* declared global var/const/function count | |||
ed */ | */ | |||
uint16 numGlobalVars; /* declared global var/const/function count | uint8 objectsOffset; /* offset to the array of nested functi | |||
*/ | on, | |||
JSAtomMap atomMap; /* maps immediate index to literal struct * | block, scope, xml and one-time regex | |||
/ | ps | |||
const char *filename; /* source filename or null */ | objects or 0 if none */ | |||
uintN lineno; /* base line number of script */ | uint8 regexpsOffset; /* offset to the array of to-be-cloned | |||
uintN depth; /* maximum stack depth in slots */ | regexps or 0 if none. */ | |||
JSTryNote *trynotes; /* exception table for this script */ | uint8 trynotesOffset; /* offset to the array of try notes or | |||
JSPrincipals *principals; /* principals for this script */ | 0 if none */ | |||
JSObject *object; /* optional Script-class object wrapper */ | jsbytecode *main; /* main entry point, after predef'ing prolo | |||
g */ | ||||
JSAtomMap atomMap; /* maps immediate index to literal struct * | ||||
/ | ||||
const char *filename; /* source filename or null */ | ||||
uintN lineno; /* base line number of script */ | ||||
uintN depth; /* maximum stack depth in slots */ | ||||
JSPrincipals *principals;/* principals for this script */ | ||||
JSObject *object; /* optional Script-class object wrapper */ | ||||
#ifdef CHECK_SCRIPT_OWNER | ||||
JSThread *owner; /* for thread-safe life-cycle assertions */ | ||||
#endif | ||||
}; | }; | |||
/* No need to store script->notes now that it is allocated right after code . */ | /* No need to store script->notes now that it is allocated right after code . */ | |||
#define SCRIPT_NOTES(script) ((jssrcnote*)((script)->code+(script)->leng th)) | #define SCRIPT_NOTES(script) ((jssrcnote*)((script)->code+(script)->leng th)) | |||
#define SCRIPT_FIND_CATCH_START(script, pc, catchpc) | #define JS_SCRIPT_OBJECTS(script) | |||
\ | \ | |||
(JS_ASSERT((script)->objectsOffset != 0), | ||||
\ | ||||
(JSObjectArray *)((uint8 *)(script) + (script)->objectsOffset)) | ||||
#define JS_SCRIPT_REGEXPS(script) | ||||
\ | ||||
(JS_ASSERT((script)->regexpsOffset != 0), | ||||
\ | ||||
(JSObjectArray *)((uint8 *)(script) + (script)->regexpsOffset)) | ||||
#define JS_SCRIPT_TRYNOTES(script) | ||||
\ | ||||
(JS_ASSERT((script)->trynotesOffset != 0), | ||||
\ | ||||
(JSTryNoteArray *)((uint8 *)(script) + (script)->trynotesOffset)) | ||||
#define JS_GET_SCRIPT_ATOM(script, index, atom) | ||||
\ | ||||
JS_BEGIN_MACRO \ | JS_BEGIN_MACRO \ | |||
JSTryNote *tn_ = (script)->trynotes; | JSAtomMap *atoms_ = &(script)->atomMap; | |||
\ | \ | |||
jsbytecode *catchpc_ = NULL; | JS_ASSERT((uint32)(index) < atoms_->length); | |||
\ | \ | |||
if (tn_) { | (atom) = atoms_->vector[(index)]; | |||
\ | \ | |||
ptrdiff_t off_ = PTRDIFF(pc, (script)->main, jsbytecode); | JS_END_MACRO | |||
\ | ||||
if (off_ >= 0) { | #define JS_GET_SCRIPT_OBJECT(script, index, obj) | |||
\ | \ | |||
while ((jsuword)(off_ - tn_->start) >= (jsuword)tn_->length | JS_BEGIN_MACRO | |||
) \ | \ | |||
++tn_; | JSObjectArray *objects_ = JS_SCRIPT_OBJECTS(script); | |||
\ | \ | |||
if (tn_->catchStart) | JS_ASSERT((uint32)(index) < objects_->length); | |||
\ | \ | |||
catchpc_ = (script)->main + tn_->catchStart; | (obj) = objects_->vector[(index)]; | |||
\ | \ | |||
} | JS_END_MACRO | |||
\ | ||||
} | #define JS_GET_SCRIPT_FUNCTION(script, index, fun) | |||
\ | \ | |||
catchpc = catchpc_; | JS_BEGIN_MACRO | |||
\ | \ | |||
JSObject *funobj_; | ||||
\ | ||||
\ | ||||
JS_GET_SCRIPT_OBJECT(script, index, funobj_); | ||||
\ | ||||
JS_ASSERT(HAS_FUNCTION_CLASS(funobj_)); | ||||
\ | ||||
JS_ASSERT(funobj_ == (JSObject *) STOBJ_GET_PRIVATE(funobj_)); | ||||
\ | ||||
(fun) = (JSFunction *) funobj_; | ||||
\ | ||||
JS_ASSERT(FUN_INTERPRETED(fun)); | ||||
\ | ||||
JS_END_MACRO | ||||
#define JS_GET_SCRIPT_REGEXP(script, index, obj) | ||||
\ | ||||
JS_BEGIN_MACRO | ||||
\ | ||||
JSObjectArray *regexps_ = JS_SCRIPT_REGEXPS(script); | ||||
\ | ||||
JS_ASSERT((uint32)(index) < regexps_->length); | ||||
\ | ||||
(obj) = regexps_->vector[(index)]; | ||||
\ | ||||
JS_ASSERT(STOBJ_GET_CLASS(obj) == &js_RegExpClass); | ||||
\ | ||||
JS_END_MACRO | JS_END_MACRO | |||
/* | /* | |||
* Find the innermost finally block that handles the given pc. This is a | * Check if pc is inside a try block that has finally code. GC calls this t | |||
* version of SCRIPT_FIND_CATCH_START that ignore catch blocks and is used | o | |||
* to implement generator.close(). | * check if it is necessary to schedule generator.close() invocation for an | |||
* unreachable generator. | ||||
*/ | */ | |||
jsbytecode * | JSBool | |||
js_FindFinallyHandler(JSScript *script, jsbytecode *pc); | js_IsInsideTryWithFinally(JSScript *script, jsbytecode *pc); | |||
extern JS_FRIEND_DATA(JSClass) js_ScriptClass; | extern JS_FRIEND_DATA(JSClass) js_ScriptClass; | |||
extern JSObject * | extern JSObject * | |||
js_InitScriptClass(JSContext *cx, JSObject *obj); | js_InitScriptClass(JSContext *cx, JSObject *obj); | |||
/* | /* | |||
* On first new context in rt, initialize script runtime state, specificall y | * On first new context in rt, initialize script runtime state, specificall y | |||
* the script filename table and its lock. | * the script filename table and its lock. | |||
*/ | */ | |||
skipping to change at line 168 | skipping to change at line 229 | |||
* does *not* call a non-null cx->runtime->newScriptHook -- only the second , | * does *not* call a non-null cx->runtime->newScriptHook -- only the second , | |||
* js_NewScriptFromCG, calls this optional debugger hook. | * js_NewScriptFromCG, calls this optional debugger hook. | |||
* | * | |||
* The js_NewScript function can't know whether the script it creates belon gs | * The js_NewScript function can't know whether the script it creates belon gs | |||
* to a function, or is top-level or eval code, but the debugger wants acce ss | * to a function, or is top-level or eval code, but the debugger wants acce ss | |||
* to the newly made script's function, if any -- so callers of js_NewScrip t | * to the newly made script's function, if any -- so callers of js_NewScrip t | |||
* are responsible for notifying the debugger after successfully creating a ny | * are responsible for notifying the debugger after successfully creating a ny | |||
* kind (function or other) of new JSScript. | * kind (function or other) of new JSScript. | |||
*/ | */ | |||
extern JSScript * | extern JSScript * | |||
js_NewScript(JSContext *cx, uint32 length, uint32 snlength, uint32 tnlength | js_NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natoms, | |||
); | uint32 nobjects, uint32 nregexps, uint32 ntrynotes); | |||
extern JS_FRIEND_API(JSScript *) | extern JSScript * | |||
js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg, JSFunction *fun); | js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg); | |||
/* | /* | |||
* New-script-hook calling is factored from js_NewScriptFromCG so that it | * New-script-hook calling is factored from js_NewScriptFromCG so that it | |||
* and callers of js_XDRScript can share this code. In the case of callers | * and callers of js_XDRScript can share this code. In the case of callers | |||
* of js_XDRScript, the hook should be invoked only after successful decode | * of js_XDRScript, the hook should be invoked only after successful decode | |||
* of any owning function (the fun parameter) or script object (null fun). | * of any owning function (the fun parameter) or script object (null fun). | |||
*/ | */ | |||
extern JS_FRIEND_API(void) | extern JS_FRIEND_API(void) | |||
js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun); | js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun); | |||
extern JS_FRIEND_API(void) | extern JS_FRIEND_API(void) | |||
js_CallDestroyScriptHook(JSContext *cx, JSScript *script); | js_CallDestroyScriptHook(JSContext *cx, JSScript *script); | |||
extern void | extern void | |||
js_DestroyScript(JSContext *cx, JSScript *script); | js_DestroyScript(JSContext *cx, JSScript *script); | |||
extern void | extern void | |||
js_MarkScript(JSContext *cx, JSScript *script); | js_TraceScript(JSTracer *trc, JSScript *script); | |||
/* | /* | |||
* To perturb as little code as possible, we introduce a js_GetSrcNote look up | * To perturb as little code as possible, we introduce a js_GetSrcNote look up | |||
* cache without adding an explicit cx parameter. Thus js_GetSrcNote becom es | * cache without adding an explicit cx parameter. Thus js_GetSrcNote becom es | |||
* a macro that uses cx from its calls' lexical environments. | * a macro that uses cx from its calls' lexical environments. | |||
*/ | */ | |||
#define js_GetSrcNote(script,pc) js_GetSrcNoteCached(cx, script, pc) | #define js_GetSrcNote(script,pc) js_GetSrcNoteCached(cx, script, pc) | |||
extern jssrcnote * | extern jssrcnote * | |||
js_GetSrcNoteCached(JSContext *cx, JSScript *script, jsbytecode *pc); | js_GetSrcNoteCached(JSContext *cx, JSScript *script, jsbytecode *pc); | |||
End of changes. 11 change blocks. | ||||
65 lines changed or deleted | 149 lines changed or added | |||
jsstr.h | jsstr.h | |||
---|---|---|---|---|
skipping to change at line 50 | skipping to change at line 50 | |||
#ifndef jsstr_h___ | #ifndef jsstr_h___ | |||
#define jsstr_h___ | #define jsstr_h___ | |||
/* | /* | |||
* JS string type implementation. | * JS string type implementation. | |||
* | * | |||
* A JS string is a counted array of unicode characters. To support handof f | * A JS string is a counted array of unicode characters. To support handof f | |||
* of API client memory, the chars are allocated separately from the length , | * of API client memory, the chars are allocated separately from the length , | |||
* necessitating a pointer after the count, to form a separately allocated | * necessitating a pointer after the count, to form a separately allocated | |||
* string descriptor. String descriptors are GC'ed, while their chars are | * string descriptor. String descriptors are GC'ed, while their chars are | |||
* allocated from the malloc heap. | * allocated from the malloc heap. | |||
* | ||||
* When a string is treated as an object (by following it with . or []), th | ||||
e | ||||
* runtime wraps it with a JSObject whose valueOf method returns the unwrap | ||||
ped | ||||
* string descriptor. | ||||
*/ | */ | |||
#include <ctype.h> | #include <ctype.h> | |||
#include "jspubtd.h" | #include "jspubtd.h" | |||
#include "jsprvtd.h" | #include "jsprvtd.h" | |||
#include "jshash.h" | ||||
JS_BEGIN_EXTERN_C | JS_BEGIN_EXTERN_C | |||
/* | /* | |||
* The original GC-thing "string" type, a flat character string owned by it | * The GC-thing "string" type. | |||
s | ||||
* GC-thing descriptor. The chars member points to a vector having byte si | ||||
ze | ||||
* (length + 1) * sizeof(jschar), terminated at index length by a zero jsch | ||||
ar. | ||||
* The terminator is purely a backstop, in case the chars pointer flows out | ||||
to | ||||
* native code that requires \u0000 termination. | ||||
* | * | |||
* NB: Always use the JSSTRING_LENGTH and JSSTRING_CHARS accessor macros, | * When the JSSTRFLAG_DEPENDENT bit of the length field is unset, the u.cha | |||
* unless you guard str->member uses with !JSSTRING_IS_DEPENDENT(str). | rs | |||
* field points to a flat character array owned by its GC-thing descriptor. | ||||
* The array is terminated at index length by a zero character and the size | ||||
of | ||||
* the array in bytes is (length + 1) * sizeof(jschar). The terminator is | ||||
* purely a backstop, in case the chars pointer flows out to native code th | ||||
at | ||||
* requires \u0000 termination. | ||||
* | ||||
* A flat string with JSSTRFLAG_MUTABLE set means that the string is access | ||||
ible | ||||
* only from one thread and it is possible to turn it into a dependent stri | ||||
ng | ||||
* of the same length to optimize js_ConcatStrings. It is also possible to | ||||
grow | ||||
* such a string, but extreme care must be taken to ensure that no other co | ||||
de | ||||
* relies on the original length of the string. | ||||
* | ||||
* A flat string with JSSTRFLAG_ATOMIZED set means that the string is hashe | ||||
d as | ||||
* an atom. This flag is used to avoid re-hashing the already-atomized stri | ||||
ng. | ||||
* | ||||
* When JSSTRFLAG_DEPENDENT is set, the string depends on characters of ano | ||||
ther | ||||
* string strongly referenced by the u.base field. The base member may poin | ||||
t to | ||||
* another dependent string if JSSTRING_CHARS has not been called yet. | ||||
* | ||||
* JSSTRFLAG_PREFIX determines the kind of the dependent string. When the f | ||||
lag | ||||
* is unset, the length field encodes both starting position relative to th | ||||
e | ||||
* base string and the number of characters in the dependent string, see | ||||
* JSSTRDEP_START_MASK and JSSTRDEP_LENGTH_MASK macros below for details. | ||||
* | ||||
* When JSSTRFLAG_PREFIX is set, the dependent string is a prefix of the ba | ||||
se | ||||
* string. The number of characters in the prefix is encoded using all non- | ||||
flag | ||||
* bits of the length field and spans the same 0 .. SIZE_T_MAX/4 range as t | ||||
he | ||||
* length of the flat string. | ||||
* | ||||
* NB: Always use the JSSTRING_LENGTH and JSSTRING_CHARS accessor macros. | ||||
*/ | */ | |||
struct JSString { | struct JSString { | |||
size_t length; | size_t length; | |||
jschar *chars; | union { | |||
jschar *chars; | ||||
JSString *base; | ||||
} u; | ||||
}; | }; | |||
/* | /* | |||
* Overlay structure for a string that depends on another string's characte | * Definitions for flags stored in the high order bits of JSString.length. | |||
rs. | * JSSTRFLAG_PREFIX and JSSTRFLAG_MUTABLE are two aliases for the same valu | |||
* Distinguished by the JSSTRFLAG_DEPENDENT bit being set in length. The b | e. | |||
ase | * JSSTRFLAG_PREFIX should be used only if JSSTRFLAG_DEPENDENT is set and | |||
* member may point to another dependent string if JSSTRING_CHARS has not b | * JSSTRFLAG_MUTABLE should be used only if the string is flat. | |||
een | * JSSTRFLAG_ATOMIZED is used only with the flat immutable strings. | |||
* called yet. The length chars in a dependent string are stored starting | ||||
at | ||||
* base->chars + start, and are not necessarily zero-terminated. If start | ||||
is | ||||
* 0, it is not stored, length is a full size_t (minus the JSSTRFLAG_* bits | ||||
in | ||||
* the high two positions), and the JSSTRFLAG_PREFIX flag is set. | ||||
*/ | */ | |||
struct JSDependentString { | #define JSSTRFLAG_DEPENDENT JSSTRING_BIT(JS_BITS_PER_WORD - 1) | |||
size_t length; | #define JSSTRFLAG_PREFIX JSSTRING_BIT(JS_BITS_PER_WORD - 2) | |||
JSString *base; | #define JSSTRFLAG_MUTABLE JSSTRFLAG_PREFIX | |||
}; | #define JSSTRFLAG_ATOMIZED JSSTRING_BIT(JS_BITS_PER_WORD - 3) | |||
/* Definitions for flags stored in the high order bits of JSString.length. | #define JSSTRING_LENGTH_BITS (JS_BITS_PER_WORD - 3) | |||
*/ | #define JSSTRING_LENGTH_MASK JSSTRING_BITMASK(JSSTRING_LENGTH_BITS) | |||
#define JSSTRFLAG_BITS 2 | ||||
#define JSSTRFLAG_SHIFT(flg) ((size_t)(flg) << JSSTRING_LENGTH_BITS) | ||||
#define JSSTRFLAG_MASK JSSTRFLAG_SHIFT(JS_BITMASK(JSSTRFLAG_BI | ||||
TS)) | ||||
#define JSSTRFLAG_DEPENDENT JSSTRFLAG_SHIFT(1) | ||||
#define JSSTRFLAG_PREFIX JSSTRFLAG_SHIFT(2) | ||||
/* Universal JSString type inquiry and accessor macros. */ | /* Universal JSString type inquiry and accessor macros. */ | |||
#define JSSTRING_BIT(n) ((size_t)1 << (n)) | #define JSSTRING_BIT(n) ((size_t)1 << (n)) | |||
#define JSSTRING_BITMASK(n) (JSSTRING_BIT(n) - 1) | #define JSSTRING_BITMASK(n) (JSSTRING_BIT(n) - 1) | |||
#define JSSTRING_HAS_FLAG(str,flg) ((str)->length & (flg)) | #define JSSTRING_HAS_FLAG(str,flg) ((str)->length & (flg)) | |||
#define JSSTRING_IS_DEPENDENT(str) JSSTRING_HAS_FLAG(str, JSSTRFLAG_DEPEND ENT) | #define JSSTRING_IS_DEPENDENT(str) JSSTRING_HAS_FLAG(str, JSSTRFLAG_DEPEND ENT) | |||
#define JSSTRING_IS_PREFIX(str) JSSTRING_HAS_FLAG(str, JSSTRFLAG_PREFIX | #define JSSTRING_IS_FLAT(str) (!JSSTRING_IS_DEPENDENT(str)) | |||
) | #define JSSTRING_IS_MUTABLE(str) (((str)->length & (JSSTRFLAG_DEPENDENT | |||
| \ | ||||
JSSTRFLAG_MUTABLE)) | ||||
== \ | ||||
JSSTRFLAG_MUTABLE) | ||||
#define JSSTRING_IS_ATOMIZED(str) (((str)->length & (JSSTRFLAG_DEPENDENT | ||||
| \ | ||||
JSSTRFLAG_ATOMIZED)) | ||||
==\ | ||||
JSSTRFLAG_ATOMIZED) | ||||
#define JSSTRING_CHARS(str) (JSSTRING_IS_DEPENDENT(str) \ | #define JSSTRING_CHARS(str) (JSSTRING_IS_DEPENDENT(str) \ | |||
? JSSTRDEP_CHARS(str) \ | ? JSSTRDEP_CHARS(str) \ | |||
: (str)->chars) | : JSFLATSTR_CHARS(str)) | |||
#define JSSTRING_LENGTH(str) (JSSTRING_IS_DEPENDENT(str) \ | #define JSSTRING_LENGTH(str) (JSSTRING_IS_DEPENDENT(str) \ | |||
? JSSTRDEP_LENGTH(str) \ | ? JSSTRDEP_LENGTH(str) \ | |||
: (str)->length) | : JSFLATSTR_LENGTH(str)) | |||
#define JSSTRING_LENGTH_BITS (sizeof(size_t) * JS_BITS_PER_BYTE | ||||
\ | ||||
- JSSTRFLAG_BITS) | ||||
#define JSSTRING_LENGTH_MASK JSSTRING_BITMASK(JSSTRING_LENGTH_BITS) | ||||
/* Specific JSDependentString shift/mask accessor and mutator macros. */ | #define JSSTRING_CHARS_AND_LENGTH(str, chars_, length_) | |||
\ | ||||
((void)(JSSTRING_IS_DEPENDENT(str) | ||||
\ | ||||
? ((length_) = JSSTRDEP_LENGTH(str), | ||||
\ | ||||
(chars_) = JSSTRDEP_CHARS(str)) | ||||
\ | ||||
: ((length_) = JSFLATSTR_LENGTH(str), | ||||
\ | ||||
(chars_) = JSFLATSTR_CHARS(str)))) | ||||
#define JSSTRING_CHARS_AND_END(str, chars_, end) | ||||
\ | ||||
((void)((end) = JSSTRING_IS_DEPENDENT(str) | ||||
\ | ||||
? JSSTRDEP_LENGTH(str) + ((chars_) = JSSTRDEP_CHARS(str)) | ||||
\ | ||||
: JSFLATSTR_LENGTH(str) + ((chars_) = JSFLATSTR_CHARS(str | ||||
)))) | ||||
/* Specific flat string initializer and accessor macros. */ | ||||
#define JSFLATSTR_INIT(str, chars_, length_) | ||||
\ | ||||
((void)(JS_ASSERT(((length_) & ~JSSTRING_LENGTH_MASK) == 0), | ||||
\ | ||||
(str)->length = (length_), (str)->u.chars = (chars_))) | ||||
#define JSFLATSTR_LENGTH(str) | ||||
\ | ||||
(JS_ASSERT(JSSTRING_IS_FLAT(str)), (str)->length & JSSTRING_LENGTH_MASK | ||||
) | ||||
#define JSFLATSTR_CHARS(str) | ||||
\ | ||||
(JS_ASSERT(JSSTRING_IS_FLAT(str)), (str)->u.chars) | ||||
/* | ||||
* Macros to manipulate atomized and mutable flags of flat strings. It is s | ||||
afe | ||||
* to use these without extra locking due to the following properties: | ||||
* | ||||
* * We do not have a macro like JSFLATSTR_CLEAR_ATOMIZED as a string | ||||
* remains atomized until the GC collects it. | ||||
* | ||||
* * A thread may call JSFLATSTR_SET_MUTABLE only when it is the only thr | ||||
ead | ||||
* accessing the string until a later call to JSFLATSTR_CLEAR_MUTABLE. | ||||
* | ||||
* * Multiple threads can call JSFLATSTR_CLEAR_MUTABLE but the macro | ||||
* actually clears the mutable flag only when the flag is set -- in whi | ||||
ch | ||||
* case only one thread can access the string (see previous property). | ||||
* | ||||
* Thus, when multiple threads access the string, JSFLATSTR_SET_ATOMIZED is | ||||
* the only macro that can update the length field of the string by changin | ||||
g | ||||
* the mutable bit from 0 to 1. We call the macro only after the string has | ||||
* been hashed. When some threads in js_ValueToStringId see that the flag i | ||||
s | ||||
* set, it knows that the string was atomized. | ||||
* | ||||
* On the other hand, if the thread sees that the flag is unset, it could b | ||||
e | ||||
* seeing a stale value when another thread has just atomized the string an | ||||
d | ||||
* set the flag. But this can lead only to an extra call to js_AtomizeStrin | ||||
g. | ||||
* This function would find that the string was already hashed and return i | ||||
t | ||||
* with the atomized bit set. | ||||
*/ | ||||
#define JSFLATSTR_SET_ATOMIZED(str) | ||||
\ | ||||
((void)(JS_ASSERT(JSSTRING_IS_FLAT(str) && !JSSTRING_IS_MUTABLE(str)), | ||||
\ | ||||
(str)->length |= JSSTRFLAG_ATOMIZED)) | ||||
#define JSFLATSTR_SET_MUTABLE(str) | ||||
\ | ||||
((void)(JS_ASSERT(JSSTRING_IS_FLAT(str) && !JSSTRING_IS_ATOMIZED(str)), | ||||
\ | ||||
(str)->length |= JSSTRFLAG_MUTABLE)) | ||||
#define JSFLATSTR_CLEAR_MUTABLE(str) | ||||
\ | ||||
((void)(JS_ASSERT(JSSTRING_IS_FLAT(str)), | ||||
\ | ||||
JSSTRING_HAS_FLAG(str, JSSTRFLAG_MUTABLE) && | ||||
\ | ||||
((str)->length &= ~JSSTRFLAG_MUTABLE))) | ||||
/* Specific dependent string shift/mask accessor and mutator macros. */ | ||||
#define JSSTRDEP_START_BITS (JSSTRING_LENGTH_BITS-JSSTRDEP_LENGTH_B ITS) | #define JSSTRDEP_START_BITS (JSSTRING_LENGTH_BITS-JSSTRDEP_LENGTH_B ITS) | |||
#define JSSTRDEP_START_SHIFT JSSTRDEP_LENGTH_BITS | #define JSSTRDEP_START_SHIFT JSSTRDEP_LENGTH_BITS | |||
#define JSSTRDEP_START_MASK JSSTRING_BITMASK(JSSTRDEP_START_BITS) | #define JSSTRDEP_START_MASK JSSTRING_BITMASK(JSSTRDEP_START_BITS) | |||
#define JSSTRDEP_LENGTH_BITS (JSSTRING_LENGTH_BITS / 2) | #define JSSTRDEP_LENGTH_BITS (JSSTRING_LENGTH_BITS / 2) | |||
#define JSSTRDEP_LENGTH_MASK JSSTRING_BITMASK(JSSTRDEP_LENGTH_BITS) | #define JSSTRDEP_LENGTH_MASK JSSTRING_BITMASK(JSSTRDEP_LENGTH_BITS) | |||
#define JSSTRDEP(str) ((JSDependentString *)(str)) | #define JSSTRDEP_IS_PREFIX(str) JSSTRING_HAS_FLAG(str, JSSTRFLAG_PREFIX | |||
#define JSSTRDEP_START(str) (JSSTRING_IS_PREFIX(str) ? 0 | ) | |||
\ | ||||
: ((JSSTRDEP(str)->length | #define JSSTRDEP_START(str) (JSSTRDEP_IS_PREFIX(str) ? 0 | |||
\ | \ | |||
: (((str)->length | ||||
\ | ||||
>> JSSTRDEP_START_SHIFT) \ | >> JSSTRDEP_START_SHIFT) \ | |||
& JSSTRDEP_START_MASK)) | & JSSTRDEP_START_MASK)) | |||
#define JSSTRDEP_LENGTH(str) (JSSTRDEP(str)->length | #define JSSTRDEP_LENGTH(str) ((str)->length | |||
\ | \ | |||
& (JSSTRING_IS_PREFIX(str) | & (JSSTRDEP_IS_PREFIX(str) | |||
\ | \ | |||
? JSSTRING_LENGTH_MASK \ | ? JSSTRING_LENGTH_MASK \ | |||
: JSSTRDEP_LENGTH_MASK)) | : JSSTRDEP_LENGTH_MASK)) | |||
#define JSSTRDEP_SET_START_AND_LENGTH(str,off,len) | #define JSSTRDEP_INIT(str,bstr,off,len) | |||
\ | \ | |||
(JSSTRDEP(str)->length = JSSTRFLAG_DEPENDENT | ((str)->length = JSSTRFLAG_DEPENDENT | |||
\ | \ | |||
| ((off) << JSSTRDEP_START_SHIFT) | | ((off) << JSSTRDEP_START_SHIFT) | |||
\ | \ | |||
| (len)) | | (len), | |||
#define JSPREFIX_SET_LENGTH(str,len) | \ | |||
\ | (str)->u.base = (bstr)) | |||
(JSSTRDEP(str)->length = JSSTRFLAG_DEPENDENT | JSSTRFLAG_PREFIX | (len) | ||||
) | ||||
#define JSSTRDEP_BASE(str) (JSSTRDEP(str)->base) | #define JSPREFIX_INIT(str,bstr,len) | |||
#define JSSTRDEP_SET_BASE(str,bstr) (JSSTRDEP(str)->base = (bstr)) | \ | |||
((str)->length = JSSTRFLAG_DEPENDENT | JSSTRFLAG_PREFIX | (len), | ||||
\ | ||||
(str)->u.base = (bstr)) | ||||
#define JSSTRDEP_BASE(str) ((str)->u.base) | ||||
#define JSPREFIX_BASE(str) JSSTRDEP_BASE(str) | #define JSPREFIX_BASE(str) JSSTRDEP_BASE(str) | |||
#define JSPREFIX_SET_BASE(str,bstr) JSSTRDEP_SET_BASE(str,bstr) | #define JSPREFIX_SET_BASE(str,bstr) ((str)->u.base = (bstr)) | |||
#define JSSTRDEP_CHARS(str) \ | #define JSSTRDEP_CHARS(str) \ | |||
(JSSTRING_IS_DEPENDENT(JSSTRDEP_BASE(str)) \ | (JSSTRING_IS_DEPENDENT(JSSTRDEP_BASE(str)) \ | |||
? js_GetDependentStringChars(str) \ | ? js_GetDependentStringChars(str) \ | |||
: JSSTRDEP_BASE(str)->chars + JSSTRDEP_START(str)) | : JSFLATSTR_CHARS(JSSTRDEP_BASE(str)) + JSSTRDEP_START(str)) | |||
extern size_t | extern size_t | |||
js_MinimizeDependentStrings(JSString *str, int level, JSString **basep); | js_MinimizeDependentStrings(JSString *str, int level, JSString **basep); | |||
extern jschar * | extern jschar * | |||
js_GetDependentStringChars(JSString *str); | js_GetDependentStringChars(JSString *str); | |||
extern jschar * | extern const jschar * | |||
js_GetStringChars(JSString *str); | js_GetStringChars(JSContext *cx, JSString *str); | |||
extern JSString * | extern JSString * | |||
js_ConcatStrings(JSContext *cx, JSString *left, JSString *right); | js_ConcatStrings(JSContext *cx, JSString *left, JSString *right); | |||
extern const jschar * | extern const jschar * | |||
js_UndependString(JSContext *cx, JSString *str); | js_UndependString(JSContext *cx, JSString *str); | |||
extern JSBool | ||||
js_MakeStringImmutable(JSContext *cx, JSString *str); | ||||
typedef struct JSCharBuffer { | ||||
size_t length; | ||||
jschar *chars; | ||||
} JSCharBuffer; | ||||
struct JSSubString { | struct JSSubString { | |||
size_t length; | size_t length; | |||
const jschar *chars; | const jschar *chars; | |||
}; | }; | |||
extern jschar js_empty_ucstr[]; | extern jschar js_empty_ucstr[]; | |||
extern JSSubString js_EmptySubString; | extern JSSubString js_EmptySubString; | |||
/* Unicode character attribute lookup tables. */ | /* Unicode character attribute lookup tables. */ | |||
extern const uint8 js_X[]; | extern const uint8 js_X[]; | |||
skipping to change at line 304 | skipping to change at line 398 | |||
#define JS7_ISDEC(c) ((((unsigned)(c)) - '0') <= 9) | #define JS7_ISDEC(c) ((((unsigned)(c)) - '0') <= 9) | |||
#define JS7_UNDEC(c) ((c) - '0') | #define JS7_UNDEC(c) ((c) - '0') | |||
#define JS7_ISHEX(c) ((c) < 128 && isxdigit(c)) | #define JS7_ISHEX(c) ((c) < 128 && isxdigit(c)) | |||
#define JS7_UNHEX(c) (uintN)(JS7_ISDEC(c) ? (c) - '0' : 10 + tolower(c) - 'a') | #define JS7_UNHEX(c) (uintN)(JS7_ISDEC(c) ? (c) - '0' : 10 + tolower(c) - 'a') | |||
#define JS7_ISLET(c) ((c) < 128 && isalpha(c)) | #define JS7_ISLET(c) ((c) < 128 && isalpha(c)) | |||
/* Initialize per-runtime string state for the first context in the runtime . */ | /* Initialize per-runtime string state for the first context in the runtime . */ | |||
extern JSBool | extern JSBool | |||
js_InitRuntimeStringState(JSContext *cx); | js_InitRuntimeStringState(JSContext *cx); | |||
extern JSBool | ||||
js_InitDeflatedStringCache(JSRuntime *rt); | ||||
/* | ||||
* Maximum character code for which we will create a pinned unit string on | ||||
* demand -- see JSRuntime.unitStrings in jscntxt.h. | ||||
*/ | ||||
#define UNIT_STRING_LIMIT 256U | ||||
/* | ||||
* Get the independent string containing only character code at index in st | ||||
r | ||||
* (backstopped with a zero character as usual for independent strings). | ||||
*/ | ||||
extern JSString * | ||||
js_GetUnitString(JSContext *cx, JSString *str, size_t index); | ||||
extern void | ||||
js_FinishUnitStrings(JSRuntime *rt); | ||||
extern void | extern void | |||
js_FinishRuntimeStringState(JSContext *cx); | js_FinishRuntimeStringState(JSContext *cx); | |||
extern void | extern void | |||
js_FinishDeflatedStringCache(JSRuntime *rt); | js_FinishDeflatedStringCache(JSRuntime *rt); | |||
/* Initialize the String class, returning its prototype object. */ | /* Initialize the String class, returning its prototype object. */ | |||
extern JSClass js_StringClass; | extern JSClass js_StringClass; | |||
extern JSObject * | extern JSObject * | |||
skipping to change at line 326 | skipping to change at line 439 | |||
extern const char js_escape_str[]; | extern const char js_escape_str[]; | |||
extern const char js_unescape_str[]; | extern const char js_unescape_str[]; | |||
extern const char js_uneval_str[]; | extern const char js_uneval_str[]; | |||
extern const char js_decodeURI_str[]; | extern const char js_decodeURI_str[]; | |||
extern const char js_encodeURI_str[]; | extern const char js_encodeURI_str[]; | |||
extern const char js_decodeURIComponent_str[]; | extern const char js_decodeURIComponent_str[]; | |||
extern const char js_encodeURIComponent_str[]; | extern const char js_encodeURIComponent_str[]; | |||
/* GC-allocate a string descriptor for the given malloc-allocated chars. */ | /* GC-allocate a string descriptor for the given malloc-allocated chars. */ | |||
extern JSString * | extern JSString * | |||
js_NewString(JSContext *cx, jschar *chars, size_t length, uintN gcflag); | js_NewString(JSContext *cx, jschar *chars, size_t length); | |||
extern JSString * | extern JSString * | |||
js_NewDependentString(JSContext *cx, JSString *base, size_t start, | js_NewDependentString(JSContext *cx, JSString *base, size_t start, | |||
size_t length, uintN gcflag); | size_t length); | |||
/* Copy a counted string and GC-allocate a descriptor for it. */ | /* Copy a counted string and GC-allocate a descriptor for it. */ | |||
extern JSString * | extern JSString * | |||
js_NewStringCopyN(JSContext *cx, const jschar *s, size_t n, uintN gcflag); | js_NewStringCopyN(JSContext *cx, const jschar *s, size_t n); | |||
/* Copy a C string and GC-allocate a descriptor for it. */ | /* Copy a C string and GC-allocate a descriptor for it. */ | |||
extern JSString * | extern JSString * | |||
js_NewStringCopyZ(JSContext *cx, const jschar *s, uintN gcflag); | js_NewStringCopyZ(JSContext *cx, const jschar *s); | |||
/* Free the chars held by str when it is finalized by the GC. */ | ||||
extern void | ||||
js_FinalizeString(JSContext *cx, JSString *str); | ||||
/* | ||||
* Free the chars held by str when it is finalized by the GC. When type is | ||||
* less then zero, it denotes an internal string. Otherwise it denotes the | ||||
* type of the external string allocated with JS_NewExternalString. | ||||
* | ||||
* This function always needs rt but can live with null cx. | ||||
*/ | ||||
extern void | extern void | |||
js_FinalizeStringRT(JSRuntime *rt, JSString *str); | js_FinalizeStringRT(JSRuntime *rt, JSString *str, intN type, JSContext *cx) | |||
; | ||||
/* Wrap a string value in a String object. */ | ||||
extern JSObject * | ||||
js_StringToObject(JSContext *cx, JSString *str); | ||||
/* | /* | |||
* Convert a value to a printable C string. | * Convert a value to a printable C string. | |||
*/ | */ | |||
typedef JSString *(*JSValueToStringFun)(JSContext *cx, jsval v); | typedef JSString *(*JSValueToStringFun)(JSContext *cx, jsval v); | |||
extern JS_FRIEND_API(const char *) | extern JS_FRIEND_API(const char *) | |||
js_ValueToPrintable(JSContext *cx, jsval v, JSValueToStringFun v2sfun); | js_ValueToPrintable(JSContext *cx, jsval v, JSValueToStringFun v2sfun); | |||
#define js_ValueToPrintableString(cx,v) \ | #define js_ValueToPrintableString(cx,v) \ | |||
skipping to change at line 379 | skipping to change at line 491 | |||
extern JS_FRIEND_API(JSString *) | extern JS_FRIEND_API(JSString *) | |||
js_ValueToString(JSContext *cx, jsval v); | js_ValueToString(JSContext *cx, jsval v); | |||
/* | /* | |||
* Convert a value to its source expression, returning null after reporting | * Convert a value to its source expression, returning null after reporting | |||
* an error, otherwise returning a new string reference. | * an error, otherwise returning a new string reference. | |||
*/ | */ | |||
extern JS_FRIEND_API(JSString *) | extern JS_FRIEND_API(JSString *) | |||
js_ValueToSource(JSContext *cx, jsval v); | js_ValueToSource(JSContext *cx, jsval v); | |||
#ifdef HT_ENUMERATE_NEXT /* XXX don't require jshash.h */ | ||||
/* | /* | |||
* Compute a hash function from str. | * Compute a hash function from str. The caller can call this function even | |||
if | ||||
* str is not a GC-allocated thing. | ||||
*/ | */ | |||
extern JSHashNumber | extern uint32 | |||
js_HashString(JSString *str); | js_HashString(JSString *str); | |||
#endif | ||||
/* | ||||
* Test if strings are equal. The caller can call the function even if str1 | ||||
* or str2 are not GC-allocated things. | ||||
*/ | ||||
extern JSBool | ||||
js_EqualStrings(JSString *str1, JSString *str2); | ||||
/* | /* | |||
* Return less than, equal to, or greater than zero depending on whether | * Return less than, equal to, or greater than zero depending on whether | |||
* str1 is less than, equal to, or greater than str2. | * str1 is less than, equal to, or greater than str2. | |||
*/ | */ | |||
extern intN | extern intN | |||
js_CompareStrings(JSString *str1, JSString *str2); | js_CompareStrings(JSString *str1, JSString *str2); | |||
/* | /* | |||
* Test if strings are equal. | ||||
*/ | ||||
extern JSBool | ||||
js_EqualStrings(JSString *str1, JSString *str2); | ||||
/* | ||||
* Boyer-Moore-Horspool superlinear search for pat:patlen in text:textlen. | * Boyer-Moore-Horspool superlinear search for pat:patlen in text:textlen. | |||
* The patlen argument must be positive and no greater than BMH_PATLEN_MAX. | * The patlen argument must be positive and no greater than BMH_PATLEN_MAX. | |||
* The start argument tells where in text to begin the search. | * The start argument tells where in text to begin the search. | |||
* | * | |||
* Return the index of pat in text, or -1 if not found. | * Return the index of pat in text, or -1 if not found. | |||
*/ | */ | |||
#define BMH_CHARSET_SIZE 256 /* ISO-Latin-1 */ | #define BMH_CHARSET_SIZE 256 /* ISO-Latin-1 */ | |||
#define BMH_PATLEN_MAX 255 /* skip table element is uint8 */ | #define BMH_PATLEN_MAX 255 /* skip table element is uint8 */ | |||
#define BMH_BAD_PATTERN (-2) /* return value if pat is not ISO-Latin-1 * / | #define BMH_BAD_PATTERN (-2) /* return value if pat is not ISO-Latin-1 * / | |||
skipping to change at line 432 | skipping to change at line 544 | |||
extern jschar * | extern jschar * | |||
js_strchr_limit(const jschar *s, jschar c, const jschar *limit); | js_strchr_limit(const jschar *s, jschar c, const jschar *limit); | |||
#define js_strncpy(t, s, n) memcpy((t), (s), (n) * sizeof(jschar)) | #define js_strncpy(t, s, n) memcpy((t), (s), (n) * sizeof(jschar)) | |||
/* | /* | |||
* Return s advanced past any Unicode white space characters. | * Return s advanced past any Unicode white space characters. | |||
*/ | */ | |||
extern const jschar * | extern const jschar * | |||
js_SkipWhiteSpace(const jschar *s); | js_SkipWhiteSpace(const jschar *s, const jschar *end); | |||
/* | /* | |||
* Inflate bytes to JS chars and vice versa. Report out of memory via cx | * Inflate bytes to JS chars and vice versa. Report out of memory via cx | |||
* and return null on error, otherwise return the jschar or byte vector tha t | * and return null on error, otherwise return the jschar or byte vector tha t | |||
* was JS_malloc'ed. length is updated with the length of the new string in jschars. | * was JS_malloc'ed. length is updated with the length of the new string in jschars. | |||
*/ | */ | |||
extern jschar * | extern jschar * | |||
js_InflateString(JSContext *cx, const char *bytes, size_t *length); | js_InflateString(JSContext *cx, const char *bytes, size_t *length); | |||
extern char * | extern char * | |||
js_DeflateString(JSContext *cx, const jschar *chars, size_t length); | js_DeflateString(JSContext *cx, const jschar *chars, size_t length); | |||
/* | /* | |||
* Inflate bytes to JS chars into a buffer. | * Inflate bytes to JS chars into a buffer. 'chars' must be large enough fo | |||
* 'chars' must be large enough for 'length' jschars. | r | |||
* The buffer is NOT null-terminated. | * 'length' jschars. The buffer is NOT null-terminated. The destination len | |||
* cx may be NULL, which means no errors are thrown. | gth | |||
* The destination length needs to be initialized with the buffer size, tak | * must be be initialized with the buffer size and will contain on return t | |||
es | he | |||
* the number of chars moved. | * number of copied chars. | |||
*/ | */ | |||
extern JSBool | extern JSBool | |||
js_InflateStringToBuffer(JSContext* cx, const char *bytes, size_t length, | js_InflateStringToBuffer(JSContext* cx, const char *bytes, size_t length, | |||
jschar *chars, size_t* charsLength); | jschar *chars, size_t* charsLength); | |||
/* | /* | |||
* Deflate JS chars to bytes into a buffer. | * Get number of bytes in the deflated sequence of characters. | |||
* 'bytes' must be large enough for 'length chars. | */ | |||
* The buffer is NOT null-terminated. | extern size_t | |||
* cx may be NULL, which means no errors are thrown. | js_GetDeflatedStringLength(JSContext *cx, const jschar *chars, | |||
* The destination length needs to be initialized with the buffer size, tak | size_t charsLength); | |||
es | ||||
* the number of bytes moved. | /* | |||
* Deflate JS chars to bytes into a buffer. 'bytes' must be large enough fo | ||||
r | ||||
* 'length chars. The buffer is NOT null-terminated. The destination length | ||||
* must to be initialized with the buffer size and will contain on return t | ||||
he | ||||
* number of copied bytes. | ||||
*/ | */ | |||
extern JSBool | extern JSBool | |||
js_DeflateStringToBuffer(JSContext* cx, const jschar *chars, | js_DeflateStringToBuffer(JSContext* cx, const jschar *chars, | |||
size_t charsLength, char *bytes, size_t* length); | size_t charsLength, char *bytes, size_t* length); | |||
/* | /* | |||
* Associate bytes with str in the deflated string cache, returning true on | * Associate bytes with str in the deflated string cache, returning true on | |||
* successful association, false on out of memory. | * successful association, false on out of memory. | |||
*/ | */ | |||
extern JSBool | extern JSBool | |||
js_SetStringBytes(JSRuntime *rt, JSString *str, char *bytes, size_t length) ; | js_SetStringBytes(JSContext *cx, JSString *str, char *bytes, size_t length) ; | |||
/* | /* | |||
* Find or create a deflated string cache entry for str that contains its | * Find or create a deflated string cache entry for str that contains its | |||
* characters chopped from Unicode code points into bytes. | * characters chopped from Unicode code points into bytes. | |||
*/ | */ | |||
extern char * | extern const char * | |||
js_GetStringBytes(JSRuntime *rt, JSString *str); | js_GetStringBytes(JSContext *cx, JSString *str); | |||
/* Remove a deflated string cache entry associated with str if any. */ | /* Remove a deflated string cache entry associated with str if any. */ | |||
extern void | extern void | |||
js_PurgeDeflatedStringCache(JSRuntime *rt, JSString *str); | js_PurgeDeflatedStringCache(JSRuntime *rt, JSString *str); | |||
JSBool | JSBool | |||
js_str_escape(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, | js_str_escape(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, | |||
jsval *rval); | jsval *rval); | |||
/* | /* | |||
* Convert one UCS-4 char and write it into a UTF-8 buffer, which must be a t | * Convert one UCS-4 char and write it into a UTF-8 buffer, which must be a t | |||
* least 6 bytes long. Return the number of UTF-8 bytes of data written. | * least 6 bytes long. Return the number of UTF-8 bytes of data written. | |||
*/ | */ | |||
extern int | extern int | |||
js_OneUcs4ToUtf8Char(uint8 *utf8Buffer, uint32 ucs4Char); | js_OneUcs4ToUtf8Char(uint8 *utf8Buffer, uint32 ucs4Char); | |||
/* | ||||
* Write str into buffer escaping any non-printable or non-ASCII character. | ||||
* Guarantees that a NUL is at the end of the buffer. Returns the length of | ||||
* the written output, NOT including the NUL. If buffer is null, just retur | ||||
ns | ||||
* the length of the output. If quote is not 0, it must be a single or doub | ||||
le | ||||
* quote character that will quote the output. | ||||
* | ||||
* The function is only defined for debug builds. | ||||
*/ | ||||
#define js_PutEscapedString(buffer, bufferSize, str, quote) | ||||
\ | ||||
js_PutEscapedStringImpl(buffer, bufferSize, NULL, str, quote) | ||||
/* | ||||
* Write str into file escaping any non-printable or non-ASCII character. | ||||
* Returns the number of bytes written to file. If quote is not 0, it must | ||||
* be a single or double quote character that will quote the output. | ||||
* | ||||
* The function is only defined for debug builds. | ||||
*/ | ||||
#define js_FileEscapedString(file, str, quote) | ||||
\ | ||||
(JS_ASSERT(file), js_PutEscapedStringImpl(NULL, 0, file, str, quote)) | ||||
extern JS_FRIEND_API(size_t) | ||||
js_PutEscapedStringImpl(char *buffer, size_t bufferSize, FILE *fp, | ||||
JSString *str, uint32 quote); | ||||
JS_END_EXTERN_C | JS_END_EXTERN_C | |||
#endif /* jsstr_h___ */ | #endif /* jsstr_h___ */ | |||
End of changes. 38 change blocks. | ||||
120 lines changed or deleted | 308 lines changed or added | |||
jstypes.h | jstypes.h | |||
---|---|---|---|---|
skipping to change at line 80 | skipping to change at line 80 | |||
** | ** | |||
** Example: | ** Example: | |||
** in dowhim.h | ** in dowhim.h | |||
** JS_EXTERN_API( void ) DoWhatIMean( void ); | ** JS_EXTERN_API( void ) DoWhatIMean( void ); | |||
** in dowhim.c | ** in dowhim.c | |||
** JS_EXPORT_API( void ) DoWhatIMean( void ) { return; } | ** JS_EXPORT_API( void ) DoWhatIMean( void ) { return; } | |||
** | ** | |||
** | ** | |||
***********************************************************************/ | ***********************************************************************/ | |||
#ifdef WIN32 | #ifdef WIN32 | |||
/* These also work for __MWERKS__ */ | /* These also work for __MWERKS__ */ | |||
#define JS_EXTERN_API(__type) extern __declspec(dllexport) __type | # define JS_EXTERN_API(__type) extern __declspec(dllexport) __type | |||
#define JS_EXPORT_API(__type) __declspec(dllexport) __type | # define JS_EXPORT_API(__type) __declspec(dllexport) __type | |||
#define JS_EXTERN_DATA(__type) extern __declspec(dllexport) __type | # define JS_EXTERN_DATA(__type) extern __declspec(dllexport) __type | |||
#define JS_EXPORT_DATA(__type) __declspec(dllexport) __type | # define JS_EXPORT_DATA(__type) __declspec(dllexport) __type | |||
#define JS_DLL_CALLBACK | # define JS_DLL_CALLBACK | |||
#define JS_STATIC_DLL_CALLBACK(__x) static __x | # define JS_STATIC_DLL_CALLBACK(__x) static __x | |||
#elif defined(XP_OS2) && defined(__declspec) | #elif defined(XP_OS2) && defined(__declspec) | |||
#define JS_EXTERN_API(__type) extern __declspec(dllexport) __type | # define JS_EXTERN_API(__type) extern __declspec(dllexport) __type | |||
#define JS_EXPORT_API(__type) __declspec(dllexport) __type | # define JS_EXPORT_API(__type) __declspec(dllexport) __type | |||
#define JS_EXTERN_DATA(__type) extern __declspec(dllexport) __type | # define JS_EXTERN_DATA(__type) extern __declspec(dllexport) __type | |||
#define JS_EXPORT_DATA(__type) __declspec(dllexport) __type | # define JS_EXPORT_DATA(__type) __declspec(dllexport) __type | |||
#define JS_DLL_CALLBACK | ||||
#define JS_STATIC_DLL_CALLBACK(__x) static __x | ||||
#elif defined(WIN16) | ||||
#ifdef _WINDLL | ||||
#define JS_EXTERN_API(__type) extern __type _cdecl _export _loadds | ||||
#define JS_EXPORT_API(__type) __type _cdecl _export _loadds | ||||
#define JS_EXTERN_DATA(__type) extern __type _export | ||||
#define JS_EXPORT_DATA(__type) __type _export | ||||
#define JS_DLL_CALLBACK __cdecl __loadds | ||||
#define JS_STATIC_DLL_CALLBACK(__x) static __x CALLBACK | ||||
#else /* this must be .EXE */ | ||||
#define JS_EXTERN_API(__type) extern __type _cdecl _export | ||||
#define JS_EXPORT_API(__type) __type _cdecl _export | ||||
#define JS_EXTERN_DATA(__type) extern __type _export | ||||
#define JS_EXPORT_DATA(__type) __type _export | ||||
#define JS_DLL_CALLBACK __cdecl __loadds | # define JS_DLL_CALLBACK | |||
#define JS_STATIC_DLL_CALLBACK(__x) __x JS_DLL_CALLBACK | # define JS_STATIC_DLL_CALLBACK(__x) static __x | |||
#endif /* _WINDLL */ | ||||
#else /* Unix */ | #else /* Unix */ | |||
#ifdef HAVE_VISIBILITY_ATTRIBUTE | # ifdef HAVE_VISIBILITY_ATTRIBUTE | |||
#define JS_EXTERNAL_VIS __attribute__((visibility ("default"))) | # define JS_EXTERNAL_VIS __attribute__((visibility ("default"))) | |||
#else | # else | |||
#define JS_EXTERNAL_VIS | # define JS_EXTERNAL_VIS | |||
#endif | # endif | |||
#define JS_EXTERN_API(__type) extern JS_EXTERNAL_VIS __type | # define JS_EXTERN_API(__type) extern JS_EXTERNAL_VIS __type | |||
#define JS_EXPORT_API(__type) JS_EXTERNAL_VIS __type | # define JS_EXPORT_API(__type) JS_EXTERNAL_VIS __type | |||
#define JS_EXTERN_DATA(__type) extern JS_EXTERNAL_VIS __type | # define JS_EXTERN_DATA(__type) extern JS_EXTERNAL_VIS __type | |||
#define JS_EXPORT_DATA(__type) JS_EXTERNAL_VIS __type | # define JS_EXPORT_DATA(__type) JS_EXTERNAL_VIS __type | |||
#define JS_DLL_CALLBACK | # define JS_DLL_CALLBACK | |||
#define JS_STATIC_DLL_CALLBACK(__x) static __x | # define JS_STATIC_DLL_CALLBACK(__x) static __x | |||
#endif | #endif | |||
#ifdef _WIN32 | #ifdef _WIN32 | |||
# if defined(__MWERKS__) || defined(__GNUC__) | # if defined(__MWERKS__) || defined(__GNUC__) | |||
# define JS_IMPORT_API(__x) __x | # define JS_IMPORT_API(__x) __x | |||
# else | # else | |||
# define JS_IMPORT_API(__x) __declspec(dllimport) __x | # define JS_IMPORT_API(__x) __declspec(dllimport) __x | |||
# endif | # endif | |||
#elif defined(XP_OS2) && defined(__declspec) | #elif defined(XP_OS2) && defined(__declspec) | |||
# define JS_IMPORT_API(__x) __declspec(dllimport) __x | # define JS_IMPORT_API(__x) __declspec(dllimport) __x | |||
#else | #else | |||
# define JS_IMPORT_API(__x) JS_EXPORT_API (__x) | # define JS_IMPORT_API(__x) JS_EXPORT_API (__x) | |||
#endif | #endif | |||
#if defined(_WIN32) && !defined(__MWERKS__) | #if defined(_WIN32) && !defined(__MWERKS__) | |||
# define JS_IMPORT_DATA(__x) __declspec(dllimport) __x | # define JS_IMPORT_DATA(__x) __declspec(dllimport) __x | |||
#elif defined(XP_OS2) && defined(__declspec) | #elif defined(XP_OS2) && defined(__declspec) | |||
# define JS_IMPORT_DATA(__x) __declspec(dllimport) __x | # define JS_IMPORT_DATA(__x) __declspec(dllimport) __x | |||
#else | #else | |||
# define JS_IMPORT_DATA(__x) JS_EXPORT_DATA (__x) | # define JS_IMPORT_DATA(__x) JS_EXPORT_DATA (__x) | |||
#endif | #endif | |||
/* | /* | |||
* The linkage of JS API functions differs depending on whether the file is | * The linkage of JS API functions differs depending on whether the file is | |||
* used within the JS library or not. Any source file within the JS | * used within the JS library or not. Any source file within the JS | |||
* interpreter should define EXPORT_JS_API whereas any client of the librar y | * interpreter should define EXPORT_JS_API whereas any client of the librar y | |||
* should not. | * should not. STATIC_JS_API is used to build JS as a static library. | |||
*/ | */ | |||
#ifdef EXPORT_JS_API | #if defined(STATIC_JS_API) | |||
#define JS_PUBLIC_API(t) JS_EXPORT_API(t) | ||||
#define JS_PUBLIC_DATA(t) JS_EXPORT_DATA(t) | # define JS_PUBLIC_API(t) t | |||
# define JS_PUBLIC_DATA(t) t | ||||
#elif defined(EXPORT_JS_API) | ||||
# define JS_PUBLIC_API(t) JS_EXPORT_API(t) | ||||
# define JS_PUBLIC_DATA(t) JS_EXPORT_DATA(t) | ||||
#else | #else | |||
#define JS_PUBLIC_API(t) JS_IMPORT_API(t) | ||||
#define JS_PUBLIC_DATA(t) JS_IMPORT_DATA(t) | # define JS_PUBLIC_API(t) JS_IMPORT_API(t) | |||
# define JS_PUBLIC_DATA(t) JS_IMPORT_DATA(t) | ||||
#endif | #endif | |||
#define JS_FRIEND_API(t) JS_PUBLIC_API(t) | #define JS_FRIEND_API(t) JS_PUBLIC_API(t) | |||
#define JS_FRIEND_DATA(t) JS_PUBLIC_DATA(t) | #define JS_FRIEND_DATA(t) JS_PUBLIC_DATA(t) | |||
#ifdef _WIN32 | #if defined(_MSC_VER) | |||
# define JS_INLINE __inline | # define JS_INLINE __forceinline | |||
#elif defined(__GNUC__) | #elif defined(__GNUC__) | |||
# define JS_INLINE | # ifndef DEBUG | |||
# define JS_INLINE __attribute__((always_inline)) | ||||
# else | ||||
# define JS_INLINE inline | ||||
# endif | ||||
#else | #else | |||
# define JS_INLINE | # define JS_INLINE | |||
#endif | #endif | |||
/*********************************************************************** | /*********************************************************************** | |||
** MACROS: JS_BEGIN_MACRO | ** MACROS: JS_BEGIN_MACRO | |||
** JS_END_MACRO | ** JS_END_MACRO | |||
** DESCRIPTION: | ** DESCRIPTION: | |||
** Macro body brackets so that macros with compound statement definiti ons | ** Macro body brackets so that macros with compound statement definiti ons | |||
** behave syntactically more like functions when called. | ** behave syntactically more like functions when called. | |||
***********************************************************************/ | ***********************************************************************/ | |||
#define JS_BEGIN_MACRO do { | #define JS_BEGIN_MACRO do { | |||
#define JS_END_MACRO } while (0) | ||||
#if defined(_MSC_VER) && _MSC_VER >= 1400 | ||||
# define JS_END_MACRO | ||||
\ | ||||
} __pragma(warning(push)) __pragma(warning(disable:4127)) | ||||
\ | ||||
while (0) __pragma(warning(pop)) | ||||
#else | ||||
# define JS_END_MACRO } while (0) | ||||
#endif | ||||
/*********************************************************************** | /*********************************************************************** | |||
** MACROS: JS_BEGIN_EXTERN_C | ** MACROS: JS_BEGIN_EXTERN_C | |||
** JS_END_EXTERN_C | ** JS_END_EXTERN_C | |||
** DESCRIPTION: | ** DESCRIPTION: | |||
** Macro shorthands for conditional C++ extern block delimiters. | ** Macro shorthands for conditional C++ extern block delimiters. | |||
***********************************************************************/ | ***********************************************************************/ | |||
#ifdef __cplusplus | #ifdef __cplusplus | |||
#define JS_BEGIN_EXTERN_C extern "C" { | ||||
#define JS_END_EXTERN_C } | # define JS_BEGIN_EXTERN_C extern "C" { | |||
# define JS_END_EXTERN_C } | ||||
#else | #else | |||
#define JS_BEGIN_EXTERN_C | ||||
#define JS_END_EXTERN_C | # define JS_BEGIN_EXTERN_C | |||
# define JS_END_EXTERN_C | ||||
#endif | #endif | |||
/*********************************************************************** | /*********************************************************************** | |||
** MACROS: JS_BIT | ** MACROS: JS_BIT | |||
** JS_BITMASK | ** JS_BITMASK | |||
** DESCRIPTION: | ** DESCRIPTION: | |||
** Bit masking macros. XXX n must be <= 31 to be portable | ** Bit masking macros. XXX n must be <= 31 to be portable | |||
***********************************************************************/ | ***********************************************************************/ | |||
#define JS_BIT(n) ((JSUint32)1 << (n)) | #define JS_BIT(n) ((JSUint32)1 << (n)) | |||
#define JS_BITMASK(n) (JS_BIT(n) - 1) | #define JS_BITMASK(n) (JS_BIT(n) - 1) | |||
skipping to change at line 243 | skipping to change at line 247 | |||
** JS_MAX | ** JS_MAX | |||
** DESCRIPTION: | ** DESCRIPTION: | |||
** Commonly used macros for operations on compatible types. | ** Commonly used macros for operations on compatible types. | |||
***********************************************************************/ | ***********************************************************************/ | |||
#define JS_HOWMANY(x,y) (((x)+(y)-1)/(y)) | #define JS_HOWMANY(x,y) (((x)+(y)-1)/(y)) | |||
#define JS_ROUNDUP(x,y) (JS_HOWMANY(x,y)*(y)) | #define JS_ROUNDUP(x,y) (JS_HOWMANY(x,y)*(y)) | |||
#define JS_MIN(x,y) ((x)<(y)?(x):(y)) | #define JS_MIN(x,y) ((x)<(y)?(x):(y)) | |||
#define JS_MAX(x,y) ((x)>(y)?(x):(y)) | #define JS_MAX(x,y) ((x)>(y)?(x):(y)) | |||
#if (defined(XP_WIN) && !defined(CROSS_COMPILE)) || defined (WINCE) | #if (defined(XP_WIN) && !defined(CROSS_COMPILE)) || defined (WINCE) | |||
# include "jscpucfg.h" /* Use standard Mac or Windows configurati on */ | # include "jscpucfg.h" /* Use standard Mac or Windows configuration */ | |||
#elif defined(XP_UNIX) || defined(XP_BEOS) || defined(XP_OS2) || defined(CR OSS_COMPILE) | #elif defined(XP_UNIX) || defined(XP_BEOS) || defined(XP_OS2) || defined(CR OSS_COMPILE) | |||
# include "jsautocfg.h" /* Use auto-detected configuration */ | # include "jsautocfg.h" /* Use auto-detected configuration */ | |||
# include "jsosdep.h" /* ...and platform-specific flags */ | ||||
#else | #else | |||
# error "Must define one of XP_BEOS, XP_OS2, XP_WIN or XP_UNIX" | # error "Must define one of XP_BEOS, XP_OS2, XP_WIN or XP_UNIX" | |||
#endif | #endif | |||
JS_BEGIN_EXTERN_C | JS_BEGIN_EXTERN_C | |||
/************************************************************************ | /************************************************************************ | |||
** TYPES: JSUint8 | ** TYPES: JSUint8 | |||
** JSInt8 | ** JSInt8 | |||
** DESCRIPTION: | ** DESCRIPTION: | |||
** The int8 types are known to be 8 bits each. There is no type that | ** The int8 types are known to be 8 bits each. There is no type that | |||
** is equivalent to a plain "char". | ** is equivalent to a plain "char". | |||
************************************************************************/ | ************************************************************************/ | |||
#if JS_BYTES_PER_BYTE == 1 | #if JS_BYTES_PER_BYTE == 1 | |||
typedef unsigned char JSUint8; | typedef unsigned char JSUint8; | |||
typedef signed char JSInt8; | typedef signed char JSInt8; | |||
#else | #else | |||
#error No suitable type for JSInt8/JSUint8 | # error No suitable type for JSInt8/JSUint8 | |||
#endif | #endif | |||
/************************************************************************ | /************************************************************************ | |||
** TYPES: JSUint16 | ** TYPES: JSUint16 | |||
** JSInt16 | ** JSInt16 | |||
** DESCRIPTION: | ** DESCRIPTION: | |||
** The int16 types are known to be 16 bits each. | ** The int16 types are known to be 16 bits each. | |||
************************************************************************/ | ************************************************************************/ | |||
#if JS_BYTES_PER_SHORT == 2 | #if JS_BYTES_PER_SHORT == 2 | |||
typedef unsigned short JSUint16; | typedef unsigned short JSUint16; | |||
typedef short JSInt16; | typedef short JSInt16; | |||
#else | #else | |||
#error No suitable type for JSInt16/JSUint16 | # error No suitable type for JSInt16/JSUint16 | |||
#endif | #endif | |||
/************************************************************************ | /************************************************************************ | |||
** TYPES: JSUint32 | ** TYPES: JSUint32 | |||
** JSInt32 | ** JSInt32 | |||
** DESCRIPTION: | ** DESCRIPTION: | |||
** The int32 types are known to be 32 bits each. | ** The int32 types are known to be 32 bits each. | |||
************************************************************************/ | ************************************************************************/ | |||
#if JS_BYTES_PER_INT == 4 | #if JS_BYTES_PER_INT == 4 | |||
typedef unsigned int JSUint32; | typedef unsigned int JSUint32; | |||
typedef int JSInt32; | typedef int JSInt32; | |||
#define JS_INT32(x) x | # define JS_INT32(x) x | |||
#define JS_UINT32(x) x ## U | # define JS_UINT32(x) x ## U | |||
#elif JS_BYTES_PER_LONG == 4 | #elif JS_BYTES_PER_LONG == 4 | |||
typedef unsigned long JSUint32; | typedef unsigned long JSUint32; | |||
typedef long JSInt32; | typedef long JSInt32; | |||
#define JS_INT32(x) x ## L | # define JS_INT32(x) x ## L | |||
#define JS_UINT32(x) x ## UL | # define JS_UINT32(x) x ## UL | |||
#else | #else | |||
#error No suitable type for JSInt32/JSUint32 | # error No suitable type for JSInt32/JSUint32 | |||
#endif | #endif | |||
/************************************************************************ | /************************************************************************ | |||
** TYPES: JSUint64 | ** TYPES: JSUint64 | |||
** JSInt64 | ** JSInt64 | |||
** DESCRIPTION: | ** DESCRIPTION: | |||
** The int64 types are known to be 64 bits each. Care must be used when | ** The int64 types are known to be 64 bits each. Care must be used when | |||
** declaring variables of type JSUint64 or JSInt64. Different hardware | ** declaring variables of type JSUint64 or JSInt64. Different hardware | |||
** architectures and even different compilers have varying support for | ** architectures and even different compilers have varying support for | |||
** 64 bit values. The only guaranteed portability requires the use of | ** 64 bit values. The only guaranteed portability requires the use of | |||
** the JSLL_ macros (see jslong.h). | ** the JSLL_ macros (see jslong.h). | |||
************************************************************************/ | ************************************************************************/ | |||
#ifdef JS_HAVE_LONG_LONG | #ifdef JS_HAVE_LONG_LONG | |||
#if JS_BYTES_PER_LONG == 8 | ||||
# if JS_BYTES_PER_LONG == 8 | ||||
typedef long JSInt64; | typedef long JSInt64; | |||
typedef unsigned long JSUint64; | typedef unsigned long JSUint64; | |||
#elif defined(WIN16) | # elif defined(WIN16) | |||
typedef __int64 JSInt64; | typedef __int64 JSInt64; | |||
typedef unsigned __int64 JSUint64; | typedef unsigned __int64 JSUint64; | |||
#elif defined(WIN32) && !defined(__GNUC__) | # elif defined(WIN32) && !defined(__GNUC__) | |||
typedef __int64 JSInt64; | typedef __int64 JSInt64; | |||
typedef unsigned __int64 JSUint64; | typedef unsigned __int64 JSUint64; | |||
#else | # else | |||
typedef long long JSInt64; | typedef long long JSInt64; | |||
typedef unsigned long long JSUint64; | typedef unsigned long long JSUint64; | |||
#endif /* JS_BYTES_PER_LONG == 8 */ | # endif /* JS_BYTES_PER_LONG == 8 */ | |||
#else /* !JS_HAVE_LONG_LONG */ | #else /* !JS_HAVE_LONG_LONG */ | |||
typedef struct { | typedef struct { | |||
#ifdef IS_LITTLE_ENDIAN | # ifdef IS_LITTLE_ENDIAN | |||
JSUint32 lo, hi; | JSUint32 lo, hi; | |||
#else | # else | |||
JSUint32 hi, lo; | JSUint32 hi, lo; | |||
#endif | #endif | |||
} JSInt64; | } JSInt64; | |||
typedef JSInt64 JSUint64; | typedef JSInt64 JSUint64; | |||
#endif /* !JS_HAVE_LONG_LONG */ | #endif /* !JS_HAVE_LONG_LONG */ | |||
/************************************************************************ | /************************************************************************ | |||
** TYPES: JSUintn | ** TYPES: JSUintn | |||
** JSIntn | ** JSIntn | |||
** DESCRIPTION: | ** DESCRIPTION: | |||
** The JSIntn types are most appropriate for automatic variables. They are | ** The JSIntn types are most appropriate for automatic variables. They are | |||
** guaranteed to be at least 16 bits, though various architectures may | ** guaranteed to be at least 16 bits, though various architectures may | |||
** define them to be wider (e.g., 32 or even 64 bits). These types are | ** define them to be wider (e.g., 32 or even 64 bits). These types are | |||
** never valid for fields of a structure. | ** never valid for fields of a structure. | |||
skipping to change at line 348 | skipping to change at line 355 | |||
** DESCRIPTION: | ** DESCRIPTION: | |||
** The JSIntn types are most appropriate for automatic variables. They are | ** The JSIntn types are most appropriate for automatic variables. They are | |||
** guaranteed to be at least 16 bits, though various architectures may | ** guaranteed to be at least 16 bits, though various architectures may | |||
** define them to be wider (e.g., 32 or even 64 bits). These types are | ** define them to be wider (e.g., 32 or even 64 bits). These types are | |||
** never valid for fields of a structure. | ** never valid for fields of a structure. | |||
************************************************************************/ | ************************************************************************/ | |||
#if JS_BYTES_PER_INT >= 2 | #if JS_BYTES_PER_INT >= 2 | |||
typedef int JSIntn; | typedef int JSIntn; | |||
typedef unsigned int JSUintn; | typedef unsigned int JSUintn; | |||
#else | #else | |||
#error 'sizeof(int)' not sufficient for platform use | # error 'sizeof(int)' not sufficient for platform use | |||
#endif | #endif | |||
/************************************************************************ | /************************************************************************ | |||
** TYPES: JSFloat64 | ** TYPES: JSFloat64 | |||
** DESCRIPTION: | ** DESCRIPTION: | |||
** NSPR's floating point type is always 64 bits. | ** NSPR's floating point type is always 64 bits. | |||
************************************************************************/ | ************************************************************************/ | |||
typedef double JSFloat64; | typedef double JSFloat64; | |||
/************************************************************************ | /************************************************************************ | |||
skipping to change at line 435 | skipping to change at line 442 | |||
** if (JS_LIKELY(v == 1)) { | ** if (JS_LIKELY(v == 1)) { | |||
** ... expected code path ... | ** ... expected code path ... | |||
** } | ** } | |||
** | ** | |||
** if (JS_UNLIKELY(v == 0)) { | ** if (JS_UNLIKELY(v == 0)) { | |||
** ... non-expected code path ... | ** ... non-expected code path ... | |||
** } | ** } | |||
** | ** | |||
***********************************************************************/ | ***********************************************************************/ | |||
#if defined(__GNUC__) && (__GNUC__ > 2) | #if defined(__GNUC__) && (__GNUC__ > 2) | |||
#define JS_LIKELY(x) (__builtin_expect((x), 1)) | ||||
#define JS_UNLIKELY(x) (__builtin_expect((x), 0)) | # define JS_LIKELY(x) (__builtin_expect((x), 1)) | |||
# define JS_UNLIKELY(x) (__builtin_expect((x), 0)) | ||||
#else | #else | |||
#define JS_LIKELY(x) (x) | ||||
#define JS_UNLIKELY(x) (x) | # define JS_LIKELY(x) (x) | |||
# define JS_UNLIKELY(x) (x) | ||||
#endif | #endif | |||
/*********************************************************************** | /*********************************************************************** | |||
** MACROS: JS_ARRAY_LENGTH | ** MACROS: JS_ARRAY_LENGTH | |||
** JS_ARRAY_END | ** JS_ARRAY_END | |||
** DESCRIPTION: | ** DESCRIPTION: | |||
** Macros to get the number of elements and the pointer to one past th e | ** Macros to get the number of elements and the pointer to one past th e | |||
** last element of a C array. Use them like this: | ** last element of a C array. Use them like this: | |||
** | ** | |||
** jschar buf[10], *s; | ** jschar buf[10], *s; | |||
End of changes. 44 change blocks. | ||||
93 lines changed or deleted | 106 lines changed or added | |||
jsxdrapi.h | jsxdrapi.h | |||
---|---|---|---|---|
skipping to change at line 192 | skipping to change at line 192 | |||
JS_XDRFindClassById(JSXDRState *xdr, uint32 id); | JS_XDRFindClassById(JSXDRState *xdr, uint32 id); | |||
/* | /* | |||
* Magic numbers. | * Magic numbers. | |||
*/ | */ | |||
#define JSXDR_MAGIC_SCRIPT_1 0xdead0001 | #define JSXDR_MAGIC_SCRIPT_1 0xdead0001 | |||
#define JSXDR_MAGIC_SCRIPT_2 0xdead0002 | #define JSXDR_MAGIC_SCRIPT_2 0xdead0002 | |||
#define JSXDR_MAGIC_SCRIPT_3 0xdead0003 | #define JSXDR_MAGIC_SCRIPT_3 0xdead0003 | |||
#define JSXDR_MAGIC_SCRIPT_4 0xdead0004 | #define JSXDR_MAGIC_SCRIPT_4 0xdead0004 | |||
#define JSXDR_MAGIC_SCRIPT_5 0xdead0005 | #define JSXDR_MAGIC_SCRIPT_5 0xdead0005 | |||
#define JSXDR_MAGIC_SCRIPT_CURRENT JSXDR_MAGIC_SCRIPT_5 | #define JSXDR_MAGIC_SCRIPT_6 0xdead0006 | |||
#define JSXDR_MAGIC_SCRIPT_7 0xdead0007 | ||||
#define JSXDR_MAGIC_SCRIPT_CURRENT JSXDR_MAGIC_SCRIPT_7 | ||||
/* | /* | |||
* Bytecode version number. Decrement the second term whenever JS bytecode | * Bytecode version number. Increment the subtrahend whenever JS bytecode | |||
* changes incompatibly. | * changes incompatibly. | |||
* | * | |||
* This version number should be XDR'ed once near the front of any file or | * This version number should be XDR'ed once near the front of any file or | |||
* larger storage unit containing XDR'ed bytecode and other data, and check ed | * larger storage unit containing XDR'ed bytecode and other data, and check ed | |||
* before deserialization of bytecode. If the saved version does not match | * before deserialization of bytecode. If the saved version does not match | |||
* the current version, abort deserialization and invalidate the file. | * the current version, abort deserialization and invalidate the file. | |||
*/ | */ | |||
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 16) | #define JSXDR_BYTECODE_VERSION (0xb973c0de - 24) | |||
/* | /* | |||
* Library-private functions. | * Library-private functions. | |||
*/ | */ | |||
extern JSBool | extern JSBool | |||
js_XDRAtom(JSXDRState *xdr, JSAtom **atomp); | js_XDRAtom(JSXDRState *xdr, JSAtom **atomp); | |||
extern JSBool | extern JSBool | |||
js_XDRStringAtom(JSXDRState *xdr, JSAtom **atomp); | js_XDRStringAtom(JSXDRState *xdr, JSAtom **atomp); | |||
/* | ||||
* FIXME: This is non-unicode version of js_XDRStringAtom that performs los | ||||
sy | ||||
* conversion. Do not use it in the new code! See bug 325202. | ||||
*/ | ||||
extern JSBool | ||||
js_XDRCStringAtom(JSXDRState *xdr, JSAtom **atomp); | ||||
JS_END_EXTERN_C | JS_END_EXTERN_C | |||
#endif /* ! jsxdrapi_h___ */ | #endif /* ! jsxdrapi_h___ */ | |||
End of changes. 4 change blocks. | ||||
11 lines changed or deleted | 5 lines changed or added | |||
jsxml.h | jsxml.h | |||
---|---|---|---|---|
skipping to change at line 45 | skipping to change at line 45 | |||
* the terms of any one of the MPL, the GPL or the LGPL. | * the terms of any one of the MPL, the GPL or the LGPL. | |||
* | * | |||
* ***** END LICENSE BLOCK ***** */ | * ***** END LICENSE BLOCK ***** */ | |||
#ifndef jsxml_h___ | #ifndef jsxml_h___ | |||
#define jsxml_h___ | #define jsxml_h___ | |||
#include "jsstddef.h" | #include "jsstddef.h" | |||
#include "jspubtd.h" | #include "jspubtd.h" | |||
JS_BEGIN_EXTERN_C | ||||
extern const char js_AnyName_str[]; | extern const char js_AnyName_str[]; | |||
extern const char js_AttributeName_str[]; | extern const char js_AttributeName_str[]; | |||
extern const char js_isXMLName_str[]; | extern const char js_isXMLName_str[]; | |||
extern const char js_XMLList_str[]; | extern const char js_XMLList_str[]; | |||
extern const char js_amp_entity_str[]; | extern const char js_amp_entity_str[]; | |||
extern const char js_gt_entity_str[]; | extern const char js_gt_entity_str[]; | |||
extern const char js_lt_entity_str[]; | extern const char js_lt_entity_str[]; | |||
extern const char js_quot_entity_str[]; | extern const char js_quot_entity_str[]; | |||
skipping to change at line 67 | skipping to change at line 69 | |||
JSString *prefix; | JSString *prefix; | |||
JSString *uri; | JSString *uri; | |||
JSBool declared; /* true if declared in its XML tag */ | JSBool declared; /* true if declared in its XML tag */ | |||
}; | }; | |||
extern JSXMLNamespace * | extern JSXMLNamespace * | |||
js_NewXMLNamespace(JSContext *cx, JSString *prefix, JSString *uri, | js_NewXMLNamespace(JSContext *cx, JSString *prefix, JSString *uri, | |||
JSBool declared); | JSBool declared); | |||
extern void | extern void | |||
js_MarkXMLNamespace(JSContext *cx, JSXMLNamespace *ns); | js_TraceXMLNamespace(JSTracer *trc, JSXMLNamespace *ns); | |||
extern void | extern void | |||
js_FinalizeXMLNamespace(JSContext *cx, JSXMLNamespace *ns); | js_FinalizeXMLNamespace(JSContext *cx, JSXMLNamespace *ns); | |||
extern JSObject * | extern JSObject * | |||
js_NewXMLNamespaceObject(JSContext *cx, JSString *prefix, JSString *uri, | js_NewXMLNamespaceObject(JSContext *cx, JSString *prefix, JSString *uri, | |||
JSBool declared); | JSBool declared); | |||
extern JSObject * | extern JSObject * | |||
js_GetXMLNamespaceObject(JSContext *cx, JSXMLNamespace *ns); | js_GetXMLNamespaceObject(JSContext *cx, JSXMLNamespace *ns); | |||
skipping to change at line 91 | skipping to change at line 93 | |||
JSString *uri; | JSString *uri; | |||
JSString *prefix; | JSString *prefix; | |||
JSString *localName; | JSString *localName; | |||
}; | }; | |||
extern JSXMLQName * | extern JSXMLQName * | |||
js_NewXMLQName(JSContext *cx, JSString *uri, JSString *prefix, | js_NewXMLQName(JSContext *cx, JSString *uri, JSString *prefix, | |||
JSString *localName); | JSString *localName); | |||
extern void | extern void | |||
js_MarkXMLQName(JSContext *cx, JSXMLQName *qn); | js_TraceXMLQName(JSTracer *trc, JSXMLQName *qn); | |||
extern void | extern void | |||
js_FinalizeXMLQName(JSContext *cx, JSXMLQName *qn); | js_FinalizeXMLQName(JSContext *cx, JSXMLQName *qn); | |||
extern JSObject * | extern JSObject * | |||
js_NewXMLQNameObject(JSContext *cx, JSString *uri, JSString *prefix, | js_NewXMLQNameObject(JSContext *cx, JSString *uri, JSString *prefix, | |||
JSString *localName); | JSString *localName); | |||
extern JSObject * | extern JSObject * | |||
js_GetXMLQNameObject(JSContext *cx, JSXMLQName *qn); | js_GetXMLQNameObject(JSContext *cx, JSXMLQName *qn); | |||
skipping to change at line 155 | skipping to change at line 157 | |||
#define JSXML_CLASS_HAS_KIDS(class_) ((class_) < JSXML_CLASS_ATTRIBUTE) | #define JSXML_CLASS_HAS_KIDS(class_) ((class_) < JSXML_CLASS_ATTRIBUTE) | |||
#define JSXML_CLASS_HAS_VALUE(class_) ((class_) >= JSXML_CLASS_ATTRIBUTE) | #define JSXML_CLASS_HAS_VALUE(class_) ((class_) >= JSXML_CLASS_ATTRIBUTE) | |||
#define JSXML_CLASS_HAS_NAME(class_) \ | #define JSXML_CLASS_HAS_NAME(class_) \ | |||
((uintN)((class_) - JSXML_CLASS_ELEMENT) <= \ | ((uintN)((class_) - JSXML_CLASS_ELEMENT) <= \ | |||
(uintN)(JSXML_CLASS_PROCESSING_INSTRUCTION - JSXML_CLASS_ELEMENT)) | (uintN)(JSXML_CLASS_PROCESSING_INSTRUCTION - JSXML_CLASS_ELEMENT)) | |||
#ifdef DEBUG_notme | #ifdef DEBUG_notme | |||
#include "jsclist.h" | #include "jsclist.h" | |||
#endif | #endif | |||
typedef struct JSXMLListVar { | ||||
JSXMLArray kids; /* NB: must come first */ | ||||
JSXML *target; | ||||
JSXMLQName *targetprop; | ||||
} JSXMLListVar; | ||||
typedef struct JSXMLElemVar { | ||||
JSXMLArray kids; /* NB: must come first */ | ||||
JSXMLArray namespaces; | ||||
JSXMLArray attrs; | ||||
} JSXMLElemVar; | ||||
struct JSXML { | struct JSXML { | |||
#ifdef DEBUG_notme | #ifdef DEBUG_notme | |||
JSCList links; | JSCList links; | |||
uint32 serial; | uint32 serial; | |||
#endif | #endif | |||
JSObject *object; | JSObject *object; | |||
void *domnode; /* DOM node if mapped info item */ | void *domnode; /* DOM node if mapped info item */ | |||
JSXML *parent; | JSXML *parent; | |||
JSXMLQName *name; | JSXMLQName *name; | |||
uint16 xml_class; /* discriminates u, below */ | uint16 xml_class; /* discriminates u, below */ | |||
uint16 xml_flags; /* flags, see below */ | uint16 xml_flags; /* flags, see below */ | |||
union { | union { | |||
struct JSXMLListVar { | JSXMLListVar list; | |||
JSXMLArray kids; /* NB: must come first */ | JSXMLElemVar elem; | |||
JSXML *target; | ||||
JSXMLQName *targetprop; | ||||
} list; | ||||
struct JSXMLVar { | ||||
JSXMLArray kids; /* NB: must come first */ | ||||
JSXMLArray namespaces; | ||||
JSXMLArray attrs; | ||||
} elem; | ||||
JSString *value; | JSString *value; | |||
} u; | } u; | |||
/* Don't add anything after u -- see js_NewXML for why. */ | /* Don't add anything after u -- see js_NewXML for why. */ | |||
}; | }; | |||
/* union member shorthands */ | /* union member shorthands */ | |||
#define xml_kids u.list.kids | #define xml_kids u.list.kids | |||
#define xml_target u.list.target | #define xml_target u.list.target | |||
#define xml_targetprop u.list.targetprop | #define xml_targetprop u.list.targetprop | |||
skipping to change at line 206 | skipping to change at line 212 | |||
#define JSXML_HAS_VALUE(xml) JSXML_CLASS_HAS_VALUE((xml)->xml_class) | #define JSXML_HAS_VALUE(xml) JSXML_CLASS_HAS_VALUE((xml)->xml_class) | |||
#define JSXML_HAS_NAME(xml) JSXML_CLASS_HAS_NAME((xml)->xml_class) | #define JSXML_HAS_NAME(xml) JSXML_CLASS_HAS_NAME((xml)->xml_class) | |||
#define JSXML_LENGTH(xml) (JSXML_CLASS_HAS_KIDS((xml)->xml_class) \ | #define JSXML_LENGTH(xml) (JSXML_CLASS_HAS_KIDS((xml)->xml_class) \ | |||
? (xml)->xml_kids.length \ | ? (xml)->xml_kids.length \ | |||
: 0) | : 0) | |||
extern JSXML * | extern JSXML * | |||
js_NewXML(JSContext *cx, JSXMLClass xml_class); | js_NewXML(JSContext *cx, JSXMLClass xml_class); | |||
extern void | extern void | |||
js_MarkXML(JSContext *cx, JSXML *xml); | js_TraceXML(JSTracer *trc, JSXML *xml); | |||
extern void | extern void | |||
js_FinalizeXML(JSContext *cx, JSXML *xml); | js_FinalizeXML(JSContext *cx, JSXML *xml); | |||
extern JSObject * | extern JSObject * | |||
js_ParseNodeToXMLObject(JSContext *cx, JSParseNode *pn); | js_ParseNodeToXMLObject(JSContext *cx, JSParseContext *pc, JSParseNode *pn) ; | |||
extern JSObject * | extern JSObject * | |||
js_NewXMLObject(JSContext *cx, JSXMLClass xml_class); | js_NewXMLObject(JSContext *cx, JSXMLClass xml_class); | |||
extern JSObject * | extern JSObject * | |||
js_GetXMLObject(JSContext *cx, JSXML *xml); | js_GetXMLObject(JSContext *cx, JSXML *xml); | |||
extern JS_FRIEND_DATA(JSXMLObjectOps) js_XMLObjectOps; | extern JS_FRIEND_DATA(JSXMLObjectOps) js_XMLObjectOps; | |||
extern JS_FRIEND_DATA(JSClass) js_XMLClass; | extern JS_FRIEND_DATA(JSClass) js_XMLClass; | |||
extern JS_FRIEND_DATA(JSExtendedClass) js_NamespaceClass; | extern JS_FRIEND_DATA(JSExtendedClass) js_NamespaceClass; | |||
extern JS_FRIEND_DATA(JSExtendedClass) js_QNameClass; | extern JS_FRIEND_DATA(JSExtendedClass) js_QNameClass; | |||
extern JS_FRIEND_DATA(JSClass) js_AttributeNameClass; | extern JS_FRIEND_DATA(JSClass) js_AttributeNameClass; | |||
extern JS_FRIEND_DATA(JSClass) js_AnyNameClass; | extern JS_FRIEND_DATA(JSClass) js_AnyNameClass; | |||
extern JSClass js_XMLFilterClass; | ||||
/* | /* | |||
* Macros to test whether an object or a value is of type "xml" (per typeof ). | * Macros to test whether an object or a value is of type "xml" (per typeof ). | |||
* NB: jsapi.h must be included before any call to VALUE_IS_XML. | * NB: jsobj.h must be included before any call to OBJECT_IS_XML, and jsapi | |||
.h | ||||
* and jsobj.h must be included before any call to VALUE_IS_XML. | ||||
*/ | */ | |||
#define OBJECT_IS_XML(cx,obj) ((obj)->map->ops == &js_XMLObjectOps.base) | #define OBJECT_IS_XML(cx,obj) ((obj)->map->ops == &js_XMLObjectOps.base) | |||
#define VALUE_IS_XML(cx,v) (!JSVAL_IS_PRIMITIVE(v) && \ | #define VALUE_IS_XML(cx,v) (!JSVAL_IS_PRIMITIVE(v) && \ | |||
OBJECT_IS_XML(cx, JSVAL_TO_OBJECT(v))) | OBJECT_IS_XML(cx, JSVAL_TO_OBJECT(v))) | |||
extern JSObject * | extern JSObject * | |||
js_InitNamespaceClass(JSContext *cx, JSObject *obj); | js_InitNamespaceClass(JSContext *cx, JSObject *obj); | |||
extern JSObject * | extern JSObject * | |||
js_InitQNameClass(JSContext *cx, JSObject *obj); | js_InitQNameClass(JSContext *cx, JSObject *obj); | |||
skipping to change at line 256 | skipping to change at line 264 | |||
extern JSObject * | extern JSObject * | |||
js_InitXMLClass(JSContext *cx, JSObject *obj); | js_InitXMLClass(JSContext *cx, JSObject *obj); | |||
extern JSObject * | extern JSObject * | |||
js_InitXMLClasses(JSContext *cx, JSObject *obj); | js_InitXMLClasses(JSContext *cx, JSObject *obj); | |||
extern JSBool | extern JSBool | |||
js_GetFunctionNamespace(JSContext *cx, jsval *vp); | js_GetFunctionNamespace(JSContext *cx, jsval *vp); | |||
/* | ||||
* If obj is QName corresponding to function::name, set *funidp to name's i | ||||
d, | ||||
* otherwise set *funidp to 0. | ||||
*/ | ||||
JSBool | ||||
js_IsFunctionQName(JSContext *cx, JSObject *obj, jsid *funidp); | ||||
extern JSBool | extern JSBool | |||
js_GetDefaultXMLNamespace(JSContext *cx, jsval *vp); | js_GetDefaultXMLNamespace(JSContext *cx, jsval *vp); | |||
extern JSBool | extern JSBool | |||
js_SetDefaultXMLNamespace(JSContext *cx, jsval v); | js_SetDefaultXMLNamespace(JSContext *cx, jsval v); | |||
/* | /* | |||
* Return true if v is a XML QName object, or if it converts to a string th at | * Return true if v is a XML QName object, or if it converts to a string th at | |||
* contains a valid XML qualified name (one containing no :), false otherwi se. | * contains a valid XML qualified name (one containing no :), false otherwi se. | |||
* NB: This function is an infallible predicate, it hides exceptions. | * NB: This function is an infallible predicate, it hides exceptions. | |||
*/ | */ | |||
extern JSBool | extern JSBool | |||
js_IsXMLName(JSContext *cx, jsval v); | js_IsXMLName(JSContext *cx, jsval v); | |||
extern JSBool | extern JSBool | |||
js_ToAttributeName(JSContext *cx, jsval *vp); | js_ToAttributeName(JSContext *cx, jsval *vp); | |||
extern JSString * | extern JSString * | |||
js_EscapeAttributeValue(JSContext *cx, JSString *str); | js_EscapeAttributeValue(JSContext *cx, JSString *str, JSBool quote); | |||
extern JSString * | extern JSString * | |||
js_AddAttributePart(JSContext *cx, JSBool isName, JSString *str, | js_AddAttributePart(JSContext *cx, JSBool isName, JSString *str, | |||
JSString *str2); | JSString *str2); | |||
extern JSString * | extern JSString * | |||
js_EscapeElementValue(JSContext *cx, JSString *str); | js_EscapeElementValue(JSContext *cx, JSString *str); | |||
extern JSString * | extern JSString * | |||
js_ValueToXMLString(JSContext *cx, jsval v); | js_ValueToXMLString(JSContext *cx, jsval v); | |||
extern JSBool | extern JSBool | |||
js_GetAnyName(JSContext *cx, jsval *vp); | js_GetAnyName(JSContext *cx, jsval *vp); | |||
/* | ||||
* Note: nameval must be either QName, AttributeName, or AnyName. | ||||
*/ | ||||
extern JSBool | extern JSBool | |||
js_FindXMLProperty(JSContext *cx, jsval name, JSObject **objp, jsval *namep | js_FindXMLProperty(JSContext *cx, jsval nameval, JSObject **objp, jsid *idp | |||
); | ); | |||
extern JSBool | ||||
js_GetXMLProperty(JSContext *cx, JSObject *obj, jsval name, jsval *vp); | ||||
extern JSBool | extern JSBool | |||
js_GetXMLFunction(JSContext *cx, JSObject *obj, jsid id, jsval *vp); | js_GetXMLFunction(JSContext *cx, JSObject *obj, jsid id, jsval *vp); | |||
extern JSBool | extern JSBool | |||
js_SetXMLProperty(JSContext *cx, JSObject *obj, jsval name, jsval *vp); | ||||
extern JSBool | ||||
js_GetXMLDescendants(JSContext *cx, JSObject *obj, jsval id, jsval *vp); | js_GetXMLDescendants(JSContext *cx, JSObject *obj, jsval id, jsval *vp); | |||
extern JSBool | extern JSBool | |||
js_DeleteXMLListElements(JSContext *cx, JSObject *listobj); | js_DeleteXMLListElements(JSContext *cx, JSObject *listobj); | |||
extern JSObject * | ||||
js_InitXMLFilterClass(JSContext *cx, JSObject* obj); | ||||
extern JSBool | extern JSBool | |||
js_FilterXMLList(JSContext *cx, JSObject *obj, jsbytecode *pc, jsval *vp); | js_StepXMLListFilter(JSContext *cx, JSBool initialized); | |||
extern JSObject * | extern JSObject * | |||
js_ValueToXMLObject(JSContext *cx, jsval v); | js_ValueToXMLObject(JSContext *cx, jsval v); | |||
extern JSObject * | extern JSObject * | |||
js_ValueToXMLListObject(JSContext *cx, jsval v); | js_ValueToXMLListObject(JSContext *cx, jsval v); | |||
extern JSObject * | extern JSObject * | |||
js_CloneXMLObject(JSContext *cx, JSObject *obj); | js_CloneXMLObject(JSContext *cx, JSObject *obj); | |||
skipping to change at line 332 | skipping to change at line 347 | |||
extern JSString * | extern JSString * | |||
js_MakeXMLCDATAString(JSContext *cx, JSString *str); | js_MakeXMLCDATAString(JSContext *cx, JSString *str); | |||
extern JSString * | extern JSString * | |||
js_MakeXMLCommentString(JSContext *cx, JSString *str); | js_MakeXMLCommentString(JSContext *cx, JSString *str); | |||
extern JSString * | extern JSString * | |||
js_MakeXMLPIString(JSContext *cx, JSString *name, JSString *str); | js_MakeXMLPIString(JSContext *cx, JSString *name, JSString *str); | |||
JS_END_EXTERN_C | ||||
#endif /* jsxml_h___ */ | #endif /* jsxml_h___ */ | |||
End of changes. 17 change blocks. | ||||
25 lines changed or deleted | 44 lines changed or added | |||
prmjtime.h | prmjtime.h | |||
---|---|---|---|---|
skipping to change at line 67 | skipping to change at line 67 | |||
* Broken down form of 64 bit time value. | * Broken down form of 64 bit time value. | |||
*/ | */ | |||
struct PRMJTime { | struct PRMJTime { | |||
JSInt32 tm_usec; /* microseconds of second (0-999999) */ | JSInt32 tm_usec; /* microseconds of second (0-999999) */ | |||
JSInt8 tm_sec; /* seconds of minute (0-59) */ | JSInt8 tm_sec; /* seconds of minute (0-59) */ | |||
JSInt8 tm_min; /* minutes of hour (0-59) */ | JSInt8 tm_min; /* minutes of hour (0-59) */ | |||
JSInt8 tm_hour; /* hour of day (0-23) */ | JSInt8 tm_hour; /* hour of day (0-23) */ | |||
JSInt8 tm_mday; /* day of month (1-31) */ | JSInt8 tm_mday; /* day of month (1-31) */ | |||
JSInt8 tm_mon; /* month of year (0-11) */ | JSInt8 tm_mon; /* month of year (0-11) */ | |||
JSInt8 tm_wday; /* 0=sunday, 1=monday, ... */ | JSInt8 tm_wday; /* 0=sunday, 1=monday, ... */ | |||
JSInt16 tm_year; /* absolute year, AD */ | JSInt32 tm_year; /* absolute year, AD */ | |||
JSInt16 tm_yday; /* day of year (0 to 365) */ | JSInt16 tm_yday; /* day of year (0 to 365) */ | |||
JSInt8 tm_isdst; /* non-zero if DST in effect */ | JSInt8 tm_isdst; /* non-zero if DST in effect */ | |||
}; | }; | |||
/* Some handy constants */ | /* Some handy constants */ | |||
#define PRMJ_USEC_PER_SEC 1000000L | #define PRMJ_USEC_PER_SEC 1000000L | |||
#define PRMJ_USEC_PER_MSEC 1000L | #define PRMJ_USEC_PER_MSEC 1000L | |||
/* Return the current local time in micro-seconds */ | /* Return the current local time in micro-seconds */ | |||
extern JSInt64 | extern JSInt64 | |||
PRMJ_Now(void); | PRMJ_Now(void); | |||
/* Release the resources associated with PRMJ_Now; don't call PRMJ_Now agai | ||||
n */ | ||||
#if defined(JS_THREADSAFE) && defined(XP_WIN) | ||||
extern void | ||||
PRMJ_NowShutdown(void); | ||||
#else | ||||
#define PRMJ_NowShutdown() | ||||
#endif | ||||
/* get the difference between this time zone and gmt timezone in seconds * / | /* get the difference between this time zone and gmt timezone in seconds * / | |||
extern JSInt32 | extern JSInt32 | |||
PRMJ_LocalGMTDifference(void); | PRMJ_LocalGMTDifference(void); | |||
/* Format a time value into a buffer. Same semantics as strftime() */ | /* Format a time value into a buffer. Same semantics as strftime() */ | |||
extern size_t | extern size_t | |||
PRMJ_FormatTime(char *buf, int buflen, char *fmt, PRMJTime *tm); | PRMJ_FormatTime(char *buf, int buflen, const char *fmt, PRMJTime *tm); | |||
/* Get the DST offset for the local time passed in */ | /* Get the DST offset for the local time passed in */ | |||
extern JSInt64 | extern JSInt64 | |||
PRMJ_DSTOffset(JSInt64 local_time); | PRMJ_DSTOffset(JSInt64 local_time); | |||
JS_END_EXTERN_C | JS_END_EXTERN_C | |||
#endif /* prmjtime_h___ */ | #endif /* prmjtime_h___ */ | |||
End of changes. 3 change blocks. | ||||
2 lines changed or deleted | 11 lines changed or added | |||