| 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 | |
|
| 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 | |
|
| 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 | |
|
| 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 | |
|
| 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 | |
|
| 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 | |
|
| 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 | |
|
| 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 | |
|
| 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 | |
|
| 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 | |
|
| 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 | |
|
| 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 | |
|
| 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 | |
|